title: mount_namespaces(7)

text:
# mount_namespaces(7)

## ИМЯ
mount_namespaces - обзор пространств имён монтирования в Linux

## ОПИСАНИЕ
Обзор пространств имён смотрите в namespaces(7).

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

Данные файлов /proc/[pid]/mounts, /proc/[pid]/mountinfo и /proc/[pid]/mountstats (описаны в proc(5)) соответствуют пространству имён монтирования, в котором расположен процесс с PID [pid] (для всех процессов, которые расположены в одном пространстве имён монтирования, данные в этих файлах одинаковы).

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

### Ограничения у пространств имён монтирования
Отметим следующие моменты относительно пространств имён монтирования:

- Владельцем пространства имён монтирования является владелец пользовательского пространство имён. Пространство имён монтирования, чей владелец пользовательского пространства имён отличается от владельца пользовательского пространства имён родительского пространства имён монтирования, считается менее привилегированным пространством имён монтирования.

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

- Точки монтирования, которые появились как единый блок из более привилегированного монтирования, объединяются и не могут быть разделены в менее привилегированном пространстве имён монтирования (операция unshare(2) CLONE_NEWNS переносит все точки монтирования из исходного пространства имён монтирования единым блоком и рекурсивные монтирования, которые передаются в нескольких пространствах имён монтирования, также единым блоком).

- Значения флагов MS_RDONLY, MS_NOSUID, MS_NOEXEC у mount(2) и флагов «atime» (MS_NOATIME, MS_NODIRATIME, MS_RELATIME) блокируются при передаче из более привилегированного в менее привилегированное пространство имён монтирования, и не могут быть изменены в менее привилегированном пространстве имён монтирования.

- Файл или каталог, являющийся точкой монтирования в одном пространстве имён, и не являющийся в другом, может быть переименован, отсоединён (unlinked) или удалён (rmdir(2)) в пространстве имён монтирования, в котором он не является точкой монтирования (выполняются обычные проверки прав доступа).При этом точка монтирования удаляется в пространстве имён монтирования, в котором она была точкой монтирования.

Раньше (до Linux 3.18), попытка переименовать, отсоединить или удалить файл или каталог, который являлся точкой монтирования в другом пространстве имён монтирования, приводила к ошибке EBUSY. Такое поведение вызывало технические проблемы в работе (например, NFS) и позволяло выполнять атаку отказа в обслуживании более привилегированных пользователей (т. е., не давало обновлять отдельные файлы посредством монтирования поверх их).

## ОБЩИЕ ПОДДЕРЕВЬЯ
После завершения реализации пространств имён монтирования опыт использования показал, что полученная изоляция, в некоторых случаях, слишком велика. Например, чтобы только что смонтированный оптический диск сделать доступным в во всех пространствах имён, требуется операция монтирования в каждом пространстве имён. Для этого случаях и других в Linux 2.6.15 были добавлены общие поддеревья. Это свойство предоставляет автоматическое, управляемое распространение событий монтирования и размонтирования в пространствах имён (или, точнее, между членами равноправной группы, которые обмениваются событиями между собой).

Каждая точка монтирования помечается (в mount(2)) одним из следующих типов распространения:

MS_SHARED

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

MS_PRIVATE

Данная точка монтирования индивидуальна; у неё нет равноправной группы. События монтирования и размонтирования не распространяются от этой точки и на эту точку.

MS_SLAVE

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

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

MS_UNBINDABLE

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

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

Описание типа распространения, назначаемого на новое монтирование, смотрите в ЗАМЕЧАНИЯХ.

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

Заметим, что тип распространения монтирования определяет, будет ли монтирование или размонтирование распространяться точки монтирования, находящиеся на одну ступень ниже точки, где возникло событие. То есть, тип распространения не влияет на распространение событий для внуков и в дальнейшем удаляемых потомков точки монтирования. Это случается, если сама точка монтирования размонтируется из-за действия типа распространения который, в сущности, влияние родительской точки монтирования.

Члены добавляются в равноправную группу, если точка монтирования помечается как общая, или:

- точка монтирования копируется при создании нового пространства имён монтирования

- создаётся новая привязка из точки монтирования

В обоих случаях новая точка монтирования присоединяется к равноправной группе, в которую входит существующая точка монтирования.

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

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

Тип распространения точек монтирования в пространстве имён монтирования может узнать через «необязательные поля» в файле /proc/[pid]/mountinfo (описание файла смотрите в proc(5)). В необязательных полях этого файла могут появляться следующие метки:

shared:X

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

master:X

Эта точка монтирования является подчинённой общей равноправной группе X.

propagate_from:X (начиная с Linux 2.6.26)

Эта точка монтирования является подчинённой и принимает события от общей равноправной группы X. Данная метка всегда появляется вместе с меткой master:X. Здесь X это ближайшая главенствующая равноправная группа из корневого каталога процесса. Если X является непосредственным владельцем точки монтирования, или в том же корне нет ближайшей главенствующей равноправной группы, то существует только поле master:X, и поле propagate_from:X отсутствует. Подробности смотрите ниже.

unbindable

Точка монтирования является непривязываемой.

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

### Пример MS_SHARED и MS_PRIVATE
Предположим, что на терминале в первоначальном пространстве имён монтирования мы помечаем одну точку монтирования как общую, а другую — как индивидуальную, и затем смотрим точки монтирования в /proc/self/mountinfo:

```
sh1# mount --make-shared /mntS
sh1# mount --make-private /mntP
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
77 61 8:17 / /mntS rw,relatime shared:1
83 61 8:15 / /mntP rw,relatime
```

Из вывода /proc/self/mountinfo мы видим, что /mntS является общей точкой монтирования в равноправной группе 1, и что /mntP не имеет необязательных меток, то есть это индивидуальная точка монтирования. Первые два поля в каждой записи этого файла содержат уникальный идентификатор этой точки монтирования и идентификатор точки монтирования родительской точки монтирования. Далее в файле мы видим, что родительская точка монтирования /mntS и /mntP является корневым каталогом, /, которая смонтирована как индивидуальная:

```
sh1# cat /proc/self/mountinfo | awk '$1 == 61' | sed 's/ - .*//'
61 0 8:2 / / rw,relatime
```

На втором терминале мы создаём новое пространство имён монтирования, в котором запускаем вторую оболочку, и смотрим точки монтирования:

```
$ PS1='sh2# ' sudo unshare -m --propagation unchanged sh
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
222 145 8:17 / /mntS rw,relatime shared:1
225 145 8:15 / /mntP rw,relatime
```

Новое пространство имён монтирования получает копию точек монтирования из начального пространства имён монтирования. Эти новые точки монтирования имеют тот же тип распространения, но другие уникальные идентификаторы монтирования (при создании нового пространства имён монтирования передача параметра --propagation unchanged программе unshare(1) не даёт помечать все точки монтирования как индивидуальные (что делается по умолчанию)).

Далее на втором терминале мы создаём подмонтирования в каталоге /mntS и /mntP и смотрим что получилось:

```
sh2# mkdir /mntS/a
sh2# mount /dev/sdb6 /mntS/a
sh2# mkdir /mntP/b
sh2# mount /dev/sdb7 /mntP/b
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
222 145 8:17 / /mntS rw,relatime shared:1
225 145 8:15 / /mntP rw,relatime
178 222 8:22 / /mntS/a rw,relatime shared:2
230 225 8:23 / /mntP/b rw,relatime
```

Из показанного выше мы видим, что /mntS/a была создана как общая (унаследовала от родительской точки монтирования), а /mntP/b — как индивидуальная точка монтирования.

Если вернуться на первый терминал и и ещё раз посмотреть параметры, то можно увидеть, что новая точка монтирования, созданная в общей точке монтирования /mntS, передалась в свою равноправную группу монтирования (в начальном пространстве имён монтирования), а новая точка монтирования, созданная в индивидуальной точке монтирования /mntP, нет:

```
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
77 61 8:17 / /mntS rw,relatime shared:1
83 61 8:15 / /mntP rw,relatime
179 77 8:22 / /mntS/a rw,relatime shared:2
```

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

Для демонстрации следствия подчинённости сначала создадим две общие точки монтирования в начальном пространстве имён монтирования:

```
sh1# mount --make-shared /mntX
sh1# mount --make-shared /mntY
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
132 83 8:23 / /mntX rw,relatime shared:1
133 83 8:22 / /mntY rw,relatime shared:2
```

На втором терминале создадим новое пространство имён монтирования и посмотрим точки монтирования:

```
sh2# unshare -m --propagation unchanged sh
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
168 167 8:23 / /mntX rw,relatime shared:1
169 167 8:22 / /mntY rw,relatime shared:2
```

Далее в новом пространстве имён монтирования пометим одну из точек монтирования как подчинённую:

```
sh2# mount --make-slave /mntY
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
168 167 8:23 / /mntX rw,relatime shared:1
169 167 8:22 / /mntY rw,relatime master:2
```

Из показанного выше видно, что /mntY теперь подчинённая точка монтирования, которая принимать распространяемые события от общей равноправной группы с ID 2.

Далее в новом пространстве имён создадим подмонтирования в /mntX и /mntY:

```
sh2# mkdir /mntX/a
sh2# mount /dev/sda3 /mntX/a
sh2# mkdir /mntY/b
sh2# mount /dev/sda5 /mntY/b
```

Если посмотреть состояние точек монтирования в новом пространстве имён монтирования можно увидеть, что /mntX/a создана как новая общая точка монтирования (наследует «общность» от родительской точки монтирования), а /mntY/b создана как индивидуальная точка монтирования:

```
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
168 167 8:23 / /mntX rw,relatime shared:1
169 167 8:22 / /mntY rw,relatime master:2
173 168 8:3 / /mntX/a rw,relatime shared:3
175 169 8:5 / /mntY/b rw,relatime
```

Если вернуться на первый терминал (в начальное пространство имён монтирования), то можно увидеть, что точка монтирования /mntX/a передалась в свою равноправную группу (общую с /mntX), а точка монтирования /mntY/b нет:

