]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: add enum types for class and whom fields in io.systemd.Machine
authorIvan Kruglov <mail@ikruglov.com>
Mon, 13 Apr 2026 10:32:16 +0000 (03:32 -0700)
committerIvan Kruglov <mail@ikruglov.com>
Tue, 14 Apr 2026 09:10:52 +0000 (02:10 -0700)
Convert the class field (Register input, List output) from plain string
to MachineClass enum type, and the whom field (Kill input) to KillWhom
enum type.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
src/machine/machine-varlink.c
src/machine/machined-varlink.c
src/shared/varlink-io.systemd.Machine.c
src/shared/varlink-io.systemd.Machine.h
src/test/meson.build
src/test/test-varlink-idl-machine.c [new file with mode: 0644]

index 07a860f6c16ca71912acc675ab8b33029dc58306..a3d3cfcc7e7eefa76f4ad2f42e7114d373f62eba 100644 (file)
@@ -360,10 +360,12 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters,
         return sd_varlink_reply(link, NULL);
 }
 
+static JSON_DISPATCH_ENUM_DEFINE(dispatch_kill_whom, KillWhom, kill_whom_from_string);
+
 typedef struct MachineKillParameters {
         const char *name;
         PidRef pidref;
-        const char *swhom;
+        KillWhom whom;
         int32_t signo;
 } MachineKillParameters;
 
