]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/bus-unit-util: add bus_dump_transient_settings() helper
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 29 May 2025 12:37:30 +0000 (14:37 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 3 Jul 2025 19:03:26 +0000 (21:03 +0200)
bus_append_unit_property() and associated functions accept a long list of
properties. But the specific names are only available through code. But it is
useful to be able to know the specific list of properties that is supported, in
particular for shell completions. Thus, add a way to list the properties that
are supported by the code.

In the future we could also turn this into a test for the documentation. For
various reasons, the list of properties listed in the docs is a partially
overlapping set. E.g. for service type, the pull request
https://github.com/systemd/systemd/pull/37661 creates a list with 212 entries,
and this code generates 7 entries less and 184 more. I didn't check all the
differences, but in the few cases I did, the list generated here was actually
correctly supported by 'systemd-run -p'.

A smoke test is added.

12 files changed:
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/rlimit-util.c
src/basic/rlimit-util.h
src/basic/unit-def.c
src/basic/unit-def.h
src/shared/bus-unit-util.c
src/shared/bus-unit-util.h
src/shared/condition.c
src/shared/condition.h
src/test/meson.build
src/test/test-bus-unit-util.c [new file with mode: 0644]

index c0ba6b9401004269908b2fb3b308129cb67bdf3c..54d845a87b19fffaff4bc5e651b51a111aeae63d 100644 (file)
@@ -2063,6 +2063,10 @@ static const char* const cgroup_io_limit_type_table[_CGROUP_IO_LIMIT_TYPE_MAX] =
 
 DEFINE_STRING_TABLE_LOOKUP(cgroup_io_limit_type, CGroupIOLimitType);
 
+void cgroup_io_limits_list(void) {
+        DUMP_STRING_TABLE(cgroup_io_limit_type, CGroupIOLimitType, _CGROUP_IO_LIMIT_TYPE_MAX);
+}
+
 static const char *const cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
         [CGROUP_CONTROLLER_CPU]                             = "cpu",
         [CGROUP_CONTROLLER_CPUACCT]                         = "cpuacct",
index 2dea0ebdc4894624d2836e81c54ba3cdd8bdf214..ac0c7d8c412253f013fb92c11021abec7b258cc2 100644 (file)
@@ -97,6 +97,7 @@ extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX];
 
 const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_;
 CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_;
+void cgroup_io_limits_list(void);
 
 /* Special values for the io.bfq.weight attribute */
 #define CGROUP_BFQ_WEIGHT_INVALID UINT64_MAX
index 803eaa09b267f34a57055a2e8b6ca0a5aa97ad7c..22fd86301c17c1a3090abbfa88b221087b28eb8c 100644 (file)
@@ -343,6 +343,11 @@ static const char* const rlimit_table[_RLIMIT_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
 
+void rlimits_list(const char *prefix) {
+        FOREACH_ELEMENT(field, rlimit_table)
+                printf("%s%s\n", strempty(prefix), *field);
+}
+
 int rlimit_from_string_harder(const char *s) {
         const char *suffix;
 
index 52ec8bd3203dee8691b34b2185c6512ac6d07820..8b600fe1d2a9bb5c095fe3d4eac1c4176baf320a 100644 (file)
@@ -10,6 +10,7 @@
 const char* rlimit_to_string(int i) _const_;
 int rlimit_from_string(const char *s) _pure_;
 int rlimit_from_string_harder(const char *s) _pure_;
+void rlimits_list(const char *prefix);
 
 int setrlimit_closest(int resource, const struct rlimit *rlim);
 int setrlimit_closest_all(const struct rlimit * const *rlim, int *which_failed);
index 8bc5f56532eb1ce7106c576564027212a19897df..f98cfd4ae18b914bc648defa330a71064eee0c00 100644 (file)
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <stdio.h>
+
 #include "alloc-util.h"
 #include "bus-label.h"
 #include "glyph-util.h"
@@ -331,6 +333,10 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
 
+void unit_types_list(void) {
+        DUMP_STRING_TABLE(unit_dependency, UnitDependency, _UNIT_DEPENDENCY_MAX);
+}
+
 static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
         [NOTIFY_NONE] = "none",
         [NOTIFY_MAIN] = "main",
index fd55950ea63ec85ede7f2f81aa8558b3bab10b2f..7664f2881ac5807baa603118a5485e6c02c2c0b2 100644 (file)
@@ -304,6 +304,7 @@ const char* unit_dbus_interface_from_name(const char *name);
 
 const char* unit_type_to_string(UnitType i) _const_;
 UnitType unit_type_from_string(const char *s) _pure_;
+void unit_types_list(void);
 
 const char* unit_load_state_to_string(UnitLoadState i) _const_;
 UnitLoadState unit_load_state_from_string(const char *s) _pure_;
index 6811c8fc4164c4e7eefdda6f08790609c5e5f18a..dafe652b56a0394200b26cc95cf864c6004c66c5 100644 (file)
@@ -1305,6 +1305,10 @@ static int bus_try_append_resource_limit(sd_bus_message *m, const char *field, c
         return 1;
 }
 
+static void dump_resource_limits(void) {
+        rlimits_list("Limit");
+}
+
 static int bus_append_string_with_ignore(sd_bus_message *m, const char *field, const char *eq) {
         int ignore = 0;
         const char *s = eq;
@@ -2271,6 +2275,11 @@ static int bus_try_append_condition(sd_bus_message *m, const char *field, const
                                         field, trigger, negate, p);
 }
 
+static void dump_conditions(void) {
+        condition_types_list();
+        assert_types_list();
+}
+
 static int bus_try_append_unit_dependency(sd_bus_message *m, const char *field, const char *eq) {
         if (unit_dependency_from_string(field) < 0)
                 return 0;
@@ -2281,6 +2290,7 @@ static int bus_try_append_unit_dependency(sd_bus_message *m, const char *field,
 typedef struct BusProperty {
         const char *name;
         int (*convert)(sd_bus_message *m, const char *field, const char *eq);
+        void (*dump)(void);
 } BusProperty;
 
 static const BusProperty cgroup_properties[] = {
@@ -2347,7 +2357,7 @@ static const BusProperty cgroup_properties[] = {
         { "BlockIOWriteBandwidth",                 warn_deprecated                               },
         { "CPUAccounting",                         warn_deprecated                               },
 
-        { NULL,                                    bus_try_append_parse_cgroup_io_limit          },
+        { NULL, bus_try_append_parse_cgroup_io_limit, cgroup_io_limits_list                      },
         {}
 };
 
@@ -2501,7 +2511,7 @@ static const BusProperty execute_properties[] = {
         { "ProtectHostname",                       bus_append_protect_hostname                   },
         { "ProtectHostnameEx",                     bus_append_protect_hostname                   },
 
-        { NULL,                                    bus_try_append_resource_limit                 },
+        { NULL, bus_try_append_resource_limit,     dump_resource_limits                          },
         {}
 };
 
@@ -2726,8 +2736,8 @@ static const BusProperty unit_properties[] = {
         { "WantsMountsFor",                        bus_append_strv                               },
         { "Markers",                               bus_append_strv                               },
 
-        { NULL,                                    bus_try_append_unit_dependency                },
-        { NULL,                                    bus_try_append_condition                      },
+        { NULL, bus_try_append_unit_dependency,    unit_types_list                               },
+        { NULL, bus_try_append_condition,          dump_conditions                               },
         {}
 };
 
@@ -2855,6 +2865,24 @@ int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char
         return 0;
 }
 
+void bus_dump_transient_settings(UnitType t) {
+        assert(t >= 0 && t < _UNIT_TYPE_MAX);
+
+        for (const BusProperty** tables = ASSERT_PTR(unit_type_properties[t]); *tables; tables++)
+                for (const BusProperty *item = *tables; item->convert; item++) {
+                        assert(item->name || item->dump);
+
+                        /* Do not print deprecated names */
+                        if (item->convert == warn_deprecated)
+                                continue;
+
+                        if (item->name)
+                                puts(item->name);
+                        else
+                                item->dump();
+                }
+}
+
 int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref, bool allow_pidfd) {
         assert(m);
 
index c6e02a01b4007c6184ff09e691523ff21ea722d5..c07a704414a967e79f9a6ee10b1717cf4a910780 100644 (file)
@@ -51,3 +51,5 @@ int unit_freezer_new(const char *name, UnitFreezer **ret);
 
 int unit_freezer_freeze(UnitFreezer *f);
 int unit_freezer_thaw(UnitFreezer *f);
+
+void bus_dump_transient_settings(UnitType t);
index 14318667ec638bed92c7fec729e92fee8b641a07..25c38f374b6213c6b575b4793b1f9f705026d3c9 100644 (file)
@@ -1402,6 +1402,10 @@ ConditionType condition_type_from_string(const char *s) {
         return _condition_type_from_string(s);
 }
 
+void condition_types_list(void) {
+        DUMP_STRING_TABLE(_condition_type, ConditionType, _CONDITION_TYPE_MAX);
+}
+
 static const char* const _assert_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_ARCHITECTURE]             = "AssertArchitecture",
         [CONDITION_FIRMWARE]                 = "AssertFirmware",
@@ -1453,6 +1457,10 @@ ConditionType assert_type_from_string(const char *s) {
         return _assert_type_from_string(s);
 }
 
+void assert_types_list(void) {
+        DUMP_STRING_TABLE(_assert_type, ConditionType, _CONDITION_TYPE_MAX);
+}
+
 static const char* const condition_result_table[_CONDITION_RESULT_MAX] = {
         [CONDITION_UNTESTED]  = "untested",
         [CONDITION_SUCCEEDED] = "succeeded",
index a06d2a89d15ae76fbfc23d30995e7919731328e7..c25b9643b90b679fbaca0a013c9a37188398a01c 100644 (file)
@@ -88,9 +88,11 @@ void condition_dump_list(Condition *c, FILE *f, const char *prefix, condition_to
 
 const char* condition_type_to_string(ConditionType t) _const_;
 ConditionType condition_type_from_string(const char *s) _pure_;
+void condition_types_list(void);
 
 const char* assert_type_to_string(ConditionType t) _const_;
 ConditionType assert_type_from_string(const char *s) _pure_;
+void assert_types_list(void);
 
 const char* condition_result_to_string(ConditionResult r) _const_;
 ConditionResult condition_result_from_string(const char *s) _pure_;
index 6bb9e3f40dde5e1b517ffc058958094280eecd58..286fcac5c7eaf79ba82dc9113f1757b76b83acd2 100644 (file)
@@ -56,6 +56,7 @@ simple_tests += files(
         'test-blockdev-util.c',
         'test-bootspec.c',
         'test-build-path.c',
+        'test-bus-unit-util.c',
         'test-bus-util.c',
         'test-calendarspec.c',
         'test-cgroup-util.c',
diff --git a/src/test/test-bus-unit-util.c b/src/test/test-bus-unit-util.c
new file mode 100644 (file)
index 0000000..a1f0104
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "bus-unit-util.h"
+#include "unit-def.h"
+#include "tests.h"
+
+TEST(bus_dump_transient_settings) {
+        /* -1 is for generic unit, natural numbers are for specific unit types */
+        for (UnitType t = 0; t < _UNIT_TYPE_MAX; t++) {
+                log_info("==================== %s ====================", t < 0 ? "unit" : unit_type_to_string(t));
+                bus_dump_transient_settings(t);
+        }
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);