LINUX.ORG.RU

Подскажите, как вытянуть pid для последующего nsenter

 ,


0

1

У меня есть неймспейс CHE в который я захожу так:

ip netns exec CHE unshare --ipc su - chabapok

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

Поэтому, в первой консоли я ввожу echo $$ и при помощи выданного PID захожу из второй консоли так: sudo nsenter PID

Так работает - но много надо вводить руками, еще и вручную этот пид из одной консоли в другую копипастить. Хочется вот этот процесс передачи пида как-то автоматизировать. И первое что приходит в голову - нужно чтобы первая команда записала этот пид в файл, а вторая прочитала. Но так просто это не получается. У команды su есть ключик -c команда, но если я им пользуюсь - то не остаюсь в неймспейсе. Команда выполняется и завершается.

Как такое сделать?

Для маны говорят, что unshare имеют форму --ipc=file:

If file is specified, then a persistent namespace is created by a bind mount.

Может это оно, но для чего оно и как им пользоваться - я не понял, и даже никаких внятных примеров не нашел. При чем тут mount, если это ipc. Если создать пустой файл и указывать его, то все работает точно так же. Помоему, это не то, что мне нужно.

man nsenter:

       By default, a new namespace persists only as long as it has member processes. A new namespace can be made persistent even when it has no member
       processes by bind mounting /proc/pid/ns/type files to a filesystem path. A namespace that has been made persistent in this way can subsequently be
       entered with nsenter(1) even after the program terminates (except PID namespaces where a permanently running init process is required). Once a
       persistent namespace is no longer needed, it can be unpersisted by using umount(8) to remove the bind mount. See the EXAMPLES section for more
       details.


Смотрим:

oas1 ~ # touch test
oas1 ~ # unshare --ipc=./test
oas1 ~ # ipcmk -M 100
Shared memory id: 0

oas1 ~ # ipcs

------ Очереди сообщений --------
ключ   msqid      владелец права исп. байты сообщения

------ Сегменты совм. исп. памяти --------
ключ   shmid      владелец права байты nattch     состояние
0xa4d27f94 0          root       644        100        0                       

------ Массивы семафоров --------
ключ   semid      владелец права nsems     

В соседней консоли(сначала смотрим есть ли точка монтирования для namespace):

oas1 ~ # mount | grep test
nsfs on /root/test type nsfs (rw)
oas1 ~ # nsenter --ipc=./test 
oas1 ~ # ipcs

------ Очереди сообщений --------
ключ   msqid      владелец права исп. байты сообщения

------ Сегменты совм. исп. памяти --------
ключ   shmid      владелец права байты nattch     состояние
0xa4d27f94 0          root       644        100        0                       

------ Массивы семафоров --------
ключ   semid      владелец права nsems     

Как видишь - созданная shared memory в наличии.

Pinkbyte ★★★★★
()
Ответ на: комментарий от Pinkbyte

Понял! Спасибо!

Странно. Получается, когда я ввожу

touch /tmp/test
ip netns exec CHE unshare --ipc=/tmp/test su - chabapok

то ip запускает unshare которое запускает su. И если так запускать, то почему-то ничего не маунтится, хотя неймспейс и создается.

А если запускать просто:

unshare --ipc=/tmp/test su - chabapok

то работает. Видимо, команда ip как-то парсит параметры калечно. Сижу-думаю.

chabapok
() автор топика
Ответ на: комментарий от chabapok

Странно. Получается, когда я ввожу

touch /tmp/test
ip netns exec CHE unshare --ipc=/tmp/test su - chabapok

то ip запускает unshare которое запускает su. И если так >запускать, то почему-то ничего не маунтится, хотя неймспейс и >создается.

все просто, контекст в контексте. Тут unshare запускает шелл с новым IPC namespace в CHE net namespace

kindof
()
Ответ на: комментарий от chabapok

Просто надо отделить создание постоянных namespace от входа в них:

oas1 ~ # ip netns add TEST
oas1 ~ # touch /root/test
oas1 ~ # ls -la /run/netns
total 0
drwxr-xr-x    2 root     root            80 Jun 21 20:10 .
drwxr-xr-x   10 root     root           760 Jun 19 12:40 ..
-r--r--r--    1 root     root             0 Jun 21 20:10 TEST
oas1 ~ # unshare --ipc=/root/test
oas1 ~ # exit
oas1 ~ # ip netns exec TEST ifconfig lo up
oas1 ~ # nsenter --ipc=/root/test --net=/run/netns/TEST bash
oas1 ~ # ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Суть проблемы в том, что unshare создает временные namespace для ВСЕГО(а не только для того, что ты указываешь аргументами). Поэтому когда ты делаешь unshare внутри ip netns exec оно создает тебе ВРЕМЕННЫЕ mount и сетевые namespace. И уже туда монтируется ipc namespace. Почему снаружи эти точки монтирования не видны - хороший вопрос, видимо такая двойная смена сетевого namespace для ip netns - это не очень хорошо.

В общем не надо так делать :-). Создавай постоянные ipc namespace через unshare(я не в курсе, может есть какая-то более вменяемая команда для работы с ipc namespace, типа ip netns add, которая пригодна для создания сетевых namespace), а входи сразу в ipc и network namespace через nsenter.

exit только не забывай делать после unshare - он вернет тебя назад и все ненужные тебе временные namespace схлопнутся

Pinkbyte ★★★★★
()
Последнее исправление: Pinkbyte (всего исправлений: 7)

И да, если не секрет - что ты там пытаешься делать? :-)

Просто если к IPC и network namespace ты еще какой-нибудь PID namespace захочешь прикрутить(а потом и mount namespace), то тут задача попахивает переходом на lxc(или даже docker, но скорее пока просто lxc).

Pinkbyte ★★★★★
()
Ответ на: комментарий от Pinkbyte

точно! Его видно изнутри почему-то. Даже внутри ip netns exec CHE его не видно:

$ sudo -i
# touch /tmp/test2
# ip netns exec CHE unshare --ipc=/tmp/test2 su - chabapok
CHE:~$ mount |grep test2
nsfs on /tmp/test2 type nsfs (rw)   // вот оно где!
CHE:~$ exit
logout
# mount |grep test2
# 

Спасибо. Теперь хоть понятно. Пойду посмотрю, что за lxc.

И да, если не секрет - что ты там пытаешься делать? :-)

Есть прожка, которая должна запускаться на разных компах, а я ее запускаю на одном, в разных неймспейсах и пытаюсь отладить. Ей хватает собственного сетевого и ipc неймспейса. А когда копии этой прожки видны в общем списке pid-ов, то это наоборот удобно, например для gdb.

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

chabapok
() автор топика
Ответ на: комментарий от chabapok

Справедливости ради:

когда копии этой прожки видны в общем списке pid-ов, то это наоборот удобно, например для gdb.

В docker можно отключить изоляцию pid namespace. Делается это опцией --pid=host

он эти образы долго конструирует

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

Тем не менее согласен с тем, что docker здесь как-то не очень подходит, но с lxc я давно не работал, не подскажу как оно там сейчас. Мне чаще приходиться эмулировать только сетевые namespace, так что руками это делать оказывается проще, чем лепить для этого контейнеры.

Pinkbyte ★★★★★
()