summaryrefslogtreecommitdiff
path: root/0029-refactor-cgroup-module.patch
diff options
context:
space:
mode:
Diffstat (limited to '0029-refactor-cgroup-module.patch')
-rw-r--r--0029-refactor-cgroup-module.patch2538
1 files changed, 2538 insertions, 0 deletions
diff --git a/0029-refactor-cgroup-module.patch b/0029-refactor-cgroup-module.patch
new file mode 100644
index 0000000..f5e853d
--- /dev/null
+++ b/0029-refactor-cgroup-module.patch
@@ -0,0 +1,2538 @@
+From c26604ff3150babae729890c549f2784212073a1 Mon Sep 17 00:00:00 2001
+From: zhongtao <zhongtao17@huawei.com>
+Date: Wed, 20 Mar 2024 15:53:56 +0800
+Subject: [PATCH 29/43] refactor cgroup module
+
+Signed-off-by: zhongtao <zhongtao17@huawei.com>
+---
+ src/cmd/isulad/main.c | 6 +
+ src/daemon/common/CMakeLists.txt | 4 +
+ src/daemon/common/cgroup.c | 625 ----------------
+ src/daemon/common/cgroup/CMakeLists.txt | 5 +
+ src/daemon/common/cgroup/cgroup.c | 136 ++++
+ src/daemon/common/cgroup/cgroup.h | 48 ++
+ src/daemon/common/cgroup/cgroup_common.c | 131 ++++
+ .../{cgroup.h => cgroup/cgroup_common.h} | 62 +-
+ src/daemon/common/{ => cgroup}/cgroup_v1.c | 699 +++++++++++++++---
+ src/daemon/common/cgroup/cgroup_v1.h | 30 +
+ src/daemon/common/{ => cgroup}/cgroup_v2.c | 162 ++--
+ src/daemon/common/cgroup/cgroup_v2.h | 30 +
+ src/daemon/common/sysinfo.c | 33 +-
+ src/daemon/common/sysinfo.h | 4 +-
+ .../v1/v1_cri_pod_sandbox_manager_service.cc | 13 +-
+ .../cri_pod_sandbox_manager_service.cc | 13 +-
+ src/daemon/executor/container_cb/execution.c | 13 +-
+ 17 files changed, 1124 insertions(+), 890 deletions(-)
+ delete mode 100644 src/daemon/common/cgroup.c
+ create mode 100644 src/daemon/common/cgroup/CMakeLists.txt
+ create mode 100644 src/daemon/common/cgroup/cgroup.c
+ create mode 100644 src/daemon/common/cgroup/cgroup.h
+ create mode 100644 src/daemon/common/cgroup/cgroup_common.c
+ rename src/daemon/common/{cgroup.h => cgroup/cgroup_common.h} (60%)
+ rename src/daemon/common/{ => cgroup}/cgroup_v1.c (52%)
+ create mode 100644 src/daemon/common/cgroup/cgroup_v1.h
+ rename src/daemon/common/{ => cgroup}/cgroup_v2.c (88%)
+ create mode 100644 src/daemon/common/cgroup/cgroup_v2.h
+
+diff --git a/src/cmd/isulad/main.c b/src/cmd/isulad/main.c
+index 7c0c072e..9fa87bdb 100644
+--- a/src/cmd/isulad/main.c
++++ b/src/cmd/isulad/main.c
+@@ -82,6 +82,7 @@
+ #include "network_api.h"
+ #endif
+ #include "id_name_manager.h"
++#include "cgroup.h"
+
+ sem_t g_daemon_shutdown_sem;
+ sem_t g_daemon_wait_shutdown_sem;
+@@ -1706,6 +1707,11 @@ static int pre_init_daemon(int argc, char **argv)
+ goto out;
+ }
+
++ if (cgroup_ops_init() != 0) {
++ ERROR("Failed to init cgroup");
++ goto out;
++ }
++
+ if (server_conf_parse_save(argc, (const char **)argv)) {
+ ERROR("%s", g_isulad_errmsg ? g_isulad_errmsg : "Failed to parse and save server conf");
+ goto out;
+diff --git a/src/daemon/common/CMakeLists.txt b/src/daemon/common/CMakeLists.txt
+index d634507b..e88578dd 100644
+--- a/src/daemon/common/CMakeLists.txt
++++ b/src/daemon/common/CMakeLists.txt
+@@ -9,16 +9,20 @@ if (GRPC_CONNECTOR)
+ add_subdirectory(cri)
+ endif()
+
++add_subdirectory(cgroup)
++
+ set(local_daemon_common_srcs ${daemon_common_top_srcs})
+
+ set(DAEMON_COMMON_SRCS
+ ${COMMON_CRI_SRCS}
++ ${COMMON_CGROUP_SRCS}
+ ${local_daemon_common_srcs}
+ PARENT_SCOPE
+ )
+
+ set(DAEMON_COMMON_INCS
+ ${COMMON_CRI_INCS}
++ ${COMMON_CGROUP_INCS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ PARENT_SCOPE
+ )
+diff --git a/src/daemon/common/cgroup.c b/src/daemon/common/cgroup.c
+deleted file mode 100644
+index 3c58f7fa..00000000
+--- a/src/daemon/common/cgroup.c
++++ /dev/null
+@@ -1,625 +0,0 @@
+-/******************************************************************************
+- * Copyright (c) Huawei Technologies Co., Ltd. 2017-2023. All rights reserved.
+- * iSulad licensed under the Mulan PSL v2.
+- * You can use this software according to the terms and conditions of the Mulan PSL v2.
+- * You may obtain a copy of Mulan PSL v2 at:
+- * http://license.coscl.org.cn/MulanPSL2
+- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+- * PURPOSE.
+- * See the Mulan PSL v2 for more details.
+- * Author: zhangxiaoyu
+- * Create: 2023-03-29
+- * Description: provide cgroup functions
+- ******************************************************************************/
+-#include "cgroup.h"
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <sys/vfs.h>
+-#include <linux/magic.h>
+-#include <sys/stat.h>
+-
+-#include <isula_libutils/auto_cleanup.h>
+-
+-#include "err_msg.h"
+-#include "utils.h"
+-#include "utils_array.h"
+-#include "sysinfo.h"
+-
+-#ifndef CGROUP_SUPER_MAGIC
+-#define CGROUP_SUPER_MAGIC 0x27e0eb
+-#endif
+-
+-static cgroup_layer_t *new_cgroup_layer(size_t len)
+-{
+- cgroup_layer_t *layers = NULL;
+-
+- if (len == 0) {
+- return NULL;
+- }
+-
+- layers = (cgroup_layer_t *)util_common_calloc_s(sizeof(cgroup_layer_t));
+- if (layers == NULL) {
+- ERROR("Out of memory");
+- return NULL;
+- }
+-
+- layers->items = (cgroup_layers_item **)util_smart_calloc_s(sizeof(cgroup_layers_item *), len);
+- if (layers->items == NULL) {
+- ERROR("Out of memory");
+- free(layers);
+- return NULL;
+- }
+-
+- layers->len = 0;
+- layers->cap = len;
+-
+- return layers;
+-}
+-
+-static int add_cgroup_layer(cgroup_layer_t *layers, char **clist, char *mountpoint)
+-{
+-#define CGROUP_LAYER_MAX_CAPABILITY 1024
+- size_t new_size;
+- cgroup_layers_item *newh = NULL;
+- cgroup_layers_item **tmp = NULL;
+-
+- if (layers->len >= CGROUP_LAYER_MAX_CAPABILITY) {
+- ERROR("Too many cgroup layers");
+- return -1;
+- }
+-
+- newh = util_common_calloc_s(sizeof(cgroup_layers_item));
+- if (newh == NULL) {
+- ERROR("Out of memory");
+- return -1;
+- }
+- newh->controllers = clist;
+- newh->mountpoint = mountpoint;
+-
+- if (layers->len < layers->cap) {
+- goto out;
+- }
+-
+- if (layers->cap > CGROUP_LAYER_MAX_CAPABILITY / 2) {
+- new_size = CGROUP_LAYER_MAX_CAPABILITY;
+- } else {
+- new_size = layers->cap * 2;
+- }
+-
+- if (util_mem_realloc((void **)&tmp, new_size * sizeof(cgroup_layers_item *),
+- layers->items, layers->cap * sizeof(cgroup_layers_item *)) != 0) {
+- ERROR("Failed to realloc memory");
+- free(newh);
+- return -1;
+- }
+-
+- layers->items = tmp;
+- tmp = NULL;
+- layers->cap = new_size;
+-
+-out:
+- layers->items[layers->len] = newh;
+- layers->len++;
+- return 0;
+-}
+-
+-void common_free_cgroup_layer(cgroup_layer_t *layers)
+-{
+- size_t i;
+-
+- if (layers == NULL) {
+- return;
+- }
+-
+- for (i = 0; i < layers->len && layers->items[i]; i++) {
+- free(layers->items[i]->mountpoint);
+- layers->items[i]->mountpoint = NULL;
+- util_free_array(layers->items[i]->controllers);
+- layers->items[i]->controllers = NULL;
+- free(layers->items[i]);
+- layers->items[i] = NULL;
+- }
+-
+- free(layers->items);
+- layers->items = NULL;
+- layers->len = 0;
+- layers->cap = 0;
+-
+- free(layers);
+-}
+-
+-static int append_subsystem_to_list(char ***klist, char ***nlist, const char *ptoken)
+-{
+- int ret = 0;
+-
+- if (strncmp(ptoken, "name=", strlen("name=")) == 0) {
+- ret = util_array_append(nlist, ptoken);
+- if (ret != 0) {
+- ERROR("Failed to append string");
+- return -1;
+- }
+- } else {
+- ret = util_array_append(klist, ptoken);
+- if (ret != 0) {
+- ERROR("Failed to append string");
+- return -1;
+- }
+- }
+-
+- return 0;
+-}
+-
+-static int get_cgroup_subsystems(char ***klist, char ***nlist)
+-{
+- int ret = 0;
+- size_t length = 0;
+- FILE *fp = NULL;
+- char *pline = NULL;
+-
+- fp = util_fopen("/proc/self/cgroup", "r");
+- if (fp == NULL) {
+- return -1;
+- }
+-
+- while (getline(&pline, &length, fp) != -1) {
+- char *pos = NULL;
+- char *pos2 = NULL;
+- char *ptoken = NULL;
+- char *psave = NULL;
+- pos = strchr(pline, ':');
+- if (pos == NULL) {
+- ERROR("Invalid cgroup entry: must contain at least two colons: %s", pline);
+- ret = -1;
+- goto out;
+- }
+- pos++;
+- pos2 = strchr(pos, ':');
+- if (pos2 == NULL) {
+- ERROR("Invalid cgroup entry: must contain at least two colons: %s", pline);
+- ret = -1;
+- goto out;
+- }
+- *pos2 = '\0';
+-
+- if ((pos2 - pos) == 0) {
+- INFO("Not supported cgroup entry: %s", pline);
+- continue;
+- }
+-
+- for (ptoken = strtok_r(pos, ",", &psave); ptoken; ptoken = strtok_r(NULL, ",", &psave)) {
+- if (append_subsystem_to_list(klist, nlist, ptoken)) {
+- goto out;
+- }
+- }
+- }
+-
+-out:
+- free(pline);
+- fclose(fp);
+- if (ret != 0) {
+- util_free_array(*klist);
+- *klist = NULL;
+- util_free_array(*nlist);
+- *nlist = NULL;
+- }
+- return ret;
+-}
+-
+-static int append_controller(const char **klist, const char **nlist, char ***clist, const char *entry)
+-{
+- int ret = 0;
+- char *dup_entry = NULL;
+-
+- if (util_array_contain(klist, entry) && util_array_contain(nlist, entry)) {
+- ERROR("Refusing to use ambiguous controller \"%s\"", entry);
+- ERROR("It is both a named and kernel subsystem");
+- return -1;
+- }
+-
+- if (strncmp(entry, "name=", 5) == 0) {
+- dup_entry = util_strdup_s(entry);
+- } else if (util_array_contain(klist, entry)) {
+- dup_entry = util_strdup_s(entry);
+- } else {
+- dup_entry = util_string_append(entry, "name=");
+- }
+- if (dup_entry == NULL) {
+- ERROR("Out of memory");
+- return -1;
+- }
+-
+- ret = util_array_append(clist, dup_entry);
+- if (ret != 0) {
+- ERROR("Failed to append array");
+- }
+-
+- free(dup_entry);
+- return ret;
+-}
+-
+-static inline bool is_cgroup_mountpoint(const char *mp)
+-{
+- return strncmp(mp, "/sys/fs/cgroup/", strlen("/sys/fs/cgroup/")) == 0;
+-}
+-
+-static char **cgroup_get_controllers(const char **klist, const char **nlist, const char *line)
+-{
+- int index;
+- char *dup = NULL;
+- char *pos2 = NULL;
+- char *tok = NULL;
+- const char *pos = line;
+- char *psave = NULL;
+- char *sep = ",";
+- char **pret = NULL;
+-
+- // line example
+- // 108 99 0:55 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
+- for (index = 0; index < 4; index++) {
+- pos = strchr(pos, ' ');
+- if (pos == NULL) {
+- ERROR("Invalid mountinfo format \"%s\"", line);
+- return NULL;
+- }
+- pos++;
+- }
+-
+- if (!is_cgroup_mountpoint(pos)) {
+- return NULL;
+- }
+-
+- pos += strlen("/sys/fs/cgroup/");
+- pos2 = strchr(pos, ' ');
+- if (pos2 == NULL) {
+- ERROR("Invalid mountinfo format \"%s\"", line);
+- return NULL;
+- }
+-
+- *pos2 = '\0';
+- dup = util_strdup_s(pos);
+- *pos2 = ' ';
+-
+- for (tok = strtok_r(dup, sep, &psave); tok; tok = strtok_r(NULL, sep, &psave)) {
+- if (append_controller(klist, nlist, &pret, tok)) {
+- ERROR("Failed to append controller");
+- util_free_array(pret);
+- pret = NULL;
+- break;
+- }
+- }
+-
+- free(dup);
+-
+- return pret;
+-}
+-
+-int cgroup_get_mountpoint_and_root(char *pline, char **mountpoint, char **root)
+-{
+- int index;
+- char *posmp = NULL;
+- char *posrt = NULL;
+- char *pos = pline;
+-
+- // find root
+- // line example
+- // 108 99 0:55 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
+- for (index = 0; index < 3; index++) {
+- pos = strchr(pos, ' ');
+- if (pos == NULL) {
+- return -1;
+- }
+- pos++;
+- }
+- posrt = pos;
+-
+- // find mountpoint
+- pos = strchr(pos, ' ');
+- if (pos == NULL) {
+- return -1;
+- }
+-
+- *pos = '\0';
+- if (root != NULL) {
+- *root = util_strdup_s(posrt);
+- }
+-
+- pos++;
+- posmp = pos;
+-
+- if (!is_cgroup_mountpoint(posmp)) {
+- return -1;
+- }
+-
+- pos = strchr(pos + strlen("/sys/fs/cgroup/"), ' ');
+- if (pos == NULL) {
+- return -1;
+- }
+- *pos = '\0';
+-
+- if (mountpoint != NULL) {
+- *mountpoint = util_strdup_s(posmp);
+- }
+-
+- return 0;
+-}
+-
+-static bool lists_intersect(const char **controllers, const char **list)
+-{
+- int index;
+-
+- if (controllers == NULL || list == NULL) {
+- return false;
+- }
+-
+- for (index = 0; controllers[index]; index++) {
+- if (util_array_contain(list, controllers[index])) {
+- return true;
+- }
+- }
+-
+- return false;
+-}
+-
+-static bool controller_list_is_dup(const cgroup_layer_t *llist, const char **clist)
+-{
+- size_t index;
+-
+- if (llist == NULL) {
+- return false;
+- }
+-
+- for (index = 0; index < llist->len && llist->items[index]; index++) {
+- if (lists_intersect((const char **)llist->items[index]->controllers, (const char **)clist)) {
+- return true;
+- }
+- }
+-
+- return false;
+-}
+-
+-cgroup_layer_t *common_cgroup_layers_find(void)
+-{
+- int nret;
+- int ret = 0;
+- FILE *fp = NULL;
+- size_t length = 0;
+- const size_t cgroup_layer_item_num = 10;
+- char *pline = NULL;
+- char **klist = NULL;
+- char **nlist = NULL;
+- cgroup_layer_t *layers = NULL;
+-
+- layers = new_cgroup_layer(cgroup_layer_item_num);
+- if (layers == NULL) {
+- ERROR("Failed to new cgroup layer");
+- return NULL;
+- }
+-
+- ret = get_cgroup_subsystems(&klist, &nlist);
+- if (ret != 0) {
+- ERROR("Failed to retrieve available legacy cgroup controllers\n");
+- goto out;
+- }
+-
+- fp = util_fopen("/proc/self/mountinfo", "r");
+- if (fp == NULL) {
+- ERROR("Failed to open \"/proc/self/mountinfo\"\n");
+- ret = -1;
+- goto out;
+- }
+-
+- while (getline(&pline, &length, fp) != -1) {
+- char *mountpoint = NULL;
+- char **clist = NULL;
+- int mret;
+-
+- clist = cgroup_get_controllers((const char **)klist, (const char **)nlist, pline);
+- if (clist == NULL) {
+- goto list_out;
+- }
+-
+- if (controller_list_is_dup(layers, (const char **)clist)) {
+- goto list_out;
+- }
+-
+- mret = cgroup_get_mountpoint_and_root(pline, &mountpoint, NULL);
+- if (mret != 0 || mountpoint == NULL) {
+- ERROR("Failed parsing mountpoint from \"%s\"\n", pline);
+- goto list_out;
+- }
+-
+- nret = add_cgroup_layer(layers, clist, mountpoint);
+- if (nret != 0) {
+- ERROR("Failed to add hierarchies");
+- goto list_out;
+- }
+-
+- continue;
+-list_out:
+- util_free_array(clist);
+- free(mountpoint);
+- }
+-out:
+- util_free_array(klist);
+- util_free_array(nlist);
+- if (fp != NULL) {
+- fclose(fp);
+- }
+- free(pline);
+-
+- if (ret != 0) {
+- common_free_cgroup_layer(layers);
+- return NULL;
+- }
+-
+- return layers;
+-}
+-
+-char *common_find_cgroup_subsystem_mountpoint(const cgroup_layer_t *layers, const char *subsystem)
+-{
+- size_t i;
+-
+- for (i = 0; i < layers->len && layers->items[i]; i++) {
+- char **cit = NULL;
+-
+- for (cit = layers->items[i]->controllers; cit && *cit; cit++) {
+- if (strcmp(*cit, subsystem) == 0) {
+- return layers->items[i]->mountpoint;
+- }
+- }
+- }
+- return NULL;
+-}
+-
+-/* find cgroup mountpoint and root */
+-int common_find_cgroup_mnt_and_root(const char *subsystem, char **mountpoint, char **root)
+-{
+- int ret = 0;
+- FILE *fp = NULL;
+- size_t length = 0;
+- char *pline = NULL;
+-
+- if (subsystem == NULL) {
+- ERROR("Empty subsystem");
+- return -1;
+- }
+-
+- fp = util_fopen("/proc/self/mountinfo", "r");
+- if (fp == NULL) {
+- ERROR("Failed to open \"/proc/self/mountinfo\"\n");
+- ret = -1;
+- goto free_out;
+- }
+-
+- while (getline(&pline, &length, fp) != -1) {
+- char *dup = NULL;
+- char *p = NULL;
+- char *tok = NULL;
+- char *mp = NULL;
+- char *rt = NULL;
+- char *saveptr = NULL;
+- char *sep = ",";
+- int mret;
+-
+- mret = cgroup_get_mountpoint_and_root(pline, &mp, &rt);
+- if (mret != 0 || mp == NULL || rt == NULL) {
+- goto mp_out;
+- }
+-
+- p = mp;
+- p += strlen("/sys/fs/cgroup/");
+- dup = util_strdup_s(p);
+- if (dup == NULL) {
+- ERROR("Out of memory");
+- free(mp);
+- ret = -1;
+- goto free_out;
+- }
+-
+- for (tok = strtok_r(dup, sep, &saveptr); tok; tok = strtok_r(NULL, sep, &saveptr)) {
+- if (strcmp(tok, subsystem) != 0) {
+- continue;
+- }
+- if (mountpoint != NULL) {
+- *mountpoint = mp;
+- } else {
+- free(mp);
+- }
+- if (root != NULL) {
+- *root = rt;
+- } else {
+- free(rt);
+- }
+- free(dup);
+- goto free_out;
+- }
+- free(dup);
+-mp_out:
+- free(mp);
+- free(rt);
+- continue;
+- }
+-free_out:
+- if (fp != NULL) {
+- fclose(fp);
+- }
+- free(pline);
+- return ret;
+-}
+-
+-int common_get_cgroup_version(void)
+-{
+- struct statfs fs = { 0 };
+-
+- if (statfs(CGROUP_MOUNTPOINT, &fs) != 0) {
+- SYSERROR("failed to statfs %s", CGROUP_MOUNTPOINT);
+- return -1;
+- }
+-
+- if (fs.f_type == CGROUP2_SUPER_MAGIC) {
+- return CGROUP_VERSION_2;
+- }
+-
+- return CGROUP_VERSION_1;
+-}
+-
+-static int get_value_ull(const char *content, void *result)
+-{
+- uint64_t ull_result = 0;
+-
+- if (util_safe_uint64(content, &ull_result) != 0) {
+- ERROR("Failed to convert %s to uint64", content);
+- return -1;
+- }
+-
+- *(uint64_t *)result = ull_result;
+- return 0;
+-}
+-
+-int get_match_value_ull(const char *content, const char *match, void *result)
+-{
+- __isula_auto_free char *llu_string = NULL;
+- __isula_auto_free char *match_with_space = NULL;
+- __isula_auto_array_t char **lines = NULL;
+- char **worker = NULL;
+-
+- if (match == NULL) {
+- return get_value_ull(content, result);
+- }
+-
+- // match full string
+- match_with_space = util_string_append(" ", match);
+- if (match_with_space == NULL) {
+- ERROR("Failed to append string");
+- return -1;
+- }
+-
+- lines = util_string_split(content, '\n');
+- if (lines == NULL) {
+- ERROR("Failed to split content %s", content);
+- return -1;
+- }
+-
+- for (worker = lines; worker && *worker; worker++) {
+- if (util_has_prefix(*worker, match_with_space)) {
+- break;
+- }
+- }
+- if (*worker == NULL) {
+- ERROR("Cannot find match string %s", match);
+- return -1;
+- }
+-
+- llu_string = util_sub_string(*worker, strlen(match_with_space), strlen(*worker) - strlen(match_with_space));
+- if (llu_string == NULL) {
+- ERROR("Failed to sub string");
+- return -1;
+- }
+- llu_string = util_trim_space(llu_string);
+-
+- return get_value_ull(llu_string, result);
+-}
+\ No newline at end of file
+diff --git a/src/daemon/common/cgroup/CMakeLists.txt b/src/daemon/common/cgroup/CMakeLists.txt
+new file mode 100644
+index 00000000..e8c1726c
+--- /dev/null
++++ b/src/daemon/common/cgroup/CMakeLists.txt
+@@ -0,0 +1,5 @@
++# get current directory sources files
++aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_common_cgroup_srcs)
++
++set(COMMON_CGROUP_SRCS ${local_common_cgroup_srcs} PARENT_SCOPE)
++set(COMMON_CGROUP_INCS ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
+diff --git a/src/daemon/common/cgroup/cgroup.c b/src/daemon/common/cgroup/cgroup.c
+new file mode 100644
+index 00000000..837b514a
+--- /dev/null
++++ b/src/daemon/common/cgroup/cgroup.c
+@@ -0,0 +1,136 @@
++/******************************************************************************
++ * Copyright (c) Huawei Technologies Co., Ltd. 2017-2023. All rights reserved.
++ * iSulad licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ * Author: zhangxiaoyu
++ * Create: 2023-03-29
++ * Description: provide cgroup functions
++ ******************************************************************************/
++#include "cgroup.h"
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <sys/vfs.h>
++#include <linux/magic.h>
++#include <sys/stat.h>
++
++#include <isula_libutils/auto_cleanup.h>
++
++#include "err_msg.h"
++#include "utils.h"
++#include "utils_array.h"
++#include "sysinfo.h"
++#include "cgroup_v1.h"
++#include "cgroup_v2.h"
++#include "path.h"
++
++#ifndef CGROUP_SUPER_MAGIC
++#define CGROUP_SUPER_MAGIC 0x27e0eb
++#endif
++
++static cgroup_ops g_cgroup_ops;
++
++static int get_cgroup_version_for_init(void)
++{
++ struct statfs fs = { 0 };
++
++ if (statfs(CGROUP_MOUNTPOINT, &fs) != 0) {
++ SYSERROR("failed to statfs %s", CGROUP_MOUNTPOINT);
++ return -1;
++ }
++
++ if (fs.f_type == CGROUP2_SUPER_MAGIC) {
++ return CGROUP_VERSION_2;
++ }
++
++ return CGROUP_VERSION_1;
++}
++
++/* connect client ops init */
++int cgroup_ops_init(void)
++{
++ (void)memset(&g_cgroup_ops, 0, sizeof(g_cgroup_ops));
++ int cgroupVersion = get_cgroup_version_for_init();
++ if (cgroupVersion < 0) {
++ ERROR("Invalid cgroup version");
++ return -1;
++ }
++
++ if (cgroupVersion == CGROUP_VERSION_1) {
++ return cgroup_v1_ops_init(&g_cgroup_ops);
++ } else {
++ return cgroup_v2_ops_init(&g_cgroup_ops);
++ }
++}
++
++int common_get_cgroup_version(void)
++{
++ if (g_cgroup_ops.get_cgroup_version == NULL) {
++ ERROR("Unimplemented get_cgroup_version ops");
++ return -1;
++ }
++
++ return g_cgroup_ops.get_cgroup_version();
++}
++
++int common_get_cgroup_info(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
++ cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
++ cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
++ cgroup_files_info_t *filesinfo, bool quiet)
++{
++ if (g_cgroup_ops.get_cgroup_info == NULL) {
++ ERROR("Unimplemented get_cgroup_info ops");
++ return -1;
++ }
++
++ return g_cgroup_ops.get_cgroup_info(meminfo, cpuinfo, hugetlbinfo, blkioinfo, cpusetinfo, pidsinfo, filesinfo, quiet);
++}
++
++int common_get_cgroup_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics)
++{
++ if (g_cgroup_ops.get_cgroup_metrics == NULL) {
++ ERROR("Unimplemented get_cgroup_metrics ops");
++ return -1;
++ }
++
++ return g_cgroup_ops.get_cgroup_metrics(cgroup_path, cgroup_metrics);
++}
++
++int common_get_cgroup_mnt_and_root_path(const char *subsystem, char **mountpoint, char **root)
++{
++ if (g_cgroup_ops.get_cgroup_mnt_and_root_path == NULL) {
++ ERROR("Unimplemented get_cgroup_mnt_and_root_path ops");
++ return -1;
++ }
++
++ return g_cgroup_ops.get_cgroup_mnt_and_root_path(subsystem, mountpoint, root);
++}
++
++// only for cgroup v1
++char *common_get_init_cgroup_path(const char *subsystem)
++{
++ if (g_cgroup_ops.get_init_cgroup_path == NULL) {
++ ERROR("Unimplemented get_init_cgroup_path ops");
++ return NULL;
++ }
++
++ return g_cgroup_ops.get_init_cgroup_path(subsystem);
++}
++
++char *common_get_own_cgroup_path(const char *subsystem)
++{
++ if (g_cgroup_ops.get_own_cgroup_path == NULL) {
++ ERROR("Unimplemented get_own_cgroup_path ops");
++ return NULL;
++ }
++
++ return g_cgroup_ops.get_own_cgroup_path(subsystem);
++}
+\ No newline at end of file
+diff --git a/src/daemon/common/cgroup/cgroup.h b/src/daemon/common/cgroup/cgroup.h
+new file mode 100644
+index 00000000..1efc3ca6
+--- /dev/null
++++ b/src/daemon/common/cgroup/cgroup.h
+@@ -0,0 +1,48 @@
++/******************************************************************************
++ * Copyright (c) Huawei Technologies Co., Ltd. 2017-2023. All rights reserved.
++ * iSulad licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ * Author: zhangxiaoyu
++ * Create: 2023-03-29
++ * Description: provide cgroup definition
++ ******************************************************************************/
++#ifndef DAEMON_COMMON_CGROUP_H
++#define DAEMON_COMMON_CGROUP_H
++
++#include <stdbool.h>
++#include <stdint.h>
++#include <stdio.h>
++
++#include <isula_libutils/log.h>
++
++#include "cgroup_common.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++int cgroup_ops_init(void);
++
++int common_get_cgroup_version(void);
++int common_get_cgroup_info(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
++ cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
++ cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
++ cgroup_files_info_t *filesinfo, bool quiet);
++int common_get_cgroup_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics);
++int common_get_cgroup_mnt_and_root_path(const char *subsystem, char **mountpoint, char **root);
++
++// only for cgroup v1
++char *common_get_init_cgroup_path(const char *subsystem);
++char *common_get_own_cgroup_path(const char *subsystem);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif // DAEMON_COMMON_CGROUP_H
+diff --git a/src/daemon/common/cgroup/cgroup_common.c b/src/daemon/common/cgroup/cgroup_common.c
+new file mode 100644
+index 00000000..0fb9405c
+--- /dev/null
++++ b/src/daemon/common/cgroup/cgroup_common.c
+@@ -0,0 +1,131 @@
++/******************************************************************************
++ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
++ * iSulad licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ * Author: zhongtao
++ * Create: 2024-03-22
++ * Description: provide cgroup common func definition
++ ******************************************************************************/
++#include "cgroup_common.h"
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <sys/vfs.h>
++#include <linux/magic.h>
++#include <sys/stat.h>
++
++#include <isula_libutils/auto_cleanup.h>
++
++#include "err_msg.h"
++#include "utils.h"
++#include "utils_array.h"
++#include "sysinfo.h"
++#include "cgroup_v1.h"
++#include "cgroup_v2.h"
++#include "path.h"
++
++static int get_value_ull(const char *content, void *result)
++{
++ uint64_t ull_result = 0;
++
++ if (util_safe_uint64(content, &ull_result) != 0) {
++ ERROR("Failed to convert %s to uint64", content);
++ return -1;
++ }
++
++ *(uint64_t *)result = ull_result;
++ return 0;
++}
++
++int get_match_value_ull(const char *content, const char *match, void *result)
++{
++ __isula_auto_free char *llu_string = NULL;
++ __isula_auto_free char *match_with_space = NULL;
++ __isula_auto_array_t char **lines = NULL;
++ char **worker = NULL;
++
++ if (match == NULL) {
++ return get_value_ull(content, result);
++ }
++
++ // match full string
++ match_with_space = util_string_append(" ", match);
++ if (match_with_space == NULL) {
++ ERROR("Failed to append string");
++ return -1;
++ }
++
++ lines = util_string_split(content, '\n');
++ if (lines == NULL) {
++ ERROR("Failed to split content %s", content);
++ return -1;
++ }
++
++ for (worker = lines; worker && *worker; worker++) {
++ if (util_has_prefix(*worker, match_with_space)) {
++ break;
++ }
++ }
++ if (*worker == NULL) {
++ ERROR("Cannot find match string %s", match);
++ return -1;
++ }
++
++ llu_string = util_sub_string(*worker, strlen(match_with_space), strlen(*worker) - strlen(match_with_space));
++ if (llu_string == NULL) {
++ ERROR("Failed to sub string");
++ return -1;
++ }
++ llu_string = util_trim_space(llu_string);
++
++ return get_value_ull(llu_string, result);
++}
++
++int get_cgroup_value_helper(const char *path, struct cgfile_t *cgfile, void *result)
++{
++ int nret = 0;
++ char file_path[PATH_MAX] = { 0 };
++ char real_path[PATH_MAX] = { 0 };
++ char *content = NULL;
++
++ if (path == NULL || strlen(path) == 0 || result == NULL) {
++ ERROR("%s: Invalid arguments", cgfile->name);
++ return -1;
++ }
++
++ nret = snprintf(file_path, sizeof(file_path), "%s/%s", path, cgfile->file);
++ if (nret < 0 || (size_t)nret >= sizeof(file_path)) {
++ ERROR("%s: failed to snprintf", cgfile->name);
++ return -1;
++ }
++
++ if (util_clean_path(file_path, real_path, sizeof(real_path)) == NULL) {
++ ERROR("%s: failed to clean path %s", cgfile->name, file_path);
++ return -1;
++ }
++
++ content = util_read_content_from_file(real_path);
++ if (content == NULL) {
++ ERROR("%s: failed to read file %s", cgfile->name, real_path);
++ return -1;
++ }
++
++ util_trim_newline(content);
++ content = util_trim_space(content);
++
++ nret = cgfile->get_value(content, cgfile->match, result);
++ if (nret != 0) {
++ ERROR("%s: failed to get value", cgfile->name);
++ }
++
++ free(content);
++ return nret;
++}
+\ No newline at end of file
+diff --git a/src/daemon/common/cgroup.h b/src/daemon/common/cgroup/cgroup_common.h
+similarity index 60%
+rename from src/daemon/common/cgroup.h
+rename to src/daemon/common/cgroup/cgroup_common.h
+index 251e3a3d..2a0935cb 100644
+--- a/src/daemon/common/cgroup.h
++++ b/src/daemon/common/cgroup/cgroup_common.h
+@@ -1,5 +1,5 @@
+ /******************************************************************************
+- * Copyright (c) Huawei Technologies Co., Ltd. 2017-2023. All rights reserved.
++ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ * iSulad licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+@@ -8,12 +8,12 @@
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+- * Author: zhangxiaoyu
+- * Create: 2023-03-29
+- * Description: provide cgroup definition
++ * Author: zhongtao
++ * Create: 2024-03-22
++ * Description: provide cgroup common func definition
+ ******************************************************************************/
+-#ifndef DAEMON_COMMON_CGROUP_H
+-#define DAEMON_COMMON_CGROUP_H
++#ifndef DAEMON_COMMON_CGROUP_COMMON_H
++#define DAEMON_COMMON_CGROUP_COMMON_H
+
+ #include <stdbool.h>
+ #include <stdint.h>
+@@ -40,10 +40,6 @@ struct cgfile_t {
+
+ int get_match_value_ull(const char *content, const char *match, void *result);
+
+-int common_get_cgroup_version(void);
+-
+-int common_find_cgroup_mnt_and_root(const char *subsystem, char **mountpoint, char **root);
+-
+ static inline void common_cgroup_do_log(bool quiet, bool do_log, const char *msg)
+ {
+ if (!quiet && do_log) {
+@@ -51,23 +47,7 @@ static inline void common_cgroup_do_log(bool quiet, bool do_log, const char *msg
+ }
+ }
+
+-typedef struct {
+- char **controllers;
+- char *mountpoint;
+-} cgroup_layers_item;
+-
+-typedef struct {
+- cgroup_layers_item **items;
+- size_t len;
+- size_t cap;
+-} cgroup_layer_t;
+-
+-char *common_find_cgroup_subsystem_mountpoint(const cgroup_layer_t *layers, const char *subsystem);
+-
+-cgroup_layer_t *common_cgroup_layers_find(void);
+-
+-void common_free_cgroup_layer(cgroup_layer_t *layers);
+-
++int get_cgroup_value_helper(const char *path, struct cgfile_t *cgfile, void *result);
+
+ typedef struct {
+ bool limit;
+@@ -113,17 +93,6 @@ typedef struct {
+ bool fileslimit;
+ } cgroup_files_info_t;
+
+-int common_get_cgroup_info_v1(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
+- cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
+- cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
+- cgroup_files_info_t *filesinfo, bool quiet);
+-
+-int common_get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
+- cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
+- cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
+- cgroup_files_info_t *filesinfo, bool quiet);
+-
+-
+ typedef struct {
+ uint64_t cpu_use_nanos;
+ } cgroup_cpu_metrics_t;
+@@ -147,15 +116,22 @@ typedef struct {
+ cgroup_pids_metrics_t cgpids_metrics;
+ } cgroup_metrics_t;
+
+-int common_get_cgroup_v1_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics);
+-int common_get_cgroup_v2_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics);
++typedef struct {
++ int (*get_cgroup_version)(void);
++ int (*get_cgroup_info)(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
++ cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
++ cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
++ cgroup_files_info_t *filesinfo, bool quiet);
++ int (*get_cgroup_metrics)(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics);
+
+-char *common_get_init_cgroup(const char *subsystem);
++ int (*get_cgroup_mnt_and_root_path)(const char *subsystem, char **mountpoint, char **root);
+
+-char *common_get_own_cgroup(const char *subsystem);
++ char *(*get_init_cgroup_path)(const char *subsystem);
++ char *(*get_own_cgroup_path)(const char *subsystem);
++} cgroup_ops;
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+-#endif // DAEMON_COMMON_CGROUP_H
++#endif // DAEMON_COMMON_CGROUP_COMMON_H
+diff --git a/src/daemon/common/cgroup_v1.c b/src/daemon/common/cgroup/cgroup_v1.c
+similarity index 52%
+rename from src/daemon/common/cgroup_v1.c
+rename to src/daemon/common/cgroup/cgroup_v1.c
+index e34100bc..51cf7512 100644
+--- a/src/daemon/common/cgroup_v1.c
++++ b/src/daemon/common/cgroup/cgroup_v1.c
+@@ -18,13 +18,31 @@
+ #include <stdlib.h>
+
+ #include "utils.h"
+-#include "path.h"
+ #include "sysinfo.h"
++#include "err_msg.h"
+
+ #define CGROUP_HUGETLB_LIMIT "hugetlb.%s.limit_in_bytes"
++#define CGROUP_MOUNT_PATH_PREFIX "/sys/fs/cgroup/"
+
+-static int get_value_ll(const char *content, const char *match, void *result);
+-static int get_value_string(const char *content, const char *match, void *result);
++
++static int get_value_ll(const char *content, const char *match, void *result)
++{
++ long long ll_result = 0;
++
++ if (util_safe_llong(content, &ll_result) != 0) {
++ ERROR("Failed to convert %s to long long", content);
++ return -1;
++ }
++
++ *(int64_t *)result = (int64_t)ll_result;
++ return 0;
++}
++
++static int get_value_string(const char *content, const char *match, void *result)
++{
++ *(char **)result = util_strdup_s(content);
++ return 0;
++}
+
+ typedef enum {
+ // CPU subsystem
+@@ -90,105 +108,579 @@ static struct cgfile_t g_cgroup_v1_files[] = {
+ [PIDS_CURRENT] = {"pids_current", "pids.current", NULL, get_match_value_ull},
+ };
+
+-static int get_value_ll(const char *content, const char *match, void *result)
++typedef struct {
++ char **controllers;
++ char *mountpoint;
++} cgroup_layers_item;
++
++typedef struct {
++ cgroup_layers_item **items;
++ size_t len;
++ size_t cap;
++} cgroup_layer_t;
++
++static char *common_find_cgroup_subsystem_mountpoint(const cgroup_layer_t *layers, const char *subsystem)
+ {
+- long long ll_result = 0;
++ size_t i;
+
+- if (util_safe_llong(content, &ll_result) != 0) {
+- ERROR("Failed to convert %s to long long", content);
++ for (i = 0; i < layers->len && layers->items[i]; i++) {
++ char **cit = NULL;
++
++ for (cit = layers->items[i]->controllers; cit && *cit; cit++) {
++ if (strcmp(*cit, subsystem) == 0) {
++ return layers->items[i]->mountpoint;
++ }
++ }
++ }
++ return NULL;
++}
++
++
++static cgroup_layer_t *new_cgroup_layer(size_t len)
++{
++ cgroup_layer_t *layers = NULL;
++
++ if (len == 0) {
++ return NULL;
++ }
++
++ layers = (cgroup_layer_t *)util_common_calloc_s(sizeof(cgroup_layer_t));
++ if (layers == NULL) {
++ ERROR("Out of memory");
++ return NULL;
++ }
++
++ layers->items = (cgroup_layers_item **)util_smart_calloc_s(sizeof(cgroup_layers_item *), len);
++ if (layers->items == NULL) {
++ ERROR("Out of memory");
++ free(layers);
++ return NULL;
++ }
++
++ layers->len = 0;
++ layers->cap = len;
++
++ return layers;
++}
++
++static int add_cgroup_layer(cgroup_layer_t *layers, char **clist, char *mountpoint)
++{
++#define CGROUP_LAYER_MAX_CAPABILITY 1024
++ size_t new_size;
++ cgroup_layers_item *newh = NULL;
++ cgroup_layers_item **tmp = NULL;
++
++ if (layers->len >= CGROUP_LAYER_MAX_CAPABILITY) {
++ ERROR("Too many cgroup layers");
+ return -1;
+ }
+
+- *(int64_t *)result = (int64_t)ll_result;
++ newh = util_common_calloc_s(sizeof(cgroup_layers_item));
++ if (newh == NULL) {
++ ERROR("Out of memory");
++ return -1;
++ }
++ newh->controllers = clist;
++ newh->mountpoint = mountpoint;
++
++ if (layers->len < layers->cap) {
++ goto out;
++ }
++
++ if (layers->cap > CGROUP_LAYER_MAX_CAPABILITY / 2) {
++ new_size = CGROUP_LAYER_MAX_CAPABILITY;
++ } else {
++ new_size = layers->cap * 2;
++ }
++
++ if (util_mem_realloc((void **)&tmp, new_size * sizeof(cgroup_layers_item *),
++ layers->items, layers->cap * sizeof(cgroup_layers_item *)) != 0) {
++ ERROR("Failed to realloc memory");
++ free(newh);
++ return -1;
++ }
++
++ layers->items = tmp;
++ tmp = NULL;
++ layers->cap = new_size;
++
++out:
++ layers->items[layers->len] = newh;
++ layers->len++;
+ return 0;
+ }
+
+-static int get_value_string(const char *content, const char *match, void *result)
++static void common_free_cgroup_layer(cgroup_layer_t *layers)
+ {
+- *(char **)result = util_strdup_s(content);
++ size_t i;
++
++ if (layers == NULL) {
++ return;
++ }
++
++ for (i = 0; i < layers->len && layers->items[i]; i++) {
++ free(layers->items[i]->mountpoint);
++ layers->items[i]->mountpoint = NULL;
++ util_free_array(layers->items[i]->controllers);
++ layers->items[i]->controllers = NULL;
++ free(layers->items[i]);
++ layers->items[i] = NULL;
++ }
++
++ free(layers->items);
++ layers->items = NULL;
++ layers->len = 0;
++ layers->cap = 0;
++
++ free(layers);
++}
++
++static int append_subsystem_to_list(char ***klist, char ***nlist, const char *ptoken)
++{
++ int ret = 0;
++
++ if (strncmp(ptoken, "name=", strlen("name=")) == 0) {
++ ret = util_array_append(nlist, ptoken);
++ if (ret != 0) {
++ ERROR("Failed to append string");
++ return -1;
++ }
++ } else {
++ ret = util_array_append(klist, ptoken);
++ if (ret != 0) {
++ ERROR("Failed to append string");
++ return -1;
++ }
++ }
++
+ return 0;
+ }
+
+-static bool check_cgroup_v1_helper(const char *mountpoint, const cgroup_v1_files_index index, const bool quiet)
++static int get_cgroup_subsystems(char ***klist, char ***nlist)
+ {
+- int nret = 0;
+- char path[PATH_MAX] = { 0 };
++ int ret = 0;
++ size_t length = 0;
++ FILE *fp = NULL;
++ char *pline = NULL;
+
+- if (index >= CGROUP_V1_FILES_INDEX_MAXS) {
+- ERROR("Index out of range");
+- return false;
++ fp = util_fopen("/proc/self/cgroup", "r");
++ if (fp == NULL) {
++ return -1;
+ }
+
+- if (mountpoint == NULL) {
+- ERROR("%s: invalid arguments", g_cgroup_v1_files[index].name);
+- return false;
++ while (getline(&pline, &length, fp) != -1) {
++ char *pos = NULL;
++ char *pos2 = NULL;
++ char *ptoken = NULL;
++ char *psave = NULL;
++ pos = strchr(pline, ':');
++ if (pos == NULL) {
++ ERROR("Invalid cgroup entry: must contain at least two colons: %s", pline);
++ ret = -1;
++ goto out;
++ }
++ pos++;
++ pos2 = strchr(pos, ':');
++ if (pos2 == NULL) {
++ ERROR("Invalid cgroup entry: must contain at least two colons: %s", pline);
++ ret = -1;
++ goto out;
++ }
++ *pos2 = '\0';
++
++ if ((pos2 - pos) == 0) {
++ INFO("Not supported cgroup entry: %s", pline);
++ continue;
++ }
++
++ for (ptoken = strtok_r(pos, ",", &psave); ptoken; ptoken = strtok_r(NULL, ",", &psave)) {
++ if (append_subsystem_to_list(klist, nlist, ptoken)) {
++ goto out;
++ }
++ }
+ }
+
+- nret = snprintf(path, sizeof(path), "%s/%s", mountpoint, g_cgroup_v1_files[index].file);
+- if (nret < 0 || (size_t)nret >= sizeof(path)) {
+- ERROR("%s: failed to snprintf", g_cgroup_v1_files[index].name);
+- return false;
++out:
++ free(pline);
++ fclose(fp);
++ if (ret != 0) {
++ util_free_array(*klist);
++ *klist = NULL;
++ util_free_array(*nlist);
++ *nlist = NULL;
+ }
++ return ret;
++}
+
+- if (util_file_exists(path)) {
+- return true;
++static int append_controller(const char **klist, const char **nlist, char ***clist, const char *entry)
++{
++ int ret = 0;
++ char *dup_entry = NULL;
++
++ if (util_array_contain(klist, entry) && util_array_contain(nlist, entry)) {
++ ERROR("Refusing to use ambiguous controller \"%s\"", entry);
++ ERROR("It is both a named and kernel subsystem");
++ return -1;
+ }
+
+- if (!quiet) {
+- WARN("Your kernel does not support cgroup %s", g_cgroup_v1_files[index].name);
++ if (strncmp(entry, "name=", 5) == 0) {
++ dup_entry = util_strdup_s(entry);
++ } else if (util_array_contain(klist, entry)) {
++ dup_entry = util_strdup_s(entry);
++ } else {
++ dup_entry = util_string_append(entry, "name=");
++ }
++ if (dup_entry == NULL) {
++ ERROR("Out of memory");
++ return -1;
++ }
++
++ ret = util_array_append(clist, dup_entry);
++ if (ret != 0) {
++ ERROR("Failed to append array");
++ }
++
++ free(dup_entry);
++ return ret;
++}
++
++static inline bool is_cgroup_mountpoint(const char *mp)
++{
++ return strncmp(mp, CGROUP_MOUNT_PATH_PREFIX, strlen(CGROUP_MOUNT_PATH_PREFIX)) == 0;
++}
++
++static char **cgroup_get_controllers(const char **klist, const char **nlist, const char *line)
++{
++ int index;
++ char *dup = NULL;
++ char *pos2 = NULL;
++ char *tok = NULL;
++ const char *pos = line;
++ char *psave = NULL;
++ char *sep = ",";
++ char **pret = NULL;
++
++ // line example
++ // 108 99 0:55 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
++ for (index = 0; index < 4; index++) {
++ pos = strchr(pos, ' ');
++ if (pos == NULL) {
++ ERROR("Invalid mountinfo format \"%s\"", line);
++ return NULL;
++ }
++ pos++;
++ }
++
++ if (!is_cgroup_mountpoint(pos)) {
++ return NULL;
++ }
++
++ pos += strlen(CGROUP_MOUNT_PATH_PREFIX);
++ pos2 = strchr(pos, ' ');
++ if (pos2 == NULL) {
++ ERROR("Invalid mountinfo format \"%s\"", line);
++ return NULL;
++ }
++
++ *pos2 = '\0';
++ dup = util_strdup_s(pos);
++ *pos2 = ' ';
++
++ for (tok = strtok_r(dup, sep, &psave); tok; tok = strtok_r(NULL, sep, &psave)) {
++ if (append_controller(klist, nlist, &pret, tok)) {
++ ERROR("Failed to append controller");
++ util_free_array(pret);
++ pret = NULL;
++ break;
++ }
++ }
++
++ free(dup);
++
++ return pret;
++}
++
++static bool lists_intersect(const char **controllers, const char **list)
++{
++ int index;
++
++ if (controllers == NULL || list == NULL) {
++ return false;
++ }
++
++ for (index = 0; controllers[index]; index++) {
++ if (util_array_contain(list, controllers[index])) {
++ return true;
++ }
+ }
+
+ return false;
+ }
+
+-static int get_cgroup_v1_value_helper(const char *path, const cgroup_v1_files_index index,
+- void *result)
++static bool controller_list_is_dup(const cgroup_layer_t *llist, const char **clist)
+ {
+- int nret = 0;
+- char file_path[PATH_MAX] = { 0 };
+- char real_path[PATH_MAX] = { 0 };
+- char *content = NULL;
++ size_t index;
+
+- if (index >= CGROUP_V1_FILES_INDEX_MAXS) {
+- ERROR("Index out of range");
++ if (llist == NULL) {
+ return false;
+ }
+
+- if (path == NULL || strlen(path) == 0 || result == NULL) {
+- ERROR("%s: Invalid arguments", g_cgroup_v1_files[index].name);
++ for (index = 0; index < llist->len && llist->items[index]; index++) {
++ if (lists_intersect((const char **)llist->items[index]->controllers, (const char **)clist)) {
++ return true;
++ }
++ }
++
++ return false;
++}
++
++static int cgroup_get_mountpoint_and_root(char *pline, char **mountpoint, char **root)
++{
++ int index;
++ char *posmp = NULL;
++ char *posrt = NULL;
++ char *pos = pline;
++
++ // find root
++ // line example
++ // 108 99 0:55 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
++ for (index = 0; index < 3; index++) {
++ pos = strchr(pos, ' ');
++ if (pos == NULL) {
++ return -1;
++ }
++ pos++;
++ }
++ posrt = pos;
++
++ // find mountpoint
++ pos = strchr(pos, ' ');
++ if (pos == NULL) {
+ return -1;
+ }
+
+- nret = snprintf(file_path, sizeof(file_path), "%s/%s", path, g_cgroup_v1_files[index].file);
+- if (nret < 0 || (size_t)nret >= sizeof(file_path)) {
+- ERROR("%s: failed to snprintf", g_cgroup_v1_files[index].name);
++ *pos = '\0';
++ if (root != NULL) {
++ *root = util_strdup_s(posrt);
++ }
++
++ pos++;
++ posmp = pos;
++
++ if (!is_cgroup_mountpoint(posmp)) {
+ return -1;
+ }
+
+- if (util_clean_path(file_path, real_path, sizeof(real_path)) == NULL) {
+- ERROR("%s: failed to clean path %s", g_cgroup_v1_files[index].name, file_path);
++ pos = strchr(pos + strlen(CGROUP_MOUNT_PATH_PREFIX), ' ');
++ if (pos == NULL) {
+ return -1;
+ }
++ *pos = '\0';
++
++ if (mountpoint != NULL) {
++ *mountpoint = util_strdup_s(posmp);
++ }
++
++ return 0;
++}
++
++/* find cgroup mountpoint and root */
++static int get_cgroup_mnt_and_root_path_v1(const char *subsystem, char **mountpoint, char **root)
++{
++ int ret = 0;
++ FILE *fp = NULL;
++ size_t length = 0;
++ char *pline = NULL;
+
+- content = util_read_content_from_file(real_path);
+- if (content == NULL) {
+- ERROR("%s: failed to read file %s", g_cgroup_v1_files[index].name, real_path);
++ if (subsystem == NULL) {
++ ERROR("Empty subsystem");
+ return -1;
+ }
+
+- util_trim_newline(content);
+- content = util_trim_space(content);
++ fp = util_fopen("/proc/self/mountinfo", "r");
++ if (fp == NULL) {
++ ERROR("Failed to open \"/proc/self/mountinfo\"\n");
++ ret = -1;
++ goto free_out;
++ }
++
++ while (getline(&pline, &length, fp) != -1) {
++ char *dup = NULL;
++ char *p = NULL;
++ char *tok = NULL;
++ char *mp = NULL;
++ char *rt = NULL;
++ char *saveptr = NULL;
++ char *sep = ",";
++ int mret;
++
++ mret = cgroup_get_mountpoint_and_root(pline, &mp, &rt);
++ if (mret != 0 || mp == NULL || rt == NULL) {
++ goto mp_out;
++ }
++
++ p = mp;
++ p += strlen(CGROUP_MOUNT_PATH_PREFIX);
++ dup = util_strdup_s(p);
++ if (dup == NULL) {
++ ERROR("Out of memory");
++ free(mp);
++ ret = -1;
++ goto free_out;
++ }
++
++ for (tok = strtok_r(dup, sep, &saveptr); tok; tok = strtok_r(NULL, sep, &saveptr)) {
++ if (strcmp(tok, subsystem) != 0) {
++ continue;
++ }
++ if (mountpoint != NULL) {
++ *mountpoint = mp;
++ } else {
++ free(mp);
++ }
++ if (root != NULL) {
++ *root = rt;
++ } else {
++ free(rt);
++ }
++ free(dup);
++ goto free_out;
++ }
++ free(dup);
++mp_out:
++ free(mp);
++ free(rt);
++ continue;
++ }
++free_out:
++ if (fp != NULL) {
++ fclose(fp);
++ }
++ free(pline);
++ return ret;
++}
++
++static cgroup_layer_t *common_cgroup_layers_find(void)
++{
++ int nret;
++ int ret = 0;
++ FILE *fp = NULL;
++ size_t length = 0;
++ const size_t cgroup_layer_item_num = 10;
++ char *pline = NULL;
++ char **klist = NULL;
++ char **nlist = NULL;
++ cgroup_layer_t *layers = NULL;
++
++ layers = new_cgroup_layer(cgroup_layer_item_num);
++ if (layers == NULL) {
++ ERROR("Failed to new cgroup layer");
++ return NULL;
++ }
++
++ ret = get_cgroup_subsystems(&klist, &nlist);
++ if (ret != 0) {
++ ERROR("Failed to retrieve available legacy cgroup controllers\n");
++ goto out;
++ }
++
++ fp = util_fopen("/proc/self/mountinfo", "r");
++ if (fp == NULL) {
++ ERROR("Failed to open \"/proc/self/mountinfo\"\n");
++ ret = -1;
++ goto out;
++ }
++
++ while (getline(&pline, &length, fp) != -1) {
++ char *mountpoint = NULL;
++ char **clist = NULL;
++ int mret;
++
++ clist = cgroup_get_controllers((const char **)klist, (const char **)nlist, pline);
++ if (clist == NULL) {
++ goto list_out;
++ }
++
++ if (controller_list_is_dup(layers, (const char **)clist)) {
++ goto list_out;
++ }
++
++ mret = cgroup_get_mountpoint_and_root(pline, &mountpoint, NULL);
++ if (mret != 0 || mountpoint == NULL) {
++ ERROR("Failed parsing mountpoint from \"%s\"\n", pline);
++ goto list_out;
++ }
++
++ nret = add_cgroup_layer(layers, clist, mountpoint);
++ if (nret != 0) {
++ ERROR("Failed to add hierarchies");
++ goto list_out;
++ }
++
++ continue;
++list_out:
++ util_free_array(clist);
++ free(mountpoint);
++ }
++out:
++ util_free_array(klist);
++ util_free_array(nlist);
++ if (fp != NULL) {
++ fclose(fp);
++ }
++ free(pline);
++
++ if (ret != 0) {
++ common_free_cgroup_layer(layers);
++ return NULL;
++ }
++
++ return layers;
++}
++
++static int get_cgroup_v1_value_helper(const char *path, const cgroup_v1_files_index index, void *result)
++{
++ if (index >= CGROUP_V1_FILES_INDEX_MAXS) {
++ ERROR("Index out of range");
++ return false;
++ }
++
++ return get_cgroup_value_helper(path, &g_cgroup_v1_files[index], result);
++}
++
++static bool check_cgroup_v1_file_exists(const char *mountpoint, const cgroup_v1_files_index index, const bool quiet)
++{
++ int nret = 0;
++ char path[PATH_MAX] = { 0 };
++
++ if (index >= CGROUP_V1_FILES_INDEX_MAXS) {
++ ERROR("Index out of range");
++ return false;
++ }
++
++ if (mountpoint == NULL) {
++ ERROR("%s: invalid arguments", g_cgroup_v1_files[index].name);
++ return false;
++ }
++
++ nret = snprintf(path, sizeof(path), "%s/%s", mountpoint, g_cgroup_v1_files[index].file);
++ if (nret < 0 || (size_t)nret >= sizeof(path)) {
++ ERROR("%s: failed to snprintf", g_cgroup_v1_files[index].name);
++ return false;
++ }
+
+- nret = g_cgroup_v1_files[index].get_value(content, g_cgroup_v1_files[index].match, result);
+- if (nret != 0) {
+- ERROR("%s: failed to get value", g_cgroup_v1_files[index].name);
++ if (util_file_exists(path)) {
++ return true;
+ }
+
+- free(content);
+- return nret;
++ if (!quiet) {
++ WARN("Your kernel does not support cgroup %s", g_cgroup_v1_files[index].name);
++ }
++
++ return false;
+ }
+
+-static void check_cgroup_v1_cpu(const cgroup_layer_t *layers, const bool quiet, cgroup_cpu_info_t *cpuinfo)
++static void get_cgroup_v1_cpu_info(const cgroup_layer_t *layers, const bool quiet, cgroup_cpu_info_t *cpuinfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -198,14 +690,14 @@ static void check_cgroup_v1_cpu(const cgroup_layer_t *layers, const bool quiet,
+ return;
+ }
+
+- cpuinfo->cpu_rt_period = check_cgroup_v1_helper(mountpoint, CPU_RT_PERIOD, quiet);
+- cpuinfo->cpu_rt_runtime = check_cgroup_v1_helper(mountpoint, CPU_RT_RUNTIME, quiet);
+- cpuinfo->cpu_shares = check_cgroup_v1_helper(mountpoint, CPU_SHARES, quiet);
+- cpuinfo->cpu_cfs_period = check_cgroup_v1_helper(mountpoint, CPU_CFS_PERIOD, quiet);
+- cpuinfo->cpu_cfs_quota = check_cgroup_v1_helper(mountpoint, CPU_CFS_QUOTA, quiet);
++ cpuinfo->cpu_rt_period = check_cgroup_v1_file_exists(mountpoint, CPU_RT_PERIOD, quiet);
++ cpuinfo->cpu_rt_runtime = check_cgroup_v1_file_exists(mountpoint, CPU_RT_RUNTIME, quiet);
++ cpuinfo->cpu_shares = check_cgroup_v1_file_exists(mountpoint, CPU_SHARES, quiet);
++ cpuinfo->cpu_cfs_period = check_cgroup_v1_file_exists(mountpoint, CPU_CFS_PERIOD, quiet);
++ cpuinfo->cpu_cfs_quota = check_cgroup_v1_file_exists(mountpoint, CPU_CFS_QUOTA, quiet);
+ }
+
+-static void check_cgroup_v1_cpuset(const cgroup_layer_t *layers, const bool quiet, cgroup_cpuset_info_t *cpusetinfo)
++static void get_cgroup_v1_cpuset_info(const cgroup_layer_t *layers, const bool quiet, cgroup_cpuset_info_t *cpusetinfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -215,10 +707,10 @@ static void check_cgroup_v1_cpuset(const cgroup_layer_t *layers, const bool quie
+ return;
+ }
+
+- if (!check_cgroup_v1_helper(mountpoint, CPUSET_CPUS, quiet)) {
++ if (!check_cgroup_v1_file_exists(mountpoint, CPUSET_CPUS, quiet)) {
+ return;
+ }
+- if (!check_cgroup_v1_helper(mountpoint, CPUSET_MEMS, quiet)) {
++ if (!check_cgroup_v1_file_exists(mountpoint, CPUSET_MEMS, quiet)) {
+ return;
+ }
+
+@@ -238,7 +730,7 @@ static void check_cgroup_v1_cpuset(const cgroup_layer_t *layers, const bool quie
+ cpusetinfo->cpuset = true;
+ }
+
+-static void check_cgroup_v1_mem(const cgroup_layer_t *layers, const bool quiet, cgroup_mem_info_t *meminfo)
++static void get_cgroup_v1_mem_info(const cgroup_layer_t *layers, const bool quiet, cgroup_mem_info_t *meminfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -248,15 +740,15 @@ static void check_cgroup_v1_mem(const cgroup_layer_t *layers, const bool quiet,
+ return;
+ }
+
+- meminfo->limit = check_cgroup_v1_helper(mountpoint, MEMORY_LIMIT, quiet);
+- meminfo->swap = check_cgroup_v1_helper(mountpoint, MEMORY_SW_LIMIT, quiet);
+- meminfo->reservation = check_cgroup_v1_helper(mountpoint, MEMORY_SOFT_LIMIT, quiet);
+- meminfo->oomkilldisable = check_cgroup_v1_helper(mountpoint, MEMORY_OOM_CONTROL, quiet);
+- meminfo->swappiness = check_cgroup_v1_helper(mountpoint, MEMORY_SWAPPINESS, quiet);
+- meminfo->kernel = check_cgroup_v1_helper(mountpoint, MEMORY_KMEM_LIMIT, quiet);
++ meminfo->limit = check_cgroup_v1_file_exists(mountpoint, MEMORY_LIMIT, quiet);
++ meminfo->swap = check_cgroup_v1_file_exists(mountpoint, MEMORY_SW_LIMIT, quiet);
++ meminfo->reservation = check_cgroup_v1_file_exists(mountpoint, MEMORY_SOFT_LIMIT, quiet);
++ meminfo->oomkilldisable = check_cgroup_v1_file_exists(mountpoint, MEMORY_OOM_CONTROL, quiet);
++ meminfo->swappiness = check_cgroup_v1_file_exists(mountpoint, MEMORY_SWAPPINESS, quiet);
++ meminfo->kernel = check_cgroup_v1_file_exists(mountpoint, MEMORY_KMEM_LIMIT, quiet);
+ }
+
+-static void check_cgroup_v1_blkio(const cgroup_layer_t *layers, const bool quiet, cgroup_blkio_info_t *blkioinfo)
++static void get_cgroup_v1_blkio_info(const cgroup_layer_t *layers, const bool quiet, cgroup_blkio_info_t *blkioinfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -266,15 +758,15 @@ static void check_cgroup_v1_blkio(const cgroup_layer_t *layers, const bool quiet
+ return;
+ }
+
+- blkioinfo->blkio_weight = check_cgroup_v1_helper(mountpoint, BLKIO_WEIGTH, quiet);
+- blkioinfo->blkio_weight_device = check_cgroup_v1_helper(mountpoint, BLKIO_WEIGTH_DEVICE, quiet);
+- blkioinfo->blkio_read_bps_device = check_cgroup_v1_helper(mountpoint, BLKIO_READ_BPS, quiet);
+- blkioinfo->blkio_write_bps_device = check_cgroup_v1_helper(mountpoint, BLKIO_WRITE_BPS, quiet);
+- blkioinfo->blkio_read_iops_device = check_cgroup_v1_helper(mountpoint, BLKIO_READ_IOPS, quiet);
+- blkioinfo->blkio_write_iops_device = check_cgroup_v1_helper(mountpoint, BLKIO_WRITE_IOPS, quiet);
++ blkioinfo->blkio_weight = check_cgroup_v1_file_exists(mountpoint, BLKIO_WEIGTH, quiet);
++ blkioinfo->blkio_weight_device = check_cgroup_v1_file_exists(mountpoint, BLKIO_WEIGTH_DEVICE, quiet);
++ blkioinfo->blkio_read_bps_device = check_cgroup_v1_file_exists(mountpoint, BLKIO_READ_BPS, quiet);
++ blkioinfo->blkio_write_bps_device = check_cgroup_v1_file_exists(mountpoint, BLKIO_WRITE_BPS, quiet);
++ blkioinfo->blkio_read_iops_device = check_cgroup_v1_file_exists(mountpoint, BLKIO_READ_IOPS, quiet);
++ blkioinfo->blkio_write_iops_device = check_cgroup_v1_file_exists(mountpoint, BLKIO_WRITE_IOPS, quiet);
+ }
+
+-static void check_cgroup_v1_hugetlb(const cgroup_layer_t *layers, const bool quiet, cgroup_hugetlb_info_t *hugetlbinfo)
++static void get_cgroup_v1_hugetlb_info(const cgroup_layer_t *layers, const bool quiet, cgroup_hugetlb_info_t *hugetlbinfo)
+ {
+ int nret;
+ char *mountpoint = NULL;
+@@ -306,7 +798,7 @@ free_out:
+ free(defaultpagesize);
+ }
+
+-static void check_cgroup_v1_pids(const cgroup_layer_t *layers, const bool quiet, cgroup_pids_info_t *pidsinfo)
++static void get_cgroup_v1_pids_info(const cgroup_layer_t *layers, const bool quiet, cgroup_pids_info_t *pidsinfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -319,7 +811,7 @@ static void check_cgroup_v1_pids(const cgroup_layer_t *layers, const bool quiet,
+ pidsinfo->pidslimit = true;
+ }
+
+-static void check_cgroup_v1_files(const cgroup_layer_t *layers, const bool quiet, cgroup_files_info_t *filesinfo)
++static void get_cgroup_v1_files_info(const cgroup_layer_t *layers, const bool quiet, cgroup_files_info_t *filesinfo)
+ {
+ char *mountpoint = NULL;
+
+@@ -332,7 +824,7 @@ static void check_cgroup_v1_files(const cgroup_layer_t *layers, const bool quiet
+ filesinfo->fileslimit = true;
+ }
+
+-int common_get_cgroup_info_v1(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
++static int get_cgroup_info_v1(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
+ cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
+ cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
+ cgroup_files_info_t *filesinfo, bool quiet)
+@@ -345,13 +837,13 @@ int common_get_cgroup_info_v1(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpu
+ return -1;
+ }
+
+- check_cgroup_v1_cpu(layers, quiet, cpuinfo);
+- check_cgroup_v1_cpuset(layers, quiet, cpusetinfo);
+- check_cgroup_v1_mem(layers, quiet, meminfo);
+- check_cgroup_v1_blkio(layers, quiet, blkioinfo);
+- check_cgroup_v1_hugetlb(layers, quiet, hugetlbinfo);
+- check_cgroup_v1_pids(layers, quiet, pidsinfo);
+- check_cgroup_v1_files(layers, quiet, filesinfo);
++ get_cgroup_v1_cpu_info(layers, quiet, cpuinfo);
++ get_cgroup_v1_cpuset_info(layers, quiet, cpusetinfo);
++ get_cgroup_v1_mem_info(layers, quiet, meminfo);
++ get_cgroup_v1_blkio_info(layers, quiet, blkioinfo);
++ get_cgroup_v1_hugetlb_info(layers, quiet, hugetlbinfo);
++ get_cgroup_v1_pids_info(layers, quiet, pidsinfo);
++ get_cgroup_v1_files_info(layers, quiet, filesinfo);
+
+ common_free_cgroup_layer(layers);
+
+@@ -432,7 +924,7 @@ static void get_cgroup_v1_metrics_pid(const cgroup_layer_t *layers, const char *
+ get_cgroup_v1_value_helper(path, PIDS_CURRENT, (void *)&cgroup_pids_metrics->pid_current);
+ }
+
+-int common_get_cgroup_v1_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics)
++static int get_cgroup_metrics_v1(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics)
+ {
+ cgroup_layer_t *layers = NULL;
+
+@@ -553,22 +1045,31 @@ static char *common_get_cgroup_path(const char *path, const char *subsystem)
+ return res;
+ }
+
+-char *common_get_init_cgroup(const char *subsystem)
++char *get_init_cgroup_path_v1(const char *subsystem)
+ {
+- if (common_get_cgroup_version() != CGROUP_VERSION_1) {
+- ERROR("Not implemented for cgroup v2 hierarchy");
+- return NULL;
+- }
+-
+ return common_get_cgroup_path("/proc/1/cgroup", subsystem);
+ }
+
+-char *common_get_own_cgroup(const char *subsystem)
++char *get_own_cgroup_v1(const char *subsystem)
+ {
+- if (common_get_cgroup_version() != CGROUP_VERSION_1) {
+- ERROR("Not implemented for cgroup v2 hierarchy");
+- return NULL;
+- }
+-
+ return common_get_cgroup_path("/proc/self/cgroup", subsystem);
+ }
++
++int get_cgroup_version_v1()
++{
++ return CGROUP_VERSION_1;
++}
++
++int cgroup_v1_ops_init(cgroup_ops *ops)
++{
++ if (ops == NULL) {
++ return -1;
++ }
++ ops->get_cgroup_version = get_cgroup_version_v1;
++ ops->get_cgroup_info = get_cgroup_info_v1;
++ ops->get_cgroup_metrics = get_cgroup_metrics_v1;
++ ops->get_cgroup_mnt_and_root_path = get_cgroup_mnt_and_root_path_v1;
++ ops->get_init_cgroup_path = get_init_cgroup_path_v1;
++ ops->get_own_cgroup_path = get_own_cgroup_v1;
++ return 0;
++}
+\ No newline at end of file
+diff --git a/src/daemon/common/cgroup/cgroup_v1.h b/src/daemon/common/cgroup/cgroup_v1.h
+new file mode 100644
+index 00000000..c2696725
+--- /dev/null
++++ b/src/daemon/common/cgroup/cgroup_v1.h
+@@ -0,0 +1,30 @@
++/******************************************************************************
++ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
++ * iSulad licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ * Author: zhongtao
++ * Create: 2024-02-19
++ * Description: provide cgroup v1 definition
++ ******************************************************************************/
++#ifndef DAEMON_COMMON_CGROUP_CGROUP_V1_H
++#define DAEMON_COMMON_CGROUP_CGROUP_V1_H
++
++#include "cgroup.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++int cgroup_v1_ops_init(cgroup_ops *ops);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif // DAEMON_COMMON_CGROUP_CGROUP_V1_H
+diff --git a/src/daemon/common/cgroup_v2.c b/src/daemon/common/cgroup/cgroup_v2.c
+similarity index 88%
+rename from src/daemon/common/cgroup_v2.c
+rename to src/daemon/common/cgroup/cgroup_v2.c
+index 25509bda..65cf90d8 100644
+--- a/src/daemon/common/cgroup_v2.c
++++ b/src/daemon/common/cgroup/cgroup_v2.c
+@@ -105,48 +105,12 @@ static struct cgfile_t g_cgroup_v2_files[] = {
+
+ static int get_cgroup_v2_value_helper(const char *path, const cgroup_v2_files_index index, void *result)
+ {
+- int nret = 0;
+- char file_path[PATH_MAX] = { 0 };
+- char real_path[PATH_MAX] = { 0 };
+- char *content = NULL;
+-
+ if (index >= CGROUP_V2_FILES_INDEX_MAXS) {
+ ERROR("Index out of range");
+ return false;
+ }
+
+- if (path == NULL || strlen(path) == 0 || result == NULL) {
+- ERROR("%s: Invalid arguments", g_cgroup_v2_files[index].name);
+- return -1;
+- }
+-
+- nret = snprintf(file_path, sizeof(file_path), "%s/%s", path, g_cgroup_v2_files[index].file);
+- if (nret < 0 || (size_t)nret >= sizeof(file_path)) {
+- ERROR("%s: failed to snprintf", g_cgroup_v2_files[index].name);
+- return -1;
+- }
+-
+- if (util_clean_path(file_path, real_path, sizeof(real_path)) == NULL) {
+- ERROR("%s: failed to clean path %s", g_cgroup_v2_files[index].name, file_path);
+- return -1;
+- }
+-
+- content = util_read_content_from_file(real_path);
+- if (content == NULL) {
+- ERROR("%s: failed to read file %s", g_cgroup_v2_files[index].name, real_path);
+- return -1;
+- }
+-
+- util_trim_newline(content);
+- content = util_trim_space(content);
+-
+- nret = g_cgroup_v2_files[index].get_value(content, g_cgroup_v2_files[index].match, result);
+- if (nret != 0) {
+- ERROR("%s: failed to get value", g_cgroup_v2_files[index].name);
+- }
+-
+- free(content);
+- return nret;
++ return get_cgroup_value_helper(path, &g_cgroup_v2_files[index], result);
+ }
+
+ static void get_cgroup_v2_metrics_cpu(const char *cgroup_path, cgroup_cpu_metrics_t *cgroup_cpu_metrics)
+@@ -306,28 +270,18 @@ static bool cgroup_v2_enabled(const char *mountpoint, const char *name)
+ return util_file_exists(path);
+ }
+
+-int common_get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
+- cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
+- cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
+- cgroup_files_info_t *filesinfo, bool quiet)
++static void get_cgroup_v2_cpu_info(const bool quiet, cgroup_cpu_info_t *cpuinfo)
+ {
+- int ret = 0;
+- int nret = 0;
+- __isula_auto_free char *size = NULL;
+- char path[PATH_MAX] = { 0 };
+-
+- if (make_sure_cgroup2_isulad_path_exist() != 0) {
+- return -1;
+- }
+-
+- // cpu cgroup
+ cpuinfo->cpu_shares = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPU_WEIGHT);
+ common_cgroup_do_log(quiet, !(cpuinfo->cpu_shares), "Your kernel does not support cgroup2 cpu weight");
+
+ cpuinfo->cpu_cfs_period = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPU_MAX);
+ cpuinfo->cpu_cfs_quota = cpuinfo->cpu_cfs_period;
+ common_cgroup_do_log(quiet, !(cpuinfo->cpu_cfs_period), "Your kernel does not support cgroup2 cpu max");
++}
+
++static int get_cgroup_v2_cpuset_info(const bool quiet, cgroup_cpuset_info_t *cpusetinfo)
++{
+ cpusetinfo->cpuset = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_CPUS_EFFECTIVE) &&
+ cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_CPUS) &&
+ cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_MEMS_EFFECTIVE) &&
+@@ -343,8 +297,23 @@ int common_get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpu
+ cpusetinfo->cpus = util_trim_space(cpusetinfo->cpus);
+ cpusetinfo->mems = util_trim_space(cpusetinfo->mems);
+ }
++ return 0;
++}
++
++static void get_cgroup_v2_mem_info(const bool quiet, cgroup_mem_info_t *meminfo)
++{
++ meminfo->limit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_MAX);
++ common_cgroup_do_log(quiet, !(meminfo->limit), "Your kernel does not support cgroup2 memory max");
++
++ meminfo->reservation = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_LOW);
++ common_cgroup_do_log(quiet, !(meminfo->reservation), "Your kernel does not support cgroup2 memory low");
+
+- // io cgroup
++ meminfo->swap = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_SWAP_MAX);
++ common_cgroup_do_log(quiet, !(meminfo->swap), "Your kernel does not support cgroup2 memory swap max");
++}
++
++static void get_cgroup_v2_blkio_info(const bool quiet, cgroup_blkio_info_t *blkioinfo)
++{
+ blkioinfo->blkio_weight = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_BFQ_WEIGHT) ||
+ cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_WEIGHT);
+ blkioinfo->blkio_weight_device = blkioinfo->blkio_weight;
+@@ -355,22 +324,14 @@ int common_get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpu
+ blkioinfo->blkio_read_iops_device = blkioinfo->blkio_read_bps_device;
+ blkioinfo->blkio_write_iops_device = blkioinfo->blkio_read_bps_device;
+ common_cgroup_do_log(quiet, !(blkioinfo->blkio_read_bps_device), "Your kernel does not support cgroup2 io max");
++}
+
+- // memory cgroup
+- meminfo->limit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_MAX);
+- common_cgroup_do_log(quiet, !(meminfo->limit), "Your kernel does not support cgroup2 memory max");
+-
+- meminfo->reservation = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_LOW);
+- common_cgroup_do_log(quiet, !(meminfo->reservation), "Your kernel does not support cgroup2 memory low");
+-
+- meminfo->swap = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_MEMORY_SWAP_MAX);
+- common_cgroup_do_log(quiet, !(meminfo->swap), "Your kernel does not support cgroup2 memory swap max");
+-
+- // pids cgroup
+- pidsinfo->pidslimit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_PIDS_MAX);
+- common_cgroup_do_log(quiet, !(pidsinfo->pidslimit), "Your kernel does not support cgroup2 pids max");
++static int get_cgroup_v2_hugetlb_info(const bool quiet, cgroup_hugetlb_info_t *hugetlbinfo)
++{
++ __isula_auto_free char *size = NULL;
++ int nret = 0;
++ char path[PATH_MAX] = { 0 };
+
+- // hugetlb cgroup
+ size = get_default_huge_page_size();
+ if (size != NULL) {
+ nret = snprintf(path, sizeof(path), CGROUP2_HUGETLB_MAX, size);
+@@ -383,15 +344,55 @@ int common_get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpu
+ } else {
+ WARN("Your kernel does not support cgroup2 hugetlb limit");
+ }
++ return 0;
++}
++
++static void get_cgroup_v2_pids_info(const bool quiet, cgroup_pids_info_t *pidsinfo)
++{
++ pidsinfo->pidslimit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_PIDS_MAX);
++ common_cgroup_do_log(quiet, !(pidsinfo->pidslimit), "Your kernel does not support cgroup2 pids max");
++
++}
+
+- // files cgroup
++static void get_cgroup_v2_files_info(const bool quiet, cgroup_files_info_t *filesinfo)
++{
+ filesinfo->fileslimit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_FILES_LIMIT);
+ common_cgroup_do_log(quiet, !(filesinfo->fileslimit), "Your kernel does not support cgroup2 files limit");
+
+- return ret;
+ }
+
+-int common_get_cgroup_v2_metrics(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics)
++static int get_cgroup_info_v2(cgroup_mem_info_t *meminfo, cgroup_cpu_info_t *cpuinfo,
++ cgroup_hugetlb_info_t *hugetlbinfo, cgroup_blkio_info_t *blkioinfo,
++ cgroup_cpuset_info_t *cpusetinfo, cgroup_pids_info_t *pidsinfo,
++ cgroup_files_info_t *filesinfo, bool quiet)
++{
++ int ret = 0;
++ if (make_sure_cgroup2_isulad_path_exist() != 0) {
++ return -1;
++ }
++
++ get_cgroup_v2_cpu_info(quiet, cpuinfo);
++
++ ret = get_cgroup_v2_cpuset_info(quiet, cpusetinfo);
++ if (ret != 0) {
++ return ret;
++ }
++
++ get_cgroup_v2_mem_info(quiet, meminfo);
++ get_cgroup_v2_blkio_info(quiet, blkioinfo);
++
++ ret = get_cgroup_v2_hugetlb_info(quiet, hugetlbinfo);
++ if (ret != 0) {
++ return ret;
++ }
++
++ get_cgroup_v2_pids_info(quiet, pidsinfo);
++ get_cgroup_v2_files_info(quiet, filesinfo);
++
++ return 0;
++}
++
++static int get_cgroup_metrics_v2(const char *cgroup_path, cgroup_metrics_t *cgroup_metrics)
+ {
+ if (cgroup_path == NULL || strlen(cgroup_path) == 0 || cgroup_metrics == NULL) {
+ ERROR("Invalid arguments");
+@@ -404,3 +405,26 @@ int common_get_cgroup_v2_metrics(const char *cgroup_path, cgroup_metrics_t *cgro
+
+ return 0;
+ }
++
++static int get_cgroup_mnt_and_root_v2(const char *subsystem, char **mountpoint, char **root)
++{
++ *mountpoint = util_strdup_s(CGROUP_ISULAD_PATH);
++ return 0;
++}
++
++int get_cgroup_version_v2()
++{
++ return CGROUP_VERSION_2;
++}
++
++int cgroup_v2_ops_init(cgroup_ops *ops)
++{
++ if (ops == NULL) {
++ return -1;
++ }
++ ops->get_cgroup_version = get_cgroup_version_v2;
++ ops->get_cgroup_info = get_cgroup_info_v2;
++ ops->get_cgroup_metrics = get_cgroup_metrics_v2;
++ ops->get_cgroup_mnt_and_root_path = get_cgroup_mnt_and_root_v2;
++ return 0;
++}
+\ No newline at end of file
+diff --git a/src/daemon/common/cgroup/cgroup_v2.h b/src/daemon/common/cgroup/cgroup_v2.h
+new file mode 100644
+index 00000000..0e8e4818
+--- /dev/null
++++ b/src/daemon/common/cgroup/cgroup_v2.h
+@@ -0,0 +1,30 @@
++/******************************************************************************
++ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
++ * iSulad licensed under the Mulan PSL v2.
++ * You can use this software according to the terms and conditions of the Mulan PSL v2.
++ * You may obtain a copy of Mulan PSL v2 at:
++ * http://license.coscl.org.cn/MulanPSL2
++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
++ * PURPOSE.
++ * See the Mulan PSL v2 for more details.
++ * Author: zhongtao
++ * Create: 2024-02-19
++ * Description: provide cgroup v2 definition
++ ******************************************************************************/
++#ifndef DAEMON_COMMON_CGROUP_CGROUP_V2_H
++#define DAEMON_COMMON_CGROUP_CGROUP_V2_H
++
++#include "cgroup.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++int cgroup_v2_ops_init(cgroup_ops *ops);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif // DAEMON_COMMON_CGROUP_CGROUP_V2_H
+diff --git a/src/daemon/common/sysinfo.c b/src/daemon/common/sysinfo.c
+index a082f717..e369c3e3 100644
+--- a/src/daemon/common/sysinfo.c
++++ b/src/daemon/common/sysinfo.c
+@@ -188,15 +188,10 @@ static char **get_huge_page_sizes()
+ struct dirent *info_archivo = NULL;
+ int cgroup_version = 0;
+
+- cgroup_version = common_get_cgroup_version();
+- if (cgroup_version == CGROUP_VERSION_2) {
+- hugetlbmp = util_strdup_s(CGROUP_ISULAD_PATH);
+- } else {
+- ret = common_find_cgroup_mnt_and_root("hugetlb", &hugetlbmp, NULL);
+- if (ret != 0 || hugetlbmp == NULL) {
+- ERROR("Hugetlb cgroup not supported");
+- return NULL;
+- }
++ ret = common_get_cgroup_mnt_and_root_path("hugetlb", &hugetlbmp, NULL);
++ if (ret != 0 || hugetlbmp == NULL) {
++ ERROR("Hugetlb cgroup not supported");
++ return NULL;
+ }
+
+ dir = opendir(hugetlbmp);
+@@ -211,6 +206,7 @@ static char **get_huge_page_sizes()
+ char *pos = NULL;
+ char *dot2 = NULL;
+
++ cgroup_version = common_get_cgroup_version();
+ if (cgroup_version == CGROUP_VERSION_2) {
+ if (!is_hugetlb_max(info_archivo->d_name)) {
+ continue;
+@@ -375,7 +371,6 @@ void free_sysinfo(sysinfo_t *sysinfo)
+ /* get sys info */
+ sysinfo_t *get_sys_info(bool quiet)
+ {
+- int cgroup_version = 0;
+ sysinfo_t *sysinfo = NULL;
+ int ret = 0;
+
+@@ -388,21 +383,9 @@ sysinfo_t *get_sys_info(bool quiet)
+ sysinfo->ncpus = get_nprocs();
+ sysinfo->ncpus_conf = get_nprocs_conf();
+
+- cgroup_version = common_get_cgroup_version();
+- if (cgroup_version < 0) {
+- ret = -1;
+- goto out;
+- }
+-
+- if (cgroup_version == CGROUP_VERSION_1) {
+- ret = common_get_cgroup_info_v1(&sysinfo->cgmeminfo, &sysinfo->cgcpuinfo, &sysinfo->hugetlbinfo,
++ ret = common_get_cgroup_info(&sysinfo->cgmeminfo, &sysinfo->cgcpuinfo, &sysinfo->hugetlbinfo,
+ &sysinfo->blkioinfo, &sysinfo->cpusetinfo, &sysinfo->pidsinfo,
+ &sysinfo->filesinfo, quiet);
+- } else {
+- ret = common_get_cgroup_info_v2(&sysinfo->cgmeminfo, &sysinfo->cgcpuinfo, &sysinfo->hugetlbinfo,
+- &sysinfo->blkioinfo, &sysinfo->cpusetinfo, &sysinfo->pidsinfo,
+- &sysinfo->filesinfo, quiet);
+- }
+ if (ret != 0) {
+ goto out;
+ }
+@@ -563,7 +546,7 @@ free_out:
+ return minfos;
+ }
+
+-char *sysinfo_cgroup_controller_cpurt_mnt_path(void)
++char *sysinfo_get_cpurt_mnt_path(void)
+ {
+ int nret = 0;
+ __isula_auto_free char *mnt = NULL;
+@@ -583,7 +566,7 @@ char *sysinfo_cgroup_controller_cpurt_mnt_path(void)
+ return NULL;
+ }
+
+- nret = common_find_cgroup_mnt_and_root("cpu", &mnt, &root);
++ nret = common_get_cgroup_mnt_and_root_path("cpu", &mnt, &root);
+ if (nret != 0 || mnt == NULL || root == NULL) {
+ ERROR("Can not find cgroup mnt and root path for subsystem 'cpu'");
+ isulad_set_error_message("Can not find cgroup mnt and root path for subsystem 'cpu'");
+diff --git a/src/daemon/common/sysinfo.h b/src/daemon/common/sysinfo.h
+index cb44d1c5..6142487b 100644
+--- a/src/daemon/common/sysinfo.h
++++ b/src/daemon/common/sysinfo.h
+@@ -95,13 +95,13 @@ mountinfo_t *find_mount_info(mountinfo_t **minfos, const char *dir);
+
+ void free_mounts_info(mountinfo_t **minfos);
+
+-char *sysinfo_cgroup_controller_cpurt_mnt_path(void);
+-
+ // define auto free function callback for sysinfo_t
+ define_auto_cleanup_callback(free_sysinfo, sysinfo_t)
+ // define auto free macro for sysinfo_t
+ #define __isula_auto_sysinfo_t auto_cleanup_tag(free_sysinfo)
+
++char *sysinfo_get_cpurt_mnt_path(void);
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
+index 3bdc3af8..f125e714 100644
+--- a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
++++ b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
+@@ -872,18 +872,7 @@ void PodSandboxManagerService::GetPodSandboxCgroupMetrics(const std::string &cgr
+ return;
+ }
+
+- auto cgroupVersion = common_get_cgroup_version();
+- if (cgroupVersion < 0) {
+- error.Errorf("Invalid cgroup version");
+- return;
+- }
+-
+- if (cgroupVersion == CGROUP_VERSION_1) {
+- nret = common_get_cgroup_v1_metrics(cgroupParent.c_str(), &cgroupMetrics);
+- } else {
+- nret = common_get_cgroup_v2_metrics(cgroupParent.c_str(), &cgroupMetrics);
+- }
+-
++ nret = common_get_cgroup_metrics(cgroupParent.c_str(), &cgroupMetrics);
+ if (nret != 0) {
+ error.Errorf("Failed to get cgroup metrics");
+ }
+diff --git a/src/daemon/entry/cri/v1alpha/cri_pod_sandbox_manager_service.cc b/src/daemon/entry/cri/v1alpha/cri_pod_sandbox_manager_service.cc
+index 49a7ca54..af6b5fff 100644
+--- a/src/daemon/entry/cri/v1alpha/cri_pod_sandbox_manager_service.cc
++++ b/src/daemon/entry/cri/v1alpha/cri_pod_sandbox_manager_service.cc
+@@ -1328,18 +1328,7 @@ void PodSandboxManagerService::GetPodSandboxCgroupMetrics(const container_inspec
+ return;
+ }
+
+- auto cgroupVersion = common_get_cgroup_version();
+- if (cgroupVersion < 0) {
+- error.Errorf("Invalid cgroup version");
+- return;
+- }
+-
+- if (cgroupVersion == CGROUP_VERSION_1) {
+- nret = common_get_cgroup_v1_metrics(cgroupParent, &cgroupMetrics);
+- } else {
+- nret = common_get_cgroup_v2_metrics(cgroupParent, &cgroupMetrics);
+- }
+-
++ nret = common_get_cgroup_metrics(cgroupParent, &cgroupMetrics);
+ if (nret != 0) {
+ error.Errorf("Failed to get cgroup metrics");
+ }
+diff --git a/src/daemon/executor/container_cb/execution.c b/src/daemon/executor/container_cb/execution.c
+index 7ed8e837..88c6b354 100644
+--- a/src/daemon/executor/container_cb/execution.c
++++ b/src/daemon/executor/container_cb/execution.c
+@@ -413,6 +413,13 @@ static int cpurt_controller_init(const char *id, const host_config *host_spec)
+ char *dirpath = NULL;
+ int64_t cpu_rt_period = 0;
+ int64_t cpu_rt_runtime = 0;
++ int cgroup_version = 0;
++
++ // cgroup v2 is not support cpurt
++ cgroup_version = common_get_cgroup_version();
++ if (cgroup_version == CGROUP_VERSION_2) {
++ return 0;
++ }
+
+ cgroups_path = merge_container_cgroups_path(id, host_spec);
+ if (cgroups_path == NULL || strcmp(cgroups_path, "/") == 0 || strcmp(cgroups_path, ".") == 0) {
+@@ -433,13 +440,13 @@ static int cpurt_controller_init(const char *id, const host_config *host_spec)
+ // should iSulad set cpu.rt_runtime_us and cpu.rt_period_us for the parent path?
+ // in fact, even if system.slice is used,
+ // cpu.rt_runtime_us and cpu.rt_period_us might still needed to be set manually
+- __isula_auto_free char *init_cgroup = common_get_init_cgroup("cpu");
++ __isula_auto_free char *init_cgroup = common_get_init_cgroup_path("cpu");
+ if (init_cgroup == NULL) {
+ ERROR("Failed to get init cgroup");
+ return -1;
+ }
+ // make sure that the own cgroup path for cpu existed
+- __isula_auto_free char *own_cgroup = common_get_own_cgroup("cpu");
++ __isula_auto_free char *own_cgroup = common_get_own_cgroup_path("cpu");
+ if (own_cgroup == NULL) {
+ ERROR("Failed to get own cgroup");
+ return -1;
+@@ -453,7 +460,7 @@ static int cpurt_controller_init(const char *id, const host_config *host_spec)
+ cgroups_path = new_cgroups_path;
+ }
+
+- mnt_root = sysinfo_cgroup_controller_cpurt_mnt_path();
++ mnt_root = sysinfo_get_cpurt_mnt_path();
+ if (mnt_root == NULL) {
+ ERROR("Failed to get cpu rt controller mnt root path");
+ return -1;
+--
+2.34.1
+