]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device-enumerator: use test_matches() more
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 8 Sep 2022 06:55:23 +0000 (15:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 8 Sep 2022 09:10:50 +0000 (18:10 +0900)
src/libsystemd/sd-device/device-enumerator.c

index ffed6fef9b4e2dc2e8560922095389953b0a5e65..fcb36f27dd32d899fcd912ee6aba400a699cddd9 100644 (file)
@@ -541,29 +541,70 @@ static int match_initialized(sd_device_enumerator *enumerator, sd_device *device
         return (enumerator->match_initialized == MATCH_INITIALIZED_NO) == (r == 0);
 }
 
+static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
+        assert(enumerator);
+
+        if (!subsystem)
+                return false;
+
+        return set_fnmatch(enumerator->match_subsystem, enumerator->nomatch_subsystem, subsystem);
+}
+
+typedef enum MatchFlag {
+        MATCH_SYSNAME     = 1u << 0,
+        MATCH_SUBSYSTEM   = 1u << 1,
+        MATCH_PARENT      = 1u << 2,
+        MATCH_TAG         = 1u << 3,
+
+        MATCH_ALL         = (1u << 4) - 1,
+} MatchFlag;
+
 static int test_matches(
                 sd_device_enumerator *enumerator,
                 sd_device *device,
-                bool ignore_parent_match) {
+                MatchFlag flags) {
 
         int r;
 
         assert(enumerator);
         assert(device);
 
-        /* Checks all matches, except for the sysname match (which the caller should check beforehand) */
+        if (FLAGS_SET(flags, MATCH_SYSNAME)) {
+                const char *sysname;
 
-        r = match_initialized(enumerator, device);
-        if (r <= 0)
-                return r;
+                r = sd_device_get_sysname(device, &sysname);
+                if (r < 0)
+                        return r;
+
+                if (!match_sysname(enumerator, sysname))
+                        return false;
+        }
 
-        if (!ignore_parent_match &&
+        if (FLAGS_SET(flags, MATCH_SUBSYSTEM)) {
+                const char *subsystem;
+
+                r = sd_device_get_subsystem(device, &subsystem);
+                if (r == -ENOENT)
+                        return false;
+                if (r < 0)
+                        return r;
+
+                if (!match_subsystem(enumerator, subsystem))
+                        return false;
+        }
+
+        if (FLAGS_SET(flags, MATCH_PARENT) &&
             !device_match_parent(device, enumerator->match_parent, NULL))
                 return false;
 
-        if (!match_tag(enumerator, device))
+        if (FLAGS_SET(flags, MATCH_TAG) &&
+            !match_tag(enumerator, device))
                 return false;
 
+        r = match_initialized(enumerator, device);
+        if (r <= 0)
+                return r;
+
         if (!match_property(enumerator, device))
                 return false;
 
@@ -573,19 +614,10 @@ static int test_matches(
         return true;
 }
 
-static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
-        assert(enumerator);
-
-        if (!subsystem)
-                return false;
-
-        return set_fnmatch(enumerator->match_subsystem, enumerator->nomatch_subsystem, subsystem);
-}
-
 static int enumerator_add_parent_devices(
                 sd_device_enumerator *enumerator,
                 sd_device *device,
-                bool ignore_parent_match) {
+                MatchFlag flags) {
 
         int k, r = 0;
 
@@ -593,8 +625,6 @@ static int enumerator_add_parent_devices(
         assert(device);
 
         for (;;) {
-                const char *ss, *usn;
-
                 k = sd_device_get_parent(device, &device);
                 if (k == -ENOENT) /* Reached the top? */
                         break;
@@ -603,27 +633,7 @@ static int enumerator_add_parent_devices(
                         break;
                 }
 
-                k = sd_device_get_subsystem(device, &ss);
-                if (k == -ENOENT) /* Has no subsystem? */
-                        continue;
-                if (k < 0) {
-                        r = k;
-                        break;
-                }
-
-                if (!match_subsystem(enumerator, ss))
-                        continue;
-
-                k = sd_device_get_sysname(device, &usn);
-                if (k < 0) {
-                        r = k;
-                        break;
-                }
-
-                if (!match_sysname(enumerator, usn))
-                        continue;
-
-                k = test_matches(enumerator, device, ignore_parent_match);
+                k = test_matches(enumerator, device, flags);
                 if (k < 0) {
                         r = k;
                         break;
@@ -644,7 +654,7 @@ static int enumerator_add_parent_devices(
 }
 
 int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device) {
-        return enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ true);
+        return enumerator_add_parent_devices(enumerator, device, MATCH_ALL & (~MATCH_PARENT));
 }
 
 static bool relevant_sysfs_subdir(const struct dirent *de) {
@@ -705,7 +715,7 @@ static int enumerator_scan_dir_and_add_devices(
                         continue;
                 }
 
-                k = test_matches(enumerator, device, /* ignore_parent_match = */ false);
+                k = test_matches(enumerator, device, MATCH_ALL & (~MATCH_SYSNAME)); /* sysname is already tested. */
                 if (k <= 0) {
                         if (k < 0)
                                 r = k;
@@ -719,7 +729,7 @@ static int enumerator_scan_dir_and_add_devices(
                 /* Also include all potentially matching parent devices in the enumeration. These are things
                  * like root busses — e.g. /sys/devices/pci0000:00/ or /sys/devices/pnp0/, which ar not
                  * linked from /sys/class/ or /sys/bus/, hence pick them up explicitly here. */
-                k = enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ false);
+                k = enumerator_add_parent_devices(enumerator, device, MATCH_ALL);
                 if (k < 0)
                         r = k;
         }
@@ -781,7 +791,6 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c
 
         FOREACH_DIRENT_ALL(de, dir, return -errno) {
                 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
-                const char *subsystem, *sysname;
                 int k;
 
                 if (de->d_name[0] == '.')
@@ -796,33 +805,11 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c
                         continue;
                 }
 
-                k = sd_device_get_subsystem(device, &subsystem);
-                if (k < 0) {
-                        if (k != -ENOENT)
-                                /* this is necessarily racy, so ignore missing devices */
-                                r = k;
-                        continue;
-                }
-
-                if (!match_subsystem(enumerator, subsystem))
-                        continue;
-
-                k = sd_device_get_sysname(device, &sysname);
-                if (k < 0) {
+                /* Generated from tag, hence not necessary to check tag again. */
+                k = test_matches(enumerator, device, MATCH_ALL & (~MATCH_TAG));
+                if (k < 0)
                         r = k;
-                        continue;
-                }
-
-                if (!match_sysname(enumerator, sysname))
-                        continue;
-
-                if (!device_match_parent(device, enumerator->match_parent, NULL))
-                        continue;
-
-                if (!match_property(enumerator, device))
-                        continue;
-
-                if (!device_match_sysattr(device, enumerator->match_sysattr, enumerator->nomatch_sysattr))
+                if (k <= 0)
                         continue;
 
                 k = device_enumerator_add_device(enumerator, device);
@@ -854,7 +841,6 @@ static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
 
 static int parent_add_child(sd_device_enumerator *enumerator, const char *path) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
-        const char *subsystem, *sysname;
         int r;
 
         r = sd_device_new_from_syspath(&device, path);
@@ -864,33 +850,11 @@ static int parent_add_child(sd_device_enumerator *enumerator, const char *path)
         else if (r < 0)
                 return r;
 
-        r = sd_device_get_subsystem(device, &subsystem);
-        if (r == -ENOENT)
-                return 0;
-        if (r < 0)
-                return r;
-
-        if (!match_subsystem(enumerator, subsystem))
-                return 0;
-
-        r = sd_device_get_sysname(device, &sysname);
-        if (r < 0)
-                return r;
-
-        if (!match_sysname(enumerator, sysname))
-                return 0;
-
-        if (!match_property(enumerator, device))
-                return 0;
-
-        if (!device_match_sysattr(device, enumerator->match_sysattr, enumerator->nomatch_sysattr))
-                return 0;
-
-        r = device_enumerator_add_device(enumerator, device);
-        if (r < 0)
+        r = test_matches(enumerator, device, MATCH_ALL & (~MATCH_PARENT));
+        if (r <= 0)
                 return r;
 
-        return 1;
+        return device_enumerator_add_device(enumerator, device);
 }
 
 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {