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 <stgra...@ubuntu.com> > Signed-off-by: Serge Hallyn <serge.hal...@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@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ 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@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel