added lots of new code
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Thu, 19 Aug 2004 16:06:37 +0000 (16:06 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Thu, 19 Aug 2004 16:06:37 +0000 (16:06 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@1677 94cd875c-1c1d-0410-91d2-eb244daf1a30

util-vserver/vserver-start/configuration-init.c
util-vserver/vserver-start/configuration.c
util-vserver/vserver-start/configuration.h
util-vserver/vserver-start/interface-add.c
util-vserver/vserver-start/interface-read.c
util-vserver/vserver-start/interface.c
util-vserver/vserver-start/interface.h
util-vserver/vserver-start/main.c
util-vserver/vserver-start/scriptlets.c
util-vserver/vserver-start/vshelper.c

index 55be6a0..74a7604 100644 (file)
@@ -26,5 +26,7 @@ void
 Cfg_init(struct Configuration *cfg)
 {
   Vector_init(&cfg->interfaces, sizeof(struct Interface));
+  cfg->vdir      = 0;
+  cfg->xid       = VC_DYNAMIC_XID;
   cfg->broadcast = 0;
 }
index 435c9ea..3ca1941 100644 (file)
@@ -47,10 +47,10 @@ getSingleInterface(struct Interface *res,
 }
 
 static inline bool
-getInterfaces(struct Configuration *c, PathInfo const *cfgdir)
+getInterfaces(struct Configuration *cfg)
 {
   ENSC_PI_DECLARE(iface_subdir, "interfaces");
-  PathInfo             ifacepath = *cfgdir;
+  PathInfo             ifacepath = cfg->cfgdir;
   char                 path_buf[ENSC_PI_APPSZ(ifacepath, iface_subdir)];
   struct Interface     iface_default;
   DIR                  *dir;
@@ -78,7 +78,7 @@ getInterfaces(struct Configuration *c, PathInfo const *cfgdir)
     if (!getSingleInterface(&iface, &iface_default, &ifacepath, ent->d_name))
       rc = false;
     else if (iface.addr.ipv4.ip!=0) {  // HACK: non-directory entries would return true also
-      struct Interface *new_iface = Vector_pushback(&c->interfaces);
+      struct Interface *new_iface = Vector_pushback(&cfg->interfaces);
       *new_iface = iface;
     }
   }
@@ -89,8 +89,23 @@ getInterfaces(struct Configuration *c, PathInfo const *cfgdir)
   return rc;
 }
 
+static bool
+initVdir(char const **vdir, PathInfo const *cfgdir)
+{
+  *vdir = vc_getVserverVdir(cfgdir->d, vcCFG_RECENT_FULL, true);
+  if (*vdir==0) {
+    WRITE_MSG(2, "Can not find root-directory of the vserver");
+    return false;
+  }
+
+  return true;
+}
+
 bool
-getConfiguration(struct Configuration *c, PathInfo const *cfgdir)
+getConfiguration(struct Configuration *cfg, PathInfo const *cfgdir)
 {
-  return getInterfaces(c, cfgdir);
+  cfg->cfgdir = *cfgdir;
+  
+  return (initVdir(&cfg->vdir, cfgdir) &&
+         getInterfaces(cfg));
 }
index d32fc42..c027ba9 100644 (file)
 #ifndef H_UTIL_VSERVER_VSERVER_START_CONFIGURATION_H
 #define H_UTIL_VSERVER_VSERVER_START_CONFIGURATION_H
 
+#include <lib/vserver.h>
 #include <ensc_vector/vector.h>
 #include <lib_internal/pathinfo.h>
 
 #include <stdbool.h>
 
 struct Configuration {
+    PathInfo           cfgdir;
+    char const *       vdir;
+    xid_t              xid;
     uint32_t           broadcast;
     struct Vector      interfaces;
 };
index 6c03825..6bf527b 100644 (file)
@@ -48,33 +48,37 @@ invokeIpAddr(struct Interface const *iface)
 {
   struct Command               cmd;
   unsigned int                 prefix = Iface_getIPv4Prefix(iface);
-  char                         buf[sizeof("255.255.255.255/") + sizeof(unsigned int)*3 + 1];
   char *                       tmp = inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.ip));
   size_t                       l   = strlen(tmp);
