X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Funit.c;h=b245356887a3fa7c6e588e988e30b3521f862ae9;hb=f440e1bb8a0b1262c7649da502d0e9358019b968;hp=447f2015ab5b50315272d806a6c86e6717c6608e;hpb=cf1265e188e876dda906dca0029248a06dc80c33;p=elogind.git diff --git a/src/core/unit.c b/src/core/unit.c index 447f2015a..b24535688 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -433,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); @@ -1987,7 +1991,7 @@ char *unit_dbus_path(Unit *u) { } char *unit_default_cgroup_path(Unit *u) { - _cleanup_free_ char *escaped_instance = NULL, *slice = NULL; + _cleanup_free_ char *escaped = NULL, *slice = NULL; int r; assert(u); @@ -2001,31 +2005,19 @@ char *unit_default_cgroup_path(Unit *u) { return NULL; } - escaped_instance = cg_escape(u->id); - if (!escaped_instance) + escaped = cg_escape(u->id); + if (!escaped) return NULL; - if (u->instance) { - _cleanup_free_ char *t = NULL, *escaped_template = NULL; - - t = unit_name_template(u->id); - if (!t) - return NULL; - - escaped_template = cg_escape(t); - if (!escaped_template) - return NULL; - - return strjoin(u->manager->cgroup_root, "/", - slice ? slice : "", slice ? "/" : "", - escaped_template, "/", escaped_instance, NULL); - } else - return strjoin(u->manager->cgroup_root, "/", - slice ? slice : "", slice ? "/" : "", - escaped_instance, NULL); + if (slice) + return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL); + else + return strjoin(u->manager->cgroup_root, "/", escaped, NULL); } int unit_add_default_slice(Unit *u) { + _cleanup_free_ char *b = NULL; + const char *slice_name; Unit *slice; int r; @@ -2037,7 +2029,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; @@ -2128,7 +2151,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; @@ -2302,11 +2326,13 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { char *s; s = strdup(v); - if (!v) + if (!s) return -ENOMEM; free(u->cgroup_path); u->cgroup_path = s; + + hashmap_put(u->manager->cgroup_unit, s, u); continue; } @@ -2707,6 +2733,7 @@ CGroupContext *unit_get_cgroup_context(Unit *u) { } static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) { + _cleanup_free_ char *b = NULL; char *p, *q; int r; @@ -2716,7 +2743,11 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c assert(_q); assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)); - if (!filename_is_safe(name)) + b = xescape(name, "/."); + if (!b) + return -ENOMEM; + + if (!filename_is_safe(b)) return -EINVAL; if (u->manager->running_as == SYSTEMD_USER) { @@ -2736,7 +2767,7 @@ static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, c if (!p) return -ENOMEM; - q = strjoin(p, "/90-", name, ".conf", NULL); + q = strjoin(p, "/90-", b, ".conf", NULL); if (!q) { free(p); return -ENOMEM; @@ -2766,7 +2797,29 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co return write_string_file_atomic_label(q, data); } -int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { +int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { + _cleanup_free_ char *p = NULL; + va_list ap; + int r; + + assert(u); + assert(name); + assert(format); + + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return unit_write_drop_in(u, mode, name, p); +} + +int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { _cleanup_free_ char *ndata = NULL; assert(u); @@ -2776,6 +2829,9 @@ int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, cons if (!UNIT_VTABLE(u)->private_section) return -EINVAL; + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); if (!ndata) return -ENOMEM; @@ -2783,6 +2839,28 @@ int unit_write_drop_in_private_section(Unit *u, UnitSetPropertiesMode mode, cons return unit_write_drop_in(u, mode, name, ndata); } +int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { + _cleanup_free_ char *p = NULL; + va_list ap; + int r; + + assert(u); + assert(name); + assert(format); + + if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME))) + return 0; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return unit_write_drop_in_private(u, mode, name, p); +} + int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { _cleanup_free_ char *p = NULL, *q = NULL; int r;