version 0.29.201
[util-vserver.git] / util-vserver / src / rpm-fake.c
index 1c2da07..f53a9db 100644 (file)
 #endif
 
 #include "pathconfig.h"
+#include "sys_clone.h"
 #include "util.h"
 
-#include <vserver.h>
+#include "lib/vserver.h"
+#include "lib/internal.h"
 
+#include <sys/socket.h>
 #include <dlfcn.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <sys/socket.h>
 #include <sys/un.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <grp.h>
 
+#define ENSC_WRAPPERS_PREFIX   "rpm-fake.so: "
+#define ENSC_WRAPPERS_VSERVER  1
+#define ENSC_WRAPPERS_UNISTD   1
+#include <wrappers.h>
+
 #ifndef CLONE_NEWNS
 #  define CLONE_NEWNS  0x00020000
 #endif
@@ -56,7 +63,7 @@
 #define PLATFORM_FILE  "/etc/rpm/platform"
 
 #define INIT(FILE,FUNC)        FUNC##_func = ((__typeof__(FUNC) *) (xdlsym(FILE, #FUNC)))
-#define DECLARE(FUNC)  static __typeof__(FUNC) *       FUNC##_func = 0
+#define DECLARE(FUNC)  static __typeof__(FUNC) *       FUNC##_func = 0
 
 
 #define DBG_INIT       0x0001
@@ -68,7 +75,7 @@
 #define DBG_VERBOSE2   (0x2000 | DBG_VERBOSE1)
 
 static char const *    ctx_s = 0;
-static ctx_t           ctx   = VC_NOCTX;
+static xid_t           ctx   = VC_NOCTX;
 static uint32_t                caps  = ~0;
 static int             flags = 0;
 static char const *    mnts  = 0;
@@ -162,6 +169,33 @@ getAndClearEnv(char const *key, int dflt)
   return res;
 }
 
+static void
+setupContext(xid_t xid)
+{
+  
+  if (vc_isSupported(vcFEATURE_MIGRATE)) {
+    xid_t      rc = vc_create_context(xid);
+    if (rc==VC_NOCTX && errno!=EEXIST) {
+      perror("rpm-fake.so: vc_create_context()");
+      exit(255);
+    }
+
+    if (rc!=VC_NOCTX) {
+      char             buf[128];
+      size_t           l;
+      strcpy(buf, "rpm-fake.so #");
+      l = utilvserver_fmt_uint(buf+sizeof("rpm-fake.so #")-1, getppid());
+      Evc_set_vhi_name(rc, vcVHI_CONTEXT, buf, sizeof("rpm-fake.so #")+l-1);
+#warning set some sane capabilities
+       // context will be activated later...
+
+      xid = rc;
+    }
+  }
+
+  Ewrite(3, &xid, sizeof xid);
+}
+
 #if 0
 static void
 initPwSocket()
@@ -180,7 +214,7 @@ initPwSocket()
        connect(pw_sock, (struct sockaddr *)(&addr), sizeof addr)==-1 ||
        (flag=fcntl(pw_sock, F_GETFD))==-1 ||
        fcntl(pw_sock, F_SETFD, flag | FD_CLOEXEC)==-1) {
-      perror("error while initializing pw-socket");
+      perror("rpm-fake.so: error while initializing pw-socket");
       exit(255);
     }
   }
@@ -225,8 +259,11 @@ initPwSocket()
       setsid();
       dup2(res_sock[1],  0);
       dup2(res_sock[1],  1);
-      dup2(sync_pipe[1], 2);
-      close(sync_pipe[1]);
+      if (sync_pipe[1]!=3) {
+       close(3);
+       dup2(sync_pipe[1], 3);
+       close(sync_pipe[1]);
+      }
       close(res_sock[1]);
        /* ... *socket[0] are marked as close-on-exec ...*/
 
@@ -236,7 +273,8 @@ initPwSocket()
       if (gid)   { *ptr++ = "-g"; *ptr++ = gid;   }
       if (ctx_s) { *ptr++ = "-c"; *ptr++ = ctx_s; }
       *ptr++ = 0;
-      
+
+      setupContext(ctx);
       execve(resolver, (char **)args, (char **)env);
       perror("rpm-fake.so: failed to exec resolver");
       exit(255);
@@ -249,11 +287,17 @@ initPwSocket()
       pw_sock   = res_sock[0];
       sync_sock = sync_pipe[0];
 
-      if (read(sync_sock, &c, 1)!=1 ||
+      if (read(sync_sock, &ctx, sizeof ctx)!=sizeof(ctx) ||
+         read(sync_sock, &c, 1)!=1 ||
          write(pw_sock, ".", 1)!=1 ||
          read(pw_sock, &c,   1)!=1 ||
          c!='.') {
-       WRITE_MSG(2, "rpm-fake.so: failed to initialize communication with resolver");
+       WRITE_MSG(2, "rpm-fake.so: failed to initialize communication with resolver\n");
+       exit(255);
+      }
+
+      if (wait4(pid, 0, WNOHANG,0)==-1) {
+       WRITE_MSG(2, "rpm-fake.so: unexpected initialization-error of resolver\n");
        exit(255);
       }
     }
@@ -287,14 +331,16 @@ initEnvironment()
 #endif
 
   ctx_s = getenv("RPM_FAKE_CTX");
-  if (ctx_s) ctx_s = strdup(ctx_s);
+  if (ctx_s && *ctx_s) ctx_s = strdup(ctx_s);
+  else                 ctx_s = 0;
 
-  ctx       = getAndClearEnv("RPM_FAKE_CTX",  VC_RANDCTX);
+  ctx       = getAndClearEnv("RPM_FAKE_CTX",  VC_DYNAMIC_XID);
   caps      = getAndClearEnv("RPM_FAKE_CAP",  ~0x3404040f);
   flags     = getAndClearEnv("RPM_FAKE_FLAGS", 0);
   root      = getenv("RPM_FAKE_CHROOT");
   mnts      = getenv("RPM_FAKE_NAMESPACE_MOUNTS");
-  if (mnts!=0) mnts = strdup(mnts);
+  if (mnts && *mnts) mnts = strdup(mnts);
+  else               mnts = 0;
 
   unsetenv("RPM_FAKE_CHROOT");
   unsetenv("RPM_FAKE_NAMESPACE_MOUNTS");
@@ -374,7 +420,7 @@ initRPMFake()
 void
 exitRPMFake()
 { 
-  write(2, ">>>>> exitRPMFake <<<<<\n", 24);
+  if (isDbgLevel(DBG_INIT)) WRITE_MSG(2, ">>>>> exitRPMFake <<<<<\n");
   if (pw_sock!=-1) {
     uint8_t    c;
     read(sync_sock, &c, 1);
@@ -460,8 +506,13 @@ execvWorker(char const *path, char * const argv[])
 {
   int          res;
 
-  if ((res=vc_new_s_context(ctx,caps,flags))!=-1 &&
-      (res=execv_func(path, argv)!=-1) ) {}
+  if (vc_isSupported(vcFEATURE_MIGRATE))
+    res = vc_migrate_context(ctx);
+  else
+    res = vc_new_s_context(ctx,caps,flags);
+  
+  if (res!=-1)
+    res=execv_func(path, argv);
 
   return res;
 }
@@ -513,7 +564,11 @@ removeNamespaceMounts(char const *path, char * const argv[])
       // make wait4() working...
     signal(SIGCHLD, SIG_DFL);
 
-    pid = syscall(__NR_clone, CLONE_NEWNS|SIGCHLD|CLONE_VFORK, 0);
+#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;