You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.5 KiB
154 lines
5.5 KiB
From 5532bedf8ef456f02fdec62d46bc1be65cdfde30 Mon Sep 17 00:00:00 2001 |
|
From: Lennart Poettering <lennart@poettering.net> |
|
Date: Tue, 28 Apr 2015 12:21:31 +0200 |
|
Subject: [PATCH] run: synchronously wait until the scope unit we create is |
|
started |
|
|
|
Otherwise it might happen that by the time PID 1 adds our process to the |
|
scope unit the process might already have died, if the process is |
|
short-running (such as an invocation to /bin/true). |
|
|
|
https://bugs.freedesktop.org/show_bug.cgi?id=86520 |
|
|
|
Cherry-picked from: de158ed22db60e3a6654557fa4aa72f7248550af |
|
Resolves: #1272368 |
|
--- |
|
src/libsystemd/sd-bus/bus-util.c | 10 ++++++++++ |
|
src/libsystemd/sd-bus/bus-util.h | 1 + |
|
src/run/run.c | 42 +++++++++++++++++++++++++++++++++------- |
|
3 files changed, 46 insertions(+), 7 deletions(-) |
|
|
|
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c |
|
index e48abf55a..6d5615082 100644 |
|
--- a/src/libsystemd/sd-bus/bus-util.c |
|
+++ b/src/libsystemd/sd-bus/bus-util.c |
|
@@ -1854,6 +1854,16 @@ int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) { |
|
return set_put_strdup(d->jobs, path); |
|
} |
|
|
|
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) { |
|
+ int r; |
|
+ |
|
+ r = bus_wait_for_jobs_add(d, path); |
|
+ if (r < 0) |
|
+ return log_oom(); |
|
+ |
|
+ return bus_wait_for_jobs(d, quiet); |
|
+} |
|
+ |
|
int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) { |
|
const char *type, *path, *source; |
|
int r; |
|
diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h |
|
index 21db98228..8c8846c6e 100644 |
|
--- a/src/libsystemd/sd-bus/bus-util.h |
|
+++ b/src/libsystemd/sd-bus/bus-util.h |
|
@@ -209,6 +209,7 @@ int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret); |
|
void bus_wait_for_jobs_free(BusWaitForJobs *d); |
|
int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path); |
|
int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet); |
|
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet); |
|
|
|
DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForJobs*, bus_wait_for_jobs_free); |
|
|
|
diff --git a/src/run/run.c b/src/run/run.c |
|
index 0e5bde23d..dd1338f3b 100644 |
|
--- a/src/run/run.c |
|
+++ b/src/run/run.c |
|
@@ -806,14 +806,20 @@ static int start_transient_scope( |
|
char **argv) { |
|
|
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; |
|
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; |
|
+ _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; |
|
_cleanup_strv_free_ char **env = NULL, **user_env = NULL; |
|
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL; |
|
_cleanup_free_ char *scope = NULL; |
|
+ const char *object = NULL; |
|
int r; |
|
|
|
assert(bus); |
|
assert(argv); |
|
|
|
+ r = bus_wait_for_jobs_new(bus, &w); |
|
+ if (r < 0) |
|
+ return log_oom(); |
|
+ |
|
if (arg_unit) { |
|
scope = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".scope"); |
|
if (!scope) |
|
@@ -854,7 +860,7 @@ static int start_transient_scope( |
|
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 scope unit: %s", bus_error_message(&error, -r)); |
|
return r; |
|
@@ -914,8 +920,16 @@ static int start_transient_scope( |
|
if (!env) |
|
return log_oom(); |
|
|
|
+ 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 (!arg_quiet) |
|
- log_info("Running as unit %s.", scope); |
|
+ log_info("Running scope as unit %s.", scope); |
|
|
|
execvpe(argv[0], argv, env); |
|
|
|
@@ -927,13 +941,19 @@ static int start_transient_timer( |
|
char **argv) { |
|
|
|
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; |
|
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL; |
|
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; |
|
+ _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; |
|
_cleanup_free_ char *timer = NULL, *service = NULL; |
|
+ const char *object = NULL; |
|
int r; |
|
|
|
assert(bus); |
|
assert(argv); |
|
|
|
+ r = bus_wait_for_jobs_new(bus, &w); |
|
+ if (r < 0) |
|
+ return log_oom(); |
|
+ |
|
if (arg_unit) { |
|
switch(unit_name_to_type(arg_unit)) { |
|
|
|
@@ -1034,15 +1054,23 @@ static int start_transient_timer( |
|
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 timer unit: %s", bus_error_message(&error, -r)); |
|
return r; |
|
} |
|
|
|
- log_info("Running as unit %s.", timer); |
|
+ 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; |
|
+ |
|
+ log_info("Running timer as unit %s.", timer); |
|
if (argv[0]) |
|
- log_info("Will run as unit %s.", service); |
|
+ log_info("Will run service as unit %s.", service); |
|
|
|
return 0; |
|
}
|
|
|