diff options
author | CoprDistGit <infra@openeuler.org> | 2024-09-03 03:24:28 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-09-03 03:24:28 +0000 |
commit | e45819fcb4a96649a4030db7684f140d5ca46735 (patch) | |
tree | 544dac3e30a0448eabdc50add41aa3a18982d9f1 /0027-feature-add-support-for-cgroup-v2-metrics.patch | |
parent | 1a71e3afebb4b43be63949dcc8e882fe7643f13b (diff) |
automatic import of iSuladopeneuler24.03_LTS
Diffstat (limited to '0027-feature-add-support-for-cgroup-v2-metrics.patch')
-rw-r--r-- | 0027-feature-add-support-for-cgroup-v2-metrics.patch | 1084 |
1 files changed, 1084 insertions, 0 deletions
diff --git a/0027-feature-add-support-for-cgroup-v2-metrics.patch b/0027-feature-add-support-for-cgroup-v2-metrics.patch new file mode 100644 index 0000000..f5b4073 --- /dev/null +++ b/0027-feature-add-support-for-cgroup-v2-metrics.patch @@ -0,0 +1,1084 @@ +From 7c7cd82619ed1f7e36d34da1afc2b417a90b3040 Mon Sep 17 00:00:00 2001 +From: zhongtao <zhongtao17@huawei.com> +Date: Tue, 23 Jan 2024 17:18:51 +0800 +Subject: [PATCH 27/43] =?UTF-8?q?=E3=80=90feature=E3=80=91add=20support=20?= + =?UTF-8?q?for=20cgroup=20v2=20metrics?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: zhongtao <zhongtao17@huawei.com> +--- + src/daemon/common/cgroup.c | 237 ++-------- + src/daemon/common/cgroup.h | 11 +- + src/daemon/common/cgroup_v1.c | 194 +++------ + src/daemon/common/cgroup_v2.c | 406 ++++++++++++++++++ + .../v1/v1_cri_pod_sandbox_manager_service.cc | 2 +- + .../cri_pod_sandbox_manager_service.cc | 2 +- + src/utils/cutils/utils_array.h | 6 + + 7 files changed, 506 insertions(+), 352 deletions(-) + create mode 100644 src/daemon/common/cgroup_v2.c + +diff --git a/src/daemon/common/cgroup.c b/src/daemon/common/cgroup.c +index 2d1cabb2..3c58f7fa 100644 +--- a/src/daemon/common/cgroup.c ++++ b/src/daemon/common/cgroup.c +@@ -29,32 +29,6 @@ + #include "utils_array.h" + #include "sysinfo.h" + +-// Cgroup V2 Item Definition +-#define CGROUP2_CPU_WEIGHT "cpu.weight" +-#define CGROUP2_CPU_MAX "cpu.max" +-#define CGROUP2_CPUSET_CPUS_EFFECTIVE "cpuset.cpus.effective" +-#define CGROUP2_CPUSET_MEMS_EFFECTIVE "cpuset.mems.effective" +-#define CGROUP2_CPUSET_CPUS "cpuset.cpus" +-#define CGROUP2_CPUSET_MEMS "cpuset.mems" +-#define CGROUP2_IO_WEIGHT "io.weight" +-#define CGROUP2_IO_BFQ_WEIGHT "io.bfq.weight" +-#define CGROUP2_IO_MAX "io.max" +-#define CGROUP2_MEMORY_MAX "memory.max" +-#define CGROUP2_MEMORY_LOW "memory.low" +-#define CGROUP2_MEMORY_SWAP_MAX "memory.swap.max" +-#define CGROUP2_HUGETLB_MAX "hugetlb.%s.max" +-#define CGROUP2_PIDS_MAX "pids.max" +-#define CGROUP2_FILES_LIMIT "files.limit" +- +-#define CGROUP2_CONTROLLERS_PATH CGROUP_MOUNTPOINT"/cgroup.controllers" +-#define CGROUP2_SUBTREE_CONTROLLER_PATH CGROUP_MOUNTPOINT"/cgroup.subtree_control" +-#define CGROUP2_CPUSET_CPUS_EFFECTIVE_PATH CGROUP_MOUNTPOINT"/cpuset.cpus.effective" +-#define CGROUP2_CPUSET_MEMS_EFFECTIVE_PATH CGROUP_MOUNTPOINT"/cpuset.mems.effective" +- +-#ifndef CGROUP2_SUPER_MAGIC +-#define CGROUP2_SUPER_MAGIC 0x63677270 +-#endif +- + #ifndef CGROUP_SUPER_MAGIC + #define CGROUP_SUPER_MAGIC 0x27e0eb + #endif +@@ -485,20 +459,6 @@ out: + return layers; + } + +-/* cgroup enabled */ +-static bool cgroup_enabled(const char *mountpoint, const char *name) +-{ +- char path[PATH_MAX] = { 0 }; +- int nret; +- +- nret = snprintf(path, sizeof(path), "%s/%s", mountpoint, name); +- if (nret < 0 || (size_t)nret >= sizeof(path)) { +- ERROR("Path is too long"); +- return false; +- } +- return util_file_exists(path); +-} +- + char *common_find_cgroup_subsystem_mountpoint(const cgroup_layer_t *layers, const char *subsystem) + { + size_t i; +@@ -607,188 +567,59 @@ int common_get_cgroup_version(void) + return CGROUP_VERSION_1; + } + +-static int cgroup2_enable_all() ++static int get_value_ull(const char *content, void *result) + { +- int ret = 0; +- int nret = 0; +- int n = 0; +- size_t i = 0; +- const char *space = ""; +- char *controllers_str = NULL; +- char *subtree_controller_str = NULL; +- char **controllers = NULL; +- char enable_controllers[PATH_MAX] = { 0 }; +- +- controllers_str = util_read_content_from_file(CGROUP2_CONTROLLERS_PATH); +- if (controllers_str == NULL || strlen(controllers_str) == 0 || strcmp(controllers_str, "\n") == 0) { +- WARN("no cgroup controller found"); +- goto out; +- } +- +- subtree_controller_str = util_read_content_from_file(CGROUP2_SUBTREE_CONTROLLER_PATH); +- if (subtree_controller_str != NULL && strcmp(controllers_str, subtree_controller_str) == 0) { +- goto out; +- } ++ uint64_t ull_result = 0; + +- controllers = util_string_split(controllers_str, ' '); +- if (controllers == NULL) { +- ERROR("split %s failed", controllers_str); +- ret = -1; +- goto out; +- } +- +- for (i = 0; i < util_array_len((const char **)controllers); i++) { +- nret = snprintf(enable_controllers + n, PATH_MAX - n, "%s+%s", space, controllers[i]); +- if (nret < 0 || (size_t)nret >= PATH_MAX - n) { +- ERROR("Path is too long"); +- goto out; +- } +- n += nret; +- space = " "; +- } +- ret = util_write_file(CGROUP2_SUBTREE_CONTROLLER_PATH, enable_controllers, strlen(enable_controllers), +- DEFAULT_CGROUP_FILE_MODE); +- if (ret != 0) { +- SYSERROR("write %s to %s failed", enable_controllers, CGROUP2_SUBTREE_CONTROLLER_PATH); +- goto out; ++ if (util_safe_uint64(content, &ull_result) != 0) { ++ ERROR("Failed to convert %s to uint64", content); ++ return -1; + } + +-out: +- util_free_array(controllers); +- free(controllers_str); +- free(subtree_controller_str); +- +- return ret; ++ *(uint64_t *)result = ull_result; ++ return 0; + } + +-#if defined (__ANDROID__) || defined(__MUSL__) +-static bool cgroup2_no_controller() ++int get_match_value_ull(const char *content, const char *match, void *result) + { +- char *controllers_str = NULL; ++ __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; + +- controllers_str = util_read_content_from_file(CGROUP2_CONTROLLERS_PATH); +- if (controllers_str == NULL || strlen(controllers_str) == 0 || strcmp(controllers_str, "\n") == 0) { +- free(controllers_str); +- return true; ++ if (match == NULL) { ++ return get_value_ull(content, result); + } + +- free(controllers_str); +- return false; +-} +-#endif +- +-static int make_sure_cgroup2_isulad_path_exist() +-{ +- int ret = 0; +- +- if (util_dir_exists(CGROUP_ISULAD_PATH)) { +- return 0; ++ // match full string ++ match_with_space = util_string_append(" ", match); ++ if (match_with_space == NULL) { ++ ERROR("Failed to append string"); ++ return -1; + } + +- if (cgroup2_enable_all() != 0) { ++ lines = util_string_split(content, '\n'); ++ if (lines == NULL) { ++ ERROR("Failed to split content %s", content); + return -1; + } + +-#if defined (__ANDROID__) || defined(__MUSL__) +- if (cgroup2_no_controller()) { +- DEBUG("no cgroup controller found"); +- return 0; ++ for (worker = lines; worker && *worker; worker++) { ++ if (util_has_prefix(*worker, match_with_space)) { ++ break; ++ } + } +-#endif +- +- ret = mkdir(CGROUP_ISULAD_PATH, DEFAULT_CGROUP_DIR_MODE); +- if (ret != 0 && (errno != EEXIST || !util_dir_exists(CGROUP_ISULAD_PATH))) { ++ if (*worker == NULL) { ++ ERROR("Cannot find match string %s", match); + return -1; + } + +- return ret; +-} +- +-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) +-{ +- int ret = 0; +- int nret = 0; +- char *size = NULL; +- char path[PATH_MAX] = { 0 }; +- +- if (make_sure_cgroup2_isulad_path_exist() != 0) { ++ 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); + +- // cpu cgroup +- cpuinfo->cpu_shares = cgroup_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_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"); +- +- cpusetinfo->cpuset = cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_CPUS_EFFECTIVE) && +- cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_CPUS) && +- cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_MEMS_EFFECTIVE) && +- cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_MEMS); +- common_cgroup_do_log(quiet, !(cpusetinfo->cpuset), "Your kernel does not support cpuset"); +- if (cpusetinfo->cpuset) { +- cpusetinfo->cpus = util_read_content_from_file(CGROUP2_CPUSET_CPUS_EFFECTIVE_PATH); +- cpusetinfo->mems = util_read_content_from_file(CGROUP2_CPUSET_MEMS_EFFECTIVE_PATH); +- if (cpusetinfo->cpus == NULL || cpusetinfo->mems == NULL) { +- ERROR("read cpus or mems failed"); +- return -1; +- } +- cpusetinfo->cpus = util_trim_space(cpusetinfo->cpus); +- cpusetinfo->mems = util_trim_space(cpusetinfo->mems); +- } +- +- // io cgroup +- blkioinfo->blkio_weight = cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_BFQ_WEIGHT) || +- cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_WEIGHT); +- blkioinfo->blkio_weight_device = blkioinfo->blkio_weight; +- common_cgroup_do_log(quiet, !(blkioinfo->blkio_weight), "Your kernel does not support cgroup2 io weight"); +- +- blkioinfo->blkio_read_bps_device = cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_MAX); +- blkioinfo->blkio_write_bps_device = blkioinfo->blkio_read_bps_device; +- 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_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_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_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_enabled(CGROUP_ISULAD_PATH, CGROUP2_PIDS_MAX); +- common_cgroup_do_log(quiet, !(pidsinfo->pidslimit), "Your kernel does not support cgroup2 pids max"); +- +- // hugetlb cgroup +- size = get_default_huge_page_size(); +- if (size != NULL) { +- nret = snprintf(path, sizeof(path), CGROUP2_HUGETLB_MAX, size); +- if (nret < 0 || (size_t)nret >= sizeof(path)) { +- WARN("Failed to print hugetlb path"); +- ret = -1; +- goto out; +- } +- hugetlbinfo->hugetlblimit = cgroup_enabled(CGROUP_ISULAD_PATH, path); +- common_cgroup_do_log(quiet, !hugetlbinfo->hugetlblimit, "Your kernel does not support cgroup2 hugetlb limit"); +- } else { +- WARN("Your kernel does not support cgroup2 hugetlb limit"); +- } +- +- // files cgroup +- filesinfo->fileslimit = cgroup_enabled(CGROUP_ISULAD_PATH, CGROUP2_FILES_LIMIT); +- common_cgroup_do_log(quiet, !(filesinfo->fileslimit), "Your kernel does not support cgroup2 files limit"); +- +-out: +- free(size); +- +- return ret; +-} ++ return get_value_ull(llu_string, result); ++} +\ No newline at end of file +diff --git a/src/daemon/common/cgroup.h b/src/daemon/common/cgroup.h +index fa20f42c..251e3a3d 100644 +--- a/src/daemon/common/cgroup.h ++++ b/src/daemon/common/cgroup.h +@@ -31,6 +31,15 @@ extern "C" { + #define CGROUP_MOUNTPOINT "/sys/fs/cgroup" + #define CGROUP_ISULAD_PATH CGROUP_MOUNTPOINT"/isulad" + ++struct cgfile_t { ++ char *name; ++ char *file; ++ char *match; ++ int (*get_value)(const char *content, const char *match, void *result); ++}; ++ ++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); +@@ -42,7 +51,6 @@ static inline void common_cgroup_do_log(bool quiet, bool do_log, const char *msg + } + } + +- + typedef struct { + char **controllers; + char *mountpoint; +@@ -140,6 +148,7 @@ typedef struct { + } 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); + + char *common_get_init_cgroup(const char *subsystem); + +diff --git a/src/daemon/common/cgroup_v1.c b/src/daemon/common/cgroup_v1.c +index e38fc03e..e34100bc 100644 +--- a/src/daemon/common/cgroup_v1.c ++++ b/src/daemon/common/cgroup_v1.c +@@ -23,20 +23,8 @@ + + #define CGROUP_HUGETLB_LIMIT "hugetlb.%s.limit_in_bytes" + +-typedef struct { +- char *match; +-} cgfile_callback_args_t; +- +-struct cgfile_t { +- char *name; +- char *file; +- int (*get_value)(const char *content, const cgfile_callback_args_t *args, void *result); +-}; +- +-static int get_value_ll(const char *content, const cgfile_callback_args_t *args, void *result); +-static int get_value_ull(const char *content, const cgfile_callback_args_t *args, void *result); +-static int get_match_value_ull(const char *content, const cgfile_callback_args_t *args, void *result); +-static int get_value_string(const char *content, const cgfile_callback_args_t *args, void *result); ++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); + + typedef enum { + // CPU subsystem +@@ -63,46 +51,46 @@ typedef enum { + + static struct cgfile_t g_cgroup_v1_files[] = { + // CPU subsystem +- [CPU_RT_PERIOD] = {"cpu_rt_period", "cpu.rt_period_us", get_value_ull}, +- [CPU_RT_RUNTIME] = {"cpu_rt_runtime", "cpu.rt_runtime_us", get_value_ull}, +- [CPU_SHARES] = {"cpu_shares", "cpu.shares", get_value_ull}, +- [CPU_CFS_PERIOD] = {"cpu_cfs_period", "cpu.cfs_period_us", get_value_ull}, +- [CPU_CFS_QUOTA] = {"cpu_cfs_quota", "cpu.cfs_quota_us", get_value_ll}, ++ [CPU_RT_PERIOD] = {"cpu_rt_period", "cpu.rt_period_us", NULL, get_match_value_ull}, ++ [CPU_RT_RUNTIME] = {"cpu_rt_runtime", "cpu.rt_runtime_us", NULL, get_match_value_ull}, ++ [CPU_SHARES] = {"cpu_shares", "cpu.shares", NULL, get_match_value_ull}, ++ [CPU_CFS_PERIOD] = {"cpu_cfs_period", "cpu.cfs_period_us", NULL, get_match_value_ull}, ++ [CPU_CFS_QUOTA] = {"cpu_cfs_quota", "cpu.cfs_quota_us", NULL, get_value_ll}, + // CPUSET subsystem +- [CPUSET_CPUS] = {"cpuset_cpus", "cpuset.cpus", get_value_string}, +- [CPUSET_MEMS] = {"cpuset_mems", "cpuset.mems", get_value_string}, ++ [CPUSET_CPUS] = {"cpuset_cpus", "cpuset.cpus", NULL, get_value_string}, ++ [CPUSET_MEMS] = {"cpuset_mems", "cpuset.mems", NULL, get_value_string}, + // CPUACCT subsystem +- [CPUACCT_USE_NANOS] = {"cpu_use_nanos", "cpuacct.usage", get_value_ull}, +- [CPUACCT_USE_USER] = {"cpu_use_user", "cpuacct.stat", get_match_value_ull}, +- [CPUACCT_USE_SYS] = {"cpu_use_sys", "cpuacct.stat", get_match_value_ull}, ++ [CPUACCT_USE_NANOS] = {"cpu_use_nanos", "cpuacct.usage", NULL, get_match_value_ull}, ++ [CPUACCT_USE_USER] = {"cpu_use_user", "cpuacct.stat", NULL, get_match_value_ull}, ++ [CPUACCT_USE_SYS] = {"cpu_use_sys", "cpuacct.stat", NULL, get_match_value_ull}, + // MEMORY subsystem +- [MEMORY_LIMIT] = {"mem_limit", "memory.limit_in_bytes", get_value_ull}, +- [MEMORY_USAGE] = {"mem_usage", "memory.usage_in_bytes", get_value_ull}, +- [MEMORY_SOFT_LIMIT] = {"mem_soft_limit", "memory.soft_limit_in_bytes", get_value_ull}, +- [MEMORY_KMEM_LIMIT] = {"kmem_limit", "memory.kmem.limit_in_bytes", get_value_ull}, +- [MEMORY_KMEM_USAGE] = {"kmem_usage", "memory.kmem.usage_in_bytes", get_value_ull}, +- [MEMORY_SWAPPINESS] = {"swappiness", "memory.swappiness", NULL}, +- [MEMORY_SW_LIMIT] = {"memsw_limit", "memory.memsw.limit_in_bytes", get_value_ull}, +- [MEMORY_SW_USAGE] = {"memsw_usage", "memory.memsw.usage_in_bytes", get_value_ull}, +- [MEMORY_CACHE] = {"cache", "memory.stat", get_match_value_ull}, +- [MEMORY_CACHE_TOTAL] = {"cache_total", "memory.stat", get_match_value_ull}, +- [MEMORY_TOTAL_RSS] = {"total_rss", "memory.stat", get_match_value_ull}, +- [MEMORY_TOTAL_PGFAULT] = {"total_page_fault", "memory.stat", get_match_value_ull}, +- [MEMORY_TOTAL_PGMAJFAULT] = {"total_page_majfault", "memory.stat", get_match_value_ull}, +- [MEMORY_TOTAL_INACTIVE_FILE] = {"total_inactive_file", "memory.stat", get_match_value_ull}, +- [MEMORY_OOM_CONTROL] = {"oom_control", "memory.oom_control", NULL}, ++ [MEMORY_LIMIT] = {"mem_limit", "memory.limit_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_USAGE] = {"mem_usage", "memory.usage_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_SOFT_LIMIT] = {"mem_soft_limit", "memory.soft_limit_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_KMEM_LIMIT] = {"kmem_limit", "memory.kmem.limit_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_KMEM_USAGE] = {"kmem_usage", "memory.kmem.usage_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_SWAPPINESS] = {"swappiness", "memory.swappiness", NULL, NULL}, ++ [MEMORY_SW_LIMIT] = {"memsw_limit", "memory.memsw.limit_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_SW_USAGE] = {"memsw_usage", "memory.memsw.usage_in_bytes", NULL, get_match_value_ull}, ++ [MEMORY_CACHE] = {"cache", "memory.stat", NULL, get_match_value_ull}, ++ [MEMORY_CACHE_TOTAL] = {"cache_total", "memory.stat", NULL, get_match_value_ull}, ++ [MEMORY_TOTAL_RSS] = {"total_rss", "memory.stat", "total_rss", get_match_value_ull}, ++ [MEMORY_TOTAL_PGFAULT] = {"total_page_fault", "memory.stat", "total_pgfault", get_match_value_ull}, ++ [MEMORY_TOTAL_PGMAJFAULT] = {"total_page_majfault", "memory.stat", "total_pgmajfault", get_match_value_ull}, ++ [MEMORY_TOTAL_INACTIVE_FILE] = {"total_inactive_file", "memory.stat", "total_inactive_file", get_match_value_ull}, ++ [MEMORY_OOM_CONTROL] = {"oom_control", "memory.oom_control", NULL, NULL}, + // BLKIO subsystem +- [BLKIO_WEIGTH] = {"blkio_weigth", "blkio.weight", NULL}, +- [BLKIO_WEIGTH_DEVICE] = {"blkio_weigth_device", "blkio.weight_device", NULL}, +- [BLKIO_READ_BPS] = {"blkio_read_bps", "blkio.throttle.read_bps_device", NULL}, +- [BLKIO_WRITE_BPS] = {"blkio_write_bps", "blkio.throttle.write_bps_device", NULL}, +- [BLKIO_READ_IOPS] = {"blkio_read_iops", "blkio.throttle.read_iops_device", NULL}, +- [BLKIO_WRITE_IOPS] = {"blkio_write_iops", "blkio.throttle.write_iops_device", NULL}, ++ [BLKIO_WEIGTH] = {"blkio_weigth", "blkio.weight", NULL, NULL}, ++ [BLKIO_WEIGTH_DEVICE] = {"blkio_weigth_device", "blkio.weight_device", NULL, NULL}, ++ [BLKIO_READ_BPS] = {"blkio_read_bps", "blkio.throttle.read_bps_device", NULL, NULL}, ++ [BLKIO_WRITE_BPS] = {"blkio_write_bps", "blkio.throttle.write_bps_device", NULL, NULL}, ++ [BLKIO_READ_IOPS] = {"blkio_read_iops", "blkio.throttle.read_iops_device", NULL, NULL}, ++ [BLKIO_WRITE_IOPS] = {"blkio_write_iops", "blkio.throttle.write_iops_device", NULL, NULL}, + // PIDS subsystem +- [PIDS_CURRENT] = {"pids_current", "pids.current", get_value_ull}, ++ [PIDS_CURRENT] = {"pids_current", "pids.current", NULL, get_match_value_ull}, + }; + +-static int get_value_ll(const char *content, const cgfile_callback_args_t *args, void *result) ++static int get_value_ll(const char *content, const char *match, void *result) + { + long long ll_result = 0; + +@@ -115,81 +103,7 @@ static int get_value_ll(const char *content, const cgfile_callback_args_t *args, + return 0; + } + +-static int get_value_ull(const char *content, const cgfile_callback_args_t *args, 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; +-} +- +-static int get_match_value_ull(const char *content, const cgfile_callback_args_t *args, void *result) +-{ +- int ret = 0; +- uint64_t llu_result = 0; +- char *llu_string = NULL; +- char *match_with_space = NULL; +- char **lines = NULL; +- char **worker = NULL; +- +- if (args == NULL || args->match == NULL || strlen(args->match) == 0) { +- ERROR("Invalid arguments"); +- return -1; +- } +- +- // match full string +- match_with_space = util_string_append(" ", args->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); +- ret = -1; +- goto out; +- } +- +- for (worker = lines; worker && *worker; worker++) { +- if (util_has_prefix(*worker, match_with_space)) { +- break; +- } +- } +- if (*worker == NULL) { +- ERROR("Cannot find match string %s", args->match); +- ret = -1; +- goto out; +- } +- +- 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"); +- ret = -1; +- goto out; +- } +- llu_string = util_trim_space(llu_string); +- +- ret = util_safe_uint64(llu_string, &llu_result); +- if (ret != 0) { +- ERROR("Failed to convert %s to uint64", llu_string); +- } else { +- *(uint64_t *)result = llu_result; +- } +- +-out: +- free(match_with_space); +- free(llu_string); +- util_free_array(lines); +- return ret; +-} +- +-static int get_value_string(const char *content, const cgfile_callback_args_t *args, void *result) ++static int get_value_string(const char *content, const char *match, void *result) + { + *(char **)result = util_strdup_s(content); + return 0; +@@ -228,7 +142,7 @@ static bool check_cgroup_v1_helper(const char *mountpoint, const cgroup_v1_files + } + + static int get_cgroup_v1_value_helper(const char *path, const cgroup_v1_files_index index, +- const cgfile_callback_args_t *args, void *result) ++ void *result) + { + int nret = 0; + char file_path[PATH_MAX] = { 0 }; +@@ -265,7 +179,7 @@ static int get_cgroup_v1_value_helper(const char *path, const cgroup_v1_files_in + util_trim_newline(content); + content = util_trim_space(content); + +- nret = g_cgroup_v1_files[index].get_value(content, args, result); ++ 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); + } +@@ -308,11 +222,11 @@ static void check_cgroup_v1_cpuset(const cgroup_layer_t *layers, const bool quie + return; + } + +- if (get_cgroup_v1_value_helper(mountpoint, CPUSET_CPUS, NULL, (void *)&cpusetinfo->cpus) != 0) { ++ if (get_cgroup_v1_value_helper(mountpoint, CPUSET_CPUS, (void *)&cpusetinfo->cpus) != 0) { + ERROR("Failed to get cgroup cpuset.cpus data"); + return; + } +- if (get_cgroup_v1_value_helper(mountpoint, CPUSET_MEMS, NULL, (void *)&cpusetinfo->mems) != 0) { ++ if (get_cgroup_v1_value_helper(mountpoint, CPUSET_MEMS, (void *)&cpusetinfo->mems) != 0) { + free(cpusetinfo->cpus); + cpusetinfo->cpus = NULL; + ERROR("Failed to get cgroup cpuset.cpus data"); +@@ -463,7 +377,7 @@ static void get_cgroup_v1_metrics_cpu(const cgroup_layer_t *layers, const char * + return; + } + +- get_cgroup_v1_value_helper(path, CPUACCT_USE_NANOS, NULL, (void *)&cgroup_cpu_metrics->cpu_use_nanos); ++ get_cgroup_v1_value_helper(path, CPUACCT_USE_NANOS, (void *)&cgroup_cpu_metrics->cpu_use_nanos); + } + + static void get_cgroup_v1_metrics_memory(const cgroup_layer_t *layers, const char *cgroup_path, +@@ -472,18 +386,6 @@ static void get_cgroup_v1_metrics_memory(const cgroup_layer_t *layers, const cha + int nret = 0; + char *mountpoint = NULL; + char path[PATH_MAX] = { 0 }; +- const cgfile_callback_args_t total_inactive_file_arg = { +- .match = "total_inactive_file", +- }; +- const cgfile_callback_args_t total_rss_arg = { +- .match = "total_rss", +- }; +- const cgfile_callback_args_t total_pgfault_arg = { +- .match = "total_pgfault", +- }; +- const cgfile_callback_args_t total_pgmajfault_arg = { +- .match = "total_pgmajfault", +- }; + + mountpoint = common_find_cgroup_subsystem_mountpoint(layers, "memory"); + if (mountpoint == NULL) { +@@ -497,14 +399,14 @@ static void get_cgroup_v1_metrics_memory(const cgroup_layer_t *layers, const cha + return; + } + +- get_cgroup_v1_value_helper(path, MEMORY_LIMIT, NULL, (void *)&cgroup_mem_metrics->mem_limit); +- get_cgroup_v1_value_helper(path, MEMORY_USAGE, NULL, (void *)&cgroup_mem_metrics->mem_used); +- get_cgroup_v1_value_helper(path, MEMORY_TOTAL_RSS, &total_rss_arg, (void *)&cgroup_mem_metrics->total_rss); +- get_cgroup_v1_value_helper(path, MEMORY_TOTAL_PGFAULT, &total_pgfault_arg, ++ get_cgroup_v1_value_helper(path, MEMORY_LIMIT, (void *)&cgroup_mem_metrics->mem_limit); ++ get_cgroup_v1_value_helper(path, MEMORY_USAGE, (void *)&cgroup_mem_metrics->mem_used); ++ get_cgroup_v1_value_helper(path, MEMORY_TOTAL_RSS, (void *)&cgroup_mem_metrics->total_rss); ++ get_cgroup_v1_value_helper(path, MEMORY_TOTAL_PGFAULT, + (void *)&cgroup_mem_metrics->total_pgfault); +- get_cgroup_v1_value_helper(path, MEMORY_TOTAL_PGMAJFAULT, &total_pgmajfault_arg, ++ get_cgroup_v1_value_helper(path, MEMORY_TOTAL_PGMAJFAULT, + (void *)&cgroup_mem_metrics->total_pgmajfault); +- get_cgroup_v1_value_helper(path, MEMORY_TOTAL_INACTIVE_FILE, &total_inactive_file_arg, ++ get_cgroup_v1_value_helper(path, MEMORY_TOTAL_INACTIVE_FILE, + (void *)&cgroup_mem_metrics->total_inactive_file); + } + +@@ -527,7 +429,7 @@ static void get_cgroup_v1_metrics_pid(const cgroup_layer_t *layers, const char * + return; + } + +- get_cgroup_v1_value_helper(path, PIDS_CURRENT, NULL, (void *)&cgroup_pids_metrics->pid_current); ++ 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) +diff --git a/src/daemon/common/cgroup_v2.c b/src/daemon/common/cgroup_v2.c +new file mode 100644 +index 00000000..25509bda +--- /dev/null ++++ b/src/daemon/common/cgroup_v2.c +@@ -0,0 +1,406 @@ ++/****************************************************************************** ++ * 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-01-16 ++ * Description: provide cgroup v2 functions ++ ******************************************************************************/ ++#include "cgroup.h" ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <sys/stat.h> ++ ++#include <isula_libutils/auto_cleanup.h> ++ ++#include "utils.h" ++#include "path.h" ++#include "sysinfo.h" ++ ++// Cgroup V2 Item Definition ++#define CGROUP2_CPU_WEIGHT "cpu.weight" ++#define CGROUP2_CPU_MAX "cpu.max" ++#define CGROUP2_CPUSET_CPUS_EFFECTIVE "cpuset.cpus.effective" ++#define CGROUP2_CPUSET_MEMS_EFFECTIVE "cpuset.mems.effective" ++#define CGROUP2_CPUSET_CPUS "cpuset.cpus" ++#define CGROUP2_CPUSET_MEMS "cpuset.mems" ++#define CGROUP2_IO_WEIGHT "io.weight" ++#define CGROUP2_IO_BFQ_WEIGHT "io.bfq.weight" ++#define CGROUP2_IO_MAX "io.max" ++#define CGROUP2_MEMORY_MAX "memory.max" ++#define CGROUP2_MEMORY_LOW "memory.low" ++#define CGROUP2_MEMORY_SWAP_MAX "memory.swap.max" ++#define CGROUP2_HUGETLB_MAX "hugetlb.%s.max" ++#define CGROUP2_PIDS_MAX "pids.max" ++#define CGROUP2_FILES_LIMIT "files.limit" ++ ++#define CGROUP2_CONTROLLERS_PATH CGROUP_MOUNTPOINT"/cgroup.controllers" ++#define CGROUP2_SUBTREE_CONTROLLER_PATH CGROUP_MOUNTPOINT"/cgroup.subtree_control" ++#define CGROUP2_CPUSET_CPUS_EFFECTIVE_PATH CGROUP_MOUNTPOINT"/cpuset.cpus.effective" ++#define CGROUP2_CPUSET_MEMS_EFFECTIVE_PATH CGROUP_MOUNTPOINT"/cpuset.mems.effective" ++ ++#ifndef CGROUP2_SUPER_MAGIC ++#define CGROUP2_SUPER_MAGIC 0x63677270 ++#endif ++ ++static int get_value_ull_v2(const char *content, const char *match, void *result) ++{ ++ uint64_t ull_result = 0; ++ __isula_auto_free char *tmp_str = util_strdup_s(content); ++ ++ tmp_str = util_trim_space(tmp_str); ++ if (strcmp(tmp_str, "max") == 0) { ++ *(uint64_t *)result = UINT64_MAX; ++ return 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; ++} ++ ++typedef enum { ++ // cpu ++ CPUACCT_USE_USER, CPUACCT_USE_SYS, CPUACCT_USE_NANOS, ++ // MEMORY subsystem ++ MEMORY_USAGE, MEMORY_LIMIT, MEMORY_ANON, ++ MEMORY_TOTAL_PGFAULT, MEMORY_TOTAL_INACTIVE_FILE, MEMORY_TOTAL_PGMAJFAULT, ++ MEMORY_CACHE, MEMORY_CACHE_TOTAL, ++ // BLKIO subsystem ++ BLKIO_READ_BPS, BLKIO_WRITE_BPS, BLKIO_READ_IOPS, BLKIO_WRITE_IOPS, ++ // PIDS subsystem ++ PIDS_CURRENT, ++ // MAX ++ CGROUP_V2_FILES_INDEX_MAXS ++} cgroup_v2_files_index; ++ ++static struct cgfile_t g_cgroup_v2_files[] = { ++ // cpu ++ [CPUACCT_USE_USER] = {"cpu_use_user", "cpu.stat", "user_usec", get_match_value_ull}, ++ [CPUACCT_USE_SYS] = {"cpu_use_sys", "cpu.stat", "system_usec", get_match_value_ull}, ++ [CPUACCT_USE_NANOS] = {"cpu_use_nanos", "cpu.stat", "usage_usec", get_match_value_ull}, ++ // memory ++ [MEMORY_USAGE] = {"mem_usage", "memory.current", NULL, get_value_ull_v2}, ++ [MEMORY_LIMIT] = {"mem_limit", "memory.max", NULL, get_value_ull_v2}, ++ [MEMORY_ANON] = {"mem_anon", "memory.stat", "anon", get_match_value_ull}, ++ [MEMORY_TOTAL_PGFAULT] = {"total_page_fault", "memory.stat", "pgfault", get_match_value_ull}, ++ [MEMORY_TOTAL_PGMAJFAULT] = {"total_page_majfault", "memory.stat", "pgmajfault", get_match_value_ull}, ++ [MEMORY_TOTAL_INACTIVE_FILE] = {"total_inactive_file", "memory.stat", "inactive_file", get_match_value_ull}, ++ [MEMORY_CACHE] = {"cache", "memory.stat", "file", get_match_value_ull}, ++ [MEMORY_CACHE_TOTAL] = {"cache_total", "memory.stat", "file", get_match_value_ull}, ++ // pids ++ [PIDS_CURRENT] = {"pids_current", "pids.current", NULL, get_value_ull_v2}, ++}; ++ ++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; ++} ++ ++static void get_cgroup_v2_metrics_cpu(const char *cgroup_path, cgroup_cpu_metrics_t *cgroup_cpu_metrics) ++{ ++ int nret = 0; ++ char path[PATH_MAX] = { 0 }; ++ ++ nret = snprintf(path, sizeof(path), "%s/%s", CGROUP_MOUNTPOINT, cgroup_path); ++ if (nret < 0 || (size_t)nret >= sizeof(path)) { ++ ERROR("Failed to snprintf"); ++ return; ++ } ++ ++ get_cgroup_v2_value_helper(path, CPUACCT_USE_NANOS, (void *)&cgroup_cpu_metrics->cpu_use_nanos); ++} ++ ++static void get_cgroup_v2_metrics_memory(const char *cgroup_path, cgroup_mem_metrics_t *cgroup_mem_metrics) ++{ ++ int nret = 0; ++ char path[PATH_MAX] = { 0 }; ++ ++ nret = snprintf(path, sizeof(path), "%s/%s", CGROUP_MOUNTPOINT, cgroup_path); ++ if (nret < 0 || (size_t)nret >= sizeof(path)) { ++ ERROR("Failed to snprintf"); ++ return; ++ } ++ ++ get_cgroup_v2_value_helper(path, MEMORY_LIMIT, (void *)&cgroup_mem_metrics->mem_limit); ++ get_cgroup_v2_value_helper(path, MEMORY_USAGE, (void *)&cgroup_mem_metrics->mem_used); ++ // Use Anon memory for RSS as cAdvisor on cgroupv2 ++ // see https://github.com/google/cadvisor/blob/a9858972e75642c2b1914c8d5428e33e6392c08a/container/libcontainer/handler.go#L799 ++ get_cgroup_v2_value_helper(path, MEMORY_ANON, (void *)&cgroup_mem_metrics->total_rss); ++ get_cgroup_v2_value_helper(path, MEMORY_TOTAL_PGFAULT, ++ (void *)&cgroup_mem_metrics->total_pgfault); ++ get_cgroup_v2_value_helper(path, MEMORY_TOTAL_PGMAJFAULT, ++ (void *)&cgroup_mem_metrics->total_pgmajfault); ++ get_cgroup_v2_value_helper(path, MEMORY_TOTAL_INACTIVE_FILE, ++ (void *)&cgroup_mem_metrics->total_inactive_file); ++} ++ ++static void get_cgroup_v2_metrics_pid(const char *cgroup_path, cgroup_pids_metrics_t *cgroup_pids_metrics) ++{ ++ int nret = 0; ++ char path[PATH_MAX] = { 0 }; ++ ++ nret = snprintf(path, sizeof(path), "%s/%s", CGROUP_MOUNTPOINT, cgroup_path); ++ if (nret < 0 || (size_t)nret >= sizeof(path)) { ++ ERROR("Failed to snprintf"); ++ return; ++ } ++ ++ get_cgroup_v2_value_helper(path, PIDS_CURRENT, (void *)&cgroup_pids_metrics->pid_current); ++} ++ ++static int cgroup2_enable_all() ++{ ++ int ret = 0; ++ int nret = 0; ++ int n = 0; ++ size_t i = 0; ++ const char *space = ""; ++ __isula_auto_free char *controllers_str = NULL; ++ __isula_auto_free char *subtree_controller_str = NULL; ++ __isula_auto_array_t char **controllers = NULL; ++ char enable_controllers[PATH_MAX] = { 0 }; ++ ++ controllers_str = util_read_content_from_file(CGROUP2_CONTROLLERS_PATH); ++ if (controllers_str == NULL || strlen(controllers_str) == 0 || strcmp(controllers_str, "\n") == 0) { ++ WARN("no cgroup controller found"); ++ return ret; ++ } ++ ++ subtree_controller_str = util_read_content_from_file(CGROUP2_SUBTREE_CONTROLLER_PATH); ++ if (subtree_controller_str != NULL && strcmp(controllers_str, subtree_controller_str) == 0) { ++ return ret; ++ } ++ ++ controllers = util_string_split(controllers_str, ' '); ++ if (controllers == NULL) { ++ ERROR("split %s failed", controllers_str); ++ return -1; ++ } ++ ++ for (i = 0; i < util_array_len((const char **)controllers); i++) { ++ nret = snprintf(enable_controllers + n, PATH_MAX - n, "%s+%s", space, controllers[i]); ++ if (nret < 0 || (size_t)nret >= PATH_MAX - n) { ++ ERROR("Path is too long"); ++ return -1; ++ } ++ n += nret; ++ space = " "; ++ } ++ ret = util_write_file(CGROUP2_SUBTREE_CONTROLLER_PATH, enable_controllers, strlen(enable_controllers), ++ DEFAULT_CGROUP_FILE_MODE); ++ if (ret != 0) { ++ SYSERROR("write %s to %s failed", enable_controllers, CGROUP2_SUBTREE_CONTROLLER_PATH); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++#if defined (__ANDROID__) || defined(__MUSL__) ++static bool cgroup2_no_controller() ++{ ++ char *controllers_str = NULL; ++ ++ controllers_str = util_read_content_from_file(CGROUP2_CONTROLLERS_PATH); ++ if (controllers_str == NULL || strlen(controllers_str) == 0 || strcmp(controllers_str, "\n") == 0) { ++ free(controllers_str); ++ return true; ++ } ++ ++ free(controllers_str); ++ return false; ++} ++#endif ++ ++static int make_sure_cgroup2_isulad_path_exist() ++{ ++ int ret = 0; ++ ++ if (util_dir_exists(CGROUP_ISULAD_PATH)) { ++ return 0; ++ } ++ ++ if (cgroup2_enable_all() != 0) { ++ return -1; ++ } ++ ++#if defined (__ANDROID__) || defined(__MUSL__) ++ if (cgroup2_no_controller()) { ++ DEBUG("no cgroup controller found"); ++ return 0; ++ } ++#endif ++ ++ ret = mkdir(CGROUP_ISULAD_PATH, DEFAULT_CGROUP_DIR_MODE); ++ if (ret != 0 && (errno != EEXIST || !util_dir_exists(CGROUP_ISULAD_PATH))) { ++ return -1; ++ } ++ ++ return ret; ++} ++ ++/* cgroup enabled */ ++static bool cgroup_v2_enabled(const char *mountpoint, const char *name) ++{ ++ char path[PATH_MAX] = { 0 }; ++ int nret; ++ ++ nret = snprintf(path, sizeof(path), "%s/%s", mountpoint, name); ++ if (nret < 0 || (size_t)nret >= sizeof(path)) { ++ ERROR("Path is too long"); ++ return false; ++ } ++ 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) ++{ ++ 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"); ++ ++ 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) && ++ cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_CPUSET_MEMS); ++ common_cgroup_do_log(quiet, !(cpusetinfo->cpuset), "Your kernel does not support cpuset"); ++ if (cpusetinfo->cpuset) { ++ cpusetinfo->cpus = util_read_content_from_file(CGROUP2_CPUSET_CPUS_EFFECTIVE_PATH); ++ cpusetinfo->mems = util_read_content_from_file(CGROUP2_CPUSET_MEMS_EFFECTIVE_PATH); ++ if (cpusetinfo->cpus == NULL || cpusetinfo->mems == NULL) { ++ ERROR("read cpus or mems failed"); ++ return -1; ++ } ++ cpusetinfo->cpus = util_trim_space(cpusetinfo->cpus); ++ cpusetinfo->mems = util_trim_space(cpusetinfo->mems); ++ } ++ ++ // io cgroup ++ 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; ++ common_cgroup_do_log(quiet, !(blkioinfo->blkio_weight), "Your kernel does not support cgroup2 io weight"); ++ ++ blkioinfo->blkio_read_bps_device = cgroup_v2_enabled(CGROUP_ISULAD_PATH, CGROUP2_IO_MAX); ++ blkioinfo->blkio_write_bps_device = blkioinfo->blkio_read_bps_device; ++ 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"); ++ ++ // hugetlb cgroup ++ size = get_default_huge_page_size(); ++ if (size != NULL) { ++ nret = snprintf(path, sizeof(path), CGROUP2_HUGETLB_MAX, size); ++ if (nret < 0 || (size_t)nret >= sizeof(path)) { ++ WARN("Failed to print hugetlb path"); ++ return -1; ++ } ++ hugetlbinfo->hugetlblimit = cgroup_v2_enabled(CGROUP_ISULAD_PATH, path); ++ common_cgroup_do_log(quiet, !hugetlbinfo->hugetlblimit, "Your kernel does not support cgroup2 hugetlb limit"); ++ } else { ++ WARN("Your kernel does not support cgroup2 hugetlb limit"); ++ } ++ ++ // files cgroup ++ 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) ++{ ++ if (cgroup_path == NULL || strlen(cgroup_path) == 0 || cgroup_metrics == NULL) { ++ ERROR("Invalid arguments"); ++ return -1; ++ } ++ ++ get_cgroup_v2_metrics_cpu(cgroup_path, &cgroup_metrics->cgcpu_metrics); ++ get_cgroup_v2_metrics_memory(cgroup_path, &cgroup_metrics->cgmem_metrics); ++ get_cgroup_v2_metrics_pid(cgroup_path, &cgroup_metrics->cgpids_metrics); ++ ++ return 0; ++} +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 76fa17bc..3bdc3af8 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 +@@ -881,7 +881,7 @@ void PodSandboxManagerService::GetPodSandboxCgroupMetrics(const std::string &cgr + if (cgroupVersion == CGROUP_VERSION_1) { + nret = common_get_cgroup_v1_metrics(cgroupParent.c_str(), &cgroupMetrics); + } else { +- // todo: get cgroup v2 metrics ++ nret = common_get_cgroup_v2_metrics(cgroupParent.c_str(), &cgroupMetrics); + } + + if (nret != 0) { +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 4d1d19eb..49a7ca54 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 +@@ -1337,7 +1337,7 @@ void PodSandboxManagerService::GetPodSandboxCgroupMetrics(const container_inspec + if (cgroupVersion == CGROUP_VERSION_1) { + nret = common_get_cgroup_v1_metrics(cgroupParent, &cgroupMetrics); + } else { +- // todo: get cgroup v2 metrics ++ nret = common_get_cgroup_v2_metrics(cgroupParent, &cgroupMetrics); + } + + if (nret != 0) { +diff --git a/src/utils/cutils/utils_array.h b/src/utils/cutils/utils_array.h +index 64f41496..1c084595 100644 +--- a/src/utils/cutils/utils_array.h ++++ b/src/utils/cutils/utils_array.h +@@ -18,6 +18,7 @@ + + #include <stdbool.h> + #include <stddef.h> ++#include <isula_libutils/auto_cleanup.h> + + #ifdef __cplusplus + extern "C" { +@@ -57,6 +58,11 @@ void util_free_sensitive_array(char **array); + + void util_free_sensitive_array_by_len(char **array, size_t len); + ++// define auto free function callback for char * ++define_auto_cleanup_callback(util_free_array, char *); ++// define auto free macro for char * ++#define __isula_auto_array_t auto_cleanup_tag(util_free_array) ++ + #ifdef __cplusplus + } + #endif +-- +2.34.1 + |