@@ -376,7 +378,7 @@ static void machine_kill_paramaters_done(MachineKillParameters *p) {
 int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
         static const sd_json_dispatch_field dispatch_table[] = {
                 VARLINK_DISPATCH_MACHINE_LOOKUP_FIELDS(MachineKillParameters),
-                { "whom",   SD_JSON_VARIANT_STRING,         sd_json_dispatch_const_string, offsetof(MachineKillParameters, swhom), 0                 },
+                { "whom",   SD_JSON_VARIANT_STRING,         dispatch_kill_whom,            offsetof(MachineKillParameters, whom),  0                 },
                 { "signal", _SD_JSON_VARIANT_TYPE_INVALID , sd_json_dispatch_signal,       offsetof(MachineKillParameters, signo), SD_JSON_MANDATORY },
                 VARLINK_DISPATCH_POLKIT_FIELD,
                 {}
@@ -385,8 +387,8 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
         Manager *manager = ASSERT_PTR(userdata);
         _cleanup_(machine_kill_paramaters_done) MachineKillParameters p = {
                 .pidref = PIDREF_NULL,
+                .whom = _KILL_WHOM_INVALID,
         };
-        KillWhom whom;
         int r;
 
         assert(link);
@@ -403,13 +405,7 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
         if (r < 0)
                 return r;
 
-        if (isempty(p.swhom))
-                whom = KILL_ALL;
-        else {
-                whom = kill_whom_from_string(p.swhom);
-                if (whom < 0)
-                        return sd_varlink_error_invalid_parameter_name(link, "whom");
-        }
+        KillWhom whom = p.whom >= 0 ? p.whom : KILL_ALL;
 
         if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
                 r = varlink_verify_polkit_async_full(
index 82b8ed93b37c24acafe56137feade32b8dba8e32..ac506ad87f5a90cc502305d526bc4d04161ae537 100644 (file)
@@ -478,7 +478,7 @@ static int list_machine_one_and_maybe_read_metadata(sd_varlink *link, Machine *m
                         &v,
                         SD_JSON_BUILD_PAIR_STRING("name", m->name),
                         SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->id), "id", SD_JSON_BUILD_ID128(m->id)),
-                        SD_JSON_BUILD_PAIR_STRING("class", machine_class_to_string(m->class)),
+                        JSON_BUILD_PAIR_ENUM("class", machine_class_to_string(m->class)),
                         JSON_BUILD_PAIR_STRING_NON_EMPTY("service", m->service),
                         JSON_BUILD_PAIR_STRING_NON_EMPTY("rootDirectory", m->root_directory),
                         JSON_BUILD_PAIR_STRING_NON_EMPTY("unit", m->unit),
index 31fb43fbac271d60438b626b0772126fa6ceac5e..9f6d36ad77c7b2482e0fb6c4c9fc3cc5aa6273a8 100644 (file)
         SD_VARLINK_DEFINE_INPUT_BY_TYPE(pid, ProcessId, SD_VARLINK_NULLABLE),                                                                  \
         VARLINK_DEFINE_POLKIT_INPUT
 
+SD_VARLINK_DEFINE_ENUM_TYPE(
+                MachineClass,
+                SD_VARLINK_DEFINE_ENUM_VALUE(container),
+                SD_VARLINK_DEFINE_ENUM_VALUE(vm),
+                SD_VARLINK_DEFINE_ENUM_VALUE(host));
+
+SD_VARLINK_DEFINE_ENUM_TYPE(
+                KillWhom,
+                SD_VARLINK_DEFINE_ENUM_VALUE(leader),
+                SD_VARLINK_DEFINE_ENUM_VALUE(supervisor),
+                SD_VARLINK_DEFINE_ENUM_VALUE(all));
+
 static SD_VARLINK_DEFINE_ENUM_TYPE(
                 AcquireMetadata,
                 SD_VARLINK_FIELD_COMMENT("Do not include metadata in the output"),
@@ -31,7 +43,7 @@ static SD_VARLINK_DEFINE_METHOD(
                 SD_VARLINK_DEFINE_INPUT(name,                    SD_VARLINK_STRING, 0),
                 SD_VARLINK_DEFINE_INPUT(id,                      SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
                 SD_VARLINK_DEFINE_INPUT(service,                 SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
-                SD_VARLINK_DEFINE_INPUT(class,                   SD_VARLINK_STRING, 0),
+                SD_VARLINK_DEFINE_INPUT_BY_TYPE(class,            MachineClass, 0),
                 SD_VARLINK_FIELD_COMMENT("The leader PID as simple positive integer."),
                 SD_VARLINK_DEFINE_INPUT(leader,                  SD_VARLINK_INT,    SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("The leader PID as ProcessId structure. If both the leader and leaderProcessId parameters are specified they must reference the same process. Typically one would only specify one or the other however. It's generally recommended to specify leaderProcessId as it references a process in a robust way without risk of identifier recycling."),
@@ -61,7 +73,7 @@ static SD_VARLINK_DEFINE_METHOD(
                 Kill,
                 VARLINK_DEFINE_MACHINE_LOOKUP_AND_POLKIT_INPUT_FIELDS,
                 SD_VARLINK_FIELD_COMMENT("Identifier that specifies what precisely to send the signal to (either 'leader', 'supervisor', or 'all')."),
-                SD_VARLINK_DEFINE_INPUT(whom, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
+                SD_VARLINK_DEFINE_INPUT_BY_TYPE(whom, KillWhom, SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("Numeric UNIX signal integer."),
                 SD_VARLINK_DEFINE_INPUT(signal, SD_VARLINK_INT, 0));
 
@@ -78,7 +90,7 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
                 SD_VARLINK_FIELD_COMMENT("Name of the software that registered this machine"),
                 SD_VARLINK_DEFINE_OUTPUT(service, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("The class of this machine"),
-                SD_VARLINK_DEFINE_OUTPUT(class, SD_VARLINK_STRING, 0),
+                SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(class, MachineClass, 0),
                 SD_VARLINK_FIELD_COMMENT("Leader process PID of this machine"),
                 SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(leader, ProcessId, SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("Supervisor process PID of this machine"),
@@ -216,6 +228,10 @@ SD_VARLINK_DEFINE_INTERFACE(
                 &vl_type_ProcessId,
                 SD_VARLINK_SYMBOL_COMMENT("A timestamp object consisting of both CLOCK_REALTIME and CLOCK_MONOTONIC timestamps"),
                 &vl_type_Timestamp,
+                SD_VARLINK_SYMBOL_COMMENT("The class of a machine"),
+                &vl_type_MachineClass,
+                SD_VARLINK_SYMBOL_COMMENT("What to send a signal to in a machine"),
+                &vl_type_KillWhom,
                 SD_VARLINK_SYMBOL_COMMENT("A enum field allowing to gracefully get metadata"),
                 &vl_type_AcquireMetadata,
                 SD_VARLINK_SYMBOL_COMMENT("An address object"),
index 605a31452642aff9c6715c6470093f79eaaffe19..2f604c5acba11bb9bc867f775170fe616008b723 100644 (file)
@@ -4,3 +4,6 @@
 #include "sd-varlink-idl.h"
 
 extern const sd_varlink_interface vl_interface_io_systemd_Machine;
+
+extern const sd_varlink_symbol vl_type_MachineClass;
+extern const sd_varlink_symbol vl_type_KillWhom;
index 241e64748538b48b56c98f6d83bf978a095c3e85..fb0aac27f88644f3128346d4a6873340e6a20d68 100644 (file)
@@ -503,6 +503,10 @@ executables += [
         core_test_template + {
                 'sources' : files('test-varlink-idl-manager.c'),
         },
+        test_template + {
+                'sources' : files('test-varlink-idl-machine.c'),
+                'objects' : ['systemd-machined'],
+        },
         test_template + {
                 'sources' : files('test-watchdog.c'),
                 'type' : 'unsafe',
diff --git a/src/test/test-varlink-idl-machine.c b/src/test/test-varlink-idl-machine.c
new file mode 100644 (file)
index 0000000..1064545
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "machine.h"
+#include "tests.h"
+#include "test-varlink-idl-util.h"
+#include "varlink-io.systemd.Machine.h"
+
+TEST(machine_enums_idl) {
+        TEST_IDL_ENUM(MachineClass, machine_class, vl_type_MachineClass);
+        TEST_IDL_ENUM(KillWhom, kill_whom, vl_type_KillWhom);
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);