]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: implement AutomountContext/Runtime for io.systemd.Unit.List + tests
authorIvan Kruglov <mail@ikruglov.com>
Fri, 17 Oct 2025 12:13:14 +0000 (05:13 -0700)
committerIvan Kruglov <mail@ikruglov.com>
Thu, 16 Apr 2026 09:15:52 +0000 (02:15 -0700)
src/core/meson.build
src/core/varlink-automount.c [new file with mode: 0644]
src/core/varlink-automount.h [new file with mode: 0644]
src/core/varlink-unit.c
src/shared/varlink-io.systemd.Unit.c
src/shared/varlink-io.systemd.Unit.h
src/test/test-varlink-idl-unit.c
test/units/TEST-74-AUX-UTILS.varlinkctl.sh

index 24e7a5e36630833cfcbd5f07f010a59889d4640b..9a91c37112e9f2d4916ae518660c77d0f4a3575f 100644 (file)
@@ -64,6 +64,7 @@ libcore_sources = files(
         'unit-serialize.c',
         'unit.c',
         'varlink.c',
+        'varlink-automount.c',
         'varlink-cgroup.c',
         'varlink-common.c',
         'varlink-dynamic-user.c',
diff --git a/src/core/varlink-automount.c b/src/core/varlink-automount.c
new file mode 100644 (file)
index 0000000..2bb5fa3
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-json.h"
+
+#include "automount.h"
+#include "json-util.h"
+#include "varlink-automount.h"
+
+int automount_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+        Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
+        return sd_json_buildo(
+                        ASSERT_PTR(ret),
+                        JSON_BUILD_PAIR_STRING_NON_EMPTY("Where", a->where),
+                        JSON_BUILD_PAIR_STRING_NON_EMPTY("ExtraOptions", a->extra_options),
+                        SD_JSON_BUILD_PAIR_UNSIGNED("DirectoryMode", a->directory_mode),
+                        JSON_BUILD_PAIR_FINITE_USEC("TimeoutIdleUSec", a->timeout_idle_usec));
+}
+
+int automount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+        Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
+        return sd_json_buildo(ASSERT_PTR(ret), JSON_BUILD_PAIR_ENUM("Result", automount_result_to_string(a->result)));
+}
diff --git a/src/core/varlink-automount.h b/src/core/varlink-automount.h
new file mode 100644 (file)
index 0000000..892f8ba
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "core-forward.h"
+
+int automount_context_build_json(sd_json_variant **ret, const char *name, void *userdata);
+int automount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata);
index 124d6d353b68ba8dca8582bd3bf4346c8eba06d4..5f8d1764d5e2443e307ca7a350570a209a9d7ff9 100644 (file)
@@ -18,6 +18,7 @@
 #include "set.h"
 #include "strv.h"
 #include "unit.h"
+#include "varlink-automount.h"
 #include "varlink-cgroup.h"
 #include "varlink-execute.h"
 #include "varlink-kill.h"
@@ -113,6 +114,11 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
          * If it make sense to place a property into a config/unit file it belongs to Context.
          * Otherwise it's a 'Runtime'. */
 
