]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api: Introduce a new API to find the cgroup setup mode
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Mon, 10 Oct 2022 15:50:34 +0000 (21:20 +0530)
committerTom Hromatka <tom.hromatka@oracle.com>
Tue, 18 Oct 2022 19:32:09 +0000 (19:32 +0000)
This patch introduces a new API to detect the current cgroup setup
mode (Legacy/Unified/Hybrid). The setup will depend on the Linux
Kernel's grub command line, the system/VM is booted with.

Uses cases:
Depending upon the cgroup setup, the users can enable or disable
features in their applications. Like some controllers are only available
on cgroup v2, so they might need to set/get settings for those available
controllers only.

Suggested-by: Tom Hromatka <tom.hromatka@oracle.com>
Suggested-by: Michal Koutný <mkoutny@suse.com>
Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
include/libcgroup/groups.h
src/api.c
src/libcgroup.map

index 41edbda2b740b0f3792287005eee085c5f37e20b..dc8479a6c3c90f9c39677f3fb38292cf1e1544c3 100644 (file)
@@ -23,6 +23,13 @@ enum cg_version_t {
        CGROUP_DISK = 0xFF,
 };
 
+enum cg_setup_mode_t {
+       CGROUP_MODE_UNK = 0,
+       CGROUP_MODE_LEGACY,
+       CGROUP_MODE_HYBRID,
+       CGROUP_MODE_UNIFIED,
+};
+
 /**
  * Flags for cgroup_delete_cgroup_ext().
  */
@@ -636,6 +643,13 @@ int cgroup_list_mount_points(const enum cg_version_t cgrp_version,
 int cgroup_get_controller_version(const char * const controller,
                                  enum cg_version_t * const version);
 
+/**
+ * Get the current group setup mode (legacy/unified/hybrid)
+ *
+ * @return CGROUP_MODE_UNK on failure and setup mode on success
+ */
+enum cg_setup_mode_t cgroup_setup_mode(void);
+
 /**
  * @}
  * @}
index 51190ad410386de5d98a68854567fd7d386d6d5b..92e211ddfda7076d71ae307abbd5f7ab902a54f7 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -43,6 +43,7 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/vfs.h>
 
 #include <linux/un.h>
 
@@ -6118,3 +6119,53 @@ const struct cgroup_library_version *cgroup_version(void)
 {
        return &library_version;
 }
+
+/**
+ * Finds the current cgroup setup mode (legacy/unified/hybrid).
+ * Returns unknown of failure and setup mode on success.
+ */
+enum cg_setup_mode_t cgroup_setup_mode(void)
+{
+#define CGROUP2_SUPER_MAGIC    0x63677270
+#define CGROUP_SUPER_MAGIC     0x27E0EB
+
+       unsigned int cg_setup_mode_bitmask = 0U;
+       enum cg_setup_mode_t setup_mode;
+       struct statfs cgrp_buf;
+       int i, ret = 0;
+
+       if (!cgroup_initialized) {
+               return ECGROUPNOTINITIALIZED;
+       }
+
+       setup_mode = CGROUP_MODE_UNK;
+
+       pthread_rwlock_wrlock(&cg_mount_table_lock);
+       for (i = 0; cg_mount_table[i].name[0] != '\0'; i++) {
+               ret = statfs(cg_mount_table[i].mount.path, &cgrp_buf);
+               if (ret) {
+                       setup_mode = CGROUP_MODE_UNK;
+                       cgroup_err("Failed to get stats of '%s'\n", cg_mount_table[i].mount.path);
+                       goto out;
+               }
+
+               if (cgrp_buf.f_type == CGROUP2_SUPER_MAGIC)
+                       cg_setup_mode_bitmask |= (1U << 0);
+               else if (cgrp_buf.f_type == CGROUP_SUPER_MAGIC)
+                       cg_setup_mode_bitmask |= (1U << 1);
+       }
+
+       if (cg_cgroup_v2_empty_mount_paths)
+               cg_setup_mode_bitmask |= (1U << 0);
+
+       if (cg_setup_mode_bitmask & (1U << 0) && cg_setup_mode_bitmask & (1U << 1))
+               setup_mode = CGROUP_MODE_HYBRID;
+       else if (cg_setup_mode_bitmask & (1U << 0))
+               setup_mode = CGROUP_MODE_UNIFIED;
+       else if (cg_setup_mode_bitmask & (1U << 1))
+               setup_mode = CGROUP_MODE_LEGACY;
+
+out:
+       pthread_rwlock_unlock(&cg_mount_table_lock);
+       return setup_mode;
+}
index fbf4d5d510cdcda1ecb357c587a91b85ad207441..0cecba2fd465d9d5a20503d33e5e5c443301dd82 100644 (file)
@@ -146,4 +146,7 @@ CGROUP_3.0 {
        cgroup_cgxset;
        cgroup_version;
        cgroup_list_mount_points;
+
+       /* libcgroup 3.0.1 */
+       cgroup_setup_mode;
 } CGROUP_2.0;