+  char                         addr[l + sizeof("/") + sizeof(unsigned int)*3 + 1];
   char *                       ptr;
+  size_t                       l1 = strlen(iface->dev);
+  size_t                       l2 = iface->name ? strlen(iface->name) : 0;
+  char                         devlabel[l1 + l2 + sizeof(":")];
+  bool                         result = true;
 
-  if (l>=sizeof("255.255.255.255")) {
-    abort();
-    return false;
-  }
-  ptr    = Xmemcpy(buf, tmp, l);
+  ptr    = Xmemcpy(addr, tmp, l);
   *ptr++ = '/';
   l      = utilvserver_fmt_uint(ptr, prefix);
   ptr[l] = '\0';
 
-  Command_init(&cmd, 5);
-  Command_appendParameter(&cmd, "/bin/echo");
-  Command_appendParameter(&cmd, PROG_IP);
-  Command_appendParameter(&cmd, buf);
-  Command_appendParameter(&cmd, "broadcast");
+  Command_init(&cmd);
+
+  size_t               idx    = 6;
+  char const *         argv[] = {
+    "/bin/echo",
+    PROG_IP, "addr", "add",
+    addr,
+    "broadcast", 0,
+    0, 0,      // label <name>
+    0, 0,      // dev   <dev>
+    0
+  };
+
   if (iface->addr.ipv4.bcast!=0)
-    Command_appendParameter(&cmd, inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.bcast)));
+    argv[idx++] = inet_ntoa(*reinterpret_cast(struct in_addr *)(&iface->addr.ipv4.bcast));
   else
-    Command_appendParameter(&cmd, "+");
-
-  size_t                       l1 = strlen(iface->dev);
-  size_t                       l2 = iface->name ? strlen(iface->name) : 0;
-  char                         devlabel[l1 + l2 + sizeof(":")];
+    argv[idx++] = "+";
   
   if (iface->name) {
     ptr    = Xmemcpy(devlabel, iface->dev,  l1);
@@ -82,20 +86,22 @@ invokeIpAddr(struct Interface const *iface)
     ptr    = Xmemcpy(ptr,      iface->name, l2);
     *ptr   = '\0';
     
-    Command_appendParameter(&cmd, "label");
-    Command_appendParameter(&cmd, devlabel);
+    argv[idx++] = "label";
+    argv[idx++] = devlabel;
   }
 
-  Command_appendParameter(&cmd, "dev");
-  Command_appendParameter(&cmd, iface->dev);
+  argv[idx++] = "dev";
+  argv[idx++] = iface->dev;  
 
+  Command_setParams(&cmd, argv);
   if (!Command_exec(&cmd, true) ||
-      !Command_wait(&cmd, true))
-    return false;
+      !Command_wait(&cmd, true) ||
+      cmd.rc!=0)
+    result = false;
 
   Command_free(&cmd);
   
-  return true;
+  return result;
 }
 
 static bool
index 1d72518..09825b6 100644 (file)
@@ -64,6 +64,9 @@ Iface_read(struct Interface *res, PathInfo *cfgdir,
   char const * bcast;
   bool         rc = false;
 
+    // skip 'disabled' interfaces
+  if (readEntryFlag(cfgdir, "disabled", false)) return true;
+    
   ip          =  readEntryStr (cfgdir, "ip",       0);
   mask        =  readEntryStr (cfgdir, "mask",     0);
   prefix      =  readEntryStr (cfgdir, "prefix",   0);
index 6afbbe4..d6fd9f1 100644 (file)
 
 #include "vserver-start.h"
 #include "configuration.h"
+#include "undo.h"
 
 #include <lib_internal/util.h>
 
+static void
+Iface_removeWrapper(void const *iface)
+{
+  (void)Iface_remove(iface);
+}
+
 void
 activateInterfaces()
 {
@@ -34,6 +41,14 @@ activateInterfaces()
 
   for (iface=Vector_begin(&cfg.interfaces);
        iface!=Vector_end(&cfg.interfaces);
-       ++iface)
-    Iface_add(iface);
+       ++iface) {
+    if (!Iface_add(iface)) {
+      WRITE_MSG(2, "Failed to add interface ");
+      Iface_print(iface, 2);
+      WRITE_MSG(2, "\n");
+      
+      exit(1);
+    }
+    Undo_addTask(Iface_removeWrapper, iface);
+  }
 }