```
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
132 83 8:23 / /mntX rw,relatime shared:1
133 83 8:22 / /mntY rw,relatime shared:2
174 132 8:3 / /mntX/a rw,relatime shared:3
```

Теперь создадим новую точку монтирования в /mntY в первом терминале:

```
sh1# mkdir /mntY/c
sh1# mount /dev/sda1 /mntY/c
sh1# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
132 83 8:23 / /mntX rw,relatime shared:1
133 83 8:22 / /mntY rw,relatime shared:2
174 132 8:3 / /mntX/a rw,relatime shared:3
178 133 8:1 / /mntY/c rw,relatime shared:4
```

Если посмотреть точки монтирования во втором пространстве имён монтирования, то можно увидеть, что на этот раз новая точка монтирования передалась в подчинённую точку монтирования и что эта новая точка монтирования сама является подчинённой (равноправной группе 4):

```
sh2# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
168 167 8:23 / /mntX rw,relatime shared:1
169 167 8:22 / /mntY rw,relatime master:2
173 168 8:3 / /mntX/a rw,relatime shared:3
175 169 8:5 / /mntY/b rw,relatime
179 169 8:1 / /mntY/c rw,relatime master:4
```

### Пример MS_UNBINDABLE
Одним из основных назначений непривязываемых точек монтирования является решение проблемы «взрыва точек монтирования» — повторяющееся выполнение привязки точки монтирования поддерева верхнего уровня в точках монтирования нижнего уровня. Эта проблема показана в сеансе далее.

Предположим, что имеется система с следующими точками монтирования:

```
# mount | awk '{print $1, $2, $3}'
/dev/sda1 on /
/dev/sdb6 on /mntX
/dev/sdb7 on /mntY
```

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

```
# mount --rbind / /home/cecilia/
# mount | awk '{print $1, $2, $3}'
/dev/sda1 on /
/dev/sdb6 on /mntX
/dev/sdb7 on /mntY
/dev/sda1 on /home/cecilia
/dev/sdb6 on /home/cecilia/mntX
/dev/sdb7 on /home/cecilia/mntY
```

Повторяя эту операцию для второго пользователя сталкиваемся с проблемой взрывного роста:

```
# mount --rbind / /home/henry
# mount | awk '{print $1, $2, $3}'
/dev/sda1 on /
/dev/sdb6 on /mntX
/dev/sdb7 on /mntY
/dev/sda1 on /home/cecilia
/dev/sdb6 on /home/cecilia/mntX
/dev/sdb7 on /home/cecilia/mntY
/dev/sda1 on /home/henry
/dev/sdb6 on /home/henry/mntX
/dev/sdb7 on /home/henry/mntY
/dev/sda1 on /home/henry/home/cecilia
/dev/sdb6 on /home/henry/home/cecilia/mntX
/dev/sdb7 on /home/henry/home/cecilia/mntY
```

В /home/henry рекурсивно добавились не только точки монтирования /mntX и /mntY, но и рекурсивные точки монтирования этих каталогов, смонтированных в /home/cecilia, который мы создали на предыдущем шаге. Далее повторяя процесс для третьего пользователя, станет очевидно, что взрывной рост происходит экспоненциально:

```
# mount --rbind / /home/otto
# mount | awk '{print $1, $2, $3}'
/dev/sda1 on /
/dev/sdb6 on /mntX
/dev/sdb7 on /mntY
/dev/sda1 on /home/cecilia
/dev/sdb6 on /home/cecilia/mntX
/dev/sdb7 on /home/cecilia/mntY
/dev/sda1 on /home/henry
/dev/sdb6 on /home/henry/mntX
/dev/sdb7 on /home/henry/mntY
/dev/sda1 on /home/henry/home/cecilia
/dev/sdb6 on /home/henry/home/cecilia/mntX
/dev/sdb7 on /home/henry/home/cecilia/mntY
/dev/sda1 on /home/otto
/dev/sdb6 on /home/otto/mntX
/dev/sdb7 on /home/otto/mntY
/dev/sda1 on /home/otto/home/cecilia
/dev/sdb6 on /home/otto/home/cecilia/mntX
/dev/sdb7 on /home/otto/home/cecilia/mntY
/dev/sda1 on /home/otto/home/henry
/dev/sdb6 on /home/otto/home/henry/mntX
/dev/sdb7 on /home/otto/home/henry/mntY
/dev/sda1 on /home/otto/home/henry/home/cecilia
/dev/sdb6 on /home/otto/home/henry/home/cecilia/mntX
/dev/sdb7 on /home/otto/home/henry/home/cecilia/mntY
```

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

```
# mount --rbind --make-unbindable / /home/cecilia
```

Перед тем как продолжить, посмотрим, что непривязываемые точки монтирования действительно нельзя привязать:

```
# mkdir /mntZ
# mount --bind /home/cecilia /mntZ
mount: wrong fs type, bad option, bad superblock on /home/cecilia,

       missing codepage or helper program, or other error

       В некоторых случаях полезная информация может быть

       найдена в syslog - попробуйте dmesg | tail или что-то

       в этом роде.
```

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

```
# mount --rbind --make-unbindable / /home/henry
# mount --rbind --make-unbindable / /home/otto
```

Если посмотреть список точек монтирования, то можно увидеть, что взрывного роста не произошло, так как непривязываемые точки монтирования не скопировались в каждый пользовательский каталог:

```
# mount | awk '{print $1, $2, $3}'
/dev/sda1 on /
/dev/sdb6 on /mntX
/dev/sdb7 on /mntY
/dev/sda1 on /home/cecilia
/dev/sdb6 on /home/cecilia/mntX
/dev/sdb7 on /home/cecilia/mntY
/dev/sda1 on /home/henry
/dev/sdb6 on /home/henry/mntX
/dev/sdb7 on /home/henry/mntY
/dev/sda1 on /home/otto
/dev/sdb6 on /home/otto/mntX
/dev/sdb7 on /home/otto/mntY
```

### Переходы типов распространения
В следующей таблице показано как влияет применение нового типа распространения (т. е., mount --make-xxxx) на текущий тип распространения точки монтирования. Строки соответствуют существующим типам распространения, а столбцы — заданию нового типа распространения. Из-за нехватки места «индивидуальная» тип сокращён до «инд», а «непривязываемая» до «неприв».

сделать-общим

сделать-подчинён

сделать-инд

сделать-неприв

общий

общий

общий/инд [1]

инд

неприв

подчинён

подчинён+общий

подчинён [2]

инд

неприв

подчинён+общий

подчинён+общий

подчинён

инд

неприв

инд

общий

инд [2]

инд

неприв

неприв

общий

неприв [2]

инд

неприв

Замечания к таблице:

[1]

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

[2]

Подчинение не общей точки монтирования не влияет на монтирование.

### Семантика привязывания (MS_BIND)
Предположим, что выполняется следующая команда:

```
mount --bind A/a B/b
```

Здесь A — исходная точка монтирования, B — целевая точка монтирования, a — подкаталог в точке монтирования A и b — подкаталог в точке монтирования B. Тип распространения получаемой точки, B/b, зависит от типов распространения точек монтирования A и B, и рассчитывается по следующей таблице:

исход(A)

общий

инд

подчинён

неприв

цель(B)

общий |

общий

общий

подчинён+общий

некорректно

не_общий |

общий

инд

подчинён

некорректно

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

Дополнительную информацию смотрите в файле Documentation/filesystems/sharedsubtree.txt дерева исходного кода ядра.

### Семантика перемещения (MS_MOVE)
Предположим, что выполняется следующая команда:

```
mount --move A B/b
```

Здесь A — исходная точка монтирования, B — целевая точка монтирования и b — подкаталог в точке монтирования B. Тип распространения получаемой точки, B/b, зависит от типов распространения точек монтирования A и B, и рассчитывается по следующей таблице:

исход(A)

общий

инд

подчинён

неприв

цель(B)

общий |

общий

общий

подчинён+общий

некорректно

не_общий |

общий

инд

подчинён

неприв

Замечание: перемещение точки монтирования, располагающейся ниже общей точки, некорректно.

Дополнительную информацию смотрите в файле Documentation/filesystems/sharedsubtree.txt дерева исходного кода ядра.

### Семантики монтирования
Предположим, что для создания точки монтирования используется следующая команда:

```
mount устройство B/b
```

Здесь B — целевая точка монтирования и b — подкаталог в точке монтирования B. Тип распространения получаемой точки, B/b, получается таким же как при привязывании, где тип распространения исходной точки монтирования всегда равен индивидуальному.

### Семантики размонтирования
Предположим, что для размонтирования точки используется следующая команда:

```
unmount A
```

Здесь A точка монтирования на B/b, где B — родительская точка монтирования и b — подкаталог в точке монтирования B. Если B имеет общий тип распространения, то все последние монтирования в b, получающие события от точки монтирования B и не имеющие подмонтирований внутри, будут размонтированы.

### Метка /proc/[pid]/mountinfo propagate_from
Метка propagate_from:X появляется в необязательных полях записи /proc/[pid]/mountinfo в случаях, когда процесс не может видеть непосредственного мастера (т. е., путь к мастеру недоступен из корневого каталога файловой системы) и поэтому не может определить цепочку распространения между точками монтирования, которые он может видеть.

В следующем примере сначала создаётся двусвязная цепочка мастер-подчинённый между точками монтирования /mnt, /tmp/etc и /mnt/tmp/etc. Затем используется команда chroot(1), чтобы сделать точку монтирования /tmp/etc недоступной из корневого каталога, что создаёт ситуацию, где мастер для /mnt/tmp/etc недоступен из (нового) корневого каталога процесса.

Сначала привяжем корневой каталог в /mnt, а затем привяжем /proc в /mnt/proc, чтобы после этого в правильном месте chroot-окружения для chroot(1) осталась доступной файловая система proc(5).

```
# mkdir -p /mnt/proc
# mount --bind / /mnt
# mount --bind /proc /mnt/proc
```

Теперь убедимся, что точка монтирования /mnt является общей в новой равноправной группе (без членов):

