From: Yu Watanabe Date: Sun, 27 Mar 2022 14:38:36 +0000 (+0900) Subject: sd-device: introduce sd_device_new_from_devname() X-Git-Tag: v251-rc2~231^2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e418f9658b9e9803945de5686d5ab0d42eb2dfb6;p=thirdparty%2Fsystemd.git sd-device: introduce sd_device_new_from_devname() and sd_device_new_from_path() which takes devname or syspath. --- diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 2773d28b4bb..0066894d547 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -773,4 +773,6 @@ global: LIBSYSTEMD_251 { global: sd_id128_to_uuid_string; + sd_device_new_from_devname; + sd_device_new_from_path; } LIBSYSTEMD_250; diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 19bf01abc71..c7389c8a3b5 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -415,6 +415,46 @@ _public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st return sd_device_new_from_devnum(ret, type, st->st_rdev); } +_public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) { + struct stat st; + + assert_return(ret, -EINVAL); + assert_return(devname, -EINVAL); + + /* This function actually accepts both devlinks and devnames, i.e. both symlinks and device + * nodes below /dev/. */ + + /* Also ignore when the specified path is "/dev". */ + if (isempty(path_startswith(devname, "/dev"))) + return -EINVAL; + + if (device_path_parse_major_minor(devname, NULL, NULL) >= 0) { + _cleanup_free_ char *syspath = NULL; + + /* Let's shortcut when "/dev/block/maj:min" or "/dev/char/maj:min" is specified. + * In that case, we directly convert the path to syspath, hence it is not necessary + * that the specified path exists. So, this works fine without udevd being running. */ + + syspath = path_join("/sys", devname); + return sd_device_new_from_syspath(ret, syspath); + } + + if (stat(devname, &st) < 0) + return ERRNO_IS_DEVICE_ABSENT(errno) ? -ENODEV : -errno; + + return sd_device_new_from_stat_rdev(ret, &st); +} + +_public_ int sd_device_new_from_path(sd_device **ret, const char *path) { + assert_return(ret, -EINVAL); + assert_return(path, -EINVAL); + + if (path_startswith(path, "/dev")) + return sd_device_new_from_devname(ret, path); + + return sd_device_new_from_syspath(ret, path); +} + int device_set_devtype(sd_device *device, const char *devtype) { _cleanup_free_ char *t = NULL; int r; diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h index 189a110ea0d..2ac670b08cd 100644 --- a/src/systemd/sd-device.h +++ b/src/systemd/sd-device.h @@ -62,6 +62,8 @@ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum); int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname); int sd_device_new_from_device_id(sd_device **ret, const char *id); int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st); +int sd_device_new_from_devname(sd_device **ret, const char *devname); +int sd_device_new_from_path(sd_device **ret, const char *path); int sd_device_new_from_ifname(sd_device **ret, const char *ifname); int sd_device_new_from_ifindex(sd_device **ret, int ifindex);