[lxc-devel] [PATCH] cgroup: re-introduce ns cgroup support
Stéphane Graber
stgraber at ubuntu.com
Wed Sep 11 18:11:17 UTC 2013
On Wed, Sep 11, 2013 at 11:50:54AM -0500, Serge Hallyn wrote:
> If a cgroup hierarchy has ns cgroup composed, then we need to treat
> that differently:
>
> 1. The container init will have already been switched to a new cgroup
> called after its pid.
> 2. We can't move the container init to new deeper cgroup directories.
>
> So, if we detect an ns cgroup, don't bother trying to construct a new
> name according to the pattern. Just rename the current one to the
> container name, and save that path for us to later enter and remove.
>
> Note I'm not dealing with the subpaths so nested containers probably
> won't work. However as ns cgroup is very much legacy, that should be
> ok. Eventually we should be able to drop ns cgroup support altogether,
> but not just yet.
>
Tested on Android with a 2.6.32 kernel, I can confirm that I'm now able
to start containers!
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> ---
> src/lxc/cgroup.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++---
> src/lxc/cgroup.h | 2 +-
> src/lxc/start.c | 2 +-
> 3 files changed, 85 insertions(+), 6 deletions(-)
>
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index bfdf112..0062571 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -535,8 +535,64 @@ struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgroup_meta_
> return i;
> }
>
> +/*
> + * If a controller has ns cgroup mounted, then in that cgroup the handler->pid
> + * is already in a new cgroup named after the pid. 'mnt' is passed in as
> + * the full current cgroup. Say that is /sys/fs/cgroup/lxc/2975 and the container
> + * name is c1. . We want to rename the cgroup directory to /sys/fs/cgroup/lxc/c1,
> + * and return the string /sys/fs/cgroup/lxc/c1.
> + */
> +static char *cgroup_rename_nsgroup(char *mountpath, const char *oldname, int pid, const char *name)
> +{
> + char *dir, *fulloldpath;
> + char *newname, *fullnewpath;
> + int len;
> +
> + /*
> + * if cgroup is mounted at /cgroup and task is in cgroup /ab/, pid 2375 and
> + * name is c1,
> + * dir: /ab
> + * fulloldpath = /cgroup/ab/2375
> + * fullnewpath = /cgroup/ab/c1
> + * newname = /ab/c1
> + */
> + dir = alloca(strlen(oldname) + 1);
> + strcpy(dir, oldname);
> +
> + fulloldpath = alloca(strlen(oldname) + strlen(mountpath) + 22);
> + sprintf(fulloldpath, "%s/%s/%d", mountpath, oldname, pid);
> +
> + len = strlen(dir) + strlen(name) + 2;
> + newname = malloc(len);
> + if (!newname) {
> + SYSERROR("Out of memory");
> + return NULL;
> + }
> + sprintf(newname, "%s/%s", dir, name);
> +
> + fullnewpath = alloca(strlen(mountpath) + len + 2);
> + sprintf(fullnewpath, "%s/%s", mountpath, newname);
> +
> + if (access(fullnewpath, F_OK) == 0) {
> + if (rmdir(fullnewpath) != 0) {
> + SYSERROR("container cgroup %s already exists.", fullnewpath);
> + free(newname);
> + return NULL;
> + }
> + }
> + if (rename(fulloldpath, fullnewpath)) {
> + SYSERROR("failed to rename cgroup %s->%s", fulloldpath, fullnewpath);
> + free(newname);
> + return NULL;
> + }
> +
> + DEBUG("'%s' renamed to '%s'", oldname, newname);
> +
> + return newname;
> +}
> +
> /* create a new cgroup */
> -extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const char *path_pattern, struct cgroup_meta_data *meta_data, const char *sub_pattern)
> +extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const char *path_pattern, struct cgroup_meta_data *meta_data, const char *sub_pattern, int pid)
> {
> char **cgroup_path_components = NULL;
> char **p = NULL;
> @@ -592,6 +648,8 @@ extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const cha
> }
> info_ptr->designated_mount_point = mp;
>
> + if (lxc_string_in_array("ns", (const char **)h->subsystems))
> + continue;
> if (handle_clone_children(mp, info_ptr->cgroup_path) < 0) {
> ERROR("Could not set clone_children to 1 for cpuset hierarchy in parent cgroup.");
> goto out_initial_error;
> @@ -669,6 +727,9 @@ extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const cha
> */
> for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) {
> char *parts2[3];
> +
> + if (lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems))
> + continue;
> current_entire_path = NULL;
>
> parts2[0] = !strcmp(info_ptr->cgroup_path, "/") ? "" : info_ptr->cgroup_path;
> @@ -753,9 +814,27 @@ extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const cha
>
> /* we're done, now update the paths */
> for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) {
> - free(info_ptr->cgroup_path);
> - info_ptr->cgroup_path = new_cgroup_paths[i];
> - info_ptr->cgroup_path_sub = new_cgroup_paths_sub[i];
> + /*
> + * For any path which has ns cgroup mounted, handler->pid is already
> + * moved into a container called '%d % (handler->pid)'. Rename it to
> + * the cgroup name and record that.
> + */
> + if (lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems)) {
> + char *tmp = cgroup_rename_nsgroup(info_ptr->designated_mount_point->mount_point,
> + info_ptr->cgroup_path, pid, name);
> + if (!tmp)
> + goto out_initial_error;
> + free(info_ptr->cgroup_path);
> + info_ptr->cgroup_path = tmp;
> + r = lxc_grow_array((void ***)&info_ptr->created_paths, &info_ptr->created_paths_capacity, info_ptr->created_paths_count + 1, 8);
> + if (r < 0)
> + goto out_initial_error;
> + info_ptr->created_paths[info_ptr->created_paths_count++] = strdup(tmp);
> + } else {
> + free(info_ptr->cgroup_path);
> + info_ptr->cgroup_path = new_cgroup_paths[i];
> + info_ptr->cgroup_path_sub = new_cgroup_paths_sub[i];
> + }
> }
> /* don't use lxc_free_array since we used the array members
> * to store them in our result...
> diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h
> index 7185ef8..bd2da25 100644
> --- a/src/lxc/cgroup.h
> +++ b/src/lxc/cgroup.h
> @@ -113,7 +113,7 @@ extern struct cgroup_process_info *lxc_cgroup_process_info_get_init(struct cgrou
> extern struct cgroup_process_info *lxc_cgroup_process_info_get_self(struct cgroup_meta_data *meta);
>
> /* create a new cgroup */
> -extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const char *path_pattern, struct cgroup_meta_data *meta_data, const char *sub_pattern);
> +extern struct cgroup_process_info *lxc_cgroup_create(const char *name, const char *path_pattern, struct cgroup_meta_data *meta_data, const char *sub_pattern, int pid);
>
> /* get the cgroup membership of a given container */
> extern struct cgroup_process_info *lxc_cgroup_get_container_info(const char *name, const char *lxcpath, struct cgroup_meta_data *meta_data);
> diff --git a/src/lxc/start.c b/src/lxc/start.c
> index 0356fc0..4d9a3b4 100644
> --- a/src/lxc/start.c
> +++ b/src/lxc/start.c
> @@ -686,7 +686,7 @@ int lxc_spawn(struct lxc_handler *handler)
> if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE))
> failed_before_rename = 1;
>
> - if ((handler->cgroup = lxc_cgroup_create(name, cgroup_pattern, cgroup_meta, NULL)) == NULL) {
> + if ((handler->cgroup = lxc_cgroup_create(name, cgroup_pattern, cgroup_meta, NULL, handler->pid)) == NULL) {
> ERROR("failed to create cgroups for '%s'", name);
> goto out_delete_net;
> }
> --
> 1.7.9.5
>
>
> ------------------------------------------------------------------------------
> How ServiceNow helps IT people transform IT departments:
> 1. Consolidate legacy IT systems to a single system of record for IT
> 2. Standardize and globalize service processes across IT
> 3. Implement zero-touch automation to replace manual, redundant tasks
> http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130911/788388cf/attachment.pgp>
More information about the lxc-devel
mailing list