core/varlink-manager: report individual job enqueue result if client sets 'more'

One nice property varlink has is that we can nicely report result
of individual operations on each unit, through the 'more' mechanism.
Hence do so for the EnqueueMarkedJobs() method.

Also, apply 502d6f4bc9 for varlink
method too.

While at it, use lowerCamelCase for method reply fields,
as requested in
https://github.com/systemd/systemd/pull/40365#discussion_r2702344239.
This commit is contained in:
Mike Yuan
2026-01-24 00:48:03 +01:00
parent 927b861add
commit f7823fdae0
4 changed files with 50 additions and 35 deletions
+33 -19
View File
@@ -2,12 +2,14 @@
#include <sys/prctl.h>
#include "sd-bus.h"
#include "sd-varlink.h"
#include "alloc-util.h"
#include "architecture.h"
#include "bitfield.h"
#include "build.h"
#include "bus-error.h"
#include "bus-polkit.h"
#include "confidential-virt.h"
#include "errno-util.h"
@@ -330,11 +332,12 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS));
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL, *reply = NULL;
Unit *u;
char *k;
int ret = 0;
HASHMAP_FOREACH_KEY(u, k, manager->units) {
_cleanup_(sd_bus_error_free) sd_bus_error bus_error = SD_BUS_ERROR_NULL;
const char *error_id = NULL;
uint32_t job_id = 0; /* silence 'maybe-uninitialized' compiler warning */
/* ignore aliases */
@@ -345,34 +348,45 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
continue;
r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(JOB_TRY_RESTART));
if (r >= 0)
if (r < 0)
error_id = SD_VARLINK_ERROR_PERMISSION_DENIED;
else
r = varlink_unit_queue_job_one(
link,
u,
JOB_TRY_RESTART,
JOB_FAIL,
/* reload_if_possible= */ !BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART),
&job_id);
&job_id,
&bus_error);
if (ERRNO_IS_NEG_RESOURCE(r))
return r;
RET_GATHER(ret, r);
if (r >= 0) {
r = sd_json_variant_append_arrayb(&array, SD_JSON_BUILD_UNSIGNED(job_id));
if (r < 0)
return r;
}
if (r < 0)
RET_GATHER(ret, log_unit_warning_errno(u, r, "Failed to enqueue marked job: %s",
bus_error_message(&bus_error, r)));
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
continue;
if (r < 0) {
if (!error_id)
error_id = varlink_error_id_from_bus_error(&bus_error);
const char *error_msg = bus_error.message ?: error_id ? NULL : STRERROR(r);
r = sd_varlink_notifybo(link,
SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
JSON_BUILD_PAIR_STRING_NON_EMPTY("error", error_id),
JSON_BUILD_PAIR_STRING_NON_EMPTY("errorMessage", error_msg));
} else
r = sd_varlink_notifybo(link,
SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
SD_JSON_BUILD_PAIR_INTEGER("jobID", job_id));
if (r < 0)
return r;
}
if (ret < 0)
return ret;
/* Return parameter is not nullable, build empty array if there's nothing to return */
if (array)
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_VARIANT("JobIDs", array));
else
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_EMPTY_ARRAY("JobIDs"));
if (r < 0)
return r;
return sd_varlink_reply(link, reply);
return sd_varlink_reply(link, NULL);
}
+5 -11
View File
@@ -507,29 +507,23 @@ int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varli
}
int varlink_unit_queue_job_one(
sd_varlink *link,
Unit *u,
JobType type,
JobMode mode,
bool reload_if_possible,
uint32_t *ret_job_id) {
uint32_t *ret_job_id,
sd_bus_error *reterr_bus_error) {
_cleanup_(sd_bus_error_free) sd_bus_error bus_error = SD_BUS_ERROR_NULL;
int r;
assert(u);
r = unit_queue_job_check_and_mangle_type(u, &type, reload_if_possible, &bus_error);
if (r < 0) {
const char *error_id = varlink_error_id_from_bus_error(&bus_error);
if (error_id)
return sd_varlink_error(link, error_id);
r = unit_queue_job_check_and_mangle_type(u, &type, reload_if_possible, reterr_bus_error);
if (r < 0)
return r;
}
Job *j;
r = manager_add_job(u->manager, type, u, mode, /* reterr_error= */ NULL, &j);
r = manager_add_job(u->manager, type, u, mode, reterr_bus_error, &j);
if (r < 0)
return r;
+2 -2
View File
@@ -10,11 +10,11 @@
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int varlink_unit_queue_job_one(
sd_varlink *link,
Unit *u,
JobType type,
JobMode mode,
bool reload_if_possible,
uint32_t *ret_job_id);
uint32_t *ret_job_id,
sd_bus_error *reterr_bus_error);
int varlink_error_no_such_unit(sd_varlink *v, const char *name);
+10 -3
View File
@@ -181,10 +181,17 @@ static SD_VARLINK_DEFINE_METHOD(
static SD_VARLINK_DEFINE_METHOD(
Reload);
static SD_VARLINK_DEFINE_METHOD(
static SD_VARLINK_DEFINE_METHOD_FULL(
EnqueueMarkedJobs,
SD_VARLINK_FIELD_COMMENT("IDs of enqueued jobs"),
SD_VARLINK_DEFINE_OUTPUT(JobIDs, SD_VARLINK_INT, SD_VARLINK_ARRAY));
SD_VARLINK_SUPPORTS_MORE,
SD_VARLINK_FIELD_COMMENT("Enqueued unit ID"),
SD_VARLINK_DEFINE_OUTPUT(unitID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("ID of enqueued job (if successful)"),
SD_VARLINK_DEFINE_OUTPUT(jobID, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Varlink error ID (on failure)"),
SD_VARLINK_DEFINE_OUTPUT(error, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Job enqueue error message (on failure)"),
SD_VARLINK_DEFINE_OUTPUT(errorMessage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(RateLimitReached);