]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device-enumerator: FOREACH_DEVICE_PROPERTY() does not provide NULL value
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 8 Aug 2022 14:19:49 +0000 (23:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 8 Aug 2022 16:17:03 +0000 (01:17 +0900)
Hence, when sd_device_enumerator_add_match_property() called with NULL
for value, then the filter always unmatches with the device.

src/libsystemd/sd-device/device-enumerator.c
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-device/device-util.c
src/libsystemd/sd-device/device-util.h

index 1f18b843f21753b4489798afaa6b8efdb6b1bbbf..01d45a941f98db97ff23185e6fba69a98ab8bf24 100644 (file)
@@ -157,7 +157,7 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
         else
                 hashmap = &enumerator->nomatch_sysattr;
 
-        r = update_match_strv(hashmap, sysattr, value);
+        r = update_match_strv(hashmap, sysattr, value, /* clear_on_null = */ true);
         if (r <= 0)
                 return r;
 
@@ -172,9 +172,7 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
         assert_return(enumerator, -EINVAL);
         assert_return(property, -EINVAL);
 
-        /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
-         * multiple times with the same property but different value. */
-        r = hashmap_put_strdup_full(&enumerator->match_property, &trivial_hash_ops_free_free, property, value);
+        r = update_match_strv(&enumerator->match_property, property, value, /* clear_on_null = */ false);
         if (r <= 0)
                 return r;
 
@@ -464,29 +462,25 @@ int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *de
 }
 
 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
-        const char *property;
-        const char *value;
+        const char *property_pattern;
+        char * const *value_patterns;
 
         assert(enumerator);
         assert(device);
 
+        /* Unlike device_match_sysattr(), this accepts device that has at least one matching property. */
+
         if (hashmap_isempty(enumerator->match_property))
                 return true;
 
-        HASHMAP_FOREACH_KEY(value, property, enumerator->match_property) {
-                const char *property_dev, *value_dev;
-
-                FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
-                        if (fnmatch(property, property_dev, 0) != 0)
-                                continue;
-
-                        if (!value && !value_dev)
-                                return true;
+        HASHMAP_FOREACH_KEY(value_patterns, property_pattern, enumerator->match_property) {
+                const char *property, *value;
 
-                        if (!value || !value_dev)
+                FOREACH_DEVICE_PROPERTY(device, property, value) {
+                        if (fnmatch(property_pattern, property, 0) != 0)
                                 continue;
 
-                        if (fnmatch(value, value_dev, 0) == 0)
+                        if (strv_fnmatch(value_patterns, value))
                                 return true;
                 }
         }
index 98163058be5d6c2aeed72a27d7e4ec8e8f86ae5a..459dbdf4e49eb2263aae83956f5b7dbe82bad235 100644 (file)
@@ -787,7 +787,7 @@ _public_ int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, co
                 hashmap = &m->nomatch_sysattr_filter;
 
         /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
-        return update_match_strv(hashmap, sysattr, value);
+        return update_match_strv(hashmap, sysattr, value, /* clear_on_null = */ true);
 }
 
 _public_ int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match) {
index e2209a0b60956eeb92fd4d827e3298e96684ff04..3b8689e0d656225679948bd72785e29ebb38bfcc 100644 (file)
@@ -5,7 +5,7 @@
 #include "device-util.h"
 #include "path-util.h"
 
-int update_match_strv(Hashmap **match_strv, const char *key, const char *value) {
+int update_match_strv(Hashmap **match_strv, const char *key, const char *value, bool clear_on_null) {
         char **strv;
         int r;
 
@@ -17,7 +17,7 @@ int update_match_strv(Hashmap **match_strv, const char *key, const char *value)
                 if (!value) {
                         char **v;
 
-                        if (strv_isempty(strv))
+                        if (strv_isempty(strv) || !clear_on_null)
                                 return 0;
 
                         /* Accept all value. Clear previous assignment. */
index 6dae8ef6f2f2b7dbea353828757e6921964e0aa0..d9e9f1e8c4a0a8581b8144ed08a2e97d8522f52f 100644 (file)
@@ -82,6 +82,6 @@
 #define log_device_warning_errno(device, error, ...) log_device_full_errno(device, LOG_WARNING, error, __VA_ARGS__)
 #define log_device_error_errno(device, error, ...)   log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__)
 
-int update_match_strv(Hashmap **match_strv, const char *key, const char *value);
+int update_match_strv(Hashmap **match_strv, const char *key, const char *value, bool clear_on_null);
 bool device_match_sysattr(sd_device *device, Hashmap *match_sysattr, Hashmap *nomatch_sysattr);
 bool device_match_parent(sd_device *device, Set *match_parent, Set *nomatch_parent);