mount

title: mount(2)

text:
# mount(2)

## ИМЯ
mount - применяется для монтирования файловых систем.

## ОБЗОР

```
#include <sys/mount.h>
```

```
int mount(const char *source, const char *target,
          const char *filesystemtype, unsigned long mountflags,
          const void *data);
```

## ОПИСАНИЕ
Вызов mount() подключает файловую систему, указанную в source (обычно здесь задаётся название устройства, но также может быть указано имя каталога, или файла, или фиктивное устройство), к пути заданному в target(каталогу или файлу).

Для монтирования файловых систем требуются специальные права (Linux: мандат CAP_SYS_ADMIN).

Вариант filesystemtype доступные ядру перечислены в /proc/filesystems (например: "btrfs", "ext4", "jfs", "xfs", "vfat", "fuse", "tmpfs", "cgroup", "proc", "mqueue", "nfs", "cifs", "iso9660"). Дополнительные типы становятся доступными после загрузки соответствующих модулей.

Аргумент data рассматривается каждой файловой системой по-своему. Обычно, это строка параметров, перечисленных через запятую, которые понимает файловая система. О том, какие параметры доступны для каждого типа файловой системы смотрите mount(8).

Вызов mount() выполняет один из нескольких типов операций, в зависимости от значений, указанных в mountflags. Выбор выполняемой операции определяется путем тестирования значений, установленных в mountflags, с проведением тестов в следующем порядке:

- Перемонтировать существующие точки монтирования: mountflags включает MS_REMOUNT.

- Создать привязку (bind mount): mountflags включает MS_BIND.

- Изменить тип существующего монтирования: mountflags включает одно из MS_SHARED, MS_PRIVATE, MS_SLAVE или MS_UNBINDABLE.

- Переместить существующее монтирование в новое место: mountflags включает MS_MOVE.

- Создать новое монтирование: mountflags не содержит ни один из указанных выше флагов.

Каждая из этих операций подробно описана далее на этой странице. Для изменения поведения mount() могут быть указаны дополнительные флаги в mountflags, как описано ниже.

### Дополнительные флаги для монтирования
Ниже расположенный список дополнительных флагов, которые можно использовать в mountflags. Обратите внимание на то, что некоторые из них или даже все игнорируются операциями. Такие случае будут описаны далее по тексту.

MS_DIRSYNC (начиная с Linux 2.5.19)

Осуществлять изменения каталогов на этой файловой системе синхронно. Это свойство может быть получено для отдельных каталогов или дерева подкаталогов с помощью chattr(1).

MS_LAZYTIME (начиная с Linux 4.0)

Можно уменьшить количество обращений к диску, если сохранять дескрипторы меток времени (atime, mtime, ctime) только в памяти. Временные метки на диске обновляются только в следующих случаях:

(a)

дескрипторы необходимо обновить для некоторого изменения, не связанного с временными метками файлов;

(b)

приложение использует fsync(2), syncfs(2), or sync(2);

(c)

неиспользуемый дескриптор вытесняется из памяти; или

(d)

прошло более 24 часов с момента записи дескриптора на диск.

Данный параметр монтирования существенно сокращает количество операций записи, необходимых для обновления меток времени inode, особенно mtime и atime. Однако, если произойдёт падение системы, то поля atime и mtime на диске могут оказаться устаревшими на 24 часа.

В качестве примеров, где данный параметр может принести значительную выгоду это частые произвольные операции записи в уже выделенные файлы, а также случаи, когда также включён параметр монтирования MS_STRICTATIME (преимущество объединения MS_STRICTATIME и MS_LAZYTIME в том, что stat(2) будет возвращать правильное обновлённое время, но обновления atime будет производиться на диск только в случаях перечисленных выше).

MS_MANDLOCK

Разрешить обязательную блокировку файлов в этой файловой системе (обязательная блокировка всё равно сначала должна быть включена для определённого файла как описано в fcntl(2)). Начиная с Linux 4.5 этот параметр монтирования требует мандата CAP_SYS_ADMIN и ядро должно быть настроено с параметром CONFIG_MANDATORY_FILE_LOCKING.

MS_NOATIME

Не обновлять время доступа для (всех типов) файлов в этой файловой системе.

MS_NODEV

Запретить доступ к устройствам (специальным файлам) в этой файловой системе.

MS_NODIRATIME

Не обновлять время доступа для каталогов в этой файловой системе. Данный флаг частично предоставляет свойство MS_NOATIME; то есть при MS_NOATIME подразумевается MS_NODIRATIME.

MS_NOEXEC

Запретить исполнение программ в этой файловой системе.

MS_NOSUID

Не учитывать биты set-UID и set-GID или файловые мандаты при исполнении программ в этой файловой системе.

MS_RDONLY

Подключить файловую систему в режиме только для чтения.

MS_REC (начиная с Linux 2.4.11)

Используется вместе с MS_BIND для создания рекурсивной точки монтирования и вместе с флагами типа распространения для рекурсивного изменения типа распространения всех точек монтирования в поддереве. Подробности смотрите далее.

MS_RELATIME (начиная с Linux 2.6.20)

При доступе к файлу на этой файловой системе значение времени последнего доступа к файлу (atime) обновляется, только если текущее значение atime меньше или равно времени последнего изменения файла (mtime) или времени последнего изменения состояния файла (ctime). Этот флаг полезен для программ (например, mutt(1)), которым нужно знать, что файл был прочитан с момента его последнего изменения. Начиная с Linux 2.6.30 в ядро это поведение включено по умолчанию (если не указан MS_NOATIME), а чтобы получить обычное поведение нужно указать флаг MS_STRICTATIME. Также, начиная с Linux 2.6.30 время последнего доступа к файлу всегда обновляется, если оно устаревает на один день.

MS_SILENT (начиная с Linux 2.6.17)

Не выводить определённые (printk()) предупреждающие сообщения в журнал ядра. Этот флаг заменяет неправильно названный и устаревший флаг MS_VERBOSE (доступный начиная с Linux 2.4.12), который выполняет такую же функцию.

MS_STRICTATIME (начиная с Linux 2.6.30)

Всегда обновлять время последнего доступа (atime) при доступе к файлам на этой файловой системе (это выполнялось по умолчанию до Linux 2.6.30). Задание этого флага отменяет поведение флагов MS_NOATIME и MS_RELATIME.

MS_SYNCHRONOUS

Осуществлять запись на эту файловую систему синхронно (как если бы флаг O_SYNC для open(2) был указан для всех файлов, открытых на этой файловой системе).

Начиная с Linux 2.4 одни из показанных выше флагов можно устанавливать на точки монтирования (свой набор на каждой), а другие — на суперблок смонтированной файловой системы, то есть все монтирования одной файловой системы имеют одинаковый набор этих флагов (ранее все флаги применялись к суперблоку).

Флаги набора для точки монтирования:

- Начиная с Linux 2.4: флаги MS_NODEV, MS_NOEXEC и MS_NOSUID задаются для каждой точки монтирования отдельно.

- Начиная с Linux 2.6.16: MS_NOATIME и MS_NODIRATIME.

- Начиная с Linux 2.6.20: MS_RELATIME.

Следующие флаги указываются для суперблока: MS_DIRSYNC, MS_LAZYTIME, MS_MANDLOCK, MS_MS_SILENT и MS_SYNCHRONOUS. Начальный настройки этих флагов определяются по первому монтированию файловой системы и будут общими для всех последующих монтирований этой файловой системы. Следовательно, набор флагом можно изменить через операцию перемонтирования (смотрите далее). Эти изменения отразятся на всех точках монтирования, связанных с этой файловой системой.

Начиная с Linux 2.6.16 флаг MS_RDONLY может устанавливаться и сбрасываться на точках монтирования по отдельности, а также на нижележащем суперблоке файловой системы. Смонтированная файловая система будет доступна на запись только, если она сама и её точка монтирования не помечены только для чтения.

### Перемонтированние существующих точек монтирования.
Существующие монтирования можно перемонтировать, указав MS_REMOUNT в mountflags. Это позволяет изменить mountflags и data существующих монтирований без необходимости размонтировать и заново монтировать файловую систему. target должен соответствовать указанному при начальном вызове mount().

Аргументы source и filesystemtype игнорируются.

Аргументы mountflags и data должны совпадать со значениями, используемыми в первоначальном вызове mount(), за исключением параметров, которые были преднамеренно изменены.

В mountflags можно изменять: MS_LAZYTIME, MS_MANDLOCK, MS_NOATIME, MS_NODEV, MS_NODIRATIME, MS_NOEXEC, MS_NOSUID, MS_RELATIME, MS_RDONLY, MS_STRICTATIME (стирает флаги MS_NOATIME и MS_RELATIME) и MS_SYNCHRONOUS. Попытка изменить флаги MS_DIRSYNC и MS_SILENT при перементировании игнорируется без ошибки. Заметим, что изменения флагов суперблока видимы на всех точках монтирования файловой системы (так как флаги суперблока едины для всех точек монтирования).

Начиная с Linux 3.17, если не одно из значений MS_NOATIME, MS_NODIRATIME, MS_RELATIME, или MS_STRICTATIME не указано в mountflags , то при перемонтировании сохраняются текущие значения этих флагов (а не изменяются на значение по умолчанию MS_RELATIME).

Начиная с Linux 2.6.26, флаг MS_REMOUNT можно использовать вместе с MS_BIND для изменения только флагов, касающихся точки монтирования. В частности, это полезно для установки или сброса флага «только для чтения» на точке монтирования без изменения нижележащей файловой системы. При значении mountflags:

```
MS_REMOUNT | MS_BIND | MS_RDONLY
```

будет обеспечен доступ к этой точке монтирования в режиме только для чтения, без изменения других точек монтирования.

### Создание привязки монтирования
Если mountflags содержит MS_BIND (доступен, начиная с Linux 2.4), то выполняется привязка монтирования. Привязка монтирования делает видимым файл или поддерево каталогов в другой точке внутри одной иерархии каталогов. Привязки монтирования могут быть в разных файловых системах и перекрывают заключения chroot(2).

Аргументы filesystemtype и data игнорируются.

