diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/cgroup.c | 69 | ||||
-rw-r--r-- | src/core/dbus-manager.c | 2 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 5 | ||||
-rw-r--r-- | src/core/manager.h | 2 | ||||
-rw-r--r-- | src/core/service.c | 2 | ||||
-rw-r--r-- | src/core/socket.c | 4 | ||||
-rw-r--r-- | src/core/special.h | 4 | ||||
-rw-r--r-- | src/core/unit-printf.c | 28 | ||||
-rw-r--r-- | src/core/unit.c | 27 | ||||
-rw-r--r-- | src/core/unit.h | 3 |
10 files changed, 74 insertions, 72 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index a995d1436d..5065329739 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -32,6 +32,7 @@ #include "log.h" #include "strv.h" #include "path-util.h" +#include "special.h" int cgroup_bonding_realize(CGroupBonding *b) { int r; @@ -304,7 +305,8 @@ int cgroup_bonding_is_empty_list(CGroupBonding *first) { LIST_FOREACH(by_unit, b, first) { int r; - if ((r = cgroup_bonding_is_empty(b)) < 0) { + r = cgroup_bonding_is_empty(b); + if (r < 0) { /* If this returned -EAGAIN, then we don't know if the * group is empty, so let's see if another group can * tell us */ @@ -319,10 +321,9 @@ int cgroup_bonding_is_empty_list(CGroupBonding *first) { } int manager_setup_cgroup(Manager *m) { - _cleanup_free_ char *current = NULL, *path = NULL; - char suffix_buffer[sizeof("/systemd-") + DECIMAL_STR_MAX(pid_t)]; - const char *suffix; + _cleanup_free_ char *path = NULL; int r; + char *e, *a; assert(m); @@ -333,37 +334,30 @@ int manager_setup_cgroup(Manager *m) { } /* 1. Determine hierarchy */ - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t); + free(m->cgroup_root); + m->cgroup_root = NULL; + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &m->cgroup_root); if (r < 0) { log_error("Cannot determine cgroup we are running in: %s", strerror(-r)); return r; } - if (m->running_as == SYSTEMD_SYSTEM) - suffix = NULL; - else { - sprintf(suffix_buffer, "/systemd-%lu", (unsigned long) getpid()); - suffix = suffix_buffer; + /* Already in /system.slice? If so, let's cut this off again */ + if (m->running_as == SYSTEMD_SYSTEM) { + e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + if (e) + *e = 0; } - free(m->cgroup_hierarchy); - if (!suffix || endswith(current, suffix)) { - /* We probably got reexecuted and can continue to use our root cgroup */ - m->cgroup_hierarchy = current; - current = NULL; - } else { - /* We need a new root cgroup */ - if (streq(current, "/")) - m->cgroup_hierarchy = strdup(suffix); - else - m->cgroup_hierarchy = strappend(current, suffix); - - if (!m->cgroup_hierarchy) - return log_oom(); - } + /* And make sure to store away the root value without trailing + * slash, even for the root dir, so that we can easily prepend + * it everywhere. */ + if (streq(m->cgroup_root, "/")) + m->cgroup_root[0] = 0; /* 2. Show data */ - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path); + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, NULL, &path); if (r < 0) { log_error("Cannot find cgroup mount point: %s", strerror(-r)); return r; @@ -382,8 +376,9 @@ int manager_setup_cgroup(Manager *m) { log_debug("Release agent already installed."); } - /* 4. Realize the group */ - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0); + /* 4. Realize the system slice and put us in there */ + a = strappenda(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, a, 0); if (r < 0) { log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); return r; @@ -402,30 +397,24 @@ int manager_setup_cgroup(Manager *m) { /* 6. Remove non-existing controllers from the default controllers list */ cg_shorten_controllers(m->default_controllers); - /* 7. Let's create the user and machine hierarchies - * right-away, so that people can inotify on them, if they - * wish, without this being racy. */ - if (m->running_as == SYSTEMD_SYSTEM) { - cg_create(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, "../user"); - cg_create(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, "../machine"); - } - return 0; } void manager_shutdown_cgroup(Manager *m, bool delete) { assert(m); - if (delete && m->cgroup_hierarchy) - cg_delete(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy); + /* We can't really delete the group, since we are in it. But + * let's trim it. */ + if (delete && m->cgroup_root) + cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, false); if (m->pin_cgroupfs_fd >= 0) { close_nointr_nofail(m->pin_cgroupfs_fd); m->pin_cgroupfs_fd = -1; } - free(m->cgroup_hierarchy); - m->cgroup_hierarchy = NULL; + free(m->cgroup_root); + m->cgroup_root = NULL; } int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) { diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 25d38cc491..d41b6ae15f 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -301,7 +301,6 @@ " <property name=\"ConfirmSpawn\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"ShowStatus\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"UnitPath\" type=\"as\" access=\"read\"/>\n" \ - " <property name=\"ControlGroupHierarchy\" type=\"s\" access=\"read\"/>\n" \ " <property name=\"DefaultControllers\" type=\"as\" access=\"read\"/>\n" \ " <property name=\"DefaultStandardOutput\" type=\"s\" access=\"read\"/>\n" \ " <property name=\"DefaultStandardError\" type=\"s\" access=\"read\"/>\n" \ @@ -614,7 +613,6 @@ static const BusProperty bus_manager_properties[] = { { "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) }, { "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) }, { "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true }, - { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_hierarchy), true }, { "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true }, { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) }, { "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) }, diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index b7391b5506..8a7ab349d1 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -89,10 +89,7 @@ static int bus_unit_append_slice(DBusMessageIter *i, const char *property, void assert(property); assert(u); - if (UNIT_DEREF(u->slice)) - d = UNIT_DEREF(u->slice)->id; - else - d = ""; + d = strempty(unit_slice_name(u)); if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) return -ENOMEM; diff --git a/src/core/manager.h b/src/core/manager.h index dcc4ebed92..e21c8f7abf 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -199,7 +199,7 @@ struct Manager { /* Data specific to the cgroup subsystem */ Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ - char *cgroup_hierarchy; + char *cgroup_root; usec_t gc_queue_timestamp; int gc_marker; diff --git a/src/core/service.c b/src/core/service.c index ac8cdb2c31..a0c648a85b 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -220,7 +220,7 @@ static void service_close_socket_fd(Service *s) { static void service_connection_unref(Service *s) { assert(s); - if (!UNIT_DEREF(s->accept_socket)) + if (!UNIT_ISSET(s->accept_socket)) return; socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); diff --git a/src/core/socket.c b/src/core/socket.c index 2b3b6813ca..2f25e25aa6 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1005,7 +1005,7 @@ static int socket_open_fds(Socket *s) { if ((r = socket_instantiate_service(s)) < 0) return r; - if (UNIT_DEREF(s->service) && + if (UNIT_ISSET(s->service) && SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); @@ -1633,7 +1633,7 @@ static int socket_start(Unit *u) { return 0; /* Cannot run this without the service being around */ - if (UNIT_DEREF(s->service)) { + if (UNIT_ISSET(s->service)) { Service *service; service = SERVICE(UNIT_DEREF(s->service)); diff --git a/src/core/special.h b/src/core/special.h index e183056a20..337a0a43e9 100644 --- a/src/core/special.h +++ b/src/core/special.h @@ -114,5 +114,7 @@ #define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target" #define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target" -/* Where we add all our system units by default */ +/* Where we add all our system units, users and machines by default */ #define SPECIAL_SYSTEM_SLICE "system.slice" +#define SPECIAL_USER_SLICE "user.slice" +#define SPECIAL_MACHINE_SLICE "machine.slice" diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 85a05b872a..caf51259d2 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -27,6 +27,8 @@ #include "unit-name.h" #include "unit-printf.h" #include "macro.h" +#include "cgroup-util.h" +#include "special.h" static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { Unit *u = userdata; @@ -86,22 +88,22 @@ static char *specifier_cgroup(char specifier, void *data, void *userdata) { } static char *specifier_cgroup_root(char specifier, void *data, void *userdata) { + _cleanup_free_ char *p = NULL; Unit *u = userdata; - char *p; - assert(u); + const char *slice; + int r; - if (specifier == 'r') - return strdup(u->manager->cgroup_hierarchy); + assert(u); - if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0) - return strdup(""); + slice = unit_slice_name(u); + if (specifier == 'R' || !slice) + return strdup(u->manager->cgroup_root); - if (streq(p, "/")) { - free(p); - return strdup(""); - } + r = cg_slice_to_path(slice, &p); + if (r < 0) + return NULL; - return p; + return strjoin(u->manager->cgroup_root, "/", p, NULL); } static char *specifier_runtime(char specifier, void *data, void *userdata) { @@ -256,8 +258,8 @@ char *unit_full_printf(Unit *u, const char *format) { * * %f the the instance if set, otherwise the id * %c cgroup path of unit - * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711") - * %R parent of root cgroup path (e.g. "/usr/lennart/shared") + * %r where units in this slice are place in the cgroup tree + * %R the root of this systemd's instance tree * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) * %U the UID of the configured user or running user * %u the username of the configured user or running user diff --git a/src/core/unit.c b/src/core/unit.c index 90ff43da66..f75045dc48 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -672,7 +672,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tActive Exit Timestamp: %s\n" "%s\tInactive Enter Timestamp: %s\n" "%s\tGC Check Good: %s\n" - "%s\tNeed Daemon Reload: %s\n", + "%s\tNeed Daemon Reload: %s\n" + "%s\tSlice: %s\n", prefix, u->id, prefix, unit_description(u), prefix, strna(u->instance), @@ -683,7 +684,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)), prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), prefix, yes_no(unit_check_gc(u)), - prefix, yes_no(unit_need_daemon_reload(u))); + prefix, yes_no(unit_need_daemon_reload(u)), + prefix, strna(unit_slice_name(u))); SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t); @@ -878,7 +880,7 @@ static int unit_add_default_dependencies(Unit *u) { return r; } - if (u->default_dependencies && UNIT_DEREF(u->slice)) { + if (u->default_dependencies && UNIT_ISSET(u->slice)) { r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); if (r < 0) return r; @@ -1994,7 +1996,7 @@ char *unit_default_cgroup_path(Unit *u) { assert(u); - if (UNIT_DEREF(u->slice)) { + if (UNIT_ISSET(u->slice)) { r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice); if (r < 0) return NULL; @@ -2015,11 +2017,11 @@ char *unit_default_cgroup_path(Unit *u) { if (!escaped_template) return NULL; - return strjoin(u->manager->cgroup_hierarchy, "/", + return strjoin(u->manager->cgroup_root, "/", slice ? slice : "", slice ? "/" : "", escaped_template, "/", escaped_instance, NULL); } else - return strjoin(u->manager->cgroup_hierarchy, "/", + return strjoin(u->manager->cgroup_root, "/", slice ? slice : "", slice ? "/" : "", escaped_instance, NULL); } @@ -2172,7 +2174,7 @@ int unit_add_default_slice(Unit *u) { assert(u); - if (UNIT_DEREF(u->slice)) + if (UNIT_ISSET(u->slice)) return 0; if (u->manager->running_as != SYSTEMD_SYSTEM) @@ -2186,6 +2188,15 @@ int unit_add_default_slice(Unit *u) { return 0; } +const char *unit_slice_name(Unit *u) { + assert(u); + + if (!UNIT_ISSET(u->slice)) + return NULL; + + return UNIT_DEREF(u->slice)->id; +} + int unit_add_default_cgroups(Unit *u) { CGroupAttribute *a; char **c; @@ -2196,7 +2207,7 @@ int unit_add_default_cgroups(Unit *u) { /* Adds in the default cgroups, if they weren't specified * otherwise. */ - if (!u->manager->cgroup_hierarchy) + if (!u->manager->cgroup_root) return 0; r = unit_add_one_default_cgroup(u, NULL); diff --git a/src/core/unit.h b/src/core/unit.h index 81b8adbfdc..da52101bd2 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -542,6 +542,8 @@ void unit_reset_failed(Unit *u); Unit *unit_following(Unit *u); +const char *unit_slice_name(Unit *u); + bool unit_stop_pending(Unit *u) _pure_; bool unit_inactive_or_pending(Unit *u) _pure_; bool unit_active_or_pending(Unit *u); @@ -563,6 +565,7 @@ Unit* unit_ref_set(UnitRef *ref, Unit *u); void unit_ref_unset(UnitRef *ref); #define UNIT_DEREF(ref) ((ref).unit) +#define UNIT_ISSET(ref) (!!(ref).unit) int unit_add_one_mount_link(Unit *u, Mount *m); int unit_add_mount_links(Unit *u); |