summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/dbus.c20
-rw-r--r--src/core/unit.c2
-rw-r--r--src/shared/bus-wait-for-units.c72
-rw-r--r--src/shared/bus-wait-for-units.h15
-rw-r--r--src/systemctl/systemctl-start-unit.c32
-rw-r--r--src/systemctl/systemctl-util.c4
6 files changed, 61 insertions, 84 deletions
diff --git a/src/core/dbus.c b/src/core/dbus.c
index a336b04daf..1c6f6fc8b3 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1113,31 +1113,29 @@ int bus_foreach_bus(
int (*send_message)(sd_bus *bus, void *userdata),
void *userdata) {
- sd_bus *b;
- int r, ret = 0;
+ int r = 0;
+
+ assert(m);
+ assert(send_message);
/* Send to all direct buses, unconditionally */
+ sd_bus *b;
SET_FOREACH(b, m->private_buses) {
/* Don't bother with enqueuing these messages to clients that haven't started yet */
if (sd_bus_is_ready(b) <= 0)
continue;
- r = send_message(b, userdata);
- if (r < 0)
- ret = r;
+ RET_GATHER(r, send_message(b, userdata));
}
/* Send to API bus, but only if somebody is subscribed */
if (m->api_bus &&
(sd_bus_track_count(m->subscribed) > 0 ||
- sd_bus_track_count(subscribed2) > 0)) {
- r = send_message(m->api_bus, userdata);
- if (r < 0)
- ret = r;
- }
+ sd_bus_track_count(subscribed2) > 0))
+ RET_GATHER(r, send_message(m->api_bus, userdata));
- return ret;
+ return r;
}
void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
diff --git a/src/core/unit.c b/src/core/unit.c
index f26c1c248e..15285a3ac4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -467,7 +467,7 @@ bool unit_may_gc(Unit *u) {
break;
case COLLECT_INACTIVE_OR_FAILED:
- if (!IN_SET(state, UNIT_INACTIVE, UNIT_FAILED))
+ if (!UNIT_IS_INACTIVE_OR_FAILED(state))
return false;
break;
diff --git a/src/shared/bus-wait-for-units.c b/src/shared/bus-wait-for-units.c
index 49963ffe34..6ccf822064 100644
--- a/src/shared/bus-wait-for-units.c
+++ b/src/shared/bus-wait-for-units.c
@@ -18,7 +18,7 @@ typedef struct WaitForItem {
sd_bus_slot *slot_get_all;
sd_bus_slot *slot_properties_changed;
- bus_wait_for_units_unit_callback unit_callback;
+ bus_wait_for_units_unit_callback_t unit_callback;
void *userdata;
char *active_state;
@@ -32,11 +32,6 @@ typedef struct BusWaitForUnits {
Hashmap *items;
- bus_wait_for_units_ready_callback ready_callback;
- void *userdata;
-
- WaitForItem *current;
-
BusWaitForUnitsState state;
bool has_failed:1;
} BusWaitForUnits;
@@ -64,9 +59,6 @@ static WaitForItem *wait_for_item_free(WaitForItem *item) {
}
assert_se(hashmap_remove_value(item->parent->items, item->bus_path, item));
-
- if (item->parent->current == item)
- item->parent->current = NULL;
}
sd_bus_slot_unref(item->slot_properties_changed);
@@ -82,8 +74,6 @@ static WaitForItem *wait_for_item_free(WaitForItem *item) {
DEFINE_TRIVIAL_CLEANUP_FUNC(WaitForItem*, wait_for_item_free);
static void call_unit_callback_and_wait(BusWaitForUnits *d, WaitForItem *item, bool good) {
- d->current = item;
-
if (item->unit_callback)
item->unit_callback(d, item->bus_path, good, item->userdata);
@@ -112,11 +102,7 @@ static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *e
log_warning("D-Bus connection terminated while waiting for unit.");
bus_wait_for_units_clear(d);
-
- if (d->ready_callback)
- d->ready_callback(d, BUS_WAIT_FAILURE, d->userdata);
- else /* If no ready callback is specified close the connection so that the event loop exits */
- sd_bus_close(sd_bus_message_get_bus(m));
+ sd_bus_close(sd_bus_message_get_bus(m));
return 0;
}
@@ -172,13 +158,6 @@ static bool bus_wait_for_units_is_ready(BusWaitForUnits *d) {
return hashmap_isempty(d->items);
}
-void bus_wait_for_units_set_ready_callback(BusWaitForUnits *d, bus_wait_for_units_ready_callback callback, void *userdata) {
- assert(d);
-
- d->ready_callback = callback;
- d->userdata = userdata;
-}
-
static void bus_wait_for_units_check_ready(BusWaitForUnits *d) {
assert(d);
@@ -186,9 +165,6 @@ static void bus_wait_for_units_check_ready(BusWaitForUnits *d) {
return;
d->state = d->has_failed ? BUS_WAIT_FAILURE : BUS_WAIT_SUCCESS;
-
- if (d->ready_callback)
- d->ready_callback(d, d->state, d->userdata);
}
static void wait_for_item_check_ready(WaitForItem *item) {
@@ -221,32 +197,26 @@ static void wait_for_item_check_ready(WaitForItem *item) {
bus_wait_for_units_check_ready(d);
}
-static int property_map_job(
+static int property_map_job_id(
sd_bus *bus,
const char *member,
sd_bus_message *m,
sd_bus_error *error,
void *userdata) {
- WaitForItem *item = ASSERT_PTR(userdata);
- const char *path;
- uint32_t id;
- int r;
+ uint32_t *job_id = ASSERT_PTR(userdata);
- r = sd_bus_message_read(m, "(uo)", &id, &path);
- if (r < 0)
- return r;
+ assert(m);
- item->job_id = id;
- return 0;
+ return sd_bus_message_read(m, "(uo)", job_id, /* path = */ NULL);
}
static int wait_for_item_parse_properties(WaitForItem *item, sd_bus_message *m) {
static const struct bus_properties_map map[] = {
- { "ActiveState", "s", NULL, offsetof(WaitForItem, active_state) },
- { "Job", "(uo)", property_map_job, 0 },
- { "CleanResult", "s", NULL, offsetof(WaitForItem, clean_result) },
+ { "ActiveState", "s", NULL, offsetof(WaitForItem, active_state) },
+ { "Job", "(uo)", property_map_job_id, offsetof(WaitForItem, job_id) },
+ { "CleanResult", "s", NULL, offsetof(WaitForItem, clean_result) },
{}
};
@@ -315,20 +285,23 @@ int bus_wait_for_units_add_unit(
BusWaitForUnits *d,
const char *unit,
BusWaitForUnitsFlags flags,
- bus_wait_for_units_unit_callback callback,
+ bus_wait_for_units_unit_callback_t callback,
void *userdata) {
_cleanup_(wait_for_item_freep) WaitForItem *item = NULL;
+ _cleanup_free_ char *bus_path = NULL;
int r;
assert(d);
assert(unit);
+ assert((flags & _BUS_WAIT_FOR_TARGET) != 0);
- assert(flags != 0);
+ bus_path = unit_dbus_path_from_name(unit);
+ if (!bus_path)
+ return -ENOMEM;
- r = hashmap_ensure_allocated(&d->items, &string_hash_ops);
- if (r < 0)
- return r;
+ if (hashmap_contains(d->items, bus_path))
+ return 0;
item = new(WaitForItem, 1);
if (!item)
@@ -336,15 +309,12 @@ int bus_wait_for_units_add_unit(
*item = (WaitForItem) {
.flags = flags,
- .bus_path = unit_dbus_path_from_name(unit),
+ .bus_path = TAKE_PTR(bus_path),
.unit_callback = callback,
.userdata = userdata,
.job_id = UINT32_MAX,
};
- if (!item->bus_path)
- return -ENOMEM;
-
if (!FLAGS_SET(item->flags, BUS_WAIT_REFFED)) {
r = sd_bus_call_method_async(
d->bus,
@@ -388,14 +358,16 @@ int bus_wait_for_units_add_unit(
if (r < 0)
return log_debug_errno(r, "Failed to request properties of unit %s: %m", unit);
- r = hashmap_put(d->items, item->bus_path, item);
+ r = hashmap_ensure_put(&d->items, &string_hash_ops, item->bus_path, item);
if (r < 0)
return r;
+ assert(r > 0);
d->state = BUS_WAIT_RUNNING;
item->parent = d;
TAKE_PTR(item);
- return 0;
+
+ return 1;
}
int bus_wait_for_units_run(BusWaitForUnits *d) {
diff --git a/src/shared/bus-wait-for-units.h b/src/shared/bus-wait-for-units.h
index c87eabcbbc..09c4f18906 100644
--- a/src/shared/bus-wait-for-units.h
+++ b/src/shared/bus-wait-for-units.h
@@ -19,17 +19,22 @@ typedef enum BusWaitForUnitsFlags {
BUS_WAIT_FOR_INACTIVE = 1 << 1, /* Wait until the unit is back in inactive or dead state */
BUS_WAIT_NO_JOB = 1 << 2, /* Wait until there's no more job pending */
BUS_WAIT_REFFED = 1 << 3, /* The unit is already reffed with RefUnit() */
+ _BUS_WAIT_FOR_TARGET = BUS_WAIT_FOR_MAINTENANCE_END|BUS_WAIT_FOR_INACTIVE|BUS_WAIT_NO_JOB,
} BusWaitForUnitsFlags;
-typedef void (*bus_wait_for_units_ready_callback)(BusWaitForUnits *d, BusWaitForUnitsState state, void *userdata);
-typedef void (*bus_wait_for_units_unit_callback)(BusWaitForUnits *d, const char *unit_path, bool good, void *userdata);
+typedef void (*bus_wait_for_units_unit_callback_t)(BusWaitForUnits *d, const char *unit_path, bool good, void *userdata);
int bus_wait_for_units_new(sd_bus *bus, BusWaitForUnits **ret);
BusWaitForUnits* bus_wait_for_units_free(BusWaitForUnits *d);
DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForUnits*, bus_wait_for_units_free);
-BusWaitForUnitsState bus_wait_for_units_state(BusWaitForUnits *d);
-void bus_wait_for_units_set_ready_callback(BusWaitForUnits *d, bus_wait_for_units_ready_callback callback, void *userdata);
-int bus_wait_for_units_add_unit(BusWaitForUnits *d, const char *unit, BusWaitForUnitsFlags flags, bus_wait_for_units_unit_callback callback, void *userdata);
+int bus_wait_for_units_add_unit(
+ BusWaitForUnits *d,
+ const char *unit,
+ BusWaitForUnitsFlags flags,
+ bus_wait_for_units_unit_callback_t callback,
+ void *userdata);
+
int bus_wait_for_units_run(BusWaitForUnits *d);
+BusWaitForUnitsState bus_wait_for_units_state(BusWaitForUnits *d);
diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c
index de8873caaf..8068d77d1c 100644
--- a/src/systemctl/systemctl-start-unit.c
+++ b/src/systemctl/systemctl-start-unit.c
@@ -35,20 +35,24 @@ static const struct {
{ "force-reload", "ReloadOrTryRestartUnit", "reload-or-try-restart" }, /* legacy alias */
};
-static const char *verb_to_method(const char *verb) {
- for (size_t i = 0; i < ELEMENTSOF(unit_actions); i++)
- if (streq_ptr(unit_actions[i].verb, verb))
- return unit_actions[i].method;
+static const char* verb_to_method(const char *verb) {
+ assert(verb);
- return "StartUnit";
+ FOREACH_ELEMENT(i, unit_actions)
+ if (streq(i->verb, verb))
+ return i->method;
+
+ return "StartUnit";
}
-static const char *verb_to_job_type(const char *verb) {
- for (size_t i = 0; i < ELEMENTSOF(unit_actions); i++)
- if (streq_ptr(unit_actions[i].verb, verb))
- return unit_actions[i].job_type;
+static const char* verb_to_job_type(const char *verb) {
+ assert(verb);
+
+ FOREACH_ELEMENT(i, unit_actions)
+ if (streq(i->verb, verb))
+ return i->job_type;
- return "start";
+ return "start";
}
static int start_unit_one(
@@ -240,6 +244,8 @@ const struct action_metadata action_table[_ACTION_MAX] = {
};
enum action verb_to_action(const char *verb) {
+ assert(verb);
+
for (enum action i = 0; i < _ACTION_MAX; i++)
if (streq_ptr(action_table[i].verb, verb))
return i;
@@ -375,10 +381,6 @@ int verb_start(int argc, char *argv[], void *userdata) {
}
if (arg_wait) {
- r = bus_call_method_async(bus, NULL, bus_systemd_mgr, "Subscribe", NULL, NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to enable subscription: %m");
-
r = bus_wait_for_units_new(bus, &wu);
if (r < 0)
return log_error_errno(r, "Failed to allocate unit watch context: %m");
@@ -402,7 +404,7 @@ int verb_start(int argc, char *argv[], void *userdata) {
}
if (!arg_no_block) {
- const char* extra_args[4];
+ const char *extra_args[4];
WaitJobsFlags flags = 0;
SET_FLAG(flags, BUS_WAIT_JOBS_LOG_ERROR, !arg_quiet);
diff --git a/src/systemctl/systemctl-util.c b/src/systemctl/systemctl-util.c
index 75c6c547f7..2482b7ccb2 100644
--- a/src/systemctl/systemctl-util.c
+++ b/src/systemctl/systemctl-util.c
@@ -64,8 +64,8 @@ int acquire_bus(BusFocus focus, sd_bus **ret) {
}
void release_busses(void) {
- for (BusFocus w = 0; w < _BUS_FOCUS_MAX; w++)
- buses[w] = sd_bus_flush_close_unref(buses[w]);
+ FOREACH_ARRAY(w, buses, _BUS_FOCUS_MAX)
+ *w = sd_bus_flush_close_unref(*w);
}
void ask_password_agent_open_maybe(void) {