Остальные биты (кроме MS_REC, описано ниже) в аргументе mountflags также игнорируются. Однако посмотрите обсуждение перемонтирования, представленное выше, о том, как сделать существующую привязку монтирования доступной только для чтения.

По умолчанию, когда каталогу назначена привязка монтирования, монтируется только этот каталог; если существуют другие подмонтирования в дереве каталогов, то им не назначается привязка монтирования. Если также указан флаг MS_REC, то выполняется операция рекурсивной привязки монтирования: всем подмонтированиям в поддереве source (отличным от непривязываемых монтирований) также назначается привязка монтирования в соответствующее расположение к поддереве target.

### Изменение типа распространения существующего монтирования
Если mountflags содержит один из флагов MS_SHARED, MS_PRIVATE, MS_SLAVE, или MS_UNBINDABLE (все доступны начиная с Linux 2.6.15), то тип распространения существующего монтирования изменяется. Если указано сразу несколько из этих флагов, то возвращается ошибка.

При смене типа распространения можно изменять только флаги MS_REC (описан ниже) и MS_SILENT (игнорируется).

Аргументы source, filesystemtype и data игнорируются.

Назначение флагов типа распространения следующее:

MS_SHARED

Делает эту точку монтирования общей. События монтирования и размонтирования этой точки сразу же распространяются на другие точки монтирования, являющиеся членами её равноправной группы. Распространение здесь означает, что монтирование или размонтирование автоматически происходит и у всех остальных точек монтирования в равноправной группе. И наоборот, события монтирования и размонтирования, возникшие у точек монтирования равноправной группы, будут распространены и на эту точку монтирования.

MS_PRIVATE

События монтирования и размонтирования не распространяются в эту точку и от этой точки.

MS_SLAVE

Если это общая точка монтирования, которая является членом непустой равноправной группы, то она преобразуется в подчинённую точку монтирования. Если это общая точка монтирования, которая является членом пустой равноправной группы, то она преобразуется в индивидуальную точку. В противном случае тип распространения точки монтирования не изменяется.

Если точка монтирования подчинённая, то события монтирования и размонтирования распространяются на эту точку монтирования из (главной) общей равноправной группы, в которую она раньше входила. События монтирования и размонтирования этой точки не распространяются на членов группы.

Точка монтирования может быть подчинённой одной равноправной группе и в тоже время может распространять события в другую группу, где она является членом.

MS_UNBINDABLE

Делает эту точку монтирования непривязываемой. Она подобна индивидуальной точке монтирования плюс недоступна привязка монтирования. При рекурсивной привязке (mount() с флагами MS_BIND и MS_REC) в поддереве каталога все непривязываемые монтирования внутри поддерева автоматически удаляются (т. е., не копируются) при копировании этого поддерева для создания целевого поддерева.

По умолчанию, изменение типа распространения касается только target точки монтирования. Если в mountflags также указан флаг MS_REC, то тип распространения всех точек монтирования ниже target также изменяется.

Дополнительную информацию по типам распространения монтирования (включая тип распространения по умолчанию, назначаемый новым точкам монтирования) смотрите в mount_namespaces(7).

### Перемещение точки монтирования
Если в mountflags содержится флаг MS_MOVE (доступен, начиная с Linux 2.4.18), то перемещается поддерево: в source задаётся существующая точка монтирования, а target указывается новое расположение, в которое будет перемещена точка монтирования. Перемещение атомарно: поддерево всегда смонтировано.

Оставшиеся биты в аргументе mountflags игнорируются, как и аргументы filesystemtype и data.

### Создание новой точки монтирования
В том случае, если ни одно из значений MS_REMOUNT, MS_BIND, MS_MOVE, MS_SHARED, MS_PRIVATE, MS_SLAVE, или MS_UNBINDABLE не указано в mountflags, вызов mount() выполняет действие по умолчанию: создаёт новую точку монтирования. В source задаётся источник новой точки монтирования, а значение target указывает каталог, в котором будет создана точка монтирования.

Используются аргументы filesystemtype и data, дополнительные параметры для изменения поведения могут быть указаны в mountflags.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
Коды ошибок, описанные ниже, не зависят от типа файловой системы. У каждой файловой системы могут быть свои коды ошибок и своё собственное поведение. Подробности смотрите в исходном коде ядра Linux.

EACCES

Поиск запрещён из-за одной части пути, которая не доступна для просмотра и поиск (см. подробнее в path_resolution(7)).

EACCES

Было предпринята попытка монтирования файловой системы доступной только на чтение, но без флага ms_rdonly.

Файловая система может быть доступна только для чтения по разным причинам: она расположена на оптическом диске, доступном только для чтения; она располагается на устройстве с физической коммутацией, которое было отмечено как доступное только для чтения; реализация файловой системы скомпилирована с поддержкой только на чтение; обнаружены ошибки при первоначальном монтировании файловой системы, из-за чего она была помечена как доступная только для чтения и её невозможно перемонтировать как доступную для чтения/записи (пока не будут исправлены ошибки).

При попытке монтирования файловой системы только для чтениянекоторые файловые системы вместо этого возвращают ошибку EROFS.

EACCES

Блочное устройство source расположено в файловой системе, которая смонтирована с параметром MS_NODEV.

EBUSY

Попытка выполнить новое монтирование непосредственно поверх существующей точки монтирования, которая была создана в этом пространстве имён монтирования с тем же источником и назначением.

EBUSY

source не может быть перемонтирован с доступом только на чтение, потому что он все ещё содержит файлы, открытые для записи.

EFAULT

Один из аргументов-указателей указывает на каталог за пределами пользовательского адресного пространства.

EINVAL

источник имеет недоступный суперблок.

EINVAL

Была предпринята попытка перемонтирования (MS_REMOUNT), но source еще не был смонтирован в target.

EINVAL

Была предпринята попытка перемещения (MS_MOVE), но смонтированнное дерево в source содержит неотвязываемые (unbindable) монтирования и target является точкой монтирования с типом распространения MS_SHARED.

EINVAL

Была предпринята попытка перемещения (MS_MOVE), но родительское монтирование монтирования source является точкой монтирования с типом распространения MS_SHARED.

EINVAL

Была предпринята попытка перемещения (MS_MOVE), но source не являлся точкой монтирования или был '/'.

EINVAL

mountflags включает более одного значения из MS_SHARED, MS_PRIVATE, MS_SLAVE, или MS_UNBINDABLE.

EINVAL

mountflags включает MS_SHARED, MS_PRIVATE, MS_SLAVE, или MS_UNBINDABLE а также включает флаг, отличный от MS_REC или MS_SILENT.

EINVAL

Была попытка выполнить связанное монтирование, как несвязанное монтирование.

EINVAL

В непривилегированном пространстве имён монтирования (т. е., пространстве имён монтирования, принадлежащем пространству имён пользователя, которое было создано непривилегированным пользователем) выполнялась операция связанного монтирования (MS_BIND) без указания (MS_REC), которая привела бы к открытию дерева файловой системы, находящемся ниже одного из подмонтирований каталога, к которому выполнялось связывание.

ELOOP

Во время разбора имён найдено слишком много ссылок.

ELOOP

Сделана попытка перемещения, но цель оказалась подкаталогом источника.

EMFILE

(В случае, если не требуются блочные устройства): таблица фиктивных устройств переполнена.

ENAMETOOLONG

Значение пути длиннее чем MAXPATHLEN.

ENODEV

Тип из filesystemtype в ядре не настроен.

ENOENT

Указан пустой путь или одна из его частей не существует.

ENOMEM

Ядро не может выделить свободную страницу для копирования имени файла или данных.

ENOTBLK

Значение source не является блочным устройством (а устройство было запрошено).

ENOTDIR

Значение target или префикс source не является каталогом.

ENXIO

Старший номер блочного устройства source вне допустимого диапазона.

EPERM

Вызывающий процесс не имеет требуемых привилегий.

EROFS

Было предпринята попытка монтирования файловой системы доступной только на чтение без флага MS_RDONLY. Смотрите описание EACCES, приведённое выше.

## ВЕРСИИ
Определения MS_DIRSYNC, MS_MOVE, MS_PRIVATE, MS_REC, MS_RELATIME, MS_SHARED, MS_SLAVE, MS_STRICTATIME и MS_UNBINDABLE были добавлены в заголовочные файлы glibc начиная с версии 2.12.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данная функция есть только в Linux и не должна использоваться в программах, которые задуманы как переносимые.

## ЗАМЕЧАНИЯ
Начиная с Linux 2.4 одна файловая система может быть смонтирована в множество точек монтирования, также множественное монтирование может осуществляться в одну точку.

В верхних 16 битах аргумента mountflags может содержаться магическое число 0xC0ED (MS_MGC_VAL) (все остальные флаги из ОПИСАНИЯ находятся в младших 16 битах mountflags). Указание MS_MGC_VAL было требованием ядра до версии 2.4, но начиная с Linux 2.4 этого больше не нужно, и число игнорируется, если указано.

Изначальный флаг MS_SYNC был переименован в MS_SYNCHRONOUS в 1.1.69, когда в <mman.h> был добавлен другой флаг MS_SYNC.

До Linux 2.4 попытка выполнения программ set-UID или set-GID на файловой системе, подключённой с параметром MS_NOSUID, вызывает ошибку EPERM. Начиная с Linux 2.4 биты set-UID и set-GID в этом случае негласно игнорируются.

### Попроцессные пространства имён
Начиная с ядра версии 2.4.19, Linux предоставляет попроцессные пространства имён монтирования. Пространство имён монтирования — это набор смонтированных файловых систем, которые видимы процессу. Пространства имён точек монтирования могут (обычно так и есть) совместно использоваться несколькими процессами, и изменение пространства имён (т.е., монтирование и размонтирование) одним процессом видимы всеми остальными процессами, использующими одно общее пространство имён. (Поведение до версии 2.4.19 в Linux можно рассматривать так, как если бы всеми процессами в системе использовалось одно пространство имён.)

Процесс-потомок, создаваемый fork(2), использует родительское пространство имён монтирования совместно с родителем; пространство имён монтирования сохраняется при вызове execve(2).

