From ab2c3861dcbece00d1c03357556faced6e048de0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 25 Mar 2016 11:38:50 -0400 Subject: [PATCH] core: update populated event handling in unified hierarchy Earlier during the development of unified hierarchy, the populated event was reported through by the dedicated "cgroup.populated" file; however, the interface was updated so that it's reported through the "populated" field of "cgroup.events" file. Update populated event handling logic accordingly. --- src/basic/cgroup-util.c | 45 ++++++++++++++++++++++++++++++-------- src/basic/cgroup-util.h | 2 ++ src/core/cgroup.c | 6 ++--- src/nspawn/nspawn-cgroup.c | 3 +-- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 5124b5bf93a..50431807475 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -101,6 +101,39 @@ int cg_read_pid(FILE *f, pid_t *_pid) { return 1; } +int cg_read_event(const char *controller, const char *path, const char *event, + char **val) +{ + _cleanup_free_ char *events = NULL, *content = NULL; + char *p, *line; + int r; + + r = cg_get_path(controller, path, "cgroup.events", &events); + if (r < 0) + return r; + + r = read_full_file(events, &content, NULL); + if (r < 0) + return r; + + p = content; + while ((line = strsep(&p, "\n"))) { + char *key; + + key = strsep(&line, " "); + if (!key || !line) + return -EINVAL; + + if (strcmp(key, event)) + continue; + + *val = strdup(line); + return 0; + } + + return -ENOENT; +} + int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) { _cleanup_free_ char *fs = NULL; int r; @@ -1007,18 +1040,12 @@ int cg_is_empty_recursive(const char *controller, const char *path) { return unified; if (unified > 0) { - _cleanup_free_ char *populated = NULL, *t = NULL; + _cleanup_free_ char *t = NULL; /* On the unified hierarchy we can check empty state - * via the "cgroup.populated" attribute. */ + * via the "populated" attribute of "cgroup.events". */ - r = cg_get_path(controller, path, "cgroup.populated", &populated); - if (r < 0) - return r; - - r = read_one_line_file(populated, &t); - if (r == -ENOENT) - return 1; + r = cg_read_event(controller, path, "populated", &t); if (r < 0) return r; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index ad1edd9cdbc..4254e51e5d9 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -96,6 +96,8 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); int cg_read_pid(FILE *f, pid_t *_pid); +int cg_read_event(const char *controller, const char *path, const char *event, + char **val); int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); int cg_read_subgroup(DIR *d, char **fn); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 39235a95f60..9c34928052b 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -765,7 +765,7 @@ int unit_set_cgroup_path(Unit *u, const char *path) { } int unit_watch_cgroup(Unit *u) { - _cleanup_free_ char *populated = NULL; + _cleanup_free_ char *events = NULL; int r; assert(u); @@ -791,11 +791,11 @@ int unit_watch_cgroup(Unit *u) { if (r < 0) return log_oom(); - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.populated", &populated); + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events", &events); if (r < 0) return log_oom(); - u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, populated, IN_MODIFY); + u->cgroup_inotify_wd = inotify_add_watch(u->manager->cgroup_inotify_fd, events, IN_MODIFY); if (u->cgroup_inotify_wd < 0) { if (errno == ENOENT) /* If the directory is already diff --git a/src/nspawn/nspawn-cgroup.c b/src/nspawn/nspawn-cgroup.c index 53a7ee71342..f50f1ad6c22 100644 --- a/src/nspawn/nspawn-cgroup.c +++ b/src/nspawn/nspawn-cgroup.c @@ -55,8 +55,7 @@ int chown_cgroup(pid_t pid, uid_t uid_shift) { "cgroup.events", "cgroup.clone_children", "cgroup.controllers", - "cgroup.subtree_control", - "cgroup.populated") + "cgroup.subtree_control") if (fchownat(fd, fn, uid_shift, uid_shift, 0) < 0) log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, "Failed to chown() cgroup file %s, ignoring: %m", fn);