Use pivot_root on kernels supporting two namespaces per context.
authorDaniel Hokka Zakrisson <daniel@hozac.com>
Fri, 31 Oct 2008 15:41:04 +0000 (15:41 +0000)
committerDaniel Hokka Zakrisson <daniel@hozac.com>
Fri, 31 Oct 2008 15:41:04 +0000 (15:41 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2819 94cd875c-1c1d-0410-91d2-eb244daf1a30

lib/issupported.c
lib/issupportedstring.c
lib/vserver.h
scripts/vserver.functions
scripts/vserver.start
scripts/vserver.stop
scripts/vserver.suexec
src/secure-mount.c
src/vcontext.c

index 7169db8..3fb32e6 100644 (file)
@@ -49,7 +49,8 @@ vc_isSupported(vcFeatureSet feature)
     case vcFEATURE_VSTAT       :  return ver >= 0x00020103;
     case vcFEATURE_PPTAG       :  return conf & VC_VCI_PPTAG;
     case vcFEATURE_SPACES      :  return conf & VC_VCI_SPACES;
-    case vcFEATURE_PIDSPACE    :  return ver >= 0x00020304 || ver >= 0x00020201;
+    case vcFEATURE_PIVOT_ROOT  :  return ver >= 0x00020304;
+    case vcFEATURE_PIDSPACE    :  return ver >= 0x00020305;
     default                    :  assert(false); 
   }
 
index a780fac..92b31bd 100644 (file)
@@ -35,7 +35,7 @@ static struct {
   DECL(MIGRATE), DECL(NAMESPACE), DECL(SCHED),    DECL(VINFO),
   DECL(VHI),     DECL(VSHELPER0), DECL(VSHELPER), DECL(VWAIT),
   DECL(VNET),    DECL(VSTAT),     DECL(PPTAG),    DECL(PIDSPACE),
-  DECL(SPACES),  DECL(PERSISTENT),
+  DECL(SPACES),  DECL(PERSISTENT),DECL(PIVOT_ROOT),
 };
 
 bool
index 4d92b29..4508082 100644 (file)
@@ -974,6 +974,7 @@ extern "C" {
                  vcFEATURE_VSHELPER0, vcFEATURE_VSHELPER, vcFEATURE_VWAIT,
                 vcFEATURE_VNET,   vcFEATURE_VSTAT,   vcFEATURE_PPTAG,
                 vcFEATURE_PIDSPACE, vcFEATURE_SPACES, vcFEATURE_PERSISTENT,
+                vcFEATURE_PIVOT_ROOT,
                 }
     vcFeatureSet;
 
index b394f50..63d1bad 100644 (file)
@@ -41,6 +41,7 @@ declare -a ENTER_SHELL=()
 declare -a OPTS_VCONTEXT_CREATE=()
 declare -a OPTS_VCONTEXT_MIGRATE=()
 declare -a OPTS_VCONTEXT_ENTER=()
+OPT_VCONTEXT_CHROOT=--chroot
 declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
 declare -a OPTS_VSCHED=()
 declare -a OPTS_ENV=()
@@ -405,6 +406,8 @@ function _generateFlagOptions
     isAvoidNamespace "$vdir" || {
        USE_VNAMESPACE=1
        CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
+       ! $_VSERVER_INFO - FEATURE PIVOT_ROOT || \
+           OPT_VCONTEXT_CHROOT=--pivot-root
     }
 }
 
@@ -940,6 +943,8 @@ function mountVserver
     local ns_opt=$2
     local vdir=$1/vdir
     local mtab_src
+    local extra_opt=
+    local real_vdir
 
     test -e "$cfgdir"/fstab -o \
          -e "$cfgdir"/fstab.local -o \
@@ -960,8 +965,11 @@ function mountVserver
     isNamespaceCleanup "$cfgdir" && \
         _namespaceCleanup "$cfgdir"
 
+    real_vdir=$(getPhysicalDir "$vdir")
+    ! $_VSERVER_INFO - FEATURE PIVOT_ROOT || \
+       extra_opt=,shared
     isAvoidNamespace "$cfgdir" || \
-       $_SECURE_MOUNT --rbind -n -o dev "$vdir" "/"
+       $_SECURE_MOUNT --rbind -n -o dev$extra_opt "$vdir" "$real_vdir"
 }
 
 function _umountVserverInternal
index d49bfdf..6658acb 100644 (file)
@@ -155,7 +155,7 @@ if $_VSERVER_INFO - FEATURE migrate; then
     $_VATTRIBUTE --set "${OPTS_VATTRIBUTE[@]}" -- \
     $_SAVE_CTXINFO "$VSERVER_DIR" \
     $_ENV -i "${OPTS_ENV[@]}" \
