From 85ae4be4f12973a1930e3f95781d9af98322af00 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 14:50:05 +0100 Subject: [PATCH 01/10] units: fix system.slice to require -.slice, instead of just want it --- units/system.slice | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/system.slice b/units/system.slice index c0e3df9d0f..841f049b58 100644 --- a/units/system.slice +++ b/units/system.slice @@ -10,5 +10,5 @@ Description=System Slice Documentation=man:systemd.special(7) DefaultDependencies=no Before=slices.target -Wants=-.slice +Requires=-.slice After=-.slice From 176ee07b690a14b7f231eb719a8baa5d568c3657 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 16:04:29 +0100 Subject: [PATCH 02/10] journalctl: refuse to --machine= in combination with --flush, --sync or --rotate --- src/journal/journalctl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 521360b11b..7367604231 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1771,6 +1771,11 @@ static int flush_to_var(void) { _cleanup_close_ int watch_fd = -1; int r; + if (arg_machine) { + log_error("--flush is not supported in conjunction with --machine=."); + return -EOPNOTSUPP; + } + /* Quick exit */ if (access("/run/systemd/journal/flushed", F_OK) >= 0) return 0; @@ -1828,6 +1833,11 @@ static int send_signal_and_wait(int sig, const char *watch_path) { usec_t start; int r; + if (arg_machine) { + log_error("--sync and --rotate are not supported in conjunction with --machine=."); + return -EOPNOTSUPP; + } + start = now(CLOCK_REALTIME); /* This call sends the specified signal to journald, and waits From a020b3b3321c2d19263ac6e163a5a5787501d823 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 16:21:30 +0100 Subject: [PATCH 03/10] journalctl: change repeated if checks into switch blocks No functional changes. --- src/journal/journalctl.c | 102 ++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 7367604231..ac0751c547 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -133,9 +133,9 @@ static enum { ACTION_UPDATE_CATALOG, ACTION_LIST_BOOTS, ACTION_FLUSH, + ACTION_SYNC, ACTION_ROTATE, ACTION_VACUUM, - ACTION_SYNC, } arg_action = ACTION_SHOW; typedef struct BootId { @@ -1945,35 +1945,19 @@ int main(int argc, char *argv[]) { * be split up into many files. */ setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384)); - if (arg_action == ACTION_NEW_ID128) { + switch (arg_action) { + + case ACTION_NEW_ID128: r = generate_new_id128(); goto finish; - } - if (arg_action == ACTION_FLUSH) { - r = flush_to_var(); - goto finish; - } - - if (arg_action == ACTION_SYNC) { - r = sync_journal(); - goto finish; - } - - if (arg_action == ACTION_ROTATE) { - r = rotate(); - goto finish; - } - - if (arg_action == ACTION_SETUP_KEYS) { + case ACTION_SETUP_KEYS: r = setup_keys(); goto finish; - } - - if (arg_action == ACTION_UPDATE_CATALOG || - arg_action == ACTION_LIST_CATALOG || - arg_action == ACTION_DUMP_CATALOG) { + case ACTION_LIST_CATALOG: + case ACTION_DUMP_CATALOG: + case ACTION_UPDATE_CATALOG: { _cleanup_free_ char *database; database = path_join(arg_root, CATALOG_DATABASE, NULL); @@ -1990,9 +1974,9 @@ int main(int argc, char *argv[]) { bool oneline = arg_action == ACTION_LIST_CATALOG; pager_open_if_enabled(); + if (optind < argc) - r = catalog_list_items(stdout, database, - oneline, argv + optind); + r = catalog_list_items(stdout, database, oneline, argv + optind); else r = catalog_list(stdout, database, oneline); if (r < 0) @@ -2002,6 +1986,31 @@ int main(int argc, char *argv[]) { goto finish; } + case ACTION_FLUSH: + r = flush_to_var(); + goto finish; + + case ACTION_SYNC: + r = sync_journal(); + goto finish; + + case ACTION_ROTATE: + r = rotate(); + goto finish; + + case ACTION_SHOW: + case ACTION_PRINT_HEADER: + case ACTION_VERIFY: + case ACTION_DISK_USAGE: + case ACTION_LIST_BOOTS: + case ACTION_VACUUM: + /* These ones require access to the journal files, continue below. */ + break; + + default: + assert_not_reached("Unknown action"); + } + if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); else if (arg_file) @@ -2011,8 +2020,7 @@ int main(int argc, char *argv[]) { else r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { - log_error_errno(r, "Failed to open %s: %m", - arg_directory ? arg_directory : arg_file ? "files" : "journal"); + log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal"); goto finish; } @@ -2020,18 +2028,28 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; - if (arg_action == ACTION_VERIFY) { - r = verify(j); - goto finish; - } + switch (arg_action) { - if (arg_action == ACTION_PRINT_HEADER) { + case ACTION_NEW_ID128: + case ACTION_SETUP_KEYS: + case ACTION_LIST_CATALOG: + case ACTION_DUMP_CATALOG: + case ACTION_UPDATE_CATALOG: + case ACTION_FLUSH: + case ACTION_SYNC: + case ACTION_ROTATE: + assert_not_reached("Unexpected action."); + + case ACTION_PRINT_HEADER: journal_print_header(j); r = 0; goto finish; - } - if (arg_action == ACTION_DISK_USAGE) { + case ACTION_VERIFY: + r = verify(j); + goto finish; + + case ACTION_DISK_USAGE: { uint64_t bytes = 0; char sbytes[FORMAT_BYTES_MAX]; @@ -2044,7 +2062,11 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_VACUUM) { + case ACTION_LIST_BOOTS: + r = list_boots(j); + goto finish; + + case ACTION_VACUUM: { Directory *d; Iterator i; @@ -2064,9 +2086,11 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_LIST_BOOTS) { - r = list_boots(j); - goto finish; + case ACTION_SHOW: + break; + + default: + assert_not_reached("Unknown action"); } /* add_boot() must be called first! From cb4c247d48fc195e64dd895a4e9dc8162ae62b23 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 16:22:25 +0100 Subject: [PATCH 04/10] core: change default deps of services to require sysinit.target instead of basic.target With this change services by default will no longer require basic.target, but instead only after it it via After=basic.target. However, they will still Require= on sysinit.target. This has the benefit that when booting into emergency mode it is relatively safe to actviate individual services, as this will not pull the entirety of basic.target anymore, thus avoid everything listed in sockets.target and suchlike. However, during the usual boot no change should be noticed. --- src/core/service.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 74bbadd3ff..a19b98dc59 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -518,12 +518,32 @@ static int service_add_default_dependencies(Service *s) { /* Add a number of automatic dependencies useful for the * majority of services. */ - /* First, pull in base system */ - r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true); + if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + /* First, pull in the really early boot stuff, and + * require it, so that we fail if we can't acquire + * it. */ + + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); + if (r < 0) + return r; + } else { + + /* In the --user instance there's no sysinit.target, + * in that case require basic.target instead. */ + + r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true); + if (r < 0) + return r; + } + + /* Second, if the rest of the base system is in the same + * transaction, order us after it, but do not pull it in or + * even require it. */ + r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true); if (r < 0) return r; - /* Second, activate normal shutdown */ + /* Third, add us in for normal shutdown. */ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); } From 45f06b3450174a9649a51a0b48fdbbbe98f2bb5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 20:39:41 +0100 Subject: [PATCH 05/10] core: pull in dbus.socket from Type=dbus services Do so only on non-kdbus systems. And on non-kdbus systems don't bother with .busname units. --- src/core/service.c | 65 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index a19b98dc59..e9d259b84f 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -515,6 +515,9 @@ static int service_add_default_dependencies(Service *s) { assert(s); + if (!UNIT(s)->default_dependencies) + return 0; + /* Add a number of automatic dependencies useful for the * majority of services. */ @@ -565,6 +568,43 @@ static void service_fix_output(Service *s) { s->exec_context.std_output = UNIT(s)->manager->default_std_output; } +static int service_setup_bus_name(Service *s) { + int r; + + assert(s); + + if (!s->bus_name) + return 0; + + if (is_kdbus_available()) { + const char *n; + + n = strjoina(s->bus_name, ".busname"); + r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true); + if (r < 0) + return log_unit_error_errno(UNIT(s), r, "Failed to add dependency to .busname unit: %m"); + + } else { + /* If kdbus is not available, we know the dbus socket is required, hence pull it in, and require it */ + r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true); + if (r < 0) + return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m"); + } + + /* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */ + r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true); + if (r < 0) + return log_unit_error_errno(UNIT(s), r, "Failed to add depdendency on " SPECIAL_DBUS_SOCKET ": %m"); + + r = unit_watch_bus_name(UNIT(s), s->bus_name); + if (r == -EEXIST) + return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name); + if (r < 0) + return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name); + + return 0; +} + static int service_add_extras(Service *s) { int r; @@ -604,26 +644,13 @@ static int service_add_extras(Service *s) { if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE) s->notify_access = NOTIFY_MAIN; - if (s->bus_name) { - const char *n; + r = service_add_default_dependencies(s); + if (r < 0) + return r; - n = strjoina(s->bus_name, ".busname"); - r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true); - if (r < 0) - return r; - - r = unit_watch_bus_name(UNIT(s), s->bus_name); - if (r == -EEXIST) - return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name); - if (r < 0) - return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name); - } - - if (UNIT(s)->default_dependencies) { - r = service_add_default_dependencies(s); - if (r < 0) - return r; - } + r = service_setup_bus_name(s); + if (r < 0) + return r; return 0; } From 4c9ea260aeaff2e837f543e3c42d2e7102af1137 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 20:42:39 +0100 Subject: [PATCH 06/10] core: simplify things a bit by checking default_dependencies boolean in callee, not caller It's nicer to hide the check away in the various xyz_add_default_dependencies() calls, rather than making it explicit in the caller, and thus require deeper nesing. --- src/core/automount.c | 11 ++++++----- src/core/mount.c | 11 ++++++----- src/core/path.c | 20 +++++++++----------- src/core/scope.c | 11 ++++++----- src/core/slice.c | 12 ++++++------ src/core/socket.c | 11 ++++++----- src/core/swap.c | 11 ++++++----- src/core/timer.c | 11 ++++++----- 8 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index 4c229247c5..41ead117c8 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -148,6 +148,9 @@ static int automount_add_default_dependencies(Automount *a) { assert(a); + if (!UNIT(a)->default_dependencies) + return 0; + if (UNIT(a)->manager->running_as != MANAGER_SYSTEM) return 0; @@ -219,11 +222,9 @@ static int automount_load(Unit *u) { if (r < 0) return r; - if (UNIT(a)->default_dependencies) { - r = automount_add_default_dependencies(a); - if (r < 0) - return r; - } + r = automount_add_default_dependencies(a); + if (r < 0) + return r; } return automount_verify(a); diff --git a/src/core/mount.c b/src/core/mount.c index d3766ba934..49525ebb78 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -393,6 +393,9 @@ static int mount_add_default_dependencies(Mount *m) { assert(m); + if (!UNIT(m)->default_dependencies) + return 0; + if (UNIT(m)->manager->running_as != MANAGER_SYSTEM) return 0; @@ -533,11 +536,9 @@ static int mount_add_extras(Mount *m) { if (r < 0) return r; - if (u->default_dependencies) { - r = mount_add_default_dependencies(m); - if (r < 0) - return r; - } + r = mount_add_default_dependencies(m); + if (r < 0) + return r; return 0; } diff --git a/src/core/path.c b/src/core/path.c index 35e1753583..c0992b4fcc 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -315,20 +315,20 @@ static int path_add_default_dependencies(Path *p) { assert(p); - r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, - SPECIAL_PATHS_TARGET, NULL, true); + if (!UNIT(p)->default_dependencies) + return 0; + + r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_PATHS_TARGET, NULL, true); if (r < 0) return r; if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) { - r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, - SPECIAL_SYSINIT_TARGET, NULL, true); + r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; } - return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, - SPECIAL_SHUTDOWN_TARGET, NULL, true); + return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); } static int path_load(Unit *u) { @@ -360,11 +360,9 @@ static int path_load(Unit *u) { if (r < 0) return r; - if (UNIT(p)->default_dependencies) { - r = path_add_default_dependencies(p); - if (r < 0) - return r; - } + r = path_add_default_dependencies(p); + if (r < 0) + return r; } return path_verify(p); diff --git a/src/core/scope.c b/src/core/scope.c index 8d6149aab0..5f6527c155 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -122,6 +122,9 @@ static int scope_add_default_dependencies(Scope *s) { assert(s); + if (!UNIT(s)->default_dependencies) + return 0; + /* Make sure scopes are unloaded on shutdown */ r = unit_add_two_dependencies_by_name( UNIT(s), @@ -173,11 +176,9 @@ static int scope_load(Unit *u) { if (r < 0) return r; - if (u->default_dependencies) { - r = scope_add_default_dependencies(s); - if (r < 0) - return r; - } + r = scope_add_default_dependencies(s); + if (r < 0) + return r; return scope_verify(s); } diff --git a/src/core/slice.c b/src/core/slice.c index 2aa3fbf8be..39dabae055 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -85,6 +85,9 @@ static int slice_add_default_dependencies(Slice *s) { assert(s); + if (!UNIT(s)->default_dependencies) + return 0; + /* Make sure slices are unloaded on shutdown */ r = unit_add_two_dependencies_by_name( UNIT(s), @@ -96,7 +99,6 @@ static int slice_add_default_dependencies(Slice *s) { return 0; } - static int slice_verify(Slice *s) { _cleanup_free_ char *parent = NULL; int r; @@ -144,11 +146,9 @@ static int slice_load(Unit *u) { if (r < 0) return r; - if (u->default_dependencies) { - r = slice_add_default_dependencies(s); - if (r < 0) - return r; - } + r = slice_add_default_dependencies(s); + if (r < 0) + return r; } return slice_verify(s); diff --git a/src/core/socket.c b/src/core/socket.c index c73ee78b13..43d4ec5dca 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -296,6 +296,9 @@ static int socket_add_default_dependencies(Socket *s) { int r; assert(s); + if (!UNIT(s)->default_dependencies) + return 0; + r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true); if (r < 0) return r; @@ -365,11 +368,9 @@ static int socket_add_extras(Socket *s) { return r; } - if (u->default_dependencies) { - r = socket_add_default_dependencies(s); - if (r < 0) - return r; - } + r = socket_add_default_dependencies(s); + if (r < 0) + return r; return 0; } diff --git a/src/core/swap.c b/src/core/swap.c index e44cffc2e8..ee0838e676 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -213,6 +213,9 @@ static int swap_add_device_links(Swap *s) { static int swap_add_default_dependencies(Swap *s) { assert(s); + if (!UNIT(s)->default_dependencies) + return 0; + if (UNIT(s)->manager->running_as != MANAGER_SYSTEM) return 0; @@ -331,11 +334,9 @@ static int swap_load(Unit *u) { if (r < 0) return r; - if (UNIT(s)->default_dependencies) { - r = swap_add_default_dependencies(s); - if (r < 0) - return r; - } + r = swap_add_default_dependencies(s); + if (r < 0) + return r; } return swap_verify(s); diff --git a/src/core/timer.c b/src/core/timer.c index c9dc97d4fb..c50e891aeb 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -102,6 +102,9 @@ static int timer_add_default_dependencies(Timer *t) { assert(t); + if (!UNIT(t)->default_dependencies) + return 0; + r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true); if (r < 0) return r; @@ -192,11 +195,9 @@ static int timer_load(Unit *u) { if (r < 0) return r; - if (u->default_dependencies) { - r = timer_add_default_dependencies(t); - if (r < 0) - return r; - } + r = timer_add_default_dependencies(t); + if (r < 0) + return r; } return timer_verify(t); From ea0ec5cea734239bf1f25aa63c62853a4beae1ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 20:46:09 +0100 Subject: [PATCH 07/10] core: simplify mount unit dependency generation a bit Let's make the code a bit more explicit. Should not change execution logic in any way. --- src/core/mount.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 49525ebb78..e86bcf3830 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -387,8 +387,8 @@ static bool should_umount(Mount *m) { } static int mount_add_default_dependencies(Mount *m) { - const char *after, *after2, *online; MountParameters *p; + const char *after; int r; assert(m); @@ -416,31 +416,35 @@ static int mount_add_default_dependencies(Mount *m) { return 0; if (mount_is_network(p)) { + /* We order ourselves after network.target. This is + * primarily useful at shutdown: services that take + * down the network should order themselves before + * network.target, so that they are shut down only + * after this mount unit is stopped. */ + + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, NULL, true); + if (r < 0) + return r; + + /* We pull in network-online.target, and order + * ourselves after it. This is useful at start-up to + * actively pull in tools that want to be started + * before we start mounting network file systems, and + * whose purpose it is to delay this until the network + * is "up". */ + + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, NULL, true); + if (r < 0) + return r; + after = SPECIAL_REMOTE_FS_PRE_TARGET; - after2 = SPECIAL_NETWORK_TARGET; - online = SPECIAL_NETWORK_ONLINE_TARGET; - } else { + } else after = SPECIAL_LOCAL_FS_PRE_TARGET; - after2 = NULL; - online = NULL; - } r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true); if (r < 0) return r; - if (after2) { - r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true); - if (r < 0) - return r; - } - - if (online) { - r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true); - if (r < 0) - return r; - } - if (should_umount(m)) { r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); if (r < 0) From c129bd5df3ca08eb352cf69d01d2f374552624ae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 20:47:07 +0100 Subject: [PATCH 08/10] man: document automatic dependencies For all units ensure there's an "Automatic Dependencies" section in the man page, and explain which dependencies are automatically added in all cases, and which ones are added on top if DefaultDependencies=yes is set. This is also done for systemd.exec(5), systemd.resource-control(5) and systemd.unit(5) as these pages describe common behaviour of various unit types. --- man/systemd.automount.xml | 20 ++++++++++-- man/systemd.device.xml | 11 +++++++ man/systemd.exec.xml | 44 ++++++++++++++++++++++++--- man/systemd.mount.xml | 52 +++++++++++++++++++++++++++++--- man/systemd.path.xml | 17 +++++++++-- man/systemd.resource-control.xml | 9 ++++++ man/systemd.scope.xml | 9 ++++++ man/systemd.service.xml | 49 +++++++++++++++++++++--------- man/systemd.slice.xml | 8 +++++ man/systemd.socket.xml | 46 +++++++++++++++++++++++++--- man/systemd.swap.xml | 34 +++++++++++++++------ man/systemd.target.xml | 15 ++++++--- man/systemd.timer.xml | 32 +++++++++++++------- man/systemd.unit.xml | 33 +++++++++++++++----- 14 files changed, 312 insertions(+), 67 deletions(-) diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml index 26a0f291dd..1b0ae832da 100644 --- a/man/systemd.automount.xml +++ b/man/systemd.automount.xml @@ -85,10 +85,24 @@ Automount units may be used to implement on-demand mounting as well as parallelized mounting of file systems. + + + + Automatic Dependencies + + If an automount unit is beneath another mount unit in the + file system hierarchy, both a requirement and an ordering + dependency between both units are created automatically. + + An implicit Before= dependency is created + between an automount unit and the mount unit it activates. + + Automount units acquire automatic Before= + and Conflicts= on + umount.target in order to be stopped during + shutdown, unless DefaultDependencies=no is + set. - If an automount point is beneath another mount point in the - file system hierarchy, a dependency between both units is created - automatically. diff --git a/man/systemd.device.xml b/man/systemd.device.xml index ac6deafb18..effed098dd 100644 --- a/man/systemd.device.xml +++ b/man/systemd.device.xml @@ -83,7 +83,18 @@ the escaping logic used to convert a file system path to a unit name see systemd.unit5. + + + Automatic Dependencies + + Many unit types automatically acquire dependencies on device + units of devices they require. For example, + .socket unit acquire dependencies on the + device units of the network interface specified in + BindToDevice=. Similar, swap and mount units + acquire dependencies on the units encapsulating their backing + block devices. diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 2b090871ff..6317830ae2 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -76,6 +76,31 @@ unit type. + + Automatic Dependencies + + A few execution parameters result in additional, automatic + dependencies to be added. + + Units with WorkingDirectory= or + RootDirectory= set automatically gain + dependencies of type Requires= and + After= on all mount units required to access + the specified paths. This is equivalent to having them listed + explicitly in RequiresMountsFor=. + + Similar, units with PrivateTmp= enabled + automatically get mount unit dependencies for all mounts + required to access /tmp and + /var/tmp. + + Units whose output standard output or error output is + connected to any other sink but , + and automatically + acquire dependencies of type After= on + journald.socket. + + Options @@ -93,7 +118,9 @@ and the respective user's home directory if run as user. If the setting is prefixed with the - character, a missing working directory is not considered - fatal. + fatal. Note that setting this parameter might result in + additional dependencies to be added to the unit (see + above). @@ -104,7 +131,9 @@ project='man-pages'>chroot2 system call. If this is used, it must be ensured that the process binary and all its auxiliary files are available in - the chroot() jail. + the chroot() jail. Note that setting this + parameter might result in additional dependencies to be added + to the unit (see above). @@ -351,6 +380,7 @@ This setting defaults to . + StandardOutput= Controls where file descriptor 1 (STDOUT) of @@ -416,8 +446,11 @@ This setting defaults to the value set with in systemd-system.conf5, - which defaults to . + which defaults to . Note that setting + this parameter might result in additional dependencies to be + added to the unit (see above). + StandardError= Controls where file descriptor 2 (STDERR) of @@ -428,8 +461,11 @@ standard error. This setting defaults to the value set with in systemd-system.conf5, - which defaults to . + which defaults to . Note that setting + this parameter might result in additional dependencies to be + added to the unit (see above). + TTYPath= Sets the terminal device node to use if diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index dd6b7a51a8..67e96dc157 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -94,10 +94,6 @@ unit, to allow on-demand or parallelized mounting. See systemd.automount5. - If a mount point is beneath another mount point in the file - system hierarchy, a dependency between both units is created - automatically. - Mount points created at runtime (independently of unit files or /etc/fstab) will be monitored by systemd and appear like any other mount unit in systemd. See @@ -113,6 +109,52 @@ File Systems. + + Automatic Dependencies + + If a mount unit is beneath another mount unit in the file + system hierarchy, both a requirement dependency and an ordering + dependency between both units are created automatically. + + Block device backed file systems automatically gain + BindsTo= and After= type + dependencies on the device unit encapsulating the block + device (see below). + + If traditional file system quota is enabled for a mount + unit, automatic Wants= and + Before= dependencies on + systemd-quotacheck.service and + quotaon.service are added. + + For mount units with + DefaultDependencies=yes (the default) a couple + additional dependencies are added. Mount units referring to local + file systems automatically gain an After= + dependency on local-fs-pre.target. Network + mount units automatically acquire After= + dependencies on remote-fs-pre.target, + network.target and + network-online.target. Towards the latter a + Wants= unit is added as well. Mount units + referring to local and network file systems are distinguished by + their file system type specification. In some cases this is not + sufficient (for example network block device based mounts, such as + iSCSI), in which case may be added to the + mount option string of the unit, which forces systemd to consider the + mount unit a network mount. Mount units (regardless if local or + network) also acquire automatic Before= and + Conflicts= on + umount.target in order to be stopped + during shutdown. + + Additional implicit dependencies may be added as result of + execution and resource control parameters as documented in + systemd.exec5 + and + systemd.resource-control5. + + <filename>fstab</filename> @@ -130,7 +172,7 @@ When reading /etc/fstab a few special mount options are understood by systemd which influence how dependencies are created for mount points. systemd will create a - dependency of type or + dependency of type Wants= or (see option below), from either local-fs.target or remote-fs.target, depending whether the file diff --git a/man/systemd.path.xml b/man/systemd.path.xml index d02bc92ae6..1bd65ce86d 100644 --- a/man/systemd.path.xml +++ b/man/systemd.path.xml @@ -79,13 +79,24 @@ limitations as inotify, and for example cannot be used to monitor files or directories changed by other machines on remote NFS file systems. + - If a path unit is beneath another mount point in the file - system hierarchy, a dependency between both units is created - automatically. + + Automatic Dependencies + + If a path unit is beneath another mount unit in the file + system hierarchy, both a requirement and an ordering dependency + between both units are created automatically. + + An implicit Before= dependency is added + between a path unit and the unit it is supposed to activate. Unless DefaultDependencies=false is used, path units will implicitly have dependencies of type + Before= on paths.target, + dependencies of type After= and + Requires= on + sysinit.target, and have dependencies of type Conflicts= and Before= on shutdown.target. These ensure that path units are terminated cleanly prior to system shutdown. Only path units diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index 164adb938a..0497f60546 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -89,6 +89,15 @@ use of resource control APIs from programs. + + Automatic Dependencies + + Units with the Slice= setting set get + automatic Requires= and + After= dependencies on the specified slice + unit. + + Options diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml index fd65a851e2..f69b2ef635 100644 --- a/man/systemd.scope.xml +++ b/man/systemd.scope.xml @@ -72,6 +72,10 @@ url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New Control Group Interfaces for an introduction on how to make use of scope units from programs. + + + + Automatic Dependencies Unless DefaultDependencies=false is used, scope units will implicitly have dependencies of @@ -82,6 +86,11 @@ shutdown. Only scope units involved with early boot or late system shutdown should disable this option. + + Additional implicit dependencies may be added as result of + resource control parameters as documented in + systemd.resource-control5. + diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 4e5098f0e1..c6ed75d158 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -1,4 +1,4 @@ - + @@ -77,18 +77,6 @@ which configure resource control settings for the processes of the service. - Unless DefaultDependencies= is set to - , service units will implicitly have - dependencies of type Requires= and - After= on basic.target as - well as dependencies of type Conflicts= and - Before= on - shutdown.target. These ensure that normal - service units pull in basic system initialization, and are - terminated cleanly prior to system shutdown. Only services - involved with early boot or late system shutdown should disable - this option. - If a service is requested under a certain name but no unit configuration file is found, systemd looks for a SysV init script by the same name (with the .service suffix @@ -97,8 +85,39 @@ compatibility is quite comprehensive but not 100%. For details about the incompatibilities, see the Incompatibilities - with SysV document. - + with SysV document. + + + + Automatic Dependencies + + Services with Type=dbus set automatically + acquire dependencies of type Requires= and + After= on + dbus.socket. + + Socket activated service are automatically ordered after + their activated .socket units via an + automatic After= dependency. + + Unless DefaultDependencies= is set to + , service units will implicitly have + dependencies of type Requires= and + After= on sysinit.target, + a dependency of type After= on + basic.target as well as dependencies of + type Conflicts= and Before= + on shutdown.target. These ensure that normal + service units pull in basic system initialization, and are + terminated cleanly prior to system shutdown. Only services + involved with early boot or late system shutdown should disable + this option. + + Additional implicit dependencies may be added as result of + execution and resource control parameters as documented in + systemd.exec5 + and + systemd.resource-control5. diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml index 87c2a3bce3..5c87bf0260 100644 --- a/man/systemd.slice.xml +++ b/man/systemd.slice.xml @@ -97,6 +97,14 @@ url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New Control Group Interfaces for an introduction on how to make use of slice units from programs. + + + + Automatic Dependencies + + Slice units automatically gain dependencies of type + After= and Requires= on + their immediate parent slice unit. Unless DefaultDependencies=false is used, slice units will implicitly have dependencies of diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 410886f841..beac053bf0 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -133,6 +133,40 @@ service file). + + Automatic Dependencies + + Socket units automatically gain a Before= + dependency on the service units they activate. + + Socket units referring to file system paths (such as AF_UNIX + sockets or FIFOs) implicitly gain Requires= and + After= dependencies on all mount units + necessary to access those paths. + + Socket units using the BindToDevice= + setting automatically gain a BindsTo= and + After= dependency on the device unit + encapsulating the specified network interface. + + If DefaultDependencies=yes is set (the + default), socket units automatically gain a + Before= dependency on + sockets.target. They also gain a pair of + After= and Requires= + dependency on sysinit.target, and a pair of + Before= and Conflicts= + dependencies on shutdown.target. These + dependencies ensure that the socket unit is started before normal + services at boot, and is stopped on shutdown. + + Additional implicit dependencies may be added as result of + execution and resource control parameters as documented in + systemd.exec5 + and + systemd.resource-control5. + + Options @@ -309,12 +343,14 @@ Specifies a network interface name to bind this socket to. If set, traffic will only be accepted from the specified network interfaces. This controls the - SO_BINDTODEVICE socket option (see - socket7 + SO_BINDTODEVICE socket option (see socket7 for details). If this option is used, an automatic dependency from this socket unit on the network interface device unit (systemd.device5 - is created. + is created. Note that setting this parameter might result in + additional dependencies to be added to the unit (see + above). @@ -719,7 +755,9 @@ with Accept=no. It defaults to the service that bears the same name as the socket (with the suffix replaced). In most cases, it should not be necessary to use - this option. + this option. Note that setting this parameter might result in + additional dependencies to be added to the unit (see + above). diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index bc9ef826e1..c600405c87 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -68,14 +68,15 @@ Additional options are listed in systemd.exec5, - which define the execution environment the - swapon8 - binary is executed in, and in + which define the execution environment the swapon8 + binary is executed in, in systemd.kill5, - which define the way the processes are terminated, and in + which define the way the these processes are + terminated, and in systemd.resource-control5, - which configure resource control settings for the processes of the - service. + which configure resource control settings for these processes of the + unit. Swap units must be named after the devices or files they control. Example: the swap device @@ -84,15 +85,28 @@ the escaping logic used to convert a file system path to a unit name, see systemd.unit5. + - All swap units automatically get the appropriate - dependencies on the devices or on the mount points of the files + + Automatic Dependencies + + All swap units automatically get the + BindsTo= and After= + dependencies on the device units or the mount units of the files they are activated from. Swap units with DefaultDependencies= - enabled implicitly acquire a conflicting dependency to + enabled implicitly acquire a Conflicts= and an + After= dependency on umount.target so that they are deactivated at - shutdown. + shutdown, unless DefaultDependencies=no is + specified. + + Additional implicit dependencies may be added as result of + execution and resource control parameters as documented in + systemd.exec5 + and + systemd.resource-control5. diff --git a/man/systemd.target.xml b/man/systemd.target.xml index e790e9b77a..54a5f5035c 100644 --- a/man/systemd.target.xml +++ b/man/systemd.target.xml @@ -77,15 +77,20 @@ See systemd.special7 for details). + + + + Automatic Dependencies Unless DefaultDependencies= is set to - , target units will implicitly complement - all configured dependencies of type Wants=, + , target units will implicitly complement all + configured dependencies of type Wants=, Requires=, RequiresOverridable= with dependencies of type - After= if the units in question also have - DefaultDependencies=true. - + After=, unless an ordering dependency of any + kind between the target and the respective other unit is already + in place. Note that this behaviour is disabled if either unit has + DefaultDependencies=no. diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml index c98258a0d7..8cf6c4683b 100644 --- a/man/systemd.timer.xml +++ b/man/systemd.timer.xml @@ -1,4 +1,4 @@ - + @@ -73,19 +73,29 @@ foo.timer activates a matching service foo.service. The unit to activate may be controlled by Unit= (see below). + + + + Automatic Dependencies + + Timer units automatically gain a Before= + dependency on the service they are supposed to activate. Unless DefaultDependencies= is set to , all timer units will implicitly have - dependencies of type Conflicts= and - Before= on shutdown.target - to ensure that they are stopped cleanly prior to system shutdown. - Timer units with at least one OnCalendar= - directive will have an additional After= - dependency on timer-sync.target to avoid - being started before the system clock has been correctly set. Only - timer units involved with early boot or late system shutdown - should disable the DefaultDependencies= - option. + dependencies of type Requires= and + After= on sysinit.target, + a dependency of type Before= on + timers.target, as well as + Conflicts= and Before= on + shutdown.target to ensure that they are + stopped cleanly prior to system shutdown. Timer units with at + least one OnCalendar= directive will have an + additional After= dependency on + timer-sync.target to avoid being started + before the system clock has been correctly set. Only timer units + involved with early boot or late system shutdown should disable + the DefaultDependencies= option. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index caba7ea69d..b4044f43ef 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1,4 +1,4 @@ - + @@ -195,12 +195,6 @@ consider it mostly obsolete, and want people to use .d/ drop-ins instead. --> - Note that while systemd offers a flexible dependency system - between units it is recommended to use this functionality only - sparingly and instead rely on techniques such as bus-based or - socket-based activation which make dependencies implicit, - resulting in a both simpler and more flexible system. - Some unit names reflect paths existing in the file system namespace. Example: a device unit dev-sda.device refers to a device with the @@ -253,6 +247,31 @@ + + Automatic Dependencies + + Note that while systemd offers a flexible dependency system + between units it is recommended to use this functionality only + sparingly and instead rely on techniques such as bus-based or + socket-based activation which make dependencies implicit, + resulting in a both simpler and more flexible system. + + A number of unit dependencies are automatically established, + depending on unit configuration. On top of that, for units with + DefaultDependencies=yes (the default) a couple + of additional dependencies are added. The precise effect of + DefaultDependencies=yes depends on the unit + type (see below). + + If DefaultDependencies=yes is set, units + that are referenced by other units of type + .target via a Wants= or + Requires= dependency might automatically gain + an Before= dependency too. See + systemd.target5 + for details. + + Unit File Load Path From c89f52ac6938374972253d8752ed65f3af0b3ef4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 22:53:05 +0100 Subject: [PATCH 09/10] core: fix dependency parsing 3d793d29059a7ddf5282efa6b32b953c183d7a4d broke parsing of unit file names that include backslashes, as extract_first_word() strips those. Fix this, by introducing a new EXTRACT_RETAIN_ESCAPE flag which disables looking at any flags, thus being compatible with the classic FOREACH_WORD() behaviour. --- src/basic/extract-word.c | 4 ++-- src/basic/extract-word.h | 9 +++++---- src/core/load-fragment.c | 2 +- src/test/test-extract-word.c | 12 ++++++++++++ 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index ff6d211ef4..fd495692fa 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -128,7 +128,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra } else if (c == quote) { /* found the end quote */ quote = 0; break; - } else if (c == '\\') { + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { backslash = true; break; } else { @@ -146,7 +146,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) { quote = c; break; - } else if (c == '\\') { + } else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) { backslash = true; break; } else if (strchr(separators, c)) { diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h index ddc1c4f463..9606ab64b3 100644 --- a/src/basic/extract-word.h +++ b/src/basic/extract-word.h @@ -24,11 +24,12 @@ #include "macro.h" typedef enum ExtractFlags { - EXTRACT_RELAX = 1, - EXTRACT_CUNESCAPE = 2, - EXTRACT_CUNESCAPE_RELAX = 4, - EXTRACT_QUOTES = 8, + EXTRACT_RELAX = 1, + EXTRACT_CUNESCAPE = 2, + EXTRACT_CUNESCAPE_RELAX = 4, + EXTRACT_QUOTES = 8, EXTRACT_DONT_COALESCE_SEPARATORS = 16, + EXTRACT_RETAIN_ESCAPE = 32, } ExtractFlags; int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 79cabd26e7..93eeeabe66 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -122,7 +122,7 @@ int config_parse_unit_deps(const char *unit, _cleanup_free_ char *word = NULL, *k = NULL; int r; - r = extract_first_word(&p, &word, NULL, 0); + r = extract_first_word(&p, &word, NULL, EXTRACT_RETAIN_ESCAPE); if (r == 0) break; if (r == -ENOMEM) diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c index 09698c07c7..65d3a0a96e 100644 --- a/src/test/test-extract-word.c +++ b/src/test/test-extract-word.c @@ -325,6 +325,18 @@ static void test_extract_first_word(void) { assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0); assert_se(!t); assert_se(!p); + + p = "foo\\xbar"; + assert_se(extract_first_word(&p, &t, NULL, 0) > 0); + assert_se(streq(t, "fooxbar")); + free(t); + assert_se(p == NULL); + + p = "foo\\xbar"; + assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0); + assert_se(streq(t, "foo\\xbar")); + free(t); + assert_se(p == NULL); } static void test_extract_first_word_and_warn(void) { From ee735086f8670be1591fa9593e80dd60163a7a2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 11 Nov 2015 22:54:56 +0100 Subject: [PATCH 10/10] util-lib: use MODE_INVALID as invalid value for mode_t everywhere --- src/basic/fs-util.c | 4 ++-- src/core/timer.c | 4 ++-- src/test/test-conf-files.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 7aee404bfc..cddd4232fc 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -311,7 +311,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi if (fd < 0) return -errno; - if (mode > 0) { + if (mode != MODE_INVALID) { r = fchmod(fd, mode); if (r < 0) return -errno; @@ -338,7 +338,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi } int touch(const char *path) { - return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0); + return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); } int symlink_idempotent(const char *from, const char *to) { diff --git a/src/core/timer.c b/src/core/timer.c index c50e891aeb..06a6035315 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -519,7 +519,7 @@ static void timer_enter_running(Timer *t) { dual_timestamp_get(&t->last_trigger); if (t->stamp_path) - touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, 0); + touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, MODE_INVALID); timer_set_state(t, TIMER_RUNNING); return; @@ -555,7 +555,7 @@ static int timer_start(Unit *u) { /* The timer has never run before, * make sure a stamp file exists. */ - touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0); + touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); } t->result = TIMER_SUCCESS; diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c index a69698d4ea..86ac513d4f 100644 --- a/src/test/test-conf-files.c +++ b/src/test/test-conf-files.c @@ -26,6 +26,7 @@ #include "conf-files.h" #include "fs-util.h" #include "macro.h" +#include "parse-util.h" #include "rm-rf.h" #include "string-util.h" #include "strv.h" @@ -40,7 +41,7 @@ static void setup_test_dir(char *tmp_dir, const char *files, ...) { va_start(ap, files); while (files != NULL) { _cleanup_free_ char *path = strappend(tmp_dir, files); - assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0) == 0); + assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID) == 0); files = va_arg(ap, const char *); } va_end(ap);