On Fri, Apr 17, 2009 at 04:50:10PM -0500, Serge E. Hallyn wrote:
>From 2513f8a7e0654e84570fe0ef2204dabe276b9e4e Mon Sep 17 00:00:00
2001
From: root <root(a)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.
I think this patch is sufficient. If it is genuinely important to
support CLONE_NEWUSER then Ubuntu can fix their kernel config,
otherwise simply disabling it in libvirt when not present is fine.
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
ACK
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|