Commit 5193cc3d by Daniel Lezcano Committed by Daniel Lezcano

fix the ns_cgroup vs clone_children

The following patch fixes the bug where the clone_children compatibility flag is available with the ns_cgroup subsystem. The 2.6.37 kernel version should be the only one which is concerned by this modification, please refer to Documentation/feature-removal-schedule.txt and look for ns_cgroup. The problem is coming from we check for clone_children and we set it automatically and then we try to create a new cgroup. As the ns_cgroup is present the cgroup already exists and we are not allowed to attach our pid to a new cgroup. The next error will be when we try to create a new container because we enabled the clone_children flag and the ns_cgroup is present, it is not allowed by the kernel. The patch fix this by checking the mount options. Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 57f61aa7
...@@ -45,10 +45,15 @@ ...@@ -45,10 +45,15 @@
lxc_log_define(lxc_cgroup, lxc); lxc_log_define(lxc_cgroup, lxc);
#define MTAB "/etc/mtab" #define MTAB "/proc/mounts"
static char nsgroup_path[MAXPATHLEN]; static char nsgroup_path[MAXPATHLEN];
enum {
CGROUP_NS_CGROUP = 1,
CGROUP_CLONE_CHILDREN,
};
static int get_cgroup_mount(const char *mtab, char *mnt) static int get_cgroup_mount(const char *mtab, char *mnt)
{ {
struct mntent *mntent; struct mntent *mntent;
...@@ -58,7 +63,7 @@ static int get_cgroup_mount(const char *mtab, char *mnt) ...@@ -58,7 +63,7 @@ static int get_cgroup_mount(const char *mtab, char *mnt)
file = setmntent(mtab, "r"); file = setmntent(mtab, "r");
if (!file) { if (!file) {
SYSERROR("failed to open %s", mtab); SYSERROR("failed to open %s", mtab);
goto out; return -1;
} }
while ((mntent = getmntent(file))) { while ((mntent = getmntent(file))) {
...@@ -81,7 +86,57 @@ static int get_cgroup_mount(const char *mtab, char *mnt) ...@@ -81,7 +86,57 @@ static int get_cgroup_mount(const char *mtab, char *mnt)
DEBUG("using cgroup mounted at '%s'", mnt); DEBUG("using cgroup mounted at '%s'", mnt);
fclose(file); fclose(file);
out:
return err;
}
static int get_cgroup_flags(const char *mtab, int *flags)
{
struct mntent *mntent;
FILE *file = NULL;
int err = -1;
file = setmntent(mtab, "r");
if (!file) {
SYSERROR("failed to open %s", mtab);
return -1;
}
*flags = 0;
while ((mntent = getmntent(file))) {
/* there is a cgroup mounted named "lxc" */
if (!strcmp(mntent->mnt_fsname, "lxc") &&
!strcmp(mntent->mnt_type, "cgroup")) {
if (hasmntopt(mntent, "ns"))
*flags |= CGROUP_NS_CGROUP;
if (hasmntopt(mntent, "clone_children"))
*flags |= CGROUP_CLONE_CHILDREN;
err = 0;
break;
}
/* fallback to the first non-lxc cgroup found */
if (!strcmp(mntent->mnt_type, "cgroup") && err) {
if (hasmntopt(mntent, "ns"))
*flags |= CGROUP_NS_CGROUP;
if (hasmntopt(mntent, "clone_children"))
*flags |= CGROUP_CLONE_CHILDREN;
err = 0;
}
};
DEBUG("cgroup flags is 0x%x", *flags);
fclose(file);
return err; return err;
} }
...@@ -151,6 +206,7 @@ int lxc_cgroup_create(const char *name, pid_t pid) ...@@ -151,6 +206,7 @@ int lxc_cgroup_create(const char *name, pid_t pid)
char cgmnt[MAXPATHLEN]; char cgmnt[MAXPATHLEN];
char cgname[MAXPATHLEN]; char cgname[MAXPATHLEN];
char clonechild[MAXPATHLEN]; char clonechild[MAXPATHLEN];
int flags;
if (get_cgroup_mount(MTAB, cgmnt)) { if (get_cgroup_mount(MTAB, cgmnt)) {
ERROR("cgroup is not mounted"); ERROR("cgroup is not mounted");
...@@ -168,14 +224,28 @@ int lxc_cgroup_create(const char *name, pid_t pid) ...@@ -168,14 +224,28 @@ int lxc_cgroup_create(const char *name, pid_t pid)
return -1; return -1;
} }
snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children", cgmnt); if (get_cgroup_flags(MTAB, &flags)) {
SYSERROR("failed to get cgroup flags");
return -1;
}
/* we check if the kernel has ns_cgroup or clone_children */ /* We have the deprecated ns_cgroup subsystem */
if (access(clonechild, F_OK)) { if (flags & CGROUP_NS_CGROUP) {
WARN("using deprecated ns_cgroup"); WARN("using deprecated ns_cgroup");
return lxc_rename_nsgroup(cgmnt, cgname, pid); return lxc_rename_nsgroup(cgmnt, cgname, pid);
} }
/* we check if the kernel has clone_children, at this point if there
* no clone_children neither ns_cgroup, that means the cgroup is mounted
* without the ns_cgroup and it has not the compatibility flag
*/
if (access(clonechild, F_OK)) {
ERROR("no ns_cgroup option specified");
return -1;
}
snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children", cgmnt);
/* we enable the clone_children flag of the cgroup */ /* we enable the clone_children flag of the cgroup */
if (cgroup_enable_clone_children(clonechild)) { if (cgroup_enable_clone_children(clonechild)) {
SYSERROR("failed to enable 'clone_children flag"); SYSERROR("failed to enable 'clone_children flag");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment