From: Yu Watanabe Date: Thu, 14 Apr 2022 08:12:10 +0000 (+0900) Subject: udevadm: info: also show parent devices by --tree X-Git-Tag: v251-rc2~111 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd4297e76128bfbb5a96fe5cabf736f3df2520e3;p=thirdparty%2Fsystemd.git udevadm: info: also show parent devices by --tree --- diff --git a/man/udevadm.xml b/man/udevadm.xml index edb1fccc0c3..3a9b133d304 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -165,7 +165,7 @@ 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. diff --git a/src/libsystemd/sd-device/device-enumerator-private.h b/src/libsystemd/sd-device/device-enumerator-private.h index 11378d89376..5aaa384095e 100644 --- a/src/libsystemd/sd-device/device-enumerator-private.h +++ b/src/libsystemd/sd-device/device-enumerator-private.h @@ -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); diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 97f4ee356c6..757f7489271 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -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; diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index 4ee15592cbd..d76dda95f16 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -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) {