chiark / gitweb /
sd-device: enumerator - fix matching on properties and sysattrs
[elogind.git] / src / libsystemd / sd-device / device-enumerator.c
index eb637f5a572457a0b9dc202f307475c6f7206fe3..71f605c5fc339da219c417a477c0ca1cf0646eda 100644 (file)
@@ -52,7 +52,7 @@ struct sd_device_enumerator {
         Set *match_sysname;
         Set *match_tag;
         sd_device *match_parent;
         Set *match_sysname;
         Set *match_tag;
         sd_device *match_parent;
-        bool match_is_initialized;
+        bool match_allow_uninitialized;
 };
 
 _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
 };
 
 _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
@@ -250,10 +250,20 @@ _public_ int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumera
         return 0;
 }
 
         return 0;
 }
 
-_public_ int sd_device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
+_public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator) {
         assert_return(enumerator, -EINVAL);
 
         assert_return(enumerator, -EINVAL);
 
-        enumerator->match_is_initialized = true;
+        enumerator->match_allow_uninitialized = true;
+
+        enumerator->scan_uptodate = false;
+
+        return 0;
+}
+
+int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
+        assert_return(enumerator, -EINVAL);
+
+        enumerator->match_allow_uninitialized = false;
 
         enumerator->scan_uptodate = false;
 
 
         enumerator->scan_uptodate = false;
 
@@ -364,11 +374,11 @@ static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
         assert(enumerator);
         assert(device);
 
         assert(enumerator);
         assert(device);
 
-        HASHMAP_FOREACH_KEY(sysattr, value, enumerator->nomatch_sysattr, i)
+        HASHMAP_FOREACH_KEY(value, sysattr, enumerator->nomatch_sysattr, i)
                 if (match_sysattr_value(device, sysattr, value))
                         return false;
 
                 if (match_sysattr_value(device, sysattr, value))
                         return false;
 
-        HASHMAP_FOREACH_KEY(sysattr, value, enumerator->match_sysattr, i)
+        HASHMAP_FOREACH_KEY(value, sysattr, enumerator->match_sysattr, i)
                 if (!match_sysattr_value(device, sysattr, value))
                         return false;
 
                 if (!match_sysattr_value(device, sysattr, value))
                         return false;
 
@@ -386,7 +396,7 @@ static bool match_property(sd_device_enumerator *enumerator, sd_device *device)
         if (hashmap_isempty(enumerator->match_property))
                 return true;
 
         if (hashmap_isempty(enumerator->match_property))
                 return true;
 
-        HASHMAP_FOREACH_KEY(property, value, enumerator->match_property, i) {
+        HASHMAP_FOREACH_KEY(value, property, enumerator->match_property, i) {
                 const char *property_dev, *value_dev;
 
                 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
                 const char *property_dev, *value_dev;
 
                 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
@@ -494,8 +504,10 @@ static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator,
 
                 k = sd_device_new_from_syspath(&device, syspath);
                 if (k < 0) {
 
                 k = sd_device_new_from_syspath(&device, syspath);
                 if (k < 0) {
-                        log_debug_errno(k, "device-enumerator: failed to create device from syspath %s: %m", syspath);
-                        r = k;
+                        if (k != -ENODEV)
+                                /* this is necessarily racey, so ignore missing devices */
+                                r = k;
+
                         continue;
                 }
 
                         continue;
                 }
 
@@ -527,7 +539,7 @@ static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator,
                  * might not store a database, and have no way to find out
                  * for all other types of devices.
                  */
                  * might not store a database, and have no way to find out
                  * for all other types of devices.
                  */
-                if (enumerator->match_is_initialized &&
+                if (!enumerator->match_allow_uninitialized &&
                     !initialized &&
                     (major(devnum) > 0 || ifindex > 0))
                         continue;
                     !initialized &&
                     (major(devnum) > 0 || ifindex > 0))
                         continue;
@@ -639,7 +651,10 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c
 
                 k = sd_device_new_from_device_id(&device, dent->d_name);
                 if (k < 0) {
 
                 k = sd_device_new_from_device_id(&device, dent->d_name);
                 if (k < 0) {
-                        r = k;
+                        if (k != -ENODEV)
+                                /* this is necessarily racy, so ignore missing devices */
+                                r = k;
+
                         continue;
                 }
 
                         continue;
                 }
 
@@ -702,7 +717,8 @@ static int parent_add_child(sd_device_enumerator *enumerator, const char *path)
         int r;
 
         r = sd_device_new_from_syspath(&device, path);
         int r;
 
         r = sd_device_new_from_syspath(&device, path);
-        if (r == -ENOENT)
+        if (r == -ENODEV)
+                /* this is necessarily racy, so ignore missing devices */
                 return 0;
         else if (r < 0)
                 return r;
                 return 0;
         else if (r < 0)
                 return r;
@@ -755,9 +771,9 @@ static int parent_crawl_children(sd_device_enumerator *enumerator, const char *p
                 if (dent->d_type != DT_DIR)
                         continue;
 
                 if (dent->d_type != DT_DIR)
                         continue;
 
-                k = asprintf(&child, "%s/%s", path, dent->d_name);
-                if (k < 0)
-                        return -errno;
+                child = strjoin(path, "/", dent->d_name, NULL);
+                if (!child)
+                        return -ENOMEM;
 
                 k = parent_add_child(enumerator, child);
                 if (k < 0)
 
                 k = parent_add_child(enumerator, child);
                 if (k < 0)