```
# mount --make-private /mnt  # Изолировать от любой предыдущей группы
# mount --make-shared /mnt
# cat /proc/self/mountinfo | grep '/mnt' | sed 's/ - .*//'
239 61 8:2 / /mnt ... shared:102
248 239 0:4 / /mnt/proc ... shared:5
```

Теперь привяжем /mnt/etc к /tmp/etc:

```
# mkdir -p /tmp/etc
# mount --bind /mnt/etc /tmp/etc
# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'
239 61 8:2 / /mnt ... shared:102
248 239 0:4 / /mnt/proc ... shared:5
267 40 8:2 /etc /tmp/etc ... shared:102
```

Первоначально, эти две точки монтирования были в одной равноправной группе, но мы сделали /tmp/etc подчинённой /mnt/etc, а затем сделали /tmp/etc общей, так чтобы она могла распространять события следующему подчинённому в цепочке:

```
# mount --make-slave /tmp/etc
# mount --make-shared /tmp/etc
# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'
239 61 8:2 / /mnt ... shared:102
248 239 0:4 / /mnt/proc ... shared:5
267 40 8:2 /etc /tmp/etc ... shared:105 master:102
```

Затем мы привязали /tmp/etc в /mnt/tmp/etc. Опять же, две точки монтирования первоначально были в одной равноправной группе, но позднее мы сделали /mnt/tmp/etc подчинённой /tmp/etc:

```
# mkdir -p /mnt/tmp/etc
# mount --bind /tmp/etc /mnt/tmp/etc
# mount --make-slave /mnt/tmp/etc
# cat /proc/self/mountinfo | egrep '/mnt|/tmp/' | sed 's/ - .*//'
239 61 8:2 / /mnt ... shared:102
248 239 0:4 / /mnt/proc ... shared:5
267 40 8:2 /etc /tmp/etc ... shared:105 master:102
273 239 8:2 /etc /mnt/tmp/etc ... master:105
```

Из показанного выше можно видеть, что /mnt является главной для подчинённой /tmp/etc, которая, в свою очередь, является главной для подчинённой /mnt/tmp/etc.

Теперь выполним chroot(1) в каталог /mnt, который делает точку монтирования с ID 267 недоступной из (нового корневого каталога:

```
# chroot /mnt
```

Если мы проверим состояние точек монтирования внутри окружения chroot, то увидим следующее:

```
# cat /proc/self/mountinfo | sed 's/ - .*//'
239 61 8:2 / / ... shared:102
248 239 0:4 / /proc ... shared:5
273 239 8:2 /etc /tmp/etc ... master:105 propagate_from:102
```

Здесь мы видим, что точка монтирования с ID 273 является подчинённой для главной, которая входит в равноправную группу 105. Точка монтирования этой главной недоступна и поэтому появилась метка propagate_from, показывающая, что идентификатор ближайшей ведущей равноправной группы (т. е., ближайшая достижимая точка монтирования в подчинённой цепи) равен 102 (соответствует точке монтирования /mnt до выполнения chroot(1)).

## ВЕРСИИ
Пространство имён монтирования впервые появилось в Linux 2.4.19.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Пространства имён есть только в Linux.

## ЗАМЕЧАНИЯ
Тип распространения, назначаемый новой точке монтирования, зависит от типа распространения родительской точки монтирования. Если точка монтирования имеет родителя (т. е., является не корневой точкой монтирования) и тип распространения родителя — MS_SHARED, то тип распространения новой точки монтирования будет также MS_SHARED. В противном случае типом новой точки монтирования будет MS_PRIVATE.

Несмотря на то, что тип распространения по умолчанию для новой точки монтирования во многих случаях равен MS_PRIVATE, обычно, тип MS_SHARED полезнее. По этой причине, при запуске системы systemd(1) автоматически перемонтирует все точки монтирования как MS_SHARED. Таким образом, в современных системах типом распространения по умолчанию практически является MS_SHARED.

При создании пространства имён монтирования с помощью unshare(1) чаще всего требуется создать полную изоляцию точек монтирования в новом пространстве имён, и unshare(1) (начиная с util-linux версии 2.27) отменяет изменения systemd(1), делая все точки монтирования индивидуальными в новом пространстве имён. То есть unshare(1) в новом пространстве имён монтирования выполняет эквивалент следующего:

```
mount --make-rprivate /
```

Чтобы этого не происходило в unshare(1) можно использовать параметр --propagation unchanged.

Описание типов распространения при перемещении точек монтирования (MS_MOVE) и создании привязок монтирования (MS_BIND) смотрите в Documentation/filesystems/sharedsubtree.txt.

## ПРИМЕР
Смотрите pivot_root(2).

## СМОТРИТЕ ТАКЖЕ
unshare(1), clone(2), mount(2), pivot_root(2), setns(2), umount(2), unshare(2), proc(5), namespaces(7), user_namespaces(7), findmnt(8), pivot_root(8)

Файл Documentation/filesystems/sharedsubtree.txt в дереве исходного кода ядра Linux.


package: man-pages-ru

title: mq_overview(7)

summary: обзор очередей сообщений POSIX

text:
# mq_overview(7)

## ИМЯ
mq_overview - обзор очередей сообщений POSIX

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

Очереди сообщений создаются и открываются с помощью mq_open(3); эта функция возвращает дескриптор очереди сообщений (mqd_t), который используется в последующих вызовах для ссылки на открытую очередь сообщений. Каждая очередь сообщений описывается именем в виде /некое_имя; оно представляет собой строку с null в конце и длиной до NAME_MAX (т. е., 255) символов, состоящую из начальной косой черты, одного и более символа (любого, кроме косой черты). Два процесса могут работать через одну очередь, если укажут одинаковое имя в mq_open(3).

Сообщения передаются в и из очереди с помощью функций mq_send(3) и mq_receive(3). Когда процесс прекращает использовать очередь, он закрывает её с помощью функции mq_close(3), и если очередь больше не нужна, то она может быть удалена с помощью функции mq_unlink(3). Атрибуты очереди можно получить и (в некоторых случаях) изменить с помощью функций mq_getattr(3) и mq_setattr(3). Процесс может запросить асинхронное уведомление о поступлении сообщения в пустую очередь с помощью функции mq_notify(3).

Дескриптор очереди сообщений — это ссылка на открытое описание очереди сообщений (смотрите open(2)). После вызова fork(2) потомок наследует копии дескрипторов очередей сообщений родителя и эти дескрипторы ссылаются на те же открытые описания очередей сообщений родителя. Соответствующие дескрипторы очередей сообщений двух процессов используют общий флаг (mq_flags), который связан с открытым описанием очереди сообщений.

У каждого сообщения есть приоритет, и сначала в принимающий процесс всегда доставляются сообщения наивысшим приоритетом. Диапазон приоритетов сообщений: 0 (низший) — sysconf(_SC_MQ_PRIO_MAX) - 1 (высший). В Linux, sysconf(_SC_MQ_PRIO_MAX) возвращает 32768, но в POSIX.1 требуется реализация поддержки только диапазона приоритетов от 0 до 31; некоторые реализации предоставляют только этот диапазон.

Далее в разделе описываются особенности реализации очередей сообщений POSIX в Linux.

### Библиотечные интерфейсы и системные вызовы
В большинстве случаев, перечисленные выше библиотечные интерфейсы mq_*() реализуются поверх системных вызовов с теми же именами. Исключения из этого правила перечислены в следующей таблице:

Библиотечный интерфейс

Системный вызов

mq_close(3)

close(2)

mq_getattr(3)

mq_getsetattr(2)

mq_notify(3)

mq_notify(2)

mq_open(3)

mq_open(2)

mq_receive(3)

mq_timedreceive(2)

mq_send(3)

mq_timedsend(2)

mq_setattr(3)

mq_getsetattr(2)

mq_timedreceive(3)

mq_timedreceive(2)

mq_timedsend(3)

mq_timedsend(2)

mq_unlink(3)

mq_unlink(2)

### Версии
Поддержка очередей сообщений POSIX началась в ядре Linux версии 2.6.6. Поддержка в glibc предоставляется с версии 2.3.4.

### Конфигурация ядра
Поддержка очередей сообщений POSIX включается параметром настройки ядра CONFIG_POSIX_MQUEUE. Данный параметр включён по умолчанию.

### Устойчивость
Очереди сообщений POSIX располагаются в ядре. Пока очередь не удалёна с помощью mq_unlink(3), она остаётся в системе до её выключения.

### Компоновка
Программы, в которых используется программный интерфейс очереди сообщений POSIX, для компоновки с библиотекой реального времени librt должны компилироваться с помощью cc -lrt.

### Интерфейсы /proc
Для ограничения потребления очередями сообщений POSIX памяти ядра и задания атрибутов по умолчанию для новых очередей сообщений, можно использовать следующие интерфейсы:

/proc/sys/fs/mqueue/msg_default (начиная с Linux 3.5)

В данном файле задаётся значение, которое используется для mq_maxmsg в создаваемой новой очереди с помощью вызова mq_open(3) со значением attr равным NULL. Значение для этого файла по умолчанию равно 10. Минимальное и максимальные значение такие же как для /proc/sys/fs/mqueue/msg_max. Значение по умолчанию mq_maxmsg у новой очереди будет меньше msg_default и msg_max. До Linux 2.6.28 значение mq_maxmsg по умолчанию равнялось 10; с Linux 2.6.28 по Linux 3.4 значение по умолчанию равнялось ограничению msg_max.

/proc/sys/fs/mqueue/msg_max

Данный файл можно использовать для просмотра и изменения значения максимального количества сообщений в очереди. Это значение служит верхним пределом для аргумента attr->mq_maxmsg, указываемого в mq_open(3). Значение msg_max по умолчанию равно 10. Минимальное значение равно 1 (10 в ядрах до версии 2.6.28). Верхний предел равен HARD_MSGMAX. Ограничитель msg_max игнорируется для привилегированных процессов (CAP_SYS_RESOURCE), но, тем не менее, учитывается предел HARD_MSGMAX.

Определение HARD_MSGMAX изменялось в разных версиях ядра следующим образом:

- До Linux 2.6.32: 131072 / sizeof(void *)

- Linux 2.6.33 по 3.4: (32768 * sizeof(void *) / 4)

- Начиная с Linux 3.5: 65536

/proc/sys/fs/mqueue/msgsize_default (начиная с Linux 3.5)

В данном файле задаётся значение, которое используется для mq_msgsize в создаваемой новой очереди с помощью вызова mq_open(3) со значением attr равным NULL. Значение для этого файла по умолчанию равно 8192 (байты). Минимальное и максимальные значение такие же как для /proc/sys/fs/mqueue/msgsize_max. Если msgsize_default превышает msgsize_max, то значение mq_msgsize для новой очереди по умолчанию ограничивается msgsize_max.До Linux 2.6.28 значение mq_msgsize по умолчанию равнялось 8192; с Linux 2.6.28 по Linux 3.4 значение по умолчанию равнялось ограничению msgsize_max.

/proc/sys/fs/mqueue/msgsize_max

Данный файл можно использовать для просмотра и изменения максимального размера сообщения. Это значение служит верхним пределом для аргумента attr->mq_msgsize, указываемого в mq_open(3). Значение msgsize_max по умолчанию равно 8192 байта. Минимальное значение равно 128 (8192 в ядрах до версии 2.6.28). Верхний предел msgsize_max изменялся в разных версиях ядер следующим образом:

- До Linux 2.6.28 верхний предел был равен INT_MAX.

- С Linux 2.6.28 по 3.4 предел равен 1048576.

- Начиная с Linux 3.5 предел равен 16777216 (HARD_MSGSIZEMAX).

Предел msgsize_max игнорируется для привилегированных процессов (CAP_SYS_RESOURCE), но, начиная с Linux 3.5, накладывается ограничение HARD_MSGSIZEMAX.

/proc/sys/fs/mqueue/queues_max

Данный файл можно использовать для просмотра и изменения системного ограничения на количество сообщений в очереди. Значение queues_max по умолчанию равно 256. У queues_max нет верхнего предела; привилегированные процессы (CAP_SYS_RESOURCE) могут превышать ограничение (но смотрите ДЕФЕКТЫ).

### Ограничение ресурса
Ограничение ресурса RLIMIT_MSGQUEUE, накладываемое на количество пространства, которое могут занять все очереди сообщений, принадлежащие процессу с реальным пользовательским ID, описано в getrlimit(2).

### Монтирование файловой системы очереди сообщений
В Linux очереди сообщений создаются в виртуальной файловой системе (другие реализации могут делать также, но, вероятно, по-другому). Данная файловая система может быть смонтирована (суперпользователем) с помощью команд:

```
# mkdir /dev/mqueue
# mount -t mqueue none /dev/mqueue
```

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

После примонтирования файловой системы очередь сообщений в системе можно просматривать и изменять с помощью команд как с обычными файлами (например, ls(1) и rm(1)).

Содержимое каждого файла в каталоге состоит из одной строки, в которой представлена информация об очереди:

```
$ cat /dev/mqueue/mymq
QSIZE:129     NOTIFY:2    SIGNO:0    NOTIFY_PID:8260
```

Эти поля означают следующее:

QSIZE

Количество байтов данных во всех сообщениях очереди (но смотрите ДЕФЕКТЫ).

NOTIFY_PID

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

NOTIFY

Способ уведомления: 0 — SIGEV_SIGNAL; 1 — SIGEV_NONE; 2 — SIGEV_THREAD.

SIGNO

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

### Реализация дескрипторов очереди сообщений в Linux
В Linux дескриптор очереди сообщений представляет собой файловый дескриптор (в POSIX не требуется этого от реализации). Это означает, что за дескриптором очереди сообщений можно следить с помощью select(2), poll(2) или epoll(7). Это является непереносимым свойством.

Флаг close-on-exec (смотрите open(2)) устанавливается автоматически на файловом дескрипторе, возвращаемом mq_open(2).

### Пространства имён IPC
Обсуждение связи объектов очереди сообщений POSIX с пространствами IPC смотрите в ipc_namespaces(7).

## ЗАМЕЧАНИЯ
Очереди сообщений System V (msgget(2), msgsnd(2), msgrcv(2) и т. д.) — более старый программный интерфейс обмена сообщениями между процессами. Очереди сообщений POSIX имеют более проработанный интерфейс чем очереди сообщений System V; с другой стороны, очереди сообщений POSIX не так широко распространены (особенно в старых системах) чем очереди сообщений System V.

В Linux (версия 2.6.26) пока нет поддержки использования списков контроля доступа (ACL) для очередей сообщений POSIX.

## ДЕФЕКТЫ
В Linux версиях с 3.5 по 3.14 ядро устанавливает верхний предел в 1024 (HARD_QUEUESMAX) на значение ограничения queues_max и это влияет даже на привилегированные процессы. Это предельное значение было удалено в Linux 3.14, а также есть заплаты к стабильным ядрам версий с 3.5.x по 3.13.x для удаления этого предела.

Первоначально реализованное (и описанное) поле QSIZE показывало общее количество (пользовательских) байт всех сообщений в очереди. Некоторые изменения в Linux 3.5 непреднамеренно изменили это поведение, и поле стало также включать байты издержек ядра, которые требуются для хранения сообщений в очереди. Это было исправлено в Linux 4.2 (и более ранних стабильных ядрах), и теперь снова считаются байты только пользовательских сообщений в очереди.

## ПРИМЕР
Пример использования функций работы с очередью сообщений смотрите в mq_notify(3).

## СМОТРИТЕ ТАКЖЕ
getrlimit(2), mq_getsetattr(2), poll(2), select(2), mq_close(3), mq_getattr(3), mq_notify(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3), epoll(7), namespaces(7)


namespaces

title: namespaces(7)

summary: обзор пространств имён Linux

text:
# namespaces(7)

## ИМЯ
namespaces - обзор пространств имён Linux

## ОПИСАНИЕ
Пространства имён облекают глобальный системный ресурс в абстрактную форму, в которой он представляется процессам внутри пространства имён таким образом, что процессы имеют свои собственные изолированные экземпляры глобального ресурса. Изменения глобального ресурса видимы другим процессам, которые являются членами пространства имён, и невидимы остальным процессам. Одно из применений пространств имён — реализация контейнеров.

В Linux предоставляются следующие пространства имён:

Пространство имён

Константа

Изоляция

Cgroup

CLONE_NEWCGROUP

корневой каталог cgroup

IPC

CLONE_NEWIPC

System V IPC, очереди сообщений POSIX

Network

CLONE_NEWNET

сетевые устройства, стеки, порты …

Mount

CLONE_NEWNS

точки монтирования

PID

CLONE_NEWPID

идентификаторы процессов

User

CLONE_NEWUSER

Идентификаторы пользователей и групп

UTS

CLONE_NEWUTS

имя узла и доменное имя NIS

В этой странице описаны различные пространства имён и связанные с ними файлы в /proc, а также кратко представлен программный интерфейс.

### Программный интерфейс пространств имён
и различные файлы в /proc описаны далее. В API пространств имён имеются следующие системные вызовы:

clone(2)

Системный вызов clone(2) создаёт новый процесс. Если в аргументе flags указан один или несколько флагов CLONE_NEW*, перечисленных далее, то для каждого флага создаётся новое пространство имён, и дочерний процесс становится членом этих пространств имён (данный системный вызов также служит для других целей, не относящихся к пространствам имён).

setns(2)

Системный вызов setns(2) позволяет вызывающему процессу присоединиться к существующему пространству имён. Требуемое пространство имён указывается через файловый дескриптор, который ссылается на один из файлов /proc/[pid]/ns, описанных далее.

unshare(2)

Системный вызов unshare(2) перемещает вызывающий процесс в новое пространство имён. Если в аргументе flags указан один или несколько флагов CLONE_NEW*, перечисленных далее, то для каждого флага создаётся новое пространство имён, и дочерний процесс становится членом этих пространств имён (данный системный вызов также служит для других целей, не относящихся к пространствам имён).

ioctl(2)

Для получения информации о пространствах имё можно использовать различные операции ioctl(2). Их можно найти в ioctl_ns(2).

Для создания новых пространств имён с помощью clone(2) и unshare(2), в большинстве случаев, требуется мандат CAP_SYS_ADMIN, так как в новом пространстве имён создатель будет обладать возможностью изменять глобальные ресурсы, которые видимы другим процессам, создаваемым или присоединяемым к пространству имён со временем. Исключение составляют пользовательские пространства имён: начиная с Linux 3.8 для создания пользовательского пространства имён особых прав не требуется.

### Каталог /proc/[pid]/ns/
Для каждого процесса в /proc/[pid]/ns/ есть подкаталог, в котором содержится по одной записи на каждое пространство имён, через которые ими можно управлять с помощью setns().

```
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 cgroup -> cgroup:[4026531835]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 net -> net:[4026531969]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 pid -> pid:[4026531836]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 pid_for_children -> pid:[4026531834]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 user -> user:[4026531837]
lrwxrwxrwx. 1 mtk mtk 0 Apr 28 12:46 uts -> uts:[4026531838]
```

При привязке монтирования (bind mounting) (смотрите mount(2)) одного из файлов этого каталога в другое место в файловой системе данное пространство имён процесса с pid не удаляется, даже если все процессы в пространстве имён завершились.

При открытии одного из файлов этого каталога (или файла, который был привязан монтированием в один из этих файлов) возвращается файловый описатель соответствующего пространства имён процесса заданного pid. Пока этот файловый дескриптор остаётся открытым, пространство имён будет оставаться действующим, даже если все процессы в пространстве имён завершились. Файловый дескриптор может быть передан в setns(2).

В Linux 3.7 и старее эти файлы видимы как жёсткие ссылки. Начиная с Linux 3.8 они представляются символьными ссылками. Если два процесса находятся в одном пространстве имён, то значения идентификаторов устройств и номера инод их символьных ссылок /proc/[pid]/ns/xxx одинаковы; приложение может проверить это через поля stat.st_dev и stat.st_ino, возвращаемые stat(2). Содержимое этой символьной ссылки представляет собой строку с типом пространства имён и значением иноды:

```
$ readlink /proc/$$/ns/uts
uts:[4026531838]
```

В этом подкаталоге содержатся символические ссылки:

/proc/[pid]/ns/cgroup (начиная с Linux 4.6)

Данный файл является описателем пространства имён cgroup этого процесса.

/proc/[pid]/ns/ipc (начиная с Linux 3.0)

Данный файл является описателем пространства имён IPC этого процесса.

/proc/[pid]/ns/mnt (начиная с Linux 3.8)

Данный файл является описателем пространства имён mount этого процесса.

/proc/[pid]/ns/net (начиная с Linux 3.0)

Данный файл является описателем пространства имён network этого процесса.

/proc/[pid]/ns/pid (начиная с Linux 3.8)

Этот является описателем пространства имён PID этого процесса. Данный описатель постоянен на протяжении всей жизни процесса (т. е., членство пространства имён PID процесса никогда не меняется).

/proc/[pid]/ns/pid_for_children (начиная с Linux 4.12)

Этот файл является описателем пространства имён PID дочерних процессов, созданных этим процессом. Он может изменяться послевызовов unshare(2) и setns(2) (смотрите pid_namespaces(7)), поэтому файл может отличаться от /proc/[pid]/ns/pid. Данные по символьной ссылке появляются только после создания в пространстве имён первого дочернего процесса (до этого вызов readlink(2) с символьной ссылкой вернёт пустой буфер).

/proc/[pid]/ns/user (начиная с Linux 3.8)

Данный файл является описателем пространства имён user этого процесса.

/proc/[pid]/ns/uts (начиная с Linux 3.0)

Данный файл является описателем пространства имён UTS этого процесса.

Право разыменовывать или читать (readlink(2)) данные символические ссылки определяется проверкой режима доступа ptrace PTRACE_MODE_READ_FSCREDS; смотрите ptrace(2).

### Каталог /proc/sys/user
Файлы в каталоге /proc/sys/user (появился в Linux начиная с версии 4.9) отражают ограничения на количество пространств имён различных типов, которые могут быть созданы. Файлы:

max_cgroup_namespaces

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

max_ipc_namespaces

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

max_mnt_namespaces

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

max_net_namespaces

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

max_pid_namespaces

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

max_user_namespaces

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

max_uts_namespaces

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

Замечания к этим файлам:

- Значения в этих файлам могут изменяться привилегированными процессами.

- Значения, отражаемые в этих файлах, являются ограничениями пользовательского пространства имён, в котором располагается открывающий процесс.

- Ограничение устанавливается по каждому пользователю отдельно. Каждый пользователь в одном пространстве имён пользователя может создать столько пространств имён, сколько допускается это ограничение.

- Ограничения применяются ко всем пользователям, даже имеющим UID 0.

- Эти ограничения применяются в дополнении к другим накладываемым ограничениям, касающимся каждого пространства имён (например, для пользовательского пространства имён и пространства имён PID).

- При достижении этих ограничений вызовы clone(2) и unshare(2) завершаются ошибкой ENOSPC.

- Для первоначального пространства пользовательского пространства имён значение по умолчанию в каждом файле равно половине ограничения на количество нитей, которые могут быть созданы (/proc/sys/kernel/threads-max). В всех дочерних пользовательских пространств имён значение по умолчанию каждого файла равно MAXINT.

- Когда пространство имён создаётся, этот объект также учитывается в родительских пространствах имён. То есть:

+

Каждое пользовательское пространство имён имен создателя UID.

+

Когда пространство имён создаётся, это учитывается в UID создателя в каждом родительском пользовательском пространстве имён, и ядро проверяет, что соответствующее ограничение на пространство имён для UID создателя не превысило значение в родительском пространстве имён.

+

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

### Пространства имён cgroup (CLONE_NEWCGROUP)
Смотрите cgroup_namespaces(7).

### Пространства имён IPC (CLONE_NEWIPC)
Смотрите ipc_namespaces(7).

### Пространства имён network (CLONE_NEWNET)
Смотрите network_namespaces(7).

### Пространства имён mount (CLONE_NEWNS)
Смотрите mount_namespaces(7).

### Пространства имён PID (CLONE_NEWPID)
Смотрите pid_namespaces(7).

### Пространства имён user (CLONE_NEWUSER)
Смотрите user_namespaces(7).

### Пространства имён UTS (CLONE_NEWUTS)
Смотрите uts_namespaces(7).

### Время жизни пространства имён
При отсутствии других факторов, пространство имён автоматически удаляется, когда последний процесс в пространстве имён завершается или покидает его. Однако есть несколько факторов, которые могут задержать существование пространства имён даже при отсутствии процессов в нём. К таким факторам относятся следующие:

- Существуют открытый дескриптор файла или привязанное монтирование для соответствующего файла /proc/[pid]/ns/*.

- Пространство имён иерархично (т. е., пространство имён PID или пользовательское) и имеет дочернее пространство имён.

- Это пользовательское пространство имен, которое владеет одним или несколькими непользовательскими пространствами имён.

- Это пространство имён PID и существует процесс, который ссылается на пространство имён через символьную ссылку /proc/[pid]/ns/pid_for_children.

- Это пространство имён IPC и соответствующее монтирование файловой системы mqueue (смотрите mq_overview(7)) ссылается на это пространство имён.

- Это пространство имён PID и соответствующее монтирование файловой системы proc(5) ссылается на это пространство имён.

## ПРИМЕР
Смотрите clone(2) и user_namespaces(7).

## СМОТРИТЕ ТАКЖЕ
nsenter(1), readlink(1), unshare(1), clone(2), ioctl_ns(2), setns(2), unshare(2), proc(5), capabilities(7), cgroup_namespaces(7), cgroups(7), credentials(7), ipc_namespaces(7), network_namespaces(7), pid_namespaces(7), user_namespaces(7), uts_namespaces(7), lsns(8), pam_namespace(8), switch_root(8)


netdevice

title: netdevice(7)

text:
# netdevice(7)

## ИМЯ
netdevice - низкоуровневый доступ к сетевым устройствам Linux

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

\#include <net/if.h>

## ОПИСАНИЕ
В этой справочной странице описан интерфейс сокетов, используемый для настройки сетевых устройств.

Linux поддерживает несколько стандартных вызовов ioctl для настройки сетевых устройств. Они могут применяться для любого файлового дескриптора сокета независимо от семейства или типа сокета. В качестве параметра большинство из них передаёт структуру ifreq:

```
struct ifreq {

    char ifr_name[IFNAMSIZ]; /* имя интерфейса */

    union {

        struct sockaddr ifr_addr;

        struct sockaddr ifr_dstaddr;

        struct sockaddr ifr_broadaddr;

        struct sockaddr ifr_netmask;

        struct sockaddr ifr_hwaddr;

        short           ifr_flags;

        int             ifr_ifindex;

        int             ifr_metric;

        int             ifr_mtu;

        struct ifmap    ifr_map;

        char            ifr_slave[IFNAMSIZ];

        char            ifr_newname[IFNAMSIZ];

        char           *ifr_data;

    };
};
```

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

### Вызовы ioctl
Если указано, вызов ioctl считается привилегированным, то для его использования необходимо иметь эффективный идентификатор пользователя 0 или мандат CAP_NET_ADMIN. В противном случае будет возвращено значение EPERM.

SIOCGIFNAME

Возвращает в ifr_name имя интерфейса для заданного индекса ifr_ifindex. Это единственный вызов ioctl, возвращающий результат в ifr_name.

SIOCGIFINDEX

Возвращает индекс интерфейса в ifr_ifindex.

SIOCGIFFLAGS, SIOCSIFFLAGS

Считывает или устанавливает слово флагов устройства. В ifr_flags содержится битовая маска из следующих значений: Флаги устройства

IFF_UP

Интерфейс активен.

IFF_BROADCAST

Установлен правильный широковещательный адрес.

IFF_DEBUG

Флаг внутренней отладки.

IFF_LOOPBACK

Интерфейс является устройством обратной петли.

IFF_POINTOPOINT

Интерфейс является соединением точка-точка.

IFF_RUNNING

Ресурсы выделены.

IFF_NOARP

Нет протокола arp, адрес назначения 2-ого уровня (L2) не установлен.

IFF_PROMISC

Интерфейс в режиме прослушки (promiscuous).

IFF_NOTRAILERS

Избегать использования концевиков (trailers).

IFF_ALLMULTI

Принимать все многоадресные пакеты.

IFF_MASTER

Мастер в связке балансирования нагрузки.

IFF_SLAVE

Подчинённый в связке балансирования нагрузки.

IFF_MULTICAST

Поддержка многоадресной передачи.

IFF_PORTSEL

Может выбирать тип среды с помощью ifmap.

IFF_AUTOMEDIA

Запущен автоматический выбор среды.

IFF_DYNAMIC

Адреса теряются, если интерфейс становится неактивным.

IFF_LOWER_UP

Сигналы драйвера L1 указывают на включение интерфейса (начиная с Linux 2.6.17).

IFF_DORMANT

Сигналы драйвера указывают на неактивность интерфейса (начиная с Linux 2.6.17).

IFF_ECHO

Посылать пакеты echo (начиная с Linux 2.6.25).

Установка флага в слове флагов является привилегированной операцией, но считывать его может любой процесс.

SIOCGIFPFLAGS, SIOCSIFPFLAGS

Считает или устанавливает (индивидуальные) флаги устройства. Значение ifr_flags представляет собой битовую маску следующих значений: Индивидуальные флаги

IFF_802_1Q_VLAN

Интерфейс является устройством 802.1Q VLAN.

IFF_EBRIDGE

Интерфейс является устройством моста Ethernet.

IFF_SLAVE_INACTIVE

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

IFF_MASTER_8023AD

Интерфейс является мастером в связке балансирования нагрузки 802.3ad.

IFF_MASTER_ALB

Интерфейс является мастером связки балансирования нагрузки в режиме balanced-alb.

IFF_BONDING

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

IFF_SLAVE_NEEDARP

Интерфейсу требуется ARP для проверки.

IFF_ISATAP

Интерфейс является интерфейсом RFC4214 ISATAP.

Установка расширенных (индивидуальных) флагов интерфейса является привилегированной операцией.

SIOCGIFADDR, SIOCSIFADDR

Назначает или получает адрес устройства с помощью ifr_addr. Назначение адреса интерфейса является привилегированной операцией. Для совместимости, принимаются или возвращаются только адреса семейства AF_INET.

SIOCGIFDSTADDR, SIOCSIFDSTADDR

Назначает или получает адрес назначения устройства точка-точка с помощью ifr_dstaddr. Для совместимости, принимаются или возвращаются только адреса семейства AF_INET. Присвоение адреса назначения является привилегированной операцией.

SIOCGIFBRDADDR, SIOCSIFBRDADDR

Назначает или получает широковещательный адрес устройства с помощью ifr_brdaddr. Для совместимости, принимаются или возвращаются только адреса семейства AF_INET. Присвоение широковещательного адреса является привилегированной операцией.

SIOCGIFNETMASK, SIOCSIFNETMASK

Назначает или получает маску сети устройства с помощью ifr_netmask. Для совместимости, принимаются или возвращаются только адреса семейства AF_INET. Назначение маски сети адреса является привилегированной операцией.

SIOCGIFMETRIC, SIOCSIFMETRIC

Считывает или устанавливает метрику устройства с помощью ifr_metric. В данный момент возможность не реализована; при считывании ifr_metric присваивается значение, равное нулю, а при попытке установки возвращается значение EOPNOTSUPP.

SIOCGIFMTU, SIOCSIFMTU

Считывает или устанавливает MTU (Maximum Transfer Unit — максимальную порцию данных) с помощью ifr_mtu. Установка MTU является привилегированной операцией. Установка слишком маленьких значений может привести к авариям в ядре.

SIOCGIFHWADDR, SIOCSIFHWADDR

Считывает или устанавливает аппаратный адрес устройства с помощью ifr_hwaddr. Аппаратный адрес задаётся в структуре sockaddr. В sa_family содержится тип устройства ARPHRD_*, в sa_data содержится аппаратный адрес L2, начиная с байта 0. Установка аппаратного адреса является привилегированной операцией.

SIOCSIFHWBROADCAST

Устанавливает аппаратный широковещательный адрес устройства с помощью ifr_hwaddr. Это привилегированная операция.

SIOCGIFMAP, SIOCSIFMAP

Считывает или устанавливает аппаратные параметры интерфейса с помощью ifr_map. Установка параметров является привилегированной операцией.

```
struct ifmap {

    unsigned long   mem_start;

    unsigned long   mem_end;

    unsigned short  base_addr;

    unsigned char   irq;

    unsigned char   dma;

    unsigned char   port;
};

```

Назначение структуры ifmap зависит от драйвера устройства и архитектуры системы.

SIOCADDMULTI, SIOCDELMULTI

Добавляет или удаляет адрес из фильтров многоадресной передачи уровня связи устройства с помощью ifr_hwaddr. Это привилегированная операция. Альтернативный способ приведен в packet(7).

SIOCGIFTXQLEN, SIOCSIFTXQLEN

Считывает или устанавливает размер очереди передачи устройства с помощью ifr_qlen. Установка размера очереди передачи является привилегированной операцией.

SIOCSIFNAME

Изменяет имя интерфейса, указанное в ifr_name, на ifr_newname. Это привилегированная операция. Она разрешена только тогда, когда интерфейс не активен.

SIOCGIFCONF

Возвращает список адресов (транспортного уровня) интерфейсов. В настоящее время, сюда входят только адреса семейства AF_INET (IPv4), для совместимости. В отличии от других, данный ioctl передаёт структуру ifconf:

```
struct ifconf {

    int                 ifc_len; /* размер буфера */

    union {

        char           *ifc_buf; /* адрес буфера */

