From: Ivan Kruglov Date: Thu, 14 May 2026 16:41:24 +0000 (-0700) Subject: shared: add exec_command_status_build_json() and ExecCommandStatus varlink type to... X-Git-Tag: v261-rc1~159^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5305da009aa9e79ca309b16bffaf3898a3fe57e8;p=thirdparty%2Fsystemd.git shared: add exec_command_status_build_json() and ExecCommandStatus varlink type to common 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). --- diff --git a/src/core/varlink-common.c b/src/core/varlink-common.c index f5745e12e8e..bdbecd4551b 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 8a238c34a5d..98fe47b48cc 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 a543c92a3b8..d9b148daac6 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 a42df7118bd..5bd351734a9 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;