Процесс может получить собственное пространство имён монтирования если: он был создан с помощью clone(2) с флагом CLONE_NEWNS; в этом случае его новое пространство имён инициализируется копией пространства имён процесса, который вызвал clone(2); или он вызовет unshare(2) с флагом CLONE_NEWNS; в этом случае пространство имён вызвавшего получит свою копию пространства имён, которое он раньше совместно использовал с другими процессами, и дальнейшие монтирования и размонтирования вызвавшим будут невидимы другим процессам (за исключением потомков, которые вызывающий создаст позже) и наоборот.

В файле /proc/[pid]/mounts (имеется только в Linux) отображается список точек монтирования в пространстве имён монтирования процесса с соответствующем ID. В файле /proc/[pid]/mountinfo отображается дополнительная информация о точках монтирования, включая тип распространения и информационный идентификатор монтирования, который позволяет обнаруживать связи между точками монтирования. Описание этих файлов смотрите в proc(5) и mount_namespaces(7).

## СМОТРИТЕ ТАКЖЕ
mountpoint(1), chroot(2), ioctl_iflags(2), pivot_root(2), umount(2), mount_namespaces(7), path_resolution(7), findmnt(8), lsblk(8), mount(8), umount(8)


package: man-pages-ru

title: move_pages(2)

text:
# move_pages(2)

## ИМЯ
move_pages - перемещает отдельные страницы процесса на другой узел

## ОБЗОР

```
#include <numaif.h>
```

```
long move_pages(int pid, unsigned long count, void **pages,
                const int *nodes, int *status, int flags);
```

Компонуется при указании параметра -lnuma.

## ОПИСАНИЕ
Вызов move_pages() перемещает указанные в pages страницы процесса с pid в память узлов, заданных в nodes. Результат перемещения отражается в status. В flags задаются ограничения на перемещаемые страницы.

Значение pid представляет собой идентификатор процесса, в котором перемещаются страницы. Если pid равен 0, то move_pages() перемещается страницы вызывающего процесса.

Для перемещения страниц в другом процессе требуются следующие права:

- В ядрах до Linux 4.12 включительно: вызывающий должен иметь права (CAP_SYS_NICE) или реальный или эффективный пользовательский ID вызывающего процесса должен совпадать с реальным или сохранённым пользовательским ID целевого процесса.

- Старые правила позволяли вызывающему обнаруживать различные виртуальные адреса, выбранные ядром, что лишает смысла случайность расположения раскладки адресного пространства процесса, принадлежащему тому же UID что и вызывающий; правила были изменены в Linux 4.13. Начиная с Linux 4.13, права регулируются проверкой режима доступа ptrace PTRACE_MODE_READ_REALCREDS целевого процесса; смотрите ptrace(2).

В аргументе count задаётся количество перемещаемых страниц. Он определяет размер трёх массивов: pages, nodes и status.

Аргумент pages представляет собой массив указателей на страницы, которые должны быть перемещены. Данные указатели должны быть выровнены на границу страницы. Адреса указываются в том же виде, в каком доступны процессу с заданным pid.

Аргумент nodes представляет собой массив целых, которыми задаются желаемые местоположения каждой страницы. Каждый элемент массива представляет собой номер узла. Также, значением nodes может быть NULL; в этом случае move_pages() не перемещает страницы, а записывает в массив status номер узла, на котором расположена каждая страница в данный момент. Получение состояния каждой страницы может потребоваться для определения страниц, которые нужно переместить.

Аргумент status представляет собой массив целых, которым определяется состояние каждой страницы. Массив содержит правильные значения только, если вызов move_pages() не завершился с ошибкой.

В аргументе flags указываются типы перемещаемых страниц. Флаг MPOL_MF_MOVE означает, что будут перемещены только страницы, которые монопольно используются процессом. Флаг MPOL_MF_MOVE_ALL означает, что также будут перемещены страницы, которые используются совместно с другими процессами. Для использования флага MPOL_MF_MOVE_ALL процесс должен быть привилегированным (CAP_SYS_NICE).

### Состояние страницы в массиве состояний
В каждом элементе массива status могут возвращаться следующие значения:

0..MAX_NUMNODES

Номер узла, в котором расположена страница.

-EACCES

Страница отображается несколькими процессами и может быть перемещена только, если указан флаг MPOL_MF_MOVE_ALL.

-EBUSY

Страница в данный момент занята и не может быть перемещена. Попробуйте позднее. Такое случается, если со страницей выполняется операция ввода-вывода или другая подсистема ядра удерживается ссылку на эту страницу.

-EFAULT

Это нулевая страница или область памяти не отображена процессом.

-EIO

Не удалось выполнить обратную запись на страницу. Для перемещения требуется выполнить обратную запись, так как данные страницы неактуальны (dirty), но файловая система не предоставляет функцию переноса (migration), которая позволила бы переместить неактуальные страницы.

-EINVAL

Нельзя переместить неактуальные страницы. Файловая система не предоставляет функцию переноса (migration), поэтому нет возможности выполнить обратную запись на страницы.

-ENOENT

Страница отсутствует.

-ENOMEM

Не удалось выделить память на узле назначения.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При нормальном завершении работы move_pages() возвращает ноль. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
E2BIG

Слишком много перемещаемых страниц. Начиная с Linux 2.6.29, ядро не генерирует эту ошибку.

EACCES

Один из узлов назначения не разрешён для текущего набора ЦП.

EFAULT

Недоступен массив параметров.

EINVAL

Указаны флаги, отличные от MPOL_MF_MOVE и MPOL_MF_MOVE_ALL, или предпринята попытка переместить (migrate) страницы нити ядра.

ENODEV

Один из узлов назначения недоступен (not online).

ENOENT

Не найдены страницы, которые требуется переместить. Все страницы или уже на узле назначения, отсутствуют, имеют неправильный адрес, или не могут быть перемещены, так как отображены несколькими процессами.

EPERM

Вызывающий указал флаг MPOL_MF_MOVE_ALL, но у него не хватает привилегий (CAP_SYS_NICE). Или вызывающий попытался переместить страницы процесса, принадлежащие другому пользователю, но не имеет привилегий для этого (CAP_SYS_NICE).

ESRCH

Процесс не существует.

## ВЕРСИИ
Вызов move_pages() впервые появился в Linux в ядре версии 2.6.18.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов есть только в Linux.

## ЗАМЕЧАНИЯ
Информация о библиотеке доступна в numa(7).

Используйте get_mempolicy(2) с флагом MPOL_F_MEMS_ALLOWED для получения набора узлов, которые доступны в текущем наборе ЦП. Заметим, что эта информация может измениться в любое время вручную или при автоматической перенастройке набора ЦП.

Использование этого вызова может привести к тому, что расположение страниц (на узле) нарушит политику памяти, установленную для заданных адресов (см. mbind(2)) и/или заданного процесса (см. set_mempolicy(2)). То есть политика памяти не ограничивает узлы назначения, используемые move_pages().

Заголовочный файл <numaif.h> не включён в glibc, его можно найти в пакете с именем libnuma-devel или подобным названием.

## СМОТРИТЕ ТАКЖЕ
get_mempolicy(2), mbind(2), set_mempolicy(2), numa(3), numa_maps(5), cpuset(7), numa(7), migratepages(8), numastat(8)


mprotect

title: mprotect(2)

summary: контролирует доступ к области памяти

text:
# mprotect(2)

## ИМЯ
mprotect, pkey_mprotect - контролирует доступ к области памяти

## ОБЗОР

```
#include <sys/mman.h>
```

```
int mprotect(void *addr, size_t len, int prot);
#define _GNU_SOURCE             /* смотрите feature_test_macros(7) */
#include <sys/mman.h>
```

```
int pkey_mprotect(void *addr, size_t len, int prot, int pkey);
```

## ОПИСАНИЕ
Вызов mprotect() изменяет параметры доступа страниц памяти вызывающего процесса, которые содержатся, даже частично, в адресном диапазоне [addr, addr+len-1]. Значение addr должно быть выровнено на границу страницы.

Если вызывающий процесс нарушает защиту доступа к памяти, то ядро посылает процессу сигнал SIGSEGV.

Значение prot представляет собой комбинацию следующих флагов доступа: PROT_NONE или побитово сложенные другие значения из следующего списка:

PROT_NONE

Доступ к памяти запрещён.

PROT_READ

Память можно читать.

PROT_WRITE

Память можно изменять.

PROT_EXEC

Память можно выполнять.

PROT_SEM (начиная с Linux 2.5.7)

Память можно использовать для атомарных операций. Этот флаг появился как часть реализации futex(2) (для гарантии способности выполнять атомарные операции, требуемые таким командам как FUTEX_WAIT), но пока не используется ни в одной архитектуре.

PROT_SAO (начиная с Linux 2.6.26)

Память должна иметь строгий порядок доступа. Это свойство есть только в архитектуре PowerPC (в спецификации архитектуры версии 2.06 добавлено свойство ЦП SAO и оно доступно, например, на POWER 7 или PowerPC A2).

Также (начиная с Linux 2.6.0), prot может содержать один из следующих установленных флагов:

PROT_GROWSUP

Применить режим защиты до конца отображения, которое растёт вверх (такие отображения создаются для области стека например в архитектуре HP-PARISC, где стек растёт вверх).

PROT_GROWSDOWN

Применить режим защиты до начала отображения, которое растёт вниз (которое должно быть сегментом стека или сегментом, отображённым с установленным флагом MAP_GROWSDOWN).

Подобно mprotect(), вызов pkey_mprotect() изменяет защиту страниц, указанных addr и len. Аргумент pkey содержит ключ защиты (смотрите pkeys(7)), назначаемый памяти. Ключ защиты должен быть выделен с помощью pkey_alloc(2) до передачи в pkey_mprotect(). Пример использования этого системного вызова смотрите в pkeys(7).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении mprotect() и pkey_mprotect() возвращают 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EACCES

Нельзя задать этот вид доступа. Например, это может случиться, если при вызове mmap(2) файл доступен только на чтение, а запрос mprotect() был PROT_WRITE.

EINVAL

Значение addr не является правильным указателем или не кратен размеру системной страницы.

EINVAL

(pkey_mprotect()) pkey не был выделен с помощью pkey_alloc(2).

EINVAL

В prot указаны оба флага, PROT_GROWSUP и PROT_GROWSDOWN.

EINVAL

Указано неверное значение в prot.

EINVAL

(архитектура PowerPC ) В prot указан PROT_SAO, но недоступно аппаратное свойство SAO.

ENOMEM

Не удалось выделить место под внутренние структуры ядра.

ENOMEM

Адреса в диапазоне [addr, addr+len-1] некорректны для адресного пространства процесса, или одна или более указанных страниц не отображена (до ядра версии 2.4.19 в этих случаях некорректно возвращалась ошибка EFAULT).

ENOMEM

Изменение защиты области памяти привело бы к превышению разрешённого максимума на количество отображений с различающимися атрибутами (защита на чтение и на чтение/запись). Например, защита диапазона PROT_READ в середине области, которая сейчас защищена PROT_READ|PROT_WRITE, привела бы к трём отображениям: два отображения на концах, доступных на чтение/запись и доступное только для чтение отображение посередине.

## ВЕРСИИ
Вызов pkey_mprotect() впервые появился в Linux 4.9; поддержка в библиотеке glibc добавлена в версии 2.27.

## СООТВЕТСТВИЕ СТАНДАРТАМ
mprotect(): В POSIX.1-2001, POSIX.1-2008, SVr4 сказано, что поведение mprotect() не определено, если переданная область памяти не получена через mmap(2).

Вызов pkey_mprotect является непереносимым расширением Linux.

## ЗАМЕЧАНИЯ
В Linux всегда можно вызвать mprotect() с любым адресом из адресного пространства процесса (за исключением области ядра vsyscall). В частности, это можно использовать для изменения отображений существующего кода на записываемые.

Отличается ли действие PROT_EXEC от PROT_READ зависит от архитектуры процессора, версии ядра и состояния процесса. Если в флагах специализаций процессора установлен READ_IMPLIES_EXEC (смотрите personality(2)), то указание PROT_READ подразумевает добавление PROT_EXEC.

На некоторых аппаратных архитектурах (например, i386) PROT_WRITE подразумевает PROT_READ.

В POSIX.1 сказано, что реализация может разрешить доступ отличный от указанного в prot, но для доступа на запись должен быть обязательно установлен флаг PROT_WRITE, и любой доступ должен быть запрещён, если установлен флаг PROT_NONE.

В приложениях нужно осторожно использовать mprotect() и pkey_mprotect() вместе. На x86, если mprotect() используется с установленным в prot значением PROT_EXEC, то pkey может быть выделен и установлен ядром в память неявным образом, но только если до этого pkey был равен 0.

В системах без аппаратной поддержки ключей защиты pkey_mprotect() всё ещё можно использовать, но значение pkey должно быть равно -1. При таком вызове операция pkey_mprotect() эквивалентна mprotect().

## ПРИМЕР
Программа, представленная далее, показывает использование mprotect(). Она выделяет четыре страницы памяти, делает третью доступной только на чтение, а затем запускает цикл, который проходит по выделенной области, меняя байты.

Результат работы программы:

```
$ ./a.out
Начало области:             0x804c000
Получен SIGSEGV при адресе: 0x804e000
```

### Исходный код программы

```
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#define handle_error(msg) \

    do { perror(msg); exit(EXIT_FAILURE); } while (0)
static char *buffer;
static void
handler(int sig, siginfo_t *si, void *unused)
{

    /* Замечание: вызов printf() из обработчика сигнала небезопасен

       (и не должен выполняться в готовых программах), так как

       printf() не async-signal-safe; смотрите signal-safety(7).

       Тем не менее, здесь мы используем printf(), так как это простой

       способ показать когда вызывается обработчик. */

    printf("Получен SIGSEGV при адресе: 0x%lx\n",

            (long) si->si_addr);

    exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{

    char *p;

    int pagesize;

    struct sigaction sa;

    sa.sa_flags = SA_SIGINFO;

    sigemptyset(&sa.sa_mask);

    sa.sa_sigaction = handler;

    if (sigaction(SIGSEGV, &sa, NULL) == -1)

        handle_error("sigaction");

    pagesize = sysconf(_SC_PAGE_SIZE);

    if (pagesize == -1)

        handle_error("sysconf");

    /* выделить буфер с выравниванием на границу страницы;

       начальная защита: PROT_READ | PROT_WRITE */

    buffer = memalign(pagesize, 4 * pagesize);

    if (buffer == NULL)

        handle_error("memalign");

    printf("Начало области:             0x%lx\n", (long) buffer);

    if (mprotect(buffer + pagesize * 2, pagesize,

                PROT_READ) == -1)

        handle_error("mprotect");

    for (p = buffer ; ; )

        *(p++) = 'a';

    printf("Цикл завершён\n");     /* никогда не должно случиться */

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
mmap(2), sysconf(3), pkeys(7)


title: mq_getsetattr(2)

text:
# mq_getsetattr(2)

## ИМЯ
mq_getsetattr - получить/установить атрибуты очереди сообщений

## ОБЗОР

```
#include <sys/types.h>
#include <mqueue.h>
```

```
int mq_getsetattr(mqd_t mqdes, struct mq_attr *newattr,
                 struct mq_attr *oldattr);
```

Замечание: В glibc нет обёрточной функции для данного системного вызова; смотрите ЗАМЕЧАНИЯ.

## ОПИСАНИЕ
Не используйте этот системный вызов.

Этот низкоуровневый системный вызов используется для реализации функций mq_getattr(3) и mq_setattr(3). Более подробно о работе этого системного вызова можно узнать на странице mq_setattr(3).

## СООТВЕТСТВИЕ СТАНДАРТАМ
Этот интерфейс является нестандартным, не используйте его.

## ЗАМЕЧАНИЯ
Glibc не предоставляет обертку (wrapper) для этого системного вызова; используйте syscall(2). (Даже не вызывайте его, если не пишете C библиотеку!)

## СМОТРИТЕ ТАКЖЕ
mq_getattr(3), mq_overview(7)


mremap

title: mremap(2)

text:
# mremap(2)

## ИМЯ
mremap - изменяет отображение адреса виртуальной памяти

## ОБЗОР

```
#define _GNU_SOURCE         /* смотрите feature_test_macros(7) */
#include <sys/mman.h>
```

```
void *mremap(void *old_address, size_t old_size,
             size_t new_size, int flags, ... /* void *new_address */);
```

## ОПИСАНИЕ
Вызов mremap() увеличивает (или уменьшает) размер существующего отображения памяти, при необходимости, перемещая его (это контролируется аргументом flags и доступным виртуальным адресным пространством).

В old_address указывается старый адрес блока виртуальной памяти, который вы хотите изменить. Заметим, что old_address должен быть выровнен по границе страницы. В old_size задаётся старый размер блока виртуальной памяти. В new_size задаётся запрашиваемый размер блока виртуальной памяти после изменения. Описание необязательного пятого аргумента new_address смотрите далее в параграфе о MREMAP_FIXED.

Если значение old_size равно нулю и old_address указывает на общее отображение (смотрите mmap(2) MAP_SHARED), то mremap() создаст новое отображение тех же страниц.Размер нового отображения будет равен значению new_size, а расположение можно указать в new_address; смотрите описание MREMAP_FIXED далее. Если новое отображение запрашивается через этот метод, то также должен быть указан флаг MREMAP_MAYMOVE.

В Linux память делится на страницы. Пользовательскому процессу выделяется один или несколько непрерывных сегментов виртуальной памяти. Каждый из этих сегментов имеет одно или несколько отображений в реальных страницах памяти (в таблице страниц). У каждого виртуального сегмента памяти есть своя защита (права доступа), которые можно нарушить, если произвести попытку некорректного доступа (например, записать информацию в сегмент, который доступен только для чтения). Доступ к виртуальной памяти за пределами сегментов также приводит к ошибке сегментации.

Вызов mremap() использует схему табличных страниц Linux. mremap() изменяет отображение между виртуальными адресами и страницами памяти. Это можно использовать при реализации очень эффективной функции realloc(3).

Аргумент битовой маски flags может быть равен 0 или содержать следующие флаги:

MREMAP_MAYMOVE

По умолчанию, если для расширения отображения недостаточно пространства в текущем расположении, то вызов mremap() завершается с ошибкой. Если указан флаг, то, если нужно, ядру разрешается переместить отображение на новый виртуальный адрес. Если отображение перемещено, то абсолютные указатели в старом расположении отображения становятся недействительными (должно быть выполнено смещение относительно начального адреса отображения).

MREMAP_FIXED (начиная с Linux 2.3.31)

Этот флаг играет ту же роль, что и MAP_FIXED для mmap(2). Если указан этот флаг, то mremap() учитывает пятый аргумент void *new_address, в котором задан выровненный на страницу адрес, куда должно быть перемещено отображение. Все предыдущие отображения в адресном диапазоне, задаваемом new_address и new_size, удаляются. При указании MREMAP_FIXED также должен быть указан MREMAP_MAYMOVE.

Если сегмент памяти, указанный old_address и old_size, заблокирован (с помощью mlock(2) или подобного вызова), то эта блокировка останется при изменении/перемещении сегмента. Следовательно, количество заблокированной процессом памяти может измениться.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении mremap() возвращается указатель на новую виртуальную область памяти. При ошибке, возвращается значение MAP_FAILED (то есть (void *) -1), а errno устанавливается в соответствующее значение.

## ОШИБКИ
EAGAIN

Вызывающий пытается расширить заблокированный сегмент памяти, но это невозможно без превышения предела ресурса RLIMIT_MEMLOCK.

EFAULT

«Ошибка сегментации (Segmentation fault).» Один из адресов в диапазоне от old_address до old_address+old_size является некорректным адресом виртуальной памяти для этого процесса. Также вы можете получить EFAULT даже если существующие отображения покрывают всё запрошенное адресное пространство, но имеют различные типы.

EINVAL

Указан недопустимый аргумент. Возможные причины:

- не выровнено значение адреса old_address;

- помимо MREMAP_MAYMOVE или MREMAP_FIXED в flags указано что-то ещё;

- значение new_size равно нулю;

- некорректное значение new_size или new_address;

- новый диапазон адресов, указанный new_address и new_size, перекрывает старый диапазон адресов, указанный old_address и old_size;

- задан MREMAP_FIXED без MREMAP_MAYMOVE;

- значение old_size равно нулю и old_address не указывает на общее отображение (но смотрите ДЕФЕКТЫ);

- значение old_size равно нулю и не указан флаг MREMAP_MAYMOVE.

ENOMEM

Область памяти не может быть расширена от текущего виртуального адреса и в flags не указано значение MREMAP_MAYMOVE. Или недостаточно свободной (виртуальной) памяти.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов существует только в Linux и не должен использоваться в программах, которые должны быть переносимыми.

## ЗАМЕЧАНИЯ
До версии 2.4, в glibc не был определён флаг MREMAP_FIXED, а прототип mremap() не позволял указывать аргумент new_address.

Если mremap() используется для перемещения или расширения области, заблокированной mlock(2) или эквивалентом, то вызов mremap() постарается заполнить новую область, но не завершится с ошибкой ENOMEM, если область невозможно заполнить.

## ДЕФЕКТЫ
До Linux 4.14, если old_size равно нулю и отображение, на которое указывает old_address — частное отображение (mmap(2) MAP_PRIVATE), то вызов mremap() создавал новое частное отображение, не относящееся к первоначальному отображению. Такое поведение не предусматривалось и, вероятно, не ожидается в приложениях пользовательского пространства (так предназначение mremap() — создание нового отображения на основе первоначального). Начиная с Linux 4.14, в этом случае mremap() завершается ошибкой EINVAL.

## СМОТРИТЕ ТАКЖЕ
brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), malloc(3), realloc(3)

Описание страничной памяти в вашей любимой книге по операционным системам (например, Современные операционные системы Эндрю С. Таненбаума, Внутри Linux Рэндольфа Бентсона, Архитектура операционной системы UNIX Мориса Дж. Баха)


msgctl

title: msgctl(2)

text:
# msgctl(2)

## ИМЯ
msgctl - операции для работы с сообщениями System V

## ОБЗОР

```
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
```

```
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
```

## ОПИСАНИЕ
Вызов msgctl() выполняет операцию, заданную в cmd, над очередью сообщений System V с идентификатором msqid.

Структура данных msqid_ds определена в <sys/msg.h> следующим образом:

```
struct msqid_ds {

