Changeset 2690

Show
Ignore:
Timestamp:
02/29/08 14:29:27 (9 months ago)
Author:
ensc
Message:

use unshare(CLONE_NEWNS) instead of a complicated 'clone(NEWNS) ... waitpid()' operation

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/rpm-fake.c

    r2677 r2690  
    2626#include <lib/vserver.h> 
    2727#include <lib/internal.h> 
    28 #include <lib_internal/sys_clone.h> 
     28#include <lib_internal/sys_unshare.h> 
    2929 
    3030#include <sys/socket.h> 
     
    5050#include <pwd.h> 
    5151#include <grp.h> 
    52  
     52#include <sched.h> 
    5353 
    5454  // from selinux.h 
     
    630630} 
    631631 
    632 struct ExecvParams 
    633 { 
    634     char const *        path; 
    635     char * const *      argv; 
    636     char * const *      envp; 
    637     char const *        mnts; 
    638 }; 
    639  
    640632static int 
    641 removeNamespaceMountsChild(struct ExecvParams const *params) 
    642 { 
    643   char                  buf[strlen(params->mnts)+1], *ptr; 
    644  
    645   strcpy(buf, params->mnts); 
     633removeNamespaceMounts(char const *mnts) 
     634{ 
     635  char                  buf[strlen(mnts)+1], *ptr; 
     636 
     637  strcpy(buf, mnts); 
    646638  ptr = strtok(buf, ":"); 
    647639  while (ptr) { 
     
    657649  } 
    658650 
    659   return execvWorker(params->path, params->argv, params->envp)
     651  return 0
    660652} 
    661653 
    662654static int 
    663 removeNamespaceMounts(char const *path, 
    664                       char * const argv[], char * const envp[]) 
    665 
    666   if (mnts==0) return execvWorker(path, argv, envp); 
    667  
    668   { 
    669     int                         status; 
    670     pid_t                       p, pid; 
    671     struct ExecvParams          params; 
    672  
    673     params.path = path; 
    674     params.argv = argv; 
    675     params.envp = envp; 
    676     params.mnts = mnts; 
    677  
    678       // the rpmlib signal-handler is still active; use the default one to 
    679       // make wait4() working... 
    680     signal(SIGCHLD, SIG_DFL); 
    681  
    682 #ifdef NDEBUG 
    683     pid = sys_clone(CLONE_NEWNS|SIGCHLD|CLONE_VFORK, 0); 
    684 #else 
    685     pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); 
    686 #endif 
    687  
    688     switch (pid) { 
    689       case -1   :  return -1; 
    690       case 0    :  _exit(removeNamespaceMountsChild(&params)); 
    691       default   :  break; 
    692     } 
    693          
    694     while ((p=wait4(pid, &status, 0,0))==-1 && 
    695            (errno==EINTR || errno==EAGAIN)) ; 
    696  
    697     if (p==-1)   return -1; 
    698  
    699     if (WIFEXITED(status))   _exit(WEXITSTATUS(status)); 
    700     if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); 
    701  
     655execv_main(char const *path, char * const argv[], char * const envp[]) 
     656
     657  int           rc = 0; 
     658 
     659  if (sys_unshare(CLONE_NEWNS)==-1) { 
     660    perror("unshare()"); 
    702661    return -1; 
    703662  } 
    704 
    705  
     663 
     664  if (mnts) 
     665    rc = removeNamespaceMounts(mnts); 
     666 
     667  if (rc!=0) 
     668    return rc; 
     669   
     670  return execvWorker(path, argv, envp); 
     671
    706672 
    707673int 
     
    716682  } 
    717683 
    718   return removeNamespaceMounts(path, argv, environ); 
     684  return execv_main(path, argv, environ); 
    719685} 
    720686 
     
    730696  } 
    731697 
    732   return removeNamespaceMounts(filename, argv, envp); 
     698  return execv_main(filename, argv, envp); 
    733699} 
    734700 
  • trunk/src/vnamespace.c

    r2415 r2690  
    2222 
    2323#include "util.h" 
    24 #include <lib_internal/sys_clone.h> 
     24#include <lib_internal/sys_unshare.h> 
    2525 
    2626#include <vserver.h> 
     
    8989 
    9090static void 
    91 newNamespace(char const *cmd) 
     91newNamespace(void) 
    9292{ 
    93   pid_t                pid
     93  int          rc
    9494 
    95   signal(SIGCHLD, SIG_DFL); 
    96    
    97 #ifdef NDEBUG     
    98   pid = sys_clone(CLONE_NEWNS|CLONE_VFORK|SIGCHLD, 0); 
    99 #else 
    100   pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); 
    101 #endif 
    102  
    103   switch (pid) { 
    104     case -1     : 
    105       perror("vnamespace: clone()"); 
    106       exit(wrapper_exit_code); 
    107     case 0      : 
    108       break; 
    109     default     : 
    110       exitLikeProcess(pid, cmd, wrapper_exit_code); 
     95  rc = sys_unshare(CLONE_NEWNS); 
     96  if (rc!=0) { 
     97    perror("vnamespace: unshare()"); 
     98    exit(wrapper_exit_code); 
    11199  } 
    112100} 
     
    182170    WRITE_MSG(2, "No command specified; try '--help' for more information\n"); 
    183171  else { 
    184     if      (do_new)     newNamespace(argv[optind]); 
     172    if      (do_new)     newNamespace(); 
    185173    else if (do_set)     setNamespace(VC_SAMECTX, CLONE_NEWNS|CLONE_FS); 
    186174    else if (do_cleanup) cleanupNamespace(); 
  • trunk/src/vspace.c

    r2679 r2690  
    2323 
    2424#include "util.h" 
    25 #include <lib_internal/sys_clone.h> 
     25#include <lib_internal/sys_unshare.h> 
    2626 
    2727#include <vserver.h> 
     
    107107 
    108108static void 
    109 newSpaces(uint_least64_t mask, const char *cmd) 
    110 
    111   pid_t pid; 
    112  
    113   /* optimize default case */ 
    114   if (mask == 0) 
    115     return; 
    116  
    117   signal(SIGCHLD, SIG_DFL); 
    118  
    119 #ifdef NDEBUG 
    120   pid = sys_clone((int) mask | CLONE_VFORK|SIGCHLD, 0); 
    121 #else 
    122   pid = sys_clone((int) mask | SIGCHLD, 0); 
    123 #endif 
    124  
    125   switch (pid) { 
    126     case -1     : 
    127       perror(ENSC_WRAPPERS_PREFIX "clone()"); 
    128       exit(wrapper_exit_code); 
    129     case 0      : 
    130       break; 
    131     default     : 
    132       exitLikeProcess(pid, cmd, wrapper_exit_code); 
     109newSpaces(uint_least64_t mask) 
     110
     111  int rc; 
     112 
     113  rc = sys_unshare(mask); 
     114  if (rc) { 
     115          perror(ENSC_WRAPPERS_PREFIX "unshare()"); 
     116          exit(wrapper_exit_code); 
    133117  } 
    134118} 
     
    212196    WRITE_MSG(2, "No command specified; try '--help' for more information\n"); 
    213197  else { 
    214     if      (do_new)     newSpaces(mask, argv[optind]); 
     198    if      (do_new)     newSpaces(mask); 
    215199    else if (do_set)     setSpaces(VC_SAMECTX, mask); 
    216200    else if (do_enter)   enterSpaces(xid, mask);