From 3d161f991e16369aa59f447eb4cdb90af33261c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 28 Apr 2015 12:33:19 +0200 Subject: run: by default, wait until the transient unit finished start-up Make this blocking behaviour optional with --no-block, similar to systemctl's switch of this name. --- man/systemctl.xml | 4 ++-- man/systemd-run.xml | 12 ++++++++++++ src/run/run.c | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 8c0a01d3e1..4e77af5259 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -316,8 +316,8 @@ Do not synchronously wait for the requested operation to finish. If this is not specified, the job will be verified, enqueued and systemctl will - wait until it is completed. By passing this argument, it is - only verified and enqueued. + wait until the unit's start-up is completed. By passing this + argument, it is only verified and enqueued. diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 629bc4ac08..71b365c8eb 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -294,6 +294,18 @@ set-property command. + + + + + Do not synchronously wait for the requested operation + to finish. If this is not specified, the job will be + verified, enqueued and systemd-run will + wait until the unit's start-up is completed. By passing this + argument, it is only verified and enqueued. + + + diff --git a/src/run/run.c b/src/run/run.c index 85fe29b672..db15ab6219 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -38,6 +38,7 @@ static bool arg_scope = false; static bool arg_remain_after_exit = false; +static bool arg_no_block = false; static const char *arg_unit = NULL; static const char *arg_description = NULL; static const char *arg_slice = NULL; @@ -77,6 +78,7 @@ static void help(void) { " -p --property=NAME=VALUE Set unit property\n" " --description=TEXT Description for unit\n" " --slice=SLICE Run in the specified slice\n" + " --no-block Do not wait until operation finished\n" " -r --remain-after-exit Leave service around until explicitly stopped\n" " --send-sighup Send SIGHUP when terminating\n" " --service-type=TYPE Service type\n" @@ -124,7 +126,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_ON_UNIT_ACTIVE, ARG_ON_UNIT_INACTIVE, ARG_ON_CALENDAR, - ARG_TIMER_PROPERTY + ARG_TIMER_PROPERTY, + ARG_NO_BLOCK, }; static const struct option options[] = { @@ -155,6 +158,7 @@ static int parse_argv(int argc, char *argv[]) { { "on-unit-inactive", required_argument, NULL, ARG_ON_UNIT_INACTIVE }, { "on-calendar", required_argument, NULL, ARG_ON_CALENDAR }, { "timer-property", required_argument, NULL, ARG_TIMER_PROPERTY }, + { "no-block", no_argument, NULL, ARG_NO_BLOCK }, {}, }; @@ -329,6 +333,10 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_NO_BLOCK: + arg_no_block = true; + break; + case '?': return -EINVAL; @@ -651,8 +659,9 @@ static int start_transient_service( sd_bus *bus, char **argv) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *service = NULL, *pty_path = NULL; _cleanup_close_ int master = -1; int r; @@ -673,7 +682,6 @@ static int start_transient_service( } else if (arg_transport == BUS_TRANSPORT_MACHINE) { _cleanup_bus_unref_ sd_bus *system_bus = NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; const char *s; r = sd_bus_open_system(&system_bus); @@ -697,6 +705,8 @@ static int start_transient_service( if (r < 0) return bus_log_parse_error(r); + reply = sd_bus_message_unref(reply); + master = fcntl(master, F_DUPFD_CLOEXEC, 3); if (master < 0) return log_error_errno(errno, "Failed to duplicate master fd: %m"); @@ -711,6 +721,12 @@ static int start_transient_service( return log_error_errno(errno, "Failed to unlock tty: %m"); } + if (!arg_no_block) { + r = bus_wait_for_jobs_new(bus, &w); + if (r < 0) + return log_error_errno(r, "Could not watch jobs: %m"); + } + if (arg_unit) { service = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".service"); if (!service) @@ -751,12 +767,24 @@ static int start_transient_service( if (r < 0) return bus_log_create_error(r); - r = sd_bus_call(bus, m, 0, &error, NULL); + r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to start transient service unit: %s", bus_error_message(&error, -r)); return r; } + if (w) { + const char *object; + + r = sd_bus_message_read(reply, "o", &object); + if (r < 0) + return bus_log_parse_error(r); + + r = bus_wait_for_jobs_one(w, object, arg_quiet); + if (r < 0) + return r; + } + if (master >= 0) { _cleanup_(pty_forward_freep) PTYForward *forward = NULL; _cleanup_event_unref_ sd_event *event = NULL; -- cgit v1.2.3-54-g00ecf