    struct ipc_perm msg_perm;     /* владелец и права */

    time_t          msg_stime;    /* время последнего msgsnd(2) */

    time_t          msg_rtime;    /* время последнего msgrcv(2) */

    time_t          msg_ctime;    /* время последнего изменения */

    unsigned long   __msg_cbytes; /* текущее количество байт в

                                     очереди (нет в стандарте) */

    msgqnum_t       msg_qnum;     /* текущее количество сообщений

                                     в очереди */

    msglen_t        msg_qbytes;   /* максимальное количество байт

                                     для очереди */

    pid_t           msg_lspid;    /* PID последнего msgsnd(2) */

    pid_t           msg_lrpid;    /* PID последнего msgrcv(2) */
};
```

Структура ipc_perm определена следующим образом (значения полей устанавливаются с помощью IPC_SET):

```
struct ipc_perm {

    key_t          __key;       /* ключ, передаваемый в msgget(2) */

    uid_t          uid;         /* эффективный UID владельца */

    gid_t          gid;         /* эффективный GID владельца */

    uid_t          cuid;        /* эффективный UID создателя */

    gid_t          cgid;        /* эффективный GID создателя */

    unsigned short mode;        /* права */

    unsigned short __seq;       /* порядковый номер */
};
```

Возможные значения cmd:

IPC_STAT

Копирует информацию из структуры данных ядра, связанной с msqid, в структуру msqid_ds, расположенную по адресу buf. Вызывающий должен иметь права на чтение очереди сообщений.

IPC_SET

Записывает значения некоторых полей структуры msqid_ds, адрес которой указан в buf, в структуру данных ядра, связанную с этой очередью сообщений, обновляя при этом её поле msg_ctime. Обновляются следующие поля структуры: msg_qbytes, msg_perm.uid, msg_perm.gid и msg_perm.mode (младшие 9 бит). Эффективный UID вызывающего процесса должен совпадать с идентификатором владельца (msg_perm.uid) или создателя (msg_perm.cuid) очереди сообщений, или вызывающий должен иметь привилегии. Для указания значения msg_qbytes большего чем значение системного параметра MSGMNB также требуются соответствующие привилегии (Linux: мандат CAP_SYS_RESOURCE).

IPC_RMID

Немедленно удаляет очередь сообщений, «будя» все процессы, ожидающие записи или чтения этой очереди (при этом возвращается ошибка, а переменная errno приобретает значение EIDRM). Вызывающий процесс должен иметь соответствующие привилегии или его эффективный идентификатор пользователя должен совпадать с идентификатором создателя или владельца очереди сообщений. Третий аргумент msgctl() в этом случае игнорируется.

IPC_INFO (есть только в Linux)

Возвращает параметры и информацию о системных максимальных значениях очереди сообщений в структуре, указанной в buf. Данная структура имеет тип msginfo (то есть, требуется приведение типов) и определена в <sys/msg.h>, если определён макрос тестирования свойств _GNU_SOURCE:

```
struct msginfo {

    int msgpool; /* размер в килобайтах буферного пула,

                    используемого для хранения данных сообщения;

                    ядром не используется */

    int msgmap;  /* максимальное количество элементов в карте

                    сообщений; ядром не используется */

    int msgmax;  /* максимальное количество байт, которые могут быть

                    записаны в одно сообщение */

    int msgmnb;  /* максимальное количество байт, которое можно

                    записать в очередь; используется для инициализации

                    msg_qbytes во время создания очереди

                    (msgget(2)) */

    int msgmni;  /* максимальное количество очередей сообщений */

    int msgssz;  /* размер сегмента сообщения;

                    ядром не используется */

    int msgtql;  /* максимальное количество сообщений во всех очередях

                    в системе; ядром не используется */

    unsigned short int msgseg;

                 /* максимальное количество сегментов;

                    ядром не используется */
};

```

Значения msgmni, msgmax и msgmnb можно изменить с помощью файлов в /proc с теми же именами; подробней смотрите proc(5).

MSG_INFO (есть только в Linux)

Возвращает структуру msginfo, содержащую такую же информацию что и при операции IPC_INFO, за исключением того, что возвращаемые значения полей содержат информацию о системных ресурсах, потребляемых очередями сообщений: в поле msgpool возвращается количество очередей сообщений, которые в данный момент находятся в системе; в поле msgmap возвращается общее количество сообщений во всех очередях системы; в поле msgtql возвращается общее количество байт во всех сообщениях во всех очередях системы.

MSG_STAT (есть только в Linux)

Возвращает структуру msqid_ds как в операции IPC_STAT. Однако аргумент msqid является не уникальным идентификатором, а индексом во внутреннем массиве ядра, в котором содержится информации о всех очередях сообщений в системе.

MSG_STAT_ANY (есть только в Linux, начиная с Linux 4.17)

Возвращает структуру msqid_ds как для MSG_STAT. Однако msg_perm.mode не проверяется на доступность чтения для msqid, что означает, что эту операцию может выполнять пользователь (как и любой пользователь, который может прочитать эту же информацию из /proc/sysvipc/msg).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении IPC_STAT, IPC_SET и IPC_RMID возвращается 0. При успешном выполнении операции IPC_INFO или MSG_INFO возвращается индекс самого последнего использованного элемента во внутреннем массиве ядра, в котором записана информация о всех очередях сообщений. (Эта информация может быть использована при повторяющихся операциях MSG_STAT и MSG_STAT_ANY для получения информации о всех очередях системы.) При успешном выполнении операции MSG_STAT или MSG_STAT_ANY возвращается идентификатор очереди, чей индекс был указан в msqid.

В случае ошибки возвращается -1, а в errno записывается значение ошибки.

## ОШИБКИ
В случае возникновения ошибки errno может принимать следующие значения:

EACCES

Значение аргумента cmd равно IPC_STAT или MSG_STAT, но вызывающий процесс не имеет прав на чтение очереди сообщений msqid, и не имеет мандата CAP_IPC_OWNER в пространстве имён пользователя, которое управляет его пространством имён IPC.

EFAULT

Значение аргумента cmd равно IPC_SET или IPC_STAT, но адрес, указанный в buf, недоступен.

EIDRM

Очередь сообщений была удалена.

EINVAL

Неверное значение cmd или msqid. Или: для операции MSG_STAT значение индекса, указанного в msqid, ссылается на слот массива, который в данный момент не используется.

EPERM

Значение аргумента cmd равно IPC_SET или IPC_RMID, но эффективный пользовательский идентификатор вызывающего процесса не равен идентификатору создателя (msg_perm.cuid) или владельца (msg_perm.uid) очереди сообщений, и вызывающий не имеет прав (Linux: не имеет мандата CAP_SYS_ADMIN).

EPERM

Была предпринята попытка (IPC_SET) увеличить msg_qbytes и нарушить границы системного параметра MSGMNB, но вызывающий не имеет прав (Linux: не имеет мандата CAP_SYS_RESOURCE).

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4.

## ЗАМЕЧАНИЯ
Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.

Операции IPC_INFO, MSG_STAT и MSG_INFO используются программой ipcs(1) для получения информации о выделенных ресурсах. В будущем для этого может быть задействован интерфейс файловой системы /proc.

Различные поля в struct msqid_ds, которые имели тип short в Linux 2.2, в Linux 2.4 теперь имеют тип long. Чтобы воспользоваться этим преимуществом достаточно пересобрать программу с glibc-2.1.91 или более новой версией. (Ядро различает старые и новые вызовы по флагу IPC_64 в cmd.)

## СМОТРИТЕ ТАКЖЕ
msgget(2), msgrcv(2), msgsnd(2), capabilities(7), mq_overview(7), sysvipc(7)


msgget

title: msgget(2)

text:
# msgget(2)

## ИМЯ
msgget - возвращает идентификатор очереди сообщений System V

## ОБЗОР

```
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
```

```
int msgget(key_t key, int msgflg);
```

## ОПИСАНИЕ
Системный вызов msgget() возвращает идентификатор очереди сообщений System V, связанный со значением аргумента key. Его можно использовать для получения идентификатора уже созданной очереди сообщений (если msgflg равно нулю и значение key не равно IPC_PRIVATE) или для создания новой.

Новая очередь сообщений создаётся, если значение key равно IPC_PRIVATE, или если key не равно IPC_PRIVATE,не существует ни одной очереди сообщений с заданным ключом key и в поле msgflg указан флаг IPC_CREAT.

Если в msgflg одновременно заданы IPC_CREAT и IPC_EXCL и с таким key очередь сообщений уже существует, то msgget() завершится с ошибкой и errno будет равно EEXIST (тот же эффект как для комбинации O_CREAT | O_EXCL у open(2)).

При создании права доступа к очереди сообщений определяются младшими битами параметра msgflg. Эти биты прав имеют тот же формат и значение, что и права в аргументе mode у вызова open(2) (право на исполнение не используется).

Если создаётся новая очередь сообщений, то этот системный вызов инициализирует структуру данных msqid_ds (смотрите msgctl(2)) следующим образом:

Полям msg_perm.cuid и msg_perm.uid присваивается эффективный идентификатор пользователя вызывающего процесса.

Полям msg_perm.cgid и msg_perm.gid присваивается эффективный идентификатор группы вызывающего процесса.

Младшим 9 битам msg_perm.mode присваивается значение младших 9 битов msgflg.

msg_qnum, msg_lspid, msg_lrpid, msg_stime и msg_rtime присваивается 0.

В поле msg_ctime записывается текущее время.

В поле msg_qbytes записывается системное ограничение MSGMNB.

Если очередь сообщений уже существует, то проверяются права доступа к ней и не помечена ли она для удаления.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается идентификатор очереди сообщений (неотрицательное целое), иначе возвращается -1, а переменной errno присваивается номер ошибки.

## ОШИБКИ
При ошибке errno устанавливается в одно из следующих значений:

EACCES

Очередь сообщений для ключа key существует, но вызывающий процесс не имеет прав доступа к ней и не имеет мандата CAP_IPC_OWNER, который управляет его пространством имён IPC.

EEXIST

В msgflg указаны IPC_CREAT и IPC_EXCL, но очередь сообщений уже существует для key.

ENOENT

Для ключа key не существует очереди сообщений, но в msgflg нет флага IPC_CREAT.

ENOMEM

Очередь сообщений необходимо создать, но системе не хватает памяти для хранения новой структуры данных.

ENOSPC

Очередь сообщений необходимо создать, но лимит, определяющий количество очередей сообщений (MSGMNI), уже достигнут.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4.

## ЗАМЕЧАНИЯ
Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.

IPC_PRIVATE является не полем с флагами, а имеет тип key_t. Если при работе с key используется это специальное значение, то системный вызов игнорирует всё, кроме 9-ти младших битов в msgflg и создаёт новую очередь сообщений (если это возможно).

На вызов msgget() влияет системное ограничение по очередям сообщений:

MSGMNI

Системное ограничение на максимальное количество очередей сообщений. В системах Linux до версии 3.19, значением по умолчанию этого ограничения рассчитывалось на основе формулы зависящей от доступной системной памяти. Начиная с Linux 3.19, значение по умолчанию равно 32000. В Linux это ограничение можно прочитать и изменять через /proc/sys/kernel/msgmni).

### Замечания, касающиеся Linux
В Linux до версии 2.3.20 вызов msgget() возвращал значение EIDRM, если очередь сообщений была запланирована к удалению.

## ДЕФЕКТЫ
Имя IPC_PRIVATE, возможно, было выбрано неудачно, IPC_NEW отражает смысл действия более ясно.

## СМОТРИТЕ ТАКЖЕ
msgctl(2), msgrcv(2), msgsnd(2), ftok(3), capabilities(7), mq_overview(7), sysvipc(7)


msgop

title: msgop(2)

summary: операции с очередью сообщений System V

text:
# msgop(2)

## ИМЯ
msgrcv, msgsnd - операции с очередью сообщений System V

## ОБЗОР

```
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
```

```
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
```

```
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
               int msgflg);
