]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
More fixes to the earlier attempt to create new cgroup inheriting parent's
authorBalbir Singh <balbir@linux.vnet.ibm.com>
Fri, 22 Aug 2008 22:34:50 +0000 (22:34 +0000)
committerBalbir Singh <balbir@linux.vnet.ibm.com>
Fri, 22 Aug 2008 22:34:50 +0000 (22:34 +0000)
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

api.c
tests/libcg_ba.cpp

diff --git a/api.c b/api.c
index 3755957afccdb09c8f75f180d5a4f680f081198e..99037e8f0119b6220fdadeda93f77d3c45ad25c8 100644 (file)
--- a/api.c
+++ b/api.c
@@ -711,32 +711,84 @@ err:
        return error;
 }
 
+/**
+ * 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);
 
index 99a9184d2dc8616f4133ae42c44628b04feab198..6d402b6552e9f777c2143abfeef8942b8eb097fb 100644 (file)
@@ -86,8 +86,7 @@ struct cgroup *cg::makenode(const string &name, const string &task_uid,
        dbg("tuid %d, tgid %d, cuid %d, cgid %d\n", tuid, tgid, cuid, cgid);
 
        cgroup_name = (char *) malloc(name.length());
-       memset(cgroup_name, '\0', name.length());
-       strncpy(cgroup_name, name.c_str(), name.length());
+       strncpy(cgroup_name, name.c_str(), name.length() + 1);
 
        ccg = cgroup_new_cgroup(cgroup_name);
        cgroup_set_uid_gid(ccg, tuid, tgid, cuid, cgid);
@@ -135,12 +134,14 @@ int main(int argc, char *argv[])
 {
        try {
                cg *app = new cg();
-               struct cgroup *ccg, *ccg_child;
+               struct cgroup *ccg, *ccg_child1, *ccg_child2;
                ccg = app->makenode("database", "root", "root", "balbir",
                                        "balbir");
-               ccg_child = app->makenodefromparent("mysql");
+               ccg_child1 = app->makenodefromparent("mysql");
+               ccg_child2 = app->makenodefromparent("mysql/db1");
                cgroup_free(&ccg);
-               cgroup_free(&ccg_child);
+               cgroup_free(&ccg_child1);
+               cgroup_free(&ccg_child2);
                delete app;
        } catch (exception &e) {
                cout << e.what() << endl;