diff -NurpPw --minimal util-vserver-0.30.196/scripts/vserver util-vserver-0.30.196-uv/scripts/vserver --- util-vserver-0.30.196/scripts/vserver 2004-08-27 23:06:45.000000000 +0200 +++ util-vserver-0.30.196-uv/scripts/vserver 2004-11-09 16:41:01.000000000 +0100 @@ -190,8 +190,6 @@ else VSERVER_NAME=$(basename "$VSERVER_DIR") fi -test "$2" != start -o "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \ - exec $_VNAMESPACE --new -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}" . $PKGLIBDIR/vserver.functions case "$2" in diff -NurpPw --minimal util-vserver-0.30.196/scripts/vserver.functions util-vserver-0.30.196-uv/scripts/vserver.functions --- util-vserver-0.30.196/scripts/vserver.functions 2004-10-19 23:07:51.000000000 +0200 +++ util-vserver-0.30.196-uv/scripts/vserver.functions 2004-11-11 13:28:40.000000000 +0100 @@ -653,6 +653,9 @@ function mountVserver local vdir=$1/vdir local mtab_src + isAvoidNamespace "$cfgdir" || \ + $_SECURE_MOUNT --rbind -n "$vdir" "$vdir" + test -e "$cfgdir"/fstab -o \ -e "$cfgdir"/fstab.local || return 0 @@ -669,9 +672,6 @@ function mountVserver _mountVserverInternal "$cfgdir"/fstab $_CHBIND "${CHBIND_OPTS[@]}" _mountVserverInternal "$cfgdir"/fstab.local - - isAvoidNamespace "$cfgdir" || \ - $_SECURE_MOUNT --rbind -n "$vdir" "/" } function _umountVserverInternal diff -NurpPw --minimal util-vserver-0.30.196/scripts/vserver.start util-vserver-0.30.196-uv/scripts/vserver.start --- util-vserver-0.30.196/scripts/vserver.start 2004-08-27 23:06:45.000000000 +0200 +++ util-vserver-0.30.196-uv/scripts/vserver.start 2004-11-09 16:58:52.000000000 +0100 @@ -93,10 +93,12 @@ test -z "$OPTION_DEFAULTTTY" || setDefau pushd "$VSERVER_DIR"/vdir/ >/dev/null is_configured=1 if $_VSERVER_INFO - FEATURE migrate; then - ${NICE_CMD[@]} \ + CMD1=`echo $_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \ + $_VNAMESPACE -d --socket /tmp/sock -c "$VSERVER_DIR"/vdir/; ` + + CMD2=`echo ${NICE_CMD[@]} \ $_CHBIND "${CHBIND_OPTS[@]}" -- \ - $_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \ - ${USE_VNAMESPACE:+$_VNAMESPACE --set -- } \ + $_VCONTEXT --migrate "${OPTS_VCONTEXT_CREATE[@]}" -- \ $_VLIMIT --dir "$VSERVER_DIR"/rlimits --missingok -- \ $_VSCHED --xid self "${OPTS_VSCHED[@]}" -- \ $_VUNAME --xid self --dir "$VSERVER_DIR"/uts --missingok -- \ @@ -105,8 +107,10 @@ if $_VSERVER_INFO - FEATURE migrate; the $_VATTRIBUTE --set "${OPTS_VATTRIBUTE[@]}" -- \ $_SAVE_CTXINFO "$VSERVER_DIR" \ $_ENV -i -- \ - $_VCONTEXT --migrate-self --endsetup --chroot $SILENT_OPT "${OPTS_VCONTEXT_MIGRATE[@]}" -- \ - "${INITCMD_START[@]}" + $_VCONTEXT --syncsock /tmp/sock --migrate-self --endsetup "$SILENT_OPT" "${OPTS_VCONTEXT_MIGRATE[@]}" -- \ + ${INITCMD_START[@]}` + $_VNAMESPACE -n /bin/bash -c "$CMD1 ; $CMD2" + rm /tmp/sock else if test "$_IS_FAKEINIT"; then startsync_pipe=$(mktemp /tmp/vserver-start.XXXXXX) diff -NurpPw --minimal util-vserver-0.30.196/scripts/vserver.stop util-vserver-0.30.196-uv/scripts/vserver.stop --- util-vserver-0.30.196/scripts/vserver.stop 2004-10-19 23:08:10.000000000 +0200 +++ util-vserver-0.30.196-uv/scripts/vserver.stop 2004-11-09 16:45:09.000000000 +0100 @@ -62,8 +62,7 @@ if test "$_IS_FAKEINIT" && \ $_VKILL -s INT -- "$initpid" || fail=1 elif $_VSERVER_INFO - FEATURE migrate; then "${NICE_CMD[@]}" \ - ${USE_VNAMESPACE:+$_VNAMESPACE --enter "$S_CONTEXT" -- } \ - $_VCONTEXT $SILENT_OPT --migrate --chroot --xid "$S_CONTEXT" -- \ + $_VCONTEXT $SILENT_OPT --namespace --migrate --xid "$S_CONTEXT" -- \ "${INITCMD_STOP[@]}" || fail=1 else "${NICE_CMD[@]}" \ diff -NurpPw --minimal util-vserver-0.30.196/scripts/vserver.suexec util-vserver-0.30.196-uv/scripts/vserver.suexec --- util-vserver-0.30.196/scripts/vserver.suexec 2004-04-15 04:00:21.000000000 +0200 +++ util-vserver-0.30.196-uv/scripts/vserver.suexec 2004-11-09 16:59:33.000000000 +0100 @@ -32,8 +32,7 @@ if $_VSERVER_INFO - FEATURE migrate; the if test -z "$is_stopped"; then exec \ $_CHBIND "${CHBIND_OPTS[@]}" \ - ${USE_VNAMESPACE:+$_VNAMESPACE --enter "$S_CONTEXT" -- } \ - $_VCONTEXT $SILENT_OPT --migrate --chroot --xid "$S_CONTEXT" --uid "$user" -- \ + $_VCONTEXT $SILENT_OPT --namespace --migrate --chroot --xid "$S_CONTEXT" --uid "$user" -- \ "$@" else exec \ @@ -41,7 +40,7 @@ if $_VSERVER_INFO - FEATURE migrate; the $_VCONTEXT --create "${OPTS_VCONTEXT_CREATE[@]}" -- \ $_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 --namespace --endsetup --chroot $SILENT_OPT -- \ "$@" fi else diff -NurpPw --minimal util-vserver-0.30.196/src/vcontext.c util-vserver-0.30.196-uv/src/vcontext.c --- util-vserver-0.30.196/src/vcontext.c 2004-10-18 18:11:48.000000000 +0200 +++ util-vserver-0.30.196-uv/src/vcontext.c 2004-11-09 16:50:09.000000000 +0100 @@ -56,6 +56,7 @@ #define CMD_MIGRATESELF 0x400a #define CMD_ENDSETUP 0x400b #define CMD_SILENTEXIST 0x400c +#define CMD_NAMESPACE 0x400d struct option const @@ -76,6 +77,7 @@ CMDLINE_OPTIONS[] = { { "chroot", no_argument, 0, CMD_CHROOT }, { "syncsock", required_argument, 0, CMD_SYNCSOCK }, { "syncmsg", required_argument, 0, CMD_SYNCMSG }, + { "namespace", no_argument, 0, CMD_NAMESPACE }, #if 1 { "fakeinit", no_argument, 0, CMD_INITPID }, // compatibility #endif @@ -90,6 +92,7 @@ struct Arguments { bool do_endsetup; bool is_initpid; bool is_silentexist; + bool namespace; int verbosity; bool do_chroot; uid_t uid; @@ -242,8 +245,15 @@ doit(struct Arguments const *args, char } tellContext(xid, args->verbosity>=1); } - else + else { xid = args->xid; + if (args->namespace) { + if (vc_enter_namespace(xid)==-1) { + perror("vnamespace: vc_enter_namespace()"); + exit(255); + } + } + } if (args->do_chroot) Echroot("."); @@ -287,6 +297,7 @@ int main (int argc, char *argv[]) .do_endsetup = false, .is_initpid = false, .is_silentexist = false, + .namespace = false, .verbosity = 1, .uid = -1, .xid = VC_DYNAMIC_XID, @@ -312,6 +323,7 @@ int main (int argc, char *argv[]) case CMD_UID : args.uid = atol(optarg); break; case CMD_XID : args.xid = Evc_xidopt2xid(optarg,true); break; case CMD_SILENT : --args.verbosity; break; + case CMD_NAMESPACE : args.namespace = true; break; case CMD_MIGRATESELF : args.do_migrate = true; args.do_migrateself = true; diff -NurpPw --minimal util-vserver-0.30.196/src/vnamespace.c util-vserver-0.30.196-uv/src/vnamespace.c --- util-vserver-0.30.196/src/vnamespace.c 2004-08-19 16:31:24.000000000 +0200 +++ util-vserver-0.30.196-uv/src/vnamespace.c 2004-11-09 10:10:14.000000000 +0100 @@ -15,7 +15,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +/* IIRC umount2 from dietlibc needs this... */ +#define _LINUX_SOURCE #ifdef HAVE_CONFIG_H # include #endif @@ -23,21 +24,36 @@ #include "util.h" #include +#include +#include + #include +#include #include #include +#include #include #include #include +#include +#include +#include +#include #define ENSC_WRAPPERS_PREFIX "vnamespace: " +#define ENSC_WRAPPERS_SOCKET 1 +#define ENSC_WRAPPERS_IOSOCK 1 +#define ENSC_WRAPPERS_IO 1 +#define ENSC_WRAPPERS_DISCONNECT 1 +#define ENSC_WRAPPERS_FCNTL 1 #define ENSC_WRAPPERS_UNISTD 1 #define ENSC_WRAPPERS_VSERVER 1 #include #define CMD_HELP 0x1000 #define CMD_VERSION 0x1001 +#define CMD_SOCKET 0x4000 int wrapper_exit_code = 255; @@ -48,7 +64,9 @@ CMDLINE_OPTIONS[] = { { "new", no_argument, 0, 'n' }, { "enter", required_argument, 0, 'e' }, { "set", no_argument, 0, 's' }, - { "cleanup", no_argument, 0, 'c' }, + { "cleanup", required_argument, 0, 'c' }, + { "socket", required_argument, 0, CMD_SOCKET }, + { "disconnect", no_argument, 0, 'd' }, {0,0,0,0} }; @@ -130,12 +148,73 @@ setNamespace() } static void -cleanupNamespace() +cleanupNamespace(char *newroot) { - if (vc_cleanup_namespace()==-1) { - perror("vnamespace: vc_cleanup_namespace()"); + /* + * We have to make sure that we create a directory that does not exist yet + * since pivot_root will fail if something is mounted on that directory. + * Ideas? + */ + char *oldroot = ".old"; + + chdir(newroot); + mkdir(oldroot, 0700); + if(pivot_root(".", oldroot) == -1) { + perror("pivot_root"); exit(255); } + chdir("/"); /* Make sure that we're actually in the newroot */ + umount2(oldroot, MNT_DETACH); + rmdir(oldroot); +} + +static void handleMessage(int fd) +{ + char buf[128]; + size_t len; + struct sockaddr_un addr; + socklen_t addr_len = sizeof(addr); + int new_fd = Eaccept(fd, &addr, &addr_len); + + len = Erecv(new_fd, buf, sizeof buf,0); + if (len==0) exit(1); + + // TODO: handle message??? +} + +static int +waitSocket(char const *filename, bool disc) +{ + int fd; + struct sockaddr_un sock; + fd_set fd_set; + + ENSC_INIT_UNIX_SOCK(sock, filename); + + fd = Esocket(PF_UNIX, SOCK_STREAM, 0); + Ebind(fd, &sock, sizeof sock); + Elisten(fd, 5); + if(disc) + { + signal(SIGCHLD, SIG_IGN); + switch(fork()) + { + case -1: perror("fork"); exit(EXIT_FAILURE); + case 0: break; + default: exit(EXIT_SUCCESS); + } + } + setsid(); + chdir("/"); + umask(0); + + FD_ZERO(&fd_set); + FD_SET(fd, &fd_set); + + Eselect(fd+1, &fd_set, 0, 0, 0); + if (FD_ISSET(fd, &fd_set)) handleMessage(fd); + + return fd; } int main(int argc, char *argv[]) @@ -144,11 +223,14 @@ int main(int argc, char *argv[]) bool do_enter = false; bool do_set = false; bool do_cleanup = false; + bool do_disconnect = false; + char const * socket_name= 0; xid_t xid = VC_NOCTX; int sum = 0; + int fd = 0; while (1) { - int c = getopt_long(argc, argv, "+nsce:", CMDLINE_OPTIONS, 0); + int c = getopt_long(argc, argv, "d+nsce:", CMDLINE_OPTIONS, 0); if (c==-1) break; switch (c) { @@ -162,6 +244,9 @@ int main(int argc, char *argv[]) xid = Evc_xidopt2xid(optarg,true); break; + case 'd' : do_disconnect = true; break; + case CMD_SOCKET : socket_name = optarg; break; + default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); @@ -181,14 +266,24 @@ int main(int argc, char *argv[]) else if (optind==argc && (do_new || do_enter)) WRITE_MSG(2, "No command specified; try '--help' for more information\n"); else { + /* Start sync */ + if (socket_name) fd = waitSocket(socket_name, do_disconnect); + if (do_new) newNamespace(argv[optind]); else if (do_set) setNamespace(); - else if (do_cleanup) cleanupNamespace(); - else if (do_enter) enterNamespace(xid); + else if (do_cleanup) { + cleanupNamespace(argv[optind]); + optind++; /* UGLY! ;-) */ + setNamespace(); /* Maybe allow clean + set instead? */ + } else if (do_enter) enterNamespace(xid); - if (optind