From 7c7cd82619ed1f7e36d34da1afc2b417a90b3040 Mon Sep 17 00:00:00 2001 From: zhongtao 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 --- 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 +#include +#include + +#include + +#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 #include +#include #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