]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm: info: also show parent devices by --tree
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 14 Apr 2022 08:12:10 +0000 (17:12 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sun, 17 Apr 2022 19:27:33 +0000 (21:27 +0200)
man/udevadm.xml
src/libsystemd/sd-device/device-enumerator-private.h
src/libsystemd/sd-device/device-enumerator.c
src/udev/udevadm-info.c

index edb1fccc0c3c61ca4e32a806b1d23184e2080026..3a9b133d304694fbb93d2599187a124bea56c8e1 100644 (file)
           <term><option>--tree</option></term>
           <listitem>
             <para>Display a sysfs tree. This recursively iterates through the sysfs hierarchy and displays it
-            in a tree structure. If a path is specified only the subtree below that directory is
+            in a tree structure. If a path is specified only the subtree below and its parent directories are
             shown. This will show both device and subsystem items.</para>
           </listitem>
         </varlistentry>
index 11378d89376ba33c1282ff50de9d6e51ac08c581..5aaa384095e099dc3c24b384610a0b991b4cfb7d 100644 (file)
@@ -16,6 +16,7 @@ int device_enumerator_scan_devices(sd_device_enumerator *enumerator);
 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator);
 int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerator);
 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device);
+int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device);
 int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator, MatchInitializedType type);
 int device_enumerator_add_match_parent_incremental(sd_device_enumerator *enumerator, sd_device *parent);
 int device_enumerator_add_prioritized_subsystem(sd_device_enumerator *enumerator, const char *subsystem);
index 97f4ee356c6b658a87c5e80b37425fb689913966..757f7489271955451a0fbca6d7542f7bf711a42d 100644 (file)
@@ -549,7 +549,8 @@ static int match_initialized(sd_device_enumerator *enumerator, sd_device *device
 
 static int test_matches(
                 sd_device_enumerator *enumerator,
-                sd_device *device) {
+                sd_device *device,
+                bool ignore_parent_match) {
 
         int r;
 
@@ -562,7 +563,8 @@ static int test_matches(
         if (r <= 0)
                 return r;
 
-        if (!device_match_parent(device, enumerator->match_parent, NULL))
+        if (!ignore_parent_match &&
+            !device_match_parent(device, enumerator->match_parent, NULL))
                 return false;
 
         if (!match_tag(enumerator, device))
@@ -599,6 +601,71 @@ static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsys
         return false;
 }
 
+static int enumerator_add_parent_devices(
+                sd_device_enumerator *enumerator,
+                sd_device *device,
+                bool ignore_parent_match) {
+
+        int k, r = 0;
+
+        assert(enumerator);
+        assert(device);
+
+        for (;;) {
+                const char *ss, *usn;
+
+                k = sd_device_get_parent(device, &device);
+                if (k == -ENOENT) /* Reached the top? */
+                        break;
+                if (k < 0) {
+                        r = k;
+                        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);
+                if (k < 0) {
+                        r = k;
+                        break;
+                }
+                if (k == 0)
+                        continue;
+
+                k = device_enumerator_add_device(enumerator, device);
+                if (k < 0) {
+                        r = k;
+                        break;
+                }
+                if (k == 0) /* Exists already? Then no need to go further up. */
+                        break;
+        }
+
+        return r;
+}
+
+int device_enumerator_add_parent_devices(sd_device_enumerator *enumerator, sd_device *device) {
+        return enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ true);
+}
+
 static bool relevant_sysfs_subdir(const struct dirent *de) {
         assert(de);
 
@@ -639,7 +706,6 @@ static int enumerator_scan_dir_and_add_devices(
         FOREACH_DIRENT_ALL(de, dir, return -errno) {
                 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
                 char syspath[strlen(path) + 1 + strlen(de->d_name) + 1];
-                sd_device *upwards;
 
                 if (!relevant_sysfs_subdir(de))
                         continue;
@@ -658,7 +724,7 @@ static int enumerator_scan_dir_and_add_devices(
                         continue;
                 }
 
-                k = test_matches(enumerator, device);
+                k = test_matches(enumerator, device, /* ignore_parent_match = */ false);
                 if (k <= 0) {
                         if (k < 0)
                                 r = k;
@@ -672,50 +738,9 @@ 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. */
-                upwards = device;
-                for (;;) {
-                        const char *ss, *usn;
-
-                        k = sd_device_get_parent(upwards, &upwards);
-                        if (k == -ENOENT) /* Reached the top? */
-                                break;
-                        if (k < 0) {
-                                r = k;
-                                break;
-                        }
-
-                        k = sd_device_get_subsystem(upwards, &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(upwards, &usn);
-                        if (k < 0) {
-                                r = k;
-                                break;
-                        }
-
-                        if (!match_sysname(enumerator, usn))
-                                continue;
-
-                        k = test_matches(enumerator, upwards);
-                        if (k < 0)
-                                break;
-                        if (k == 0)
-                                continue;
-
-                        k = device_enumerator_add_device(enumerator, upwards);
-                        if (k < 0)
-                                r = k;
-                        else if (k == 0) /* Exists already? Then no need to go further up. */
-                                break;
-                }
+                k = enumerator_add_parent_devices(enumerator, device, /* ignore_parent_match = */ false);
+                if (k < 0)
+                        r = k;
         }
 
         return r;
index 4ee15592cbd968ad02ac5f13a4e66351679393ff..d76dda95f1682b3a4058da26ff7f0bdcc16cc8b6 100644 (file)
@@ -637,6 +637,13 @@ static int print_tree(sd_device* below) {
         if (r < 0)
                 return log_error_errno(r, "Failed to scan for devices and subsystems: %m");
 
+        if (below) {
+                /* This must be called after device_enumerator_scan_devices_and_subsystems(). */
+                r = device_enumerator_add_parent_devices(e, below);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to add parent devices: %m");
+        }
+
         assert_se(array = device_enumerator_get_devices(e, &n));
 
         if (n == 0) {