        struct ifreq   *ifc_req; /* массив структур */

    };
};

```

Если ifc_req равно NULL, то SIOCGIFCONF возвращает необходимый размер буфера в байтах для приёма всех доступных адресов в ifc_len. В противном случае ifc_req содержит указатель на массив структур ifreq, который будет заполнен адресами всех активных интерфейсов L3. В ifc_len содержится размер массива в байтах. Внутри каждой структуры ifreq в ifr_name будет записано имя интерфейса, а в ifr_addr — адрес. Реальное количество переданных байт возвращается в ifc_len.

Если размера, указанного в ifc_len, недостаточно для сохранения всех адресов, то ядро не запишет не поместившиеся и сообщит об успешном выполнении. Не существует надёжного способа обнаружения возникновения такой ситуации. Поэтому рекомендуется или сначала определить необходимый размер буфера вызовом SIOCGIFCONF с значением ifc_req равным NULL, или повторить вызов с большим буфером и проверить не отличается ли ifc_len на менее чем sizeof(struct ifreq) от первого значения.

Если произошла ошибка доступа к структуре ifconf или ifreq, то возвращается EFAULT.

Большинство протоколов поддерживают свои собственные вызовы ioctl для настройки предназначенных только для протокола параметров интерфейса. Подробности приведены в справочных страницах протоколов. Настройка адресов IP описывается в ip(7).

В дополнение ко всему, некоторые устройства поддерживают индивидуальные (private) вызовы ioctl. Здесь они не описаны.

## ЗАМЕЧАНИЯ
Строго говоря, SIOCGIFCONF и другие вызовы ioctl, которые принимают или возвращают только адреса сокетов AF_INET, работают только с IP и принадлежат ip(7).

Имена интерфейсов, не имеющих адресов или установленного флага IFF_RUNNING, можно определить с помощью /proc/net/dev.

Локальные IP-адреса IPv6 можно найти в /proc/net или по rtnetlink(7).

## ДЕФЕКТЫ
В glibc 2.1 отсутствует макрос ifr_newname в файле <net/if.h>. Добавьте следующие строки в вашу программу (чтобы обойти это):

```
#ifndef ifr_newname
#define ifr_newname     ifr_ifru.ifru_slave
#endif
```

## СМОТРИТЕ ТАКЖЕ
proc(5), capabilities(7), ip(7), rtnetlink(7)


netlink

title: netlink(7)

text:
# netlink(7)

## ИМЯ
netlink - обмен информацией между ядром и пользовательским пространством (AF_NETLINK)

## ОБЗОР

```
#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
```

```
netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);
```

## ОПИСАНИЕ
Протокол netlink используется для передачи информации между ядром и процессами в пользовательском пространстве. Он состоит из стандартного, основанного на сокетах, интерфейса для процессов пользователя и внутреннего API ядра, предназначенного для модулей ядра. Внутренний интерфейс ядра в этой странице не описан. Кроме того, существует устаревший интерфейс netlink, работающий через символьные устройства netlink. Этот интерфейс здесь также не описан; он предназначен только для обратной совместимости.

Netlink обеспечивает для приложений сервис передачи датаграмм. В качестве socket_type могут использоваться типы сокетов как SOCK_RAW, так и SOCK_DGRAM. Несмотря на это, протокол netlink не различает датаграмные и неструктурированные (raw) сокеты.

По значению netlink_family выбирается модуль ядра или группа netlink для связи. В данный момент определены следующие семейства netlink:

NETLINK_ROUTE

Получает обновления маршрутов и состояние подключений (link); может использоваться для изменения таблицы маршрутизации (IPv4 и IPv6), IP-адресов, параметров подключения, настроек взаимодействия с ответной стороной (neighbor), параметров работы очереди, классов трафика и классификаторов пакетов (см. rtnetlink(7)).

NETLINK_W1 (начиная с Linux 2.6.13 до 2.16.17)

Сообщения из однопроводной подсистемы.

NETLINK_USERSOCK

Зарезервировано для будущих протоколов сокетов пространства пользователя.

NETLINK_FIREWALL (существует до Linux 3.4 включительно)

Переправляет пакеты IPv4 из netfilter в пространство пользователя. Используется модулем ядра ip_queue. После долгого времени объявления устаревшим (предлагается использовать улучшенное свойство nfnetlink_queue), NETLINK_FIREWALL был удалён к Linux 3.5.

NETLINK_INET_DIAG (начиная с Linux 2.6.14)

Запрашивает информации о сокетах различных семейств протоколов из ядра (смотрите sock_diag(7)).

NETLINK_SOCK_DIAG (начиная с Linux 3.3)

Синоним для NETLINK_INET_DIAG.

NETLINK_NFLOG (существует до Linux 3.16 включительно)

Netfilter/iptables ULOG.

NETLINK_XFRM

IPsec.

NETLINK_SELINUX (начиная с Linux 2.6.4)

Уведомляет о событиях SELinux.

NETLINK_ISCSI (начиная с Linux 2.6.15)

Open-iSCSI.

NETLINK_AUDIT (начиная с Linux 2.6.6)

Ведёт контроль за системой.

NETLINK_FIB_LOOKUP (начиная с Linux 2.6.13)

Доступ к таблице FIB из пользовательского пространства.

NETLINK_CONNECTOR (начиная с Linux 2.6.14)

Точка связи с ядром. Дополнительную информацию смотрите в файле Documentation/connector/* дерева исходного кода ядра Linux.

NETLINK_NETFILTER (начиная с Linux 2.6.14)

Подсистема netfilter.

NETLINK_SCSITRANSPORT (начиная с Linux 2.6.19)

Транспорты SCSI.

NETLINK_RDMA (начиная с Linux 3.0)

Infiniband RDMA.

NETLINK_IP6_FW (существует до Linux 3.4 включительно)

Переправляет пакеты IPv6 из netfilter в пространство пользователя. Используется модулем ядра ip6_queue.

NETLINK_DNRTMSG

Сообщения маршрутизации DECnet.

NETLINK_KOBJECT_UEVENT (начиная с Linux 2.6.10)

Сообщения ядра в пользовательском пространстве.

NETLINK_GENERIC (начиная с Linux 2.6.15)

Обобщённое семейство netlink для использования netlink.

NETLINK_CRYPTO (начиная с Linux 3.2)

Интерфейс netlink для запроса информации о зарегистрированных алгоритмах шифрования с помощью программного интерфейса ядра шифрования, а также настройки программного интерфейса ядра шифрования.

Сообщения netlink состоят из потока байтов с одним или несколькими заголовками nlmsghdr и присоединённой полезной нагрузкой. Доступ к потоку байтов нужно осуществлять только с помощью стандартных макросов NLMSG_*. Подробности смотрите в netlink(3).

В первом и всех последующих заголовках сообщений, состоящих из нескольких частей (несколько заголовков nlmsghdr с полезной нагрузкой в одном потоке байт), установлен флаг NLM_F_MULTI. Последний заголовок имеет тип NLMSG_DONE и этот флаг не устанавливается.

После каждого nlmsghdr следует полезная нагрузка:

```
struct nlmsghdr {

