From 569b1bfe1e5954fa083532dc37d2fe7418ec2d4a Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Fri, 31 Oct 2008 15:41:04 +0000 Subject: [PATCH] Use pivot_root on kernels supporting two namespaces per context. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2819 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- lib/issupported.c | 3 ++- lib/issupportedstring.c | 2 +- lib/vserver.h | 1 + scripts/vserver.functions | 10 +++++++++- scripts/vserver.start | 2 +- scripts/vserver.stop | 2 +- scripts/vserver.suexec | 10 +++++----- src/secure-mount.c | 5 +++++ src/vcontext.c | 36 ++++++++++++++++++++++++++++++++++++ 9 files changed, 61 insertions(+), 10 deletions(-) diff --git a/lib/issupported.c b/lib/issupported.c index 7169db8..3fb32e6 100644 --- a/lib/issupported.c +++ b/lib/issupported.c @@ -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); } diff --git a/lib/issupportedstring.c b/lib/issupportedstring.c index a780fac..92b31bd 100644 --- a/lib/issupportedstring.c +++ b/lib/issupportedstring.c @@ -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 diff --git a/lib/vserver.h b/lib/vserver.h index 4d92b29..4508082 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -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; diff --git a/scripts/vserver.functions b/scripts/vserver.functions index b394f50..63d1bad 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -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 diff --git a/scripts/vserver.start b/scripts/vserver.start index d49bfdf..6658acb 100644 --- a/scripts/vserver.start +++ b/scripts/vserver.start @@ -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 diff --git a/scripts/vserver.stop b/scripts/vserver.stop index 033d0c3..d5c939e 100644 --- a/scripts/vserver.stop +++ b/scripts/vserver.stop @@ -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[@]}" \ diff --git a/scripts/vserver.suexec b/scripts/vserver.suexec index c7dfa04..f6c9e78 100644 --- a/scripts/vserver.suexec +++ b/scripts/vserver.suexec @@ -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 diff --git a/src/secure-mount.c b/src/secure-mount.c index 6dc2c41..57fe874 100644 --- a/src/secure-mount.c +++ b/src/secure-mount.c @@ -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; diff --git a/src/vcontext.c b/src/vcontext.c index 9768041..140062c 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,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; -- 1.8.1.5