Trellis branch to support network namespaces
authorAndy Bavier <acb@cs.princeton.edu>
Thu, 30 Oct 2008 15:35:58 +0000 (15:35 +0000)
committerAndy Bavier <acb@cs.princeton.edu>
Thu, 30 Oct 2008 15:35:58 +0000 (15:35 +0000)
python/vserver.py
python/vserverimpl.c
src/netns.c
src/planetlab.c
src/planetlab.h
src/vsh.c
util-vserver-pl.spec

index 69e150c..654077f 100644 (file)
@@ -250,6 +250,13 @@ class VServer:
         # No clean way to do this right now.
         return None
 
+    def get_unshare_netns_config(self):
+        try:
+            unshare_netns = int(self.config.get('spaces/net'))
+        except:
+            unshare_netns = 0;
+        return unshare_netns;
+
     def __do_chroot(self):
         os.chroot(self.dir)
         os.chdir("/")
@@ -368,7 +375,7 @@ class VServer:
             print >>state_file, "%u" % self.ctx
             state_file.close()
 
-        if vserverimpl.chcontext(self.ctx, vserverimpl.text2bcaps(self.get_capabilities_config())):
+        if vserverimpl.chcontext(self.ctx, vserverimpl.text2bcaps(self.get_capabilities_config()), self.get_unshare_netns_config()):
             self.set_resources()
             vserverimpl.setup_done(self.ctx)
 
index b9a06aa..d8ca952 100644 (file)
@@ -71,12 +71,13 @@ vserver_chcontext(PyObject *self, PyObject *args)
   int  ctx_is_new;
   xid_t  ctx;
   uint_least64_t bcaps = 0;
+  int unshare_netns = 0;
 
-  if (!PyArg_ParseTuple(args, "I|K", &ctx, &bcaps))
+  if (!PyArg_ParseTuple(args, "I|KI", &ctx, &bcaps, &unshare_netns))
     return NULL;
   bcaps |= ~PL_INSECURE_BCAPS;
 
-  if ((ctx_is_new = pl_chcontext(ctx, bcaps, 0)) < 0)
+  if ((ctx_is_new = pl_chcontext(ctx, bcaps, 0, unshare_netns)) < 0)
     return PyErr_SetFromErrno(PyExc_OSError);
 
   return PyBool_FromLong(ctx_is_new);
index 8f0c598..cf91eff 100644 (file)
 #define     SPACE_FILE      "/spaces/net"
 #define     VSERVERCONF     "/etc/vservers/"
 
