chiark / gitweb /
cgroup: don't ever try to destroy the cgroup of the root slice
[elogind.git] / src / core / unit.c
index c6c9c18653485b56d15aa612f44e44f270dae9c2..bfde08d68cf429ece1686ad5db35c750d915cbb5 100644 (file)
@@ -60,7 +60,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SNAPSHOT] = &snapshot_vtable,
         [UNIT_SWAP] = &swap_vtable,
         [UNIT_PATH] = &path_vtable,
-        [UNIT_SLICE] = &slice_vtable
+        [UNIT_SLICE] = &slice_vtable,
+        [UNIT_SCOPE] = &scope_vtable
 };
 
 Unit *unit_new(Manager *m, size_t size) {
@@ -230,8 +231,13 @@ int unit_set_description(Unit *u, const char *description) {
 
         assert(u);
 
-        if (!(s = strdup(description)))
-                return -ENOMEM;
+        if (isempty(description))
+                s = NULL;
+        else {
+                s = strdup(description);
+                if (!s)
+                        return -ENOMEM;
+        }
 
         free(u->description);
         u->description = s;
@@ -305,9 +311,6 @@ void unit_add_to_gc_queue(Unit *u) {
         u->in_gc_queue = true;
 
         u->manager->n_in_gc_queue ++;
-
-        if (u->manager->gc_queue_timestamp <= 0)
-                u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
 }
 
 void unit_add_to_dbus_queue(Unit *u) {
@@ -430,7 +433,11 @@ void unit_free(Unit *u) {
         if (u->in_cgroup_queue)
                 LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u);
 
-        free(u->cgroup_path);
+        if (u->cgroup_path) {
+                hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
+                free(u->cgroup_path);
+        }
+
         free(u->description);
         strv_free(u->documentation);
         free(u->fragment_path);
@@ -2023,6 +2030,8 @@ char *unit_default_cgroup_path(Unit *u) {
 }
 
 int unit_add_default_slice(Unit *u) {
+        _cleanup_free_ char *b = NULL;
+        const char *slice_name;
         Unit *slice;
         int r;
 
@@ -2034,7 +2043,38 @@ int unit_add_default_slice(Unit *u) {
         if (!unit_get_cgroup_context(u))
                 return 0;
 
-        r = manager_load_unit(u->manager, u->manager->running_as == SYSTEMD_SYSTEM ? SPECIAL_SYSTEM_SLICE : SPECIAL_ROOT_SLICE, NULL, NULL, &slice);
+        if (u->instance) {
+                _cleanup_free_ char *prefix = NULL, *escaped = NULL;
+                        ;
+                /* Implicitly place all instantiated units in their
+                 * own per-template slice */
+
+                prefix = unit_name_to_prefix(u->id);
+                if (!prefix)
+                        return -ENOMEM;
+
+                /* The prefix is already escaped, but it might include
+                 * "-" which has a special meaning for slice units,
+                 * hence escape it here extra. */
+                escaped = strreplace(prefix, "-", "\\x2d");
+                if (!escaped)
+                        return -ENOMEM;
+
+                if (u->manager->running_as == SYSTEMD_SYSTEM)
+                        b = strjoin("system-", escaped, ".slice", NULL);
+                else
+                        b = strappend(escaped, ".slice");
+                if (!b)
+                        return -ENOMEM;
+
+                slice_name = b;
+        } else
+                slice_name =
+                        u->manager->running_as == SYSTEMD_SYSTEM
+                        ? SPECIAL_SYSTEM_SLICE
+                        : SPECIAL_ROOT_SLICE;
+
+        r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
         if (r < 0)
                 return r;
 
@@ -2125,7 +2165,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         if (!unit_can_serialize(u))
                 return 0;
 
-        if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
+        r = UNIT_VTABLE(u)->serialize(u, f, fds);
+        if (r < 0)
                 return r;
 
 
@@ -2304,6 +2345,8 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                         free(u->cgroup_path);
                         u->cgroup_path = s;
+
+                        hashmap_put(u->manager->cgroup_unit, s, u);
                         continue;
                 }