From 3f6fd1ba65f962702753c4ad284b588e59689a23 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 23 Sep 2015 03:01:06 +0200 Subject: util: introduce common version() implementation and use it everywhere This also allows us to drop build.h from a ton of files, hence do so. Since we touched the #includes of those files, let's order them properly according to CODING_STYLE. --- src/systemctl/systemctl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 34e4751b94..56c7982b8f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -37,7 +37,6 @@ #include "sd-daemon.h" #include "sd-login.h" -#include "build.h" #include "bus-common-errors.h" #include "bus-error.h" #include "bus-message.h" @@ -6422,9 +6421,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return 0; case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0; + return version(); case 't': { const char *word, *state; -- cgit v1.2.3-54-g00ecf From 94f099d8132da7987a5dbe930dadf31aaded9a11 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 23 Sep 2015 17:04:43 +0200 Subject: systemctl: make "systemctl is-system-running" return "offline" if we are not booted with systemd This sounds like the better place to expose this than in "systemd-notify --booted". Also document the so far undocumented "unknown" state the command might return. And rearrange the table of states documented to be more like the one for "is-running". Also, don't document the precise exit code of this function, just say errors are reported != 0 or > 0... --- man/systemctl.xml | 50 +++++++++++++++++++++++++++++++++++------------ man/systemd-notify.xml | 7 ++++++- src/systemctl/systemctl.c | 6 ++++++ 3 files changed, 49 insertions(+), 14 deletions(-) (limited to 'src/systemctl') diff --git a/man/systemctl.xml b/man/systemctl.xml index c1359d1678..9e9ba5a5b6 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1120,9 +1120,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service - Printed string - Meaning - Return value + Name + Description + Exit Code @@ -1137,7 +1137,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service linked Made available through a symlink to the unit file (permanently or just in /run). - 1 + > 0 linked-runtime @@ -1145,7 +1145,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service masked Disabled entirely (permanently or just in /run). - 1 + > 0 masked-runtime @@ -1163,7 +1163,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service disabled Unit file is not enabled. - 1 + > 0 @@ -1474,22 +1474,25 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service Checks whether the system is operational. This - returns success when the system is fully up and running, - meaning not in startup, shutdown or maintenance - mode. Failure is returned otherwise. In addition, the + returns success (exit code 0) when the system is fully up + and running, specifically not in startup, shutdown or + maintenance mode, and with no failed services. Failure is + returned otherwise (exit code non-zero). In addition, the current state is printed in a short string to standard output, see table below. Use to suppress this output. - Manager Operational States - - - + <command>is-system-running</command> output + + + + Name Description + Exit Code @@ -1499,32 +1502,53 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service basic.target is reached or the maintenance state entered. + > 0 starting Late bootup, before the job queue becomes idle for the first time, or one of the rescue targets are reached. + > 0 running The system is fully operational. + 0 degraded The system is operational but one or more units failed. + > 0 maintenance The rescue or emergency target is active. + > 0 stopping The manager is shutting down. + > 0 + + + offline + The manager is not + running. Specifically, this is the operational + state if an incompatible program is running as + system manager (PID 1). + > 0 + + + unknown + The operational state could not be + determined, due to lack of resources or another + error cause. + > 0 diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml index 06d5ae5319..5832cc6759 100644 --- a/man/systemd-notify.xml +++ b/man/systemd-notify.xml @@ -124,7 +124,12 @@ systemd, non-zero otherwise. If this option is passed, no message is sent. This option is hence unrelated to the other options. For details about the semantics of this option, see - sd_booted3. + sd_booted3. An + alternative way to check for this state is to call + systemctl1 + with the is-system-running command. It will + return offline if the system was not booted + with systemd. diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 56c7982b8f..2b9de5d016 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5753,6 +5753,12 @@ static int is_system_running(sd_bus *bus, char **args) { _cleanup_free_ char *state = NULL; int r; + if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) { + if (!arg_quiet) + puts("offline"); + return EXIT_FAILURE; + } + r = sd_bus_get_property_string( bus, "org.freedesktop.systemd1", -- cgit v1.2.3-54-g00ecf From f2d11d35e90d5143d2bc6103ff451778909644f0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 11:51:51 +0200 Subject: systemctl: introduce a single function to set the wall message Let's not have the same code three times, but reduce it to one function. --- src/systemctl/systemctl.c | 110 +++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 75 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2b9de5d016..4de01d91d1 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2760,6 +2760,37 @@ static int start_unit(sd_bus *bus, char **args) { return r; } +static int set_wall_message(sd_bus *bus) { +#ifdef HAVE_LOGIND + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *m = NULL; + int r; + + assert(bus); + + m = strv_join(arg_wall, " "); + if (!m) + return log_oom(); + + r = sd_bus_call_method( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "SetWallMessage", + &error, + NULL, + "sb", + m, + !arg_no_wall); + + if (r < 0) + return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r)); + +#endif + return 0; +} + /* Ask systemd-logind, which might grant access to unprivileged users * through PolicyKit */ static int reboot_with_logind(sd_bus *bus, enum action a) { @@ -2773,6 +2804,8 @@ static int reboot_with_logind(sd_bus *bus, enum action a) { polkit_agent_open_if_enabled(); + (void) set_wall_message(bus); + switch (a) { case ACTION_REBOOT: @@ -2804,33 +2837,6 @@ static int reboot_with_logind(sd_bus *bus, enum action a) { return -EINVAL; } - if (!strv_isempty(arg_wall)) { - _cleanup_free_ char *m; - - m = strv_join(arg_wall, " "); - if (!m) - return log_oom(); - - r = sd_bus_call_method( - bus, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "SetWallMessage", - &error, - NULL, - "sb", - m, - !arg_no_wall); - - if (r < 0) { - log_warning_errno(r, "Failed to set wall message, ignoring: %s", - bus_error_message(&error, r)); - sd_bus_error_free(&error); - } - } - - r = sd_bus_call_method( bus, "org.freedesktop.login1", @@ -7455,7 +7461,6 @@ static int halt_main(sd_bus *bus) { if (arg_when > 0) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; - _cleanup_free_ char *m = NULL; const char *action; assert(geteuid() == 0); @@ -7469,27 +7474,7 @@ static int halt_main(sd_bus *bus) { if (r < 0) return log_error_errno(r, "Unable to open system bus: %m"); - m = strv_join(arg_wall, " "); - if (!m) - return log_oom(); - - r = sd_bus_call_method( - b, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "SetWallMessage", - &error, - NULL, - "sb", - m, - !arg_no_wall); - - if (r < 0) { - log_warning_errno(r, "Failed to set wall message, ignoring: %s", - bus_error_message(&error, r)); - sd_bus_error_free(&error); - } + (void) set_wall_message(b); switch (arg_action) { case ACTION_HALT: @@ -7642,7 +7627,6 @@ int main(int argc, char*argv[]) { case ACTION_CANCEL_SHUTDOWN: { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; - _cleanup_free_ char *m = NULL; if (avoid_bus()) { log_error("Unable to perform operation without bus connection."); @@ -7653,31 +7637,7 @@ int main(int argc, char*argv[]) { if (r < 0) return log_error_errno(r, "Unable to open system bus: %m"); - if (arg_wall) { - m = strv_join(arg_wall, " "); - if (!m) { - r = log_oom(); - goto finish; - } - } - - r = sd_bus_call_method( - b, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "SetWallMessage", - &error, - NULL, - "sb", - m, - !arg_no_wall); - - if (r < 0) { - log_warning_errno(r, "Failed to set wall message, ignoring: %s", - bus_error_message(&error, r)); - sd_bus_error_free(&error); - } + (void) set_wall_message(b); r = sd_bus_call_method( b, -- cgit v1.2.3-54-g00ecf From 4f16c1f479ac3d790933ca196075cba333bab387 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 11:54:15 +0200 Subject: systemctl: don't special case ACTION_RUNLEVEL anymore Let's move its dispatching to the main switch statement. --- src/systemctl/systemctl.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 4de01d91d1..fe71d059fc 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -266,6 +266,11 @@ static void warn_wall(enum action a) { static bool avoid_bus(void) { + /* /sbin/runlevel doesn't need to communicate via D-Bus, so + * let's shortcut this */ + if (arg_action == ACTION_RUNLEVEL) + return true; + if (running_in_chroot() > 0) return true; @@ -7574,13 +7579,6 @@ int main(int argc, char*argv[]) { if (r <= 0) goto finish; - /* /sbin/runlevel doesn't need to communicate via D-Bus, so - * let's shortcut this */ - if (arg_action == ACTION_RUNLEVEL) { - r = runlevel_main(); - goto finish; - } - if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) { log_info("Running in chroot, ignoring request."); r = 0; @@ -7654,6 +7652,9 @@ int main(int argc, char*argv[]) { } case ACTION_RUNLEVEL: + r = runlevel_main(); + break; + case _ACTION_INVALID: default: assert_not_reached("Unknown action"); -- cgit v1.2.3-54-g00ecf From 949d9ce954ab78f6d3922ad7a51cce20332129e0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 11:56:04 +0200 Subject: systemctl: move shutdown cancelling code into its own function Let's make sure the main switch statement only invokes functions, but doesn't do anything real on its own. --- src/systemctl/systemctl.c | 59 +++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index fe71d059fc..2b8145848d 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7562,6 +7562,36 @@ static int runlevel_main(void) { return 0; } +static int cancel_shutdown(void) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; + int r; + + if (avoid_bus()) { + log_error("Unable to perform operation without bus connection."); + return -ENOSYS; + } + + r = sd_bus_open_system(&b); + if (r < 0) + return log_error_errno(r, "Unable to open system bus: %m"); + + (void) set_wall_message(b); + + r = sd_bus_call_method( + b, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "CancelScheduledShutdown", + &error, + NULL, NULL); + if (r < 0) + return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r)); + + return 0; +} + int main(int argc, char*argv[]) { _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; @@ -7622,34 +7652,9 @@ int main(int argc, char*argv[]) { r = reload_with_fallback(bus); break; - case ACTION_CANCEL_SHUTDOWN: { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; - - if (avoid_bus()) { - log_error("Unable to perform operation without bus connection."); - return -ENOSYS; - } - - r = sd_bus_open_system(&b); - if (r < 0) - return log_error_errno(r, "Unable to open system bus: %m"); - - (void) set_wall_message(b); - - r = sd_bus_call_method( - b, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "CancelScheduledShutdown", - &error, - NULL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", - bus_error_message(&error, r)); + case ACTION_CANCEL_SHUTDOWN: + r = cancel_shutdown(); break; - } case ACTION_RUNLEVEL: r = runlevel_main(); -- cgit v1.2.3-54-g00ecf From 2cf05793f20adeff6da949f86cd502adb402cca2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:07:31 +0200 Subject: systemctl: rename all logind-specific functions to logind_xyz() --- src/systemctl/systemctl.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2b8145848d..b097cc2f65 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2765,7 +2765,7 @@ static int start_unit(sd_bus *bus, char **args) { return r; } -static int set_wall_message(sd_bus *bus) { +static int logind_set_wall_message(sd_bus *bus) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *m = NULL; @@ -2798,7 +2798,7 @@ static int set_wall_message(sd_bus *bus) { /* Ask systemd-logind, which might grant access to unprivileged users * through PolicyKit */ -static int reboot_with_logind(sd_bus *bus, enum action a) { +static int logind_reboot(sd_bus *bus, enum action a) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *method, *description; @@ -2809,7 +2809,7 @@ static int reboot_with_logind(sd_bus *bus, enum action a) { polkit_agent_open_if_enabled(); - (void) set_wall_message(bus); + (void) logind_set_wall_message(bus); switch (a) { @@ -2860,7 +2860,7 @@ static int reboot_with_logind(sd_bus *bus, enum action a) { #endif } -static int check_inhibitors(sd_bus *bus, enum action a) { +static int logind_check_inhibitors(sd_bus *bus, enum action a) { #ifdef HAVE_LOGIND _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_strv_free_ char **sessions = NULL; @@ -3023,7 +3023,7 @@ static int start_special(sd_bus *bus, char **args) { a = verb_to_action(args[0]); - r = check_inhibitors(bus, a); + r = logind_check_inhibitors(bus, a); if (r < 0) return r; @@ -3091,7 +3091,7 @@ static int start_special(sd_bus *bus, char **args) { ACTION_SUSPEND, ACTION_HIBERNATE, ACTION_HYBRID_SLEEP)) { - r = reboot_with_logind(bus, a); + r = logind_reboot(bus, a); if (r >= 0) return r; if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) @@ -7435,7 +7435,7 @@ static int halt_now(enum action a) { static int halt_main(sd_bus *bus) { int r; - r = check_inhibitors(bus, arg_action); + r = logind_check_inhibitors(bus, arg_action); if (r < 0) return r; @@ -7453,7 +7453,7 @@ static int halt_main(sd_bus *bus) { if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) { - r = reboot_with_logind(bus, arg_action); + r = logind_reboot(bus, arg_action); if (r >= 0) return r; if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) @@ -7562,7 +7562,8 @@ static int runlevel_main(void) { return 0; } -static int cancel_shutdown(void) { +static int logind_cancel_shutdown(void) { +#ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; int r; @@ -7576,7 +7577,7 @@ static int cancel_shutdown(void) { if (r < 0) return log_error_errno(r, "Unable to open system bus: %m"); - (void) set_wall_message(b); + (void) logind_set_wall_message(b); r = sd_bus_call_method( b, @@ -7590,6 +7591,10 @@ static int cancel_shutdown(void) { return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r)); return 0; +#else + log_error("Not compiled with logind support, cannot cancel scheduled shutdowns."); + return -ENOSYS; +#endif } int main(int argc, char*argv[]) { @@ -7653,7 +7658,7 @@ int main(int argc, char*argv[]) { break; case ACTION_CANCEL_SHUTDOWN: - r = cancel_shutdown(); + r = logind_cancel_shutdown(); break; case ACTION_RUNLEVEL: -- cgit v1.2.3-54-g00ecf From 56a730fa568f6ad168cb77ed46e57c042325eedb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:08:23 +0200 Subject: systemctl: split out code that schedules shutdowsn into its own function --- src/systemctl/systemctl.c | 121 +++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 56 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b097cc2f65..f7deb439da 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7432,6 +7432,68 @@ static int halt_now(enum action a) { } } +static int logind_schedule_shutdown(void) { + +#ifdef HAVE_LOGIND + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; + char date[FORMAT_TIMESTAMP_MAX]; + const char *action; + int r; + + assert(geteuid() == 0); + + if (avoid_bus()) { + log_error("Unable to perform operation without bus connection."); + return -ENOSYS; + } + + r = sd_bus_open_system(&b); + if (r < 0) + return log_error_errno(r, "Unable to open system bus: %m"); + + (void) logind_set_wall_message(b); + + switch (arg_action) { + case ACTION_HALT: + action = "halt"; + break; + case ACTION_POWEROFF: + action = "poweroff"; + break; + case ACTION_KEXEC: + action = "kexec"; + break; + default: + action = "reboot"; + break; + } + + if (arg_dry) + action = strjoina("dry-", action); + + r = sd_bus_call_method( + b, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ScheduleShutdown", + &error, + NULL, + "st", + action, + arg_when); + if (r < 0) + return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r)); + + log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when)); + return 0; +#else + log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown."); + return -ENOSYS; +#endif +} + static int halt_main(sd_bus *bus) { int r; @@ -7464,62 +7526,9 @@ static int halt_main(sd_bus *bus) { } if (arg_when > 0) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; - const char *action; - - assert(geteuid() == 0); - - if (avoid_bus()) { - log_error("Unable to perform operation without bus connection."); - return -ENOSYS; - } - - r = sd_bus_open_system(&b); - if (r < 0) - return log_error_errno(r, "Unable to open system bus: %m"); - - (void) set_wall_message(b); - - switch (arg_action) { - case ACTION_HALT: - action = "halt"; - break; - case ACTION_POWEROFF: - action = "poweroff"; - break; - case ACTION_KEXEC: - action = "kexec"; - break; - default: - action = "reboot"; - break; - } - - if (arg_dry) - action = strjoina("dry-", action); - - r = sd_bus_call_method( - b, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ScheduleShutdown", - &error, - NULL, - "st", - action, - arg_when); - if (r < 0) - log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", - bus_error_message(&error, r)); - else { - char date[FORMAT_TIMESTAMP_MAX]; - - log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", - format_timestamp(date, sizeof(date), arg_when)); - return 0; - } + r = logind_schedule_shutdown(); + if (r >= 0) + return r; } if (!arg_dry && !arg_force) -- cgit v1.2.3-54-g00ecf From e3ead6bb42f7c0f18d0ac100d33b71913fe4dcca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:23:21 +0200 Subject: systemctl: move strv_skip_first() out of systemctl.c Make it generic, call it strv_skip() and move it to strv.[ch] --- src/basic/strv.c | 12 ++++++++++++ src/basic/strv.h | 2 ++ src/systemctl/systemctl.c | 20 +++++++------------- src/test/test-strv.c | 23 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 13 deletions(-) (limited to 'src/systemctl') diff --git a/src/basic/strv.c b/src/basic/strv.c index 92f900936e..9524e80a6f 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -733,3 +733,15 @@ char ***strv_free_free(char ***l) { free(l); return NULL; } + +char **strv_skip(char **l, size_t n) { + + while (n > 0) { + if (strv_isempty(l)) + return l; + + l++, n--; + } + + return l; +} diff --git a/src/basic/strv.h b/src/basic/strv.h index 713e91f8f8..4c4b6526de 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -156,3 +156,5 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i } char ***strv_free_free(char ***l); + +char **strv_skip(char **l, size_t n); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index f7deb439da..059e51c2cd 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -146,12 +146,6 @@ static int daemon_reload(sd_bus *bus, char **args); static int halt_now(enum action a); static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet); -static char** strv_skip_first(char **strv) { - if (strv_length(strv) > 0) - return strv + 1; - return NULL; -} - static void pager_open_if_enabled(void) { if (arg_no_pager) @@ -664,7 +658,7 @@ static int list_units(sd_bus *bus, char **args) { pager_open_if_enabled(); - r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines); + r = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (r < 0) return r; @@ -870,7 +864,7 @@ static int list_sockets(sd_bus *bus, char **args) { pager_open_if_enabled(); - n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines); + n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1178,7 +1172,7 @@ static int list_timers(sd_bus *bus, char **args) { pager_open_if_enabled(); - n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines); + n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1368,7 +1362,7 @@ static int list_unit_files(sd_bus *bus, char **args) { } HASHMAP_FOREACH(u, h, i) { - if (!output_show_unit_file(u, strv_skip_first(args))) + if (!output_show_unit_file(u, strv_skip(args, 1))) continue; units[c++] = *u; @@ -1408,7 +1402,7 @@ static int list_unit_files(sd_bus *bus, char **args) { unit_file_state_from_string(state) }; - if (output_show_unit_file(&units[c], strv_skip_first(args))) + if (output_show_unit_file(&units[c], strv_skip(args, 1))) c ++; } @@ -1889,7 +1883,7 @@ static int list_machines(sd_bus *bus, char **args) { pager_open_if_enabled(); - r = get_machine_list(bus, &machine_infos, strv_skip_first(args)); + r = get_machine_list(bus, &machine_infos, strv_skip(args, 1)); if (r < 0) return r; @@ -2121,7 +2115,7 @@ static int list_jobs(sd_bus *bus, char **args) { while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) { struct job_info job = { id, name, type, state }; - if (!output_show_job(&job, strv_skip_first(args))) { + if (!output_show_job(&job, strv_skip(args, 1))) { skipped = true; continue; } diff --git a/src/test/test-strv.c b/src/test/test-strv.c index bff43950a9..cc47fd4d34 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -569,6 +569,28 @@ static void test_strv_shell_escape(void) { assert_se(streq_ptr(v[3], NULL)); } +static void test_strv_skip_one(char **a, size_t n, char **b) { + a = strv_skip(a, n); + assert_se(strv_equal(a, b)); +} + +static void test_strv_skip(void) { + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz")); + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz")); + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz")); + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL)); + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL)); + test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL)); + + test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux")); + test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL)); + test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL)); + + test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL)); + test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL)); + test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL)); +} + int main(int argc, char *argv[]) { test_specifier_printf(); test_strv_foreach(); @@ -627,6 +649,7 @@ int main(int argc, char *argv[]) { test_strv_is_uniq(); test_strv_reverse(); test_strv_shell_escape(); + test_strv_skip(); return 0; } -- cgit v1.2.3-54-g00ecf From 48ec22bc02921ae6324f5ec1373244437fb4a6fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:24:35 +0200 Subject: systemctl: remove client-side wall message support logind sends out wall messages now, let's remove this from the systemctl client side hence. If people build systemd without logind support they won't get wall messages now, but that's OK. --- src/systemctl/systemctl.c | 49 +++-------------------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 059e51c2cd..421443fef3 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -223,41 +223,6 @@ static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) return EXIT_FAILURE; } -static void warn_wall(enum action a) { - static const char *table[_ACTION_MAX] = { - [ACTION_HALT] = "The system is going down for system halt NOW!", - [ACTION_REBOOT] = "The system is going down for reboot NOW!", - [ACTION_POWEROFF] = "The system is going down for power-off NOW!", - [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!", - [ACTION_RESCUE] = "The system is going down to rescue mode NOW!", - [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!", - [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!" - }; - - if (arg_no_wall) - return; - - if (arg_wall) { - _cleanup_free_ char *p; - - p = strv_join(arg_wall, " "); - if (!p) { - log_oom(); - return; - } - - if (*p) { - utmp_wall(p, NULL, NULL, NULL, NULL); - return; - } - } - - if (!table[a]) - return; - - utmp_wall(table[a], NULL, NULL, NULL, NULL); -} - static bool avoid_bus(void) { /* /sbin/runlevel doesn't need to communicate via D-Bus, so @@ -3094,11 +3059,7 @@ static int start_special(sd_bus *bus, char **args) { /* on all other errors, try low-level operation */ } - r = start_unit(bus, args); - if (r == EXIT_SUCCESS) - warn_wall(a); - - return r; + return start_unit(bus, args); } static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) { @@ -7367,20 +7328,16 @@ static int start_with_fallback(sd_bus *bus) { if (bus) { /* First, try systemd via D-Bus. */ if (start_unit(bus, NULL) >= 0) - goto done; + return 0; } /* Nothing else worked, so let's try * /dev/initctl */ if (talk_initctl() > 0) - goto done; + return 0; log_error("Failed to talk to init daemon."); return -EIO; - -done: - warn_wall(arg_action); - return 0; } static int halt_now(enum action a) { -- cgit v1.2.3-54-g00ecf From fc2ffaf17d69fbe58183b2bdd61a655d575d8b0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:28:07 +0200 Subject: systemctl: add 'const' where appropriate --- src/systemctl/systemctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 421443fef3..ecd4c01858 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -133,7 +133,7 @@ static enum action { _ACTION_MAX } arg_action = ACTION_SYSTEMCTL; static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; -static char *arg_host = NULL; +static const char *arg_host = NULL; static unsigned arg_lines = 10; static OutputMode arg_output = OUTPUT_SHORT; static bool arg_plain = false; -- cgit v1.2.3-54-g00ecf From 172d7abfea003d84d0e697a510a222f32b40f4c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:30:05 +0200 Subject: systemctl: allocate arg_wall only on the heap Previously, we'd allocate it sometimes from the heap, but otherwise let it point directly int argv[]. Let's clean this up, so that we know exactly how to release its resources, and do so at the end. --- src/systemctl/systemctl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index ecd4c01858..804f485403 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -6835,6 +6835,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { {} }; + char **wall = NULL; int c, r; assert(argc >= 0); @@ -6908,10 +6909,16 @@ static int shutdown_parse_argv(int argc, char *argv[]) { if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN) /* No time argument for shutdown cancel */ - arg_wall = argv + optind; + wall = argv + optind; else if (argc > optind + 1) /* We skip the time argument */ - arg_wall = argv + optind + 1; + wall = argv + optind + 1; + + if (wall) { + arg_wall = strv_copy(wall); + if (!arg_wall) + return log_oom(); + } optind = argc; @@ -7639,6 +7646,8 @@ finish: strv_free(arg_states); strv_free(arg_properties); + strv_free(arg_wall); + sd_bus_default_flush_close(); return r < 0 ? EXIT_FAILURE : r; -- cgit v1.2.3-54-g00ecf From eca830bee94e2cd24add44a5aa5c1836f54da27a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:33:07 +0200 Subject: systemctl: conditionalize /dev/initctl fallback on HAVE_SYSV_COMPAT --- src/systemctl/systemctl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 804f485403..c85c5e011b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7118,7 +7118,7 @@ _pure_ static int action_to_runlevel(void) { } static int talk_initctl(void) { - +#ifdef HAVE_SYSV_COMPAT struct init_request request = { .magic = INIT_MAGIC, .sleeptime = 0, @@ -7140,8 +7140,7 @@ static int talk_initctl(void) { if (errno == ENOENT) return 0; - log_error_errno(errno, "Failed to open "INIT_FIFO": %m"); - return -errno; + return log_error_errno(errno, "Failed to open "INIT_FIFO": %m"); } r = loop_write(fd, &request, sizeof(request), false); @@ -7149,6 +7148,9 @@ static int talk_initctl(void) { return log_error_errno(r, "Failed to write to "INIT_FIFO": %m"); return 1; +#else + return 0; +#endif } static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { -- cgit v1.2.3-54-g00ecf From 2cc7b0a25f7307a50fdad38ee4a2c6b9d856fff9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 12:35:02 +0200 Subject: systemctl: rename parse_time_spec() to parse_shutdown_time_spec() Let's clarify that this function is specific to shutdown time specifications, nothing else. --- src/systemctl/systemctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index c85c5e011b..7ee1e8d801 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -6769,7 +6769,7 @@ static int halt_parse_argv(int argc, char *argv[]) { return 1; } -static int parse_time_spec(const char *t, usec_t *_u) { +static int parse_shutdown_time_spec(const char *t, usec_t *_u) { assert(t); assert(_u); @@ -6899,7 +6899,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { } if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) { - r = parse_time_spec(argv[optind], &arg_when); + r = parse_shutdown_time_spec(argv[optind], &arg_when); if (r < 0) { log_error("Failed to parse time specification: %s", argv[optind]); return r; -- cgit v1.2.3-54-g00ecf From 266f3e269d173f104aa2a5e3ceac9b6979ea5039 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 24 Sep 2015 13:30:10 +0200 Subject: bus-util: rename bus_open_transport() to bus_connect_transport() In sd-bus, the sd_bus_open_xyz() family of calls allocates a new bus, while sd_bus_default_xyz() family tries to reuse the thread's default bus. bus_open_transport() sometimes internally uses the former, sometimes the latter family, but suggests it only calls the former via its name. Hence, let's avoid this confusion, and generically rename the call to bus_connect_transport(). Similar for all related calls. And while we are at it, also change cgls + cgtop to do direct systemd connections where possible, since all they do is talk to systemd itself. --- src/analyze/analyze.c | 2 +- src/cgls/cgls.c | 2 +- src/cgroups-agent/cgroups-agent.c | 2 +- src/cgtop/cgtop.c | 2 +- src/fsck/fsck.c | 2 +- src/hostname/hostnamectl.c | 2 +- src/initctl/initctl.c | 2 +- src/journal/journalctl.c | 2 +- src/locale/localectl.c | 2 +- src/login/loginctl.c | 2 +- src/machine/machinectl.c | 2 +- src/run/run.c | 2 +- src/shared/bus-util.c | 20 ++++++++++---------- src/shared/bus-util.h | 8 ++++---- src/systemctl/systemctl.c | 2 +- src/timedate/timedatectl.c | 2 +- src/update-utmp/update-utmp.c | 2 +- 17 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src/systemctl') diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index c8ace3778e..7054deeae5 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -1432,7 +1432,7 @@ int main(int argc, char *argv[]) { else { _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus); + r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index d3a5a4df28..41c539a1bc 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -145,7 +145,7 @@ static int get_cgroup_root(char **ret) { if (!path) return log_oom(); - r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus); + r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus); if (r < 0) return log_error_errno(r, "Failed to create bus connection: %m"); diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c index 612bc8fdec..b79519dd09 100644 --- a/src/cgroups-agent/cgroups-agent.c +++ b/src/cgroups-agent/cgroups-agent.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { * this to avoid an activation loop when we start dbus when we * are called when the dbus service is shut down. */ - r = bus_open_system_systemd(&bus); + r = bus_connect_system_systemd(&bus); if (r < 0) { /* If we couldn't connect we assume this was triggered * while systemd got restarted/transitioned from diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index b404c83616..ad9cd2532f 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -861,7 +861,7 @@ static int get_cgroup_root(char **ret) { if (!path) return log_oom(); - r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus); + r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus); if (r < 0) return log_error_errno(r, "Failed to create bus connection: %m"); diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index bd3051f30d..8e790b85ae 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -67,7 +67,7 @@ static void start_target(const char *target) { assert(target); - r = bus_open_system_systemd(&bus); + r = bus_connect_system_systemd(&bus); if (r < 0) { log_error_errno(r, "Failed to get D-Bus connection: %m"); return; diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 7974683179..0724fcc16d 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -517,7 +517,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - r = bus_open_transport(arg_transport, arg_host, false, &bus); + r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 6d08db74ef..2d5f7501e7 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -318,7 +318,7 @@ static int server_init(Server *s, unsigned n_sockets) { s->n_fifos ++; } - r = bus_open_system_systemd(&s->bus); + r = bus_connect_system_systemd(&s->bus); if (r < 0) { log_error_errno(r, "Failed to get D-Bus connection: %m"); r = -EIO; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index de67a9687c..75e59dbd42 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1722,7 +1722,7 @@ static int flush_to_var(void) { /* OK, let's actually do the full logic, send SIGUSR1 to the * daemon and set up inotify to wait for the flushed file to appear */ - r = bus_open_system_systemd(&bus); + r = bus_connect_system_systemd(&bus); if (r < 0) return log_error_errno(r, "Failed to get D-Bus connection: %m"); diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 26d7d5890e..880a1794aa 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -676,7 +676,7 @@ int main(int argc, char*argv[]) { if (r <= 0) goto finish; - r = bus_open_transport(arg_transport, arg_host, false, &bus); + r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/login/loginctl.c b/src/login/loginctl.c index efd6c5f4b0..bfc8716009 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1542,7 +1542,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - r = bus_open_transport(arg_transport, arg_host, false, &bus); + r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index b3c8ea44a3..17a186eb0e 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -2745,7 +2745,7 @@ int main(int argc, char*argv[]) { if (r <= 0) goto finish; - r = bus_open_transport(arg_transport, arg_host, false, &bus); + r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/run/run.c b/src/run/run.c index 2b51b0889b..62687591f4 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1174,7 +1174,7 @@ int main(int argc, char* argv[]) { arg_description = description; } - r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus); + r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 16b17c2c82..10df3fc3d6 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -574,14 +574,14 @@ int bus_check_peercred(sd_bus *c) { return 1; } -int bus_open_system_systemd(sd_bus **_bus) { +int bus_connect_system_systemd(sd_bus **_bus) { _cleanup_bus_unref_ sd_bus *bus = NULL; int r; assert(_bus); if (geteuid() != 0) - return sd_bus_open_system(_bus); + return sd_bus_default_system(_bus); /* If we are root and kdbus is not available, then let's talk * directly to the system instance, instead of going via the @@ -616,7 +616,7 @@ int bus_open_system_systemd(sd_bus **_bus) { r = sd_bus_start(bus); if (r < 0) - return sd_bus_open_system(_bus); + return sd_bus_default_system(_bus); r = bus_check_peercred(bus); if (r < 0) @@ -628,7 +628,7 @@ int bus_open_system_systemd(sd_bus **_bus) { return 0; } -int bus_open_user_systemd(sd_bus **_bus) { +int bus_connect_user_systemd(sd_bus **_bus) { _cleanup_bus_unref_ sd_bus *bus = NULL; _cleanup_free_ char *ee = NULL; const char *e; @@ -658,7 +658,7 @@ int bus_open_user_systemd(sd_bus **_bus) { e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) - return sd_bus_open_user(_bus); + return sd_bus_default_user(_bus); ee = bus_address_escape(e); if (!ee) @@ -674,7 +674,7 @@ int bus_open_user_systemd(sd_bus **_bus) { r = sd_bus_start(bus); if (r < 0) - return sd_bus_open_user(_bus); + return sd_bus_default_user(_bus); r = bus_check_peercred(bus); if (r < 0) @@ -1209,7 +1209,7 @@ int bus_map_all_properties( return bus_message_map_all_properties(m, map, userdata); } -int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { +int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { int r; assert(transport >= 0); @@ -1244,7 +1244,7 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b return r; } -int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { +int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { int r; assert(transport >= 0); @@ -1258,9 +1258,9 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us case BUS_TRANSPORT_LOCAL: if (user) - r = bus_open_user_systemd(bus); + r = bus_connect_user_systemd(bus); else - r = bus_open_system_systemd(bus); + r = bus_connect_system_systemd(bus); break; diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index d2b2d701ce..f03f951dc7 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -65,11 +65,11 @@ int bus_test_polkit(sd_bus_message *call, int capability, const char *action, co int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); void bus_verify_polkit_async_registry_free(Hashmap *registry); -int bus_open_system_systemd(sd_bus **_bus); -int bus_open_user_systemd(sd_bus **_bus); +int bus_connect_system_systemd(sd_bus **_bus); +int bus_connect_user_systemd(sd_bus **_bus); -int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus); -int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus); +int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus); +int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus); int bus_print_property(const char *name, sd_bus_message *property, bool all); int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7ee1e8d801..2208081c44 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7590,7 +7590,7 @@ int main(int argc, char*argv[]) { } if (!avoid_bus()) - r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus); + r = bus_connect_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus); if (bus) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index ea41227e52..68fbe3f5b8 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -500,7 +500,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - r = bus_open_transport(arg_transport, arg_host, false, &bus); + r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c index b2998dce43..8dbce27242 100644 --- a/src/update-utmp/update-utmp.c +++ b/src/update-utmp/update-utmp.c @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) { if (c.audit_fd < 0 && errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error_errno(errno, "Failed to connect to audit log: %m"); #endif - r = bus_open_system_systemd(&c.bus); + r = bus_connect_system_systemd(&c.bus); if (r < 0) { log_error_errno(r, "Failed to get D-Bus connection: %m"); r = -EIO; -- cgit v1.2.3-54-g00ecf From 4fbd7192c5058d73c8aa408c21428dd554ac1cea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 13:13:50 +0200 Subject: systemctl: rework how we connect to busses Sometimes we have to connect to the system manager directly (early boot, initrd, late boot, ...), sometimes through the system bus (unprivileged, remote, logind, ...). Instead of guessing in advance, which kind of connection we require (and sometimes guessing incorrectly), let's make sure each time we need bus connection we request the right bus explicitly. This way, we set up exactly the bus connections require, never guess incorrectly, and do so only immediately when necessary. As effect this reworks avoid_bus() into install_client_side(), since that's all it determines now: whether to install unit files client-side or server-side (i.e. in PID 1). --- src/systemctl/systemctl.c | 627 +++++++++++++++++++++++++++++----------------- 1 file changed, 394 insertions(+), 233 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2208081c44..7dcdf32a9b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -140,12 +140,56 @@ static bool arg_plain = false; static bool arg_firmware_setup = false; static bool arg_now = false; -static bool original_stdout_is_tty; - -static int daemon_reload(sd_bus *bus, char **args); +static int daemon_reload(char **args); static int halt_now(enum action a); static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet); +static bool original_stdout_is_tty; + +typedef enum BusFocus { + BUS_FULL, /* The full bus indicated via --system or --user */ + BUS_MANAGER, /* The manager itself, possibly directly, possibly via the bus */ + _BUS_FOCUS_MAX +} BusFocus; + +static sd_bus *busses[_BUS_FOCUS_MAX] = {}; + +static int acquire_bus(BusFocus focus, sd_bus **ret) { + int r; + + assert(focus < _BUS_FOCUS_MAX); + assert(ret); + + /* We only go directly to the manager, if we are using a local transport */ + if (arg_transport != BUS_TRANSPORT_LOCAL) + focus = BUS_FULL; + + if (!busses[focus]) { + bool user; + + user = arg_scope != UNIT_FILE_SYSTEM; + + if (focus == BUS_MANAGER) + r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]); + else + r = bus_connect_transport(arg_transport, arg_host, user, &busses[focus]); + if (r < 0) + return log_error_errno(r, "Failed to connect to bus: %m"); + + (void) sd_bus_set_allow_interactive_authorization(busses[focus], arg_ask_password); + } + + *ret = busses[focus]; + return 0; +} + +static void release_busses(void) { + BusFocus w; + + for (w = 0; w < _BUS_FOCUS_MAX; w++) + busses[w] = sd_bus_flush_close_unref(busses[w]); +} + static void pager_open_if_enabled(void) { if (arg_no_pager) @@ -223,12 +267,10 @@ static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) return EXIT_FAILURE; } -static bool avoid_bus(void) { +static bool install_client_side(void) { - /* /sbin/runlevel doesn't need to communicate via D-Bus, so - * let's shortcut this */ - if (arg_action == ACTION_RUNLEVEL) - return true; + /* Decides when to execute enable/disable/... operations + * client-side rather than server-side. */ if (running_in_chroot() > 0) return true; @@ -615,14 +657,19 @@ static int get_unit_list_recursive( return c; } -static int list_units(sd_bus *bus, char **args) { +static int list_units(char **args) { _cleanup_free_ UnitInfo *unit_infos = NULL; _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; + sd_bus *bus; int r; pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (r < 0) return r; @@ -639,6 +686,10 @@ static int get_triggered_units( _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; int r; + assert(bus); + assert(path); + assert(ret); + r = sd_bus_get_property_strv( bus, "org.freedesktop.systemd1", @@ -816,7 +867,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { return 0; } -static int list_sockets(sd_bus *bus, char **args) { +static int list_sockets(char **args) { _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; _cleanup_free_ UnitInfo *unit_infos = NULL; @@ -826,9 +877,14 @@ static int list_sockets(sd_bus *bus, char **args) { unsigned cs = 0; size_t size = 0; int r = 0, n; + sd_bus *bus; pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1123,7 +1179,7 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) { return next_elapse; } -static int list_timers(sd_bus *bus, char **args) { +static int list_timers(char **args) { _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; _cleanup_free_ struct timer_info *timer_infos = NULL; @@ -1133,10 +1189,15 @@ static int list_timers(sd_bus *bus, char **args) { size_t size = 0; int n, c = 0; dual_timestamp nw; + sd_bus *bus; int r = 0; pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1289,7 +1350,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { printf("\n%u unit files listed.\n", c); } -static int list_unit_files(sd_bus *bus, char **args) { +static int list_unit_files(char **args) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ UnitFileList *units = NULL; UnitFileList *unit; @@ -1301,7 +1362,7 @@ static int list_unit_files(sd_bus *bus, char **args) { pager_open_if_enabled(); - if (avoid_bus()) { + if (install_client_side()) { Hashmap *h; UnitFileList *u; Iterator i; @@ -1338,6 +1399,11 @@ static int list_unit_files(sd_bus *bus, char **args) { hashmap_free(h); } else { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; + + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; r = sd_bus_call_method( bus, @@ -1382,7 +1448,7 @@ static int list_unit_files(sd_bus *bus, char **args) { qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list); output_unit_file_list(units, c); - if (avoid_bus()) { + if (install_client_side()) { for (unit = units; unit < units + c; unit++) free(unit->path); } @@ -1601,14 +1667,13 @@ static int list_dependencies_one( return 0; } -static int list_dependencies(sd_bus *bus, char **args) { +static int list_dependencies(char **args) { _cleanup_strv_free_ char **units = NULL; _cleanup_free_ char *unit = NULL; const char *u; + sd_bus *bus; int r; - assert(bus); - if (args[1]) { r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &unit); if (r < 0) @@ -1620,6 +1685,10 @@ static int list_dependencies(sd_bus *bus, char **args) { pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + puts(u); return list_dependencies_one(bus, u, 0, &units, 0); @@ -1835,12 +1904,11 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n) printf("\n%u machines listed.\n", n); } -static int list_machines(sd_bus *bus, char **args) { +static int list_machines(char **args) { struct machine_info *machine_infos = NULL; + sd_bus *bus; int r; - assert(bus); - if (geteuid() != 0) { log_error("Must be root."); return -EPERM; @@ -1848,6 +1916,10 @@ static int list_machines(sd_bus *bus, char **args) { pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = get_machine_list(bus, &machine_infos, strv_skip(args, 1)); if (r < 0) return r; @@ -1859,13 +1931,13 @@ static int list_machines(sd_bus *bus, char **args) { return 0; } -static int get_default(sd_bus *bus, char **args) { +static int get_default(char **args) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ char *_path = NULL; const char *path; int r; - if (!bus || avoid_bus()) { + if (install_client_side()) { r = unit_file_get_default(arg_scope, arg_root, &_path); if (r < 0) return log_error_errno(r, "Failed to get default target: %m"); @@ -1873,6 +1945,11 @@ static int get_default(sd_bus *bus, char **args) { } else { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; + + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; r = sd_bus_call_method( bus, @@ -1912,17 +1989,18 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha } } -static int set_default(sd_bus *bus, char **args) { +static int set_default(char **args) { _cleanup_free_ char *unit = NULL; - UnitFileChange *changes = NULL; - unsigned n_changes = 0; int r; r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &unit); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); - if (!bus || avoid_bus()) { + if (install_client_side()) { + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes); if (r < 0) return log_error_errno(r, "Failed to set default target: %m"); @@ -1930,13 +2008,19 @@ static int set_default(sd_bus *bus, char **args) { if (!arg_quiet) dump_unit_file_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); r = 0; } else { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + sd_bus *bus; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -1957,13 +2041,11 @@ static int set_default(sd_bus *bus, char **args) { /* Try to reload if enabled */ if (!arg_no_reload) - r = daemon_reload(bus, args); + r = daemon_reload(args); else r = 0; } - unit_file_changes_free(changes, n_changes); - return r; } @@ -2048,17 +2130,24 @@ static bool output_show_job(struct job_info *job, char **patterns) { return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE); } -static int list_jobs(sd_bus *bus, char **args) { +static int list_jobs(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *name, *type, *state, *job_path, *unit_path; _cleanup_free_ struct job_info *jobs = NULL; size_t size = 0; unsigned c = 0; + sd_bus *bus; uint32_t id; int r; bool skipped = false; + pager_open_if_enabled(); + + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -2101,17 +2190,22 @@ static int list_jobs(sd_bus *bus, char **args) { return r; } -static int cancel_job(sd_bus *bus, char **args) { +static int cancel_job(char **args) { + sd_bus *bus; char **name; int r = 0; assert(args); if (strv_length(args) <= 1) - return daemon_reload(bus, args); + return daemon_reload(args); polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + STRV_FOREACH(name, args+1) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; uint32_t id; @@ -2216,7 +2310,6 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un static int unit_find_paths( sd_bus *bus, const char *unit_name, - bool avoid_bus_cache, LookupPaths *lp, char **fragment_path, char ***dropin_paths) { @@ -2237,7 +2330,7 @@ static int unit_find_paths( assert(fragment_path); assert(lp); - if (!avoid_bus_cache && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { + if (!install_client_side() && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL; _cleanup_free_ char *unit = NULL; @@ -2571,11 +2664,13 @@ static int start_unit_one( } static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) { - _cleanup_strv_free_ char **mangled = NULL, **globs = NULL; char **name; int r, i; + assert(bus); + assert(ret); + STRV_FOREACH(name, names) { char *t; @@ -2600,9 +2695,6 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ UnitInfo *unit_infos = NULL; - if (!bus) - return log_error_errno(EOPNOTSUPP, "Unit name globbing without bus is not implemented."); - r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply); if (r < 0) return r; @@ -2650,18 +2742,21 @@ static enum action verb_to_action(const char *verb) { return _ACTION_INVALID; } -static int start_unit(sd_bus *bus, char **args) { +static int start_unit(char **args) { _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; const char *method, *mode, *one_name, *suffix = NULL; _cleanup_strv_free_ char **names = NULL; + sd_bus *bus; char **name; int r = 0; - assert(bus); - ask_password_agent_open_if_enabled(); polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + if (arg_action == ACTION_SYSTEMCTL) { enum action action; method = verb_to_method(args[0]); @@ -2687,7 +2782,7 @@ static int start_unit(sd_bus *bus, char **args) { if (one_name) names = strv_new(one_name, NULL); else { - r = expand_names(bus, args + 1, suffix, &names); + r = expand_names(bus, strv_skip(args, 1), suffix, &names); if (r < 0) log_error_errno(r, "Failed to expand names: %m"); } @@ -2724,13 +2819,16 @@ static int start_unit(sd_bus *bus, char **args) { return r; } -static int logind_set_wall_message(sd_bus *bus) { +static int logind_set_wall_message(void) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; _cleanup_free_ char *m = NULL; int r; - assert(bus); + r = acquire_bus(BUS_FULL, &bus); + if (r < 0) + return r; m = strv_join(arg_wall, " "); if (!m) @@ -2757,18 +2855,19 @@ static int logind_set_wall_message(sd_bus *bus) { /* Ask systemd-logind, which might grant access to unprivileged users * through PolicyKit */ -static int logind_reboot(sd_bus *bus, enum action a) { +static int logind_reboot(enum action a) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *method, *description; + sd_bus *bus; int r; - if (!bus) - return -EIO; - polkit_agent_open_if_enabled(); + (void) logind_set_wall_message(); - (void) logind_set_wall_message(bus); + r = acquire_bus(BUS_FULL, &bus); + if (r < 0) + return r; switch (a) { @@ -2819,19 +2918,17 @@ static int logind_reboot(sd_bus *bus, enum action a) { #endif } -static int logind_check_inhibitors(sd_bus *bus, enum action a) { +static int logind_check_inhibitors(enum action a) { #ifdef HAVE_LOGIND _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_strv_free_ char **sessions = NULL; const char *what, *who, *why, *mode; uint32_t uid, pid; + sd_bus *bus; unsigned c = 0; char **s; int r; - if (!bus) - return 0; - if (arg_ignore_inhibitors || arg_force > 0) return 0; @@ -2844,6 +2941,10 @@ static int logind_check_inhibitors(sd_bus *bus, enum action a) { if (!on_tty()) return 0; + r = acquire_bus(BUS_FULL, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.login1", @@ -2933,25 +3034,16 @@ static int logind_check_inhibitors(sd_bus *bus, enum action a) { #endif } -static int prepare_firmware_setup(sd_bus *bus) { +static int logind_prepare_firmware_setup(void) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; -#endif + sd_bus *bus; int r; - if (!arg_firmware_setup) - return 0; - - if (arg_transport == BUS_TRANSPORT_LOCAL) { - - r = efi_set_reboot_to_firmware(true); - if (r < 0) - log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m"); - else - return r; - } + r = acquire_bus(BUS_FULL, &bus); + if (r < 0) + return r; -#ifdef HAVE_LOGIND r = sd_bus_call_method( bus, "org.freedesktop.login1", @@ -2961,20 +3053,35 @@ static int prepare_firmware_setup(sd_bus *bus) { &error, NULL, "b", true); - if (r < 0) { - log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r)); return 0; #else log_error("Cannot remotely indicate to EFI to boot into setup mode."); - return -EINVAL; + return -ENOSYS; #endif } -static int start_special(sd_bus *bus, char **args) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; +static int prepare_firmware_setup(void) { + int r; + + if (!arg_firmware_setup) + return 0; + + if (arg_transport == BUS_TRANSPORT_LOCAL) { + + r = efi_set_reboot_to_firmware(true); + if (r < 0) + log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m"); + else + return r; + } + + return logind_prepare_firmware_setup(); +} + +static int start_special(char **args) { enum action a; int r; @@ -2982,7 +3089,7 @@ static int start_special(sd_bus *bus, char **args) { a = verb_to_action(args[0]); - r = logind_check_inhibitors(bus, a); + r = logind_check_inhibitors(a); if (r < 0) return r; @@ -2991,7 +3098,7 @@ static int start_special(sd_bus *bus, char **args) { return -EPERM; } - r = prepare_firmware_setup(bus); + r = prepare_firmware_setup(); if (r < 0) return r; @@ -3000,10 +3107,12 @@ static int start_special(sd_bus *bus, char **args) { if (r < 0) return r; } else if (a == ACTION_EXIT && strv_length(args) > 1) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; /* If the exit code is not given on the command line, don't * reset it to zero: just keep it as it might have been set * previously. */ uint8_t code = 0; + sd_bus *bus; r = safe_atou8(args[1], &code); if (r < 0) { @@ -3011,6 +3120,10 @@ static int start_special(sd_bus *bus, char **args) { return -EINVAL; } + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -3040,7 +3153,7 @@ static int start_special(sd_bus *bus, char **args) { ACTION_REBOOT, ACTION_KEXEC, ACTION_EXIT)) - return daemon_reload(bus, args); + return daemon_reload(args); /* first try logind, to allow authentication with polkit */ if (geteuid() != 0 && @@ -3050,7 +3163,7 @@ static int start_special(sd_bus *bus, char **args) { ACTION_SUSPEND, ACTION_HIBERNATE, ACTION_HYBRID_SLEEP)) { - r = logind_reboot(bus, a); + r = logind_reboot(a); if (r >= 0) return r; if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) @@ -3059,17 +3172,21 @@ static int start_special(sd_bus *bus, char **args) { /* on all other errors, try low-level operation */ } - return start_unit(bus, args); + return start_unit(args); } -static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) { +static int check_unit_generic(int code, const char *good_states, char **args) { _cleanup_strv_free_ char **names = NULL; + sd_bus *bus; char **name; int r; - assert(bus); assert(args); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = expand_names(bus, args, NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -3087,25 +3204,29 @@ static int check_unit_generic(sd_bus *bus, int code, const char *good_states, ch return r; } -static int check_unit_active(sd_bus *bus, char **args) { +static int check_unit_active(char **args) { /* According to LSB: 3, "program is not running" */ - return check_unit_generic(bus, 3, "active\0reloading\0", args + 1); + return check_unit_generic(3, "active\0reloading\0", strv_skip(args, 1)); } -static int check_unit_failed(sd_bus *bus, char **args) { - return check_unit_generic(bus, 1, "failed\0", args + 1); +static int check_unit_failed(char **args) { + return check_unit_generic(1, "failed\0", strv_skip(args, 1)); } -static int kill_unit(sd_bus *bus, char **args) { +static int kill_unit(char **args) { _cleanup_strv_free_ char **names = NULL; char *kill_who = NULL, **name; + sd_bus *bus; int r, q; - assert(bus); assert(args); polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + if (!arg_kill_who) arg_kill_who = "all"; @@ -4516,12 +4637,12 @@ static int show_system_status(sd_bus *bus) { return 0; } -static int show(sd_bus *bus, char **args) { +static int show(char **args) { bool show_properties, show_status, new_line = false; bool ellipsized = false; int r, ret = 0; + sd_bus *bus; - assert(bus); assert(args); show_properties = streq(args[0], "show"); @@ -4536,8 +4657,11 @@ static int show(sd_bus *bus, char **args) { * be split up into many files. */ setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384)); - /* If no argument is specified inspect the manager itself */ + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + /* If no argument is specified inspect the manager itself */ if (show_properties && strv_length(args) <= 1) return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized); @@ -4659,19 +4783,20 @@ static int cat_file(const char *filename, bool newline) { return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false); } -static int cat(sd_bus *bus, char **args) { +static int cat(char **args) { _cleanup_free_ char *user_home = NULL; _cleanup_free_ char *user_runtime = NULL; _cleanup_lookup_paths_free_ LookupPaths lp = {}; _cleanup_strv_free_ char **names = NULL; char **name; - bool first = true, avoid_bus_cache; + sd_bus *bus; + bool first = true; int r; assert(args); if (arg_transport != BUS_TRANSPORT_LOCAL) { - log_error("Cannot remotely cat units"); + log_error("Cannot remotely cat units."); return -EINVAL; } @@ -4679,11 +4804,13 @@ static int cat(sd_bus *bus, char **args) { if (r < 0) return r; - r = expand_names(bus, args + 1, NULL, &names); + r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) - return log_error_errno(r, "Failed to expand names: %m"); + return r; - avoid_bus_cache = !bus || avoid_bus(); + r = expand_names(bus, strv_skip(args, 1), NULL, &names); + if (r < 0) + return log_error_errno(r, "Failed to expand names: %m"); pager_open_if_enabled(); @@ -4692,7 +4819,7 @@ static int cat(sd_bus *bus, char **args) { _cleanup_strv_free_ char **dropin_paths = NULL; char **path; - r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths); + r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths); if (r < 0) return r; else if (r == 0) @@ -4719,15 +4846,20 @@ static int cat(sd_bus *bus, char **args) { return 0; } -static int set_property(sd_bus *bus, char **args) { +static int set_property(char **args) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *n = NULL; + sd_bus *bus; char **i; int r; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_message_new_method_call( bus, &m, @@ -4777,11 +4909,12 @@ static int set_property(sd_bus *bus, char **args) { return 0; } -static int snapshot(sd_bus *bus, char **args) { +static int snapshot(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ char *n = NULL, *id = NULL; const char *path; + sd_bus *bus; int r; polkit_agent_open_if_enabled(); @@ -4796,6 +4929,10 @@ static int snapshot(sd_bus *bus, char **args) { return log_oom(); } + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -4833,8 +4970,9 @@ static int snapshot(sd_bus *bus, char **args) { return 0; } -static int delete_snapshot(sd_bus *bus, char **args) { +static int delete_snapshot(char **args) { _cleanup_strv_free_ char **names = NULL; + sd_bus *bus; char **name; int r; @@ -4842,9 +4980,13 @@ static int delete_snapshot(sd_bus *bus, char **args) { polkit_agent_open_if_enabled(); - r = expand_names(bus, args + 1, ".snapshot", &names); + r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) - log_error_errno(r, "Failed to expand names: %m"); + return r; + + r = expand_names(bus, strv_skip(args, 1), ".snapshot", &names); + if (r < 0) + return log_error_errno(r, "Failed to expand names: %m"); STRV_FOREACH(name, names) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -4869,13 +5011,18 @@ static int delete_snapshot(sd_bus *bus, char **args) { return r; } -static int daemon_reload(sd_bus *bus, char **args) { +static int daemon_reload(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *method; + sd_bus *bus; int r; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + if (arg_action == ACTION_RELOAD) method = "Reload"; else if (arg_action == ACTION_REEXEC) @@ -4919,17 +5066,22 @@ static int daemon_reload(sd_bus *bus, char **args) { return r < 0 ? r : 0; } -static int reset_failed(sd_bus *bus, char **args) { +static int reset_failed(char **args) { _cleanup_strv_free_ char **names = NULL; + sd_bus *bus; char **name; int r, q; if (strv_length(args) <= 1) - return daemon_reload(bus, args); + return daemon_reload(args); polkit_agent_open_if_enabled(); - r = expand_names(bus, args + 1, NULL, &names); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + + r = expand_names(bus, strv_skip(args, 1), NULL, &names); if (r < 0) log_error_errno(r, "Failed to expand names: %m"); @@ -4955,14 +5107,19 @@ static int reset_failed(sd_bus *bus, char **args) { return r; } -static int show_environment(sd_bus *bus, char **args) { +static int show_environment(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *text; + sd_bus *bus; int r; pager_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_get_property( bus, "org.freedesktop.systemd1", @@ -4993,13 +5150,19 @@ static int show_environment(sd_bus *bus, char **args) { return 0; } -static int switch_root(sd_bus *bus, char **args) { +static int switch_root(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *cmdline_init = NULL; const char *root, *init; + sd_bus *bus; unsigned l; int r; + if (arg_transport != BUS_TRANSPORT_LOCAL) { + log_error("Cannot switch root remotely."); + return -EINVAL; + } + l = strv_length(args); if (l < 2 || l > 3) { log_error("Wrong number of arguments."); @@ -5035,6 +5198,10 @@ static int switch_root(sd_bus *bus, char **args) { init = NULL; } + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + log_debug("Switching root - root: %s; init: %s", root, strna(init)); r = sd_bus_call_method( @@ -5054,17 +5221,21 @@ static int switch_root(sd_bus *bus, char **args) { return 0; } -static int set_environment(sd_bus *bus, char **args) { +static int set_environment(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; const char *method; + sd_bus *bus; int r; - assert(bus); assert(args); polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + method = streq(args[0], "set-environment") ? "SetEnvironment" : "UnsetEnvironment"; @@ -5092,16 +5263,20 @@ static int set_environment(sd_bus *bus, char **args) { return 0; } -static int import_environment(sd_bus *bus, char **args) { +static int import_environment(char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + sd_bus *bus; int r; - assert(bus); assert(args); polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_message_new_method_call( bus, &m, @@ -5331,7 +5506,7 @@ static int mangle_names(char **original_names, char ***mangled_names) { return 0; } -static int enable_unit(sd_bus *bus, char **args) { +static int enable_unit(char **args) { _cleanup_strv_free_ char **names = NULL; const char *verb = args[0]; UnitFileChange *changes = NULL; @@ -5355,7 +5530,7 @@ static int enable_unit(sd_bus *bus, char **args) { if (strv_isempty(names)) return 0; - if (!bus || avoid_bus()) { + if (install_client_side()) { if (streq(verb, "enable")) { r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes); carries_install_info = r; @@ -5391,9 +5566,14 @@ static int enable_unit(sd_bus *bus, char **args) { int expect_carries_install_info = false; bool send_force = true, send_preset_mode = false; const char *method; + sd_bus *bus; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + if (streq(verb, "enable")) { method = "EnableUnitFiles"; expect_carries_install_info = true; @@ -5470,7 +5650,7 @@ static int enable_unit(sd_bus *bus, char **args) { /* Try to reload if enabled */ if (!arg_no_reload) - r = daemon_reload(bus, args); + r = daemon_reload(args); else r = 0; } @@ -5488,14 +5668,19 @@ static int enable_unit(sd_bus *bus, char **args) { if (arg_now && n_changes > 0 && STR_IN_SET(args[0], "enable", "disable", "mask")) { char *new_args[n_changes + 2]; + sd_bus *bus; unsigned i; - new_args[0] = streq(args[0], "enable") ? (char *)"start" : (char *)"stop"; + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + + new_args[0] = (char*) (streq(args[0], "enable") ? "start" : "stop"); for (i = 0; i < n_changes; i++) new_args[i + 1] = basename(changes[i].path); new_args[i + 1] = NULL; - r = start_unit(bus, new_args); + r = start_unit(new_args); } finish: @@ -5504,7 +5689,7 @@ finish: return r; } -static int add_dependency(sd_bus *bus, char **args) { +static int add_dependency(char **args) { _cleanup_strv_free_ char **names = NULL; _cleanup_free_ char *target = NULL; const char *verb = args[0]; @@ -5529,7 +5714,7 @@ static int add_dependency(sd_bus *bus, char **args) { else assert_not_reached("Unknown verb"); - if (!bus || avoid_bus()) { + if (install_client_side()) { UnitFileChange *changes = NULL; unsigned n_changes = 0; @@ -5546,9 +5731,14 @@ static int add_dependency(sd_bus *bus, char **args) { } else { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_message_new_method_call( bus, &m, @@ -5578,7 +5768,7 @@ static int add_dependency(sd_bus *bus, char **args) { return r; if (!arg_no_reload) - r = daemon_reload(bus, args); + r = daemon_reload(args); else r = 0; } @@ -5586,12 +5776,12 @@ static int add_dependency(sd_bus *bus, char **args) { return r; } -static int preset_all(sd_bus *bus, char **args) { +static int preset_all(char **args) { UnitFileChange *changes = NULL; unsigned n_changes = 0; int r; - if (!bus || avoid_bus()) { + if (install_client_side()) { r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes); if (r < 0) { @@ -5607,9 +5797,14 @@ static int preset_all(sd_bus *bus, char **args) { } else { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + sd_bus *bus; polkit_agent_open_if_enabled(); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -5632,7 +5827,7 @@ static int preset_all(sd_bus *bus, char **args) { return r; if (!arg_no_reload) - r = daemon_reload(bus, args); + r = daemon_reload(args); else r = 0; } @@ -5643,9 +5838,8 @@ finish: return r; } -static int unit_is_enabled(sd_bus *bus, char **args) { +static int unit_is_enabled(char **args) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_strv_free_ char **names = NULL; bool enabled; char **name; @@ -5661,7 +5855,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) { enabled = r > 0; - if (!bus || avoid_bus()) { + if (install_client_side()) { STRV_FOREACH(name, names) { UnitFileState state; @@ -5682,6 +5876,13 @@ static int unit_is_enabled(sd_bus *bus, char **args) { } } else { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; + + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + STRV_FOREACH(name, names) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *s; @@ -5715,8 +5916,9 @@ static int unit_is_enabled(sd_bus *bus, char **args) { return !enabled; } -static int is_system_running(sd_bus *bus, char **args) { +static int is_system_running(char **args) { _cleanup_free_ char *state = NULL; + sd_bus *bus; int r; if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) { @@ -5725,6 +5927,10 @@ static int is_system_running(sd_bus *bus, char **args) { return EXIT_FAILURE; } + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + r = sd_bus_get_property_string( bus, "org.freedesktop.systemd1", @@ -5995,7 +6201,6 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { _cleanup_free_ char *user_home = NULL; _cleanup_free_ char *user_runtime = NULL; _cleanup_lookup_paths_free_ LookupPaths lp = {}; - bool avoid_bus_cache; char **name; int r; @@ -6006,13 +6211,11 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { if (r < 0) return r; - avoid_bus_cache = !bus || avoid_bus(); - STRV_FOREACH(name, names) { _cleanup_free_ char *path = NULL; char *new_path, *tmp_path; - r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL); + r = unit_find_paths(bus, *name, &lp, &path, NULL); if (r < 0) return r; else if (r == 0) @@ -6038,25 +6241,30 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { return 0; } -static int edit(sd_bus *bus, char **args) { +static int edit(char **args) { _cleanup_strv_free_ char **names = NULL; _cleanup_strv_free_ char **paths = NULL; char **original, **tmp; + sd_bus *bus; int r; assert(args); if (!on_tty()) { - log_error("Cannot edit units if not on a tty"); + log_error("Cannot edit units if not on a tty."); return -EINVAL; } if (arg_transport != BUS_TRANSPORT_LOCAL) { - log_error("Cannot remotely edit units"); + log_error("Cannot edit units remotely."); return -EINVAL; } - r = expand_names(bus, args + 1, NULL, &names); + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + + r = expand_names(bus, strv_skip(args, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -6086,8 +6294,8 @@ static int edit(sd_bus *bus, char **args) { } } - if (!arg_no_reload && bus && !avoid_bus()) - r = daemon_reload(bus, args); + if (!arg_no_reload && bus && !install_client_side()) + r = daemon_reload(args); end: STRV_FOREACH_PAIR(original, tmp, paths) @@ -7153,7 +7361,7 @@ static int talk_initctl(void) { #endif } -static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { +static int systemctl_main(int argc, char *argv[], int bus_error) { static const struct { const char* verb; @@ -7163,14 +7371,10 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { EQUAL } argc_cmp; const int argc; - int (* const dispatch)(sd_bus *bus, char **args); - const enum { - NOBUS = 1, - FORCE, - } bus; + int (* const dispatch)(char **args); } verbs[] = { { "list-units", MORE, 0, list_units }, - { "list-unit-files", MORE, 1, list_unit_files, NOBUS }, + { "list-unit-files", MORE, 1, list_unit_files }, { "list-sockets", MORE, 1, list_sockets }, { "list-timers", MORE, 1, list_timers }, { "list-jobs", MORE, 1, list_jobs }, @@ -7194,7 +7398,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "check", MORE, 2, check_unit_active }, { "is-failed", MORE, 2, check_unit_failed }, { "show", MORE, 1, show }, - { "cat", MORE, 2, cat, NOBUS }, + { "cat", MORE, 2, cat, }, { "status", MORE, 1, show }, { "help", MORE, 2, show }, { "snapshot", LESS, 2, snapshot }, @@ -7205,9 +7409,9 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "set-environment", MORE, 2, set_environment }, { "unset-environment", MORE, 2, set_environment }, { "import-environment", MORE, 1, import_environment}, - { "halt", EQUAL, 1, start_special, FORCE }, - { "poweroff", EQUAL, 1, start_special, FORCE }, - { "reboot", MORE, 1, start_special, FORCE }, + { "halt", EQUAL, 1, start_special, }, + { "poweroff", EQUAL, 1, start_special, }, + { "reboot", MORE, 1, start_special, }, { "kexec", EQUAL, 1, start_special }, { "suspend", EQUAL, 1, start_special }, { "hibernate", EQUAL, 1, start_special }, @@ -7217,24 +7421,24 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "emergency", EQUAL, 1, start_special }, { "exit", LESS, 2, start_special }, { "reset-failed", MORE, 1, reset_failed }, - { "enable", MORE, 2, enable_unit, NOBUS }, - { "disable", MORE, 2, enable_unit, NOBUS }, - { "is-enabled", MORE, 2, unit_is_enabled, NOBUS }, - { "reenable", MORE, 2, enable_unit, NOBUS }, - { "preset", MORE, 2, enable_unit, NOBUS }, - { "preset-all", EQUAL, 1, preset_all, NOBUS }, - { "mask", MORE, 2, enable_unit, NOBUS }, - { "unmask", MORE, 2, enable_unit, NOBUS }, - { "link", MORE, 2, enable_unit, NOBUS }, + { "enable", MORE, 2, enable_unit, }, + { "disable", MORE, 2, enable_unit, }, + { "is-enabled", MORE, 2, unit_is_enabled, }, + { "reenable", MORE, 2, enable_unit, }, + { "preset", MORE, 2, enable_unit, }, + { "preset-all", EQUAL, 1, preset_all, }, + { "mask", MORE, 2, enable_unit, }, + { "unmask", MORE, 2, enable_unit, }, + { "link", MORE, 2, enable_unit, }, { "switch-root", MORE, 2, switch_root }, { "list-dependencies", LESS, 2, list_dependencies }, - { "set-default", EQUAL, 2, set_default, NOBUS }, - { "get-default", EQUAL, 1, get_default, NOBUS }, + { "set-default", EQUAL, 2, set_default, }, + { "get-default", EQUAL, 1, get_default, }, { "set-property", MORE, 3, set_property }, { "is-system-running", EQUAL, 1, is_system_running }, - { "add-wants", MORE, 3, add_dependency, NOBUS }, - { "add-requires", MORE, 3, add_dependency, NOBUS }, - { "edit", MORE, 2, edit, NOBUS }, + { "add-wants", MORE, 3, add_dependency, }, + { "add-requires", MORE, 3, add_dependency, }, + { "edit", MORE, 2, edit, }, {} }, *verb = verbs; @@ -7292,36 +7496,14 @@ found: assert_not_reached("Unknown comparison operator."); } - /* Require a bus connection for all operations but - * enable/disable */ - if (verb->bus == NOBUS) { - if (!bus && !avoid_bus()) { - log_error_errno(bus_error, "Failed to get D-Bus connection: %m"); - return -EIO; - } - - } else { - if (running_in_chroot() > 0) { - log_info("Running in chroot, ignoring request."); - return 0; - } - - if ((verb->bus != FORCE || arg_force <= 0) && !bus) { - log_error_errno(bus_error, "Failed to get D-Bus connection: %m"); - return -EIO; - } - } - - return verb->dispatch(bus, argv + optind); + return verb->dispatch(argv + optind); } -static int reload_with_fallback(sd_bus *bus) { +static int reload_with_fallback(void) { - if (bus) { - /* First, try systemd via D-Bus. */ - if (daemon_reload(bus, NULL) >= 0) - return 0; - } + /* First, try systemd via D-Bus. */ + if (daemon_reload(NULL) >= 0) + return 0; /* Nothing else worked, so let's try signals */ assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC); @@ -7332,13 +7514,11 @@ static int reload_with_fallback(sd_bus *bus) { return 0; } -static int start_with_fallback(sd_bus *bus) { +static int start_with_fallback(void) { - if (bus) { - /* First, try systemd via D-Bus. */ - if (start_unit(bus, NULL) >= 0) - return 0; - } + /* First, try systemd via D-Bus. */ + if (start_unit(NULL) >= 0) + return 0; /* Nothing else worked, so let's try * /dev/initctl */ @@ -7396,23 +7576,16 @@ static int logind_schedule_shutdown(void) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; char date[FORMAT_TIMESTAMP_MAX]; const char *action; + sd_bus *bus; int r; - assert(geteuid() == 0); - - if (avoid_bus()) { - log_error("Unable to perform operation without bus connection."); - return -ENOSYS; - } + (void) logind_set_wall_message(); - r = sd_bus_open_system(&b); + r = acquire_bus(BUS_FULL, &bus); if (r < 0) - return log_error_errno(r, "Unable to open system bus: %m"); - - (void) logind_set_wall_message(b); + return r; switch (arg_action) { case ACTION_HALT: @@ -7433,7 +7606,7 @@ static int logind_schedule_shutdown(void) { action = strjoina("dry-", action); r = sd_bus_call_method( - b, + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", @@ -7454,10 +7627,10 @@ static int logind_schedule_shutdown(void) { #endif } -static int halt_main(sd_bus *bus) { +static int halt_main(void) { int r; - r = logind_check_inhibitors(bus, arg_action); + r = logind_check_inhibitors(arg_action); if (r < 0) return r; @@ -7475,7 +7648,7 @@ static int halt_main(sd_bus *bus) { if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) { - r = logind_reboot(bus, arg_action); + r = logind_reboot(arg_action); if (r >= 0) return r; if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) @@ -7492,7 +7665,7 @@ static int halt_main(sd_bus *bus) { } if (!arg_dry && !arg_force) - return start_with_fallback(bus); + return start_with_fallback(); assert(geteuid() == 0); @@ -7534,22 +7707,17 @@ static int runlevel_main(void) { static int logind_cancel_shutdown(void) { #ifdef HAVE_LOGIND _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; + sd_bus *bus; int r; - if (avoid_bus()) { - log_error("Unable to perform operation without bus connection."); - return -ENOSYS; - } - - r = sd_bus_open_system(&b); + r = acquire_bus(BUS_FULL, &bus); if (r < 0) - return log_error_errno(r, "Unable to open system bus: %m"); + return r; - (void) logind_set_wall_message(b); + (void) logind_set_wall_message(); r = sd_bus_call_method( - b, + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", @@ -7567,7 +7735,6 @@ static int logind_cancel_shutdown(void) { } int main(int argc, char*argv[]) { - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -7589,26 +7756,20 @@ int main(int argc, char*argv[]) { goto finish; } - if (!avoid_bus()) - r = bus_connect_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus); - - if (bus) - sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); - /* systemctl_main() will print an error message for the bus * connection, but only if it needs to */ switch (arg_action) { case ACTION_SYSTEMCTL: - r = systemctl_main(bus, argc, argv, r); + r = systemctl_main(argc, argv, r); break; case ACTION_HALT: case ACTION_POWEROFF: case ACTION_REBOOT: case ACTION_KEXEC: - r = halt_main(bus); + r = halt_main(); break; case ACTION_RUNLEVEL2: @@ -7618,12 +7779,12 @@ int main(int argc, char*argv[]) { case ACTION_RESCUE: case ACTION_EMERGENCY: case ACTION_DEFAULT: - r = start_with_fallback(bus); + r = start_with_fallback(); break; case ACTION_RELOAD: case ACTION_REEXEC: - r = reload_with_fallback(bus); + r = reload_with_fallback(); break; case ACTION_CANCEL_SHUTDOWN: @@ -7650,7 +7811,7 @@ finish: strv_free(arg_wall); - sd_bus_default_flush_close(); + release_busses(); return r < 0 ? EXIT_FAILURE : r; } -- cgit v1.2.3-54-g00ecf From 691395d84c27fea079513631b2e3b2f00b2107d6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 13:35:27 +0200 Subject: systemctl: make use of log_error_errno() where we can Also adds a couple of "return" statements, where they are missing. --- src/systemctl/systemctl.c | 225 ++++++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 139 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7dcdf32a9b..d61b9afff2 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -698,9 +698,8 @@ static int get_triggered_units( "Triggers", &error, ret); - if (r < 0) - log_error("Failed to determine triggers: %s", bus_error_message(&error, r)); + return log_error_errno(r, "Failed to determine triggers: %s", bus_error_message(&error, r)); return 0; } @@ -724,10 +723,8 @@ static int get_listening( &error, &reply, "a(ss)"); - if (r < 0) { - log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get list of listening sockets: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)"); if (r < 0) @@ -966,10 +963,8 @@ static int get_next_elapse( &error, 't', &t.monotonic); - if (r < 0) { - log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r)); r = sd_bus_get_property_trivial( bus, @@ -980,10 +975,8 @@ static int get_next_elapse( &error, 't', &t.realtime); - if (r < 0) { - log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r)); *next = t; return 0; @@ -1010,10 +1003,8 @@ static int get_last_trigger( &error, 't', last); - if (r < 0) { - log_error("Failed to get last trigger time: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get last trigger time: %s", bus_error_message(&error, r)); return 0; } @@ -1375,8 +1366,7 @@ static int list_unit_files(char **args) { r = unit_file_get_list(arg_scope, arg_root, h); if (r < 0) { unit_file_list_free(h); - log_error_errno(r, "Failed to get unit file list: %m"); - return r; + return log_error_errno(r, "Failed to get unit file list: %m"); } n_units = hashmap_size(h); @@ -1414,10 +1404,8 @@ static int list_unit_files(char **args) { &error, &reply, NULL); - if (r < 0) { - log_error("Failed to list unit files: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to list unit files: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)"); if (r < 0) @@ -1540,10 +1528,8 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha &error, &reply, "s", "org.freedesktop.systemd1.Unit"); - if (r < 0) { - log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get properties of %s: %s", name, bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}"); if (r < 0) @@ -1960,10 +1946,8 @@ static int get_default(char **args) { &error, &reply, NULL); - if (r < 0) { - log_error("Failed to get default target: %s", bus_error_message(&error, -r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get default target: %s", bus_error_message(&error, r)); r = sd_bus_message_read(reply, "s", &path); if (r < 0) @@ -2030,10 +2014,8 @@ static int set_default(char **args) { &error, &reply, "sb", unit, 1); - if (r < 0) { - log_error("Failed to set default target: %s", bus_error_message(&error, -r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r)); r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL); if (r < 0) @@ -2157,10 +2139,8 @@ static int list_jobs(char **args) { &error, &reply, NULL); - if (r < 0) { - log_error("Failed to list jobs: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to list jobs: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, 'a', "(usssoo)"); if (r < 0) @@ -2225,7 +2205,7 @@ static int cancel_job(char **args) { NULL, "u", id); if (q < 0) { - log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q)); + log_error_errno(q, "Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -2527,10 +2507,8 @@ static int check_triggering_units( "LoadState", &error, &state); - if (r < 0) { - log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r)); if (streq(state, "masked")) return 0; @@ -2543,10 +2521,8 @@ static int check_triggering_units( "TriggeredBy", &error, &triggered_by); - if (r < 0) { - log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r)); STRV_FOREACH(i, triggered_by) { r = check_one_unit(bus, *i, "active\0reloading\0", true); @@ -2642,8 +2618,7 @@ static int start_unit_one( verb = method_to_verb(method); - log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r)); - return r; + return log_error_errno(r, "Failed to %s %s: %s", verb, name, bus_error_message(error, r)); } r = sd_bus_message_read(reply, "o", &path); @@ -2784,7 +2759,7 @@ static int start_unit(char **args) { else { r = expand_names(bus, strv_skip(args, 1), suffix, &names); if (r < 0) - log_error_errno(r, "Failed to expand names: %m"); + return log_error_errno(r, "Failed to expand names: %m"); } if (!arg_no_block) { @@ -2910,9 +2885,9 @@ static int logind_reboot(enum action a) { NULL, "b", arg_ask_password); if (r < 0) - log_error("Failed to %s via logind: %s", description, bus_error_message(&error, r)); + return log_error_errno(r, "Failed to %s via logind: %s", description, bus_error_message(&error, r)); - return r; + return 0; #else return -ENOSYS; #endif @@ -3133,10 +3108,8 @@ static int start_special(char **args) { &error, NULL, "y", code); - if (r < 0) { - log_error("Failed to execute operation: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); } if (arg_force >= 2 && @@ -3236,7 +3209,7 @@ static int kill_unit(char **args) { r = expand_names(bus, args + 1, NULL, &names); if (r < 0) - log_error_errno(r, "Failed to expand names: %m"); + return log_error_errno(r, "Failed to expand names: %m"); STRV_FOREACH(name, names) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -3251,7 +3224,7 @@ static int kill_unit(char **args) { NULL, "ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal); if (q < 0) { - log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q)); + log_error_errno(q, "Failed to kill unit %s: %s", *names, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -3947,13 +3920,13 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo * info->name = strdup(name); if (!info->name) - log_oom(); + return log_oom(); LIST_PREPEND(exec, i->exec, info); info = new0(ExecStatusInfo, 1); if (!info) - log_oom(); + return log_oom(); } if (r < 0) @@ -4525,10 +4498,8 @@ static int get_unit_dbus_path_by_pid( &error, &reply, "u", pid); - if (r < 0) { - log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r)); r = sd_bus_message_read(reply, "o", &u); if (r < 0) @@ -4713,7 +4684,7 @@ static int show(char **args) { r = expand_names(bus, patterns, NULL, &names); if (r < 0) - log_error_errno(r, "Failed to expand names: %m"); + return log_error_errno(r, "Failed to expand names: %m"); STRV_FOREACH(name, names) { _cleanup_free_ char *unit; @@ -4901,10 +4872,8 @@ static int set_property(char **args) { return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); - if (r < 0) { - log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r)); return 0; } @@ -4942,10 +4911,8 @@ static int snapshot(char **args) { &error, &reply, "sb", n, false); - if (r < 0) { - log_error("Failed to create snapshot: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to create snapshot: %s", bus_error_message(&error, r)); r = sd_bus_message_read(reply, "o", &path); if (r < 0) @@ -4959,10 +4926,8 @@ static int snapshot(char **args) { "Id", &error, &id); - if (r < 0) { - log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get ID of snapshot: %s", bus_error_message(&error, r)); if (!arg_quiet) puts(id); @@ -5002,7 +4967,7 @@ static int delete_snapshot(char **args) { NULL, "s", *name); if (q < 0) { - log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q)); + log_error_errno(q, "Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -5061,7 +5026,7 @@ static int daemon_reload(char **args) { * reply */ r = 0; else if (r < 0) - log_error("Failed to execute operation: %s", bus_error_message(&error, r)); + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); return r < 0 ? r : 0; } @@ -5083,7 +5048,7 @@ static int reset_failed(char **args) { r = expand_names(bus, strv_skip(args, 1), NULL, &names); if (r < 0) - log_error_errno(r, "Failed to expand names: %m"); + return log_error_errno(r, "Failed to expand names: %m"); STRV_FOREACH(name, names) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -5098,7 +5063,7 @@ static int reset_failed(char **args) { NULL, "s", *name); if (q < 0) { - log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q)); + log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -5129,10 +5094,8 @@ static int show_environment(char **args) { &error, &reply, "as"); - if (r < 0) { - log_error("Failed to get environment: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r)); r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s"); if (r < 0) @@ -5213,10 +5176,8 @@ static int switch_root(char **args) { &error, NULL, "ss", root, init); - if (r < 0) { - log_error("Failed to switch root: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r)); return 0; } @@ -5255,10 +5216,8 @@ static int set_environment(char **args) { return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); - if (r < 0) { - log_error("Failed to set environment: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r)); return 0; } @@ -5324,10 +5283,8 @@ static int import_environment(char **args) { return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); - if (r < 0) { - log_error("Failed to import environment: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r)); return 0; } @@ -5430,13 +5387,13 @@ static int enable_sysv_units(const char *verb, char **args) { (void) reset_signal_mask(); execv(argv[0], (char**) argv); - log_error("Failed to execute %s: %m", argv[0]); + log_error_errno(r, "Failed to execute %s: %m", argv[0]); _exit(EXIT_FAILURE); } j = wait_for_terminate(pid, &status); if (j < 0) { - log_error_errno(r, "Failed to wait for child: %m"); + log_error_errno(j, "Failed to wait for child: %m"); return j; } @@ -5633,10 +5590,8 @@ static int enable_unit(char **args) { } r = sd_bus_call(bus, m, 0, &error, &reply); - if (r < 0) { - log_error("Failed to execute operation: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); if (expect_carries_install_info) { r = sd_bus_message_read(reply, "b", &carries_install_info); @@ -5758,10 +5713,8 @@ static int add_dependency(char **args) { return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, &reply); - if (r < 0) { - log_error("Failed to execute operation: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL); if (r < 0) @@ -5817,10 +5770,8 @@ static int preset_all(char **args) { unit_file_preset_mode_to_string(arg_preset_mode), arg_runtime, arg_force); - if (r < 0) { - log_error("Failed to execute operation: %s", bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL); if (r < 0) @@ -5896,10 +5847,8 @@ static int unit_is_enabled(char **args) { &error, &reply, "s", *name); - if (r < 0) { - log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r)); r = sd_bus_message_read(reply, "s", &s); if (r < 0) @@ -5965,9 +5914,8 @@ static int create_edit_temp_file(const char *new_path, const char *original_path r = mkdir_parents(new_path, 0755); if (r < 0) { - log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path); free(t); - return r; + return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path); } r = copy_file(original_path, t, 0, 0644, 0); @@ -6022,12 +5970,16 @@ static int get_file_to_edit(const char *name, const char *user_home, const char return log_oom(); if (arg_runtime) { - if (access(path, F_OK) >= 0) - return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", - run, path); - if (path2 && access(path2, F_OK) >= 0) - return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", - run, path2); + if (access(path, F_OK) >= 0) { + log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path); + return -EEXIST; + } + + if (path2 && access(path2, F_OK) >= 0) { + log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path2); + return -EEXIST; + } + *ret_path = run; run = NULL; } else { @@ -6120,10 +6072,8 @@ static int run_editor(char **paths) { assert(paths); pid = fork(); - if (pid < 0) { - log_error_errno(errno, "Failed to fork: %m"); - return -errno; - } + if (pid < 0) + return log_error_errno(errno, "Failed to fork: %m"); if (pid == 0) { const char **args; @@ -6181,7 +6131,7 @@ static int run_editor(char **paths) { * failing. */ if (errno != ENOENT) { - log_error("Failed to execute %s: %m", editor); + log_error_errno(errno, "Failed to execute %s: %m", editor); _exit(EXIT_FAILURE); } } @@ -6775,7 +6725,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case 's': - if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) { + arg_signal = signal_from_string_try_harder(optarg); + if (arg_signal < 0) { log_error("Failed to parse signal string %s.", optarg); return -EINVAL; } @@ -7190,8 +7141,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { } if (optind >= argc) { - log_error("%s: required argument missing.", - program_invocation_short_name); + log_error("%s: required argument missing.", program_invocation_short_name); return -EINVAL; } @@ -7452,8 +7402,7 @@ static int systemctl_main(int argc, char *argv[], int bus_error) { /* Special rule: no arguments (left == 0) means "list-units" */ if (left > 0) { if (streq(argv[optind], "help") && !argv[optind+1]) { - log_error("This command expects one or more " - "unit names. Did you mean --help?"); + log_error("This command expects one or more unit names. Did you mean --help?"); return -EINVAL; } @@ -7558,8 +7507,7 @@ static int halt_now(enum action a) { if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { log_info("Rebooting with argument '%s'.", param); - syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, - LINUX_REBOOT_CMD_RESTART2, param); + syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); } log_info("Rebooting."); @@ -7683,9 +7631,8 @@ static int halt_main(void) { return 0; r = halt_now(arg_action); - log_error_errno(r, "Failed to reboot: %m"); - return r; + return log_error_errno(r, "Failed to reboot: %m"); } static int runlevel_main(void) { -- cgit v1.2.3-54-g00ecf From 14b316ebf81fd21adade2fa6d2f48cc421dc5d95 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 13:36:07 +0200 Subject: systemctl: make use of strv_skip() where appropriate --- src/systemctl/systemctl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index d61b9afff2..6641aa7ebd 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3207,7 +3207,7 @@ static int kill_unit(char **args) { if (streq(arg_job_mode, "fail")) kill_who = strjoina(arg_kill_who, "-fail", NULL); - r = expand_names(bus, args + 1, NULL, &names); + r = expand_names(bus, strv_skip(args, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -4648,7 +4648,7 @@ static int show(char **args) { _cleanup_free_ char **patterns = NULL; char **name; - STRV_FOREACH(name, args + 1) { + STRV_FOREACH(name, strv_skip(args, 1)) { _cleanup_free_ char *unit = NULL; uint32_t id; @@ -5211,7 +5211,7 @@ static int set_environment(char **args) { if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append_strv(m, args + 1); + r = sd_bus_message_append_strv(m, strv_skip(args, 1)); if (r < 0) return bus_log_create_error(r); @@ -5246,7 +5246,7 @@ static int import_environment(char **args) { if (r < 0) return bus_log_create_error(r); - if (strv_isempty(args + 1)) + if (strv_isempty(strv_skip(args, 1))) r = sd_bus_message_append_strv(m, environ); else { char **a, **b; @@ -5255,7 +5255,7 @@ static int import_environment(char **args) { if (r < 0) return bus_log_create_error(r); - STRV_FOREACH(a, args + 1) { + STRV_FOREACH(a, strv_skip(args, 1)) { if (!env_name_is_valid(*a)) { log_error("Not a valid environment variable name: %s", *a); -- cgit v1.2.3-54-g00ecf From 4057e12315ae4ce2325b68c0b65cf23ccbe4de55 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 13:38:36 +0200 Subject: systemctl: don't assert on the arguments array unnecessarily In most verbs it's fine to treat the arguments array being NULL is empty array, hence do so. --- src/systemctl/systemctl.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6641aa7ebd..5bcea28411 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2175,8 +2175,6 @@ static int cancel_job(char **args) { char **name; int r = 0; - assert(args); - if (strv_length(args) <= 1) return daemon_reload(args); @@ -3154,8 +3152,6 @@ static int check_unit_generic(int code, const char *good_states, char **args) { char **name; int r; - assert(args); - r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) return r; @@ -3192,8 +3188,6 @@ static int kill_unit(char **args) { sd_bus *bus; int r, q; - assert(args); - polkit_agent_open_if_enabled(); r = acquire_bus(BUS_MANAGER, &bus); @@ -4764,8 +4758,6 @@ static int cat(char **args) { bool first = true; int r; - assert(args); - if (arg_transport != BUS_TRANSPORT_LOCAL) { log_error("Cannot remotely cat units."); return -EINVAL; @@ -4941,8 +4933,6 @@ static int delete_snapshot(char **args) { char **name; int r; - assert(args); - polkit_agent_open_if_enabled(); r = acquire_bus(BUS_MANAGER, &bus); @@ -5228,8 +5218,6 @@ static int import_environment(char **args) { sd_bus *bus; int r; - assert(args); - polkit_agent_open_if_enabled(); r = acquire_bus(BUS_MANAGER, &bus); @@ -6198,8 +6186,6 @@ static int edit(char **args) { sd_bus *bus; int r; - assert(args); - if (!on_tty()) { log_error("Cannot edit units if not on a tty."); return -EINVAL; -- cgit v1.2.3-54-g00ecf From 57ab90065d550b5f86e67f5d9ebc40f8a4c1297d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 14:00:12 +0200 Subject: systemctl: split out code invoking SetExitCode() into function of its own --- src/systemctl/systemctl.c | 56 ++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 5bcea28411..56852fdb92 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3054,6 +3054,30 @@ static int prepare_firmware_setup(void) { return logind_prepare_firmware_setup(); } +static int set_exit_code(uint8_t code) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus; + int r; + + r = acquire_bus(BUS_MANAGER, &bus); + if (r < 0) + return r; + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "SetExitCode", + &error, + NULL, + "y", code); + if (r < 0) + return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); + + return 0; +} + static int start_special(char **args) { enum action a; int r; @@ -3075,39 +3099,25 @@ static int start_special(char **args) { if (r < 0) return r; - if (a == ACTION_REBOOT && args[1]) { + if (a == ACTION_REBOOT && strv_length(args) > 1) { r = update_reboot_param_file(args[1]); if (r < 0) return r; + } else if (a == ACTION_EXIT && strv_length(args) > 1) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - /* If the exit code is not given on the command line, don't - * reset it to zero: just keep it as it might have been set - * previously. */ uint8_t code = 0; - sd_bus *bus; - r = safe_atou8(args[1], &code); - if (r < 0) { - log_error("Invalid exit code."); - return -EINVAL; - } + /* If the exit code is not given on the command line, + * don't reset it to zero: just keep it as it might + * have been set previously. */ - r = acquire_bus(BUS_MANAGER, &bus); + r = safe_atou8(args[1], &code); if (r < 0) - return r; + return log_error_errno(r, "Invalid exit code."); - r = sd_bus_call_method( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "SetExitCode", - &error, - NULL, - "y", code); + r = set_exit_code(code); if (r < 0) - return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r)); + return r; } if (arg_force >= 2 && -- cgit v1.2.3-54-g00ecf From 7089051f67e969a524bde5a7f264491a0373f7e5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 14:00:21 +0200 Subject: systemctl: prefer shutting down through logind even as root Otherwise, wall messages will not be generated for root. --- src/systemctl/systemctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 56852fdb92..83a29e6abc 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3136,9 +3136,8 @@ static int start_special(char **args) { ACTION_EXIT)) return daemon_reload(args); - /* first try logind, to allow authentication with polkit */ - if (geteuid() != 0 && - IN_SET(a, + /* First try logind, to allow authentication with polkit */ + if (IN_SET(a, ACTION_POWEROFF, ACTION_REBOOT, ACTION_SUSPEND, @@ -3150,7 +3149,8 @@ static int start_special(char **args) { if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) /* requested operation is not supported or already in progress */ return r; - /* on all other errors, try low-level operation */ + + /* On all other errors, try low-level operation */ } return start_unit(args); -- cgit v1.2.3-54-g00ecf From e449de87776877dc59d6662fda08621d15a19eff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 15:00:07 +0200 Subject: systemctl: port verb dispatching to generic verbs.[ch] code Let's parse the command line the same way in our various tools. --- src/systemctl/systemctl.c | 460 ++++++++++++++++++++-------------------------- 1 file changed, 203 insertions(+), 257 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 83a29e6abc..14ef29f76e 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -73,6 +73,7 @@ #include "unit-name.h" #include "util.h" #include "utmp-wtmp.h" +#include "verbs.h" static char **arg_types = NULL; static char **arg_states = NULL; @@ -140,7 +141,7 @@ static bool arg_plain = false; static bool arg_firmware_setup = false; static bool arg_now = false; -static int daemon_reload(char **args); +static int daemon_reload(int argc, char *argv[], void* userdata); static int halt_now(enum action a); static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet); @@ -657,7 +658,7 @@ static int get_unit_list_recursive( return c; } -static int list_units(char **args) { +static int list_units(int argc, char *argv[], void *userdata) { _cleanup_free_ UnitInfo *unit_infos = NULL; _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; @@ -670,7 +671,7 @@ static int list_units(char **args) { if (r < 0) return r; - r = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); + r = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines); if (r < 0) return r; @@ -864,7 +865,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { return 0; } -static int list_sockets(char **args) { +static int list_sockets(int argc, char *argv[], void *userdata) { _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; _cleanup_free_ UnitInfo *unit_infos = NULL; @@ -882,7 +883,7 @@ static int list_sockets(char **args) { if (r < 0) return r; - n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); + n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1170,7 +1171,7 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) { return next_elapse; } -static int list_timers(char **args) { +static int list_timers(int argc, char *argv[], void *userdata) { _cleanup_(message_set_freep) Set *replies = NULL; _cleanup_strv_free_ char **machines = NULL; _cleanup_free_ struct timer_info *timer_infos = NULL; @@ -1189,7 +1190,7 @@ static int list_timers(char **args) { if (r < 0) return r; - n = get_unit_list_recursive(bus, strv_skip(args, 1), &unit_infos, &replies, &machines); + n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines); if (n < 0) return n; @@ -1341,7 +1342,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { printf("\n%u unit files listed.\n", c); } -static int list_unit_files(char **args) { +static int list_unit_files(int argc, char *argv[], void *userdata) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ UnitFileList *units = NULL; UnitFileList *unit; @@ -1378,7 +1379,7 @@ static int list_unit_files(char **args) { } HASHMAP_FOREACH(u, h, i) { - if (!output_show_unit_file(u, strv_skip(args, 1))) + if (!output_show_unit_file(u, strv_skip(argv, 1))) continue; units[c++] = *u; @@ -1421,7 +1422,7 @@ static int list_unit_files(char **args) { unit_file_state_from_string(state) }; - if (output_show_unit_file(&units[c], strv_skip(args, 1))) + if (output_show_unit_file(&units[c], strv_skip(argv, 1))) c ++; } @@ -1653,15 +1654,15 @@ static int list_dependencies_one( return 0; } -static int list_dependencies(char **args) { +static int list_dependencies(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **units = NULL; _cleanup_free_ char *unit = NULL; const char *u; sd_bus *bus; int r; - if (args[1]) { - r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &unit); + if (argv[1]) { + r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &unit); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -1890,7 +1891,7 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n) printf("\n%u machines listed.\n", n); } -static int list_machines(char **args) { +static int list_machines(int argc, char *argv[], void *userdata) { struct machine_info *machine_infos = NULL; sd_bus *bus; int r; @@ -1906,7 +1907,7 @@ static int list_machines(char **args) { if (r < 0) return r; - r = get_machine_list(bus, &machine_infos, strv_skip(args, 1)); + r = get_machine_list(bus, &machine_infos, strv_skip(argv, 1)); if (r < 0) return r; @@ -1917,7 +1918,7 @@ static int list_machines(char **args) { return 0; } -static int get_default(char **args) { +static int get_default(int argc, char *argv[], void *userdata) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ char *_path = NULL; const char *path; @@ -1973,11 +1974,14 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha } } -static int set_default(char **args) { +static int set_default(int argc, char *argv[], void *userdata) { _cleanup_free_ char *unit = NULL; int r; - r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &unit); + assert(argc >= 2); + assert(argv); + + r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &unit); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -2023,7 +2027,7 @@ static int set_default(char **args) { /* Try to reload if enabled */ if (!arg_no_reload) - r = daemon_reload(args); + r = daemon_reload(argc, argv, userdata); else r = 0; } @@ -2112,7 +2116,7 @@ static bool output_show_job(struct job_info *job, char **patterns) { return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE); } -static int list_jobs(char **args) { +static int list_jobs(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *name, *type, *state, *job_path, *unit_path; @@ -2149,7 +2153,7 @@ static int list_jobs(char **args) { while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) { struct job_info job = { id, name, type, state }; - if (!output_show_job(&job, strv_skip(args, 1))) { + if (!output_show_job(&job, strv_skip(argv, 1))) { skipped = true; continue; } @@ -2170,13 +2174,13 @@ static int list_jobs(char **args) { return r; } -static int cancel_job(char **args) { +static int cancel_job(int argc, char *argv[], void *userdata) { sd_bus *bus; char **name; int r = 0; - if (strv_length(args) <= 1) - return daemon_reload(args); + if (argc <= 1) + return daemon_reload(argc, argv, userdata); polkit_agent_open_if_enabled(); @@ -2184,7 +2188,7 @@ static int cancel_job(char **args) { if (r < 0) return r; - STRV_FOREACH(name, args+1) { + STRV_FOREACH(name, strv_skip(argv, 1)) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; uint32_t id; int q; @@ -2715,7 +2719,7 @@ static enum action verb_to_action(const char *verb) { return _ACTION_INVALID; } -static int start_unit(char **args) { +static int start_unit(int argc, char *argv[], void *userdata) { _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; const char *method, *mode, *one_name, *suffix = NULL; _cleanup_strv_free_ char **names = NULL; @@ -2732,10 +2736,11 @@ static int start_unit(char **args) { if (arg_action == ACTION_SYSTEMCTL) { enum action action; - method = verb_to_method(args[0]); - action = verb_to_action(args[0]); - if (streq(args[0], "isolate")) { + method = verb_to_method(argv[0]); + action = verb_to_action(argv[0]); + + if (streq(argv[0], "isolate")) { mode = "isolate"; suffix = ".target"; } else @@ -2755,7 +2760,7 @@ static int start_unit(char **args) { if (one_name) names = strv_new(one_name, NULL); else { - r = expand_names(bus, strv_skip(args, 1), suffix, &names); + r = expand_names(bus, strv_skip(argv, 1), suffix, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); } @@ -3078,13 +3083,13 @@ static int set_exit_code(uint8_t code) { return 0; } -static int start_special(char **args) { +static int start_special(int argc, char *argv[], void *userdata) { enum action a; int r; - assert(args); + assert(argv); - a = verb_to_action(args[0]); + a = verb_to_action(argv[0]); r = logind_check_inhibitors(a); if (r < 0) @@ -3099,19 +3104,19 @@ static int start_special(char **args) { if (r < 0) return r; - if (a == ACTION_REBOOT && strv_length(args) > 1) { - r = update_reboot_param_file(args[1]); + if (a == ACTION_REBOOT && argc > 1) { + r = update_reboot_param_file(argv[1]); if (r < 0) return r; - } else if (a == ACTION_EXIT && strv_length(args) > 1) { + } else if (a == ACTION_EXIT && argc > 1) { uint8_t code = 0; /* If the exit code is not given on the command line, * don't reset it to zero: just keep it as it might * have been set previously. */ - r = safe_atou8(args[1], &code); + r = safe_atou8(argv[1], &code); if (r < 0) return log_error_errno(r, "Invalid exit code."); @@ -3134,7 +3139,7 @@ static int start_special(char **args) { ACTION_REBOOT, ACTION_KEXEC, ACTION_EXIT)) - return daemon_reload(args); + return daemon_reload(argc, argv, userdata); /* First try logind, to allow authentication with polkit */ if (IN_SET(a, @@ -3153,7 +3158,7 @@ static int start_special(char **args) { /* On all other errors, try low-level operation */ } - return start_unit(args); + return start_unit(argc, argv, userdata); } static int check_unit_generic(int code, const char *good_states, char **args) { @@ -3183,16 +3188,16 @@ static int check_unit_generic(int code, const char *good_states, char **args) { return r; } -static int check_unit_active(char **args) { +static int check_unit_active(int argc, char *argv[], void *userdata) { /* According to LSB: 3, "program is not running" */ - return check_unit_generic(3, "active\0reloading\0", strv_skip(args, 1)); + return check_unit_generic(3, "active\0reloading\0", strv_skip(argv, 1)); } -static int check_unit_failed(char **args) { - return check_unit_generic(1, "failed\0", strv_skip(args, 1)); +static int check_unit_failed(int argc, char *argv[], void *userdata) { + return check_unit_generic(1, "failed\0", strv_skip(argv, 1)); } -static int kill_unit(char **args) { +static int kill_unit(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; char *kill_who = NULL, **name; sd_bus *bus; @@ -3211,7 +3216,7 @@ static int kill_unit(char **args) { if (streq(arg_job_mode, "fail")) kill_who = strjoina(arg_kill_who, "-fail", NULL); - r = expand_names(bus, strv_skip(args, 1), NULL, &names); + r = expand_names(bus, strv_skip(argv, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -4612,16 +4617,22 @@ static int show_system_status(sd_bus *bus) { return 0; } -static int show(char **args) { - bool show_properties, show_status, new_line = false; +static int show(int argc, char *argv[], void *userdata) { + bool show_properties, show_status, show_help, new_line = false; bool ellipsized = false; int r, ret = 0; sd_bus *bus; - assert(args); + assert(argv); - show_properties = streq(args[0], "show"); - show_status = streq(args[0], "status"); + show_properties = streq(argv[0], "show"); + show_status = streq(argv[0], "status"); + show_help = streq(argv[0], "help"); + + if (show_help && argc <= 1) { + log_error("This command expects one or more unit names. Did you mean --help?"); + return -EINVAL; + } if (show_properties) pager_open_if_enabled(); @@ -4637,22 +4648,22 @@ static int show(char **args) { return r; /* If no argument is specified inspect the manager itself */ - if (show_properties && strv_length(args) <= 1) - return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized); + if (show_properties && argc <= 1) + return show_one(argv[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized); - if (show_status && strv_length(args) <= 1) { + if (show_status && argc <= 1) { pager_open_if_enabled(); show_system_status(bus); new_line = true; if (arg_all) - ret = show_all(args[0], bus, false, &new_line, &ellipsized); + ret = show_all(argv[0], bus, false, &new_line, &ellipsized); } else { _cleanup_free_ char **patterns = NULL; char **name; - STRV_FOREACH(name, strv_skip(args, 1)) { + STRV_FOREACH(name, strv_skip(argv, 1)) { _cleanup_free_ char *unit = NULL; uint32_t id; @@ -4675,8 +4686,7 @@ static int show(char **args) { } } - r = show_one(args[0], bus, unit, show_properties, - &new_line, &ellipsized); + r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized); if (r < 0) return r; else if (r > 0 && ret == 0) @@ -4697,8 +4707,7 @@ static int show(char **args) { if (!unit) return log_oom(); - r = show_one(args[0], bus, unit, show_properties, - &new_line, &ellipsized); + r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized); if (r < 0) return r; else if (r > 0 && ret == 0) @@ -4758,7 +4767,7 @@ static int cat_file(const char *filename, bool newline) { return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false); } -static int cat(char **args) { +static int cat(int argc, char *argv[], void *userdata) { _cleanup_free_ char *user_home = NULL; _cleanup_free_ char *user_runtime = NULL; _cleanup_lookup_paths_free_ LookupPaths lp = {}; @@ -4781,7 +4790,7 @@ static int cat(char **args) { if (r < 0) return r; - r = expand_names(bus, strv_skip(args, 1), NULL, &names); + r = expand_names(bus, strv_skip(argv, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -4819,7 +4828,7 @@ static int cat(char **args) { return 0; } -static int set_property(char **args) { +static int set_property(int argc, char *argv[], void *userdata) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *n = NULL; @@ -4843,7 +4852,7 @@ static int set_property(char **args) { if (r < 0) return bus_log_create_error(r); - r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &n); + r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); @@ -4855,7 +4864,7 @@ static int set_property(char **args) { if (r < 0) return bus_log_create_error(r); - STRV_FOREACH(i, args + 2) { + STRV_FOREACH(i, strv_skip(argv, 2)) { r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); if (r < 0) return bus_log_create_error(r); @@ -4880,7 +4889,7 @@ static int set_property(char **args) { return 0; } -static int snapshot(char **args) { +static int snapshot(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_free_ char *n = NULL, *id = NULL; @@ -4890,8 +4899,8 @@ static int snapshot(char **args) { polkit_agent_open_if_enabled(); - if (strv_length(args) > 1) { - r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".snapshot", &n); + if (argc > 1) { + r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".snapshot", &n); if (r < 0) return log_error_errno(r, "Failed to generate unit name: %m"); } else { @@ -4937,7 +4946,7 @@ static int snapshot(char **args) { return 0; } -static int delete_snapshot(char **args) { +static int delete_snapshot(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; sd_bus *bus; char **name; @@ -4949,7 +4958,7 @@ static int delete_snapshot(char **args) { if (r < 0) return r; - r = expand_names(bus, strv_skip(args, 1), ".snapshot", &names); + r = expand_names(bus, strv_skip(argv, 1), ".snapshot", &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -4976,7 +4985,7 @@ static int delete_snapshot(char **args) { return r; } -static int daemon_reload(char **args) { +static int daemon_reload(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *method; sd_bus *bus; @@ -4996,15 +5005,15 @@ static int daemon_reload(char **args) { assert(arg_action == ACTION_SYSTEMCTL); method = - streq(args[0], "clear-jobs") || - streq(args[0], "cancel") ? "ClearJobs" : - streq(args[0], "daemon-reexec") ? "Reexecute" : - streq(args[0], "reset-failed") ? "ResetFailed" : - streq(args[0], "halt") ? "Halt" : - streq(args[0], "poweroff") ? "PowerOff" : - streq(args[0], "reboot") ? "Reboot" : - streq(args[0], "kexec") ? "KExec" : - streq(args[0], "exit") ? "Exit" : + streq(argv[0], "clear-jobs") || + streq(argv[0], "cancel") ? "ClearJobs" : + streq(argv[0], "daemon-reexec") ? "Reexecute" : + streq(argv[0], "reset-failed") ? "ResetFailed" : + streq(argv[0], "halt") ? "Halt" : + streq(argv[0], "poweroff") ? "PowerOff" : + streq(argv[0], "reboot") ? "Reboot" : + streq(argv[0], "kexec") ? "KExec" : + streq(argv[0], "exit") ? "Exit" : /* "daemon-reload" */ "Reload"; } @@ -5031,14 +5040,14 @@ static int daemon_reload(char **args) { return r < 0 ? r : 0; } -static int reset_failed(char **args) { +static int reset_failed(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; sd_bus *bus; char **name; int r, q; - if (strv_length(args) <= 1) - return daemon_reload(args); + if (argc <= 1) + return daemon_reload(argc, argv, userdata); polkit_agent_open_if_enabled(); @@ -5046,7 +5055,7 @@ static int reset_failed(char **args) { if (r < 0) return r; - r = expand_names(bus, strv_skip(args, 1), NULL, &names); + r = expand_names(bus, strv_skip(argv, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -5072,7 +5081,7 @@ static int reset_failed(char **args) { return r; } -static int show_environment(char **args) { +static int show_environment(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *text; @@ -5113,12 +5122,11 @@ static int show_environment(char **args) { return 0; } -static int switch_root(char **args) { +static int switch_root(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *cmdline_init = NULL; const char *root, *init; sd_bus *bus; - unsigned l; int r; if (arg_transport != BUS_TRANSPORT_LOCAL) { @@ -5126,16 +5134,15 @@ static int switch_root(char **args) { return -EINVAL; } - l = strv_length(args); - if (l < 2 || l > 3) { + if (argc < 2 || argc > 3) { log_error("Wrong number of arguments."); return -EINVAL; } - root = args[1]; + root = argv[1]; - if (l >= 3) - init = args[2]; + if (argc >= 3) + init = argv[2]; else { r = parse_env_file("/proc/cmdline", WHITESPACE, "init", &cmdline_init, @@ -5182,14 +5189,15 @@ static int switch_root(char **args) { return 0; } -static int set_environment(char **args) { +static int set_environment(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; const char *method; sd_bus *bus; int r; - assert(args); + assert(argc > 1); + assert(argv); polkit_agent_open_if_enabled(); @@ -5197,7 +5205,7 @@ static int set_environment(char **args) { if (r < 0) return r; - method = streq(args[0], "set-environment") + method = streq(argv[0], "set-environment") ? "SetEnvironment" : "UnsetEnvironment"; @@ -5211,7 +5219,7 @@ static int set_environment(char **args) { if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append_strv(m, strv_skip(args, 1)); + r = sd_bus_message_append_strv(m, strv_skip(argv, 1)); if (r < 0) return bus_log_create_error(r); @@ -5222,7 +5230,7 @@ static int set_environment(char **args) { return 0; } -static int import_environment(char **args) { +static int import_environment(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; sd_bus *bus; @@ -5244,7 +5252,7 @@ static int import_environment(char **args) { if (r < 0) return bus_log_create_error(r); - if (strv_isempty(strv_skip(args, 1))) + if (argc < 2) r = sd_bus_message_append_strv(m, environ); else { char **a, **b; @@ -5253,7 +5261,7 @@ static int import_environment(char **args) { if (r < 0) return bus_log_create_error(r); - STRV_FOREACH(a, strv_skip(args, 1)) { + STRV_FOREACH(a, strv_skip(argv, 1)) { if (!env_name_is_valid(*a)) { log_error("Not a valid environment variable name: %s", *a); @@ -5461,18 +5469,18 @@ static int mangle_names(char **original_names, char ***mangled_names) { return 0; } -static int enable_unit(char **args) { +static int enable_unit(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; - const char *verb = args[0]; + const char *verb = argv[0]; UnitFileChange *changes = NULL; unsigned n_changes = 0; int carries_install_info = -1; int r; - if (!args[1]) + if (!argv[1]) return 0; - r = mangle_names(args+1, &names); + r = mangle_names(strv_skip(argv, 1), &names); if (r < 0) return r; @@ -5603,7 +5611,7 @@ static int enable_unit(char **args) { /* Try to reload if enabled */ if (!arg_no_reload) - r = daemon_reload(args); + r = daemon_reload(argc, argv, userdata); else r = 0; } @@ -5619,7 +5627,7 @@ static int enable_unit(char **args) { "3) A unit may be started when needed via activation (socket, path, timer,\n" " D-Bus, udev, scripted systemctl call, ...).\n"); - if (arg_now && n_changes > 0 && STR_IN_SET(args[0], "enable", "disable", "mask")) { + if (arg_now && n_changes > 0 && STR_IN_SET(argv[0], "enable", "disable", "mask")) { char *new_args[n_changes + 2]; sd_bus *bus; unsigned i; @@ -5628,12 +5636,12 @@ static int enable_unit(char **args) { if (r < 0) return r; - new_args[0] = (char*) (streq(args[0], "enable") ? "start" : "stop"); + new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop"); for (i = 0; i < n_changes; i++) new_args[i + 1] = basename(changes[i].path); new_args[i + 1] = NULL; - r = start_unit(new_args); + r = start_unit(strv_length(new_args), new_args, userdata); } finish: @@ -5642,21 +5650,21 @@ finish: return r; } -static int add_dependency(char **args) { +static int add_dependency(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; _cleanup_free_ char *target = NULL; - const char *verb = args[0]; + const char *verb = argv[0]; UnitDependency dep; int r = 0; - if (!args[1]) + if (!argv[1]) return 0; - r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &target); + r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); - r = mangle_names(args+2, &names); + r = mangle_names(strv_skip(argv, 2), &names); if (r < 0) return r; @@ -5719,7 +5727,7 @@ static int add_dependency(char **args) { return r; if (!arg_no_reload) - r = daemon_reload(args); + r = daemon_reload(argc, argv, userdata); else r = 0; } @@ -5727,7 +5735,7 @@ static int add_dependency(char **args) { return r; } -static int preset_all(char **args) { +static int preset_all(int argc, char *argv[], void *userdata) { UnitFileChange *changes = NULL; unsigned n_changes = 0; int r; @@ -5776,7 +5784,7 @@ static int preset_all(char **args) { return r; if (!arg_no_reload) - r = daemon_reload(args); + r = daemon_reload(argc, argv, userdata); else r = 0; } @@ -5787,18 +5795,18 @@ finish: return r; } -static int unit_is_enabled(char **args) { +static int unit_is_enabled(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; bool enabled; char **name; int r; - r = mangle_names(args+1, &names); + r = mangle_names(strv_skip(argv, 1), &names); if (r < 0) return r; - r = enable_sysv_units(args[0], names); + r = enable_sysv_units(argv[0], names); if (r < 0) return r; @@ -5863,7 +5871,7 @@ static int unit_is_enabled(char **args) { return !enabled; } -static int is_system_running(char **args) { +static int is_system_running(int argc, char *argv[], void *userdata) { _cleanup_free_ char *state = NULL; sd_bus *bus; int r; @@ -6189,7 +6197,7 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { return 0; } -static int edit(char **args) { +static int edit(int argc, char *argv[], void *userdata) { _cleanup_strv_free_ char **names = NULL; _cleanup_strv_free_ char **paths = NULL; char **original, **tmp; @@ -6210,7 +6218,7 @@ static int edit(char **args) { if (r < 0) return r; - r = expand_names(bus, strv_skip(args, 1), NULL, &names); + r = expand_names(bus, strv_skip(argv, 1), NULL, &names); if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); @@ -6241,7 +6249,7 @@ static int edit(char **args) { } if (!arg_no_reload && bus && !install_client_side()) - r = daemon_reload(args); + r = daemon_reload(argc, argv, userdata); end: STRV_FOREACH_PAIR(original, tmp, paths) @@ -7307,147 +7315,85 @@ static int talk_initctl(void) { #endif } -static int systemctl_main(int argc, char *argv[], int bus_error) { - - static const struct { - const char* verb; - const enum { - MORE, - LESS, - EQUAL - } argc_cmp; - const int argc; - int (* const dispatch)(char **args); - } verbs[] = { - { "list-units", MORE, 0, list_units }, - { "list-unit-files", MORE, 1, list_unit_files }, - { "list-sockets", MORE, 1, list_sockets }, - { "list-timers", MORE, 1, list_timers }, - { "list-jobs", MORE, 1, list_jobs }, - { "list-machines", MORE, 1, list_machines }, - { "clear-jobs", EQUAL, 1, daemon_reload }, - { "cancel", MORE, 2, cancel_job }, - { "start", MORE, 2, start_unit }, - { "stop", MORE, 2, start_unit }, - { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ - { "reload", MORE, 2, start_unit }, - { "restart", MORE, 2, start_unit }, - { "try-restart", MORE, 2, start_unit }, - { "reload-or-restart", MORE, 2, start_unit }, - { "reload-or-try-restart", MORE, 2, start_unit }, - { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */ - { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ - { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ - { "isolate", EQUAL, 2, start_unit }, - { "kill", MORE, 2, kill_unit }, - { "is-active", MORE, 2, check_unit_active }, - { "check", MORE, 2, check_unit_active }, - { "is-failed", MORE, 2, check_unit_failed }, - { "show", MORE, 1, show }, - { "cat", MORE, 2, cat, }, - { "status", MORE, 1, show }, - { "help", MORE, 2, show }, - { "snapshot", LESS, 2, snapshot }, - { "delete", MORE, 2, delete_snapshot }, - { "daemon-reload", EQUAL, 1, daemon_reload }, - { "daemon-reexec", EQUAL, 1, daemon_reload }, - { "show-environment", EQUAL, 1, show_environment }, - { "set-environment", MORE, 2, set_environment }, - { "unset-environment", MORE, 2, set_environment }, - { "import-environment", MORE, 1, import_environment}, - { "halt", EQUAL, 1, start_special, }, - { "poweroff", EQUAL, 1, start_special, }, - { "reboot", MORE, 1, start_special, }, - { "kexec", EQUAL, 1, start_special }, - { "suspend", EQUAL, 1, start_special }, - { "hibernate", EQUAL, 1, start_special }, - { "hybrid-sleep", EQUAL, 1, start_special }, - { "default", EQUAL, 1, start_special }, - { "rescue", EQUAL, 1, start_special }, - { "emergency", EQUAL, 1, start_special }, - { "exit", LESS, 2, start_special }, - { "reset-failed", MORE, 1, reset_failed }, - { "enable", MORE, 2, enable_unit, }, - { "disable", MORE, 2, enable_unit, }, - { "is-enabled", MORE, 2, unit_is_enabled, }, - { "reenable", MORE, 2, enable_unit, }, - { "preset", MORE, 2, enable_unit, }, - { "preset-all", EQUAL, 1, preset_all, }, - { "mask", MORE, 2, enable_unit, }, - { "unmask", MORE, 2, enable_unit, }, - { "link", MORE, 2, enable_unit, }, - { "switch-root", MORE, 2, switch_root }, - { "list-dependencies", LESS, 2, list_dependencies }, - { "set-default", EQUAL, 2, set_default, }, - { "get-default", EQUAL, 1, get_default, }, - { "set-property", MORE, 3, set_property }, - { "is-system-running", EQUAL, 1, is_system_running }, - { "add-wants", MORE, 3, add_dependency, }, - { "add-requires", MORE, 3, add_dependency, }, - { "edit", MORE, 2, edit, }, +static int systemctl_main(int argc, char *argv[]) { + + static const Verb verbs[] = { + { "list-units", VERB_ANY, 1, VERB_DEFAULT, list_units }, + { "list-unit-files", VERB_ANY, 1, 0, list_unit_files }, + { "list-sockets", VERB_ANY, 1, 0, list_sockets }, + { "list-timers", VERB_ANY, 1, 0, list_timers }, + { "list-jobs", VERB_ANY, 1, 0, list_jobs }, + { "list-machines", VERB_ANY, 1, 0, list_machines }, + { "clear-jobs", VERB_ANY, 1, 0, daemon_reload }, + { "cancel", 2, VERB_ANY, 0, cancel_job }, + { "start", 2, VERB_ANY, 0, start_unit }, + { "stop", 2, VERB_ANY, 0, start_unit }, + { "condstop", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */ + { "reload", 2, VERB_ANY, 0, start_unit }, + { "restart", 2, VERB_ANY, 0, start_unit }, + { "try-restart", 2, VERB_ANY, 0, start_unit }, + { "reload-or-restart", 2, VERB_ANY, 0, start_unit }, + { "reload-or-try-restart", 2, VERB_ANY, 0, start_unit }, + { "force-reload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with SysV */ + { "condreload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */ + { "condrestart", 2, VERB_ANY, 0, start_unit }, /* For compatibility with RH */ + { "isolate", 2, 2, 0, start_unit }, + { "kill", 2, VERB_ANY, 0, kill_unit }, + { "is-active", 2, VERB_ANY, 0, check_unit_active }, + { "check", 2, VERB_ANY, 0, check_unit_active }, + { "is-failed", 2, VERB_ANY, 0, check_unit_failed }, + { "show", VERB_ANY, VERB_ANY, 0, show }, + { "cat", 2, VERB_ANY, 0, cat }, + { "status", VERB_ANY, VERB_ANY, 0, show }, + { "help", VERB_ANY, VERB_ANY, 0, show }, + { "snapshot", VERB_ANY, 2, 0, snapshot }, + { "delete", 2, VERB_ANY, 0, delete_snapshot }, + { "daemon-reload", VERB_ANY, 1, 0, daemon_reload }, + { "daemon-reexec", VERB_ANY, 1, 0, daemon_reload }, + { "show-environment", VERB_ANY, 1, 0, show_environment }, + { "set-environment", 2, VERB_ANY, 0, set_environment }, + { "unset-environment", 2, VERB_ANY, 0, set_environment }, + { "import-environment", VERB_ANY, VERB_ANY, 0, import_environment}, + { "halt", VERB_ANY, 1, 0, start_special }, + { "poweroff", VERB_ANY, 1, 0, start_special }, + { "reboot", VERB_ANY, 2, 0, start_special }, + { "kexec", VERB_ANY, 1, 0, start_special }, + { "suspend", VERB_ANY, 1, 0, start_special }, + { "hibernate", VERB_ANY, 1, 0, start_special }, + { "hybrid-sleep", VERB_ANY, 1, 0, start_special }, + { "default", VERB_ANY, 1, 0, start_special }, + { "rescue", VERB_ANY, 1, 0, start_special }, + { "emergency", VERB_ANY, 1, 0, start_special }, + { "exit", VERB_ANY, 2, 0, start_special }, + { "reset-failed", VERB_ANY, VERB_ANY, 0, reset_failed }, + { "enable", 2, VERB_ANY, 0, enable_unit }, + { "disable", 2, VERB_ANY, 0, enable_unit }, + { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled }, + { "reenable", 2, VERB_ANY, 0, enable_unit }, + { "preset", 2, VERB_ANY, 0, enable_unit }, + { "preset-all", VERB_ANY, 1, 0, preset_all }, + { "mask", 2, VERB_ANY, 0, enable_unit }, + { "unmask", 2, VERB_ANY, 0, enable_unit }, + { "link", 2, VERB_ANY, 0, enable_unit }, + { "switch-root", 2, VERB_ANY, 0, switch_root }, + { "list-dependencies", VERB_ANY, 2, 0, list_dependencies }, + { "set-default", 2, 2, 0, set_default }, + { "get-default", VERB_ANY, 1, 0, get_default, }, + { "set-property", 3, VERB_ANY, 0, set_property }, + { "is-system-running", VERB_ANY, 1, 0, is_system_running }, + { "add-wants", 3, VERB_ANY, 0, add_dependency }, + { "add-requires", 3, VERB_ANY, 0, add_dependency }, + { "edit", 2, VERB_ANY, 0, edit }, {} - }, *verb = verbs; - - int left; - - assert(argc >= 0); - assert(argv); - - left = argc - optind; - - /* Special rule: no arguments (left == 0) means "list-units" */ - if (left > 0) { - if (streq(argv[optind], "help") && !argv[optind+1]) { - log_error("This command expects one or more unit names. Did you mean --help?"); - return -EINVAL; - } - - for (; verb->verb; verb++) - if (streq(argv[optind], verb->verb)) - goto found; - - log_error("Unknown operation '%s'.", argv[optind]); - return -EINVAL; - } -found: - - switch (verb->argc_cmp) { - - case EQUAL: - if (left != verb->argc) { - log_error("Invalid number of arguments."); - return -EINVAL; - } - - break; - - case MORE: - if (left < verb->argc) { - log_error("Too few arguments."); - return -EINVAL; - } - - break; - - case LESS: - if (left > verb->argc) { - log_error("Too many arguments."); - return -EINVAL; - } - - break; - - default: - assert_not_reached("Unknown comparison operator."); - } + }; - return verb->dispatch(argv + optind); + return dispatch_verb(argc, argv, verbs, NULL); } static int reload_with_fallback(void) { /* First, try systemd via D-Bus. */ - if (daemon_reload(NULL) >= 0) + if (daemon_reload(0, NULL, NULL) >= 0) return 0; /* Nothing else worked, so let's try signals */ @@ -7462,7 +7408,7 @@ static int reload_with_fallback(void) { static int start_with_fallback(void) { /* First, try systemd via D-Bus. */ - if (start_unit(NULL) >= 0) + if (start_unit(0, NULL, NULL) >= 0) return 0; /* Nothing else worked, so let's try @@ -7705,7 +7651,7 @@ int main(int argc, char*argv[]) { switch (arg_action) { case ACTION_SYSTEMCTL: - r = systemctl_main(argc, argv, r); + r = systemctl_main(argc, argv); break; case ACTION_HALT: -- cgit v1.2.3-54-g00ecf From 19578bb26b10b766227cff4d5962521952aac369 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 15:08:33 +0200 Subject: systemctl: minor modernizations --- src/systemctl/systemctl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 14ef29f76e..6b70d80da4 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7425,22 +7425,22 @@ static int halt_now(enum action a) { /* The kernel will automaticall flush ATA disks and suchlike * on reboot(), but the file systems need to be synce'd * explicitly in advance. */ - sync(); + (void) sync(); /* Make sure C-A-D is handled by the kernel from this point * on... */ - reboot(RB_ENABLE_CAD); + (void) reboot(RB_ENABLE_CAD); switch (a) { case ACTION_HALT: log_info("Halting."); - reboot(RB_HALT_SYSTEM); + (void) reboot(RB_HALT_SYSTEM); return -errno; case ACTION_POWEROFF: log_info("Powering off."); - reboot(RB_POWER_OFF); + (void) reboot(RB_POWER_OFF); return -errno; case ACTION_KEXEC: @@ -7449,11 +7449,11 @@ static int halt_now(enum action a) { if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { log_info("Rebooting with argument '%s'.", param); - syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); + (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); } log_info("Rebooting."); - reboot(RB_AUTOBOOT); + (void) reboot(RB_AUTOBOOT); return -errno; } -- cgit v1.2.3-54-g00ecf From 7f96539d45028650f2ba9452095473a9c455d84b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Sep 2015 15:09:10 +0200 Subject: systemctl: when a shutdown is scheduled, always go via logind --- src/systemctl/systemctl.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'src/systemctl') diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6b70d80da4..e0a69867d2 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7524,10 +7524,11 @@ static int halt_main(void) { if (r < 0) return r; + if (arg_when > 0) + return logind_schedule_shutdown(); + if (geteuid() != 0) { - if (arg_when > 0 || - arg_dry || - arg_force > 0) { + if (arg_dry || arg_force > 0) { log_error("Must be root."); return -EPERM; } @@ -7535,25 +7536,19 @@ static int halt_main(void) { /* Try logind if we are a normal user and no special * mode applies. Maybe PolicyKit allows us to shutdown * the machine. */ - if (IN_SET(arg_action, - ACTION_POWEROFF, - ACTION_REBOOT)) { + if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) { r = logind_reboot(arg_action); if (r >= 0) return r; if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS)) - /* requested operation is not supported or already in progress */ + /* requested operation is not + * supported on the local system or + * already in progress */ return r; /* on all other errors, try low-level operation */ } } - if (arg_when > 0) { - r = logind_schedule_shutdown(); - if (r >= 0) - return r; - } - if (!arg_dry && !arg_force) return start_with_fallback(); @@ -7573,7 +7568,6 @@ static int halt_main(void) { return 0; r = halt_now(arg_action); - return log_error_errno(r, "Failed to reboot: %m"); } -- cgit v1.2.3-54-g00ecf