From: Ivan Kruglov Date: Thu, 7 May 2026 10:15:15 +0000 (-0700) Subject: core: implement PathContext/Runtime for io.systemd.Unit.List + tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8787415123b87b74170e29b180fb5cb9ac32b7e9;p=thirdparty%2Fsystemd.git core: implement PathContext/Runtime for io.systemd.Unit.List + tests Add varlink context and runtime builders for .path units: PathContext: Paths (array of PathType enum + path specs), Unit, MakeDirectory, DirectoryMode, TriggerLimit PathRuntime: Result (PathResult enum) Both PathType and PathResult are exposed as proper varlink enum types. Co-developed-by: Claude Opus 4.6 --- diff --git a/src/core/meson.build b/src/core/meson.build index d24fc3b6d37..0dae1e50cc9 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -73,6 +73,7 @@ libcore_sources = files( 'varlink-manager.c', 'varlink-metrics.c', 'varlink-mount.c', + 'varlink-path.c', 'varlink-unit.c', ) diff --git a/src/core/varlink-path.c b/src/core/varlink-path.c new file mode 100644 index 00000000000..c6ba45a04d7 --- /dev/null +++ b/src/core/varlink-path.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "sd-json.h" + +#include "json-util.h" +#include "path.h" +#include "varlink-path.h" + +static int path_specs_build_json(sd_json_variant **ret, const char *name, void *userdata) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + PathSpec *specs = userdata; + int r; + + assert(ret); + + LIST_FOREACH(spec, k, specs) { + r = sd_json_variant_append_arraybo( + &v, + JSON_BUILD_PAIR_ENUM("type", path_type_to_string(k->type)), + SD_JSON_BUILD_PAIR_STRING("path", k->path)); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(v); + return 0; +} + +int path_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Path *p = ASSERT_PTR(PATH(userdata)); + Unit *trigger = UNIT_TRIGGER(UNIT(p)); + + return sd_json_buildo( + ASSERT_PTR(ret), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("Paths", path_specs_build_json, p->specs), + JSON_BUILD_PAIR_STRING_NON_EMPTY("Unit", trigger ? trigger->id : NULL), + SD_JSON_BUILD_PAIR_BOOLEAN("MakeDirectory", p->make_directory), + SD_JSON_BUILD_PAIR_UNSIGNED("DirectoryMode", p->directory_mode), + JSON_BUILD_PAIR_RATELIMIT("TriggerLimit", &p->trigger_limit)); +} + +int path_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Path *p = ASSERT_PTR(PATH(userdata)); + + return sd_json_buildo( + ASSERT_PTR(ret), + JSON_BUILD_PAIR_ENUM("Result", path_result_to_string(p->result))); +} diff --git a/src/core/varlink-path.h b/src/core/varlink-path.h new file mode 100644 index 00000000000..a466949e37c --- /dev/null +++ b/src/core/varlink-path.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "core-forward.h" + +int path_context_build_json(sd_json_variant **ret, const char *name, void *userdata); +int path_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 5b1dc77aae0..ca357cf899e 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -29,6 +29,7 @@ #include "varlink-execute.h" #include "varlink-kill.h" #include "varlink-mount.h" +#include "varlink-path.h" #include "varlink-unit.h" #include "varlink-util.h" @@ -162,6 +163,7 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = { [UNIT_AUTOMOUNT] = automount_context_build_json, [UNIT_MOUNT] = mount_context_build_json, + [UNIT_PATH] = path_context_build_json, [UNIT_SERVICE] = service_context_build_json, }; @@ -328,6 +330,7 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = { [UNIT_AUTOMOUNT] = automount_runtime_build_json, [UNIT_MOUNT] = mount_runtime_build_json, + [UNIT_PATH] = path_runtime_build_json, }; return sd_json_buildo( diff --git a/src/shared/varlink-io.systemd.Unit.c b/src/shared/varlink-io.systemd.Unit.c index be5c942fcc7..4e8e4f04b7f 100644 --- a/src/shared/varlink-io.systemd.Unit.c +++ b/src/shared/varlink-io.systemd.Unit.c @@ -973,6 +973,49 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("Remount command"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecRemount, ExecCommand, SD_VARLINK_NULLABLE)); +/* PathContext + * https://www.freedesktop.org/software/systemd/man/latest/systemd.path.html */ +SD_VARLINK_DEFINE_ENUM_TYPE( + PathType, + SD_VARLINK_DEFINE_ENUM_VALUE(PathExists), + SD_VARLINK_DEFINE_ENUM_VALUE(PathExistsGlob), + SD_VARLINK_DEFINE_ENUM_VALUE(DirectoryNotEmpty), + SD_VARLINK_DEFINE_ENUM_VALUE(PathChanged), + SD_VARLINK_DEFINE_ENUM_VALUE(PathModified)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + PathSpec, + SD_VARLINK_FIELD_COMMENT("Path spec type"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(type, PathType, 0), + SD_VARLINK_FIELD_COMMENT("Path"), + SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + PathContext, + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.path.html#PathExists="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Paths, PathSpec, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.path.html#Unit="), + SD_VARLINK_DEFINE_FIELD(Unit, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.path.html#MakeDirectory="), + SD_VARLINK_DEFINE_FIELD(MakeDirectory, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.path.html#DirectoryMode="), + SD_VARLINK_DEFINE_FIELD(DirectoryMode, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.path.html#TriggerLimitIntervalSec="), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(TriggerLimit, RateLimit, SD_VARLINK_NULLABLE)); + +SD_VARLINK_DEFINE_ENUM_TYPE( + PathResult, + SD_VARLINK_DEFINE_ENUM_VALUE(success), + SD_VARLINK_DEFINE_ENUM_VALUE(resources), + SD_VARLINK_DEFINE_ENUM_VALUE(start_limit_hit), + SD_VARLINK_DEFINE_ENUM_VALUE(unit_start_limit_hit), + SD_VARLINK_DEFINE_ENUM_VALUE(trigger_limit_hit)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + PathRuntime, + SD_VARLINK_FIELD_COMMENT("Result of path operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, PathResult, 0)); + /* Service-specific types */ /* Keep in sync with service_type_table[] in src/core/service.c */ @@ -1165,7 +1208,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("The automount context of the unit"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Automount, AutomountContext, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("The mount context of the unit"), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(Mount, MountContext, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Mount, MountContext, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The path context of the unit"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Path, PathContext, SD_VARLINK_NULLABLE)); static SD_VARLINK_DEFINE_STRUCT_TYPE( ActivationDetails, @@ -1339,7 +1384,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("The automount runtime of the unit"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Automount, AutomountRuntime, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("The mount runtime of the unit"), - SD_VARLINK_DEFINE_FIELD_BY_TYPE(Mount, MountRuntime, SD_VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Mount, MountRuntime, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The path runtime of the unit"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Path, PathRuntime, SD_VARLINK_NULLABLE)); static SD_VARLINK_DEFINE_METHOD_FULL( List, @@ -1501,6 +1548,11 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_MountContext, &vl_type_MountResult, &vl_type_MountRuntime, + &vl_type_PathType, + &vl_type_PathSpec, + &vl_type_PathContext, + &vl_type_PathResult, + &vl_type_PathRuntime, /* UnitContext enums */ &vl_type_CollectMode, diff --git a/src/shared/varlink-io.systemd.Unit.h b/src/shared/varlink-io.systemd.Unit.h index f12ac60701e..bc43d7b59fb 100644 --- a/src/shared/varlink-io.systemd.Unit.h +++ b/src/shared/varlink-io.systemd.Unit.h @@ -30,6 +30,8 @@ extern const sd_varlink_symbol vl_type_MountPropagationFlag; extern const sd_varlink_symbol vl_type_KillMode; extern const sd_varlink_symbol vl_type_AutomountResult; extern const sd_varlink_symbol vl_type_MountResult; +extern const sd_varlink_symbol vl_type_PathType; +extern const sd_varlink_symbol vl_type_PathResult; extern const sd_varlink_symbol vl_type_CollectMode; extern const sd_varlink_symbol vl_type_JobMode; extern const sd_varlink_symbol vl_type_ServiceType; diff --git a/src/test/test-varlink-idl-unit.c b/src/test/test-varlink-idl-unit.c index 24698594119..6c0f834a7a3 100644 --- a/src/test/test-varlink-idl-unit.c +++ b/src/test/test-varlink-idl-unit.c @@ -6,6 +6,7 @@ #include "kill.h" #include "mount.h" #include "numa-util.h" +#include "path.h" #include "process-util.h" #include "service.h" #include "tests.h" @@ -63,6 +64,12 @@ TEST(unit_enums_idl) { /* ServiceContext enums */ TEST_IDL_ENUM(ServiceType, service_type, vl_type_ServiceType); + /* PathContext enums */ + TEST_IDL_ENUM(PathType, path_type, vl_type_PathType); + + /* PathRuntime enums */ + TEST_IDL_ENUM(PathResult, path_result, vl_type_PathResult); + /* UnitContext enums */ TEST_IDL_ENUM(CollectMode, collect_mode, vl_type_CollectMode); TEST_IDL_ENUM(EmergencyAction, emergency_action, vl_type_EmergencyAction); diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh index 3e6d4a9a257..1db22b85c11 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh @@ -246,6 +246,12 @@ test -n "$mount_id" mount_params=$(jq -cn --arg name "$mount_id" '{name: $name}') varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$mount_params" | jq -e '.context.Mount' varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "$mount_params" | jq -e '.runtime.Mount' +# test for PathContext/Runtime +path_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}' | jq -r '.[] | select(.context.Type == "path" and .runtime.LoadState == "loaded") .context.ID' | grep -v null | tail -n 1) +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 io.systemd.Metrics varlinkctl info /run/systemd/report/io.systemd.Manager