    __u32 nlmsg_len;    /* длина сообщения, включая заголовок */

    __u16 nlmsg_type;   /* тип содержимого сообщения */

    __u16 nlmsg_flags;  /* дополнительные флаги */

    __u32 nlmsg_seq;    /* номер в последовательности */

    __u32 nlmsg_pid;    /* ID порта отправителя */
};
```

Значение nlmsg_type может быть одним из стандартных типов сообщения: сообщения NLMSG_NOOP должны игнорироваться, сообщение NLMSG_ERROR сообщает об ошибке и в нагрузке содержится структура nlmsgerr, сообщение NLMSG_DONE заканчивает сообщение, состоящее из нескольких частей.

```
struct nlmsgerr {

    int error;        /* отрицательный errno или

                         0 для подтверждений */

    struct nlmsghdr msg;  /* заголовок сообщения, вызвавшего

                             ошибку */
};
```

Семейство netlink обычно определяет и другие типы сообщений (см. соответствующие справочные страницы, например, rtnetlink(7) о NETLINK_ROUTE).

Стандартные биты флагов в nlmsg_flags

NLM_F_REQUEST

Должен быть установлен у всех сообщений с запросами.

NLM_F_MULTI

Сообщение является одной из частей длинного сообщения, которое заканчивается NLMSG_DONE.

NLM_F_ACK

Запрашивать подтверждение при успешном выполнении.

NLM_F_ECHO

Послать эхо этого запроса.

Дополнительные биты флагов для запросов GET

NLM_F_ROOT

Вернуть полную таблицу вместо одной записи.

NLM_F_MATCH

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

NLM_F_ATOMIC

Вернуть атомарный образ (snapshot) таблицы.

NLM_F_DUMP

Макрос для удобства; эквивалентен (NLM_F_ROOT|NLM_F_MATCH).

Заметим, что NLM_F_ATOMIC требует мандата CAP_NET_ADMIN или эффективного UID 0.

Дополнительные биты флагов для запросов NEW

NLM_F_REPLACE

Переписать существующий подходящий объект.

NLM_F_EXCL

Не перезаписывать, если объект уже существует.

NLM_F_CREATE

Создать объект, если он ещё не существует.

NLM_F_APPEND

Добавить в конец списка объектов.

Поля nlmsg_seq и nlmsg_pid используются для отслеживания передачи сообщений. В nlmsg_pid указывается источник сообщения. Заметим, что нет связи 1:1 между nlmsg_pid и PID процесса, если сообщение возникло из сокета netlink. Дополнительную информацию ищите в разделе ФОРМАТЫ АДРЕСА.

Тип поля nlmsg_seq и nlmsg_pid скрыт в ядре netlink.

Netlink не является надежным протоколом. Он делает всё возможное для доставки сообщения по адресу (адресам), но может отбрасывать пакеты при нехватке памяти или возникновении других ошибок в работе. Для повышения надёжности передачи отправитель может запросить подтверждение от получателя, установив флаг NLM_F_ACK. Подтверждающим является пакет NLMSG_ERROR с полем ошибки, равным нулю. Приложение должно само создавать подтверждения полученным сообщениям. Ядро пытается послать сообщение NLMSG_ERROR всем ошибочным пакетам. Процесс пользователя также должен следовать этому соглашению.

Однако, надёжная передача от ядра пользователю в любом случае невозможна. Ядро не может послать сообщение netlink, если заполнен буфер сокета: сообщение будет отброшено и ядро и пользовательский процесс будут иметь разное понятие о состоянии ядра. В обязанность приложения входит обнаружение такой ситуации (посредством ошибки ENOBUFS, возвращаемой recvmsg(2)) и выполнение восстановления синхронизации.

### Форматы адресов
Структура sockaddr_nl описывает клиент netlink в пространстве пользователя или в ядре. Она может быть как одноадресной (передача информации только на один адрес), так и посылаться многоадресной группе netlink (значение nl_groups не равно нулю).

```
struct sockaddr_nl {

    sa_family_t     nl_family;  /* AF_NETLINK */

    unsigned short  nl_pad;     /* ноль */

    pid_t           nl_pid;     /* ID порта */

    __u32           nl_groups;  /* маска многоадресных групп */
};
```

nl_pid — одиночный адрес сокета netlink. Он всегда равен 0, если местом назначения является ядро. Для процесса пользовательского пространства значение nl_pid, обычно, равно PID процесса, которому принадлежит сокет назначения. Однако, значением nl_pid определяется сокет netlink, а не процесс. Если процессу принадлежит несколько сокетов netlink, то значение nl_pid может быть равно ID процесса только у одного сокета. Есть два способа назначить nl_pid сокету netlink. Если приложение задаёт nl_pid до вызова bind(2), то приложение само должно убедиться, что значение nl_pid уникально. Если приложение устанавливает его равным 0, то присвоение уникального значения выполняется ядром. Первому сокету netlink ядро назначает ID процесса, который его открыл, а всем последующим создаваемым процессом сокетам netlink, будет назначено уникальное значение nl_pid.

Значение nl_groups — это битовая маска, где каждый бит представляет номер группы netlink. Каждое семейство netlink имеет набор из 32-х многоадресных групп. Когда для сокета вызывается bind(2), то поле nl_groups структуры sockaddr_nl должно содержать битовую маску групп, которые оно хочет прослушивать. По умолчанию значение этого поля равно нулю, что означает, что многоадресные передачи не будут приниматься. Сокет может передавать многоадресные сообщения любой из многоадресных групп, присвоив nl_groups битовую маску групп, которым он желает передавать данные вызовом sendmsg(2) или при выполнении connect(2). Принимать или посылать сообщения многоадресной группы netlink могут только процессы с эффективным UID, равным 0, или имеющие мандат CAP_NET_ADMIN. Начиная с Linux 2.6.13, сообщения не могут вещаться в многоадресные группы. Любые ответы на сообщение, полученное многоадресной группой, должны быть отправлены посылающему процессу с PID и многоадресной группе. Некоторые подсистемы ядра Linux могут разрешать отправку и/или приём сообщений другим пользователям. Начиная с Linux 3.0, в группах NETLINK_KOBJECT_UEVENT, NETLINK_GENERIC, NETLINK_ROUTE и NETLINK_SELINUX разрешено принимать сообщения от других пользователей. Отправлять сообщения другим пользователям запрещено.

### Параметры сокета
Для получения и задания параметров сокета netlink используйте вызовы getsockopt(2) и setsockopt(2), соответственно. Значение аргумента уровня параметров должно быть равно SOL_NETLINK. Если не указано обратного, значение optval является указателем на int.

NETLINK_PKTINFO (начиная с Linux 2.6.14)

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

NETLINK_ADD_MEMBERSHIP, NETLINK_DROP_MEMBERSHIP (начиная с Linux 2.6.14)

Присоединиться/покинуть группу, заданную в optval.

NETLINK_LIST_MEMBERSHIPS (начиная с Linux 4.2)

Получить все группы, в которых сокет является членом В аргументе optval передаётся указатель на __u32, а в optlen — размер массива. Массив заполняется полным набором членства сокета, а требуемый размер массива возвращается в optlen.

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

Если не установлен, то netlink_broadcast() сообщает только об ошибках ESRCH и игнорирует ошибки NOBUFS.

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

Данный флаг могут использовать слушающие одноадресные и широковещательные передачи, чтобы избежать ошибок ENOBUFS.

NETLINK_LISTEN_ALL_NSID (начиная с Linux 4.2)

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

NETLINK_CAP_ACK (начиная с Linux 4.2)

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

## ВЕРСИИ
Сокетный интерфейс для netlink впервые появился в Linux 2.2.

Linux 2.0 поддерживал более примитивный интерфейс на основе устройств (который всё ещё доступен для совместимости). Этот устаревший интерфейс здесь не описывается.

## ЗАМЕЧАНИЯ
В большинстве случаев лучше использовать netlink с помощью функций библиотек libnetlink или libnl, а не через низкоуровневый интерфейс ядра.

## ДЕФЕКТЫ
Эта справочной странице не содержится всей необходимой информации.

## ПРИМЕР
В следующем примере создаётся сокет netlink семейства NETLINK_ROUTE, который будет прослушивать многоадресные группы RTMGRP_LINK (события о создании/удалении/включении/выключении сетевых интерфейсов) и RTMGRP_IPV4_IFADDR (события о добавлении/удалении адресов IPv4).

```
struct sockaddr_nl sa;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
bind(fd, (struct sockaddr *) &sa, sizeof(sa));
```

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

```
struct nlmsghdr *nh; /* отправляется nlmsghdr с полезной нагрузкой */
struct sockaddr_nl sa;
struct iovec iov = { nh, nh->nlmsg_len };
struct msghdr msg;
msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
memset(&sa, 0, sizeof(sa));
sanl_family = AF_NETLINK;
nh->nlmsg_pid = 0;
nh->nlmsg_seq = ++sequence_number;
/* для запроса подтверждения от ядра, устанавливаем NLM_F_ACK */
nh->nlmsg_flags |= NLM_F_ACK;
sendmsg(fd, &msg, 0);
```

И последний пример о том, как выполнять чтение сообщения netlink.

```
int len;
char buf[8192];     /* 8192 чтобы сообщение не обрезалось на

                       платформах с размером страницы > 4096 */
