mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
systemctl-wait: do not fail for non-existent unit as non-root user
Although the man page says
> A unit that does not exist is treated like a unit that terminated
> successfully, and a message about this is shown.
systemctl wait fails as follows when invoked by a non-root user:
```
$ systemctl wait nonexistent.service
Unit nonexistent.service has been removed while waiting for it.
Failed to wait for unit nonexistent.service to terminate.
$ echo $?
1
```
This makes the unit be treated as non-existent when the initial
GetAll() call returns LoadState=not-found. With this change,
```
$ systemctl wait nonexistent.service
Unit nonexistent.service does not exist, treating as terminated.
$ echo $?
0
```
Follow-up for 0e51517319.
This commit is contained in:
1 parent
30bbc1a5a5
commit
ac08033068
1 file changed
+26
@@ -455,6 +455,10 @@ static int wait_for_item_parse_properties(WaitForItem *item, sd_bus_message *m)
|
||||
assert(item);
|
||||
assert(m);
|
||||
|
||||
/* LoadState is a constant property, hence it is only contained in the reply to GetAll(), but never in
|
||||
* PropertiesChanged signals. */
|
||||
bool had_load_state = item->load_state;
|
||||
|
||||
r = bus_message_map_all_properties(m, map, BUS_MAP_STRDUP, /* reterr_error= */ NULL, item);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -481,6 +485,28 @@ static int wait_for_item_parse_properties(WaitForItem *item, sd_bus_message *m)
|
||||
item->removed = false;
|
||||
}
|
||||
|
||||
if (!had_load_state && streq_ptr(item->load_state, "not-found")) {
|
||||
/* The unit did not exist from the beginning. Treat it as terminated successfully. */
|
||||
log_debug("Unit %s is not loaded.", item->name);
|
||||
|
||||
/* No result is collected for a unit that does not exist. Hence, create a fake result that
|
||||
* only contains the load state, and pass it to the callback, so that the caller can tell
|
||||
* that the unit does not exist. */
|
||||
if (FLAGS_SET(item->flags, BUS_WAIT_COLLECT_RESULT)) {
|
||||
r = free_and_strdup(&item->result.load_state, item->load_state);
|
||||
if (r < 0) {
|
||||
log_oom_debug();
|
||||
wait_for_item_fail(item);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
BusWaitForUnits *d = ASSERT_PTR(item->parent);
|
||||
call_unit_callback_and_wait(d, item, /* good= */ true);
|
||||
bus_wait_for_units_check_ready(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wait_for_item_check_ready(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user