[LXC] Detect support for NETNS in lxc driver initialization

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.
This commit is contained in:
Dan Smith 2008-06-26 16:05:02 +00:00
parent f3c3550771
commit 99ded85f45
2 changed files with 25 additions and 4 deletions

View File

@ -89,6 +89,7 @@ struct __lxc_driver {
int ninactivevms; int ninactivevms;
char* configDir; char* configDir;
char* stateDir; char* stateDir;
int have_netns;
}; };
/* Types and structs */ /* Types and structs */

View File

@ -66,6 +66,9 @@
#ifndef CLONE_NEWIPC #ifndef CLONE_NEWIPC
#define CLONE_NEWIPC 0x08000000 #define CLONE_NEWIPC 0x08000000
#endif #endif
#ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000 /* New network namespace */
#endif
static int lxcStartup(void); static int lxcStartup(void);
static int lxcShutdown(void); static int lxcShutdown(void);
@ -77,11 +80,11 @@ static int lxcDummyChild( void *argv ATTRIBUTE_UNUSED )
exit(0); exit(0);
} }
static int lxcCheckContainerSupport( void ) static int lxcCheckContainerSupport(int extra_flags)
{ {
int rc = 0; int rc = 0;
int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER| int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWUSER|
CLONE_NEWIPC|SIGCHLD; CLONE_NEWIPC|SIGCHLD|extra_flags;
int cpid; int cpid;
char *childStack; char *childStack;
char *stack; char *stack;
@ -112,7 +115,7 @@ check_complete:
static const char *lxcProbe(void) static const char *lxcProbe(void)
{ {
#ifdef __linux__ #ifdef __linux__
if (0 == lxcCheckContainerSupport()) { if (0 == lxcCheckContainerSupport(0)) {
return("lxc:///"); return("lxc:///");
} }
#endif #endif
@ -1039,6 +1042,22 @@ error_out:
return rc; 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) static int lxcStartup(void)
{ {
uid_t uid = getuid(); uid_t uid = getuid();
@ -1053,10 +1072,11 @@ static int lxcStartup(void)
} }
/* Check that this is a container enabled kernel */ /* Check that this is a container enabled kernel */
if(0 != lxcCheckContainerSupport()) { if(0 != lxcCheckContainerSupport(0)) {
return -1; return -1;
} }
lxc_driver->have_netns = lxcCheckNetNsSupport();
/* Call function to load lxc driver configuration information */ /* Call function to load lxc driver configuration information */
if (lxcLoadDriverConfig(lxc_driver) < 0) { if (lxcLoadDriverConfig(lxc_driver) < 0) {