]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
properties: Peek the variant value type once 43145/head
authorChris Down <chris@chrisdown.name>
Sat, 18 Jul 2026 22:18:27 +0000 (15:18 -0700)
committerChris Down <chris@chrisdown.name>
Fri, 31 Jul 2026 23:51:08 +0000 (16:51 -0700)
bus_message_print_all_properties() peeks the variant type, but then the
print callback and the default bus_print_property() each peek the value
type again, so there can be up to two redundant calls per property. Peek
it once up front and pass it through.

With this, in my tests `systemctl show` over 160 units decreases in
instructions retired from 1167.6M to 1155.7M, so about 1%.

src/login/loginctl.c
src/shared/bus-print-properties.c
src/shared/bus-print-properties.h
src/systemctl/systemctl-show.c
src/timedate/timedatectl.c

index 566f4db877d938a2c07ced0558d191c033fdd660..7d63e6b03bdc402bcfa042206d3cd7dc76991bf0 100644 (file)
@@ -793,18 +793,19 @@ static int print_seat_status_info(sd_bus *bus, const char *path) {
         return 0;
 }
 
-static int print_property(const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags) {
-        char type;
-        const char *contents;
+static int print_property(
+                const char *name,
+                const char *expected_value,
+                char type,
+                const char *contents,
+                sd_bus_message *m,
+                BusPrintPropertyFlags flags) {
+
         int r;
 
         assert(name);
         assert(m);
 
-        r = sd_bus_message_peek_type(m, &type, &contents);
-        if (r < 0)
-                return r;
-
         switch (type) {
 
         case SD_BUS_TYPE_STRUCT:
index d2377ceb60b844db38aaf811176aabbc38a72683..a7967cf957d539dde81753b6b91ef9111de36919 100644 (file)
@@ -58,18 +58,19 @@ int bus_print_property_valuef(const char *name, const char *expected_value, BusP
         return bus_print_property_value(name, expected_value, flags, s);
 }
 
-static int bus_print_property(const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags) {
-        char type;
-        const char *contents;
+static int bus_print_property(
+                const char *name,
+                const char *expected_value,
+                char type,
+                const char *contents,
+                sd_bus_message *m,
+                BusPrintPropertyFlags flags) {
+
         int r;
 
         assert(name);
         assert(m);
 
-        r = sd_bus_message_peek_type(m, &type, &contents);
-        if (r < 0)
-                return r;
-
         switch (type) {
 
         case SD_BUS_TYPE_STRING: {
@@ -389,10 +390,16 @@ int bus_message_print_all_properties(
                         if (r < 0)
                                 return r;
 
+                        char value_type;
+                        const char *value_contents;
+                        r = sd_bus_message_peek_type(m, &value_type, &value_contents);
+                        if (r < 0)
+                                return r;
+
                         if (func)
-                                r = func(name, expected_value, m, flags);
+                                r = func(name, expected_value, value_type, value_contents, m, flags);
                         if (!func || r == 0)
-                                r = bus_print_property(name, expected_value, m, flags);
+                                r = bus_print_property(name, expected_value, value_type, value_contents, m, flags);
                         if (r < 0)
                                 return r;
                         if (r == 0) {
index 88db8882bf8e7c128f31d8cf2c2ebb9af42dd025..03abcf537aae56beff495fe9f3bdc3d355bbc7b9 100644 (file)
@@ -8,7 +8,13 @@ typedef enum BusPrintPropertyFlags {
         BUS_PRINT_PROPERTY_SHOW_EMPTY = 1 << 1,  /* e.g. systemctl --all */
 } BusPrintPropertyFlags;
 
-typedef int (*bus_message_print_t) (const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags);
+typedef int (*bus_message_print_t) (
+                const char *name,
+                const char *expected_value,
+                char type,
+                const char *contents,
+                sd_bus_message *m,
+                BusPrintPropertyFlags flags);
 
 bool bus_property_is_timestamp(const char *name);
 
index 82b85688133653c10f4c5b45a1bdff2dfc2c7308..e6b3f0fe3b281df7c648f3efdd54d8f8fce961a0 100644 (file)
@@ -1169,9 +1169,14 @@ static int map_quota(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
         return 0;
 }
 
-static int print_property(const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags) {
-        char bus_type;
-        const char *contents;
+static int print_property(
+                const char *name,
+                const char *expected_value,
+                char type,
+                const char *contents,
+                sd_bus_message *m,
+                BusPrintPropertyFlags flags) {
+
         int r;
 
         assert(name);
@@ -1179,17 +1184,13 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
 
         /* This is a low-level property printer, see print_status_info() for the nicer output */
 
-        r = sd_bus_message_peek_type(m, &bus_type, &contents);
-        if (r < 0)
-                return r;
-
-        switch (bus_type) {
+        switch (type) {
 
         case SD_BUS_TYPE_INT32:
                 if (endswith(name, "ActionExitStatus")) {
                         int32_t i;
 
-                        r = sd_bus_message_read_basic(m, bus_type, &i);
+                        r = sd_bus_message_read_basic(m, type, &i);
                         if (r < 0)
                                 return r;
 
@@ -1202,7 +1203,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                 } else if (streq(name, "NUMAPolicy")) {
                         int32_t i;
 
-                        r = sd_bus_message_read_basic(m, bus_type, &i);
+                        r = sd_bus_message_read_basic(m, type, &i);
                         if (r < 0)
                                 return r;
 
@@ -1216,7 +1217,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                 if (bus_property_is_timestamp(name)) {
                         uint64_t timestamp;
 
-                        r = sd_bus_message_read_basic(m, bus_type, &timestamp);
+                        r = sd_bus_message_read_basic(m, type, &timestamp);
                         if (r < 0)
                                 return r;
 
@@ -1432,14 +1433,14 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                         return 1;
 
                 } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
-                        const char *type, *path;
+                        const char *entry_type, *path;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
-                                bus_print_property_valuef(name, expected_value, flags, "%s (%s)", path, type);
+                        while ((r = sd_bus_message_read(m, "(ss)", &entry_type, &path)) > 0)
+                                bus_print_property_valuef(name, expected_value, flags, "%s (%s)", path, entry_type);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
@@ -1450,14 +1451,14 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                         return 1;
 
                 } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
-                        const char *type, *path;
+                        const char *entry_type, *path;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
-                                bus_print_property_valuef(name, expected_value, flags, "%s (%s)", path, type);
+                        while ((r = sd_bus_message_read(m, "(ss)", &entry_type, &path)) > 0)
+                                bus_print_property_valuef(name, expected_value, flags, "%s (%s)", path, entry_type);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
index 2c9ab9b6fd77755236158c053d91f4d9f64ebd04..2d76488f90c9cb67a3a12cab7d9be5b6729e9662 100644 (file)
@@ -723,18 +723,19 @@ static int verb_timesync_status(int argc, char *argv[], uintptr_t _data, void *u
         return 0;
 }
 
-static int print_timesync_property(const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags) {
-        char type;
-        const char *contents;
+static int print_timesync_property(
+                const char *name,
+                const char *expected_value,
+                char type,
+                const char *contents,
+                sd_bus_message *m,
+                BusPrintPropertyFlags flags) {
+
         int r;
 
         assert(name);
         assert(m);
 
-        r = sd_bus_message_peek_type(m, &type, &contents);
-        if (r < 0)
-                return r;
-
         switch (type) {
 
         case SD_BUS_TYPE_STRUCT: