From b6854081ffb26c32a8d1440346f9ee5b9d2f1e57 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 10 Dec 2018 11:46:21 +0100 Subject: [PATCH] udevadm: allow a .device unit to be specified for query and trigger This is convenient when working with device units in systemd. Instead of converting the systemd unit name to a path to feed to udevadm, udevadm info|trigger can be called directly on the unit name. The man page is reworked a bit to describe the modern syntax with positional arguments first. It's just simpler to use than the positional options. --- man/udevadm.xml | 53 ++++++++++++++++++++--------------------- src/udev/udevadm-info.c | 2 +- src/udev/udevadm-util.c | 25 ++++++++++++++----- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/man/udevadm.xml b/man/udevadm.xml index a63a92cef2..ac3198b1f8 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -76,39 +76,40 @@ udevadm info <arg choice="opt"><replaceable>options</replaceable></arg> - <arg choice="opt"><replaceable>devpath</replaceable>|<replaceable>file</replaceable></arg> + <arg choice="opt"><replaceable>devpath</replaceable>|<replaceable>file</replaceable>|<replaceable>unit</replaceable></arg> - Queries the udev database for device information - stored in the udev database. It can also query the properties - of a device from its sysfs representation to help creating udev - rules that match this device. + Query the udev database for device information. + + A positional argument should be used to specify a device. It may be a device name (in which case + it must start with /dev/), a sys path (in which case it must start with + /sys/), or a systemd device unit name (in which case it must end with + .device, see + systemd.device5). + + - Query the database for the specified type of device - data. It needs the or - to identify the specified device. + Query the database for the specified type of device data. Valid TYPEs are: name, symlink, path, property, all. + - The /sys path of the device to - query, e.g. - /sys/class/block/sda. - Note that this option usually is not very useful, since - udev can guess the type of the - argument, so udevadm info - --path=/class/block/sda is equivalent to - udevadm info /sys/class/block/sda. + The /sys path of the device to query, e.g. + /sys/class/block/sda. This option is an alternative to + the positional argument with a /sys/ prefix. udevadm info + --path=/class/block/sda is equivalent to udevadm info + /sys/class/block/sda. @@ -116,11 +117,9 @@ The name of the device node or a symlink to query, - e.g. /dev/sda. - Note that this option usually is not very useful, since - udev can guess the type of the - argument, so udevadm info --name=sda is - equivalent to udevadm info /dev/sda. + e.g. /dev/sda. This option is an alternative to the + positional argument with a /dev/ prefix. udevadm info + --name=sda is equivalent to udevadm info /dev/sda. @@ -179,17 +178,17 @@ - - In addition, an optional positional argument can be used - to specify a device name or a sys path. It must start with - /dev or /sys - respectively. udevadm trigger <arg choice="opt"><replaceable>options</replaceable></arg> - <arg choice="opt" rep="repeat"><replaceable>devpath</replaceable>|<replaceable>file</replaceable></arg> + devpath|file|unit + Request device events from the kernel. Primarily used to replay events at system coldplug time. + + Takes one or more device specifications as arguments. See the description of info + above. + diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index ff4cf4ec45..31a6291279 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -440,7 +440,7 @@ int info_main(int argc, char *argv[], void *userdata) { r = find_device(argv[optind], NULL, &device); if (r == -EINVAL) - return log_error_errno(r, "Bad argument \"%s\", an absolute path in /dev/ or /sys expected: %m", + return log_error_errno(r, "Bad argument \"%s\", expected an absolute path in /dev/ or /sys or a unit name: %m", argv[optind]); if (r < 0) return log_error_errno(r, "Unknown device \"%s\": %m", argv[optind]); diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c index ef0dc564ce..557982b23d 100644 --- a/src/udev/udevadm-util.c +++ b/src/udev/udevadm-util.c @@ -6,18 +6,31 @@ #include "device-private.h" #include "path-util.h" #include "udevadm-util.h" +#include "unit-name.h" int find_device(const char *id, const char *prefix, sd_device **ret) { - _cleanup_free_ char *buf = NULL; + _cleanup_free_ char *path = NULL; + int r; assert(id); assert(ret); - if (prefix && !path_startswith(id, prefix)) { - buf = path_join(prefix, id); - if (!buf) - return -ENOMEM; - id = buf; + if (prefix) { + if (!path_startswith(id, prefix)) { + id = path = path_join(prefix, id); + if (!path) + return -ENOMEM; + } + } else { + /* In cases where the argument is generic (no prefix specified), + * check if the argument looks like a device unit name. */ + if (unit_name_is_valid(id, UNIT_NAME_PLAIN) && + unit_name_to_type(id) == UNIT_DEVICE) { + r = unit_name_to_path(id, &path); + if (r < 0) + return log_debug_errno(r, "Failed to convert \"%s\" to a device path: %m", id); + id = path; + } } if (path_startswith(id, "/sys/")) -- 2.25.1