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..0db5ef4 --- /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 +Date: Tue, 23 Jan 2024 17:18:51 +0800 +Subject: [PATCH 27/34] =?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.25.1 + diff --git a/0028-use-supervisor-to-notify-sandbox-exit-event.patch b/0028-use-supervisor-to-notify-sandbox-exit-event.patch new file mode 100644 index 0000000..e139bbb --- /dev/null +++ b/0028-use-supervisor-to-notify-sandbox-exit-event.patch @@ -0,0 +1,254 @@ +From 835185f7c4739993c2ca26d737bb0a45277ad932 Mon Sep 17 00:00:00 2001 +From: jikai +Date: Wed, 20 Mar 2024 15:48:42 +0800 +Subject: [PATCH 28/34] use supervisor to notify sandbox exit event + +Signed-off-by: jikai +--- + src/daemon/modules/api/container_api.h | 2 +- + .../modules/container/restore/restore.c | 6 +++- + .../modules/container/supervisor/supervisor.c | 15 +++++++- + .../modules/service/service_container.c | 9 +++-- + .../controller/shim/shim_controller.cc | 35 ++----------------- + src/daemon/sandbox/sandbox_ops.cc | 23 ++++++++++++ + src/daemon/sandbox/sandbox_ops.h | 2 ++ + 7 files changed, 53 insertions(+), 39 deletions(-) + +diff --git a/src/daemon/modules/api/container_api.h b/src/daemon/modules/api/container_api.h +index 4602d244..43d66d64 100644 +--- a/src/daemon/modules/api/container_api.h ++++ b/src/daemon/modules/api/container_api.h +@@ -270,7 +270,7 @@ bool container_is_valid_state_string(const char *state); + void container_update_health_monitor(const char *container_id); + + extern int container_supervisor_add_exit_monitor(int fd, const pid_ppid_info_t *pid_info, const char *name, +- const char *runtime); ++ const char *runtime, bool sandbox_container); + + extern char *container_exit_fifo_create(const char *cont_state_path); + +diff --git a/src/daemon/modules/container/restore/restore.c b/src/daemon/modules/container/restore/restore.c +index 2669ea22..76868e28 100644 +--- a/src/daemon/modules/container/restore/restore.c ++++ b/src/daemon/modules/container/restore/restore.c +@@ -57,6 +57,7 @@ static int restore_supervisor(const container_t *cont) + char *statepath = cont->state_path; + char *runtime = cont->runtime; + pid_ppid_info_t pid_info = { 0 }; ++ bool sandbox_container = false; + + nret = snprintf(container_state, sizeof(container_state), "%s/%s", statepath, id); + if (nret < 0 || (size_t)nret >= sizeof(container_state)) { +@@ -90,8 +91,11 @@ static int restore_supervisor(const container_t *cont) + pid_info.ppid = cont->state->state->p_pid; + pid_info.start_time = cont->state->state->start_time; + pid_info.pstart_time = cont->state->state->p_start_time; ++#ifdef ENABLE_CRI_API_V1 ++ sandbox_container = is_sandbox_container(cont->common_config->sandbox_info); ++#endif + +- if (container_supervisor_add_exit_monitor(exit_fifo_fd, &pid_info, id, runtime)) { ++ if (container_supervisor_add_exit_monitor(exit_fifo_fd, &pid_info, id, runtime, sandbox_container)) { + ERROR("Failed to add exit monitor to supervisor"); + ret = -1; + goto out; +diff --git a/src/daemon/modules/container/supervisor/supervisor.c b/src/daemon/modules/container/supervisor/supervisor.c +index 1f9a043c..63289283 100644 +--- a/src/daemon/modules/container/supervisor/supervisor.c ++++ b/src/daemon/modules/container/supervisor/supervisor.c +@@ -38,6 +38,9 @@ + #include "container_api.h" + #include "event_type.h" + #include "utils_file.h" ++#ifdef ENABLE_CRI_API_V1 ++#include "sandbox_ops.h" ++#endif + + pthread_mutex_t g_supervisor_lock = PTHREAD_MUTEX_INITIALIZER; + struct epoll_descr g_supervisor_descr; +@@ -47,6 +50,7 @@ struct supervisor_handler_data { + int exit_code; + char *name; + char *runtime; ++ bool is_sandbox_container; + pid_ppid_info_t pid_info; + }; + +@@ -211,6 +215,14 @@ retry: + + (void)isulad_monitor_send_container_event(name, STOPPED, (int)pid, data->exit_code, NULL, NULL); + ++#ifdef ENABLE_CRI_API_V1 ++ if (data->is_sandbox_container) { ++ if (sandbox_on_sandbox_exit(name, data->exit_code) < 0) { ++ ERROR("Failed to handle sandbox %s exit", name); ++ } ++ } ++#endif ++ + supervisor_handler_data_free(data); + + DAEMON_CLEAR_ERRMSG(); +@@ -259,7 +271,7 @@ static int supervisor_exit_cb(int fd, uint32_t events, void *cbdata, struct epol + + /* supervisor add exit monitor */ + int container_supervisor_add_exit_monitor(int fd, const pid_ppid_info_t *pid_info, const char *name, +- const char *runtime) ++ const char *runtime, bool sandbox_container) + { + int ret = 0; + struct supervisor_handler_data *data = NULL; +@@ -285,6 +297,7 @@ int container_supervisor_add_exit_monitor(int fd, const pid_ppid_info_t *pid_inf + data->fd = fd; + data->name = util_strdup_s(name); + data->runtime = util_strdup_s(runtime); ++ data->is_sandbox_container = sandbox_container; + data->pid_info.pid = pid_info->pid; + data->pid_info.start_time = pid_info->start_time; + data->pid_info.ppid = pid_info->ppid; +diff --git a/src/daemon/modules/service/service_container.c b/src/daemon/modules/service/service_container.c +index a3606a82..7b34cc7f 100644 +--- a/src/daemon/modules/service/service_container.c ++++ b/src/daemon/modules/service/service_container.c +@@ -275,13 +275,14 @@ static void clean_resources_on_failure(const container_t *cont, const char *engi + return; + } + +-static int do_post_start_on_success(const char *id, const char *runtime, const char *pidfile, int exit_fifo_fd, ++static int do_post_start_on_success(const char *id, const char *runtime, bool sandbox_container, ++ const char *pidfile, int exit_fifo_fd, + const pid_ppid_info_t *pid_info) + { + int ret = 0; + + // exit_fifo_fd was closed in container_supervisor_add_exit_monitor +- if (container_supervisor_add_exit_monitor(exit_fifo_fd, pid_info, id, runtime)) { ++ if (container_supervisor_add_exit_monitor(exit_fifo_fd, pid_info, id, runtime, sandbox_container)) { + ERROR("Failed to add exit monitor to supervisor"); + ret = -1; + } +@@ -749,6 +750,7 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo + oci_runtime_spec *oci_spec = NULL; + rt_create_params_t create_params = { 0 }; + rt_start_params_t start_params = { 0 }; ++ bool sandbox_container; + + nret = snprintf(bundle, sizeof(bundle), "%s/%s", cont->root_path, id); + if (nret < 0 || (size_t)nret >= sizeof(bundle)) { +@@ -897,6 +899,7 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo + if (cont->common_config->sandbox_info != NULL) { + create_params.task_addr = cont->common_config->sandbox_info->task_address; + } ++ sandbox_container = is_sandbox_container(cont->common_config->sandbox_info); + #endif + + if (runtime_create(id, runtime, &create_params) != 0) { +@@ -921,7 +924,7 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo + + ret = runtime_start(id, runtime, &start_params, pid_info); + if (ret == 0) { +- if (do_post_start_on_success(id, runtime, pidfile, exit_fifo_fd, pid_info) != 0) { ++ if (do_post_start_on_success(id, runtime, sandbox_container, pidfile, exit_fifo_fd, pid_info) != 0) { + ERROR("Failed to do post start on runtime start success"); + ret = -1; + goto clean_resources; +diff --git a/src/daemon/sandbox/controller/shim/shim_controller.cc b/src/daemon/sandbox/controller/shim/shim_controller.cc +index 39fcf8ea..593fade9 100644 +--- a/src/daemon/sandbox/controller/shim/shim_controller.cc ++++ b/src/daemon/sandbox/controller/shim/shim_controller.cc +@@ -397,39 +397,8 @@ bool ShimController::Stop(const std::string &sandboxId, uint32_t timeoutSecs, Er + + bool ShimController::Wait(std::shared_ptr cb, const std::string &sandboxId, Errors &error) + { +- std::thread([this, cb, sandboxId]() { +- if (m_cb == nullptr || m_cb->container.wait == nullptr) { +- ERROR("Unimplemented callback"); +- return; +- } +- +- auto requestWrapper = makeUniquePtrCStructWrapper(free_container_wait_request); +- if (requestWrapper == nullptr) { +- ERROR("Out of memory"); +- return; +- } +- auto request = requestWrapper->get(); +- request->id = isula_strdup_s(sandboxId.c_str()); +- request->condition = WAIT_CONDITION_STOPPED; +- container_wait_response *response { nullptr }; +- +- int ret = m_cb->container.wait(request, &response); +- auto responseWrapper = makeUniquePtrCStructWrapper(response, free_container_wait_response); +- +- if (ret != 0) { +- std::string msg = (response != nullptr && response->errmsg != nullptr) ? response->errmsg : "internal"; +- ERROR("Failed to wait sandbox %s: %s", sandboxId.c_str(), msg.c_str()); +- return; +- } +- +- ControllerExitInfo info; +- auto currentTime = std::chrono::high_resolution_clock::now(); +- auto duration = currentTime.time_since_epoch(); +- info.exitedAt = std::chrono::duration_cast(duration).count(); +- info.exitStatus = response->exit_code; +- cb->OnSandboxExit(info); +- }).detach(); +- ++ // ShimController will use sandbox_on_exit callback of supervisor in lower container level ++ // to notify the sandbox exit event + return true; + } + +diff --git a/src/daemon/sandbox/sandbox_ops.cc b/src/daemon/sandbox/sandbox_ops.cc +index 005063c0..b7fb40bf 100644 +--- a/src/daemon/sandbox/sandbox_ops.cc ++++ b/src/daemon/sandbox/sandbox_ops.cc +@@ -18,6 +18,7 @@ + #include + + #include "controller_manager.h" ++#include "sandbox_manager.h" + #include "namespace.h" + #include "utils.h" + +@@ -175,3 +176,25 @@ int sandbox_purge_exec(const container_config_v2_common_config *config, const ch + { + return do_sandbox_purge(config, exec_id); + } ++ ++int sandbox_on_sandbox_exit(const char *sandbox_id, int exit_code) ++{ ++ if (nullptr == sandbox_id) { ++ ERROR("Invalid parameter: sandbox_id"); ++ return -1; ++ } ++ ++ auto sandbox = sandbox::SandboxManager::GetInstance()->GetSandbox(sandbox_id); ++ if (nullptr == sandbox) { ++ ERROR("Sandbox %s not found", sandbox_id); ++ return -1; ++ } ++ ++ sandbox::ControllerExitInfo info; ++ auto currentTime = std::chrono::high_resolution_clock::now(); ++ auto duration = currentTime.time_since_epoch(); ++ info.exitedAt = std::chrono::duration_cast(duration).count(); ++ info.exitStatus = exit_code; ++ sandbox->OnSandboxExit(info); ++ return 0; ++} +diff --git a/src/daemon/sandbox/sandbox_ops.h b/src/daemon/sandbox/sandbox_ops.h +index bef884fb..8189efd6 100644 +--- a/src/daemon/sandbox/sandbox_ops.h ++++ b/src/daemon/sandbox/sandbox_ops.h +@@ -36,6 +36,8 @@ int sandbox_purge_container(const container_config_v2_common_config *config); + + int sandbox_purge_exec(const container_config_v2_common_config *config, const char *exec_id); + ++int sandbox_on_sandbox_exit(const char *sandbox_id, int exit_code); ++ + #ifdef __cplusplus + } + #endif +-- +2.25.1 + diff --git a/0029-refactor-cgroup-module.patch b/0029-refactor-cgroup-module.patch new file mode 100644 index 0000000..2b93c7b --- /dev/null +++ b/0029-refactor-cgroup-module.patch @@ -0,0 +1,2538 @@ +From c26604ff3150babae729890c549f2784212073a1 Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 20 Mar 2024 15:53:56 +0800 +Subject: [PATCH 29/34] refactor cgroup module + +Signed-off-by: zhongtao +--- + 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 +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 ++#include ++#include ++ ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 + #include +@@ -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 + + #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.25.1 + diff --git a/0030-adaptor-unit-test-for-cgroup-module.patch b/0030-adaptor-unit-test-for-cgroup-module.patch new file mode 100644 index 0000000..3a816ad --- /dev/null +++ b/0030-adaptor-unit-test-for-cgroup-module.patch @@ -0,0 +1,351 @@ +From 59e7ea0f16e83e0bdbc39bdc41d1ade8d3db885e Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Thu, 22 Feb 2024 09:52:30 +0800 +Subject: [PATCH 30/34] adaptor unit test for cgroup module + +Signed-off-by: zhongtao +--- + src/daemon/modules/image/CMakeLists.txt | 6 ++++-- + test/cgroup/cpu/CMakeLists.txt | 7 +++++-- + test/cgroup/cpu/cgroup_cpu_ut.cc | 12 ++++++++++-- + test/image/oci/oci_config_merge/CMakeLists.txt | 7 +++++-- + test/image/oci/registry/CMakeLists.txt | 7 +++++-- + test/network/network_ns/CMakeLists.txt | 7 +++++-- + test/runtime/isula/CMakeLists.txt | 7 +++++-- + test/runtime/lcr/CMakeLists.txt | 7 +++++-- + .../execute/execution_extend/CMakeLists.txt | 6 +++++- + test/specs/specs/CMakeLists.txt | 7 +++++-- + test/specs/specs_extend/CMakeLists.txt | 7 +++++-- + test/specs/verify/CMakeLists.txt | 7 +++++-- + test/volume/CMakeLists.txt | 7 +++++-- + 13 files changed, 69 insertions(+), 25 deletions(-) + +diff --git a/src/daemon/modules/image/CMakeLists.txt b/src/daemon/modules/image/CMakeLists.txt +index f8bc5840..d8b78ce1 100644 +--- a/src/daemon/modules/image/CMakeLists.txt ++++ b/src/daemon/modules/image/CMakeLists.txt +@@ -68,8 +68,9 @@ set(LIB_ISULAD_IMG_SRCS + ${CMAKE_SOURCE_DIR}/src/utils/buffer/buffer.c + ${CMAKE_SOURCE_DIR}/src/daemon/common/err_msg.c + ${CMAKE_SOURCE_DIR}/src/daemon/common/sysinfo.c +- ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup.c +- ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup_v1.c ++ ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup/cgroup_v2.c + ${CMAKE_SOURCE_DIR}/src/utils/tar/util_gzip.c + ${CMAKE_SOURCE_DIR}/src/daemon/config/isulad_config.c + ${CMAKE_SOURCE_DIR}/src/daemon/config/daemon_arguments.c +@@ -102,6 +103,7 @@ target_include_directories(${LIB_ISULAD_IMG} PUBLIC + ${CMAKE_SOURCE_DIR}/src/utils/tar + ${CMAKE_SOURCE_DIR}/src/daemon/config + ${CMAKE_SOURCE_DIR}/src/daemon/common ++ ${CMAKE_SOURCE_DIR}/src/daemon/common/cgroup + ${CMAKE_SOURCE_DIR}/src/daemon/modules/spec/ + ${CMAKE_SOURCE_DIR}/src/utils/cutils + ${CMAKE_SOURCE_DIR}/src/utils/cutils/map +diff --git a/test/cgroup/cpu/CMakeLists.txt b/test/cgroup/cpu/CMakeLists.txt +index 32fe0a23..30bfc417 100644 +--- a/test/cgroup/cpu/CMakeLists.txt ++++ b/test/cgroup/cpu/CMakeLists.txt +@@ -6,8 +6,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/isulad_config.c +@@ -20,6 +22,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/common + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_BINARY_DIR}/conf + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd +diff --git a/test/cgroup/cpu/cgroup_cpu_ut.cc b/test/cgroup/cpu/cgroup_cpu_ut.cc +index eaee90c0..6e6e04f4 100644 +--- a/test/cgroup/cpu/cgroup_cpu_ut.cc ++++ b/test/cgroup/cpu/cgroup_cpu_ut.cc +@@ -69,13 +69,21 @@ TEST(CgroupCpuUnitTest, test_common_find_cgroup_mnt_and_root) + { + char *mnt = NULL; + char *root = NULL; +- ASSERT_EQ(common_find_cgroup_mnt_and_root(nullptr, &mnt, &root), -1); ++ ++ int ret = cgroup_ops_init(); ++ ASSERT_EQ(ret, 0); ++ ++ ASSERT_EQ(common_get_cgroup_mnt_and_root_path(nullptr, &mnt, &root), -1); + } + + TEST(CgroupCpuUnitTest, test_sysinfo_cgroup_controller_cpurt_mnt_path) + { + MOCK_SET(util_common_calloc_s, nullptr); + ASSERT_EQ(get_sys_info(true), nullptr); +- ASSERT_EQ(sysinfo_cgroup_controller_cpurt_mnt_path(), nullptr); ++ ++ int ret = cgroup_ops_init(); ++ ASSERT_EQ(ret, 0); ++ ++ ASSERT_EQ(sysinfo_get_cpurt_mnt_path(), nullptr); + MOCK_CLEAR(util_common_calloc_s); + } +diff --git a/test/image/oci/oci_config_merge/CMakeLists.txt b/test/image/oci/oci_config_merge/CMakeLists.txt +index 90809080..d13ec738 100644 +--- a/test/image/oci/oci_config_merge/CMakeLists.txt ++++ b/test/image/oci/oci_config_merge/CMakeLists.txt +@@ -25,8 +25,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config/isulad_config.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/image/oci/oci_ut_common.cc +@@ -55,6 +57,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/volume + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/runtime/engines +diff --git a/test/image/oci/registry/CMakeLists.txt b/test/image/oci/registry/CMakeLists.txt +index 77a7907e..5b5bc3f5 100644 +--- a/test/image/oci/registry/CMakeLists.txt ++++ b/test/image/oci/registry/CMakeLists.txt +@@ -26,8 +26,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/image_store/image_type.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry_type.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/image_store/image_store.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/registry.c +@@ -58,6 +60,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/image_store +diff --git a/test/network/network_ns/CMakeLists.txt b/test/network/network_ns/CMakeLists.txt +index 50520427..71b8039d 100644 +--- a/test/network/network_ns/CMakeLists.txt ++++ b/test/network/network_ns/CMakeLists.txt +@@ -30,8 +30,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/mocks/image_mock.cc +@@ -55,6 +57,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/options + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/volume + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/runtime +diff --git a/test/runtime/isula/CMakeLists.txt b/test/runtime/isula/CMakeLists.txt +index cc1178b8..c1f0a5cc 100644 +--- a/test/runtime/isula/CMakeLists.txt ++++ b/test/runtime/isula/CMakeLists.txt +@@ -21,8 +21,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/mainloop.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc +@@ -51,6 +53,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container/restart_manager + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container/health_check +diff --git a/test/runtime/lcr/CMakeLists.txt b/test/runtime/lcr/CMakeLists.txt +index 424a6101..c3b93d67 100644 +--- a/test/runtime/lcr/CMakeLists.txt ++++ b/test/runtime/lcr/CMakeLists.txt +@@ -18,8 +18,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/rb_tree.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc +@@ -39,6 +41,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container/restart_manager +diff --git a/test/services/execution/execute/execution_extend/CMakeLists.txt b/test/services/execution/execute/execution_extend/CMakeLists.txt +index 68e0f443..f0875fd7 100644 +--- a/test/services/execution/execute/execution_extend/CMakeLists.txt ++++ b/test/services/execution/execute/execution_extend/CMakeLists.txt +@@ -21,7 +21,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/mainloop.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/filters.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/events_sender/event_sender.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console/console.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils.c +@@ -59,6 +62,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/console + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image +diff --git a/test/specs/specs/CMakeLists.txt b/test/specs/specs/CMakeLists.txt +index 508123fa..45f688f9 100644 +--- a/test/specs/specs/CMakeLists.txt ++++ b/test/specs/specs/CMakeLists.txt +@@ -28,8 +28,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/spec/specs_security.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc +@@ -54,6 +56,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/isulad + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/volume + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/runtime +diff --git a/test/specs/specs_extend/CMakeLists.txt b/test/specs/specs_extend/CMakeLists.txt +index bf4b378e..1b737089 100644 +--- a/test/specs/specs_extend/CMakeLists.txt ++++ b/test/specs/specs_extend/CMakeLists.txt +@@ -28,8 +28,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/spec/specs_security.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/command_parser.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/daemon_arguments.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc +@@ -54,6 +56,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/isulad + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/volume + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/container +diff --git a/test/specs/verify/CMakeLists.txt b/test/specs/verify/CMakeLists.txt +index 0e60a39e..b0602127 100644 +--- a/test/specs/verify/CMakeLists.txt ++++ b/test/specs/verify/CMakeLists.txt +@@ -23,8 +23,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/rb_tree.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/spec/verify.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/image/oci/oci_ut_common.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/mocks/containers_store_mock.cc +@@ -50,6 +52,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/cmd/isulad + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/volume + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/modules/runtime +diff --git a/test/volume/CMakeLists.txt b/test/volume/CMakeLists.txt +index cc309352..27d07330 100644 +--- a/test/volume/CMakeLists.txt ++++ b/test/volume/CMakeLists.txt +@@ -20,8 +20,10 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/utils/sha256/sha256.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/err_msg.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/sysinfo.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup.c +- ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup/cgroup.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup/cgroup_v1.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup/cgroup_v2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup/cgroup_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/cmd/command_parser.c + volume_ut.cc) + +@@ -34,6 +36,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/utils/http + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/modules/api + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/common/cgroup + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/daemon/modules/volume + ${CMAKE_BINARY_DIR}/conf + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/utils/sha256 +-- +2.25.1 + diff --git a/0031-cgroup-v2-does-not-support-isulad-setting-cpu_rt-opt.patch b/0031-cgroup-v2-does-not-support-isulad-setting-cpu_rt-opt.patch new file mode 100644 index 0000000..ba3a9a5 --- /dev/null +++ b/0031-cgroup-v2-does-not-support-isulad-setting-cpu_rt-opt.patch @@ -0,0 +1,71 @@ +From 8e11a1eea62cb8061f1613379ff83bd9a721fa50 Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 31 Jan 2024 18:10:46 +0800 +Subject: [PATCH 31/34] cgroup v2 does not support isulad setting cpu_rt + options + +Signed-off-by: zhongtao +--- + src/cmd/isulad/isulad_commands.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/cmd/isulad/isulad_commands.c b/src/cmd/isulad/isulad_commands.c +index 5fb55689..619e36d1 100644 +--- a/src/cmd/isulad/isulad_commands.c ++++ b/src/cmd/isulad/isulad_commands.c +@@ -34,6 +34,7 @@ + #include "utils_verify.h" + #include "opt_ulimit.h" + #include "opt_log.h" ++#include "sysinfo.h" + + const char isulad_desc[] = "GLOBAL OPTIONS:"; + const char isulad_usage[] = "[global options]"; +@@ -411,6 +412,33 @@ out: + return ret; + } + ++static int check_args_cpu_rt(const struct service_arguments *args) ++{ ++ int ret = 0; ++ __isula_auto_sysinfo_t sysinfo_t *sysinfo = NULL; ++ ++ sysinfo = get_sys_info(true); ++ if (sysinfo == NULL) { ++ COMMAND_ERROR("Failed to get system info"); ++ ERROR("Failed to get system info"); ++ return -1; ++ } ++ ++ if (!(sysinfo->cgcpuinfo.cpu_rt_period) && args->json_confs->cpu_rt_period != 0) { ++ COMMAND_ERROR("Invalid --cpu-rt-period: Your kernel does not support cgroup rt period"); ++ ERROR("Invalid --cpu-rt-period: Your kernel does not support cgroup rt period"); ++ return -1; ++ } ++ ++ if (!(sysinfo->cgcpuinfo.cpu_rt_runtime) && args->json_confs->cpu_rt_runtime != 0) { ++ COMMAND_ERROR("Invalid --cpu-rt-runtime: Your kernel does not support cgroup rt runtime"); ++ ERROR("Invalid --cpu-rt-runtime: Your kernel does not support cgroup rt runtime"); ++ return -1; ++ } ++ ++ return ret; ++} ++ + int check_args(struct service_arguments *args) + { + int ret = 0; +@@ -471,6 +499,10 @@ int check_args(struct service_arguments *args) + goto out; + } + ++ if (check_args_cpu_rt(args) != 0) { ++ ret = -1; ++ goto out; ++ } + out: + return ret; + } +-- +2.25.1 + diff --git a/0032-add-test-that-isulad-cannot-set-cpu_rt-parameters-wh.patch b/0032-add-test-that-isulad-cannot-set-cpu_rt-parameters-wh.patch new file mode 100644 index 0000000..f059de1 --- /dev/null +++ b/0032-add-test-that-isulad-cannot-set-cpu_rt-parameters-wh.patch @@ -0,0 +1,30 @@ +From 1ab0f4608fb749b50aa6f8d8188db23aa8a6e1ac Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Thu, 1 Feb 2024 10:48:45 +0800 +Subject: [PATCH 32/34] add test that isulad cannot set cpu_rt parameters when + adding cgroup v2 + +Signed-off-by: zhongtao +--- + CI/test_cases/container_cases/cpu_rt.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/CI/test_cases/container_cases/cpu_rt.sh b/CI/test_cases/container_cases/cpu_rt.sh +index bdc43a5e..23d3baed 100755 +--- a/CI/test_cases/container_cases/cpu_rt.sh ++++ b/CI/test_cases/container_cases/cpu_rt.sh +@@ -106,7 +106,10 @@ function test_kernel_without_cpurt() + + msg_info "${test} starting..." + +- start_isulad_without_valgrind --cpu-rt-period 1000000 --cpu-rt-runtime 950000 ++ isulad --cpu-rt-period 1000000 --cpu-rt-runtime 950000 2>&1 | grep 'Your kernel does not support cgroup rt period' ++ [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - kernel does not support cpu-rt, but start isulad with cpu-rt success" && ((ret++)) ++ ++ start_isulad_without_valgrind + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} +-- +2.25.1 + diff --git a/0033-fix-sandbox-container-bool-value-uninitialized.patch b/0033-fix-sandbox-container-bool-value-uninitialized.patch new file mode 100644 index 0000000..52ad07d --- /dev/null +++ b/0033-fix-sandbox-container-bool-value-uninitialized.patch @@ -0,0 +1,26 @@ +From f62df3dedbbe11bb56e6da7dd610c573fd3ed828 Mon Sep 17 00:00:00 2001 +From: jikai +Date: Mon, 25 Mar 2024 10:01:56 +0800 +Subject: [PATCH 33/34] fix sandbox container bool value uninitialized + +Signed-off-by: jikai +--- + src/daemon/modules/service/service_container.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/daemon/modules/service/service_container.c b/src/daemon/modules/service/service_container.c +index 7b34cc7f..a8090d5a 100644 +--- a/src/daemon/modules/service/service_container.c ++++ b/src/daemon/modules/service/service_container.c +@@ -750,7 +750,7 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo + oci_runtime_spec *oci_spec = NULL; + rt_create_params_t create_params = { 0 }; + rt_start_params_t start_params = { 0 }; +- bool sandbox_container; ++ bool sandbox_container = false; + + nret = snprintf(bundle, sizeof(bundle), "%s/%s", cont->root_path, id); + if (nret < 0 || (size_t)nret >= sizeof(bundle)) { +-- +2.25.1 + diff --git a/0034-bugfix-for-cpurt.sh.patch b/0034-bugfix-for-cpurt.sh.patch new file mode 100644 index 0000000..13db455 --- /dev/null +++ b/0034-bugfix-for-cpurt.sh.patch @@ -0,0 +1,47 @@ +From 411483ad9b2a0c50190f9b56779d41889c895014 Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 27 Mar 2024 10:29:11 +0800 +Subject: [PATCH 34/34] bugfix for cpurt.sh + +Signed-off-by: zhongtao +--- + CI/test_cases/container_cases/cpu_rt.sh | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/CI/test_cases/container_cases/cpu_rt.sh b/CI/test_cases/container_cases/cpu_rt.sh +index 23d3baed..64dcd81f 100755 +--- a/CI/test_cases/container_cases/cpu_rt.sh ++++ b/CI/test_cases/container_cases/cpu_rt.sh +@@ -109,7 +109,7 @@ function test_kernel_without_cpurt() + isulad --cpu-rt-period 1000000 --cpu-rt-runtime 950000 2>&1 | grep 'Your kernel does not support cgroup rt period' + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - kernel does not support cpu-rt, but start isulad with cpu-rt success" && ((ret++)) + +- start_isulad_without_valgrind ++ start_isulad_with_valgrind + + isula pull ${image} + [[ $? -ne 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} +@@ -194,6 +194,9 @@ function do_test() + test_cpurt_isulad_abnormal $runtime || ((ret++)) + test_isula_update_normal $runtime || ((ret++)) + test_isula_update_abnormal $runtime || ((ret++)) ++ stop_isulad_without_valgrind ++ # set cpu-rt to the initial state ++ start_isulad_with_valgrind --cpu-rt-period 1000000 --cpu-rt-runtime 0 + else + test_kernel_without_cpurt $runtime || ((ans++)) + fi +@@ -211,10 +214,6 @@ do + + do_test $element || ((ans++)) + +- stop_isulad_without_valgrind +- # set cpu-rt to the initial state +- start_isulad_with_valgrind --cpu-rt-period 1000000 --cpu-rt-runtime 0 +- + isula rm -f $(isula ps -aq) + done + +-- +2.25.1 + diff --git a/iSulad.spec b/iSulad.spec index 4de13be..62d8e8b 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ %global _version 2.1.5 -%global _release 2 +%global _release 3 %global is_systemd 1 %global enable_criv1 1 %global enable_shimv2 1 @@ -41,6 +41,14 @@ Patch0023: 0023-add-benchmark-result-of-perf-test-in-cri.patch Patch0024: 0024-add-support-for-systemd-cgroup-driver.patch Patch0025: 0025-add-ci-cases-for-systemd-cgroup-driver.patch Patch0026: 0026-move-systemd_cgroup-CI-test-to-manual-cases.patch +Patch0027: 0027-feature-add-support-for-cgroup-v2-metrics.patch +Patch0028: 0028-use-supervisor-to-notify-sandbox-exit-event.patch +Patch0029: 0029-refactor-cgroup-module.patch +Patch0030: 0030-adaptor-unit-test-for-cgroup-module.patch +Patch0031: 0031-cgroup-v2-does-not-support-isulad-setting-cpu_rt-opt.patch +Patch0032: 0032-add-test-that-isulad-cannot-set-cpu_rt-parameters-wh.patch +Patch0033: 0033-fix-sandbox-container-bool-value-uninitialized.patch +Patch0034: 0034-bugfix-for-cpurt.sh.patch %ifarch x86_64 aarch64 Provides: libhttpclient.so()(64bit) @@ -295,6 +303,12 @@ fi %endif %changelog +* Sat Mar 30 2024 zhongtao - 2.1.5-3 +- Type: update +- ID: NA +- SUG: NA +- DESC: add support for cgroup v2 + * Tue Mar 19 2024 zhongtao - 2.1.5-2 - Type: update - ID: NA