From: Enrico Scholz Date: Fri, 29 Feb 2008 13:29:27 +0000 (+0000) Subject: use unshare(CLONE_NEWNS) instead of a complicated 'clone(NEWNS) ... waitpid()' operation X-Git-Tag: release-0.30.215~17 X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=724ab5b8c85dd45b6ad3c682d402f554f862f549;p=util-vserver.git use unshare(CLONE_NEWNS) instead of a complicated 'clone(NEWNS) ... waitpid()' operation git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2690 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- diff --git a/src/rpm-fake.c b/src/rpm-fake.c index 26c5fa8..c751dc8 100644 --- a/src/rpm-fake.c +++ b/src/rpm-fake.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -49,7 +49,7 @@ #include #include #include - +#include // from selinux.h // FIXME: add configure autodetection and include directly @@ -629,20 +629,12 @@ execvWorker(char const *path, char * const argv[], char * const envp[]) return res; } -struct ExecvParams -{ - char const * path; - char * const * argv; - char * const * envp; - char const * mnts; -}; - static int -removeNamespaceMountsChild(struct ExecvParams const *params) +removeNamespaceMounts(char const *mnts) { - char buf[strlen(params->mnts)+1], *ptr; + char buf[strlen(mnts)+1], *ptr; - strcpy(buf, params->mnts); + strcpy(buf, mnts); ptr = strtok(buf, ":"); while (ptr) { if (umount2(ptr, 0)==-1) { @@ -656,53 +648,27 @@ removeNamespaceMountsChild(struct ExecvParams const *params) ptr = strtok(0, ":"); } - return execvWorker(params->path, params->argv, params->envp); + return 0; } static int -removeNamespaceMounts(char const *path, - char * const argv[], char * const envp[]) +execv_main(char const *path, char * const argv[], char * const envp[]) { - if (mnts==0) return execvWorker(path, argv, envp); - - { - int status; - pid_t p, pid; - struct ExecvParams params; - - params.path = path; - params.argv = argv; - params.envp = envp; - params.mnts = mnts; - - // the rpmlib signal-handler is still active; use the default one to - // make wait4() working... - signal(SIGCHLD, SIG_DFL); - -#ifdef NDEBUG - pid = sys_clone(CLONE_NEWNS|SIGCHLD|CLONE_VFORK, 0); -#else - pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); -#endif - - switch (pid) { - case -1 : return -1; - case 0 : _exit(removeNamespaceMountsChild(¶ms)); - default : break; - } - - while ((p=wait4(pid, &status, 0,0))==-1 && - (errno==EINTR || errno==EAGAIN)) ; - - if (p==-1) return -1; - - if (WIFEXITED(status)) _exit(WEXITSTATUS(status)); - if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); + int rc = 0; + if (sys_unshare(CLONE_NEWNS)==-1) { + perror("unshare()"); return -1; } -} + if (mnts) + rc = removeNamespaceMounts(mnts); + + if (rc!=0) + return rc; + + return execvWorker(path, argv, envp); +} int execv(char const *path, char * const argv[]) @@ -715,7 +681,7 @@ execv(char const *path, char * const argv[]) WRITE_MSG(2, "', ...)\n"); } - return removeNamespaceMounts(path, argv, environ); + return execv_main(path, argv, environ); } int @@ -729,7 +695,7 @@ rpm_execcon(unsigned int UNUSED verified, WRITE_MSG(2, "', ...)\n"); } - return removeNamespaceMounts(filename, argv, envp); + return execv_main(filename, argv, envp); } int diff --git a/src/vnamespace.c b/src/vnamespace.c index c71cc9f..076b4e4 100644 --- a/src/vnamespace.c +++ b/src/vnamespace.c @@ -21,7 +21,7 @@ #endif #include "util.h" -#include +#include #include @@ -88,26 +88,14 @@ showVersion() } static void -newNamespace(char const *cmd) +newNamespace(void) { - pid_t pid; + int rc; - signal(SIGCHLD, SIG_DFL); - -#ifdef NDEBUG - pid = sys_clone(CLONE_NEWNS|CLONE_VFORK|SIGCHLD, 0); -#else - pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); -#endif - - switch (pid) { - case -1 : - perror("vnamespace: clone()"); - exit(wrapper_exit_code); - case 0 : - break; - default : - exitLikeProcess(pid, cmd, wrapper_exit_code); + rc = sys_unshare(CLONE_NEWNS); + if (rc!=0) { + perror("vnamespace: unshare()"); + exit(wrapper_exit_code); } } @@ -181,7 +169,7 @@ 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 { - if (do_new) newNamespace(argv[optind]); + if (do_new) newNamespace(); else if (do_set) setNamespace(VC_SAMECTX, CLONE_NEWNS|CLONE_FS); else if (do_cleanup) cleanupNamespace(); else if (do_enter) enterNamespace(xid, CLONE_NEWNS|CLONE_FS); diff --git a/src/vspace.c b/src/vspace.c index 4c1c64f..4819138 100644 --- a/src/vspace.c +++ b/src/vspace.c @@ -22,7 +22,7 @@ #endif #include "util.h" -#include +#include #include @@ -106,30 +106,14 @@ showVersion() } static void -newSpaces(uint_least64_t mask, const char *cmd) +newSpaces(uint_least64_t mask) { - pid_t pid; + int rc; - /* optimize default case */ - if (mask == 0) - return; - - signal(SIGCHLD, SIG_DFL); - -#ifdef NDEBUG - pid = sys_clone((int) mask | CLONE_VFORK|SIGCHLD, 0); -#else - pid = sys_clone((int) mask | SIGCHLD, 0); -#endif - - switch (pid) { - case -1 : - perror(ENSC_WRAPPERS_PREFIX "clone()"); - exit(wrapper_exit_code); - case 0 : - break; - default : - exitLikeProcess(pid, cmd, wrapper_exit_code); + rc = sys_unshare(mask); + if (rc) { + perror(ENSC_WRAPPERS_PREFIX "unshare()"); + exit(wrapper_exit_code); } } @@ -211,7 +195,7 @@ 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 { - if (do_new) newSpaces(mask, argv[optind]); + if (do_new) newSpaces(mask); else if (do_set) setSpaces(VC_SAMECTX, mask); else if (do_enter) enterSpaces(xid, mask);