```

## ОПИСАНИЕ
Системные вызовы msgsnd() и msgrcv() используются для отправки и получения сообщений из очереди сообщений System V. Вызывающий процесс должен иметь права на запись в очередь сообщений, чтобы отправлять сообщения и права на чтение для получения сообщений.

Аргумент msgp представляет собой указатель на структуру, определяемую вызывающим как:

```
struct msgbuf {

    long mtype;       /* тип сообщения, значение должно быть > 0 */

    char mtext[1];    /* данные сообщения */
};
```

Поле mtext является массивом (или другой структурой), размер которого определяется msgsz — неотрицательным целым значением. Разрешены сообщения нулевой длины (т.е. без поля mtext). Поле mtype должно быть только положительным целым значением. Это значение используется процессом-получателем для выбора сообщения (см. описание msgrcv() далее).

### msgsnd()
Системный вызов msgsnd() добавляет копию сообщения, указанного msgp, в очередь сообщений, идентификатор которой задаётся в msqid.

Если в очереди достаточно места, то msgsnd() сразу успешно завершается. Размер очереди управляется полем msg_qbytes в связанной структуре данных очереди сообщений. При создании очереди это поле инициализируется значением MSGMNB байт, но данное ограничение можно изменить с помощью msgctl(2). Очередь сообщений считается заполненной при одном из следующих условий:

- Добавление нового сообщения привело бы к превышению общего количества байт очереди над максимальным количеством размером очереди (поле msg_qbytes).

- Добавление другого сообщения привело бы к превышению общего количества сообщений очереди над максимальным количеством размером очереди (поле msg_qbytes). Эта проверка необходима для предотвращения помещения в очередь бесконечного количества сообщений нулевой длины. Хотя такие сообщения не содержат данных, тем не менее, они потребляют (блокируют) память ядра.

Если в очереди недостаточно места, то по умолчанию msgsnd() блокирует выполнение до появления свободного места. Если в msgflg указан IPC_NOWAIT, то вызов вместо этого завершается с ошибкой EAGAIN.

Заблокированный вызов msgsnd() может завершиться ошибкой если:

- очередь удалена (в этом случае системный вызов выдаст ошибку, определив errno в значение EIDRM;

- пойман сигнал; в этом случае системный вызов завершается с ошибкой и присваивает errno значение EINTR; см. signal(7). Вызов msgsnd() никогда не перезапускается автоматически после прерывания обработчиком сигнала, независимо от установки флага SA_RESTART при настройке обработчика сигнала.

Перед успешным завершением структура данных очереди сообщений будет обновлена следующим образом:

Значение msg_lspid устанавливается равным идентификатору вызывающего процесса.

Значение msg_qnum увеличивается на 1.

Значение msg_stime присваивается значение текущего времени.

### msgrcv()
Системный вызов msgrcv() удаляет сообщение из очереди, указанной в msqid и помещает его в буфер, указанный в msgp.

Параметр msgsz задаёт максимальный размер (в байтах) элемента mtext структуры, находящейся по адресу, указанному в аргументе msgp. Если длина текста сообщения больше чем msgsz, то поведение зависит от наличия флага MSG_NOERROR в msgflg. Если MSG_NOERROR указан, то текст сообщения будет урезан (а урезанная часть потеряна); иначе сообщение не удаляется из очереди, а системный вызов возвращает -1 и присваивает errno значение E2BIG.

Если в msgflg (смотрите ниже ) не указан MSG_COPY, то в аргументе msgtyp указывается тип запрашиваемого сообщения:

- Если msgtyp равно нулю, то читается первое сообщение в очереди.

- Если msgtyp больше нуля, то из очереди читается первое сообщение с типом msgtyp (если только в msgflg не указан MSG_EXCEPT. В этом случае из очереди читается первое сообщение, тип которого не равен msgtyp).

- Если msgtyp меньше нуля, то из очереди читается первое сообщение со значением, меньшим или равным абсолютному значению msgtyp.

Аргумент msgflg представляет собой битовую маску из комбинации нуля или более следующих флагов:

IPC_NOWAIT

Немедленный возврат, если в очереди нет сообщений необходимого типа. При этом системный вызов возвращает ошибку, присваивая errno значение ENOMSG.

MSG_COPY (начиная с Linux 3.8)

Забирает копию сообщения без удаления из начальной позиции в очереди, заданной в msgtyp (сообщения нумеруются начиная с 0).

Этот флаг должен указываться вместе с IPC_NOWAIT; в этом случае, если в заданной позиции сообщение отсутствует, то вызов завершается с ошибкой ENOMSG немедленно. Флаги MSG_COPY и MSG_EXCEPT не могут указываться вместе в msgflg, так как кардинально изменяют смысл msgtyp.

Флаг MSG_COPY был добавлен для реализации способности ядра для контрольных точек/восстановления и доступен только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

MSG_EXCEPT

Используется, если msgtyp больше 0, для чтения первого сообщения в очереди с типом, отличным от msgtyp.

MSG_NOERROR

Используется для урезания текста сообщения, если его размер больше msgsz байт.

Если в очереди нет сообщения необходимого типа и в msgflg не указан IPC_NOWAIT, то вызывающий процесс будет заблокирован до тех пор, пока не произойдет одно из следующих событий:

- В очередь не будет помещено сообщение необходимого типа.

- Очередь сообщений удалена из системы. В этом случае системный вызов возвращает ошибку и присваивает errno значение EIDRM.

- Вызывающий процесс не получит сигнал, который должен обработать. В этом случае системный вызов возвращает ошибку и присваивает переменной errno значение EINTR. Вызов msgrcv() никогда не перезапускается автоматически после прерывания обработчиком сигнала, независимо от установки флага SA_RESTART при настройке обработчика сигнала.

Перед успешным завершением структура данных очереди сообщений будет обновлена следующим образом:

Значение msg_lrpid устанавливается равным идентификатору вызывающего процесса.

Значение msg_qnum уменьшается на 1.

Значение msg_rtime становится равным текущему времени.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При ошибке оба вызова возвращают -1, а переменная errno приобретает соответствующее значение. В противном случае msgsnd() возвращает 0, а msgrcv() возвращает количество байтов, скопированных в массив mtext.

## ОШИБКИ
Значения errno, устанавливаемые при возникновении ошибок в msgsnd():

EACCES

Вызывающий процесс не имеет прав записи в очередь сообщений и не имеет мандата CAP_IPC_OWNER в пользовательском пространстве имён, которое управляет его пространством имён IPC.

EAGAIN

Сообщение не может быть отправлено, так как размер очереди превысит лимит, равный msg_qbytes, а в параметре msgflg установлен флаг IPC_NOWAIT.

EFAULT

Память с адресом, указанным msgp, недоступна.

EIDRM

Очередь сообщений была удалена.

EINTR

Процесс ждал свободного места в очереди и получил сигнал, который должен обработать.

EINVAL

Задано неправильное значение msqid, не положительное значение mtype или неправильное значение msgsz (меньше 0, или больше системного лимита, заданного MSGMAX).

ENOMEM

Недостаточно памяти в системе для копирования сообщения, указанного msgp.

Значения errno, устанавливаемые при возникновении ошибок в msgrcv():

E2BIG

Длина текста получаемого сообщения больше, чем msgsz, а в поле msgflg не установлен флаг MSG_NOERROR.

EACCES

Вызывающий процесс не имеет прав чтобы прочитать очереди сообщений и не имеет мандата CAP_IPC_OWNER в пространстве имён пользователя, который управляет его пространством имён IPC.

EFAULT

Память с адресом, указанным msgp, недоступна.

EIDRM

Процесс ждал приёма сообщения, и в это время очередь сообщений была удалена.

EINTR

Во время ожидания приёма сообщения процесс получил сигнал; см. signal(7).

EINVAL

Неверное значение msqid или msgsz меньше 0.

EINVAL (начиная с Linux 3.14)

В msgflg указан флаг MSG_COPY, но нет IPC_NOWAIT.

EINVAL (начиная с Linux 3.14)

В msgflg указаны MSG_COPY и MSG_EXCEPT.

ENOMSG

В очереди нет сообщения необходимого типа, а в параметре msgflg установлен флаг IPC_NOWAIT.

ENOMSG

Флаги IPC_NOWAIT и MSG_COPY указаны в msgflg, но в очереди содержится меньше msgtyp сообщений.

ENOSYS (начиная с Linux 3.8)

Флаг MSG_COPY указан в msgflg, но ядро собрано без параметра CONFIG_CHECKPOINT_RESTORE.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4.

Флаги MSG_EXCEPT и MSG_COPY есть только в Linux; их определения можно получить указав макрос тестирования свойств _GNU_SOURCE.

## ЗАМЕЧАНИЯ
Включение файлов <sys/types.h> и <sys/ipc.h> не требуется в Linux или любых версий POSIX. Однако, некоторые старые реализации требуют включения данных заголовочных файлов, и это также требуется по SVID. В приложениях, которые нужно перенести на такие старые системы, может потребоваться включить данных заголовочные файлы.

Аргумент msgp в glibc 2.0 и 2.1 объявлен как struct msgbuf *. В glibc 2.2 и новее, в соответствии с SUSv2 и SUSv3, он объявлен как void *.

На работу системного вызова msgsnd() влияют следующие системные ограничения на ресурсы очереди сообщений:

MSGMAX

Максимальный размер текста сообщения: по умолчанию он равен 8192 байтам (в Linux это ограничение можно прочитать и изменить через /proc/sys/kernel/msgmax).

MSGMNB

Максимальное количество байт, которое может храниться в очереди сообщений (по умолчанию 16384 байт). В Linux это ограничение можно прочитать и изменить через /proc/sys/kernel/msgmnb. Привилегированный процесс (Linux: процесс с мандатом CAP_SYS_RESOURCE) может устанавливать размер очереди сообщений больше чем MSGMNB при помощи вызова msgctl() с операцией IPC_SET.

Реализация не накладывает существенных системных ограничений на максимальное количество заголовков сообщений (MSGTQL) и на количество байт в пуле сообщений (MSGPOOL).

## ДЕФЕКТЫ
В Linux 3.13 и старее, если msgrcv() был вызван с флагом MSG_COPY flag, но без IPC_NOWAIT, и очередь сообщений содержала менее msgtyp сообщений, то вызов блокировал выполнения до тех пор, пока следующее сообщение не записывалось в очередь. written to the queue. В этот момент вызов возвращал копию сообщения, независимо от того, что сообщение было в начальной позиции msgtyp. Этот дефект был исправлен в Linux 3.14.

Указание обоих флагов MSG_COPY и MSC_EXCEPT в msgflg является логической ошибкой (так как для флагов по-разному интерпретируется msgtyp). В Linux 3.13 и старее эта ошибка не определялась msgrcv(). Этот дефект был исправлен в Linux 3.14.

## ПРИМЕР
Представленная ниже программа показывает использование msgsnd() и msgrcv().

В первый раз программа запускается с параметром -s для отправки сообщения, а в второй — с параметром -r для получения сообщения.

Пример сеанса работы с программой:

```
$ ./a.out -s
отправка: дата сообщения Wed Mar  4 16:25:45 2015
$ ./a.out -r
приём: дата сообщения Wed Mar  4 16:25:45 2015
```

### Исходный код программы

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {

    long mtype;

    char mtext[80];
};
static void
usage(char *prog_name, char *msg)
{

    if (msg != NULL)

        fputs(msg, stderr);

    fprintf(stderr, "Использование: %s [параметры]\n", prog_name);

    fprintf(stderr, "Параметры:\n");

    fprintf(stderr, "-s        отправить сообщение с помощью msgsnd()\n");

    fprintf(stderr, "-r        прочитать сообщение с помощью msgrcv()\n");

    fprintf(stderr, "-t        тип сообщения (по умолчанию 1)\n");

    fprintf(stderr, "-k        ключ очереди сообщения (по умолчанию 1234)\n");

    exit(EXIT_FAILURE);
}
static void
send_msg(int qid, int msgtype)
{

    struct msgbuf msg;

    time_t t;

    msg.mtype = msgtype;

    time(&t);

    snprintf(msg.mtext, sizeof(msg.mtext), "дата сообщения %s",

            ctime(&t));

    if (msgsnd(qid, (void *) &msg, sizeof(msg.mtext),

                IPC_NOWAIT) == -1) {

        perror("msgsnd error");

        exit(EXIT_FAILURE);

    }

    printf("отправка: %s\n", msg.mtext);
}
static void
get_msg(int qid, int msgtype)
{

    struct msgbuf msg;

    if (msgrcv(qid, (void *) &msg, sizeof(msg.mtext), msgtype,

               MSG_NOERROR | IPC_NOWAIT) == -1) {

        if (errno != ENOMSG) {

            perror("msgrcv");

            exit(EXIT_FAILURE);

        }

        printf("С помощью msgrcv() сообщений не получено\n");

    } else

        printf("приём: %s\n", msg.mtext);
}
int
main(int argc, char *argv[])
{

    int qid, opt;

    int mode = 0;               /* 1 = send, 2 = receive */

    int msgtype = 1;

    int msgkey = 1234;

    while ((opt = getopt(argc, argv, "srt:k:")) != -1) {

        switch (opt) {

        case 's':

            mode = 1;

            break;

        case 'r':

            mode = 2;

            break;

        case 't':

            msgtype = atoi(optarg);

            if (msgtype <= 0)

                usage(argv[0], "параметр -t должен быть больше 0\n");

            break;

        case 'k':

            msgkey = atoi(optarg);

            break;

        default:

            usage(argv[0], "Неизвестный параметр\n");

        }

    }

    if (mode == 0)

        usage(argv[0], "нужно указать параметр -s или -r\n");

    qid = msgget(msgkey, IPC_CREAT | 0666);

    if (qid == -1) {

        perror("msgget");

        exit(EXIT_FAILURE);

    }

    if (mode == 2)

        get_msg(qid, msgtype);

    else

        send_msg(qid, msgtype);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
msgctl(2), msgget(2), capabilities(7), mq_overview(7), sysvipc(7)


msync

title: msync(2)

text:
# msync(2)

## ИМЯ
msync - синхронизирует содержимое файла с его отображением в памяти

## ОБЗОР
\#include <sys/mman.h>

int msync(void *addr, size_t length, int flags);

## ОПИСАНИЕ
Вызов msync() сбрасывает изменения файла, который отображён в память с помощью mmap(2), обратно в файловую систему. Без использования этого вызова нет никакой гарантии, что изменения будут записаны в файл до вызова munmap(2). Если быть точнее, то на диск записывается часть файла, начинающаяся в памяти с адреса addr длиной length.

В аргументе flags должен быть один из флагов MS_ASYNC и MS_SYNC, а также дополнительно можно указать MS_INVALIDATE. Данные биты имеют следующее значение:

MS_ASYNC

Запланировать обновление, но вызов завершается сразу.

MS_SYNC

Запланировать обновление и ждать его завершения.

MS_INVALIDATE

Считать недействительными другие отображения того же файла (для того, чтобы они могли обновиться до достоверных значений, которые запишутся).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EBUSY

В flags указан MS_INVALIDATE, но на указанный адресный диапазон есть блокировка в памяти.

EINVAL

Значение addr не кратно PAGESIZE; в flags установлен любой другой бит, отличный от MS_ASYNC | MS_INVALIDATE | MS_SYNC; в flags установлены сразу MS_SYNC и MS_ASYNC.

ENOMEM

Указанная память (или её часть) не была отображена.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

Этот вызов появился в Linux 1.3.21, и в нём использовалось EFAULT вместо ENOMEM. В Linux 2.4.19 это было изменено на значение POSIX ENOMEM.

## ДОСТУПНОСТЬ
В системах POSIX, в которых доступен msync(), значения _POSIX_MAPPED_FILES и _POSIX_SYNCHRONIZED_IO, определённые в <unistd.h>, больше нуля. (См. также sysconf(3).)

## ЗАМЕЧАНИЯ
Согласно POSIX, в flags должен быть указан или MS_SYNC, или MS_ASYNC и отказ включить один из этих флагов вызывает ошибку в msync() на некоторых системах. Однако Linux позволяет вызывать msync() без этих флагов, используя семантику, которая (в настоящее время) эквивалентна указанию MS_ASYNC (начиная с Linux 2.6.19, MS_ASYNC, фактически, ничего не делает, так как ядро правильно отслеживает грязные страницы и записывает их в место хранения при необходимости). Несмотря на поведение Linux, в переносимых, ориентированных на будущее приложениях в flags должен быть указан или MS_SYNC, или MS_ASYNC.

## СМОТРИТЕ ТАКЖЕ
mmap(2)

B.O. Gallmeister, POSIX.4, O'Reilly, страницы 128–129 и 389–391.


nanosleep

title: nanosleep(2)

text:
# nanosleep(2)

## ИМЯ
nanosleep - остановка работы процесса с более точным указанием периода

## ОБЗОР
\#include <time.h>

int nanosleep(const struct timespec *req, struct timespec *rem);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

nanosleep(): _POSIX_C_SOURCE >= 199309L

## ОПИСАНИЕ
nanosleep() приостанавливает работу вызывающей нити как минимум на время, заданное параметром *req, или до получения сигнала, который вызовет обработчик в вызывающей нити, или приведёт к завершению процесса.

Если вызов прерван обработчиком сигнала, то nanosleep() возвращает -1, устанавливает errno в значение EINTR и записывает оставшееся время в структуру, на которую указывает rem, если значение rem не равно NULL. Значение *rem можно использовать для повторения вызова nanosleep() и продления окончания ожидания интервала (но см. ЗАМЕЧАНИЯ).

Структура timespec позволяет задавать интервалы времени с точностью до наносекунды. Она определена следующим образом:

```
struct timespec {

