Zbigniew Jędrzejewski-Szmek a48f80
From e083aeafc31469b302d14570b5c5eabfdea49098 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek a48f80
From: Lennart Poettering <lennart@poettering.net>
Zbigniew Jędrzejewski-Szmek a48f80
Date: Tue, 28 Apr 2015 12:21:31 +0200
Zbigniew Jędrzejewski-Szmek a48f80
Subject: [PATCH] run: synchronously wait until the scope unit we create is
Zbigniew Jędrzejewski-Szmek a48f80
 started
Zbigniew Jędrzejewski-Szmek a48f80
Zbigniew Jędrzejewski-Szmek a48f80
Otherwise it might happen that by the time PID 1 adds our process to the
Zbigniew Jędrzejewski-Szmek a48f80
scope unit the process might already have died, if the process is
Zbigniew Jędrzejewski-Szmek a48f80
short-running (such as an invocation to /bin/true).
Zbigniew Jędrzejewski-Szmek a48f80
Zbigniew Jędrzejewski-Szmek a48f80
https://bugs.freedesktop.org/show_bug.cgi?id=86520
Zbigniew Jędrzejewski-Szmek a48f80
(cherry picked from commit de158ed22db60e3a6654557fa4aa72f7248550af)
Zbigniew Jędrzejewski-Szmek a48f80
---
Zbigniew Jędrzejewski-Szmek a48f80
 src/libsystemd/sd-bus/bus-util.c | 10 ++++++++++
Zbigniew Jędrzejewski-Szmek a48f80
 src/libsystemd/sd-bus/bus-util.h |  1 +
Zbigniew Jędrzejewski-Szmek a48f80
 src/run/run.c                    | 42 +++++++++++++++++++++++++++++++++-------
Zbigniew Jędrzejewski-Szmek a48f80
 3 files changed, 46 insertions(+), 7 deletions(-)
Zbigniew Jędrzejewski-Szmek a48f80
Zbigniew Jędrzejewski-Szmek a48f80
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
Zbigniew Jędrzejewski-Szmek a48f80
index 52d4ebe611..427f9a583d 100644
Zbigniew Jędrzejewski-Szmek a48f80
--- a/src/libsystemd/sd-bus/bus-util.c
Zbigniew Jędrzejewski-Szmek a48f80
+++ b/src/libsystemd/sd-bus/bus-util.c
Zbigniew Jędrzejewski-Szmek a48f80
@@ -1785,6 +1785,16 @@ int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
Zbigniew Jędrzejewski-Szmek a48f80
         return set_put_strdup(d->jobs, path);
Zbigniew Jędrzejewski-Szmek a48f80
 }
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
Zbigniew Jędrzejewski-Szmek a48f80
+        int r;
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
+        r = bus_wait_for_jobs_add(d, path);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return log_oom();
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
+        return bus_wait_for_jobs(d, quiet);
Zbigniew Jędrzejewski-Szmek a48f80
+}
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet) {
Zbigniew Jędrzejewski-Szmek a48f80
         const char *type, *path, *source;
Zbigniew Jędrzejewski-Szmek a48f80
         int r;
Zbigniew Jędrzejewski-Szmek a48f80
diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h
Zbigniew Jędrzejewski-Szmek a48f80
index e8a97cef9e..0dc4e699b1 100644
Zbigniew Jędrzejewski-Szmek a48f80
--- a/src/libsystemd/sd-bus/bus-util.h
Zbigniew Jędrzejewski-Szmek a48f80
+++ b/src/libsystemd/sd-bus/bus-util.h
Zbigniew Jędrzejewski-Szmek a48f80
@@ -208,6 +208,7 @@ int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret);
Zbigniew Jędrzejewski-Szmek a48f80
 void bus_wait_for_jobs_free(BusWaitForJobs *d);
Zbigniew Jędrzejewski-Szmek a48f80
 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path);
Zbigniew Jędrzejewski-Szmek a48f80
 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet);
Zbigniew Jędrzejewski-Szmek a48f80
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
 DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForJobs*, bus_wait_for_jobs_free);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
