Current libcgroup design handles each hierarchy only once. If a hierarchy
is mounted twice or more times, only the first mount point is taken into
account and the others are 'invisible' to libcgroup.

This causes cgsnapshot and lssubsys to show only one mount point for a
hierarchy and especially in case of cgsnapshot it's not what user expects.
The patch below enhances internal table of mount points with duplicate
mounts of the same hierarchy.

In addition. cgroup_get_controller_begin is enhanced too. This introduces
incompatible ABI change, sizeof() public structure changes and all apps
needs to be recompiled - how does it sound to you? Or should I make new set
of begin/next/end functions to get all mount points of a hierarchy?


Please note that the patch is not intended to be accepted, I need to test
it and also some changes in lssubsys and cgsnapshot are needed.

Signed-off-by: Jan Safranek <jsafr...@redhat.com>
---

 include/libcgroup/iterators.h |   15 +++++++++++++++
 src/api.c                     |   41 +++++++++++++++++++++++++----------------
 src/config.c                  |    4 ++++
 src/libcgroup-internal.h      |    6 ++++++
 4 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/include/libcgroup/iterators.h b/include/libcgroup/iterators.h
index 8ecc53f..a897336 100644
--- a/include/libcgroup/iterators.h
+++ b/include/libcgroup/iterators.h
@@ -305,6 +305,19 @@ int cgroup_get_task_end(void **handle);
  */
 
 /**
+ * Flags for struct cgroup_mount_point.
+ */
+enum cgroup_mount_point_flags {
+       /**
+        * When this flag is set, cgroup_mount_point describes a controller,
+        * which has already been reported by  cgroup_get_controller_begin()
+        * or cgroup_get_controller_next(). This happens when one hierarchy
+        * is mounted to two or more different mount points.
+        */
+       CGROUP_MOUNT_POINT_DUPLICATE
+};
+
+/**
  * Information about mounted controller.
  */
 struct cgroup_mount_point {
@@ -312,6 +325,8 @@ struct cgroup_mount_point {
        char name[FILENAME_MAX];
        /** Mount point of the controller. */
        char path[FILENAME_MAX];
+       /** Flags; combination of enum cgroup_mount_point_flags. */
+       int flags;
 };
 
 /**
diff --git a/src/api.c b/src/api.c
index b76b793..508fc1f 100644
--- a/src/api.c
+++ b/src/api.c
@@ -823,16 +823,12 @@ int cgroup_init(void)
                                        break;
                                }
                        }
-                       if (duplicate) {
-                               cgroup_dbg("controller %s is already mounted on 
%s\n",
-                                       mntopt, cg_mount_table[j].path);
-                               break;
-                       }
-
                        strcpy(cg_mount_table[found_mnt].name, controllers[i]);
                        strcpy(cg_mount_table[found_mnt].path, ent->mnt_dir);
-                       cgroup_dbg("Found cgroup option %s, count %d\n",
-                               ent->mnt_opts, found_mnt);
+                       cg_mount_table[found_mnt].duplicate = duplicate;
+                       cgroup_dbg("Found cgroup option %s, count %d, " \
+                               "duplicate %d\n", ent->mnt_opts, found_mnt,
+                               duplicate);
                        found_mnt++;
                }
 
@@ -856,16 +852,12 @@ int cgroup_init(void)
                                }
                        }
 
-                       if (duplicate) {
-                               cgroup_dbg("controller %s is already mounted on 
%s\n",
-                                       mntopt, cg_mount_table[j].path);
-                               continue;
-                       }
-
                        strcpy(cg_mount_table[found_mnt].name, mntopt);
                        strcpy(cg_mount_table[found_mnt].path, ent->mnt_dir);
-                       cgroup_dbg("Found cgroup option %s, count %d\n",
-                               ent->mnt_opts, found_mnt);
+                       cg_mount_table[found_mnt].duplicate = duplicate;
+                       cgroup_dbg("Found cgroup option %s, count %d, " \
+                               "duplicate %d\n", ent->mnt_opts, found_mnt,
+                               duplicate);
                        found_mnt++;
                }
        }
@@ -954,6 +946,12 @@ static char *cg_build_path_locked(const char *name, char 
*path,
        int i;
        for (i = 0; cg_mount_table[i].name[0] != '\0'; i++) {
                /*
+                * Don't examine duplicates, those controllers were already
+                * checked.
+                */
+               if (cg_mount_table[i].duplicate)
+                       continue;
+               /*
                 * XX: Change to snprintf once you figure what n should be
                 */
                if (strcmp(cg_mount_table[i].name, type) == 0) {
@@ -1046,6 +1044,8 @@ int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t 
tid)
                pthread_rwlock_rdlock(&cg_mount_table_lock);
                for (i = 0; i < CG_CONTROLLER_MAX &&
                                cg_mount_table[i].name[0] != '\0'; i++) {
+                       if (cg_mount_table[i].duplicate)
+                               continue;
                        if (!cg_build_path_locked(NULL, path,
                                                cg_mount_table[i].name))
                                continue;
@@ -2119,6 +2119,9 @@ int cgroup_get_cgroup(struct cgroup *cgroup)
                struct stat stat_buffer;
                int path_len;
 
+               if (cg_mount_table[i].duplicate)
+                       continue;
+
                if (!cg_build_path_locked(NULL, path,
                                        cg_mount_table[i].name))
                        continue;
@@ -2245,6 +2248,8 @@ static int cg_prepare_cgroup(struct cgroup *cgroup, pid_t 
pid,
                        pthread_rwlock_rdlock(&cg_mount_table_lock);
                        for (j = 0; j < CG_CONTROLLER_MAX &&
                                cg_mount_table[j].name[0] != '\0'; j++) {
+                               if (cg_mount_table[j].duplicate)
+                                       continue;
                                cgroup_dbg("Adding controller %s\n",
                                        cg_mount_table[j].name);
                                cptr = cgroup_add_controller(cgroup,
@@ -3282,6 +3287,10 @@ int cgroup_get_controller_next(void **handle, struct 
cgroup_mount_point *info)
        strncpy(info->name, cg_mount_table[*pos].name, FILENAME_MAX);
 
        strncpy(info->path, cg_mount_table[*pos].path, FILENAME_MAX);
+       if (cg_mount_table[*pos].duplicate)
+               info->flags = CGROUP_MOUNT_POINT_DUPLICATE;
+       else
+               info->flags = 0;
 
        (*pos)++;
        *handle = pos;
diff --git a/src/config.c b/src/config.c
index 0f71003..6a50eaa 100644
--- a/src/config.c
+++ b/src/config.c
@@ -498,6 +498,8 @@ static int config_validate_namespaces(void)
 
        pthread_rwlock_wrlock(&cg_mount_table_lock);
        for (i = 0; cg_mount_table[i].name[0] != '\0'; i++) {
+               if (cg_mount_table[i].duplicate)
+                       continue;
                /*
                 * If we get the path in the first run, then we
                 * are good, else we will need to go for two
@@ -626,6 +628,8 @@ static int config_order_namespace_table(void)
                int j;
                int flag = 0;
                for (j = 0; cg_mount_table[j].name[0] != '\0'; j++) {
+                       if (cg_mount_table[j].duplicate)
+                               continue;
                        if (strncmp(config_namespace_table[i].name,
                                cg_mount_table[j].name, FILENAME_MAX) == 0) {
 
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index 801b35e..5cf8fbe 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -93,6 +93,12 @@ struct cg_mount_table_s {
        char name[FILENAME_MAX];
        char path[FILENAME_MAX];
        int index;
+
+       /**
+        * When set, the same controller is already in mount table with lower
+        * index - used when one hierarchy is mounted multiple times.
+        */
+       int duplicate;
 };
 
 struct cgroup_rules_data {


------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to