From: Lennart Poettering Date: Tue, 5 Sep 2017 09:40:47 +0000 (+0200) Subject: manager: watching the cgroup2 inotify fd is safe in test runs too X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=31a88b7046d1d9040018e3e6d6fc71aac22192f3;p=elogind.git manager: watching the cgroup2 inotify fd is safe in test runs too Less deviation between test runs and normal runs is always a good idea, hence enable more stuff that is safe in test runs --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 48f09658b..1289ddf73 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1759,6 +1759,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, int manager_setup_cgroup(Manager *m) { _cleanup_free_ char *path = NULL; + const char *scope_path; CGroupController c; int r, all_unified; char *e; @@ -1824,95 +1825,88 @@ int manager_setup_cgroup(Manager *m) { log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER_LEGACY ". File system hierarchy is at %s.", path); } - if (!m->test_run_flags) { - const char *scope_path; - #if 0 /// elogind is not init, and does not install the agent here. - /* 3. Install agent */ - if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) { + /* 3. Install agent */ + if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) { - /* In the unified hierarchy we can get - * cgroup empty notifications via inotify. */ + /* In the unified hierarchy we can get + * cgroup empty notifications via inotify. */ - m->cgroup_inotify_event_source = sd_event_source_unref(m->cgroup_inotify_event_source); - safe_close(m->cgroup_inotify_fd); + m->cgroup_inotify_event_source = sd_event_source_unref(m->cgroup_inotify_event_source); + safe_close(m->cgroup_inotify_fd); - m->cgroup_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); - if (m->cgroup_inotify_fd < 0) - return log_error_errno(errno, "Failed to create control group inotify object: %m"); + m->cgroup_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (m->cgroup_inotify_fd < 0) + return log_error_errno(errno, "Failed to create control group inotify object: %m"); - r = sd_event_add_io(m->event, &m->cgroup_inotify_event_source, m->cgroup_inotify_fd, EPOLLIN, on_cgroup_inotify_event, m); - if (r < 0) - return log_error_errno(r, "Failed to watch control group inotify object: %m"); + r = sd_event_add_io(m->event, &m->cgroup_inotify_event_source, m->cgroup_inotify_fd, EPOLLIN, on_cgroup_inotify_event, m); + if (r < 0) + return log_error_errno(r, "Failed to watch control group inotify object: %m"); - /* Process cgroup empty notifications early, but after service notifications and SIGCHLD. Also - * see handling of cgroup agent notifications, for the classic cgroup hierarchy support. */ - r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_NORMAL-5); - if (r < 0) - return log_error_errno(r, "Failed to set priority of inotify event source: %m"); + /* Process cgroup empty notifications early, but after service notifications and SIGCHLD. Also + * see handling of cgroup agent notifications, for the classic cgroup hierarchy support. */ + r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_NORMAL-5); + if (r < 0) + return log_error_errno(r, "Failed to set priority of inotify event source: %m"); - (void) sd_event_source_set_description(m->cgroup_inotify_event_source, "cgroup-inotify"); + (void) sd_event_source_set_description(m->cgroup_inotify_event_source, "cgroup-inotify"); - } else if (MANAGER_IS_SYSTEM(m)) { + } else if (MANAGER_IS_SYSTEM(m) && m->test_run_flags == 0) { - /* On the legacy hierarchy we only get - * notifications via cgroup agents. (Which - * isn't really reliable, since it does not - * generate events when control groups with - * children run empty. */ + /* On the legacy hierarchy we only get notifications via cgroup agents. (Which isn't really reliable, + * since it does not generate events when control groups with children run empty. */ - r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH); - if (r < 0) - log_warning_errno(r, "Failed to install release agent, ignoring: %m"); - else if (r > 0) - log_debug("Installed release agent."); - else if (r == 0) - log_debug("Release agent already installed."); - } + r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH); + if (r < 0) + log_warning_errno(r, "Failed to install release agent, ignoring: %m"); + else if (r > 0) + log_debug("Installed release agent."); + else if (r == 0) + log_debug("Release agent already installed."); + } - /* 4. Make sure we are in the special "init.scope" unit in the root slice. */ - scope_path = strjoina(m->cgroup_root, "/" SPECIAL_INIT_SCOPE); - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); + /* 4. Make sure we are in the special "init.scope" unit in the root slice. */ + scope_path = strjoina(m->cgroup_root, "/" SPECIAL_INIT_SCOPE); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); #else - /* Note: - * This method is in core, and normally called by systemd - * being init. As elogind is never init, we can not install - * our agent here. We do so when mounting our cgroup file - * system, so only if elogind is its own tiny controller. - * Further, elogind is not meant to run in systemd init scope. */ - if (MANAGER_IS_SYSTEM(m)) - // we are our own cgroup controller - scope_path = strjoina(""); - else if (streq(m->cgroup_root, "/elogind")) - // root already is our cgroup - scope_path = strjoina(m->cgroup_root); - else - // we have to create our own group - scope_path = strjoina(m->cgroup_root, "/elogind"); - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); + /* Note: + * This method is in core, and normally called by systemd + * being init. As elogind is never init, we can not install + * our agent here. We do so when mounting our cgroup file + * system, so only if elogind is its own tiny controller. + * Further, elogind is not meant to run in systemd init scope. */ + if (MANAGER_IS_SYSTEM(m)) + // we are our own cgroup controller + scope_path = strjoina(""); + else if (streq(m->cgroup_root, "/elogind")) + // root already is our cgroup + scope_path = strjoina(m->cgroup_root); + else + // we have to create our own group + scope_path = strjoina(m->cgroup_root, "/elogind"); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); #endif // 0 - if (r < 0) - return log_error_errno(r, "Failed to create %s control group: %m", scope_path); - log_debug_elogind("Created control group \"%s\"", scope_path); + if (r < 0) + return log_error_errno(r, "Failed to create %s control group: %m", scope_path); + log_debug_elogind("Created control group \"%s\"", scope_path); #if 0 /// elogind is not a "sub-controller" like systemd, so migration is not needed. - /* also, move all other userspace processes remaining - * in the root cgroup into that scope. */ - r = cg_migrate(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); - if (r < 0) - log_warning_errno(r, "Couldn't move remaining userspace processes, ignoring: %m"); + /* also, move all other userspace processes remaining + * in the root cgroup into that scope. */ + r = cg_migrate(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, SYSTEMD_CGROUP_CONTROLLER, scope_path, 0); + if (r < 0) + log_warning_errno(r, "Couldn't move remaining userspace processes, ignoring: %m"); #endif // 0 - /* 5. And pin it, so that it cannot be unmounted */ - safe_close(m->pin_cgroupfs_fd); - m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); - if (m->pin_cgroupfs_fd < 0) - return log_error_errno(errno, "Failed to open pin file: %m"); + /* 5. And pin it, so that it cannot be unmounted */ + safe_close(m->pin_cgroupfs_fd); + m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); + if (m->pin_cgroupfs_fd < 0) + return log_error_errno(errno, "Failed to open pin file: %m"); - /* 6. Always enable hierarchical support if it exists... */ - if (!all_unified) - (void) cg_set_attribute("memory", "/", "memory.use_hierarchy", "1"); - } + /* 6. Always enable hierarchical support if it exists... */ + if (!all_unified && m->test_run_flags == 0) + (void) cg_set_attribute("memory", "/", "memory.use_hierarchy", "1"); /* 7. Figure out which controllers are supported */ r = cg_mask_supported(&m->cgroup_supported);