mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 22:34:41 +00:00
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: Daniel Lezcano <dlezcano@fr.ibm.com>
This commit is contained in:
parent
57f61aa750
commit
5193cc3d93
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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");
|
||||||
|
Loading…
Reference in New Issue
Block a user