[systemd-commits] src/core src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Tue Sep 24 18:38:41 PDT 2013


 src/core/cgroup.c        |    8 +-
 src/core/execute.c       |    4 -
 src/core/mount.c         |    2 
 src/core/scope.c         |    2 
 src/core/service.c       |    2 
 src/core/socket.c        |    2 
 src/core/swap.c          |    2 
 src/shared/cgroup-util.c |  154 ++++++++++++++++++++++++++++++-----------------
 src/shared/cgroup-util.h |   12 ++-
 9 files changed, 118 insertions(+), 70 deletions(-)

New commits:
commit 13b84ec7df103ce388910a2b868fe1668c1e27ef
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Sep 23 21:56:05 2013 -0500

    cgroup: if we do a cgroup operation then do something on all supported controllers
    
    Previously we did operations like attach, trim or migrate only on the
    controllers that were enabled for a specific unit. With this changes we
    will now do them for all supproted controllers, and fall back to all
    possible prefix paths if the specified paths do not exist.
    
    This fixes issues if a controller is being disabled for a unit where it
    was previously enabled, and makes sure that all processes stay as "far
    down" the tree as groups exist.

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index e66b8f4..8bf4d89 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -397,13 +397,13 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
         }
 
         /* First, create our own group */
-        r = cg_create_with_mask(mask, path);
+        r = cg_create_everywhere(u->manager->cgroup_supported, mask, path);
         if (r < 0)
                 log_error("Failed to create cgroup %s: %s", path, strerror(-r));
 
         /* Then, possibly move things over */
-        if (u->cgroup_path && !streq(path, u->cgroup_path)) {
-                r = cg_migrate_with_mask(mask, u->cgroup_path, path);
+        if (u->cgroup_path) {
+                r = cg_migrate_everywhere(u->manager->cgroup_supported, u->cgroup_path, path);
                 if (r < 0)
                         log_error("Failed to migrate cgroup %s: %s", path, strerror(-r));
         }
@@ -537,7 +537,7 @@ void unit_destroy_cgroup(Unit *u) {
         if (!u->cgroup_path)
                 return;
 
-        r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
+        r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !unit_has_name(u, SPECIAL_ROOT_SLICE));
         if (r < 0)
                 log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r));
 
diff --git a/src/core/execute.c b/src/core/execute.c
index f840642..0bfa418 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1017,7 +1017,7 @@ int exec_spawn(ExecCommand *command,
                bool apply_chroot,
                bool apply_tty_stdin,
                bool confirm_spawn,
-               CGroupControllerMask cgroup_mask,
+               CGroupControllerMask cgroup_supported,
                const char *cgroup_path,
                const char *unit_id,
                int idle_pipe[4],
@@ -1198,7 +1198,7 @@ int exec_spawn(ExecCommand *command,
                 }
 
                 if (cgroup_path) {
-                        err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0);
+                        err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0);
                         if (err < 0) {
                                 r = EXIT_CGROUP;
                                 goto fail_child;
diff --git a/src/core/mount.c b/src/core/mount.c
index 5c18d4e..78c5c1e 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -888,7 +888,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
                        true,
                        true,
                        UNIT(m)->manager->confirm_spawn,
-                       UNIT(m)->cgroup_mask,
+                       UNIT(m)->manager->cgroup_supported,
                        UNIT(m)->cgroup_path,
                        UNIT(m)->id,
                        NULL,
diff --git a/src/core/scope.c b/src/core/scope.c
index b94f3ff..50e5dba 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -257,7 +257,7 @@ static int scope_start(Unit *u) {
                 return r;
         }
 
-        r = cg_attach_many_with_mask(u->cgroup_mask, u->cgroup_path, s->pids);
+        r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, s->pids);
         if (r < 0)
                 return r;
 
diff --git a/src/core/service.c b/src/core/service.c
index cc61b54..24b7bef 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1820,7 +1820,7 @@ static int service_spawn(
                        apply_chroot,
                        apply_tty_stdin,
                        UNIT(s)->manager->confirm_spawn,
-                       UNIT(s)->cgroup_mask,
+                       UNIT(s)->manager->cgroup_supported,
                        path,
                        UNIT(s)->id,
                        s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL,
diff --git a/src/core/socket.c b/src/core/socket.c
index 46a73e0..190b36c 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1239,7 +1239,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
                        true,
                        true,
                        UNIT(s)->manager->confirm_spawn,
-                       UNIT(s)->cgroup_mask,
+                       UNIT(s)->manager->cgroup_supported,
                        UNIT(s)->cgroup_path,
                        UNIT(s)->id,
                        NULL,
diff --git a/src/core/swap.c b/src/core/swap.c
index 82bfad1..dc6731a 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -625,7 +625,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
                        true,
                        true,
                        UNIT(s)->manager->confirm_spawn,
-                       UNIT(s)->cgroup_mask,
+                       UNIT(s)->manager->cgroup_supported,
                        UNIT(s)->cgroup_path,
                        UNIT(s)->id,
                        NULL,
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 0bffebd..2e630d4 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -435,6 +435,46 @@ int cg_migrate_recursive(
         return ret;
 }
 
+int cg_migrate_recursive_fallback(
+                const char *cfrom,
+                const char *pfrom,
+                const char *cto,
+                const char *pto,
+                bool ignore_self,
+                bool rem) {
+
+        int r;
+
+        assert(cfrom);
+        assert(pfrom);
+        assert(cto);
+        assert(pto);
+
+        r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem);
+        if (r < 0) {
+                char prefix[strlen(pto) + 1];
+
+                /* This didn't work? Then let's try all prefixes of the destination */
+
+                strcpy(prefix, pto);
+                for (;;) {
+                        char *slash;
+
+                        slash = strrchr(prefix, '/');
+                        if (!slash)
+                                break;
+
+                        *slash = 0;
+
+                        r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem);
+                        if (r >= 0)
+                                break;
+                }
+        }
+
+        return r;
+}
+
 static const char *normalize_controller(const char *controller) {
 
         assert(controller);
@@ -607,6 +647,39 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
         return write_string_file(fs, c);
 }
 
