unshare -m não criando espaço de nomes de montagem

0

eu corri

unshare -mfp sh -c 'mount -tproc none /proc ; ls /proc'

Como esperado, isso imprimiu um / proc com apenas diretórios para PID 1 e PID 3, e saiu, deixando-me de volta no meu prompt antigo no namespace raiz.

Então eu fiz

ls /proc

e eu recebi uma listagem sem nenhum diretório PID. Eu estava esperando meu usual / proc cheio de processos. Eu tive que montar proc novamente para consertar as coisas.

Por que isso está acontecendo? Como faço para consertar as coisas para que o / proc montado dentro do namespace PID permaneça local para ele?

Eu tentei passar --mount-private para montar, mas não parece ter nenhum efeito.

Estou no Amazon Linux 2016.03 que vem com o util-linux 2.23.2.

    
por user6204751 29.04.2016 / 16:13

1 resposta

0

Ou o unshare (1) está quebrado ou eu sou idiota.

Eu modifiquei o código no link para que funcionasse para mim. Tinha que desmontar / proc preguiçosamente com umount2 e incluir linux/sched.h em vez de sched.h .

Para compilar do gcc foo.c -ofoo .

Você notará que, após a exibição, por exemplo, ./foo ls /proc , / proc no sistema host não será eliminado.

//
// This compiles and works on Amazon Linux 2016.03 (kernel 4.4.5-15.26.amzn1.x86_64)
//

#include <stdio.h>
#include <stdlib.h>
// was <sched.h>, but wouldn't compile on Amazon Linux
#include <linux/sched.h>
// for umount2()
#include <sys/mount.h>
#include <sys/wait.h>
#include <errno.h>

#define STACKSIZE (1024*1024)
static char child_stack[STACKSIZE];

struct clone_args {
        char **argv;
};

static int child_exec(void *stuff) {
        struct clone_args *args = (struct clone_args *)stuff;

        // the fprintf()s crash. Not sure why.

        // changed from umount(), lazy umount succeeds
        if (umount2("/proc", MNT_DETACH) != 0) {
                fprintf(stderr, "failed to unmount /proc: %s\n", strerror(errno));
                exit(-1);
        }

        if (mount("proc", "/proc", "proc", 0, "") != 0) {
                fprintf(stderr, "failed to mount /proc: %s\n", strerror(errno));
                exit(-1);
        }

        if (execvp(args->argv[0], args->argv) != 0) {
                fprintf(stderr, "failed to execvp arguments: %s\n", strerror(errno));
                exit(-1);
        }

        // unreachable
        exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
        struct clone_args args;
        args.argv = &argv[1];

        int clone_flags = CLONE_NEWPID | CLONE_NEWNS | SIGCHLD;
        pid_t pid = clone(child_exec, child_stack + STACKSIZE, clone_flags, &args);

        if (pid < 0) {
                fprintf(stderr, "clone failed: %s\n", strerror(errno));
                exit(EXIT_FAILURE);
        }

        if (waitpid(pid, NULL, 0) == -1) {
                fprintf(stderr, "failed to wait pid %d\n", pid);
                exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
}
    
por 06.05.2016 / 16:35

Tags