+        /* TODO missing callbacks */
+        static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = {
+                [UNIT_AUTOMOUNT] = automount_context_build_json,
+        };
+
         return sd_json_buildo(
                         ASSERT_PTR(ret),
                         SD_JSON_BUILD_PAIR_STRING("Type", unit_type_to_string(u->type)),
@@ -191,16 +197,8 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
 
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_context_build_json, u),
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", unit_exec_context_build_json, u),
-                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("Kill", unit_kill_context_build_json, unit_get_kill_context(u)));
-
-        // TODO follow up PRs:
-        // Mount/Automount context
-        // Path context
-        // Scope context
-        // Swap context
-        // Timer context
-        // Service context
-        // Socket context
+                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("Kill", unit_kill_context_build_json, unit_get_kill_context(u)),
+                        JSON_BUILD_PAIR_CALLBACK_NON_NULL(unit_type_to_capitalized_string(u->type), unit_type_callbacks[u->type], u));
 }
 
 static int can_clean_build_json(sd_json_variant **ret, const char *name, void *userdata) {
@@ -280,6 +278,11 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void
         Unit *u = ASSERT_PTR(userdata);
         Unit *f = unit_following(u);
 
+        /* TODO missing callbacks */
+        static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = {
+                [UNIT_AUTOMOUNT] = automount_runtime_build_json,
+        };
+
         return sd_json_buildo(
                         ASSERT_PTR(ret),
                         JSON_BUILD_PAIR_STRING_NON_EMPTY("Following", f ? f->id : NULL),
@@ -309,7 +312,8 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void
                         SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(u->invocation_id), "InvocationID", SD_JSON_BUILD_UUID(u->invocation_id)),
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("Markers", markers_build_json, &u->markers),
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("ActivationDetails", activation_details_build_json, u->activation_details),
-                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_runtime_build_json, u));
+                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_runtime_build_json, u),
+                        JSON_BUILD_PAIR_CALLBACK_NON_NULL(unit_type_to_capitalized_string(u->type), unit_type_callbacks[u->type], u));
 }
 
 static int list_unit_one(sd_varlink *link, Unit *unit) {
index fbcdce8e0677f7af3d2e2a3e6e9d146d9518c60e..b11aedfa5af5d4c3b906aa77a01ae3a7af662778 100644 (file)
@@ -928,6 +928,19 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.kill.html#WatchdogSignal="),
                 SD_VARLINK_DEFINE_FIELD(WatchdogSignal, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
 
+/* AutomountContext
+ * https://www.freedesktop.org/software/systemd/man/latest/systemd.automount.html */
+static SD_VARLINK_DEFINE_STRUCT_TYPE(
+                AutomountContext,
+                SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.automount.html#Where="),
+                SD_VARLINK_DEFINE_FIELD(Where, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
+                SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.automount.html#ExtraOptions="),
+                SD_VARLINK_DEFINE_FIELD(ExtraOptions, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
+                SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.automount.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.automount.html#TimeoutIdleSec="),
+                SD_VARLINK_DEFINE_FIELD(TimeoutIdleUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
+
 /* UnitContext */
 static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 Condition,
@@ -1087,8 +1100,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 SD_VARLINK_FIELD_COMMENT("The exec context of the unit"),
                 SD_VARLINK_DEFINE_FIELD_BY_TYPE(Exec, ExecContext, SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("The kill context of the unit"),
-                SD_VARLINK_DEFINE_FIELD_BY_TYPE(Kill, KillContext, SD_VARLINK_NULLABLE));
-
+                SD_VARLINK_DEFINE_FIELD_BY_TYPE(Kill, KillContext, SD_VARLINK_NULLABLE),
+                SD_VARLINK_FIELD_COMMENT("The automount context of the unit"),
+                SD_VARLINK_DEFINE_FIELD_BY_TYPE(Automount, AutomountContext, SD_VARLINK_NULLABLE));
 
 static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 ActivationDetails,
@@ -1162,6 +1176,19 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 SD_VARLINK_FIELD_COMMENT("The number of processes of this unit killed by systemd-oomd"),
                 SD_VARLINK_DEFINE_FIELD(ManagedOOMKills, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
 
+SD_VARLINK_DEFINE_ENUM_TYPE(
+                AutomountResult,
+                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(mount_start_limit_hit),
+                SD_VARLINK_DEFINE_ENUM_VALUE(unmounted));
+
+static SD_VARLINK_DEFINE_STRUCT_TYPE(
+                AutomountRuntime,
+                SD_VARLINK_FIELD_COMMENT("Result of automount operation"),
+                SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, AutomountResult, 0));
+
 static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 UnitRuntime,
                 SD_VARLINK_FIELD_COMMENT("If not empty, the field contains the name of another unit that this unit follows in state"),
@@ -1219,7 +1246,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 SD_VARLINK_FIELD_COMMENT("Provides details about why a unit was activated"),
                 SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActivationDetails, ActivationDetails, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("The cgroup runtime of the unit"),
-                SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupRuntime, SD_VARLINK_NULLABLE));
+                SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupRuntime, SD_VARLINK_NULLABLE),
+                SD_VARLINK_FIELD_COMMENT("The automount runtime of the unit"),
+                SD_VARLINK_DEFINE_FIELD_BY_TYPE(Automount, AutomountRuntime, SD_VARLINK_NULLABLE));
 
 static SD_VARLINK_DEFINE_METHOD_FULL(
                 List,
@@ -1350,6 +1379,9 @@ SD_VARLINK_DEFINE_INTERFACE(
                 /* other contexts */
                 &vl_type_KillMode,
                 &vl_type_KillContext,
+                &vl_type_AutomountContext,
+                &vl_type_AutomountResult,
+                &vl_type_AutomountRuntime,
 
                 /* UnitContext enums */
                 &vl_type_CollectMode,
index 61abb754bc7c6d561de44437c8e7ba595ea4e446..0b3cbf30e57641034de5e5e03b036b10aef4c6d0 100644 (file)
@@ -28,5 +28,6 @@ extern const sd_varlink_symbol vl_type_IOSchedulingClass;
 extern const sd_varlink_symbol vl_type_NUMAPolicy;
 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_CollectMode;
 extern const sd_varlink_symbol vl_type_JobMode;
index 90ff3f6b787c1c8f6b92a07dc4f02106f3e92637..56a50554d8142e4d72c97344fc3133263819bb58 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include "automount.h"
 #include "cgroup.h"
 #include "ioprio-util.h"
 #include "kill.h"
@@ -51,6 +52,9 @@ TEST(unit_enums_idl) {
         TEST_IDL_ENUM(CGroupPressureWatch, cgroup_pressure_watch, vl_type_CGroupPressureWatch);
         TEST_IDL_ENUM(CGroupController, cgroup_controller, vl_type_CGroupController);
 
+        /* AutomountRuntime enums */
+        TEST_IDL_ENUM(AutomountResult, automount_result, vl_type_AutomountResult);
+
         /* UnitContext enums */
         TEST_IDL_ENUM(CollectMode, collect_mode, vl_type_CollectMode);
         TEST_IDL_ENUM(EmergencyAction, emergency_action, vl_type_EmergencyAction);
index 2ec1e0408955d935c2d0089b29d9e28b4efde0e6..318034323ba677cc567af8d9d01f7a6ac2248e69 100755 (executable)
@@ -232,6 +232,11 @@ invocation_id="$(systemctl show -P InvocationID systemd-journald.service)"
 varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "{\"invocationID\": \"$invocation_id\"}"
 # test for KillContext
 varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"pid": {"pid": 0}}' | jq -e '.context.Kill'
+# test for AutomountContext/Runtime
+automount_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}' | jq -r '.[] | select(.context.Type == "automount" and .runtime.LoadState == "loaded") .context.ID' | grep -v null | tail -n 1)
+test -n "$automount_id"
+varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "{\"name\": \"$automount_id\"}" | jq -e '.context.Automount'
+varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "{\"name\": \"$automount_id\"}" | jq -e '.runtime.Automount'
 
 # test io.systemd.Metrics
 varlinkctl info /run/systemd/report/io.systemd.Manager