+int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
+        int r;
+
+        assert(controller);
+        assert(path);
+        assert(pid >= 0);
+
+        r = cg_attach(controller, path, pid);
+        if (r < 0) {
+                char prefix[strlen(path) + 1];
+
+                /* This didn't work? Then let's try all prefixes of
+                 * the destination */
+
+                strcpy(prefix, path);
+                for (;;) {
+                        char *slash;
+
+                        slash = strrchr(prefix, '/');
+                        if (!slash)
+                                break;
+
+                        *slash = 0;
+
+                        r = cg_attach(controller, prefix, pid);
+                        if (r >= 0)
+                                break;
+                }
+        }
+
+        return r;
+}
+
 int cg_set_group_access(
                 const char *controller,
                 const char *path,
@@ -1607,7 +1680,7 @@ static const char mask_names[] =
         "memory\0"
         "devices\0";
 
-int cg_create_with_mask(CGroupControllerMask mask, const char *path) {
+int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
         CGroupControllerMask bit = 1;
         const char *n;
         int r;
@@ -1623,102 +1696,75 @@ int cg_create_with_mask(CGroupControllerMask mask, const char *path) {
 
         /* Then, do the same in the other hierarchies */
         NULSTR_FOREACH(n, mask_names) {
-                if (bit & mask)
+                if (mask & bit)
                         cg_create(n, path);
-                else
+                else if (supported & bit)
                         cg_trim(n, path, true);
 
                 bit <<= 1;
         }
 
-        return r;
+        return 0;
 }
 
-int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid) {
+int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) {
         CGroupControllerMask bit = 1;
         const char *n;
         int r;
 
         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
+        if (r < 0)
+                return r;
 
         NULSTR_FOREACH(n, mask_names) {
-                if (bit & mask)
-                        cg_attach(n, path, pid);
-                else {
-                        char prefix[strlen(path) + 1], *slash;
-
-                        /* OK, this one is a bit harder... Now we need
-                         * to add to the closest parent cgroup we
-                         * can find */
-                        strcpy(prefix, path);
-                        while ((slash = strrchr(prefix, '/'))) {
-                                int q;
-                                *slash = 0;
-
-                                q = cg_attach(n, prefix, pid);
-                                if (q >= 0)
-                                        break;
-                        }
-                }
+                if (supported & bit)
+                        cg_attach_fallback(n, path, pid);
 
                 bit <<= 1;
         }
 
-        return r;
+        return 0;
 }
 
-int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids) {
+int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) {
         Iterator i;
         void *pidp;
         int r = 0;
 
         SET_FOREACH(pidp, pids, i) {
                 pid_t pid = PTR_TO_LONG(pidp);
-                int k;
+                int q;
 
-                k = cg_attach_with_mask(mask, path, pid);
-                if (k < 0)
-                        r = k;
+                q = cg_attach_everywhere(supported, path, pid);
+                if (q < 0)
+                        r = q;
         }
 
         return r;
 }
 
-int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to) {
+int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) {
         CGroupControllerMask bit = 1;
         const char *n;
         int r;
 
-        if (path_equal(from, to))
-                return 0;
-
-        r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
+        if (!path_equal(from, to))  {
+                r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
+                if (r < 0)
+                        return r;
+        }
 
         NULSTR_FOREACH(n, mask_names) {
-                if (bit & mask)
-                        cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
-                else {
-                        char prefix[strlen(to) + 1], *slash;
-
-                        strcpy(prefix, to);
-                        while ((slash = strrchr(prefix, '/'))) {
-                                int q;
-
-                                *slash = 0;
-
-                                q = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, prefix, false, false);
-                                if (q >= 0)
-                                        break;
-                        }
-                }
+                if (supported & bit)
+                        cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
 
                 bit <<= 1;
         }
 
-        return r;
+        return 0;
 }
 
-int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root) {
+int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
         CGroupControllerMask bit = 1;
         const char *n;
         int r;
@@ -1728,13 +1774,13 @@ int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_r
                 return r;
 
         NULSTR_FOREACH(n, mask_names) {
-                if (bit & mask)
+                if (supported & bit)
                         cg_trim(n, path, delete_root);
 
                 bit <<= 1;
         }
 
-        return r;
+        return 0;
 }
 
 CGroupControllerMask cg_mask_supported(void) {
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index 0fc93c1..0963450 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -64,6 +64,7 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re
 
 int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self);
 int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool remove);
+int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem);
 
 int cg_split_spec(const char *spec, char **controller, char **path);
 int cg_join_spec(const char *controller, const char *path, char **spec);
@@ -81,6 +82,7 @@ int cg_delete(const char *controller, const char *path);
 
 int cg_create(const char *controller, const char *path);
 int cg_attach(const char *controller, const char *path, pid_t pid);
+int cg_attach_fallback(const char *controller, const char *path, pid_t pid);
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
 
 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
@@ -126,10 +128,10 @@ bool cg_controller_is_valid(const char *p, bool allow_named);
 
 int cg_slice_to_path(const char *unit, char **ret);
 
-int cg_create_with_mask(CGroupControllerMask mask, const char *path);
-int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid);
-int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids);
-int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to);
-int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root);
+int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path);
+int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid);
+int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids);
+int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to);
+int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root);
 
 CGroupControllerMask cg_mask_supported(void);



More information about the systemd-commits mailing list