X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fvcontext.c;h=fd2f59fa439efb442e4ccd1316f33083da6e9b03;hb=27862613d32cb19d2d8ddbe2c9d13c01f114564c;hp=7f1a8099090759f1b6283a6234448430f1d49d95;hpb=e49176a0372f11f52309284b62fed5c2da98f3ab;p=util-vserver.git diff --git a/src/vcontext.c b/src/vcontext.c index 7f1a809..fd2f59f 100644 --- a/src/vcontext.c +++ b/src/vcontext.c @@ -24,6 +24,7 @@ #include "lib/internal.h" #include "lib_internal/jail.h" #include "lib_internal/sys_personality.h" +#include "lib_internal/sys_unshare.h" #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include @@ -66,6 +68,12 @@ #define CMD_PERSTYPE 0x400e #define CMD_PERSFLAG 0x400f #define CMD_VLOGIN 0x4010 +#define CMD_PIVOT_ROOT 0x4011 + + +#ifndef MNT_DETACH +#define MNT_DETACH 0x0002 +#endif struct option const @@ -90,6 +98,7 @@ CMDLINE_OPTIONS[] = { { "personality-type", required_argument, 0, CMD_PERSTYPE }, { "personality-flags", required_argument, 0, CMD_PERSFLAG }, { "vlogin", no_argument, 0, CMD_VLOGIN }, + { "pivot-root", no_argument, 0, CMD_PIVOT_ROOT }, #if 1 { "fakeinit", no_argument, 0, CMD_INITPID }, // compatibility #endif @@ -110,6 +119,7 @@ struct Arguments { uint_least32_t personality_type; int verbosity; bool do_chroot; + bool do_pivot_root; char const * uid; xid_t xid; char const * sync_sock; @@ -254,7 +264,7 @@ doit(struct Arguments const *args, int argc, char *argv[]) doSyncStage0(p, args->do_disconnect); if (args->do_create) { - xid = vc_ctx_create(args->xid); + xid = vc_ctx_create(args->xid, NULL); if (xid==VC_NOCTX) { switch (errno) { case EEXIST : @@ -274,8 +284,38 @@ doit(struct Arguments const *args, int argc, char *argv[]) if (args->do_chroot) { Echroot("."); if (args->set_namespace) { - if (args->do_migrateself) Evc_set_namespace(xid, 0); - else if (args->do_migrate) Evc_enter_namespace(xid, 0); + if (args->do_migrateself) Evc_set_namespace(xid, CLONE_NEWNS|CLONE_FS, 0); + else if (args->do_migrate) Evc_enter_namespace(xid, CLONE_NEWNS|CLONE_FS, 0); + } + } + else if (args->do_pivot_root) { + if (vc_enter_namespace(xid, CLONE_NEWNS | CLONE_FS, 1) == -1) { + bool existed = false; + if (sys_unshare(CLONE_NEWNS) == -1) { + perror(ENSC_WRAPPERS_PREFIX "unshare(NEWNS)"); + return wrapper_exit_code; + } + if (mkdir("./.oldroot", 0700) == -1) { + if (errno == EEXIST) + existed = true; + else { + perror(ENSC_WRAPPERS_PREFIX "mkdir()"); + return wrapper_exit_code; + } + } + if (pivot_root(".", "./.oldroot") == -1) { + perror(ENSC_WRAPPERS_PREFIX "pivot_root()"); + return wrapper_exit_code; + } + if (umount2("/.oldroot", MNT_DETACH) == -1) { + perror(ENSC_WRAPPERS_PREFIX "umount2()"); + return wrapper_exit_code; + } + if (!existed && rmdir("/.oldroot") == -1) { + perror(ENSC_WRAPPERS_PREFIX "rmdir()"); + return wrapper_exit_code; + } + Evc_set_namespace(xid, CLONE_NEWNS | CLONE_FS, 1); } } @@ -405,6 +445,7 @@ int main (int argc, char *argv[]) case CMD_VLOGIN : args.do_vlogin = true; break; case CMD_INITPID : args.is_initpid = true; break; case CMD_CHROOT : args.do_chroot = true; break; + case CMD_PIVOT_ROOT : args.do_pivot_root = true; break; case CMD_NAMESPACE : args.set_namespace = true; break; case CMD_SILENTEXIST : args.is_silentexist = true; break; case CMD_SYNCSOCK : args.sync_sock = optarg; break;