From 5bc59b709b475d6b8b33018c7bd966a096c54de0 Mon Sep 17 00:00:00 2001 From: Kichan Kwon Date: Sat, 5 Nov 2016 15:01:39 +0900 Subject: common : add cgroup control functions - Getting pid - Getting information about memory.stat - In addition, all cgroup functions will unify prefix Change-Id: I305ba00c5baa8e7962340d03c133cdc75faa3949 Signed-off-by: Kichan Kwon --- src/CMakeLists.txt | 2 + src/common/cgroup-memory-stat-lookup.gperf | 119 +++++++++++++++++ src/common/cgroup.c | 204 +++++++++++++++++++++++++++-- src/common/cgroup.h | 88 ++++++++++++- src/cpu/cpu.c | 4 +- src/memory/vmpressure-lowmem-handler.c | 4 +- src/swap/swap.c | 12 +- src/timer-slack/timer-slack.c | 6 +- src/vip-agent/vip-process.c | 8 +- 9 files changed, 410 insertions(+), 37 deletions(-) create mode 100644 src/common/cgroup-memory-stat-lookup.gperf diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c853a25c..317945a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,9 +15,11 @@ INCLUDE(${CMAKE_SOURCE_DIR}/cmake/InstallSymlink.cmake) INCLUDE(${CMAKE_SOURCE_DIR}/cmake/ProcessGPERF.cmake) PROCESS_GPERF(${COMMON_SOURCE_DIR}/smaps-lookup.gperf ${COMMON_SOURCE_DIR}/smaps-lookup.c) +PROCESS_GPERF(${COMMON_SOURCE_DIR}/cgroup-memory-stat-lookup.gperf ${COMMON_SOURCE_DIR}/cgroup-memory-stat-lookup.c) PROCESS_GPERF(${COMMON_SOURCE_DIR}/meminfo-lookup.gperf ${COMMON_SOURCE_DIR}/meminfo-lookup.c) SET(RESOURCED_SHARED_SOURCES ${RESOURCED_SHARED_SOURCES} ${COMMON_SOURCE_DIR}/smaps-lookup.c + ${COMMON_SOURCE_DIR}/cgroup-memory-stat-lookup.c ${COMMON_SOURCE_DIR}/meminfo-lookup.c ) diff --git a/src/common/cgroup-memory-stat-lookup.gperf b/src/common/cgroup-memory-stat-lookup.gperf new file mode 100644 index 00000000..6522b4b3 --- /dev/null +++ b/src/common/cgroup-memory-stat-lookup.gperf @@ -0,0 +1,119 @@ +%{ +#include +#include + +#include "cgroup.h" + +struct memory_stat_key { + const char* name; + enum cgroup_memory_stat_id id; +}; + +%} +struct memory_stat_key; +%language=C +%define slot-name name +%define hash-function-name cgroup_memory_stat_hash +%define lookup-function-name cgroup_memory_stat_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +cache, CGROUP_MEMORY_STAT_CACHE +rss, CGROUP_MEMORY_STAT_RSS +rss_huge, CGROUP_MEMORY_STAT_RSS_HUGE +mapped_file, CGROUP_MEMORY_STAT_MAPPED_FILE +dirty, CGROUP_MEMORY_STAT_DIRTY +writeback, CGROUP_MEMORY_STAT_WRITEBACK +swap, CGROUP_MEMORY_STAT_SWAP +pgpgin, CGROUP_MEMORY_STAT_PGPGIN +pgpgout, CGROUP_MEMORY_STAT_PGPGOUT +pgfault, CGROUP_MEMORY_STAT_PGFAULT +pgmajfault, CGROUP_MEMORY_STAT_PGMAJFAULT +inactive_anon, CGROUP_MEMORY_STAT_INACTIVE_ANON +active_anon, CGROUP_MEMORY_STAT_ACTIVE_ANON +inactive_file, CGROUP_MEMORY_STAT_INACTIVE_FILE +active_file, CGROUP_MEMORY_STAT_ACTIVE_FILE +unevictable, CGROUP_MEMORY_STAT_UNEVICTABLE +hierarchical_memory_limit, CGROUP_MEMORY_STAT_HIERARCHICAL_MEMORY_LIMIT +hierarchical_memsw_limit, CGROUP_MEMORY_STAT_HIERARCHICAL_MEMSW_LIMIT +total_cache, CGROUP_MEMORY_STAT_TOTAL_CACHE +total_rss, CGROUP_MEMORY_STAT_TOTAL_RSS +total_rss_huge, CGROUP_MEMORY_STAT_TOTAL_RSS_HUGE +total_mapped_file, CGROUP_MEMORY_STAT_TOTAL_MAPPED_FILE +total_dirty, CGROUP_MEMORY_STAT_TOTAL_DIRTY +total_writeback, CGROUP_MEMORY_STAT_TOTAL_WRITEBACK +total_swap, CGROUP_MEMORY_STAT_TOTAL_SWAP +total_pgpgin, CGROUP_MEMORY_STAT_TOTAL_PGPGIN +total_pgpgout, CGROUP_MEMORY_STAT_TOTAL_PGPGOUT +total_pgfault, CGROUP_MEMORY_STAT_TOTAL_PGFAULT +total_pgmajfault, CGROUP_MEMORY_STAT_TOTAL_PGMAJFAULT +total_inactive_anon, CGROUP_MEMORY_STAT_TOTAL_INACTIVE_ANON +total_active_anon, CGROUP_MEMORY_STAT_TOTAL_ACTIVE_ANON +total_inactive_file, CGROUP_MEMORY_STAT_TOTAL_INACTIVE_FILE +total_active_file, CGROUP_MEMORY_STAT_TOTAL_ACTIVE_FILE +total_unevictable, CGROUP_MEMORY_STAT_TOTAL_UNEVICTABLE +recent_rotated_anon, CGROUP_MEMORY_STAT_RECENT_ROTATED_ANON +recent_rotated_file, CGROUP_MEMORY_STAT_RECENT_ROTATED_FILE +recent_scanned_anon, CGROUP_MEMORY_STAT_RECENT_SCANNED_ANON +recent_scanned_file, CGROUP_MEMORY_STAT_RECENT_SCANNED_FILE +%% +static const char* const cgroup_memory_stat_str[CGROUP_MEMORY_STAT_MAX] = { + [CGROUP_MEMORY_STAT_CACHE] = "cache", + [CGROUP_MEMORY_STAT_RSS] = "rss", + [CGROUP_MEMORY_STAT_RSS_HUGE] = "rss_huge", + [CGROUP_MEMORY_STAT_MAPPED_FILE] = "mapped_file", + [CGROUP_MEMORY_STAT_DIRTY] = "dirty", + [CGROUP_MEMORY_STAT_WRITEBACK] = "writeback", + [CGROUP_MEMORY_STAT_SWAP] = "swap", + [CGROUP_MEMORY_STAT_PGPGIN] = "pgpgin", + [CGROUP_MEMORY_STAT_PGPGOUT] = "pgpgout", + [CGROUP_MEMORY_STAT_PGFAULT] = "pgfault", + [CGROUP_MEMORY_STAT_PGMAJFAULT] = "pgmajfault", + [CGROUP_MEMORY_STAT_INACTIVE_ANON] = "inactive_anon", + [CGROUP_MEMORY_STAT_ACTIVE_ANON] = "active_anon", + [CGROUP_MEMORY_STAT_INACTIVE_FILE] = "inactive_file", + [CGROUP_MEMORY_STAT_ACTIVE_FILE] = "active_file", + [CGROUP_MEMORY_STAT_UNEVICTABLE] = "unevictable", + [CGROUP_MEMORY_STAT_HIERARCHICAL_MEMORY_LIMIT] = "hierarchical_memory_limit", + [CGROUP_MEMORY_STAT_HIERARCHICAL_MEMSW_LIMIT] = "hierarchical_memsw_limit", + [CGROUP_MEMORY_STAT_TOTAL_CACHE] = "total_cache", + [CGROUP_MEMORY_STAT_TOTAL_RSS] = "total_rss", + [CGROUP_MEMORY_STAT_TOTAL_RSS_HUGE] = "total_rss_huge", + [CGROUP_MEMORY_STAT_TOTAL_MAPPED_FILE] = "total_mapped_file", + [CGROUP_MEMORY_STAT_TOTAL_DIRTY] = "total_dirty", + [CGROUP_MEMORY_STAT_TOTAL_WRITEBACK] = "total_writeback", + [CGROUP_MEMORY_STAT_TOTAL_SWAP] = "total_swap", + [CGROUP_MEMORY_STAT_TOTAL_PGPGIN] = "total_pgpgin", + [CGROUP_MEMORY_STAT_TOTAL_PGPGOUT] = "total_pgpgout", + [CGROUP_MEMORY_STAT_TOTAL_PGFAULT] = "total_pgfault", + [CGROUP_MEMORY_STAT_TOTAL_PGMAJFAULT] = "total_pgmajfault", + [CGROUP_MEMORY_STAT_TOTAL_INACTIVE_ANON] = "total_inactive_anon", + [CGROUP_MEMORY_STAT_TOTAL_ACTIVE_ANON] = "total_active_anon", + [CGROUP_MEMORY_STAT_TOTAL_INACTIVE_FILE] = "total_inactive_file", + [CGROUP_MEMORY_STAT_TOTAL_ACTIVE_FILE] = "total_active_file", + [CGROUP_MEMORY_STAT_TOTAL_UNEVICTABLE] = "total_unevictable", + [CGROUP_MEMORY_STAT_RECENT_ROTATED_ANON] = "recent_rotated_anon", + [CGROUP_MEMORY_STAT_RECENT_ROTATED_FILE] = "recent_rotated_file", + [CGROUP_MEMORY_STAT_RECENT_SCANNED_ANON] = "recent_scanned_anon", + [CGROUP_MEMORY_STAT_RECENT_SCANNED_FILE] = "recent_scanned_file" +}; + +const char *cgroup_memory_stat_id_to_string(enum cgroup_memory_stat_id id) +{ + assert(id >= 0 && id < CGROUP_MEMORY_STAT_MAX); + + return cgroup_memory_stat_str[id]; +} + +enum cgroup_memory_stat_id cgroup_memory_stat_string_to_id(const char *str) +{ + const struct memory_stat_key *k; + + assert(str); + + k = cgroup_memory_stat_lookup(str, strlen(str)); + + return k ? k->id : CGROUP_MEMORY_STAT_INVALID; +} diff --git a/src/common/cgroup.c b/src/common/cgroup.c index 90e869ce..180a5c8d 100644 --- a/src/common/cgroup.c +++ b/src/common/cgroup.c @@ -46,13 +46,13 @@ #define RELEASE_AGENT "/release_agent" #define NOTIFY_ON_RELEASE "/notify_on_release" -static bool is_cgroup_exists(const char *cgroup_full_path) +static bool cgroup_is_exists(const char *cgroup_full_path) { struct stat stat_buf; return stat(cgroup_full_path, &stat_buf) == 0; } -static int create_cgroup(const char *cgroup_full_path) +static int cgroup_create(const char *cgroup_full_path) { if (mkdir(cgroup_full_path, S_IRUSR | S_IWUSR | S_IRGRP) < 0) @@ -65,7 +65,7 @@ static int create_cgroup(const char *cgroup_full_path) * @desc place pid to cgroup.procs file * @return 0 in case of success, errno value in case of failure */ -resourced_ret_c place_pid_to_cgroup_by_fullpath(const char *cgroup_full_path, +resourced_ret_c cgroup_write_pid_fullpath(const char *cgroup_full_path, const int pid) { char buf[256]; @@ -78,15 +78,15 @@ resourced_ret_c place_pid_to_cgroup_by_fullpath(const char *cgroup_full_path, return RESOURCED_ERROR_NONE; } -resourced_ret_c place_pid_to_cgroup(const char *cgroup_subsystem, +resourced_ret_c cgroup_write_pid(const char *cgroup_subsystem, const char *cgroup_name, const int pid) { char buf[MAX_PATH_LENGTH]; snprintf(buf, sizeof(buf), "%s/%s", cgroup_subsystem, cgroup_name); - return place_pid_to_cgroup_by_fullpath(buf, pid); + return cgroup_write_pid_fullpath(buf, pid); } -resourced_ret_c place_pidtree_to_cgroup(const char *cgroup_subsystem, +resourced_ret_c cgroup_write_pidtree(const char *cgroup_subsystem, const char *cgroup_name, const int pid) { char buf[MAX_PATH_LENGTH]; @@ -100,7 +100,7 @@ resourced_ret_c place_pidtree_to_cgroup(const char *cgroup_subsystem, snprintf(buf, sizeof(buf), "%s/%s", cgroup_subsystem, cgroup_name); /* place parent */ - ret = place_pid_to_cgroup_by_fullpath(buf, pid); + ret = cgroup_write_pid_fullpath(buf, pid); ret_value_msg_if(ret != RESOURCED_ERROR_NONE, ret, "Failed to put parent process %d into %s cgroup", pid, cgroup_name); @@ -115,7 +115,7 @@ resourced_ret_c place_pidtree_to_cgroup(const char *cgroup_subsystem, fclose(f); return RESOURCED_ERROR_FAIL; } - resourced_ret_c ret = place_pid_to_cgroup_by_fullpath(buf, child_pid); + resourced_ret_c ret = cgroup_write_pid_fullpath(buf, child_pid); if (ret != RESOURCED_ERROR_NONE) { _E("Failed to put parent process %d into %s cgroup", pid, cgroup_name); fclose(f); @@ -155,7 +155,7 @@ int cgroup_read_node(const char *cgroup_name, return ret; } -int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *already) +int cgroup_make_subdir(const char* parentdir, const char* cgroup_name, bool *already) { char buf[MAX_PATH_LENGTH]; bool cgroup_exists; @@ -171,7 +171,7 @@ int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *alr ret_value_msg_if(ret > sizeof(buf), RESOURCED_ERROR_FAIL, "Not enought buffer size for %s%s", parentdir, cgroup_name); - cgroup_exists = is_cgroup_exists(buf); + cgroup_exists = cgroup_is_exists(buf); if (!cgroup_exists) { if (!strncmp(parentdir, DEFAULT_CGROUP, sizeof(DEFAULT_CGROUP))) { ret = mount("tmpfs", DEFAULT_CGROUP, "tmpfs", @@ -182,7 +182,7 @@ int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *alr } } - ret = create_cgroup(buf); + ret = cgroup_create(buf); ret_value_msg_if(ret < 0, RESOURCED_ERROR_FAIL, "Fail to create cgroup %s : err %d", cgroup_name, errno); @@ -200,13 +200,13 @@ int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *alr return RESOURCED_ERROR_NONE; } -int mount_cgroup_subsystem(char* source, char* mount_point, char* opts) +int cgroup_mount_subsystem(char* source, char* mount_point, char* opts) { return mount(source, mount_point, "cgroup", MS_NODEV | MS_NOSUID | MS_NOEXEC, opts); } -int set_release_agent(const char *cgroup_subsys, const char *release_agent) +int cgroup_set_release_agent(const char *cgroup_subsys, const char *release_agent) { _cleanup_free_ char *buf = NULL; int r; @@ -221,3 +221,181 @@ int set_release_agent(const char *cgroup_subsys, const char *release_agent) return cgroup_write_node_str(buf, NOTIFY_ON_RELEASE, "1"); } + +int cgroup_pid_get_path(const char *controller, pid_t pid, char **path) +{ + _cleanup_free_ char *pid_cgroup = NULL; + _cleanup_fclose_ FILE *f = NULL; + char buf[LINE_MAX]; + int r; + + assert(controller); + assert(pid >= 0); + assert(path); + + if (pid) + r = asprintf(&pid_cgroup, "/proc/%d/cgroup", pid); + else + r = asprintf(&pid_cgroup, "/proc/self/cgroup"); + if (r < 0) + return -ENOMEM; + + f = fopen(pid_cgroup, "re"); + if (!f) + return -errno; + + for (;;) { + _cleanup_free_ char *subsys = NULL, *p = NULL; + int n, id; + + if (!fgets(buf, sizeof(buf), f)) { + if (ferror(f)) + return -errno; + + return -ENXIO; + } + + n = sscanf(buf, "%d:%m[^:]:%ms", &id, &subsys, &p); + if (n != 3) + continue; + + if ((streq(subsys, controller)) || + (strneq(subsys, "name=", strlen("name=")) && + streq(subsys + strlen("name="), controller))) { + *path = strdup(p); + + if (!*path) + return -ENOMEM; + + break; + } + } + + return 0; +} + +int cgroup_get_pids(const char *name, GArray **pids) +{ + _cleanup_free_ char *cg_procs = NULL; + _cleanup_fclose_ FILE *f = NULL; + char buf[MAX_PATH_LENGTH] = ""; + GArray *array; + pid_t pid; + + assert(name); + assert(pids); + assert(!pids); + + if (asprintf(&cg_procs, "%s/cgroup.procs", name) < 0) + return -ENOMEM; + + f = fopen(cg_procs, "r"); + if (!f) { + _E("Failed to open '%s': %m", name); + return -errno; + } + + array = g_array_new(false, false, sizeof(pid_t)); + + while (fgets(buf, 32, f)) { + pid = atoi(buf); + g_array_append_val(array, pid); + } + + *pids = array; + + return 0; +} + +static void cgroup_memory_stat_init(struct cgroup_memory_stat *mem_stat, long long val) +{ + enum cgroup_memory_stat_id id; + + assert(mem_stat); + + for (id = 0; id < CGROUP_MEMORY_STAT_MAX; id++) + mem_stat->value[id] = val; +} + +int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_stat) +{ + _cleanup_fclose_ FILE *f = NULL; + struct cgroup_memory_stat *st; + char p[PATH_MAX] = ""; + char buf[LINE_MAX]; + const char *memory_stat = "memory.stat"; + const int memory_stat_len = strlen(memory_stat); + + if (name) { + int l; + int name_len = strlen(name); + + if (strneq(name, CGROUP_MEMORY, strlen(CGROUP_MEMORY))) + l = snprintf(p, PATH_MAX, "%s", name); + else + l = snprintf(p, PATH_MAX, "%s%s%s", + CGROUP_MEMORY, + name[0] != '/' ? "/" : "", + name); + + if (name_len >= memory_stat_len && + memcmp(name + name_len - memory_stat_len, memory_stat, memory_stat_len)) + snprintf(p + l, PATH_MAX - l, "%s%s", + p[l - 1] != '/' ? "/" : "", + memory_stat); + } else + snprintf(p, PATH_MAX, "%s/%s", CGROUP_MEMORY, memory_stat); + + f = fopen(p, "re"); + if (!f) + return -errno; + + st = (struct cgroup_memory_stat *)malloc(sizeof(struct cgroup_memory_stat)); + if (!st) + return -ENOMEM; + + cgroup_memory_stat_init(st, -1); + + for (;;) { + enum cgroup_memory_stat_id id; + size_t l; + + if (!fgets(buf, sizeof(buf), f)) { + if (ferror(f)) { + free(st); + return -errno; + } + break; + } + + l = strcspn(buf, " "); + if (!l) + break; + + buf[l] = 0; + + id = cgroup_memory_stat_string_to_id(buf); + if (id < 0 || id >= CGROUP_MEMORY_STAT_MAX) + continue; + + st->value[id] = atoll(buf + l + 1); + } + + *mem_stat = st; + + return 0; +} + +/* + * Usage example: + * int i; + * pid_t pid; + * GArray *pids_array = NULL; + * + * cgroup_get_pids(name, &pids_array); + * + * for (i=0; i < pids_array->len; i++) + * _D("pid_t: %d", g_array_index(pids_array, pid_t, i)); + * g_array_free(pids_array, TRUE); + * + */ diff --git a/src/common/cgroup.h b/src/common/cgroup.h index eafcf5f6..2cb67e4b 100644 --- a/src/common/cgroup.h +++ b/src/common/cgroup.h @@ -19,6 +19,7 @@ #include #include +#include /* * Cgroup creation interface @@ -28,6 +29,8 @@ #define _CGROUP_LIBRARY_CGROUP_H_ #define DEFAULT_CGROUP "/sys/fs/cgroup" +#define CGROUP_CPU DEFAULT_CGROUP "/cpu" +#define CGROUP_MEMORY DEFAULT_CGROUP "/memory" #define PROC_TASK_CHILDREN "/proc/%d/task/%d/children" /** @@ -67,7 +70,7 @@ int cgroup_write_node_str(const char *cgroup_name, * as formal argument, in this case it will not be filled * @return negative value if error */ -int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *already); +int cgroup_make_subdir(const char* parentdir, const char* cgroup_name, bool *already); /** * @desc mount cgroup, @@ -76,7 +79,7 @@ int make_cgroup_subdir(const char* parentdir, const char* cgroup_name, bool *alr * @param opts - mount options * @return negative value if error */ -int mount_cgroup_subsystem(char* source, char* mount_point, char* opts); +int cgroup_mount_subsystem(char* source, char* mount_point, char* opts); /** * @desc write pid into cgroup_subsystem/cgroup_name file, @@ -84,17 +87,17 @@ int mount_cgroup_subsystem(char* source, char* mount_point, char* opts); * @param cgroup_name - name in /sys/fs/cgroup/subsystem/ * @return negative value if error */ -resourced_ret_c place_pid_to_cgroup(const char *cgroup_subsystem, +resourced_ret_c cgroup_write_pid(const char *cgroup_subsystem, const char *cgroup_name, const int pid); -resourced_ret_c place_pid_to_cgroup_by_fullpath(const char *cgroup_full_path, +resourced_ret_c cgroup_write_pid_fullpath(const char *cgroup_full_path, const int pid); /** - * @desc doing the same as @see place_pid_to_cgroup, + * @desc doing the same as @see cgroup_write_pid, * but also put into cgroup first level child processes */ -resourced_ret_c place_pidtree_to_cgroup(const char *cgroup_subsystem, +resourced_ret_c cgroup_write_pidtree(const char *cgroup_subsystem, const char *cgroup_name, const int pid); /** @@ -105,6 +108,77 @@ resourced_ret_c place_pidtree_to_cgroup(const char *cgroup_subsystem, * @param release_agent full path to release agent executable * @return negative value if error */ -int set_release_agent(const char *cgroup_subsys, const char *release_agent); +int cgroup_set_release_agent(const char *cgroup_subsys, const char *release_agent); + +/** + * @desc get controller path of pid + * @param controller the name of control group such like + * "cpuacct,cpu", memory, freezer or debug. Especially supporting + * "name=" prefix. For example, if "systemd" is given as controller + * then finding also "name=systemd". + * @param pid pid to get the controller path + * @param path contoller path is filled. This value has to be free-ed + * by caller function. + * @return negative value if error + */ +int cgroup_pid_get_path(const char *controller, pid_t pid, char **path); + +/** + * @desc get PIDs of processes in a certain cgroup, an allocated array must be provided + * @return 0 if pids were read and array filled + */ +int cgroup_get_pids(const char *name, GArray **pids); + +enum cgroup_memory_stat_id { + CGROUP_MEMORY_STAT_CACHE = 0, + CGROUP_MEMORY_STAT_RSS, + CGROUP_MEMORY_STAT_RSS_HUGE, + CGROUP_MEMORY_STAT_MAPPED_FILE, + CGROUP_MEMORY_STAT_DIRTY, + CGROUP_MEMORY_STAT_WRITEBACK, + CGROUP_MEMORY_STAT_SWAP, + CGROUP_MEMORY_STAT_PGPGIN, + CGROUP_MEMORY_STAT_PGPGOUT, + CGROUP_MEMORY_STAT_PGFAULT, + CGROUP_MEMORY_STAT_PGMAJFAULT, + CGROUP_MEMORY_STAT_INACTIVE_ANON, + CGROUP_MEMORY_STAT_ACTIVE_ANON, + CGROUP_MEMORY_STAT_INACTIVE_FILE, + CGROUP_MEMORY_STAT_ACTIVE_FILE, + CGROUP_MEMORY_STAT_UNEVICTABLE, + CGROUP_MEMORY_STAT_HIERARCHICAL_MEMORY_LIMIT, + CGROUP_MEMORY_STAT_HIERARCHICAL_MEMSW_LIMIT, + CGROUP_MEMORY_STAT_TOTAL_CACHE, + CGROUP_MEMORY_STAT_TOTAL_RSS, + CGROUP_MEMORY_STAT_TOTAL_RSS_HUGE, + CGROUP_MEMORY_STAT_TOTAL_MAPPED_FILE, + CGROUP_MEMORY_STAT_TOTAL_DIRTY, + CGROUP_MEMORY_STAT_TOTAL_WRITEBACK, + CGROUP_MEMORY_STAT_TOTAL_SWAP, + CGROUP_MEMORY_STAT_TOTAL_PGPGIN, + CGROUP_MEMORY_STAT_TOTAL_PGPGOUT, + CGROUP_MEMORY_STAT_TOTAL_PGFAULT, + CGROUP_MEMORY_STAT_TOTAL_PGMAJFAULT, + CGROUP_MEMORY_STAT_TOTAL_INACTIVE_ANON, + CGROUP_MEMORY_STAT_TOTAL_ACTIVE_ANON, + CGROUP_MEMORY_STAT_TOTAL_INACTIVE_FILE, + CGROUP_MEMORY_STAT_TOTAL_ACTIVE_FILE, + CGROUP_MEMORY_STAT_TOTAL_UNEVICTABLE, + CGROUP_MEMORY_STAT_RECENT_ROTATED_ANON, + CGROUP_MEMORY_STAT_RECENT_ROTATED_FILE, + CGROUP_MEMORY_STAT_RECENT_SCANNED_ANON, + CGROUP_MEMORY_STAT_RECENT_SCANNED_FILE, + CGROUP_MEMORY_STAT_MAX, + CGROUP_MEMORY_STAT_INVALID = -1, +}; + +struct cgroup_memory_stat { + long long value[CGROUP_MEMORY_STAT_MAX]; +}; + +const char *cgroup_memory_stat_id_to_string(enum cgroup_memory_stat_id id); +enum cgroup_memory_stat_id cgroup_memory_stat_string_to_id(const char *str); + +int cgroup_get_memory_stat(const char *name, struct cgroup_memory_stat **mem_stat); #endif /*_CGROUP_LIBRARY_CGROUP_H_*/ diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index c1d337ba..8f929ee5 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -387,11 +387,11 @@ static int resourced_cpu_init(void *data) int ret_code; _D("resourced_cpu_init"); - ret_code = make_cgroup_subdir(CPU_DEFAULT_CGROUP, "background", NULL); + ret_code = cgroup_make_subdir(CPU_DEFAULT_CGROUP, "background", NULL); ret_value_msg_if(ret_code < 0, ret_code, "cpu init failed\n"); cpu_check_cpuquota(); if (cpu_quota_enabled()) { - ret_code = make_cgroup_subdir(CPU_DEFAULT_CGROUP, "quota", NULL); + ret_code = cgroup_make_subdir(CPU_DEFAULT_CGROUP, "quota", NULL); ret_value_msg_if(ret_code < 0, ret_code, "create service cgroup failed\n"); } config_parse(CPU_CONF_FILE, load_cpu_config, NULL); diff --git a/src/memory/vmpressure-lowmem-handler.c b/src/memory/vmpressure-lowmem-handler.c index bd365d23..e55a74e3 100644 --- a/src/memory/vmpressure-lowmem-handler.c +++ b/src/memory/vmpressure-lowmem-handler.c @@ -1715,7 +1715,7 @@ static int create_memcgs(void) continue; mi = memcg_tree[i]->info; name = mi->name; - ret = make_cgroup_subdir(LOWMEM_DEFAULT_CGROUP, memcg_name[i], NULL); + ret = cgroup_make_subdir(LOWMEM_DEFAULT_CGROUP, memcg_name[i], NULL); _D("Create subcgroup of memory : name = %s, ret = %d", memcg_name[i], ret); if (!memcg_tree[i]->use_hierarchy) continue; @@ -1725,7 +1725,7 @@ static int create_memcgs(void) name = strstr(mi->name, memcg_name[i]) + strlen(memcg_name[i]) + 1; snprintf(parent_dir, MAX_PATH_LENGTH, "%s/%s", LOWMEM_DEFAULT_CGROUP, memcg_name[i]); - ret = make_cgroup_subdir(parent_dir, name, NULL); + ret = cgroup_make_subdir(parent_dir, name, NULL); _D("Create subcgroup of memory/%s : name = %s, ret = %d", memcg_name[i], name, ret); } } diff --git a/src/swap/swap.c b/src/swap/swap.c index 4123a534..1b2460fe 100644 --- a/src/swap/swap.c +++ b/src/swap/swap.c @@ -231,12 +231,12 @@ static int swap_move_to_cgroup_by_pid(enum memcg_type type, pid_t pid) mi = memcg_swap->info; if (!pai) - return place_pid_to_cgroup_by_fullpath(mi->name, pid); + return cgroup_write_pid_fullpath(mi->name, pid); - ret = place_pid_to_cgroup_by_fullpath(mi->name, pai->main_pid); + ret = cgroup_write_pid_fullpath(mi->name, pai->main_pid); gslist_for_each_item(iter_child, pai->childs) { pid_t child = GPOINTER_TO_PID(iter_child->data); - ret = place_pid_to_cgroup_by_fullpath(mi->name, child); + ret = cgroup_write_pid_fullpath(mi->name, child); } pai->memory.memcg_idx = MEMCG_SWAP; pai->memory.memcg_info = mi; @@ -256,10 +256,10 @@ static int swap_move_to_cgroup(struct memcg_info *info, GArray *candidates) for (index = 0; index < candidates->len; index++) { tsk = g_array_index(candidates, struct swap_task, index); pai = tsk.pai; - place_pid_to_cgroup_by_fullpath(info->name, pai->main_pid); + cgroup_write_pid_fullpath(info->name, pai->main_pid); gslist_for_each_item(iter_child, pai->childs) { pid_t child = GPOINTER_TO_PID(iter_child->data); - place_pid_to_cgroup_by_fullpath(info->name, child); + cgroup_write_pid_fullpath(info->name, child); } pai->memory.memcg_idx = MEMCG_SWAP; pai->memory.memcg_info = info; @@ -1020,7 +1020,7 @@ static int resourced_swap_init(void *data) { int ret; - make_cgroup_subdir(MEMCG_PATH, "swap", NULL); + cgroup_make_subdir(MEMCG_PATH, "swap", NULL); resourced_swap_change_memcg_settings(MEMCG_SWAP); resourced_swap_change_memcg_settings(MEMCG_FAVORITE); resourced_swap_change_memcg_settings(MEMCG_PLATFORM); diff --git a/src/timer-slack/timer-slack.c b/src/timer-slack/timer-slack.c index 969462c3..43518a10 100644 --- a/src/timer-slack/timer-slack.c +++ b/src/timer-slack/timer-slack.c @@ -211,9 +211,9 @@ static int load_timer_config(struct parse_result *result, void *user_data) static void timer_slack_cgroup_init(void) { - make_cgroup_subdir(TIMER_CGROUP_PATH, TIMER_EXCLUDE_CGROUP, NULL); - make_cgroup_subdir(TIMER_CGROUP_PATH, TIMER_SERVICE_CGROUP, NULL); - make_cgroup_subdir(TIMER_CGROUP_PATH, TIMER_BACKGRD_CGROUP, NULL); + cgroup_make_subdir(TIMER_CGROUP_PATH, TIMER_EXCLUDE_CGROUP, NULL); + cgroup_make_subdir(TIMER_CGROUP_PATH, TIMER_SERVICE_CGROUP, NULL); + cgroup_make_subdir(TIMER_CGROUP_PATH, TIMER_BACKGRD_CGROUP, NULL); config_parse(TIMER_CONF_FILE, load_timer_config, NULL); set_default_cgroup_value(); diff --git a/src/vip-agent/vip-process.c b/src/vip-agent/vip-process.c index d2a4bbd6..3ed905e1 100644 --- a/src/vip-agent/vip-process.c +++ b/src/vip-agent/vip-process.c @@ -99,7 +99,7 @@ static int vip_create_sub_cgroup(const char *name, pid_t pid) assert(name); assert(pid); - r = make_cgroup_subdir(VIP_CGROUP, name, &already); + r = cgroup_make_subdir(VIP_CGROUP, name, &already); if (r < 0) { _E("failed to create vip sub dir"); return r; @@ -224,20 +224,20 @@ static int resourced_vip_process_init(void *data) return RESOURCED_ERROR_NONE; if (!is_mounted(VIP_CGROUP)) { - r = make_cgroup_subdir(DEFAULT_CGROUP, "vip", NULL); + r = cgroup_make_subdir(DEFAULT_CGROUP, "vip", NULL); if (r < 0) { _E("failed to make vip cgroup"); return RESOURCED_ERROR_FAIL; } - r = mount_cgroup_subsystem("vip_cgroup", VIP_CGROUP, + r = cgroup_mount_subsystem("vip_cgroup", VIP_CGROUP, "none,name=vip_cgroup"); if (r < 0) { _E("failed to mount vip cgroup: %m"); return RESOURCED_ERROR_FAIL; } - r = set_release_agent("vip", "/usr/bin/vip-release-agent"); + r = cgroup_set_release_agent("vip", "/usr/bin/vip-release-agent"); if (r < 0) { _E("failed to set vip release agent: %s", strerror_r(-r, buf, sizeof(buf))); return RESOURCED_ERROR_FAIL; -- cgit v1.2.3