dbus: report action and condition failures instead of empty success

Service1 Start/Stop/Restart discarded the action return value, their
Manager1 twins map it to org.finit.Error.Failed.  Cond1 Set/Clear
replied success even when the condition symlink operation failed,
where legacy initctl exits 73.  Verify the resulting condition state
with cond_get() rather than the noupdate return values, which report
no-change, not failure, and would reject an idempotent re-set.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-08-16 22:03:38 +02:00
parent 2af83ea632
commit 8b61aaea1a
+16 -3
View File
@@ -665,7 +665,11 @@ static int service_action_method(link_call_t *call, void *userdata,
"org.finit.Error.NoSuchService",
"Service object no longer valid");
action(svc, NULL);
if (action(svc, NULL))
return link_call_reply_error(call,
"org.finit.Error.Failed",
"failed on service");
(void)link_call_reply(call);
return 0;
}
@@ -1148,7 +1152,7 @@ static int cond1_set_or_clear(link_call_t *call, int do_set)
"org.freedesktop.DBus.Error.InvalidArgs",
"Set/Clear is restricted to usr/* conditions");
if (do_set)
if (do_set) {
/* cond_set_oneshot, not cond_set: a user-asserted condition
* is a symlink to _PATH_RECONF, so it tracks the reconf
* generation automatically and stays "on" across reloads
@@ -1157,8 +1161,17 @@ static int cond1_set_or_clear(link_call_t *call, int do_set)
* semantics for user conditions, and what initctl cond set
* has done forever via the filesystem path. */
cond_set_oneshot(full);
else
if (cond_get(full) != COND_ON)
return link_call_reply_error(call,
"org.finit.Error.Failed",
"failed asserting condition");
} else {
cond_clear(full);
if (cond_get(full) != COND_OFF)
return link_call_reply_error(call,
"org.finit.Error.Failed",
"failed clearing condition");
}
(void)link_call_reply(call);
return 0;