From: Lennart Poettering Date: Tue, 15 Jun 2010 02:24:30 +0000 (+0200) Subject: systemctl: fix race in --block X-Git-Tag: v1~199 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=479ef5d398e4c7467396bdfcdbad3e121150cfd6;p=systemd systemctl: fix race in --block --- diff --git a/src/systemctl.c b/src/systemctl.c index 8a7a2de4..b0fb7b24 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",