index 2277950..bd0d8b0 100644 (file)
@@ -53,6 +53,8 @@ bool          Iface_read(struct Interface *, PathInfo *cfgdir,
                           struct Interface const *dflt);
 bool           Iface_add(struct Interface const *);
 bool           Iface_del(struct Interface const *);
+bool           Iface_remove(struct Interface const *);
+void           Iface_print(struct Interface const *, int fd);
 
 #include "interface-init.hc"
 #include "interface-free.hc"
index 5896281..deaebda 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 <sys/socket.h>
+
+#define ENSC_WRAPPERS_VSERVER  1
+#define ENSC_WRAPPERS_SOCKET   1
+#define ENSC_WRAPPERS_FCNTL    1
+#define ENSC_WRAPPERS_STDLIB   1
+#include <ensc_wrappers/wrappers.h>
 
 struct Options                 opts;
 struct Configuration           cfg;
@@ -120,9 +133,45 @@ 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();
+      
+      xid = Evc_ctx_create(cfg.xid);
+      mountVserver(&cfg);
+       //      prepareInit(&cfg, &cfgdir);
+
+      Esend(sync_fd[0], &xid, sizeof xid, MSG_NOSIGNAL);
+      Erecv(sync_fd[0], &c, 1, 0);
+      execScriptlets(&cfgdir, opts.VSERVER_NAME, "pre-start");
+
+      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;
+  }
 }
index 30874ca..c2375ae 100644 (file)
@@ -50,9 +50,9 @@ visitFile(char const *fname, char const *vname, char const *style)
              "!!!LEGACY ALERT!!!\n"
              "The special handling of non-executable scriptlets which allows to\n"
              "override environment variables is not supported anymore. This change\n"
-             "was needed as 'vserver ... start' is a done by a native C program\n"
-             "now. If you need the old functionality please fill a bugreport so\n"
-             "that workarounds can be found/implemented.\n"
+             "was needed as 'vserver ... start' is done by a native C program now.\n"
+             "If you need the old functionality please fill a bugreport so that\n"
+             "workarounds can be found/implemented.\n"
              "The file triggering this message was\n"
              "    '");
     WRITE_STR(2, fname);
@@ -61,10 +61,8 @@ visitFile(char const *fname, char const *vname, char const *style)
     return false;
   }
 
-  Command_init(&cmd, 4);
-  Command_appendParameter(&cmd, fname);
-  Command_appendParameter(&cmd, style);
-  Command_appendParameter(&cmd, vname);
+  char const *par[] = { fname, style, vname, 0 };
+  Command_setParams(&cmd, par);
 
   if (!Command_exec(&cmd, true) ||
       !Command_wait(&cmd, true)) {
index 4e1b1fe..c640872 100644 (file)
 void
 Vshelper_doSanityCheck()
 {
-  struct Command       cmd = {
-    .filename = "/bin/bash"
+  struct Command       cmd;
+  char const *         argv[] = {
+    "/bin/bash", "-c",
+    ". " PATH_UTILVSERVER_VARS ";. " PATH_FUNCTIONS "; vshelper.doSanityCheck",
+    0
   };
 
-  Command_init(&cmd, 10);
-  Command_appendParameter(&cmd, "/bin/bash");
-  Command_appendParameter(&cmd, "-c");
-  Command_appendParameter(&cmd, ". " PATH_UTILVSERVER_VARS ";. " PATH_FUNCTIONS "; vshelper.doSanityCheck");
+  Command_init(&cmd);
+  Command_setParams(&cmd, argv);
   if (!Command_exec(&cmd, true) ||
       !Command_wait(&cmd, true))
     WRITE_MSG(2, "vserver-start: failed to do the vshelper-sanitycheck\n");