[libvirt] [PATCH 1/1] lxc: only do CLONE_NEWUSER when kernel supports it

Serge E. Hallyn serue at us.ibm.com
Fri Apr 17 21:50:10 UTC 2009


I was trying to get the lxc driver to work on ubuntu jaunty.  This
patch gets me further than I was getting before.  Like I say below,
it's probably not the right way though.

-serge

>From 2513f8a7e0654e84570fe0ef2204dabe276b9e4e Mon Sep 17 00:00:00 2001
From: root <root at jaunty.(none)>
Date: Fri, 17 Apr 2009 16:41:01 -0500
Subject: [PATCH 1/1] lxc: only do CLONE_NEWUSER when kernel supports it

The ubuntu jaunty kernel is not compiled with USER_NS.  Since
libvirt-lxc always does clone(CLONE_NEWUSER) it gets -EINVAL
and mysteriously claims to be unable to contact hypervisor.

This patch isn't the right thing to do, but I'm not sure what
is.  User namespaces do (since recently) isolate the in-kernel
keyring.  So the right thing might be to add a flag to the
xml definition file to specify whether to use a user namespace.
This patch doesn't do that, rather it always does CLONE_NEWUSER
if the kernel supports it, and never if not.

Signed-off-by: Serge Hallyn <serue at us.ibm.com>
---
 src/lxc_container.c |   15 +++++++++++++--
 src/lxc_container.h |    1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/lxc_container.c b/src/lxc_container.c
index 67c66bd..8069af7 100644
--- a/src/lxc_container.c
+++ b/src/lxc_container.c
@@ -666,6 +666,11 @@ static int lxcContainerChild( void *data )
     return lxcContainerExecInit(vmDef);
 }
 
+int userns_supported(void)
+{
+	return lxcContainerAvailable(LXC_CONTAINER_FEATURE_USER) == 0;
+}
+
 /**
  * lxcContainerStart:
  * @driver: pointer to driver structure
@@ -694,7 +699,10 @@ int lxcContainerStart(virDomainDefPtr def,
     }
     stacktop = stack + stacksize;
 
-    flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|CLONE_NEWIPC|SIGCHLD;
+    flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD;
+
+    if (userns_supported())
+        flags |= CLONE_NEWUSER;
 
     if (def->nets != NULL)
         flags |= CLONE_NEWNET;
@@ -719,13 +727,16 @@ static int lxcContainerDummyChild(void *argv ATTRIBUTE_UNUSED)
 
 int lxcContainerAvailable(int features)
 {
-    int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|
+    int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|
         CLONE_NEWIPC|SIGCHLD;
     int cpid;
     char *childStack;
     char *stack;
     int childStatus;
 
+    if (features & LXC_CONTAINER_FEATURE_USER)
+        flags |= CLONE_NEWUSER;
+
     if (features & LXC_CONTAINER_FEATURE_NET)
         flags |= CLONE_NEWNET;
 
diff --git a/src/lxc_container.h b/src/lxc_container.h
index 5d037b0..b99e83e 100644
--- a/src/lxc_container.h
+++ b/src/lxc_container.h
@@ -28,6 +28,7 @@
 
 enum {
     LXC_CONTAINER_FEATURE_NET = (1 << 0),
+    LXC_CONTAINER_FEATURE_USER = (1 << 1),
 };
 
 #define LXC_DEV_MAJ_MEMORY  1
-- 
1.6.0.4




More information about the libvir-list mailing list