From: Ivan Kruglov Date: Fri, 17 Oct 2025 14:59:23 +0000 (-0700) Subject: core: implement MountContext/Runtime for io.systemd.Unit.List + tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcdf4d0c70a19bd646ad8f162a7142ae19445712;p=thirdparty%2Fsystemd.git core: implement MountContext/Runtime for io.systemd.Unit.List + tests --- diff --git a/src/core/meson.build b/src/core/meson.build index 9a91c37112e..c5ef7e48cbd 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -72,6 +72,7 @@ libcore_sources = files( 'varlink-kill.c', 'varlink-manager.c', 'varlink-metrics.c', + 'varlink-mount.c', 'varlink-unit.c', ) diff --git a/src/core/varlink-mount.c b/src/core/varlink-mount.c new file mode 100644 index 00000000000..f4148cafb38 --- /dev/null +++ b/src/core/varlink-mount.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "sd-json.h" + +#include "json-util.h" +#include "mount.h" +#include "user-util.h" +#include "varlink-common.h" +#include "varlink-mount.h" + +int mount_context_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Mount *m = ASSERT_PTR(MOUNT(userdata)); + _cleanup_free_ char *what = NULL, *where = NULL, *options = NULL; + + what = mount_get_what_escaped(m); + if (!what) + return -ENOMEM; + + where = mount_get_where_escaped(m); + if (!where) + return -ENOMEM; + + options = mount_get_options_escaped(m); + if (!options) + return -ENOMEM; + + return sd_json_buildo( + ASSERT_PTR(ret), + JSON_BUILD_PAIR_STRING_NON_EMPTY("What", what), + JSON_BUILD_PAIR_STRING_NON_EMPTY("Where", where), + JSON_BUILD_PAIR_STRING_NON_EMPTY("Type", mount_get_fstype(m)), + JSON_BUILD_PAIR_STRING_NON_EMPTY("Options", options), + SD_JSON_BUILD_PAIR_BOOLEAN("SloppyOptions", m->sloppy_options), + SD_JSON_BUILD_PAIR_BOOLEAN("LazyUnmount", m->lazy_unmount), + SD_JSON_BUILD_PAIR_BOOLEAN("ReadWriteOnly", m->read_write_only), + SD_JSON_BUILD_PAIR_BOOLEAN("ForceUnmount", m->force_unmount), + SD_JSON_BUILD_PAIR_UNSIGNED("DirectoryMode", m->directory_mode), + JSON_BUILD_PAIR_FINITE_USEC("TimeoutUSec", m->timeout_usec), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecMount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_MOUNT]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecUnmount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_UNMOUNT]), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecRemount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_REMOUNT])); +} + +int mount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) { + Unit *u = ASSERT_PTR(userdata); + Mount *m = ASSERT_PTR(MOUNT(u)); + return sd_json_buildo( + ASSERT_PTR(ret), + SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(&m->control_pid), "ControlPID", JSON_BUILD_PIDREF(&m->control_pid)), + JSON_BUILD_PAIR_ENUM("Result", mount_result_to_string(m->result)), + JSON_BUILD_PAIR_ENUM("ReloadResult", mount_result_to_string(m->reload_result)), + JSON_BUILD_PAIR_ENUM("CleanResult", mount_result_to_string(m->clean_result)), + 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-mount.h b/src/core/varlink-mount.h new file mode 100644 index 00000000000..30fd92781a5 --- /dev/null +++ b/src/core/varlink-mount.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "core-forward.h" + +int mount_context_build_json(sd_json_variant **ret, const char *name, void *userdata); +int mount_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 5f8d1764d5e..789b21947c8 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -22,6 +22,7 @@ #include "varlink-cgroup.h" #include "varlink-execute.h" #include "varlink-kill.h" +#include "varlink-mount.h" #include "varlink-unit.h" #include "varlink-util.h" @@ -117,6 +118,7 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void /* TODO missing callbacks */ 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, }; return sd_json_buildo( @@ -281,6 +283,7 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void /* TODO missing callbacks */ 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, }; return sd_json_buildo( diff --git a/src/shared/varlink-io.systemd.Unit.c b/src/shared/varlink-io.systemd.Unit.c index b11aedfa5af..422aeb6952b 100644 --- a/src/shared/varlink-io.systemd.Unit.c +++ b/src/shared/varlink-io.systemd.Unit.c @@ -941,6 +941,37 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( 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)); +/* MountContext + * https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html */ +static SD_VARLINK_DEFINE_STRUCT_TYPE( + MountContext, + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#What="), + SD_VARLINK_DEFINE_FIELD(What, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.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.mount.html#Type="), + SD_VARLINK_DEFINE_FIELD(Type, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#Options="), + SD_VARLINK_DEFINE_FIELD(Options, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#SloppyOptions="), + SD_VARLINK_DEFINE_FIELD(SloppyOptions, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#LazyUnmount="), + SD_VARLINK_DEFINE_FIELD(LazyUnmount, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#ReadWriteOnly="), + SD_VARLINK_DEFINE_FIELD(ReadWriteOnly, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.html#ForceUnmount="), + SD_VARLINK_DEFINE_FIELD(ForceUnmount, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.mount.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.mount.html#TimeoutSec="), + SD_VARLINK_DEFINE_FIELD(TimeoutUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Mount command"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecMount, ExecCommand, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Unmount command"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecUnmount, ExecCommand, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Remount command"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExecRemount, ExecCommand, SD_VARLINK_NULLABLE)); + /* UnitContext */ static SD_VARLINK_DEFINE_STRUCT_TYPE( Condition, @@ -1102,7 +1133,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("The kill context of the unit"), 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)); + 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)); static SD_VARLINK_DEFINE_STRUCT_TYPE( ActivationDetails, @@ -1189,6 +1222,32 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("Result of automount operation"), SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, AutomountResult, 0)); +SD_VARLINK_DEFINE_ENUM_TYPE( + MountResult, + SD_VARLINK_DEFINE_ENUM_VALUE(success), + SD_VARLINK_DEFINE_ENUM_VALUE(resources), + 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(start_limit_hit), + SD_VARLINK_DEFINE_ENUM_VALUE(protocol)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( + MountRuntime, + SD_VARLINK_FIELD_COMMENT("PID of the current mount/remount/etc process running"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ControlPID, ProcessId, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Result of mount operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, MountResult, 0), + SD_VARLINK_FIELD_COMMENT("Result of remount operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(ReloadResult, MountResult, 0), + SD_VARLINK_FIELD_COMMENT("Result of cleaning operation"), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(CleanResult, MountResult, 0), + 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)); + 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"), @@ -1248,7 +1307,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_FIELD_COMMENT("The cgroup runtime of the unit"), 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)); + 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)); static SD_VARLINK_DEFINE_METHOD_FULL( List, @@ -1382,6 +1443,10 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_AutomountContext, &vl_type_AutomountResult, &vl_type_AutomountRuntime, + &vl_type_ExecCommand, + &vl_type_MountContext, + &vl_type_MountResult, + &vl_type_MountRuntime, /* UnitContext enums */ &vl_type_CollectMode, diff --git a/src/shared/varlink-io.systemd.Unit.h b/src/shared/varlink-io.systemd.Unit.h index 0b3cbf30e57..a3940713384 100644 --- a/src/shared/varlink-io.systemd.Unit.h +++ b/src/shared/varlink-io.systemd.Unit.h @@ -29,5 +29,6 @@ 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_MountResult; extern const sd_varlink_symbol vl_type_CollectMode; extern const sd_varlink_symbol vl_type_JobMode; diff --git a/src/test/test-varlink-idl-unit.c b/src/test/test-varlink-idl-unit.c index 56a50554d81..2f4bb1c9e91 100644 --- a/src/test/test-varlink-idl-unit.c +++ b/src/test/test-varlink-idl-unit.c @@ -4,6 +4,7 @@ #include "cgroup.h" #include "ioprio-util.h" #include "kill.h" +#include "mount.h" #include "numa-util.h" #include "process-util.h" #include "tests.h" @@ -55,6 +56,9 @@ TEST(unit_enums_idl) { /* AutomountRuntime enums */ TEST_IDL_ENUM(AutomountResult, automount_result, vl_type_AutomountResult); + /* MountRuntime enums */ + TEST_IDL_ENUM(MountResult, mount_result, vl_type_MountResult); + /* 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 318034323ba..9a22757067f 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh @@ -237,6 +237,11 @@ automount_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.syst 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 for MountContext/Runtime +mount_id=$(varlinkctl call --collect /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}' | jq -r '.[] | select(.context.Type == "mount" and .runtime.LoadState == "loaded") .context.ID' | grep -v null | tail -n 1) +test -n "$mount_id" +varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "{\"name\": \"$mount_id\"}" | jq -e '.context.Mount' +varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List "{\"name\": \"$mount_id\"}" | jq -e '.runtime.Mount' # test io.systemd.Metrics varlinkctl info /run/systemd/report/io.systemd.Manager