    time_t tv_sec;        /* секунды */

    long   tv_nsec;       /* наносекунды */
};
```

Значение поля наносекунд должно находиться в диапазоне от 0 до 999999999.

По сравнению с sleep(3) и usleep(3), в nanosleep() есть следующие достоинства: он позволяет задавать более точные интервалы времени, в POSIX.1 явно определено то, что он не влияет на сигналы, и позволяет более лёгким способом возобновить паузу после прерывания сигналом.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При удачной остановке на заданное время возвращаемое nanosleep() значение равно нулю. Если вызов прерван обработчиком сигнала или произошла ошибка, то возвращается -1, а переменной errno присваивается номер ошибки.

## ОШИБКИ
EFAULT

Проблема с копированием информации из пространства пользователя.

EINTR

Пауза была прервана сигналом, отправленным нити (смотрите signal(7)). Оставшееся время записано в *rem для того, чтобы нить могла вызвать nanosleep() снова для возобновления паузы.

EINVAL

Значение поля tv_nsec не находится в интервале от 0 до 999999999 или tv_sec содержит отрицательное число.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ЗАМЕЧАНИЯ
Если интервал, указанный в req, не кратен степени разрешения используемых часов (см. time(7)), то интервал будет округлён до следующего кратного значения. Также, после окончания интервала приостановки может возникнуть задержка перед тем, как ЦП освободится снова для следующего выполнения вызывающей нити.

Тот факт, что nanosleep() вызывает приостановку на относительный интервал, может привести к проблемам, если вызов постоянно перезапускается после прерывания по сигналу, так как время между прерываниями и перезапуском вызова будет приводить к временному смещению полного завершения приостановки. Этой проблемы можно избежать, если использовать clock_nanosleep(2) с абсолютными величинами времени.

В POSIX.1 указано, что nanosleep() должен измерять время по часам CLOCK_REALTIME. Однако, в Linux время измеряется с помощью часов CLOCK_MONOTONIC. Это, скорее всего, не важно, так как в спецификации POSIX.1 для clock_settime(2) указано, что быстро происходящие изменения в CLOCK_REALTIME не должны влиять на nanosleep():

Установка значения часов CLOCK_REALTIME с помощью clock_settime(2) не оказывает влияния на нити, которые находятся в состоянии простоя из-за служб, работа которых основана на этих часах, включая функцию nanosleep(); ... В результате, интервал данных служб истечёт, когда истечёт запрошенный относительный интервал, независимо от нового или старого значения часов.

### Старое поведение
Для поддержки приложений, которым требуется указывать более точное время простоя (например, чтобы управлять оборудованием, критичным к временным интервалам), nanosleep() выдерживает время простоя до 2 мс с микросекундной точностью, если вызывается из нити, запланированной выполняться в реальном времени с помощью SCHED_FIFO или SCHED_RR. Это специальное расширение было удалено из ядра 2.5.39, и поэтому недоступно в Linux версии 2.6.0 и более новых ядрах.

## ДЕФЕКТЫ
Если программа, обрабатывающая сигналы и использующая nanosleep(), принимает сигналы с очень высокой частотой, то возникают задержки планирования и ошибки округления в ядерных подсчётах интервала сна и возвращается значение остатка, на которое можно уверенно увеличивать интервал при последующем перезапуске вызова nanosleep(). Чтобы избежать таких проблем используйте clock_nanosleep(2) с флагом TIMER_ABSTIME, чтобы спать до абсолютного конечного срока.

В Linux 2.4, если nanosleep() останавливается по сигналу (например, SIGTSTP), то после того, как нить продолжит работу по сигналу SIGCONT, вызов завершится неудачно с ошибкой EINTR. Если системный вызов после этого перезапускается, то время, которое нить провела в остановленном состоянии, не учитывается в интервале остановки. Эта проблема исправлена в Linux 2.6.0 и новее.

## СМОТРИТЕ ТАКЖЕ
clock_nanosleep(2), restart_syscall(2), sched_setscheduler(2), timer_create(2), sleep(3), usleep(3), time(7)


nfsservctl

title: nfsservctl(2)

summary: интерфейс syscall к ядерной службе nfs

text:
# nfsservctl(2)

## ИМЯ
nfsservctl - интерфейс syscall к ядерной службе nfs

## ОБЗОР

```
#include <linux/nfsd/syscall.h>
```

```
long nfsservctl(int cmd, struct nfsctl_arg *argp,
                union nfsctl_res *resp);
