summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-08-08 23:19:49 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-08-09 01:17:03 +0900
commitb07131facff9a6937e595caa2c4f020586ba98a5 (patch)
treee2c7653d053ee5413ec97942ef1edbec7816fdfc
parent585f2035b37a073dcea5c61e26ccb869b1c43578 (diff)
downloadsystemd-b07131facff9a6937e595caa2c4f020586ba98a5.tar.gz
sd-device-enumerator: FOREACH_DEVICE_PROPERTY() does not provide NULL value
Hence, when sd_device_enumerator_add_match_property() called with NULL for value, then the filter always unmatches with the device.
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c28
-rw-r--r--src/libsystemd/sd-device/device-monitor.c2
-rw-r--r--src/libsystemd/sd-device/device-util.c4
-rw-r--r--src/libsystemd/sd-device/device-util.h2
4 files changed, 15 insertions, 21 deletions
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 1f18b843f2..01d45a941f 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -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;
}
}
diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c
index 98163058be..459dbdf4e4 100644
--- a/src/libsystemd/sd-device/device-monitor.c
+++ b/src/libsystemd/sd-device/device-monitor.c
@@ -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) {
diff --git a/src/libsystemd/sd-device/device-util.c b/src/libsystemd/sd-device/device-util.c
index e2209a0b60..3b8689e0d6 100644
--- a/src/libsystemd/sd-device/device-util.c
+++ b/src/libsystemd/sd-device/device-util.c
@@ -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. */
diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h
index 6dae8ef6f2..d9e9f1e8c4 100644
--- a/src/libsystemd/sd-device/device-util.h
+++ b/src/libsystemd/sd-device/device-util.h
@@ -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);