diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-06-15 04:24:30 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-06-15 04:24:30 +0200 |
commit | 479ef5d398e4c7467396bdfcdbad3e121150cfd6 (patch) | |
tree | a3322587747388b591111ed8a2a081ca07ea310c /src | |
parent | fd0d7f7a6ec746e8aa811f661c051cdf8f3a4c8e (diff) |
systemctl: fix race in --block
Diffstat (limited to 'src')
-rw-r--r-- | src/systemctl.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/src/systemctl.c b/src/systemctl.c index 8a7a2de403..b0fb7b24ae 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -447,13 +447,12 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static int wait_for_jobs(DBusConnection *bus, Set *s) { +static int enable_wait_for_jobs(DBusConnection *bus) { DBusError error; DBusMessage *m = NULL, *reply = NULL; int r; assert(bus); - assert(s); dbus_error_init(&error); @@ -471,12 +470,6 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { goto finish; } - if (!dbus_connection_add_filter(bus, wait_filter, s, NULL)) { - log_error("Failed to add filter."); - r = -ENOMEM; - goto finish; - } - if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -493,14 +486,10 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { goto finish; } - while (!set_isempty(s) && - dbus_connection_read_write_dispatch(bus, -1)) - ; - r = 0; finish: - /* This is slightly dirty, since we don't undo the filter or the matches. */ + /* This is slightly dirty, since we don't undo the match registrations. */ if (m) dbus_message_unref(m); @@ -513,6 +502,30 @@ finish: return r; } +static int wait_for_jobs(DBusConnection *bus, Set *s) { + int r; + + assert(bus); + assert(s); + + if (!dbus_connection_add_filter(bus, wait_filter, s, NULL)) { + log_error("Failed to add filter."); + r = -ENOMEM; + goto finish; + } + + while (!set_isempty(s) && + dbus_connection_read_write_dispatch(bus, -1)) + ; + + r = 0; + +finish: + /* This is slightly dirty, since we don't undo the filter registration. */ + + return r; +} + static int start_unit(DBusConnection *bus, char **args, unsigned n) { DBusMessage *m = NULL, *reply = NULL; DBusError error; @@ -532,6 +545,13 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) { mode = arg_replace ? "replace" : "fail"; + if (arg_block) { + if ((r = enable_wait_for_jobs(bus)) < 0) { + log_error("Could not watch jobs: %s", strerror(-r)); + goto finish; + } + } + for (i = 1; i < n; i++) { if (!(m = dbus_message_new_method_call( @@ -628,6 +648,13 @@ static int isolate_unit(DBusConnection *bus, char **args, unsigned n) { dbus_error_init(&error); + if (arg_block) { + if ((r = enable_wait_for_jobs(bus)) < 0) { + log_error("Could not watch jobs: %s", strerror(-r)); + goto finish; + } + } + if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", |