[lxc-devel] multiple cgroup instances fixes
Serge Hallyn
serge.hallyn at canonical.com
Mon Jun 27 11:51:38 UTC 2011
Quoting Daniel Lezcano (daniel.lezcano at free.fr):
> Hi Serge,
>
> your patch was doing a nested call to the setmntent which is not reentrant.
>
> Fixed with the patch in attachment. Some other nits fixed too.
Looks good, thanks.
Acked-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Once this all settles down, we can of course consider re-introducing
caching the mounts we find so multiple lxc_cgroup_{sg}et()s are
quicker. But I figured optimizations should be done later.
> ---
> src/lxc/cgroup.c | 81 +++++++++++++++++++++----------------------------------
> 1 file changed, 32 insertions(+), 49 deletions(-)
>
> Index: lxc/src/lxc/cgroup.c
> ===================================================================
> --- lxc.orig/src/lxc/cgroup.c
> +++ lxc/src/lxc/cgroup.c
> @@ -82,40 +82,19 @@ static int get_cgroup_mount(const char *
> return -1;
> }
>
> -static int get_cgroup_flags(const char *mtab, const char *mnt_dir, int *flags)
> +static int get_cgroup_flags(const struct mntent *mntent)
> {
> - struct mntent *mntent;
> - FILE *file = NULL;
> - int err = -1;
> + int flags = 0;
>
> - file = setmntent(mtab, "r");
> - if (!file) {
> - SYSERROR("failed to open %s", mtab);
> - return -1;
> - }
> + if (hasmntopt(mntent, "ns"))
> + flags |= CGROUP_NS_CGROUP;
>
> - *flags = 0;
> -- Daniel
> ---
> src/lxc/cgroup.c | 81 +++++++++++++++++++++----------------------------------
> 1 file changed, 32 insertions(+), 49 deletions(-)
>
> Index: lxc/src/lxc/cgroup.c
> ===================================================================
> --- lxc.orig/src/lxc/cgroup.c
> +++ lxc/src/lxc/cgroup.c
> @@ -82,40 +82,19 @@ static int get_cgroup_mount(const char *
> return -1;
> }
>
> -static int get_cgroup_flags(const char *mtab, const char *mnt_dir, int *flags)
> +static int get_cgroup_flags(const struct mntent *mntent)
> {
> - struct mntent *mntent;
> - FILE *file = NULL;
> - int err = -1;
> + int flags = 0;
>
> - file = setmntent(mtab, "r");
> - if (!file) {
> - SYSERROR("failed to open %s", mtab);
> - return -1;
> - }
> + if (hasmntopt(mntent, "ns"))
> + flags |= CGROUP_NS_CGROUP;
>
> - *flags = 0;
> + if (hasmntopt(mntent, "clone_children"))
> + flags |= CGROUP_CLONE_CHILDREN;
>
> - while ((mntent = getmntent(file))) {
> - if (strcmp(mntent->mnt_type, "cgroup"))
> - continue;
> - if (strcmp(mntent->mnt_dir, mnt_dir))
> - continue;
> - if (hasmntopt(mntent, "ns")) {
> - *flags |= CGROUP_NS_CGROUP;
> - err = 0;
> - }
> - if (hasmntopt(mntent, "clone_children")) {
> - *flags |= CGROUP_CLONE_CHILDREN;
> - err = 0;
> - }
> - fclose(file);
> - DEBUG("cgroup flags for %s is 0x%x", mnt_dir, *flags);
> - return err;
> - }
> + DEBUG("cgroup '%s' has flags 0x%x", mntent->mnt_dir, flags);
>
> - fclose(file);
> - return err;
> + return flags;
> }
>
> static int cgroup_rename_nsgroup(const char *mnt, const char *name, pid_t pid)
> @@ -184,14 +163,15 @@ static int cgroup_attach(const char *pat
> * XXX TODO we will of course want to use cgroup_path{subsystem}/lxc/name,
> * not just cgroup_path{subsystem}/name.
> */
> -int lxc_one_cgroup_create(const char *name, const char *cgmnt, pid_t pid)
> +static int lxc_one_cgroup_create(const char *name,
> + const struct mntent *mntent, pid_t pid)
> {
> char cgname[MAXPATHLEN];
> char clonechild[MAXPATHLEN];
> int flags;
>
> - snprintf(cgname, MAXPATHLEN, "%s/%s", cgmnt, name);
> -
> + snprintf(cgname, MAXPATHLEN, "%s/%s", mntent->mnt_dir, name);
> +
> /*
> * There is a previous cgroup, assume it is empty,
> * otherwise that fails
> @@ -201,18 +181,18 @@ int lxc_one_cgroup_create(const char *na
> return -1;
> }
>
> - if (get_cgroup_flags(MTAB, cgmnt, &flags)) {
> - SYSERROR("failed to get cgroup flags");
> - return -1;
> - }
> + flags = get_cgroup_flags(mntent);
>
> /* We have the deprecated ns_cgroup subsystem */
> if (flags & CGROUP_NS_CGROUP) {
> WARN("using deprecated ns_cgroup");
> - return cgroup_rename_nsgroup(cgmnt, cgname, pid);
> + return cgroup_rename_nsgroup(mntent->mnt_dir, cgname, pid);
> }
>
> - snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children", cgmnt);
> + snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children",
> + mntent->mnt_dir);
> +
> + DEBUG("checking '%s' presence", clonechild);
>
> /* 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
> @@ -242,6 +222,8 @@ int lxc_one_cgroup_create(const char *na
> return -1;
> }
>
> + INFO("created cgroup '%s'", cgname);
> +
> return 0;
> }
>
> @@ -252,9 +234,8 @@ int lxc_cgroup_create(const char *name,
> {
> struct mntent *mntent;
> FILE *file = NULL;
> - int ret, err = -1;
> + int err = -1;
>
> - DEBUG("%s: starting\n", __func__);
> file = setmntent(MTAB, "r");
> if (!file) {
> SYSERROR("failed to open %s", MTAB);
> @@ -262,19 +243,21 @@ int lxc_cgroup_create(const char *name,
> }
>
> while ((mntent = getmntent(file))) {
> +
> + DEBUG("checking '%s' (%s)", mntent->mnt_dir, mntent->mnt_type);
> +
> if (!strcmp(mntent->mnt_type, "cgroup")) {
> - DEBUG("creating %s %s %d\n", name, mntent->mnt_dir, pid);
> - err = lxc_one_cgroup_create(name, mntent->mnt_dir, pid);
> - if (ret) {
> - fclose(file);
> - return ret;
> - }
> - err = 0;
> +
> + INFO("found cgroup mounted at '%s'", mntent->mnt_dir);
> + err = lxc_one_cgroup_create(name, mntent, pid);
> + if (err)
> + goto out;
> +
> }
> };
>
> - fclose(file);
> -
> +out:
> + endmntent(file);
> return err;
> }
>
More information about the lxc-devel
mailing list