chiark / gitweb /
cgroup: minor optimization
[elogind.git] / src / core / cgroup.c
index 7a5f673a7ad0c7e4731dda7bd3f9b08baf8a2254..8fb2952c161e26b9d36d1dc041edfbd1a1edeb1c 100644 (file)
@@ -30,6 +30,8 @@
 #include "cgroup.h"
 #include "cgroup-util.h"
 #include "log.h"
+#include "strv.h"
+#include "path-util.h"
 
 int cgroup_bonding_realize(CGroupBonding *b) {
         int r;
@@ -108,7 +110,6 @@ void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) {
                 cgroup_bonding_trim(b, delete_root);
 }
 
-
 int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) {
         char *p = NULL;
         const char *path;
@@ -118,7 +119,7 @@ int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffi
         assert(pid >= 0);
 
         if (cgroup_suffix) {
-                p = join(b->path, "/", cgroup_suffix, NULL);
+                p = strjoin(b->path, "/", cgroup_suffix, NULL);
                 if (!p)
                         return -ENOMEM;
 
@@ -149,6 +150,34 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgr
         return 0;
 }
 
+int cgroup_bonding_migrate(CGroupBonding *b, CGroupBonding *list) {
+        CGroupBonding *q;
+        int ret = 0;
+
+        LIST_FOREACH(by_unit, q, list) {
+                int r;
+
+                if (q == b)
+                        continue;
+
+                if (!q->ours)
+                        continue;
+
+                r = cg_migrate_recursive(q->controller, q->path, b->controller, b->path, true, false);
+                if (r < 0 && ret == 0)
+                        ret = r;
+        }
+
+        return ret;
+}
+
+int cgroup_bonding_migrate_to(CGroupBonding *b, const char *target, bool rem) {
+        assert(b);
+        assert(target);
+
+        return cg_migrate_recursive(b->controller, b->path, b->controller, target, true, rem);
+}
+
 int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
         assert(b);
 
@@ -193,7 +222,7 @@ int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t
         return 0;
 }
 
-int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const char *cgroup_suffix) {
+int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) {
         char *p = NULL;
         const char *path;
         int r;
@@ -206,7 +235,7 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const c
                 return 0;
 
         if (cgroup_suffix) {
-                p = join(b->path, "/", cgroup_suffix, NULL);
+                p = strjoin(b->path, "/", cgroup_suffix, NULL);
                 if (!p)
                         return -ENOMEM;
 
@@ -214,13 +243,13 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const c
         } else
                 path = b->path;
 
-        r = cg_kill_recursive(b->controller, path, sig, sigcont, true, false, s);
+        r = cg_kill_recursive(b->controller, path, sig, sigcont, true, rem, s);
         free(p);
 
         return r;
 }
 
-int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s, const char *cgroup_suffix) {
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, bool rem, Set *s, const char *cgroup_suffix) {
         CGroupBonding *b;
         Set *allocated_set = NULL;
         int ret = -EAGAIN, r;
@@ -233,7 +262,7 @@ int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s
                         return -ENOMEM;
 
         LIST_FOREACH(by_unit, b, first) {
-                r = cgroup_bonding_kill(b, sig, sigcont, s, cgroup_suffix);
+                r = cgroup_bonding_kill(b, sig, sigcont, rem, s, cgroup_suffix);
                 if (r < 0) {
                         if (r == -EAGAIN || r == -ESRCH)
                                 continue;
@@ -305,12 +334,13 @@ int manager_setup_cgroup(Manager *m) {
         }
 
         /* 1. Determine hierarchy */
-        if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &current)) < 0) {
+        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &current);
+        if (r < 0) {
                 log_error("Cannot determine cgroup we are running in: %s", strerror(-r));
                 goto finish;
         }
 
-        if (m->running_as == MANAGER_SYSTEM)
+        if (m->running_as == SYSTEMD_SYSTEM)
                 strcpy(suffix, "/system");
         else {
                 snprintf(suffix, sizeof(suffix), "/systemd-%lu", (unsigned long) getpid());
@@ -327,14 +357,14 @@ int manager_setup_cgroup(Manager *m) {
                 /* We need a new root cgroup */
                 m->cgroup_hierarchy = NULL;
                 if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0) {
-                        log_error("Out of memory");
-                        r = -ENOMEM;
+                        r = log_oom();
                         goto finish;
                 }
         }
 
         /* 2. Show data */
-        if ((r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path)) < 0) {
+        r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path);
+        if (r < 0) {
                 log_error("Cannot find cgroup mount point: %s", strerror(-r));
                 goto finish;
         }
@@ -342,7 +372,8 @@ int manager_setup_cgroup(Manager *m) {
         log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
 
         /* 3. Install agent */
-        if ((r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH)) < 0)
+        r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
+        if (r < 0)
                 log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
         else if (r > 0)
                 log_debug("Installed release agent.");
@@ -350,7 +381,8 @@ int manager_setup_cgroup(Manager *m) {
                 log_debug("Release agent already installed.");
 
         /* 4. Realize the group */
-        if ((r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0)) < 0) {
+        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0);
+        if (r < 0) {
                 log_error("Failed to create root cgroup hierarchy: %s", strerror(-r));
                 goto finish;
         }
@@ -359,7 +391,8 @@ int manager_setup_cgroup(Manager *m) {
         if (m->pin_cgroupfs_fd >= 0)
                 close_nointr_nofail(m->pin_cgroupfs_fd);
 
-        if ((m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK)) < 0) {
+        m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
+        if (r < 0) {
                 log_error("Failed to open pin file: %m");
                 r = -errno;
                 goto finish;
@@ -367,6 +400,8 @@ int manager_setup_cgroup(Manager *m) {
 
         log_debug("Created root group.");
 
+        cg_shorten_controllers(m->default_controllers);
+
 finish:
         free(current);
         free(path);
@@ -403,7 +438,7 @@ int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding)
                 return 1;
         }
 
-        p = strdup(cgroup);
+        p = strdupa(cgroup);
         if (!p)
                 return -ENOMEM;
 
@@ -411,8 +446,7 @@ int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding)
                 char *e;
 
                 e = strrchr(p, '/');
-                if (!e || e == p) {
-                        free(p);
+                if (e == p || !e) {
                         *bonding = NULL;
                         return 0;
                 }
@@ -421,7 +455,6 @@ int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding)
 
                 b = hashmap_get(m->cgroup_bondings, p);
                 if (b) {
-                        free(p);
                         *bonding = b;
                         return 1;
                 }
@@ -512,7 +545,8 @@ Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) {
 CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) {
         CGroupBonding *b;
 
-        assert(controller);
+        if (!controller)
+                controller = SYSTEMD_CGROUP_CONTROLLER;
 
         LIST_FOREACH(by_unit, b, first)
                 if (streq(b->controller, controller))