-uint32_t
-get_space_flag(xid_t xid) {
+int
+pl_unshare_netns(xid_t xid) {
     char *ctx_space_file, *space_name;
     struct passwd *slice_user;
-    uint32_t space_flag = 0;
+    int res = 0;
+    char buf[100];
+    FILE *fb;
 
     slice_user = getpwuid(xid);
 
     if (!slice_user)
-        return 0;
+      return 0;
 
     ctx_space_file=(char *) malloc(sizeof(VSERVERCONF SPACE_FILE "Z")+strlen(slice_user->pw_name));
     if (!ctx_space_file)
-        return 0;
+      return 0;
 
     sprintf(ctx_space_file,VSERVERCONF "%s" SPACE_FILE, slice_user->pw_name);
 
-    if (access(ctx_space_file, F_OK)==0)
-        space_flag |= CLONE_NEWNET;
+    if ((fb = fopen(ctx_space_file, "r")) == NULL)
+      return 0;
 
+    if (fgets(buf, sizeof(buf), fb) != NULL) {
+      res = atoi(buf);
+    }
+
+    fclose(fb);
     free(ctx_space_file);
-    return space_flag;
+    return res;
 }
index 92042fb..78174ef 100644 (file)
@@ -138,7 +138,8 @@ pl_setup_done(xid_t ctx)
 #define RETRY_LIMIT  10
 
 int
-pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr)
+pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr, 
+            int unshare_netns)
 {
   int  retry_count = 0;
   int  net_migrated = 0;
@@ -152,12 +153,12 @@ pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr)
 
       if (vc_get_cflags(ctx, &vc_flags))
        {
-        uint32_t unshare_flags;
+         uint32_t unshare_flags;
          if (errno != ESRCH)
            return -1;
 
-       /* Unshare the net namespace if the slice if requested in the local slice configuration */
-        unshare_flags = get_space_flag(ctx);
+         /* Unshare the net namespace if requested in the slice configuration */
+         unshare_flags = unshare_netns ? CLONE_NEWNET : 0;
 
          /* context doesn't exist - create it */
          if (create_context(ctx, bcaps, unshare_flags))
@@ -192,13 +193,15 @@ pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr)
     migrate:
       if (net_migrated || !vc_net_migrate(ctx))
        {
-        uint32_t unshare_flags;
-      /* Unshare the net namespace if the slice if requested in the local slice configuration */
-      unshare_flags = get_space_flag(ctx);
-      if (unshare_flags != 0) {
-          unshare_flags |=vc_get_space_mask();
-          vc_enter_namespace(ctx, unshare_flags);
-      }
+         uint32_t unshare_flags;
+
+         /* Unshare the net namespace if requested in the slice configuration */
+         unshare_flags = unshare_netns ? CLONE_NEWNET : 0;
+
+         if (unshare_flags != 0) {
+           unshare_flags |=vc_get_space_mask();
+           vc_enter_namespace(ctx, unshare_flags);
+         }
 
          if (!vc_tag_migrate(ctx) && !vc_ctx_migrate(ctx, 0))
            break;  /* done */
index 088eba0..7127c3a 100644 (file)
@@ -52,7 +52,8 @@ struct sliver_resources {
 int adjust_lim(const struct vc_rlimit *vcr, struct rlimit *lim);
 
 int
-pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr);
+pl_chcontext(xid_t ctx, uint64_t bcaps, const struct sliver_resources *slr, 
+            int unshare_netns);
 
 int
 pl_setup_done(xid_t ctx);
@@ -66,6 +67,9 @@ pl_setsched(xid_t ctx, uint32_t cpu_min, uint32_t cpu_share);
 void pl_get_limits(const char *, struct sliver_resources *);
 int pl_set_ulimits(const struct sliver_resources *);
 
+/* For network namespaces */
+int pl_unshare_netns(xid_t xid);
+
 static inline int
 _PERROR(const char *format, char *file, int line, int _errno, ...)
 {
index ffbe027..9a23505 100644 (file)
--- a/src/vsh.c
+++ b/src/vsh.c
@@ -113,6 +113,8 @@ static int sandbox_processes(xid_t ctx, const char *context, const struct passwd
        int  ctx_is_new;
        struct sliver_resources slr;
        char hostname[HOST_NAME_MAX+1];
+       int unshare_netns;
+
        pl_get_limits(context,&slr);
 
        if (gethostname(hostname, sizeof hostname) == -1)
@@ -127,10 +129,13 @@ static int sandbox_processes(xid_t ctx, const char *context, const struct passwd
            fprintf(stderr, "*** %s: %s has zero cpu resources and presumably it has been disabled/suspended ***\n", hostname, context);
            exit(0);
          }
+       
+       unshare_netns = pl_unshare_netns(ctx);
 
        (void) (sandbox_chroot(pwd));
 
-        if ((ctx_is_new = pl_chcontext(ctx, ~vc_get_insecurebcaps(),&slr)) < 0)
+        if ((ctx_is_new = pl_chcontext(ctx, ~vc_get_insecurebcaps(),&slr, 
+                                      unshare_netns)) < 0)
           {
             PERROR("pl_chcontext(%u)", ctx);
             exit(1);
index 092d1e8..33a1fd4 100644 (file)
@@ -5,7 +5,7 @@
 
 %define name   util-vserver-pl
 %define version 0.3
-%define taglevel 14
+%define taglevel 15.trellis
 
 %define release        %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}