diff --git a/src/run/run.c b/src/run/run.c
Zbigniew Jędrzejewski-Szmek a48f80
index 0661b3bee9..0b03d8e40d 100644
Zbigniew Jędrzejewski-Szmek a48f80
--- a/src/run/run.c
Zbigniew Jędrzejewski-Szmek a48f80
+++ b/src/run/run.c
Zbigniew Jędrzejewski-Szmek a48f80
@@ -807,14 +807,20 @@ static int start_transient_scope(
Zbigniew Jędrzejewski-Szmek a48f80
                 char **argv) {
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
         _cleanup_strv_free_ char **env = NULL, **user_env = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
-        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
         _cleanup_free_ char *scope = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        const char *object = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
         int r;
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         assert(bus);
Zbigniew Jędrzejewski-Szmek a48f80
         assert(argv);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
+        r = bus_wait_for_jobs_new(bus, &w);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return log_oom();
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
         if (arg_unit) {
Zbigniew Jędrzejewski-Szmek a48f80
                 scope = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".scope");
Zbigniew Jędrzejewski-Szmek a48f80
                 if (!scope)
Zbigniew Jędrzejewski-Szmek a48f80
@@ -855,7 +861,7 @@ static int start_transient_scope(
Zbigniew Jędrzejewski-Szmek a48f80
         if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
                 return bus_log_create_error(r);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
-        r = sd_bus_call(bus, m, 0, &error, NULL);
Zbigniew Jędrzejewski-Szmek a48f80
+        r = sd_bus_call(bus, m, 0, &error, &reply);
Zbigniew Jędrzejewski-Szmek a48f80
         if (r < 0) {
Zbigniew Jędrzejewski-Szmek a48f80
                 log_error("Failed to start transient scope unit: %s", bus_error_message(&error, -r));
Zbigniew Jędrzejewski-Szmek a48f80
                 return r;
Zbigniew Jędrzejewski-Szmek a48f80
@@ -915,8 +921,16 @@ static int start_transient_scope(
Zbigniew Jędrzejewski-Szmek a48f80
         if (!env)
Zbigniew Jędrzejewski-Szmek a48f80
                 return log_oom();
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
+        r = sd_bus_message_read(reply, "o", &object);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return bus_log_parse_error(r);
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
+        r = bus_wait_for_jobs_one(w, object, arg_quiet);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return r;
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
         if (!arg_quiet)
Zbigniew Jędrzejewski-Szmek a48f80
-                log_info("Running as unit %s.", scope);
Zbigniew Jędrzejewski-Szmek a48f80
+                log_info("Running scope as unit %s.", scope);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         execvpe(argv[0], argv, env);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
@@ -928,13 +942,19 @@ static int start_transient_timer(
Zbigniew Jędrzejewski-Szmek a48f80
                 char **argv) {
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
Zbigniew Jędrzejewski-Szmek a48f80
-        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
         _cleanup_free_ char *timer = NULL, *service = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
+        const char *object = NULL;
Zbigniew Jędrzejewski-Szmek a48f80
         int r;
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         assert(bus);
Zbigniew Jędrzejewski-Szmek a48f80
         assert(argv);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
+        r = bus_wait_for_jobs_new(bus, &w);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return log_oom();
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
         if (arg_unit) {
Zbigniew Jędrzejewski-Szmek a48f80
                 switch(unit_name_to_type(arg_unit)) {
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
@@ -1035,15 +1055,23 @@ static int start_transient_timer(
Zbigniew Jędrzejewski-Szmek a48f80
         if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
                 return bus_log_create_error(r);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
-        r = sd_bus_call(bus, m, 0, &error, NULL);
Zbigniew Jędrzejewski-Szmek a48f80
+        r = sd_bus_call(bus, m, 0, &error, &reply);
Zbigniew Jędrzejewski-Szmek a48f80
         if (r < 0) {
Zbigniew Jędrzejewski-Szmek a48f80
                 log_error("Failed to start transient timer unit: %s", bus_error_message(&error, -r));
Zbigniew Jędrzejewski-Szmek a48f80
                 return r;
Zbigniew Jędrzejewski-Szmek a48f80
         }
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
-        log_info("Running as unit %s.", timer);
Zbigniew Jędrzejewski-Szmek a48f80
+        r = sd_bus_message_read(reply, "o", &object);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return bus_log_parse_error(r);
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
+        r = bus_wait_for_jobs_one(w, object, arg_quiet);
Zbigniew Jędrzejewski-Szmek a48f80
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek a48f80
+                return r;
Zbigniew Jędrzejewski-Szmek a48f80
+
Zbigniew Jędrzejewski-Szmek a48f80
+        log_info("Running timer as unit %s.", timer);
Zbigniew Jędrzejewski-Szmek a48f80
         if (argv[0])
Zbigniew Jędrzejewski-Szmek a48f80
-                log_info("Will run as unit %s.", service);
Zbigniew Jędrzejewski-Szmek a48f80
+                log_info("Will run service as unit %s.", service);
Zbigniew Jędrzejewski-Szmek a48f80
 
Zbigniew Jędrzejewski-Szmek a48f80
         return 0;
Zbigniew Jędrzejewski-Szmek a48f80
 }