-    $_VCONTEXT   --migrate-self --endsetup --chroot $SILENT_OPT \
+    $_VCONTEXT   --migrate-self --endsetup $OPT_VCONTEXT_CHROOT $SILENT_OPT \
     "${OPTS_VCONTEXT_MIGRATE[@]}" "${OPTS_VCONTEXT_ENTER[@]}" -- \
     "${INITCMD_START[@]}"
 else
index 033d0c3..d5c939e 100644 (file)
@@ -85,7 +85,7 @@ elif $_VSERVER_INFO - FEATURE migrate; then
     "${CHBIND_CMD[@]}" \
     "$_VSPACE" --enter "$S_CONTEXT" "${OPTS_VSPACE[@]}" -- \
     "$_VTAG" --migrate "${OPTS_VTAG_ENTER[@]}" --silent -- \
-    $_VCONTEXT $SILENT_OPT --migrate --chroot --xid "$S_CONTEXT" -- \
+    $_VCONTEXT $SILENT_OPT --migrate $OPT_VCONTEXT_CHROOT --xid "$S_CONTEXT" -- \
     "${INITCMD_STOP[@]}" || fail=1
 else
     "${IONICE_CMD[@]}" \
index c7dfa04..f6c9e78 100644 (file)
@@ -41,7 +41,7 @@ if $_VSERVER_INFO - FEATURE migrate; then
        ${USE_VNAMESPACE:+$_VNAMESPACE --enter "$S_CONTEXT" -- } \
        $_VSPACE --enter "$S_CONTEXT" "${OPTS_VSPACE[@]}" -- \
        $_VTAG --migrate "${OPTS_VTAG_ENTER[@]}" --silent -- \
-       $_VCONTEXT $SILENT_OPT --migrate --chroot \
+       $_VCONTEXT $SILENT_OPT --migrate $OPT_VCONTEXT_CHROOT \
          --xid "$S_CONTEXT" --uid "$user" "${OPTS_VCONTEXT_ENTER[@]}" -- \
        "$@"
     else
@@ -51,12 +51,12 @@ if $_VSERVER_INFO - FEATURE migrate; then
        "${CHBIND_CMD[@]}" \
        $_EXEC_ULIMIT "$VSERVER_DIR/ulimits" \
        $_VTAG --create "${OPTS_VTAG_CREATE[@]}" --silent -- \
-       $_VSPACE --new "${OPTS_VSPACE[@]}" -- \
+       $_VSPACE --new "${OPTS_VSPACE[@]}" ${USE_VNAMESPACE:+--mount --fs} -- \
         $_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \
-       $_VSPACE --set "${OPTS_VSPACE[@]}" -- \
-       $_VUNAME   --xid self --dir "$VSERVER_DIR"/uts     --missingok -- \
+       $_VSPACE --set "${OPTS_VSPACE[@]}" ${USE_VNAMESPACE:+--mount --fs} -- \
+       $_VUNAME   --xid self --dir "$VSERVER_DIR"/uts --missingok -- \
        $_VUNAME   --xid self --set -t context="$VSERVER_DIR" -- \
-       $_VCONTEXT --migrate-self --endsetup --chroot $SILENT_OPT -- \
+       $_VCONTEXT --migrate-self --endsetup $OPT_VCONTEXT_CHROOT $SILENT_OPT -- \
        "$@"
     fi
 else
index 6dc2c41..57fe874 100644 (file)
@@ -153,6 +153,11 @@ static struct FstabOption {
   { "noauto",     0,              0,               XFLAG_NOAUTO, false },
   { "user",       0,              0,               0, false },
   { "nouser",     0,              0,               0, false },
+  { "rec",        MS_REC,         MS_REC,          0, false },
+  { "unbindable", MS_UNBINDABLE,  MS_UNBINDABLE,   0, false },
+  { "private",    MS_PRIVATE,     MS_PRIVATE,      0, false },
+  { "slave",      MS_SLAVE,       MS_SLAVE,        0, false },
+  { "shared",     MS_SHARED,      MS_SHARED,       0, false },
 };
 
 int                    wrapper_exit_code = 1;
index 9768041..140062c 100644 (file)
@@ -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 <vserver.h>
 #include <getopt.h>
@@ -36,6 +37,7 @@
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
+#include <sys/mount.h>
 
 #include <linux/personality.h>
 
@@ -66,6 +68,7 @@
 #define CMD_PERSTYPE           0x400e
 #define CMD_PERSFLAG           0x400f
 #define CMD_VLOGIN             0x4010
+#define CMD_PIVOT_ROOT         0x4011
 
 
 struct option const
@@ -90,6 +93,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 +114,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;
@@ -278,6 +283,36 @@ doit(struct Arguments const *args, int argc, char *argv[])
        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);
+      }
+    }
 
     setFlags(args, xid);
 
@@ -405,6 +440,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;