struct iovec iov = { buf, sizeof(buf) };
struct sockaddr_nl sa;
struct msghdr msg;
struct nlmsghdr *nh;
msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
len = recvmsg(fd, &msg, 0);
for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);

     nh = NLMSG_NEXT (nh, len)) {

    /* конец сообщения из нескольких частей */

    if (nh->nlmsg_type == NLMSG_DONE)

        return;

    if (nh->nlmsg_type == NLMSG_ERROR)

        /* выполняем обработку ошибок */

    …

    /* разбираем полезную нагрузку */

    …
}
```

## СМОТРИТЕ ТАКЖЕ
cmsg(3), netlink(3), capabilities(7), rtnetlink(7), sock_diag(7)

Информация о libnetlink

Информация о libnl

RFC 3549 «Linux Netlink as an IP Services Protocol»


title: network_namespaces(7)

summary: обзор сетевых пространств имён Linux

text:
# network_namespaces(7)

## ИМЯ
network_namespaces - обзор сетевых пространств имён Linux

## ОПИСАНИЕ
Сетевые пространства имён позволяют изолировать системные ресурсы, связанные с сетью: сетевые устройства, стеки протоколов IPv4 и IPv6, таблицы IP-маршрутизации, правила межсетевых экранов, каталог /proc/net (символическая ссылка на /proc/PID/net), каталог /sys/class/net, различные файлы в /proc/sys/net, номера портов (сокеты) и т. п. Также сетевые пространства имён изолируют пространство имён абстрактных сокетов домена UNIX (смотрите unix(7)).

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

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

Для использования пространств имён network требуется, чтобы ядро было собрано с параметром CONFIG_NET_NS.

## СМОТРИТЕ ТАКЖЕ
nsenter(1), unshare(1), clone(2), veth(4), proc(5), sysfs(5), namespaces(7), user_namespaces(7), brctl(8), ip(8), ip-address(8), ip-link(8), ip-netns(8), iptables(8), ovs-vsctl(8)


nptl

title: nptl(7)

summary: библиотека нитей POSIX

text:
# nptl(7)

## ИМЯ
nptl - библиотека нитей POSIX

## ОПИСАНИЕ
NPTL (Native POSIX Threads Library — библиотека нитей POSIX) это библиотека GNU C, в которой реализованы нити POSIX, используется в современных версиях Linux.

### NPTL и сигналы
Внутри NPTL используются два первых сигнала реального времени (с номерами 32 и 33). Один из них служит для поддержки удаления (cancellation) нитей и таймеров POSIX (смотрите timer_create(2)); второй используется как часть механизма обеспечения всех нитей в одном процессе единым UID и GID, как того требует POSIX. Данные сигналы нельзя использовать в приложениях.

Чтобы не допустить случайного использования этих сигналов в приложениях, что может помешать работе реализации NPTL, в различных функциях библиотеки glibc и обёрточных функциях системных вызовов добавлено сокрытие этих сигналов от приложений:

- Сигнал SIGRTMIN определён со значением 34 (а не 32).

- Интерфейсы sigwaitinfo(2), sigtimedwait(2) и sigwait(3) игнорируют запросы на ожидание этих сигналов, если но указаны в аргументе набора сигналов.

- Интерфейсы sigprocmask(2) и pthread_sigmask(3) игнорируют попытки блокировки этих сигналов.

- Интерфейсы sigaction(2), pthread_kill(3) и pthread_sigqueue(3) завершаются с ошибкой EINVAL (указан некорректный номер сигнала), если заданы эти сигналы.

- Функция sigfillset(3) не включает эти сигналы при создании полного набора сигналов.

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

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

Обёрточные функции, использующие такую же технику: setgid(2), setuid(2), setegid(2), seteuid(2), setregid(2), setreuid(2), setresgid(2), setresuid(2) и setgroups(2).

## СООТВЕТСТВИЕ СТАНДАРТАМ
Дополнительную информацию о соответствии NPTL стандарту POSIX находится в pthreads(7).

## ЗАМЕЧАНИЯ
В POSIX сказано, что всем нитям процесса с доступом к памяти, содержащей общие для процесса (PTHREAD_PROCESS_SHARED) мьютексы, доступны эти мьютексы. Однако в 64-битных системах с архитектурой x86 определение мьютекса для x86-64 несовместимо с определением для i386, что означает, что исполняемые 32-битные и 64-битные файлы не могут иметь общих мьютексов в системах x86-64.

## СМОТРИТЕ ТАКЖЕ
credentials(7), pthreads(7), signal(7), standards(7)


numa

title: numa(7)

summary: обзор архитектуры с неравномерной памятью (Non\-Uniform Memory

text:
# numa(7)

## ИМЯ
numa - обзор архитектуры с неравномерной памятью (Non-Uniform Memory Architecture)

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

### Системные вызовы NUMA
В ядре Linux реализованы следующие системные вызовы, относящиеся к NUMA: get_mempolicy(2), mbind(2), migrate_pages(2), move_pages(2) и set_mempolicy(2). Однако, приложения, обычно, должны использовать интерфейс, предоставляемый библиотекой libnuma; смотрите «Поддержка в библиотеках» далее.

### /proc/[число]/numa_maps (начиная с Linux 2.6.14)
В этом файле содержится информация о политике и выделении памяти NUMA для процесса.

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

Файл numa_maps доступен только на чтение. При чтении /proc/<pid>/numa_maps ядро сканирует виртуальное адресное пространство процесса и выдаёт как используется память. Одна строка соответствует уникальной области памяти процесса.

В первом поле каждой строки содержится начальный адрес области памяти. Это поле позволяет провести параллель с файлом /proc/<pid>/maps, в котором содержится конечный адрес области и другая информация, такая как права доступа и данные о совместном использовании.

Во втором поле показана политика памяти, которая применена к области в настоящее время. Заметим, что применённая политика необязательно является политикой, установленной процессом для этой области памяти. В частности, если для этой области процесс установил политику «default» (по умолчанию), то применяемая политика для этой области будет политикой процесса, которая может совпадать, а может и не совпадать с «default».

В оставшейся части строки содержится информация о страницах, выделенных в области памяти:

N<узел>=<кол-во_страниц>

Количество страниц, выделенных на <узле>. В <кол-во_страниц> учитываются только страницы, отображённые процессом в настоящий момент. Перемещение (migration) страниц и возвращение памяти может приводить к временному неотображению страниц, связанных с этой областью памяти. Такие страницы могут появиться снова только после того, как процесс попытается обратиться к ним. Если область памяти считается общей или является отображением файла, то для других процессов в это же время могут быть показаны дополнительные страницы, отображённые в соответствующее адресное пространство.

file=<имя_файла>

Файл, отображаемый в область памяти. Если файл отображён как закрытый (private), попытка записи может сгенерировать страницы COW (копирование при записи) в этой области памяти. Эти страницы показываются как анонимные.

heap

Область памяти, используемая под кучу.

stack

Область памяти, используемая под стек.

huge

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

anon=<страниц>

Количество анонимных страниц в области.

dirty=<страниц>

Количество грязных (dirty) страниц.

mapped=<страниц>

Общее количество отображённых страниц, если оно отличается от количества страниц dirty и anon.

mapmax=<количество>

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

swapcache=<количество>

Количество страниц, связанных с участками на устройстве подкачки.

active=<страниц>

Количество страниц в активном списке. Это поле показывается только, если его значение отличается от количества страниц в этой области. Это означает, что в области памяти существует несколько неактивных страниц, которые могут быть скоро удалены swapper.

writeback=<страниц>

Количество страниц, которые в настоящий момент записываются на диск.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Интерфейсы NUMA не описаны в стандартах.

## ЗАМЕЧАНИЯ
Системные вызовы Linux NUMA и интерфейс /proc доступны только, если ядро было собрано с включённым параметром CONFIG_NUMA.

### Поддержка в библиотеках
Выполняйте компоновку с -lnuma. Библиотека libnuma и требуемый заголовочный файл <numaif.h> доступны в пакете numactl.

Однако, приложения не должны использовать эти системные вызовы напрямую. Вместо этого, рекомендуется использовать интерфейс высокого уровня, предоставляемый функциями numa(3) из пакета numactl. Пакет numactl доступен по адресу ftp://oss.sgi.com/www/projects/libnuma/download/. Пакет также включён в некоторые дистрибутивы Linux. Некоторые дистрибутивы помещают библиотеку для разработки и заголовочные файлы в пакет numactl-devel.

## СМОТРИТЕ ТАКЖЕ
get_mempolicy(2), mbind(2), move_pages(2), set_mempolicy(2), numa(3), cpuset(7), numactl(8)


operator

title: operator(7)

text:
# operator(7)

## ИМЯ
operator - приоритет и порядок вычисления операторов в Си

## ОПИСАНИЕ
В данной справочной странице показан приоритет и порядок вычисления операторов в языке Си.

Оператор

Ассоциативность

Примечания

() [] -> . ++ --

слева направо

[1]

! ~ ++ -- + - (type) * & sizeof

справа налево

[2]

* / %

слева направо

+ -

слева направо

<< >>

слева направо

< <= > >=

слева направо

== !=

слева направо

&

слева направо

^

слева направо

|

слева направо

&&

слева направо

||

слева направо

?:

справа налево

= += -= *= /= %= <<= >>= &= ^= |=

справа налево

,

слева направо

Примечания к таблице:

[1]

Операторы ++ и -- на этом уровне приоритета считаются постфиксной разновидностью операторов.

[2]

Операторы ++ и -- на этом уровне приоритета считаются префиксной разновидностью операторов.