```

## ОПИСАНИЕ
Замечание: Начиная с Linux 3.1, данный системный вызов больше не существует. Он был заменён набором файлов в файловой системе nfsd; смотрите nfsd(7).

```
/*

 * Эти команды понимает nfsctl()

 */
#define NFSCTL_SVC        0  /* это серверный процесс */
#define NFSCTL_ADDCLIENT  1  /* добавить клиента NFS */
#define NFSCTL_DELCLIENT  2  /* удалить клиента NFS */
#define NFSCTL_EXPORT     3  /* экспортировать файловую систему */
#define NFSCTL_UNEXPORT   4  /* снять экспорт файловой системы */
#define NFSCTL_UGIDUPDATE 5  /* обновить карту клиентов UID/GID

                                (только в Linux 2.4.x и старее) */
#define NFSCTL_GETFH      6  /* получить описатель файла (используется mountd)

                                (только в Linux 2.4.x и старее). */
struct nfsctl_arg {

    int                       ca_version;     /* защитная мера */

    union {

        struct nfsctl_svc     u_svc;

        struct nfsctl_client  u_client;

        struct nfsctl_export  u_export;

        struct nfsctl_uidmap  u_umap;

        struct nfsctl_fhparm  u_getfh;

        unsigned int          u_debug;

    } u;
}
union nfsctl_res {

        struct knfs_fh          cr_getfh;

        unsigned int            cr_debug;
};
```

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ВЕРСИИ
Данный системный вызов был удалён из ядра Linux в версии 3.1. Поддержка в библиотеке glibc была удалена в версии 2.28.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов существует только в Linux.


nice

title: nice(2)

summary: изменяет приоритет процесса

text:
# nice(2)

## ИМЯ
nice - изменяет приоритет процесса

## ОБЗОР
\#include <unistd.h>

int nice(int inc);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

nice(): _XOPEN_SOURCE

|| /* начиная с glibc 2.19: */ _DEFAULT_SOURCE

|| /* версии glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

## ОПИСАНИЕ
Вызов nice() добавляет значение аргумента inc к значению уступчивости (nice) вызвавшей нити (большее значение уступчивости означает меньший приоритет).

Диапазон значений уступчивости: от +19 (низкий приоритет) до -20 (высокий приоритет). Попытки установить значение уступчивости вне этого диапазона срезаются до значения из этого диапазона.

Обычно, только привилегированный процесс может понижать значение уступчивости (т. е., повышать приоритет). Однако начиная с Linux 2.6.12 непривилегированный процесс может понизить значение уступчивости процесса назначения, у которого установлено подходящее мягкое ограничение RLIMIT_NICE; подробности смотрите в getrlimit(2).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается новое значение nice (но см. ЗАМЕЧАНИЯ далее). В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

При успешном выполнении с полным основанием может вернуть -1. Для обнаружения ошибки перед вызовом присвойте errno значение 0 и проверьте, что оно не равно нулю после возврата nice() значения -1.

## ОШИБКИ
EPERM

Вызывающий процесс пытается увеличить свой приоритет, указав отрицательное значение inc, но не имеет для этого прав. В Linux для этого требуется мандат CAP_SYS_NICE (но смотрите обсуждение ограничение ресурса RLIMIT_NICE в setrlimit(2)).

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr, 43BSD. Однако системный вызов и функция (g)libc (до glibc 2.2.4) возвращали нестандартное значение, смотрите далее.

## ЗАМЕЧАНИЯ
Дополнительную информацию о значении уступчивости смотрите в sched(7).

Замечание: дополнительное свойство «autogroup» из Linux 2.6.38 означает, что значение уступчивости во многих случаях больше не работает как обычно. Подробней смотрите в sched(7).

### Отличия между библиотекой C и ядром
В POSIX.1 указано, что nice() должен возвращать новое значение уступчивости. Однако, системный вызов Linux при успешном выполнении возвращает 0. Таким же образом поступает обёрточная функция nice() из glibc 2.2.3 и старее.

Начиная с glibc 2.2.4, обёрточная функция nice() из glibc, поступает в соответствии с POSIX.1, вызывая getpriority(2) для получения нового значения уступчивости, которое возвращается вызывающему.

## СМОТРИТЕ ТАКЖЕ
nice(1), renice(1), fork(2), getpriority(2), getrlimit(2), setpriority(2), capabilities(7), sched(7)