]> xenbits.xensource.com Git - libvirt.git/commitdiff
[LXC] Detect support for NETNS in lxc driver initialization
authorDan Smith <danms@us.ibm.com>
Thu, 26 Jun 2008 16:05:02 +0000 (16:05 +0000)
committerDan Smith <danms@us.ibm.com>
Thu, 26 Jun 2008 16:05:02 +0000 (16:05 +0000)
Allow check for containers support to be done without CLONE_NEWNET, and then
determine support on the fly by checking for iproute2 support and a
successful clone(CLONE_NEWNET).  This lets us set a flag for later, as well
as not completely disable LXC support on a system without NETNS support.

src/lxc_conf.h
src/lxc_driver.c

index 625cd3e373d88661ec96a03cb7956c69d38c468c..3cf77d85761827844f0d5bd7a9d679901664aad8 100644 (file)
@@ -89,6 +89,7 @@ struct __lxc_driver {
     int ninactivevms;
     char* configDir;
     char* stateDir;
+    int have_netns;
 };
 
 /* Types and structs */
index dea3aff0ed31e55bba581709033cae033dbd5922..d9b41e032198cf05c20d227b15042d63429d647a 100644 (file)
@@ -66,6 +66,9 @@
 #ifndef CLONE_NEWIPC
 #define CLONE_NEWIPC  0x08000000
 #endif
+#ifndef CLONE_NEWNET
+#define CLONE_NEWNET  0x40000000 /* New network namespace */
+#endif
 
 static int lxcStartup(void);
 static int lxcShutdown(void);
@@ -77,11 +80,11 @@ static int lxcDummyChild( void *argv ATTRIBUTE_UNUSED )
     exit(0);
 }
 
-static int lxcCheckContainerSupport( void )
+static int lxcCheckContainerSupport(int extra_flags)
 {
     int rc = 0;
     int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|
-        CLONE_NEWIPC|SIGCHLD;
+        CLONE_NEWIPC|SIGCHLD|extra_flags;
     int cpid;
     char *childStack;
     char *stack;
@@ -112,7 +115,7 @@ check_complete:
 static const char *lxcProbe(void)
 {
 #ifdef __linux__
-    if (0 == lxcCheckContainerSupport()) {
+    if (0 == lxcCheckContainerSupport(0)) {
         return("lxc:///");
     }
 #endif
@@ -1039,6 +1042,22 @@ error_out:
     return rc;
 }
 
+static int lxcCheckNetNsSupport(void)
+{
+    const char *argv[] = {"ip", "link", "set", "lo", "netns", "-1", NULL};
+    int ip_rc;
+    int user_netns = 0;
+    int kern_netns = 0;
+
+    if (virRun(NULL, (char **)argv, &ip_rc) == 0)
+        user_netns = WIFEXITED(ip_rc) && (WEXITSTATUS(ip_rc) != 255);
+
+    if (lxcCheckContainerSupport(CLONE_NEWNET) == 0)
+        kern_netns = 1;
+
+    return kern_netns && user_netns;
+}
+
 static int lxcStartup(void)
 {
     uid_t uid = getuid();
@@ -1053,10 +1072,11 @@ static int lxcStartup(void)
     }
 
     /* Check that this is a container enabled kernel */
-    if(0 != lxcCheckContainerSupport()) {
+    if(0 != lxcCheckContainerSupport(0)) {
         return -1;
     }
 
+    lxc_driver->have_netns = lxcCheckNetNsSupport();
 
     /* Call function to load lxc driver configuration information */
     if (lxcLoadDriverConfig(lxc_driver) < 0) {