pid 1200
다음과 같은 격리된 MOUNT 네임스페이스를 가진 프로세스가 있다고 가정해 보겠습니다 .unshare()
해당 네임스페이스를 상위 프로세스에서 격리합니다. 그런 다음 pid 1200
네임스페이스 내부에서만 액세스할 수 있는 장치를 마운트하고 싶습니다 pid 1200
. 가능합니까?
lxc.monitor.unshare = 1
컨테이너를 다시 시작 하지 않고 실행 중인 LXC 컨테이너 내부의 호스트 시스템에 장치를 마운트하거나 디렉터리를 바인드 마운트하고 싶습니다 .
답변1
이상적이지는 않지만 항상 NFS 또는 기타 네트워크 파일 시스템을 마운트할 수 있습니다.
다음 부분이 완료되었습니다.아니요작동합니다(적어도 4.2 커널에서는 아님). 사람들이 직접 시도할 필요가 없도록 참조용으로 보관하세요.
nsenter -m
마운트 네임스페이스( 또는 ) 를 입력하면 setns(CLONE_NEWNS)
작업 디렉터리가 자동으로 해당 네임스페이스( )의 루트로 변경되지만 /
일부 파일 설명자에서 디렉터리를 열고 네임스페이스를 입력하고 여전히 해당 네임스페이스에 있을 수 있습니다. 디렉터리 열기 공간적으로 fd합니다(예를 들어 fchdir()
a를 실행합니다).
따라서 이 접근 방식이 효과가 있을 것이라고 생각할 수 있습니다.
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sched.h>
void die(char *msg) {perror(msg); exit(1);}
int main(int argc, char *argv[]) {
int fd;
if (argc != 3) {
fprintf(stderr, "Usage: %s <source-in-current-namespace> <dest-in-namespace-on-stdin>\n");
exit(1);
}
fd = open(argv[1], O_RDONLY|O_DIRECTORY);
if (fd < 0) die("open");
if (setns(0, CLONE_NEWNS) < 0) die("setns");
if (fchdir(fd) < 0) die("fchdir");
printf("cwd: %s\n", get_current_dir_name());
if (mount(".", argv[2], 0, MS_BIND, 0) < 0) die("mount");
}
까지 작동 fchdir()
하지만 mount
다음에서는 실패합니다 EINVAL
.
# ~/a.out /home /mnt < /proc/1200/ns/mnt
cwd: (unreachable)/home
mount: Invalid argument
답변2
나는 이것으로 약간의 성공을 거두었습니다. lxc 컨테이너를 사용하지 않는 경우 다른 개인 마운트 네임스페이스와 작동하도록 만들었습니다. lxc는 내가 사용하는 기본 Linux 네임스페이스를 기반으로 구축되었으므로 이것이 작동하지 않을 이유가 없습니다.
먼저 네임스페이스를 다음과 같이 설정했습니다.
sudo unshare -m sh -c '
mount -ttmpfs none /tmp
echo x > /tmp/mytmp
findmnt -o+PROPAGATION /tmp
echo "$$"
cd /tmp
exec "$0" -i
TARGET SOURCE FSTYPE OPTIONS PROPAGATION
/tmp tmpfs tmpfs rw private
/tmp none tmpfs rw,relatime private
29384
$
...대화형 쉘이 생겼습니다. 별도의 터미널 세션에서 다음으로 한 일은...
sudo sh -c ' { cd /dev/fd/0 ; mkdir mnt
ls -l; cat mytmp
} 3<$0/ns/mnt <$0/29384/cwd
' /proc/29384
drwxr-xr-x 2 root root 40 Jan 4 02:52 mnt
-rw-r--r-- 1 root root 2 Jan 4 02:38 mytmp
x
...정말 고무적이네요!
하지만 거기에 마운트할 수는 없습니다. mount
상위 ns 디렉토리를 하위 ns의 디렉토리에 덮어쓰려고 할 때마다 실패합니다. 비참하게도 말이죠. 일부 연구에 따르면 이는 의도적으로 설계된 것입니다.(특히 PROPAGATION 플래그에 대한 경고를 참조하세요 man 7 user_namespaces
). 무엇했다그러나 직업은(새 네임스페이스에서):
sudo unshare --propagation slave -m sh -c '
mount -ttmpfs none /tmp; cd /tmp
exec "$0" -i'
그런 다음 상위 네임스페이스 세션에서...
sudo mount --bind / /mnt
sudo mount --bind / /tmp
sudo mount --bind /tmp /mnt/img/tmp
이제 위의 방법은 첫 번째 경우에는 작동하지만 두 번째 경우에는 작동하지 않습니다. 하위 ns는 fs 변경 사항을 위쪽으로 전파하지 않기 때문에 상위 ns는 fs 보기에 대한 변경 사항에 영향을 주지 않습니다. 따라서 아이에게는 자신만의 탈 것이 있으므로 /tmp
부모가 하는 일은 아무 것도 중요하지 않습니다. 그러나 공통 계층 구조가 있고 하위 ns가 파일 시스템 변경 사항을 수신하도록 구성된 경우~ 할 것이다상위 항목에서 아래로 전파된 변경 사항을 봅니다.
위 명령을 실행한 후 하위 ns에서...
ls /tmp /mnt /mnt/tmp
/mnt:
bin dev etc lib mnt proc run srv tmp var
boot esp home lib64 opt root sbin sys usr
/mnt/tmp:
serverauth.FT3Z6IFyWW
systemd-private-...systemd-timesyncd.service-YUkVU6
/tmp:
그래서 저는 그 질문에 대답하고 싶습니다. 예, 가능하다고 믿습니다. 그러나 나는 또한 당신이 필요하다고 확신합니다마련하다너무 이르다.
답변3
이 답변unshare(루트가 아님) 및 nsenter(컨테이너 내부의 루트)를 사용하여 바인드 마운트를 유발하고 동기적으로 호출하여 원하는 작업을 수행하는 몇 가지 작업 예제가 있습니다. 실제 루트 액세스가 필요하지 않습니다
안타깝게도 util-linux 2.39.1이 필요합니다. 이는 아마도 ubuntu 23.04 이상을 의미할 것입니다.
공유 해제 통화에는 이전에 상호 배타적인 옵션이 있었습니다.
나는 여전히 22.04(최신 LTS)와 같은 이전 우분투에서 작동하도록 노력하고 있습니다. 24.04가 나오면 시도를 중단하겠습니다.