Как сделать пространство имен видимым внутри процесса chrooted/NEWPID

Эта переменная извлекается из colorsавтозагружаемой функции.

Вам нужно загрузить и запустить эту функцию:

autoload colors
colors

Обратите внимание, что вы также можете использовать подсказку, которая не требует этой функции colors:

print -P %F{red}

Или:

echo ${(%):-%F{red}}

В любом случае, это переменная ассоциативного массива оболочки , а не то, что можно или нужно экспортировать в среду. Если вы хотите увидеть его объявление, используйтеtypeset -p fg_bold(обратите внимание, что переменная имеет атрибут-H(скрыть значение ), поэтому typeset -pбудет отображать значения, вы можете удалить этот атрибут с помощью typeset +H fg_boldили посмотреть значения с помощьюtypeset fg_bold).

1
19.08.2020, 03:46
1 ответ

Обратите внимание, что /var/runявляется символической ссылкой на /runи должна быть «разрешена» заранее, иначе /mnt/var/runможет указывать на /runс помощью различных команд.

На первый взгляд этой более простой команды (, а не OP, которая никогда не может работать, как объяснено в последнем примечании в конце )из начального пространства имен, должно быть достаточно, чтобы позволить ip netns execработать из chrooted pid пространство имен:

mount --bind /run/netns/test1 /mnt/run/netns/test1

но это не так. Это связано не с пространством имен pid , а с chroot . На самом деле вся проблема такая же, когда вообще не переключаешься на новое пространство имен pid .

ip netns execне манипулирует только сетевыми пространствами имен, но также должен манипулировать mount пространствами имен и использовать mount (2)системные вызовы по причинам, которые я объяснил в этот SF Q/A:Невозможно создать вложенное сетевое пространство имен .


Проблема :chroot

/procдолжен быть смонтирован внутри chroot для корректной работы. По крайней мере, /proc, смонтированный из chroot, используя strace, можно увидеть, что ip netns exec test1...войдет в новое пространство имен монтирования и не сможет перемонтировать/:

getuid()                                = 0
openat(AT_FDCWD, "/run/netns/test1", O_RDONLY|O_CLOEXEC) = 3
setns(3, CLONE_NEWNET)                  = 0
close(3)                                = 0
unshare(CLONE_NEWNS)                    = 0
mount("", "/", 0x5595a749373f, MS_REC|MS_SLAVE, NULL) = -1 EINVAL (Invalid argument)
write(2, "\"mount --make-rslave /\" failed: "..., 49) = 49
exit_group(-1)                          = ?
+++ exited with 255 +++

Ошибка повторного монтирования сEINVAL:из-за того, что chroot , /больше не является точкой монтирования.

Обратите внимание, что часть пространства имен network сама по себе не вызывает проблем. Так, например, делая это со стороны chroot:

nsenter --net=/run/netns/test1 ip link

завершится успешно и отобразит test1 сетевые интерфейсы, но, например, не будет переключать соответствующие записи, доступные в /sys/, как сделал бы ip netns exec(, как описано в моей предыдущей ссылке ), если те быть нужным.


Решение :добавить привязку поверх самого себя

Исправление :bind -монтирует цель chroot к себе, чтобы принудительно превратить ее в точку монтирования, желательно в приватном режиме, чтобы избежать взаимодействий (, особенно когда systemd превратил /общий )перед выполнением chroot .

Ниже я воспроизвожу рабочую установку с командами оболочки.

Я опускаю некоторые шаблоны, например, монтирование/run(ака init/mnt/run)из tmpfs и т. д., но монтирование /procиз chroot действительно должно быть выполнено.

первый в семестре1:

~# unshare --fork --pid bash
~# echo $$
1
~# mount --bind --make-private /mnt /mnt
~# chroot /mnt bash
/# mount -t proc proc /proc

затем в несвязанном термине2:

 ~# ip netns add test1
 ~# mkdir -p /mnt/run/netns
 ~# touch /mnt/run/netns/test1
 ~# mount --bind /run/netns/test1 /mnt/run/netns/test1

снова в срок1:

/# ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Примечания:

  • , как было сказано ранее, не имеет отношения к пространству имен pid . Удаление команды unshare --fork --pid bashрешит ту же проблему при использовании только chroot без пространства имен pid .

  • команда монтирования никогда не должна запускаться из команды ip netns exec.Помните, что ip netns execсам по себе создает временное пространство имен монтирования. Какое бы ездовое животное ни было сделано внутри, оно исчезнет, ​​когда ip netns execзакончится. Это также объясняется в моей предыдущей ссылке. Вместо этого все равно будет нормально:

    nsenter --net=/run/netns/test1 mount --bind /proc/self/ns/net /mnt/var/run/netns/test1
    

    но, конечно, не требуется, так как это точно такой же объект, который можно проверить, имея тот же индекс в виртуальной файловой системе nsfs :

    ~# stat -f -c %T /run/netns/test1; stat -c %i /run/netns/test1
    nsfs
    4026533129
    ~# nsenter --net=/run/netns/test1 sh -c 'stat -f -L -c %T /proc/self/ns/net; stat -L -c %i /proc/self/ns/net'
    nsfs
    4026533129
    
0
18.03.2021, 23:11

Теги

Похожие вопросы