diff options
author | Balbir Singh <balbir@linux.vnet.ibm.com> | 2008-08-22 22:34:50 +0000 |
---|---|---|
committer | Balbir Singh <balbir@linux.vnet.ibm.com> | 2008-08-22 22:34:50 +0000 |
commit | 137549382fba5ff7fa874e787226a7f3e3f9d9f4 (patch) | |
tree | a2ca680f984df3b96e6be86100f012ca8e6550b9 /api.c | |
parent | 2124f1ea16bcc12482928c45689c1fa4d92a74a1 (diff) | |
download | libcg-137549382fba5ff7fa874e787226a7f3e3f9d9f4.tar.gz libcg-137549382fba5ff7fa874e787226a7f3e3f9d9f4.tar.xz libcg-137549382fba5ff7fa874e787226a7f3e3f9d9f4.zip |
More fixes to the earlier attempt to create new cgroup inheriting parent's
attributes. Test cases have also been updated.
Tested on an x86_64 box with libcg_ba
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@166 4f4bb910-9a46-0410-90c8-c897d4f1cd53
Diffstat (limited to 'api.c')
-rw-r--r-- | api.c | 90 |
1 files changed, 74 insertions, 16 deletions
@@ -712,31 +712,83 @@ err: } /** + * Find the parent of the specified directory. It returns the parent (the + * parent is usually name/.. unless name is a mount point. + */ +char *cgroup_find_parent(char *name) +{ + char child[FILENAME_MAX], *parent; + struct stat stat_child, stat_parent; + char *type; + char *dir; + + pthread_rwlock_rdlock(&cg_mount_table_lock); + type = cg_mount_table[0].name; + if (!cg_build_path_locked(name, child, type)) { + pthread_rwlock_unlock(&cg_mount_table_lock); + return NULL; + } + pthread_rwlock_unlock(&cg_mount_table_lock); + + dbg("path is %s\n", child); + dir = dirname(child); + dbg("directory name is %s\n", dir); + + if (asprintf(&parent, "%s/..", dir) < 0) + return NULL; + + dbg("parent's name is %s\n", parent); + + if (stat(dir, &stat_child) < 0) + goto free_parent; + + if (stat(parent, &stat_parent) < 0) + goto free_parent; + + /* + * Is the specified "name" a mount point? + */ + if (stat_parent.st_dev != stat_child.st_dev) { + dbg("parent is a mount point\n"); + strcpy(parent, "."); + } else { + dir = strdup(name); + if (!dir) + goto free_parent; + dir = dirname(dir); + if (strcmp(dir, ".") == 0) + strcpy(parent, ".."); + else + strcpy(parent, dir); + } + + return parent; + +free_parent: + free(parent); + return NULL; +} + +/** * @cgroup: cgroup data structure to be filled with parent values and then * passed down for creation * @ignore_ownership: Ignore doing a chown on the newly created cgroup */ -int cgroup_create_cgroup_from_parent(struct cgroup *cgroup, int ignore_ownership) +int cgroup_create_cgroup_from_parent(struct cgroup *cgroup, + int ignore_ownership) { char *parent; struct cgroup *parent_cgroup; int ret = ECGFAIL; - char *dir_name, *orig_dir_name; - - dir_name = strdup(cgroup->name); - if (!dir_name) - return ECGFAIL; - orig_dir_name = dir_name; - dir_name = dirname(dir_name); + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; - /* - * Ugly: but we expect cgroup_get_cgroup() to do the right thing - */ - if (asprintf(&parent, "%s", dir_name) < 0) { - free(orig_dir_name); + parent = cgroup_find_parent(cgroup->name); + if (!parent) return ret; - } + + dbg("parent is %s\n", parent); parent_cgroup = cgroup_new_cgroup(parent); if (!parent_cgroup) goto err_nomem; @@ -744,17 +796,19 @@ int cgroup_create_cgroup_from_parent(struct cgroup *cgroup, int ignore_ownership if (cgroup_get_cgroup(parent_cgroup) == NULL) goto err_parent; + dbg("got parent group for %s\n", parent_cgroup->name); ret = cgroup_copy_cgroup(cgroup, parent_cgroup); if (ret) goto err_parent; + dbg("copied parent group %s to %s\n", parent_cgroup->name, + cgroup->name); ret = cgroup_create_cgroup(cgroup, ignore_ownership); err_parent: cgroup_free(&parent_cgroup); err_nomem: free(parent); - free(orig_dir_name); return ret; } @@ -861,7 +915,11 @@ static char *cg_rd_ctrl_file(char *subsys, char *cgroup, char *file) if (!value) return NULL; - fscanf(ctrl_file, "%as", &value); + /* + * using %as crashes when we try to read from files like + * memory.stat + */ + fscanf(ctrl_file, "%s", value); fclose(ctrl_file); |