]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
properties: Skip value building for nominal case 43146/head
authorChris Down <chris@chrisdown.name>
Fri, 24 Jul 2026 23:18:27 +0000 (16:18 -0700)
committerChris Down <chris@chrisdown.name>
Sat, 1 Aug 2026 07:53:16 +0000 (00:53 -0700)
bus_message_print_all_properties() builds a PROP= string for every
property in the reply so that -p PROP=value filters can be matched
against it, but most queries never need this.

Take the normal `systemctl show` or `systemctl show UNIT` case. In that
case there is no filter. Even with `-p PROP` there is no value filter
since there is no value.

Avoid constructing the string entirely by comparing property names
directly against filter entries.

In my tests with a `systemctl show` over 160 units this brings the
instructions retired from 992.6M down to 960.5M, a reduction of 3.2%.

The same goes for property filters with units. When running:

    systemctl show -p UnitFileState -p ActiveState UNIT

...the instructions retired drops from 9.52M to 9.22M, a reduction of
3.2%. The output in each case is unchanged.

src/shared/bus-print-properties.c

index d2377ceb60b844db38aaf811176aabbc38a72683..b8a12bdb8be46909ae174d6aab7ab98cb495e9a7 100644 (file)
@@ -344,6 +344,34 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
         return 0;
 }
 
+static bool match_filter(char **filter, const char *name, const char **ret_expected_value) {
+        const char *expected_value = NULL;
+
+        assert(name);
+        assert(ret_expected_value);
+
+        if (!filter) {
+                *ret_expected_value = NULL;
+                return true;
+        }
+
+        STRV_FOREACH(f, filter) {
+                const char *p = startswith(*f, name);
+
+                if (!p)
+                        continue;
+                if (*p == '\0') {
+                        *ret_expected_value = NULL;
+                        return true;
+                }
+                if (*p == '=' && !expected_value)
+                        expected_value = p + 1;
+        }
+
+        *ret_expected_value = expected_value;
+        return expected_value != NULL;
+}
+
 int bus_message_print_all_properties(
                 sd_bus_message *m,
                 bus_message_print_t func,
@@ -360,7 +388,6 @@ int bus_message_print_all_properties(
                 return r;
 
         while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
-                _cleanup_free_ char *name_with_equal = NULL;
                 const char *name, *contents, *expected_value = NULL;
 
                 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
@@ -373,14 +400,7 @@ int bus_message_print_all_properties(
                                 return log_oom();
                 }
 
-                name_with_equal = strjoin(name, "=");
-                if (!name_with_equal)
-                        return log_oom();
-
-                if (!filter ||
-                    strv_contains(filter, name) ||
-                    (expected_value = strv_find_startswith(filter, name_with_equal))) {
-
+                if (match_filter(filter, name, &expected_value)) {
                         r = sd_bus_message_peek_type(m, NULL, &contents);
                         if (r < 0)
                                 return r;