use $(LIBENSCVECTOR) instead of libensc_vector.a
[util-vserver.git] / util-vserver / vserver-start / main.c
index 5896281..6957f1f 100644 (file)
 #include "pathconfig.h"
 #include "interface.h"
 #include "configuration.h"
+#include "mount.h"
+#include "undo.h"
 
 #include "lib_internal/util.h"
 #include "lib_internal/errinfo.h"
+#include "lib_internal/sys_clone.h"
 #include "lib/vserver.h"
+#include "lib/internal.h"
 
 #include <sys/file.h>
+#include <sched.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#define ENSC_WRAPPERS_VSERVER  1
+#define ENSC_WRAPPERS_SOCKET   1
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_FCNTL    1
+#define ENSC_WRAPPERS_STDLIB   1
+#include <ensc_wrappers/wrappers.h>
 
 struct Options                 opts;
 struct Configuration           cfg;
@@ -112,6 +127,17 @@ checkConstraints()
   Vshelper_doSanityCheck();
 }
 
+static void
+setCFlag(xid_t xid, uint_least64_t value)
+{
+  struct vc_ctx_flags  flags = {
+    .flagword = value,
+    .mask     = value
+  };
+
+  Evc_set_cflags(xid, &flags);
+}
+
 int main(int argc, char *argv[])
 {
   Cfg_init(&cfg);
@@ -120,9 +146,55 @@ int main(int argc, char *argv[])
   initLock();
   checkConstraints();
 
+  int          sync_fd[2];
+  char         c;
+  xid_t                xid;
+  char         buf[sizeof(xid)*3 + 2];
   PathInfo     cfgdir = { .d = opts.VSERVER_DIR, .l = strlen(opts.VSERVER_DIR) };
 
+  Esocketpair(AF_UNIX, SOCK_STREAM, 0, sync_fd);
+  Efcntl(sync_fd[0], F_SETFD, FD_CLOEXEC);
+  Efcntl(sync_fd[1], F_SETFD, FD_CLOEXEC);
+  
   getConfiguration(&cfg, &cfgdir);
-  execScriptlets(&cfgdir, opts.VSERVER_NAME, "prepre-start");
-  activateInterfaces();
+  pid_t                pid    = sys_clone(CLONE_NEWNS|SIGCHLD, 0);
+  FatalErrnoError(pid==-1, "sys_clone()");
+  
+  switch (pid) {
+    case 0     :
+      Undo_init();
+      execScriptlets(&cfgdir, opts.VSERVER_NAME, "prepre-start");
+      activateInterfaces(&cfg.interfaces);
+      
+      xid = Evc_ctx_create(cfg.xid);
+      setCFlag(xid, VC_VXF_INFO_NAMESPACE);
+      
+      mountVserver(&cfg);
+       //      prepareInit(&cfg, &cfgdir);
+
+      Esend(sync_fd[0], &xid, sizeof xid, MSG_NOSIGNAL);
+       // 'pre-start.parent' will be executed now in the parent-context
+      Erecv(sync_fd[0], &c, 1, 0);
+      execScriptlets(&cfgdir, opts.VSERVER_NAME, "pre-start");
+
+      if (cfg.nice)
+       Enice(atoi(cfg.nice));
+      if (opts.OPTION_DEFAULTTTY)
+       setDefaultTTY(&cfgdir, 0);
+
+      
+
+      Undo_detach();
+      break;
+
+    default    :
+      Erecv(sync_fd[1], &xid, sizeof xid, 0);
+      utilvserver_fmt_uint(buf, xid);
+      Esetenv("CHILD_XID", buf, 1);
+      
+      execScriptlets(&cfgdir, opts.VSERVER_NAME, "pre-start.parent");
+      Esend(sync_fd[1], ".", 1, MSG_NOSIGNAL);
+      
+      break;
+  }
 }