From 59203dca3af581be32f383263e2a3e4bc406c2e4 Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Thu, 14 May 2026 09:41:09 -0700 Subject: [PATCH 1/4] core: move service_context_build_json() to varlink-service.c Move the existing (partial) service context builder from varlink-unit.c into its own varlink-service.c file, following the pattern established by other unit type context builders (varlink-path.c, varlink-scope.c, etc.). No functional change. --- src/core/meson.build | 1 + src/core/varlink-service.c | 22 ++++++++++++++++++++++ src/core/varlink-service.h | 6 ++++++ src/core/varlink-unit.c | 15 +-------------- 4 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 src/core/varlink-service.c create mode 100644 src/core/varlink-service.h diff --git a/src/core/meson.build b/src/core/meson.build index 3af15b948f..98cf02aef8 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -76,6 +76,7 @@ libcore_sources = files( 'varlink-mount.c', 'varlink-path.c', 'varlink-scope.c', + 'varlink-service.c', 'varlink-socket.c', 'varlink-swap.c', 'varlink-timer.c', diff --git a/src/core/varlink-service.c b/src/core/varlink-service.c new file mode 100644 index 0000000000..8d9ed6e91d --- /dev/null +++ b/src/core/varlink-service.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "sd-json.h" + +#include "json-util.h" +#include "service.h" +#include "varlink-common.h" +#include "varlink-service.h" + +/* TODO: This covers only a small subset of a service object's properties. Extend to make more available to + * consumers like Unit.StartTransient */ +int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Unit *u = ASSERT_PTR(userdata); + Service *s = ASSERT_PTR(SERVICE(u)); + assert(ret); + + return sd_json_buildo( + ret, + JSON_BUILD_PAIR_ENUM("Type", service_type_to_string(s->type)), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStart", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_START]), + SD_JSON_BUILD_PAIR_BOOLEAN("RemainAfterExit", s->remain_after_exit)); +} diff --git a/src/core/varlink-service.h b/src/core/varlink-service.h new file mode 100644 index 0000000000..07ed1b9d1b --- /dev/null +++ b/src/core/varlink-service.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "core-forward.h" + +int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata); diff --git a/src/core/varlink-unit.c b/src/core/varlink-unit.c index f7ef750649..368e39a63e 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -31,6 +31,7 @@ #include "varlink-mount.h" #include "varlink-path.h" #include "varlink-scope.h" +#include "varlink-service.h" #include "varlink-socket.h" #include "varlink-swap.h" #include "varlink-timer.h" @@ -119,20 +120,6 @@ static int unit_conditions_build_json(sd_json_variant **ret, const char *name, v return 0; } -/* TODO: This covers only a small subset of a service object's properties. Extend to make more available to - * consumers like Unit.StartTransient */ -static int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { - Unit *u = ASSERT_PTR(userdata); - Service *s = ASSERT_PTR(SERVICE(u)); - assert(ret); - - return sd_json_buildo( - ret, - JSON_BUILD_PAIR_ENUM("Type", service_type_to_string(s->type)), - JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStart", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_START]), - SD_JSON_BUILD_PAIR_BOOLEAN("RemainAfterExit", s->remain_after_exit)); -} - static int unit_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { Unit *u = ASSERT_PTR(userdata); From 5305da009aa9e79ca309b16bffaf3898a3fe57e8 Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Thu, 14 May 2026 09:41:24 -0700 Subject: [PATCH 2/4] shared: add exec_command_status_build_json() and ExecCommandStatus varlink type to common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add exec_command_status_build_json() and exec_command_status_list_build_json() to varlink-common, alongside exec_command_build_json() and exec_command_list_build_json(). The status list function is the runtime counterpart of the command list function — the two arrays are positionally aligned so index N in the status array corresponds to index N in the command array. Commands that have not yet run produce null entries to preserve alignment. Add the ExecCommandStatus varlink struct type to varlink-idl-common next to ExecCommand. It contains PID, timestamps, and mutually exclusive ExitStatus (int, for normal exit) / ExitSignal (string, for signal kill). --- src/core/varlink-common.c | 59 +++++++++++++++++++++++++++++++++ src/core/varlink-common.h | 2 ++ src/shared/varlink-idl-common.c | 15 +++++++++ src/shared/varlink-idl-common.h | 1 + 4 files changed, 77 insertions(+) diff --git a/src/core/varlink-common.c b/src/core/varlink-common.c index f5745e12e8..bdbecd4551 100644 --- a/src/core/varlink-common.c +++ b/src/core/varlink-common.c @@ -7,6 +7,8 @@ #include "cpu-set-util.h" #include "execute.h" #include "json-util.h" +#include "pidref.h" +#include "process-util.h" #include "rlimit-util.h" #include "varlink-common.h" #include "varlink-unit.h" @@ -159,3 +161,60 @@ int exec_command_list_build_json(sd_json_variant **ret, const char *name, void * *ret = TAKE_PTR(v); return 0; } + +int exec_command_status_build_json(sd_json_variant **ret, const char *name, void *userdata) { + ExecStatus *status = ASSERT_PTR(userdata); + + assert(ret); + + if (!pid_is_valid(status->pid)) { + *ret = NULL; + return 0; + } + + return sd_json_buildo( + ret, + /* TODO: replace with a real PidRef once ExecStatus carries one */ + SD_JSON_BUILD_PAIR("PID", JSON_BUILD_PIDREF(&PIDREF_MAKE_FROM_PID(status->pid))), + JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("StartTimestamp", &status->start_timestamp), + JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ExitTimestamp", &status->exit_timestamp), + JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("HandoffTimestamp", &status->handoff_timestamp), + SD_JSON_BUILD_PAIR_CONDITION(status->code > 0, "Code", SD_JSON_BUILD_INTEGER(status->code)), + SD_JSON_BUILD_PAIR_CONDITION(status->code > 0, "Status", SD_JSON_BUILD_INTEGER(status->status))); +} + +/* exec_command_status_list_build_json() is the runtime counterpart of exec_command_list_build_json(). + * The two arrays are positionally aligned: index N in the status array corresponds to index N in the + * command array. Commands that have not yet run produce null entries to preserve alignment. */ +int exec_command_status_list_build_json(sd_json_variant **ret, const char *name, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + ExecCommand *list = userdata; + bool any_ran = false; + int r; + + assert(ret); + + LIST_FOREACH(command, c, list) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *entry = NULL; + + r = exec_command_status_build_json(&entry, /* name= */ NULL, &c->exec_status); + if (r < 0) + return r; + + if (entry) { + any_ran = true; + r = sd_json_variant_append_array(&v, entry); + } else + r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_NULL); + if (r < 0) + return r; + } + + if (!any_ran) { + *ret = NULL; + return 0; + } + + *ret = TAKE_PTR(v); + return 0; +} diff --git a/src/core/varlink-common.h b/src/core/varlink-common.h index 8a238c34a5..98fe47b48c 100644 --- a/src/core/varlink-common.h +++ b/src/core/varlink-common.h @@ -9,4 +9,6 @@ int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata); const char* varlink_error_id_from_bus_error(const sd_bus_error *e); int exec_command_build_json(sd_json_variant **ret, const char *name, void *userdata); int exec_command_list_build_json(sd_json_variant **ret, const char *name, void *userdata); +int exec_command_status_build_json(sd_json_variant **ret, const char *name, void *userdata); +int exec_command_status_list_build_json(sd_json_variant **ret, const char *name, void *userdata); int varlink_reply_bus_error(sd_varlink *link, int r, const sd_bus_error *e); diff --git a/src/shared/varlink-idl-common.c b/src/shared/varlink-idl-common.c index a543c92a3b..d9b148daac 100644 --- a/src/shared/varlink-idl-common.c +++ b/src/shared/varlink-idl-common.c @@ -71,6 +71,21 @@ SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("Run via shell"), SD_VARLINK_DEFINE_FIELD(viaShell, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); +SD_VARLINK_DEFINE_STRUCT_TYPE( + ExecCommandStatus, + SD_VARLINK_FIELD_COMMENT("Process ID"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(PID, ProcessId, 0), + SD_VARLINK_FIELD_COMMENT("Timestamp when the process started"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(StartTimestamp, Timestamp, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp when the process exited"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExitTimestamp, Timestamp, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp when the process was handed off to the executor"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(HandoffTimestamp, Timestamp, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Termination reason (si_code): CLD_EXITED, CLD_KILLED, CLD_DUMPED"), + SD_VARLINK_DEFINE_FIELD(Code, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Exit code or signal number (si_status), meaning depends on Code"), + SD_VARLINK_DEFINE_FIELD(Status, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_ENUM_TYPE( ExecOutputType, SD_VARLINK_DEFINE_ENUM_VALUE(inherit), diff --git a/src/shared/varlink-idl-common.h b/src/shared/varlink-idl-common.h index a42df7118b..5bd351734a 100644 --- a/src/shared/varlink-idl-common.h +++ b/src/shared/varlink-idl-common.h @@ -9,6 +9,7 @@ extern const sd_varlink_symbol vl_type_RateLimit; extern const sd_varlink_symbol vl_type_ResourceLimit; extern const sd_varlink_symbol vl_type_ResourceLimitTable; extern const sd_varlink_symbol vl_type_ExecCommand; +extern const sd_varlink_symbol vl_type_ExecCommandStatus; extern const sd_varlink_symbol vl_type_ExecOutputType; extern const sd_varlink_symbol vl_type_CGroupPressureWatch; extern const sd_varlink_symbol vl_type_ManagedOOMMode; From 69b5c5db10d078644c30d40ea38ff1c0e48a42ab Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Thu, 14 May 2026 09:41:39 -0700 Subject: [PATCH 3/4] core: expand ServiceContext and add ServiceRuntime for io.systemd.Unit.List Co-developed-by: Claude Opus 4.6 --- src/core/varlink-service.c | 178 +++++++++++++++++++++- src/core/varlink-service.h | 1 + src/core/varlink-unit.c | 1 + src/shared/varlink-io.systemd.Unit.c | 216 ++++++++++++++++++++++++++- src/shared/varlink-io.systemd.Unit.h | 6 + 5 files changed, 388 insertions(+), 14 deletions(-) diff --git a/src/core/varlink-service.c b/src/core/varlink-service.c index 8d9ed6e91d..dde75a30ff 100644 --- a/src/core/varlink-service.c +++ b/src/core/varlink-service.c @@ -2,21 +2,185 @@ #include "sd-json.h" +#include "exit-status.h" #include "json-util.h" +#include "open-file.h" #include "service.h" +#include "signal-util.h" +#include "strv.h" +#include "user-util.h" #include "varlink-common.h" #include "varlink-service.h" -/* TODO: This covers only a small subset of a service object's properties. Extend to make more available to - * consumers like Unit.StartTransient */ -int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { - Unit *u = ASSERT_PTR(userdata); - Service *s = ASSERT_PTR(SERVICE(u)); +static int exit_status_set_build_json(sd_json_variant **ret, const char *name, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *statuses = NULL, *signals = NULL; + ExitStatusSet *set = ASSERT_PTR(userdata); + unsigned n; + int r; + assert(ret); + if (exit_status_set_is_empty(set)) { + *ret = NULL; + return 0; + } + + BITMAP_FOREACH(n, &set->status) { + assert(n < 256); + + r = sd_json_variant_append_arrayb(&statuses, SD_JSON_BUILD_UNSIGNED(n)); + if (r < 0) + return r; + } + + BITMAP_FOREACH(n, &set->signal) { + const char *str = signal_to_string(n); + if (!str) + continue; + + r = sd_json_variant_append_arrayb(&signals, SD_JSON_BUILD_STRING(str)); + if (r < 0) + return r; + } + + return sd_json_buildo(ret, + JSON_BUILD_PAIR_VARIANT_NON_NULL("statuses", statuses), + JSON_BUILD_PAIR_VARIANT_NON_NULL("signals", signals)); +} + +static int open_files_build_json(sd_json_variant **ret, const char *name, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + OpenFile *open_files = userdata; + int r; + + assert(ret); + + LIST_FOREACH(open_files, of, open_files) { + r = sd_json_variant_append_arraybo( + &v, + SD_JSON_BUILD_PAIR_STRING("path", of->path), + SD_JSON_BUILD_PAIR_STRING("fileDescriptorName", of->fdname), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("flags", of->flags)); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(v); + return 0; +} + +static int extra_fd_names_build_json(sd_json_variant **ret, const char *name, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + Service *s = ASSERT_PTR(userdata); + int r; + + assert(ret); + + FOREACH_ARRAY(i, s->extra_fds, s->n_extra_fds) { + r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(i->fdname)); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(v); + return 0; +} + +static int refresh_on_reload_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Service *s = ASSERT_PTR(userdata); + _cleanup_strv_free_ char **l = NULL; + int r; + + assert(ret); + + r = service_refresh_on_reload_to_strv(s->refresh_on_reload_flags, &l); + if (r < 0) + return r; + + if (strv_isempty(l)) { + *ret = NULL; + return 0; + } + + return sd_json_variant_new_array_strv(ret, l); +} + +int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Service *s = ASSERT_PTR(SERVICE(userdata)); + return sd_json_buildo( - ret, + ASSERT_PTR(ret), JSON_BUILD_PAIR_ENUM("Type", service_type_to_string(s->type)), + JSON_BUILD_PAIR_ENUM("ExitType", service_exit_type_to_string(s->exit_type)), + JSON_BUILD_PAIR_ENUM("Restart", service_restart_to_string(s->restart)), + JSON_BUILD_PAIR_ENUM("RestartMode", service_restart_mode_to_string(s->restart_mode)), + JSON_BUILD_PAIR_STRING_NON_EMPTY("PIDFile", s->pid_file), + JSON_BUILD_PAIR_FINITE_USEC("RestartUSec", s->restart_usec), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("RestartSteps", s->restart_steps), + JSON_BUILD_PAIR_FINITE_USEC_NON_ZERO("RestartMaxDelayUSec", s->restart_max_delay_usec), + JSON_BUILD_PAIR_FINITE_USEC("TimeoutStartUSec", s->timeout_start_usec), + JSON_BUILD_PAIR_FINITE_USEC("TimeoutStopUSec", s->timeout_stop_usec), + JSON_BUILD_PAIR_ENUM("TimeoutStartFailureMode", service_timeout_failure_mode_to_string(s->timeout_start_failure_mode)), + JSON_BUILD_PAIR_ENUM("TimeoutStopFailureMode", service_timeout_failure_mode_to_string(s->timeout_stop_failure_mode)), + JSON_BUILD_PAIR_FINITE_USEC_NON_ZERO("RuntimeMaxUSec", s->runtime_max_usec), + JSON_BUILD_PAIR_FINITE_USEC_NON_ZERO("RuntimeRandomizedExtraUSec", s->runtime_rand_extra_usec), + JSON_BUILD_PAIR_FINITE_USEC_NON_ZERO("WatchdogUSec", s->watchdog_usec), + SD_JSON_BUILD_PAIR_BOOLEAN("RemainAfterExit", s->remain_after_exit), + SD_JSON_BUILD_PAIR_BOOLEAN("RootDirectoryStartOnly", s->root_directory_start_only), + SD_JSON_BUILD_PAIR_BOOLEAN("GuessMainPID", s->guess_main_pid), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("SuccessExitStatus", exit_status_set_build_json, &s->success_status), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("RestartPreventExitStatus", exit_status_set_build_json, &s->restart_prevent_status), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("RestartForceExitStatus", exit_status_set_build_json, &s->restart_force_status), + JSON_BUILD_PAIR_STRING_NON_EMPTY("BusName", s->bus_name), + JSON_BUILD_PAIR_ENUM("NotifyAccess", notify_access_to_string(service_get_notify_access(s))), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("FileDescriptorStoreMax", s->n_fd_store_max), + JSON_BUILD_PAIR_ENUM("FileDescriptorStorePreserve", exec_preserve_mode_to_string(s->fd_store_preserve_mode)), + JSON_BUILD_PAIR_STRING_NON_EMPTY("USBFunctionDescriptors", s->usb_function_descriptors), + JSON_BUILD_PAIR_STRING_NON_EMPTY("USBFunctionStrings", s->usb_function_strings), + JSON_BUILD_PAIR_ENUM("OOMPolicy", oom_policy_to_string(s->oom_policy)), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("OpenFile", open_files_build_json, s->open_files), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExtraFileDescriptorNames", extra_fd_names_build_json, s), + SD_JSON_BUILD_PAIR_STRING("ReloadSignal", signal_to_string(s->reload_signal)), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("RefreshOnReload", refresh_on_reload_build_json, s), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecCondition", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_CONDITION]), JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStart", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_START]), - SD_JSON_BUILD_PAIR_BOOLEAN("RemainAfterExit", s->remain_after_exit)); + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStartPre", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_START_PRE]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStartPost", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_START_POST]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecReload", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_RELOAD]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecReloadPost", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_RELOAD_POST]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStop", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_STOP]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStopPost", exec_command_list_build_json, s->exec_command[SERVICE_EXEC_STOP_POST])); +} + +int service_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Unit *u = ASSERT_PTR(userdata); + Service *s = ASSERT_PTR(SERVICE(u)); + + return sd_json_buildo( + ASSERT_PTR(ret), + SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(&s->main_pid), "MainPID", JSON_BUILD_PIDREF(&s->main_pid)), + SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(&s->control_pid), "ControlPID", JSON_BUILD_PIDREF(&s->control_pid)), + JSON_BUILD_PAIR_STRING_NON_EMPTY("StatusText", s->status_text), + JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE("StatusErrno", s->status_errno), + JSON_BUILD_PAIR_STRING_NON_EMPTY("StatusBusError", s->status_bus_error), + JSON_BUILD_PAIR_STRING_NON_EMPTY("StatusVarlinkError", s->status_varlink_error), + JSON_BUILD_PAIR_ENUM("Result", service_result_to_string(s->result)), + JSON_BUILD_PAIR_ENUM("ReloadResult", service_result_to_string(s->reload_result)), + JSON_BUILD_PAIR_ENUM("CleanResult", service_result_to_string(s->clean_result)), + JSON_BUILD_PAIR_ENUM("LiveMountResult", service_result_to_string(s->live_mount_result)), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("NFileDescriptorStore", s->n_fd_store), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("NRestarts", s->n_restarts), + JSON_BUILD_PAIR_FINITE_USEC_NON_ZERO("RestartUSecNext", service_restart_usec_next(s)), + JSON_BUILD_PAIR_FINITE_USEC("TimeoutAbortUSec", service_timeout_abort_usec(s)), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecMain", exec_command_status_build_json, &s->main_exec_status), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecConditionStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_CONDITION]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStartPreStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_START_PRE]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStartStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_START]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStartPostStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_START_POST]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecReloadStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_RELOAD]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecReloadPostStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_RELOAD_POST]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStopStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_STOP]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecStopPostStatus", exec_command_status_list_build_json, s->exec_command[SERVICE_EXEC_STOP_POST]), + SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(u->ref_uid), "UID", SD_JSON_BUILD_UNSIGNED(u->ref_uid)), + SD_JSON_BUILD_PAIR_CONDITION(gid_is_valid(u->ref_gid), "GID", SD_JSON_BUILD_UNSIGNED(u->ref_gid))); } diff --git a/src/core/varlink-service.h b/src/core/varlink-service.h index 07ed1b9d1b..a64ce45803 100644 --- a/src/core/varlink-service.h +++ b/src/core/varlink-service.h @@ -4,3 +4,4 @@ #include "core-forward.h" int service_context_build_json(sd_json_variant **ret, const char *name, void *userdata); +int service_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata); diff --git a/src/core/varlink-unit.c b/src/core/varlink-unit.c index 368e39a63e..31f7898a8c 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -304,6 +304,7 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void [UNIT_MOUNT] = mount_runtime_build_json, [UNIT_PATH] = path_runtime_build_json, [UNIT_SCOPE] = scope_runtime_build_json, + [UNIT_SERVICE] = service_runtime_build_json, [UNIT_SOCKET] = socket_runtime_build_json, [UNIT_SWAP] = swap_runtime_build_json, [UNIT_TIMER] = timer_runtime_build_json, diff --git a/src/shared/varlink-io.systemd.Unit.c b/src/shared/varlink-io.systemd.Unit.c index 0758792e13..3efa90ed0c 100644 --- a/src/shared/varlink-io.systemd.Unit.c +++ b/src/shared/varlink-io.systemd.Unit.c @@ -1328,9 +1328,8 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("Last time the timer triggered"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(LastTriggerUSec, Timestamp, SD_VARLINK_NULLABLE)); -/* Service-specific types */ - -/* Keep in sync with service_type_table[] in src/core/service.c */ +/* ServiceContext + * https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html */ SD_VARLINK_DEFINE_ENUM_TYPE( ServiceType, SD_VARLINK_DEFINE_ENUM_VALUE(simple), @@ -1343,14 +1342,205 @@ SD_VARLINK_DEFINE_ENUM_TYPE( SD_VARLINK_DEFINE_ENUM_VALUE(notify_reload), SD_VARLINK_DEFINE_ENUM_VALUE(idle)); +SD_VARLINK_DEFINE_ENUM_TYPE( + ServiceExitType, + SD_VARLINK_DEFINE_ENUM_VALUE(main), + SD_VARLINK_DEFINE_ENUM_VALUE(cgroup)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ServiceRestart, + SD_VARLINK_DEFINE_ENUM_VALUE(no), + SD_VARLINK_DEFINE_ENUM_VALUE(on_success), + SD_VARLINK_DEFINE_ENUM_VALUE(on_failure), + SD_VARLINK_DEFINE_ENUM_VALUE(on_abnormal), + SD_VARLINK_DEFINE_ENUM_VALUE(on_watchdog), + SD_VARLINK_DEFINE_ENUM_VALUE(on_abort), + SD_VARLINK_DEFINE_ENUM_VALUE(always)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ServiceRestartMode, + SD_VARLINK_DEFINE_ENUM_VALUE(normal), + SD_VARLINK_DEFINE_ENUM_VALUE(direct), + SD_VARLINK_DEFINE_ENUM_VALUE(debug)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ServiceTimeoutFailureMode, + SD_VARLINK_DEFINE_ENUM_VALUE(terminate), + SD_VARLINK_DEFINE_ENUM_VALUE(abort), + SD_VARLINK_DEFINE_ENUM_VALUE(kill)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + NotifyAccess, + SD_VARLINK_DEFINE_ENUM_VALUE(none), + SD_VARLINK_DEFINE_ENUM_VALUE(all), + SD_VARLINK_DEFINE_ENUM_VALUE(exec), + SD_VARLINK_DEFINE_ENUM_VALUE(main)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + ServiceResult, + SD_VARLINK_DEFINE_ENUM_VALUE(success), + SD_VARLINK_DEFINE_ENUM_VALUE(resources), + SD_VARLINK_DEFINE_ENUM_VALUE(protocol), + SD_VARLINK_DEFINE_ENUM_VALUE(timeout), + SD_VARLINK_DEFINE_ENUM_VALUE(exit_code), + SD_VARLINK_DEFINE_ENUM_VALUE(signal), + SD_VARLINK_DEFINE_ENUM_VALUE(core_dump), + SD_VARLINK_DEFINE_ENUM_VALUE(watchdog), + SD_VARLINK_DEFINE_ENUM_VALUE(start_limit_hit), + SD_VARLINK_DEFINE_ENUM_VALUE(oom_kill), + SD_VARLINK_DEFINE_ENUM_VALUE(exec_condition)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + ExitStatusSet, + SD_VARLINK_FIELD_COMMENT("Exit status codes"), + SD_VARLINK_DEFINE_FIELD(statuses, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Signal names"), + SD_VARLINK_DEFINE_FIELD(signals, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + OpenFile, + SD_VARLINK_FIELD_COMMENT("Path to the file to open"), + SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("Name for the file descriptor"), + SD_VARLINK_DEFINE_FIELD(fileDescriptorName, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("Open file flags"), + SD_VARLINK_DEFINE_FIELD(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + static SD_VARLINK_DEFINE_STRUCT_TYPE( ServiceContext, SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#Type="), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Type, ServiceType, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExitType="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExitType, ServiceExitType, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#Restart="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Restart, ServiceRestart, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartMode="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RestartMode, ServiceRestartMode, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#PIDFile="), + SD_VARLINK_DEFINE_FIELD(PIDFile, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartSec="), + SD_VARLINK_DEFINE_FIELD(RestartUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartSteps="), + SD_VARLINK_DEFINE_FIELD(RestartSteps, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartMaxDelaySec="), + SD_VARLINK_DEFINE_FIELD(RestartMaxDelayUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#TimeoutStartSec="), + SD_VARLINK_DEFINE_FIELD(TimeoutStartUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#TimeoutStopSec="), + SD_VARLINK_DEFINE_FIELD(TimeoutStopUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#TimeoutStartFailureMode="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(TimeoutStartFailureMode, ServiceTimeoutFailureMode, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#TimeoutStopFailureMode="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(TimeoutStopFailureMode, ServiceTimeoutFailureMode, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RuntimeMaxSec="), + SD_VARLINK_DEFINE_FIELD(RuntimeMaxUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RuntimeRandomizedExtraSec="), + SD_VARLINK_DEFINE_FIELD(RuntimeRandomizedExtraUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#WatchdogSec="), + SD_VARLINK_DEFINE_FIELD(WatchdogUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RemainAfterExit="), + SD_VARLINK_DEFINE_FIELD(RemainAfterExit, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RootDirectoryStartOnly="), + SD_VARLINK_DEFINE_FIELD(RootDirectoryStartOnly, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#GuessMainPID="), + SD_VARLINK_DEFINE_FIELD(GuessMainPID, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#SuccessExitStatus="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(SuccessExitStatus, ExitStatusSet, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartPreventExitStatus="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RestartPreventExitStatus, ExitStatusSet, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RestartForceExitStatus="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(RestartForceExitStatus, ExitStatusSet, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#BusName="), + SD_VARLINK_DEFINE_FIELD(BusName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#NotifyAccess="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(NotifyAccess, NotifyAccess, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#FileDescriptorStoreMax="), + SD_VARLINK_DEFINE_FIELD(FileDescriptorStoreMax, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#FileDescriptorStorePreserve="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(FileDescriptorStorePreserve, ExecPreserveMode, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#USBFunctionDescriptors="), + SD_VARLINK_DEFINE_FIELD(USBFunctionDescriptors, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#USBFunctionStrings="), + SD_VARLINK_DEFINE_FIELD(USBFunctionStrings, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#OOMPolicy="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(OOMPolicy, OOMPolicy, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#OpenFile="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(OpenFile, OpenFile, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExtraFileDescriptorNames="), + SD_VARLINK_DEFINE_FIELD(ExtraFileDescriptorNames, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ReloadSignal="), + SD_VARLINK_DEFINE_FIELD(ReloadSignal, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RefreshOnReload="), + SD_VARLINK_DEFINE_FIELD(RefreshOnReload, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecCondition="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecCondition, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecStart="), SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStart, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), - SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#RemainAfterExit="), - SD_VARLINK_DEFINE_FIELD(RemainAfterExit, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecStartPre="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStartPre, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecStartPost="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStartPost, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecReload="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecReload, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecReloadPost="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecReloadPost, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecStop="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStop, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.service.html#ExecStopPost="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStopPost, ExecCommand, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + ServiceRuntime, + SD_VARLINK_FIELD_COMMENT("Main process PID"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(MainPID, ProcessId, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Control process PID"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ControlPID, ProcessId, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Status text set by the service"), + SD_VARLINK_DEFINE_FIELD(StatusText, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Status errno set by the service"), + SD_VARLINK_DEFINE_FIELD(StatusErrno, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Status D-Bus error set by the service"), + SD_VARLINK_DEFINE_FIELD(StatusBusError, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Status Varlink error set by the service"), + SD_VARLINK_DEFINE_FIELD(StatusVarlinkError, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Result of service operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, ServiceResult, 0), + SD_VARLINK_FIELD_COMMENT("Result of reload operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ReloadResult, ServiceResult, 0), + SD_VARLINK_FIELD_COMMENT("Result of cleaning operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(CleanResult, ServiceResult, 0), + SD_VARLINK_FIELD_COMMENT("Result of live mount operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(LiveMountResult, ServiceResult, 0), + SD_VARLINK_FIELD_COMMENT("Number of file descriptors in the store"), + SD_VARLINK_DEFINE_FIELD(NFileDescriptorStore, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Number of restarts"), + SD_VARLINK_DEFINE_FIELD(NRestarts, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Next restart delay"), + SD_VARLINK_DEFINE_FIELD(RestartUSecNext, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timeout for abort"), + SD_VARLINK_DEFINE_FIELD(TimeoutAbortUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Main process execution status"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecMain, ExecCommandStatus, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecCondition commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecConditionStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecStartPre commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStartPreStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecStart commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStartStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecStartPost commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStartPostStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecReload commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecReloadStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecReloadPost commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecReloadPostStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecStop commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStopStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Execution status of ExecStopPost commands"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecStopPostStatus, ExecCommandStatus, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Reference UID"), + SD_VARLINK_DEFINE_FIELD(UID, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Reference GID"), + SD_VARLINK_DEFINE_FIELD(GID, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); /* UnitContext */ static SD_VARLINK_DEFINE_STRUCT_TYPE( @@ -1709,6 +1899,8 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_FIELD_BY_TYPE(Path, PathRuntime, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("The scope runtime of the unit"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Scope, ScopeRuntime, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The service runtime of the unit"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Service, ServiceRuntime, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("The socket runtime of the unit"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Socket, SocketRuntime, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("The swap runtime of the unit"), @@ -1874,6 +2066,7 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_AutomountResult, &vl_type_AutomountRuntime, &vl_type_ExecCommand, + &vl_type_ExecCommandStatus, &vl_type_MountContext, &vl_type_MountResult, &vl_type_MountRuntime, @@ -1907,6 +2100,17 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_EmergencyAction, /* Shared types (used by both StartTransient and Unit.List) */ + &vl_type_ExitStatusSet, + &vl_type_NotifyAccess, + &vl_type_OpenFile, + SD_VARLINK_SYMBOL_COMMENT("Service-specific context"), + &vl_type_ServiceContext, + &vl_type_ServiceExitType, + &vl_type_ServiceRestart, + &vl_type_ServiceRestartMode, + &vl_type_ServiceResult, + &vl_type_ServiceRuntime, + &vl_type_ServiceTimeoutFailureMode, SD_VARLINK_SYMBOL_COMMENT("Service type"), &vl_type_ServiceType, SD_VARLINK_SYMBOL_COMMENT("Job mode"), @@ -1919,8 +2123,6 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_JobResult, SD_VARLINK_SYMBOL_COMMENT("A job object (defined in io.systemd.Job)"), &vl_type_Job, - SD_VARLINK_SYMBOL_COMMENT("Service-specific context"), - &vl_type_ServiceContext, /* Errors */ SD_VARLINK_SYMBOL_COMMENT("No matching unit found"), diff --git a/src/shared/varlink-io.systemd.Unit.h b/src/shared/varlink-io.systemd.Unit.h index a5e2e33df2..000ed19611 100644 --- a/src/shared/varlink-io.systemd.Unit.h +++ b/src/shared/varlink-io.systemd.Unit.h @@ -42,4 +42,10 @@ extern const sd_varlink_symbol vl_type_TimerBase; extern const sd_varlink_symbol vl_type_TimerResult; extern const sd_varlink_symbol vl_type_CollectMode; extern const sd_varlink_symbol vl_type_JobMode; +extern const sd_varlink_symbol vl_type_NotifyAccess; +extern const sd_varlink_symbol vl_type_ServiceExitType; +extern const sd_varlink_symbol vl_type_ServiceRestart; +extern const sd_varlink_symbol vl_type_ServiceRestartMode; +extern const sd_varlink_symbol vl_type_ServiceResult; +extern const sd_varlink_symbol vl_type_ServiceTimeoutFailureMode; extern const sd_varlink_symbol vl_type_ServiceType; From 3fcb483bca38df416e0f4f49754a85738c7373ae Mon Sep 17 00:00:00 2001 From: Ivan Kruglov Date: Thu, 14 May 2026 09:41:50 -0700 Subject: [PATCH 4/4] test: add ServiceContext/Runtime enum and integration tests Co-developed-by: Claude Opus 4.6 --- src/test/test-varlink-idl-unit.c | 8 ++++++++ test/units/TEST-74-AUX-UTILS.varlinkctl.sh | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/test/test-varlink-idl-unit.c b/src/test/test-varlink-idl-unit.c index 7859f2d735..51d5b9396f 100644 --- a/src/test/test-varlink-idl-unit.c +++ b/src/test/test-varlink-idl-unit.c @@ -67,6 +67,14 @@ TEST(unit_enums_idl) { /* ServiceContext enums */ TEST_IDL_ENUM(ServiceType, service_type, vl_type_ServiceType); + TEST_IDL_ENUM(ServiceExitType, service_exit_type, vl_type_ServiceExitType); + TEST_IDL_ENUM(ServiceRestart, service_restart, vl_type_ServiceRestart); + TEST_IDL_ENUM(ServiceRestartMode, service_restart_mode, vl_type_ServiceRestartMode); + TEST_IDL_ENUM(ServiceTimeoutFailureMode, service_timeout_failure_mode, vl_type_ServiceTimeoutFailureMode); + + /* ServiceRuntime enums */ + TEST_IDL_ENUM(NotifyAccess, notify_access, vl_type_NotifyAccess); + TEST_IDL_ENUM(ServiceResult, service_result, vl_type_ServiceResult); /* PathContext enums */ TEST_IDL_ENUM(PathType, path_type, vl_type_PathType); diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh index de56b37c31..bbc219decb 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh @@ -252,6 +252,12 @@ test -n "$path_id" path_params=$(jq -cn --arg name "$path_id" '{name: $name}') varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$path_params" | jq -e '.context.Path' varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$path_params" | jq -e '.runtime.Path' +# test for ServiceContext/Runtime +service_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}' | jq -r '.[] | select(.context.Type == "service" and .runtime.LoadState == "loaded") .context.ID // empty' | tail -n 1) +test -n "$service_id" +service_params=$(jq -cn --arg name "$service_id" '{name: $name}') +varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$service_params" | jq -e '.context.Service' +varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$service_params" | jq -e '.runtime.Service' # test for ScopeContext/Runtime scope_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}' | jq -r '.[] | select(.context.Type == "scope" and .runtime.LoadState == "loaded") .context.ID // empty' | tail -n 1) test -n "$scope_id"