diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index 03969d650dd..369a853072c 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -30,3 +30,30 @@ for (device = sd_device_enumerator_get_subsystem_first(enumerator); \ device; \ device = sd_device_enumerator_get_subsystem_next(enumerator)) + +#define log_device_full(device, level, error, ...) \ + ({ \ + const char *_sysname = NULL, *_subsystem = NULL; \ + sd_device *_d = (device); \ + int _level = (level), _error = (error); \ + \ + if (_d && _unlikely_(log_get_max_level() >= _level)) { \ + (void) sd_device_get_sysname(_d, &_sysname); \ + (void) sd_device_get_subsystem(_d, &_subsystem); \ + } \ + log_object_internal(_level, _error, __FILE__, __LINE__, __func__, \ + _sysname ? "DEVICE=" : NULL, _sysname, \ + _subsystem ? "SUBSYSTEM=" : NULL, _subsystem, ##__VA_ARGS__); \ + }) + +#define log_device_debug(link, ...) log_device_full(link, LOG_DEBUG, 0, ##__VA_ARGS__) +#define log_device_info(link, ...) log_device_full(link, LOG_INFO, 0, ##__VA_ARGS__) +#define log_device_notice(link, ...) log_device_full(link, LOG_NOTICE, 0, ##__VA_ARGS__) +#define log_device_warning(link, ...) log_device_full(link, LOG_WARNING, 0, ##__VA_ARGS__) +#define log_device_error(link, ...) log_device_full(link, LOG_ERR, 0, ##__VA_ARGS__) + +#define log_device_debug_errno(link, error, ...) log_device_full(link, LOG_DEBUG, error, ##__VA_ARGS__) +#define log_device_info_errno(link, error, ...) log_device_full(link, LOG_INFO, error, ##__VA_ARGS__) +#define log_device_notice_errno(link, error, ...) log_device_full(link, LOG_NOTICE, error, ##__VA_ARGS__) +#define log_device_warning_errno(link, error, ...) log_device_full(link, LOG_WARNING, error, ##__VA_ARGS__) +#define log_device_error_errno(link, error, ...) log_device_full(link, LOG_ERR, error, ##__VA_ARGS__) diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index a0da293b553..7ed4fbad788 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -26,7 +26,7 @@ #include "strxcpyx.h" #include "udev-builtin.h" -static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) { +static void print_property(sd_device *dev, bool test, const char *name, const char *value) { char s[256]; s[0] = '\0'; @@ -94,7 +94,7 @@ static void print_property(struct udev_device *dev, bool test, const char *name, } } -static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) { +static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) { #if defined(GPT_ROOT_NATIVE) && ENABLE_EFI @@ -182,6 +182,8 @@ static int probe_superblocks(blkid_probe pr) { struct stat st; int rc; + /* TODO: Return negative errno. */ + if (fstat(blkid_probe_get_fd(pr), &st)) return -errno; @@ -210,18 +212,13 @@ static int probe_superblocks(blkid_probe pr) { return blkid_do_safeprobe(pr); } -static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) { - const char *root_partition; - int64_t offset = 0; - bool noraid = false; - _cleanup_close_ int fd = -1; +static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) { + const char *devnode, *root_partition = NULL, *data, *name; _cleanup_(blkid_free_probep) blkid_probe pr = NULL; - const char *data; - const char *name; - int nvals; - int i; - int err = 0; - bool is_gpt = false; + bool noraid = false, is_gpt = false; + _cleanup_close_ int fd = -1; + int64_t offset = 0; + int nvals, i, r; static const struct option options[] = { { "offset", required_argument, NULL, 'o' }, @@ -238,13 +235,11 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t switch (option) { case 'o': - err = safe_atoi64(optarg, &offset); - if (err < 0) - goto out; - if (offset < 0) { - err = -ERANGE; - goto out; - } + r = safe_atoi64(optarg, &offset); + if (r < 0) + return r; + if (offset < 0) + return -ERANGE; break; case 'R': noraid = true; @@ -252,9 +247,10 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t } } + errno = 0; pr = blkid_new_probe(); if (!pr) - return EXIT_FAILURE; + return errno > 0 ? -errno : -ENOMEM; blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | @@ -264,27 +260,30 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t if (noraid) blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID); - fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC); - if (fd < 0) { - err = log_debug_errno(errno, "Failure opening block device %s: %m", udev_device_get_devnode(dev)); - goto out; - } + r = sd_device_get_devname(dev, &devnode); + if (r < 0) + return r; - err = blkid_probe_set_device(pr, fd, offset, 0); - if (err < 0) - goto out; + fd = open(devnode, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return log_debug_errno(errno, "Failure opening block device %s: %m", devnode); + + errno = 0; + r = blkid_probe_set_device(pr, fd, offset, 0); + if (r < 0) + return errno > 0 ? -errno : -ENOMEM; log_debug("probe %s %sraid offset=%"PRIi64, - udev_device_get_devnode(dev), + devnode, noraid ? "no" : "", offset); - err = probe_superblocks(pr); - if (err < 0) - goto out; + r = probe_superblocks(pr); + if (r < 0) + return r; /* If we are a partition then our parent passed on the root * partition UUID to us */ - root_partition = udev_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID"); + (void) sd_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID", &root_partition); nvals = blkid_probe_numof_values(pr); for (i = 0; i < nvals; i++) { @@ -306,11 +305,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t if (is_gpt) find_gpt_root(dev, pr, test); -out: - if (err < 0) - return EXIT_FAILURE; - - return EXIT_SUCCESS; + return 0; } const struct udev_builtin udev_builtin_blkid = { diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c index fa6c352c30c..4380eb0be43 100644 --- a/src/udev/udev-builtin-btrfs.c +++ b/src/udev/udev-builtin-btrfs.c @@ -15,25 +15,25 @@ #include "udev-builtin.h" #include "util.h" -static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) { +static int builtin_btrfs(sd_device *dev, int argc, char *argv[], bool test) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; - int err; + int r; if (argc != 3 || !streq(argv[1], "ready")) - return EXIT_FAILURE; + return -EINVAL; fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC); if (fd < 0) - return EXIT_FAILURE; + return -errno; strscpy(args.name, sizeof(args.name), argv[2]); - err = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); - if (err < 0) - return EXIT_FAILURE; + r = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); + if (r < 0) + return -errno; - udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(err == 0)); - return EXIT_SUCCESS; + udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(r == 0)); + return 0; } const struct udev_builtin udev_builtin_btrfs = { diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 1978fddd14f..3beb433589f 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +#include #include #include #include @@ -9,19 +10,18 @@ #include "alloc-util.h" #include "hwdb-util.h" -#include "libudev-private.h" #include "parse-util.h" #include "string-util.h" #include "udev-builtin.h" static sd_hwdb *hwdb; -int udev_builtin_hwdb_lookup(struct udev_device *dev, +int udev_builtin_hwdb_lookup(sd_device *dev, const char *prefix, const char *modalias, const char *filter, bool test) { _cleanup_free_ char *lookup = NULL; const char *key, *value; - int n = 0; + int n = 0, r; if (!hwdb) return -ENOENT; @@ -37,22 +37,21 @@ int udev_builtin_hwdb_lookup(struct udev_device *dev, if (filter && fnmatch(filter, key, FNM_NOESCAPE) != 0) continue; - if (udev_builtin_add_property(dev, test, key, value) < 0) - return -ENOMEM; + r = udev_builtin_add_property(dev, test, key, value); + if (r < 0) + return r; n++; } return n; } -static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { +static const char *modalias_usb(sd_device *dev, char *s, size_t size) { const char *v, *p; uint16_t vn, pn; - v = udev_device_get_sysattr_value(dev, "idVendor"); - if (!v) + if (sd_device_get_sysattr_value(dev, "idVendor", &v) < 0) return NULL; - p = udev_device_get_sysattr_value(dev, "idProduct"); - if (!p) + if (sd_device_get_sysattr_value(dev, "idProduct", &p) < 0) return NULL; if (safe_atoux16(v, &vn) < 0) return NULL; @@ -62,10 +61,10 @@ static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) { return s; } -static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device *srcdev, +static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev, const char *subsystem, const char *prefix, const char *filter, bool test) { - struct udev_device *d; + sd_device *d; char s[16]; bool last = false; int r = 0; @@ -75,21 +74,21 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device if (!srcdev) srcdev = dev; - for (d = srcdev; d && !last; d = udev_device_get_parent(d)) { - const char *dsubsys; - const char *modalias = NULL; + for (d = srcdev; d; ) { + const char *dsubsys, *devtype, *modalias = NULL; - dsubsys = udev_device_get_subsystem(d); - if (!dsubsys) - continue; + if (sd_device_get_subsystem(d, &dsubsys) < 0) + goto next; /* look only at devices of a specific subsystem */ if (subsystem && !streq(dsubsys, subsystem)) - continue; + goto next; - modalias = udev_device_get_property_value(d, "MODALIAS"); + (void) sd_device_get_property_value(d, "MODALIAS", &modalias); - if (streq(dsubsys, "usb") && streq_ptr(udev_device_get_devtype(d), "usb_device")) { + if (streq(dsubsys, "usb") && + sd_device_get_devtype(d, &devtype) >= 0 && + streq(devtype, "usb_device")) { /* if the usb_device does not have a modalias, compose one */ if (!modalias) modalias = modalias_usb(d, s, sizeof(s)); @@ -99,17 +98,23 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device } if (!modalias) - continue; + goto next; r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test); if (r > 0) break; + + if (last) + break; +next: + if (sd_device_get_parent(d, &d) < 0) + break; } return r; } -static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) { +static int builtin_hwdb(sd_device *dev, int argc, char *argv[], bool test) { static const struct option options[] = { { "filter", required_argument, NULL, 'f' }, { "device", required_argument, NULL, 'd' }, @@ -121,10 +126,11 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te const char *device = NULL; const char *subsystem = NULL; const char *prefix = NULL; - _cleanup_(udev_device_unrefp) struct udev_device *srcdev = NULL; + _cleanup_(sd_device_unrefp) sd_device *srcdev = NULL; + int r; if (!hwdb) - return EXIT_FAILURE; + return -EINVAL; for (;;) { int option; @@ -153,22 +159,17 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te } /* query a specific key given as argument */ - if (argv[optind]) { - if (udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, test) > 0) - return EXIT_SUCCESS; - return EXIT_FAILURE; - } + if (argv[optind]) + return udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, test); /* read data from another device than the device we will store the data */ if (device) { - srcdev = udev_device_new_from_device_id(NULL, device); - if (!srcdev) - return EXIT_FAILURE; + r = sd_device_new_from_device_id(&srcdev, device); + if (r < 0) + return r; } - if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0) - return EXIT_SUCCESS; - return EXIT_FAILURE; + return udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test); } /* called at udev startup and reload */ diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 4252a9a696e..900c8150581 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -46,7 +46,7 @@ static inline int abs_size_mm(const struct input_absinfo *absinfo) { return (absinfo->maximum - absinfo->minimum) / absinfo->resolution; } -static void extract_info(struct udev_device *dev, const char *devpath, bool test) { +static void extract_info(sd_device *dev, const char *devpath, bool test) { char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)]; struct input_absinfo xabsinfo = {}, yabsinfo = {}; _cleanup_close_ int fd = -1; @@ -71,12 +71,12 @@ static void extract_info(struct udev_device *dev, const char *devpath, bool test /* * Read a capability attribute and return bitmask. - * @param dev udev_device + * @param dev sd_device * @param attr sysfs attribute name (e. g. "capabilities/key") * @param bitmask: Output array which has a sizeof of bitmask_size */ -static void get_cap_mask(struct udev_device *dev, - struct udev_device *pdev, const char* attr, +static void get_cap_mask(sd_device *dev, + sd_device *pdev, const char* attr, unsigned long *bitmask, size_t bitmask_size, bool test) { const char *v; @@ -85,8 +85,8 @@ static void get_cap_mask(struct udev_device *dev, char* word; unsigned long val; - v = udev_device_get_sysattr_value(pdev, attr); - v = strempty(v); + if (sd_device_get_sysattr_value(pdev, attr, &v) < 0) + v = ""; xsprintf(text, "%s", v); log_debug("%s raw kernel attribute: %s", attr, text); @@ -126,7 +126,7 @@ static void get_cap_mask(struct udev_device *dev, } /* pointer devices */ -static bool test_pointers(struct udev_device *dev, +static bool test_pointers(sd_device *dev, const unsigned long* bitmask_ev, const unsigned long* bitmask_abs, const unsigned long* bitmask_key, @@ -248,7 +248,7 @@ static bool test_pointers(struct udev_device *dev, } /* key like devices */ -static bool test_key(struct udev_device *dev, +static bool test_key(sd_device *dev, const unsigned long* bitmask_ev, const unsigned long* bitmask_key, bool test) { @@ -299,8 +299,8 @@ static bool test_key(struct udev_device *dev, return ret; } -static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) { - struct udev_device *pdev; +static int builtin_input_id(sd_device *dev, int argc, char *argv[], bool test) { + sd_device *pdev; unsigned long bitmask_ev[NBITS(EV_MAX)]; unsigned long bitmask_abs[NBITS(ABS_MAX)]; unsigned long bitmask_key[NBITS(KEY_MAX)]; @@ -314,9 +314,18 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo /* walk up the parental chain until we find the real input device; the * argument is very likely a subdevice of this, like eventN */ - pdev = dev; - while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL) - pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); + for (pdev = dev; pdev; ) { + const char *s; + + if (sd_device_get_sysattr_value(pdev, "capabilities/ev", &s) >= 0) + break; + + if (sd_device_get_parent_with_subsystem_devtype(pdev, "input", NULL, &pdev) >= 0) + continue; + + pdev = NULL; + break; + } if (pdev) { /* Use this as a flag that input devices were detected, so that this @@ -340,12 +349,12 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo } - devnode = udev_device_get_devnode(dev); - sysname = udev_device_get_sysname(dev); - if (devnode && sysname && startswith(sysname, "event")) + if (sd_device_get_devname(dev, &devnode) >= 0 && + sd_device_get_sysname(dev, &sysname) >= 0 && + startswith(sysname, "event")) extract_info(dev, devnode, test); - return EXIT_SUCCESS; + return 0; } const struct udev_builtin udev_builtin_input_id = { diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c index 0e026697c12..728daa02d88 100644 --- a/src/udev/udev-builtin-keyboard.c +++ b/src/udev/udev-builtin-keyboard.c @@ -8,6 +8,7 @@ #include #include +#include "device-util.h" #include "fd-util.h" #include "parse-util.h" #include "stdio-util.h" @@ -18,25 +19,25 @@ static const struct key_name *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len); #include "keyboard-keys-from-name.h" -static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) { - struct udev_device *atkbd; +static int install_force_release(sd_device *dev, const unsigned *release, unsigned release_count) { + sd_device *atkbd; const char *cur; char codes[4096]; char *s; size_t l; unsigned i; - int ret; + int r; assert(dev); assert(release); - atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL); - if (!atkbd) - return -ENODEV; + r = sd_device_get_parent_with_subsystem_devtype(dev, "serio", NULL, &atkbd); + if (r < 0) + return r; - cur = udev_device_get_sysattr_value(atkbd, "force_release"); - if (!cur) - return -ENODEV; + r = sd_device_get_sysattr_value(atkbd, "force_release", &cur); + if (r < 0) + return r; s = codes; l = sizeof(codes); @@ -49,14 +50,14 @@ static int install_force_release(struct udev_device *dev, const unsigned *releas l = strpcpyf(&s, l, ",%u", release[i]); log_debug("keyboard: updating force-release list with '%s'", codes); - ret = udev_device_set_sysattr_value(atkbd, "force_release", codes); - if (ret < 0) - log_error_errno(ret, "Error writing force-release attribute: %m"); - return ret; + r = sd_device_set_sysattr_value(atkbd, "force_release", codes); + if (r < 0) + return log_error_errno(r, "Error writing force-release attribute: %m"); + + return 0; } -static void map_keycode(int fd, const char *devnode, int scancode, const char *keycode) -{ +static void map_keycode(int fd, const char *devnode, int scancode, const char *keycode) { struct { unsigned scan; unsigned key; @@ -139,36 +140,37 @@ static void override_abs(int fd, const char *devnode, log_error_errno(errno, "Unable to EVIOCSABS device \"%s\"", devnode); } -static void set_trackpoint_sensitivity(struct udev_device *dev, const char *value) -{ - struct udev_device *pdev; +static int set_trackpoint_sensitivity(sd_device *dev, const char *value) { + sd_device *pdev; char val_s[DECIMAL_STR_MAX(int)]; + const char *devnode; int r, val_i; assert(dev); assert(value); + r = sd_device_get_devname(dev, &devnode); + if (r < 0) + return log_error_errno(r, "Failed to get devname: %m"); + /* The sensitivity sysfs attr belongs to the serio parent device */ - pdev = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL); - if (!pdev) { - log_warning("Failed to get serio parent for '%s'", udev_device_get_devnode(dev)); - return; - } + r = sd_device_get_parent_with_subsystem_devtype(dev, "serio", NULL, &pdev); + if (r < 0) + return log_warning_errno(r, "Failed to get serio parent for '%s': %m", devnode); r = safe_atoi(value, &val_i); - if (r < 0) { - log_error("Unable to parse POINTINGSTICK_SENSITIVITY '%s' for '%s'", value, udev_device_get_devnode(dev)); - return; - } else if (val_i < 0 || val_i > 255) { - log_error("POINTINGSTICK_SENSITIVITY %d outside range [0..255] for '%s' ", val_i, udev_device_get_devnode(dev)); - return; - } + if (r < 0) + return log_error_errno(r, "Unable to parse POINTINGSTICK_SENSITIVITY '%s' for '%s': %m", value, devnode); + else if (val_i < 0 || val_i > 255) + return log_error_errno(ERANGE, "POINTINGSTICK_SENSITIVITY %d outside range [0..255] for '%s'", val_i, devnode); xsprintf(val_s, "%d", val_i); - r = udev_device_set_sysattr_value(pdev, "sensitivity", val_s); + r = sd_device_set_sysattr_value(pdev, "sensitivity", val_s); if (r < 0) - log_error_errno(r, "Failed to write 'sensitivity' attribute for '%s': %m", udev_device_get_devnode(pdev)); + return log_error_errno(r, "Failed to write 'sensitivity' attribute for '%s': %m", devnode); + + return 0; } static int open_device(const char *devnode) { @@ -181,27 +183,26 @@ static int open_device(const char *devnode) { return fd; } -static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) { - struct udev_list_entry *entry; +static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) { unsigned release[1024]; unsigned release_count = 0; _cleanup_close_ int fd = -1; - const char *node; - int has_abs = -1; + const char *node, *key, *value; + int has_abs = -1, r; - node = udev_device_get_devnode(dev); - if (!node) { - log_error("No device node for \"%s\"", udev_device_get_syspath(dev)); - return EXIT_FAILURE; + r = sd_device_get_devname(dev, &node); + if (r < 0) { + const char *s = NULL; + + (void) sd_device_get_syspath(dev, &s); + return log_error_errno(r, "No device node for \"%s\": %m", strnull(s)); } - udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) { - const char *key; + FOREACH_DEVICE_PROPERTY(dev, key, value) { char *endptr; - key = udev_list_entry_get_name(entry); if (startswith(key, "KEYBOARD_KEY_")) { - const char *keycode; + const char *keycode = value; unsigned scancode; /* KEYBOARD_KEY_= */ @@ -211,8 +212,6 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo continue; } - keycode = udev_list_entry_get_value(entry); - /* a leading '!' needs a force-release entry */ if (keycode[0] == '!') { keycode++; @@ -228,7 +227,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo if (fd == -1) { fd = open_device(node); if (fd < 0) - return EXIT_FAILURE; + return fd; } map_keycode(fd, node, scancode, keycode); @@ -245,7 +244,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo if (fd == -1) { fd = open_device(node); if (fd < 0) - return EXIT_FAILURE; + return fd; } if (has_abs == -1) { @@ -253,10 +252,8 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo int rc; rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits); - if (rc < 0) { - log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node); - return EXIT_FAILURE; - } + if (rc < 0) + return log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node); has_abs = !!(bits & (1 << EV_ABS)); if (!has_abs) @@ -266,16 +263,16 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo if (!has_abs) continue; - override_abs(fd, node, evcode, udev_list_entry_get_value(entry)); + override_abs(fd, node, evcode, value); } else if (streq(key, "POINTINGSTICK_SENSITIVITY")) - set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry)); + set_trackpoint_sensitivity(dev, value); } /* install list of force-release codes */ if (release_count > 0) install_force_release(dev, release, release_count); - return EXIT_SUCCESS; + return 0; } const struct udev_builtin udev_builtin_keyboard = { diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index 6ed0210ee60..d8575b72bd5 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -21,7 +21,7 @@ _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *fi log_internalv(priority, 0, file, line, fn, format, args); } -static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { +static int builtin_kmod(sd_device *dev, int argc, char *argv[], bool test) { int i; if (!ctx) @@ -29,13 +29,13 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te if (argc < 3 || !streq(argv[1], "load")) { log_error("%s: expected: load ", argv[0]); - return EXIT_FAILURE; + return -EINVAL; } for (i = 2; argv[i]; i++) (void) module_load_and_warn(ctx, argv[i], false); - return EXIT_SUCCESS; + return 0; } /* called at udev startup and reload */ diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 28d15cc1006..afcf60933f9 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -106,7 +106,6 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" -#include "libudev-private.h" #include "parse-util.h" #include "stdio-util.h" #include "string-util.h" @@ -133,7 +132,7 @@ struct netnames { uint8_t mac[6]; bool mac_valid; - struct udev_device *pcidev; + sd_device *pcidev; char pci_slot[IFNAMSIZ]; char pci_path[IFNAMSIZ]; char pci_onboard[IFNAMSIZ]; @@ -147,94 +146,111 @@ struct netnames { }; struct virtfn_info { - struct udev_device *physfn_pcidev; + sd_device *physfn_pcidev; char suffix[IFNAMSIZ]; }; /* skip intermediate virtio devices */ -static struct udev_device *skip_virtio(struct udev_device *dev) { - struct udev_device *parent = dev; +static sd_device *skip_virtio(sd_device *dev) { + sd_device *parent; /* there can only ever be one virtio bus per parent device, so we can - safely ignore any virtio buses. see - */ - while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent))) - parent = udev_device_get_parent(parent); + * safely ignore any virtio buses. see + * http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html */ + for (parent = dev; parent; ) { + const char *subsystem; + + if (sd_device_get_subsystem(parent, &subsystem) < 0) + break; + + if (!streq(subsystem, "virtio")) + break; + + if (sd_device_get_parent(parent, &parent) < 0) + return NULL; + } + return parent; } -static int get_virtfn_info(struct udev_device *dev, struct netnames *names, struct virtfn_info *vf_info) { - const char *physfn_link_file; +static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn_info *ret) { + _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; + const char *physfn_link_file, *syspath; _cleanup_free_ char *physfn_pci_syspath = NULL; _cleanup_free_ char *virtfn_pci_syspath = NULL; struct dirent *dent; _cleanup_closedir_ DIR *dir = NULL; - struct virtfn_info vf_info_local = {}; + char suffix[IFNAMSIZ]; int r; + assert(dev); + assert(names); + assert(ret); + + r = sd_device_get_syspath(names->pcidev, &syspath); + if (r < 0) + return r; + /* Check if this is a virtual function. */ - physfn_link_file = strjoina(udev_device_get_syspath(names->pcidev), "/physfn"); + physfn_link_file = strjoina(syspath, "/physfn"); r = chase_symlinks(physfn_link_file, NULL, 0, &physfn_pci_syspath); if (r < 0) return r; /* Get physical function's pci device. */ - vf_info_local.physfn_pcidev = udev_device_new_from_syspath(NULL, physfn_pci_syspath); - if (!vf_info_local.physfn_pcidev) - return -ENOENT; + r = sd_device_new_from_syspath(&physfn_pcidev, physfn_pci_syspath); + if (r < 0) + return r; /* Find the virtual function number by finding the right virtfn link. */ dir = opendir(physfn_pci_syspath); - if (!dir) { - r = -errno; - goto out_unref; - } + if (!dir) + return -errno; + FOREACH_DIRENT_ALL(dent, dir, break) { _cleanup_free_ char *virtfn_link_file = NULL; + if (!startswith(dent->d_name, "virtfn")) continue; + virtfn_link_file = strjoin(physfn_pci_syspath, "/", dent->d_name); - if (!virtfn_link_file) { - r = -ENOMEM; - goto out_unref; - } + if (!virtfn_link_file) + return -ENOMEM; + if (chase_symlinks(virtfn_link_file, NULL, 0, &virtfn_pci_syspath) < 0) continue; - if (streq(udev_device_get_syspath(names->pcidev), virtfn_pci_syspath)) { - if (!snprintf_ok(vf_info_local.suffix, sizeof(vf_info_local.suffix), "v%s", &dent->d_name[6])) { - r = -ENOENT; - goto out_unref; - } + + if (streq(syspath, virtfn_pci_syspath)) { + if (!snprintf_ok(suffix, sizeof(suffix), "v%s", &dent->d_name[6])) + return -ENOENT; + break; } } - if (isempty(vf_info_local.suffix)) { - r = -ENOENT; - goto out_unref; - } - *vf_info = vf_info_local; - return 0; + if (isempty(suffix)) + return -ENOENT; -out_unref: - udev_device_unref(vf_info_local.physfn_pcidev); - return r; + ret->physfn_pcidev = TAKE_PTR(physfn_pcidev); + strncpy(ret->suffix, suffix, sizeof(ret->suffix)); + + return 0; } /* retrieve on-board index number and label from firmware */ -static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { +static int dev_pci_onboard(sd_device *dev, struct netnames *names) { unsigned long idx, dev_port = 0; - const char *attr, *port_name; + const char *attr, *port_name = NULL; size_t l; char *s; int r; /* ACPI _DSM — device specific method for naming a PCI or PCI Express device */ - attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); - /* SMBIOS type 41 — Onboard Devices Extended Information */ - if (!attr) - attr = udev_device_get_sysattr_value(names->pcidev, "index"); - if (!attr) - return -ENOENT; + if (sd_device_get_sysattr_value(names->pcidev, "acpi_index", &attr) < 0) { + /* SMBIOS type 41 — Onboard Devices Extended Information */ + r = sd_device_get_sysattr_value(names->pcidev, "index", &attr); + if (r < 0) + return r; + } r = safe_atolu(attr, &idx); if (r < 0) @@ -248,12 +264,11 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { return -ENOENT; /* kernel provided port index for multiple ports on a single PCI function */ - attr = udev_device_get_sysattr_value(dev, "dev_port"); - if (attr) + if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) dev_port = strtoul(attr, NULL, 10); /* kernel provided front panel port name for multiple port PCI device */ - port_name = udev_device_get_sysattr_value(dev, "phys_port_name"); + (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name); s = names->pci_onboard; l = sizeof(names->pci_onboard); @@ -265,18 +280,22 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { if (l == 0) names->pci_onboard[0] = '\0'; - names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label"); + if (sd_device_get_sysattr_value(names->pcidev, "label", &names->pci_onboard_label) < 0) + names->pci_onboard_label = NULL; return 0; } /* read the 256 bytes PCI configuration space to check the multi-function bit */ -static bool is_pci_multifunction(struct udev_device *dev) { +static bool is_pci_multifunction(sd_device *dev) { _cleanup_close_ int fd = -1; - const char *filename; + const char *filename, *syspath; uint8_t config[64]; - filename = strjoina(udev_device_get_syspath(dev), "/config"); + if (sd_device_get_syspath(dev, &syspath) < 0) + return false; + + filename = strjoina(syspath, "/config"); fd = open(filename, O_RDONLY | O_CLOEXEC); if (fd < 0) return false; @@ -284,30 +303,38 @@ static bool is_pci_multifunction(struct udev_device *dev) { return false; /* bit 0-6 header type, bit 7 multi/single function device */ - if ((config[PCI_HEADER_TYPE] & 0x80) != 0) - return true; - - return false; + return config[PCI_HEADER_TYPE] & 0x80; } -static bool is_pci_ari_enabled(struct udev_device *dev) { - return streq_ptr(udev_device_get_sysattr_value(dev, "ari_enabled"), "1"); +static bool is_pci_ari_enabled(sd_device *dev) { + const char *a; + + if (sd_device_get_sysattr_value(dev, "ari_enabled", &a) < 0) + return false; + + return streq(a, "1"); } -static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { +static int dev_pci_slot(sd_device *dev, struct netnames *names) { unsigned long dev_port = 0; unsigned domain, bus, slot, func, hotplug_slot = 0; size_t l; char *s; - const char *attr, *port_name; - _cleanup_(udev_device_unrefp) struct udev_device *pci = NULL; - struct udev_device *hotplug_slot_dev; + const char *sysname, *attr, *port_name = NULL, *syspath; + _cleanup_(sd_device_unrefp) sd_device *pci = NULL; + sd_device *hotplug_slot_dev; char slots[PATH_MAX]; _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; + int r; - if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) + r = sd_device_get_sysname(names->pcidev, &sysname); + if (r < 0) + return r; + + if (sscanf(sysname, "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) return -ENOENT; + if (is_pci_ari_enabled(names->pcidev)) /* ARI devices support up to 256 functions on a single device ("slot"), and interpret the * traditional 5-bit slot and 3-bit function number as a single 8-bit function number, @@ -315,27 +342,24 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { func += slot * 8; /* kernel provided port index for multiple ports on a single PCI function */ - attr = udev_device_get_sysattr_value(dev, "dev_port"); - if (attr) { + if (sd_device_get_sysattr_value(dev, "dev_port", &attr) >= 0) { dev_port = strtoul(attr, NULL, 10); /* With older kernels IP-over-InfiniBand network interfaces sometimes erroneously * provide the port number in the 'dev_id' sysfs attribute instead of 'dev_port', * which thus stays initialized as 0. */ - if (dev_port == 0) { - attr = udev_device_get_sysattr_value(dev, "type"); - if (attr) { - unsigned long type = strtoul(attr, NULL, 10); - if (type == ARPHRD_INFINIBAND) { - attr = udev_device_get_sysattr_value(dev, "dev_id"); - if (attr) - dev_port = strtoul(attr, NULL, 16); - } - } + if (dev_port == 0 && + sd_device_get_sysattr_value(dev, "type", &attr) >= 0) { + unsigned long type; + + type = strtoul(attr, NULL, 10); + if (type == ARPHRD_INFINIBAND && + sd_device_get_sysattr_value(dev, "dev_id", &attr) >= 0) + dev_port = strtoul(attr, NULL, 16); } } /* kernel provided front panel port name for multiple port PCI device */ - port_name = udev_device_get_sysattr_value(dev, "phys_port_name"); + (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name); /* compose a name based on the raw kernel's PCI bus, slot numbers */ s = names->pci_path; @@ -353,11 +377,14 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { names->pci_path[0] = '\0'; /* ACPI _SUN — slot user number */ - pci = udev_device_new_from_subsystem_sysname(NULL, "subsystem", "pci"); - if (!pci) - return -ENOENT; + r = sd_device_new_from_subsystem_sysname(&pci, "subsystem", "pci"); + if (r < 0) + return r; - if (!snprintf_ok(slots, sizeof slots, "%s/slots", udev_device_get_syspath(pci))) + r = sd_device_get_syspath(pci, &syspath); + if (r < 0) + return r; + if (!snprintf_ok(slots, sizeof slots, "%s/slots", syspath)) return -ENAMETOOLONG; dir = opendir(slots); @@ -366,31 +393,33 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { hotplug_slot_dev = names->pcidev; while (hotplug_slot_dev) { + if (sd_device_get_sysname(hotplug_slot_dev, &sysname) < 0) + continue; + FOREACH_DIRENT_ALL(dent, dir, break) { unsigned i; - int r; char str[PATH_MAX]; _cleanup_free_ char *address = NULL; if (dent->d_name[0] == '.') continue; r = safe_atou_full(dent->d_name, 10, &i); - if (i < 1 || r < 0) + if (r < 0 || i <= 0) continue; + /* match slot address with device by stripping the function */ if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && - read_one_line_file(str, &address) >= 0) - /* match slot address with device by stripping the function */ - if (startswith(udev_device_get_sysname(hotplug_slot_dev), address)) - hotplug_slot = i; - - if (hotplug_slot > 0) + read_one_line_file(str, &address) >= 0 && + startswith(sysname, address)) { + hotplug_slot = i; break; + } } if (hotplug_slot > 0) break; + if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0) + break; rewinddir(dir); - hotplug_slot_dev = udev_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL); } if (hotplug_slot > 0) { @@ -412,24 +441,30 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { return 0; } -static int names_vio(struct udev_device *dev, struct netnames *names) { - struct udev_device *parent; +static int names_vio(sd_device *dev, struct netnames *names) { + sd_device *parent; unsigned busid, slotid, ethid; - const char *syspath; + const char *syspath, *subsystem; + int r; /* check if our direct parent is a VIO device with no other bus in-between */ - parent = udev_device_get_parent(dev); - if (!parent) - return -ENOENT; + r = sd_device_get_parent(dev, &parent); + if (r < 0) + return r; - if (!streq_ptr("vio", udev_device_get_subsystem(parent))) - return -ENOENT; + r = sd_device_get_subsystem(parent, &subsystem); + if (r < 0) + return r; + if (!streq("vio", subsystem)) + return -ENOENT; /* The devices' $DEVPATH number is tied to (virtual) hardware (slot id * selected in the HMC), thus this provides a reliable naming (e.g. * "/devices/vio/30000002/net/eth1"); we ignore the bus number, as * there should only ever be one bus, and then remove leading zeros. */ - syspath = udev_device_get_syspath(dev); + r = sd_device_get_syspath(dev, &syspath); + if (r < 0) + return r; if (sscanf(syspath, "/sys/devices/vio/%4x%4x/net/eth%u", &busid, &slotid, ðid) != 3) return -EINVAL; @@ -443,21 +478,28 @@ static int names_vio(struct udev_device *dev, struct netnames *names) { #define _PLATFORM_PATTERN4 "/sys/devices/platform/%4s%4x:%2x/net/eth%u" #define _PLATFORM_PATTERN3 "/sys/devices/platform/%3s%4x:%2x/net/eth%u" -static int names_platform(struct udev_device *dev, struct netnames *names, bool test) { - struct udev_device *parent; +static int names_platform(sd_device *dev, struct netnames *names, bool test) { + sd_device *parent; char vendor[5]; unsigned model, instance, ethid; - const char *syspath, *pattern, *validchars; + const char *syspath, *pattern, *validchars, *subsystem; + int r; /* check if our direct parent is a platform device with no other bus in-between */ - parent = udev_device_get_parent(dev); - if (!parent) - return -ENOENT; + r = sd_device_get_parent(dev, &parent); + if (r < 0) + return r; - if (!streq_ptr("platform", udev_device_get_subsystem(parent))) + r = sd_device_get_subsystem(parent, &subsystem); + if (r < 0) + return r; + + if (!streq("platform", subsystem)) return -ENOENT; - syspath = udev_device_get_syspath(dev); + r = sd_device_get_syspath(dev, &syspath); + if (r < 0) + return r; /* syspath is too short, to have a valid ACPI instance */ if (strlen(syspath) < sizeof _PLATFORM_TEST) @@ -493,15 +535,19 @@ static int names_platform(struct udev_device *dev, struct netnames *names, bool return 0; } -static int names_pci(struct udev_device *dev, struct netnames *names) { - struct udev_device *parent; +static int names_pci(sd_device *dev, struct netnames *names) { + sd_device *parent; struct netnames vf_names = {}; struct virtfn_info vf_info = {}; + const char *subsystem; + int r; assert(dev); assert(names); - parent = udev_device_get_parent(dev); + r = sd_device_get_parent(dev, &parent); + if (r < 0) + return r; /* skip virtio subsystem if present */ parent = skip_virtio(parent); @@ -509,13 +555,14 @@ static int names_pci(struct udev_device *dev, struct netnames *names) { return -ENOENT; /* check if our direct parent is a PCI device with no other bus in-between */ - if (streq_ptr("pci", udev_device_get_subsystem(parent))) { + if (sd_device_get_subsystem(parent, &subsystem) >= 0 && + streq("pci", subsystem)) { names->type = NET_PCI; names->pcidev = parent; } else { - names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL); - if (!names->pcidev) - return -ENOENT; + r = sd_device_get_parent_with_subsystem_devtype(dev, "pci", NULL, &names->pcidev); + if (r < 0) + return r; } if (get_virtfn_info(dev, names, &vf_info) >= 0) { @@ -535,32 +582,35 @@ static int names_pci(struct udev_device *dev, struct netnames *names) { if (strlen(vf_names.pci_path) + strlen(vf_info.suffix) < sizeof(names->pci_path)) strscpyl(names->pci_path, sizeof(names->pci_path), vf_names.pci_path, vf_info.suffix, NULL); - udev_device_unref(vf_info.physfn_pcidev); + sd_device_unref(vf_info.physfn_pcidev); } else { dev_pci_onboard(dev, names); dev_pci_slot(dev, names); } + return 0; } -static int names_usb(struct udev_device *dev, struct netnames *names) { - struct udev_device *usbdev; - char name[256]; - char *ports; - char *config; - char *interf; +static int names_usb(sd_device *dev, struct netnames *names) { + sd_device *usbdev; + char name[256], *ports, *config, *interf, *s; + const char *sysname; size_t l; - char *s; + int r; assert(dev); assert(names); - usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); - if (!usbdev) - return -ENOENT; + r = sd_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface", &usbdev); + if (r < 0) + return r; + + r = sd_device_get_sysname(usbdev, &sysname); + if (r < 0) + return r; /* get USB port number chain, configuration, interface */ - strscpy(name, sizeof(name), udev_device_get_sysname(usbdev)); + strscpy(name, sizeof(name), sysname); s = strchr(name, '-'); if (!s) return -EINVAL; @@ -599,19 +649,25 @@ static int names_usb(struct udev_device *dev, struct netnames *names) { return 0; } -static int names_bcma(struct udev_device *dev, struct netnames *names) { - struct udev_device *bcmadev; +static int names_bcma(sd_device *dev, struct netnames *names) { + sd_device *bcmadev; unsigned core; + const char *sysname; + int r; assert(dev); assert(names); - bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL); - if (!bcmadev) - return -ENOENT; + r = sd_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL, &bcmadev); + if (r < 0) + return r; + + r = sd_device_get_sysname(bcmadev, &sysname); + if (r < 0) + return r; /* bus num:core num */ - if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*u:%u", &core) != 1) + if (sscanf(sysname, "bcma%*u:%u", &core) != 1) return -EINVAL; /* suppress the common core == 0 */ if (core > 0) @@ -621,34 +677,41 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) { return 0; } -static int names_ccw(struct udev_device *dev, struct netnames *names) { - struct udev_device *cdev; +static int names_ccw(sd_device *dev, struct netnames *names) { + sd_device *cdev; const char *bus_id, *subsys; size_t bus_id_len; size_t bus_id_start; + int r; assert(dev); assert(names); /* Retrieve the associated CCW device */ - cdev = udev_device_get_parent(dev); + r = sd_device_get_parent(dev, &cdev); + if (r < 0) + return r; + /* skip virtio subsystem if present */ cdev = skip_virtio(cdev); if (!cdev) return -ENOENT; + r = sd_device_get_subsystem(cdev, &subsys); + if (r < 0) + return r; + /* Network devices are either single or grouped CCW devices */ - subsys = udev_device_get_subsystem(cdev); - if (!STRPTR_IN_SET(subsys, "ccwgroup", "ccw")) + if (!STR_IN_SET(subsys, "ccwgroup", "ccw")) return -ENOENT; /* Retrieve bus-ID of the CCW device. The bus-ID uniquely * identifies the network device on the Linux on System z channel * subsystem. Note that the bus-ID contains lowercase characters. */ - bus_id = udev_device_get_sysname(cdev); - if (!bus_id) - return -ENOENT; + r = sd_device_get_sysname(cdev, &bus_id); + if (r < 0) + return r; /* Check the length of the bus-ID. Rely on that the kernel provides * a correct bus-ID; alternatively, improve this check and parse and @@ -673,17 +736,19 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) { return 0; } -static int names_mac(struct udev_device *dev, struct netnames *names) { +static int names_mac(sd_device *dev, struct netnames *names) { const char *s; unsigned long i; unsigned a1, a2, a3, a4, a5, a6; + int r; /* Some kinds of devices tend to have hardware addresses * that are impossible to use in an iface name. */ - s = udev_device_get_sysattr_value(dev, "type"); - if (!s) - return EXIT_FAILURE; + r = sd_device_get_sysattr_value(dev, "type", &s); + if (r < 0) + return r; + i = strtoul(s, NULL, 0); switch (i) { /* The persistent part of a hardware address of an InfiniBand NIC @@ -696,16 +761,16 @@ static int names_mac(struct udev_device *dev, struct netnames *names) { } /* check for NET_ADDR_PERM, skip random MAC addresses */ - s = udev_device_get_sysattr_value(dev, "addr_assign_type"); - if (!s) - return EXIT_FAILURE; + r = sd_device_get_sysattr_value(dev, "addr_assign_type", &s); + if (r < 0) + return r; i = strtoul(s, NULL, 0); if (i != 0) return 0; - s = udev_device_get_sysattr_value(dev, "address"); - if (!s) - return -ENOENT; + r = sd_device_get_sysattr_value(dev, "address", &s); + if (r < 0) + return r; if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) return -EINVAL; @@ -724,7 +789,7 @@ static int names_mac(struct udev_device *dev, struct netnames *names) { } /* IEEE Organizationally Unique Identifier vendor string */ -static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) { +static int ieee_oui(sd_device *dev, struct netnames *names, bool test) { char str[32]; if (!names->mac_valid) @@ -739,21 +804,17 @@ static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) return 0; } -static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) { - const char *s; - const char *p; - unsigned long i; - const char *devtype; - const char *prefix = "en"; +static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) { + const char *s, *p, *devtype, *prefix = "en"; struct netnames names = {}; - int err; + unsigned long i; + int r; + + /* handle only ARPHRD_ETHER, ARPHRD_SLIP and ARPHRD_INFINIBAND devices */ + r = sd_device_get_sysattr_value(dev, "type", &s); + if (r < 0) + return r; - /* handle only ARPHRD_ETHER, ARPHRD_SLIP - * and ARPHRD_INFINIBAND devices - */ - s = udev_device_get_sysattr_value(dev, "type"); - if (!s) - return EXIT_FAILURE; i = strtoul(s, NULL, 0); switch (i) { case ARPHRD_ETHER: @@ -770,25 +831,24 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool } /* skip stacked devices, like VLANs, ... */ - s = udev_device_get_sysattr_value(dev, "ifindex"); - if (!s) - return EXIT_FAILURE; - p = udev_device_get_sysattr_value(dev, "iflink"); - if (!p) - return EXIT_FAILURE; + r = sd_device_get_sysattr_value(dev, "ifindex", &s); + if (r < 0) + return r; + r = sd_device_get_sysattr_value(dev, "iflink", &p); + if (r < 0) + return r; if (!streq(s, p)) return 0; - devtype = udev_device_get_devtype(dev); - if (devtype) { + if (sd_device_get_devtype(dev, &devtype) >= 0) { if (streq("wlan", devtype)) prefix = "wl"; else if (streq("wwan", devtype)) prefix = "ww"; } - err = names_mac(dev, &names); - if (err >= 0 && names.mac_valid) { + r = names_mac(dev, &names); + if (r >= 0 && names.mac_valid) { char str[IFNAMSIZ]; xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix, @@ -800,39 +860,35 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool } /* get path names for Linux on System z network devices */ - err = names_ccw(dev, &names); - if (err >= 0 && names.type == NET_CCW) { + if (names_ccw(dev, &names) >= 0 && names.type == NET_CCW) { char str[IFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.ccw_busid)) udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); - goto out; + return 0; } /* get ibmveth/ibmvnic slot-based names. */ - err = names_vio(dev, &names); - if (err >= 0 && names.type == NET_VIO) { + if (names_vio(dev, &names) >= 0 && names.type == NET_VIO) { char str[IFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.vio_slot)) udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); - goto out; + return 0; } /* get ACPI path names for ARM64 platform devices */ - err = names_platform(dev, &names, test); - if (err >= 0 && names.type == NET_PLATFORM) { + if (names_platform(dev, &names, test) >= 0 && names.type == NET_PLATFORM) { char str[IFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.platform_path)) udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); - goto out; + return 0; } /* get PCI based path names, we compose only PCI based paths */ - err = names_pci(dev, &names); - if (err < 0) - goto out; + if (names_pci(dev, &names) < 0) + return 0; /* plain PCI device */ if (names.type == NET_PCI) { @@ -853,12 +909,11 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool if (names.pci_slot[0] && snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_slot)) udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); - goto out; + return 0; } /* USB device */ - err = names_usb(dev, &names); - if (err >= 0 && names.type == NET_USB) { + if (names_usb(dev, &names) >= 0 && names.type == NET_USB) { char str[IFNAMSIZ]; if (names.pci_path[0] && @@ -868,12 +923,11 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool if (names.pci_slot[0] && snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_slot, names.usb_ports)) udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); - goto out; + return 0; } /* Broadcom bus */ - err = names_bcma(dev, &names); - if (err >= 0 && names.type == NET_BCMA) { + if (names_bcma(dev, &names) >= 0 && names.type == NET_BCMA) { char str[IFNAMSIZ]; if (names.pci_path[0] && @@ -883,10 +937,10 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool if (names.pci_slot[0] && snprintf(str, sizeof str, "%s%s%s", prefix, names.pci_slot, names.bcma_core)) udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); - goto out; + return 0; } -out: - return EXIT_SUCCESS; + + return 0; } const struct udev_builtin udev_builtin_net_id = { diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index 3384b76dc1c..d9a0acb63d9 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -1,14 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include "alloc-util.h" -#include "libudev-device-internal.h" #include "link-config.h" #include "log.h" +#include "string-util.h" #include "udev-builtin.h" static link_config_ctx *ctx = NULL; -static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv, bool test) { +static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool test) { _cleanup_free_ char *driver = NULL; const char *name = NULL; link_config *link; @@ -16,34 +16,35 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv if (argc > 1) { log_error("This program takes no arguments."); - return EXIT_FAILURE; + return -EINVAL; } - r = link_get_driver(ctx, dev->device, &driver); + r = link_get_driver(ctx, dev, &driver); if (r >= 0) udev_builtin_add_property(dev, test, "ID_NET_DRIVER", driver); - r = link_config_get(ctx, dev->device, &link); + r = link_config_get(ctx, dev, &link); if (r < 0) { - if (r == -ENOENT) { - log_debug("No matching link configuration found."); - return EXIT_SUCCESS; - } else { - log_error_errno(r, "Could not get link config: %m"); - return EXIT_FAILURE; - } + if (r == -ENOENT) + return log_debug_errno(r, "No matching link configuration found."); + + return log_error_errno(r, "Could not get link config: %m"); } - r = link_config_apply(ctx, link, dev->device, &name); - if (r < 0) - log_warning_errno(r, "Could not apply link config to %s, ignoring: %m", udev_device_get_sysname(dev)); + r = link_config_apply(ctx, link, dev, &name); + if (r < 0) { + const char *sysname = NULL; + + (void) sd_device_get_sysname(dev, &sysname); + log_warning_errno(r, "Could not apply link config to %s, ignoring: %m", strnull(sysname)); + } udev_builtin_add_property(dev, test, "ID_NET_LINK_FILE", link->filename); if (name) udev_builtin_add_property(dev, test, "ID_NET_NAME", name); - return EXIT_SUCCESS; + return 0; } static int builtin_net_setup_link_init(void) { diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 6bbce3c66c1..e8581a48697 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -56,57 +56,68 @@ static void path_prepend(char **path, const char *fmt, ...) { ** Linux only supports 32 bit luns. ** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details. */ -static void format_lun_number(struct udev_device *dev, char **path) { - unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10); +static int format_lun_number(sd_device *dev, char **path) { + const char *sysnum; + unsigned long lun; + int r; + r = sd_device_get_sysnum(dev, &sysnum); + if (r < 0) + return r; + if (!sysnum) + return -ENOENT; + + lun = strtoul(sysnum, NULL, 10); if (lun < 256) /* address method 0, peripheral device addressing with bus id of zero */ path_prepend(path, "lun-%lu", lun); else /* handle all other lun addressing methods by using a variant of the original lun format */ path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff); + + return 0; } -static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) { - struct udev_device *parent = dev; +static sd_device *skip_subsystem(sd_device *dev, const char *subsys) { + sd_device *parent; assert(dev); assert(subsys); - while (parent) { + for (parent = dev; ; ) { const char *subsystem; - subsystem = udev_device_get_subsystem(parent); - if (!streq_ptr(subsystem, subsys)) + if (sd_device_get_subsystem(parent, &subsystem) < 0) + break; + + if (!streq(subsystem, subsys)) break; dev = parent; - parent = udev_device_get_parent(parent); + if (sd_device_get_parent(dev, &parent) < 0) + break; } return dev; } -static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) { - struct udev_device *targetdev; - _cleanup_(udev_device_unrefp) struct udev_device *fcdev = NULL; - const char *port; +static sd_device *handle_scsi_fibre_channel(sd_device *parent, char **path) { + sd_device *targetdev; + _cleanup_(sd_device_unrefp) sd_device *fcdev = NULL; + const char *port, *sysname; _cleanup_free_ char *lun = NULL; assert(parent); assert(path); - targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); - if (!targetdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target", &targetdev) < 0) return NULL; - - fcdev = udev_device_new_from_subsystem_sysname(NULL, "fc_transport", udev_device_get_sysname(targetdev)); - if (!fcdev) + if (sd_device_get_sysname(targetdev, &sysname) < 0) return NULL; - - port = udev_device_get_sysattr_value(fcdev, "port_name"); - if (!port) + if (sd_device_new_from_subsystem_sysname(&fcdev, "fc_transport", sysname) < 0) + return NULL; + if (sd_device_get_sysattr_value(fcdev, "port_name", &port) < 0) return NULL; format_lun_number(parent, &lun); @@ -114,31 +125,24 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, return parent; } -static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, char **path) { - struct udev_device *targetdev, *target_parent; - _cleanup_(udev_device_unrefp) struct udev_device *sasdev = NULL; - const char *sas_address; +static sd_device *handle_scsi_sas_wide_port(sd_device *parent, char **path) { + sd_device *targetdev, *target_parent; + _cleanup_(sd_device_unrefp) sd_device *sasdev = NULL; + const char *sas_address, *sysname; _cleanup_free_ char *lun = NULL; assert(parent); assert(path); - - targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); - if (!targetdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target", &targetdev) < 0) return NULL; - - target_parent = udev_device_get_parent(targetdev); - if (!target_parent) + if (sd_device_get_parent(targetdev, &target_parent) < 0) return NULL; - - sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", - udev_device_get_sysname(target_parent)); - if (!sasdev) + if (sd_device_get_sysname(target_parent, &sysname) < 0) return NULL; - - sas_address = udev_device_get_sysattr_value(sasdev, "sas_address"); - if (!sas_address) + if (sd_device_new_from_subsystem_sysname(&sasdev, "sas_device", sysname) < 0) + return NULL; + if (sd_device_get_sysattr_value(sasdev, "sas_address", &sas_address) < 0) return NULL; format_lun_number(parent, &lun); @@ -146,43 +150,35 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, return parent; } -static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) -{ - struct udev_device *targetdev, *target_parent, *port, *expander; - _cleanup_(udev_device_unrefp) struct udev_device - *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL; +static sd_device *handle_scsi_sas(sd_device *parent, char **path) { + sd_device *targetdev, *target_parent, *port, *expander; + _cleanup_(sd_device_unrefp) sd_device *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL; const char *sas_address = NULL; const char *phy_id; - const char *phy_count; + const char *phy_count, *sysname; _cleanup_free_ char *lun = NULL; assert(parent); assert(path); - - targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); - if (!targetdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target", &targetdev) < 0) return NULL; - - target_parent = udev_device_get_parent(targetdev); - if (!target_parent) + if (sd_device_get_parent(targetdev, &target_parent) < 0) + return NULL; + if (sd_device_get_sysname(target_parent, &sysname) < 0) return NULL; - /* Get sas device */ - target_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", udev_device_get_sysname(target_parent)); - if (!target_sasdev) + if (sd_device_new_from_subsystem_sysname(&target_sasdev, "sas_device", sysname) < 0) return NULL; - /* The next parent is sas port */ - port = udev_device_get_parent(target_parent); - if (!port) + if (sd_device_get_parent(target_parent, &port) < 0) + return NULL; + if (sd_device_get_sysname(port, &sysname) < 0) return NULL; - /* Get port device */ - port_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_port", udev_device_get_sysname(port)); - - phy_count = udev_device_get_sysattr_value(port_sasdev, "num_phys"); - if (!phy_count) + if (sd_device_new_from_subsystem_sysname(&port_sasdev, "sas_port", sysname) < 0) + return NULL; + if (sd_device_get_sysattr_value(port_sasdev, "num_phys", &phy_count) < 0) return NULL; /* Check if we are simple disk */ @@ -190,22 +186,20 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa return handle_scsi_sas_wide_port(parent, path); /* Get connected phy */ - phy_id = udev_device_get_sysattr_value(target_sasdev, "phy_identifier"); - if (!phy_id) + if (sd_device_get_sysattr_value(target_sasdev, "phy_identifier", &phy_id) < 0) return NULL; /* The port's parent is either hba or expander */ - expander = udev_device_get_parent(port); - if (!expander) + if (sd_device_get_parent(port, &expander) < 0) return NULL; + if (sd_device_get_sysname(expander, &sysname) < 0) + return NULL; /* Get expander device */ - expander_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", udev_device_get_sysname(expander)); - if (expander_sasdev) { - /* Get expander's address */ - sas_address = udev_device_get_sysattr_value(expander_sasdev, "sas_address"); - if (!sas_address) - return NULL; + if (sd_device_new_from_subsystem_sysname(&expander_sasdev, "sas_device", sysname) >= 0) { + /* Get expander's address */ + if (sd_device_get_sysattr_value(expander_sasdev, "sas_address", &sas_address) < 0) + return NULL; } format_lun_number(parent, &lun); @@ -217,44 +211,43 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa return parent; } -static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) { - struct udev_device *transportdev; - _cleanup_(udev_device_unrefp) struct udev_device - *sessiondev = NULL, *conndev = NULL; +static sd_device *handle_scsi_iscsi(sd_device *parent, char **path) { + sd_device *transportdev; + _cleanup_(sd_device_unrefp) sd_device *sessiondev = NULL, *conndev = NULL; const char *target, *connname, *addr, *port; _cleanup_free_ char *lun = NULL; + const char *sysname, *sysnum; assert(parent); assert(path); - /* find iscsi session */ - transportdev = parent; - for (;;) { - transportdev = udev_device_get_parent(transportdev); - if (!transportdev) + for (transportdev = parent; ; ) { + + if (sd_device_get_parent(transportdev, &transportdev) < 0) return NULL; - if (startswith(udev_device_get_sysname(transportdev), "session")) + if (sd_device_get_sysname(transportdev, &sysname) < 0) + return NULL; + if (startswith(sysname, "session")) break; } /* find iscsi session device */ - sessiondev = udev_device_new_from_subsystem_sysname(NULL, "iscsi_session", udev_device_get_sysname(transportdev)); - if (!sessiondev) + if (sd_device_new_from_subsystem_sysname(&sessiondev, "iscsi_session", sysname) < 0) return NULL; - target = udev_device_get_sysattr_value(sessiondev, "targetname"); - if (!target) + if (sd_device_get_sysattr_value(sessiondev, "targetname", &target) < 0) return NULL; - connname = strjoina("connection", udev_device_get_sysnum(transportdev), ":0"); - conndev = udev_device_new_from_subsystem_sysname(NULL, "iscsi_connection", connname); - if (!conndev) + if (sd_device_get_sysnum(transportdev, &sysnum) < 0 || !sysnum) + return NULL; + connname = strjoina("connection", sysnum, ":0"); + if (sd_device_new_from_subsystem_sysname(&conndev, "iscsi_connection", connname) < 0) return NULL; - addr = udev_device_get_sysattr_value(conndev, "persistent_address"); - port = udev_device_get_sysattr_value(conndev, "persistent_port"); - if (!addr || !port) + if (sd_device_get_sysattr_value(conndev, "persistent_address", &addr) < 0) + return NULL; + if (sd_device_get_sysattr_value(conndev, "persistent_port", &port) < 0) return NULL; format_lun_number(parent, &lun); @@ -262,37 +255,34 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char ** return parent; } -static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **path) { - struct udev_device *targetdev, *target_parent; - _cleanup_(udev_device_unrefp) struct udev_device *atadev = NULL; - const char *port_no; +static sd_device *handle_scsi_ata(sd_device *parent, char **path) { + sd_device *targetdev, *target_parent; + _cleanup_(sd_device_unrefp) sd_device *atadev = NULL; + const char *port_no, *sysname; assert(parent); assert(path); - - targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); - if (!targetdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host", &targetdev) < 0) return NULL; - target_parent = udev_device_get_parent(targetdev); - if (!target_parent) + if (sd_device_get_parent(targetdev, &target_parent) < 0) return NULL; - atadev = udev_device_new_from_subsystem_sysname(NULL, "ata_port", udev_device_get_sysname(target_parent)); - if (!atadev) + if (sd_device_get_sysname(target_parent, &sysname) < 0) + return NULL; + if (sd_device_new_from_subsystem_sysname(&atadev, "ata_port", sysname) < 0) return NULL; - port_no = udev_device_get_sysattr_value(atadev, "port_no"); - if (!port_no) + if (sd_device_get_sysattr_value(atadev, "port_no", &port_no) < 0) return NULL; path_prepend(path, "ata-%s", port_no); return parent; } -static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) { - struct udev_device *hostdev; +static sd_device *handle_scsi_default(sd_device *parent, char **path) { + sd_device *hostdev; int host, bus, target, lun; const char *name, *base, *pos; _cleanup_closedir_ DIR *dir = NULL; @@ -302,11 +292,11 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char assert(parent); assert(path); - hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); - if (!hostdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host", &hostdev) < 0) return NULL; - name = udev_device_get_sysname(parent); + if (sd_device_get_sysname(parent, &name) < 0) + return NULL; if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) return NULL; @@ -328,7 +318,8 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char * get into the way of this "I hope it works" logic. */ - base = udev_device_get_syspath(hostdev); + if (sd_device_get_syspath(hostdev, &base) < 0) + return NULL; pos = strrchr(base, '/'); if (!pos) return NULL; @@ -367,9 +358,9 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char return hostdev; } -static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path, size_t guid_str_len) { - struct udev_device *hostdev; - struct udev_device *vmbusdev; +static sd_device *handle_scsi_hyperv(sd_device *parent, char **path, size_t guid_str_len) { + sd_device *hostdev; + sd_device *vmbusdev; const char *guid_str; _cleanup_free_ char *lun = NULL; char guid[39]; @@ -379,16 +370,13 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char * assert(path); assert(guid_str_len < sizeof(guid)); - hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); - if (!hostdev) + if (sd_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host", &hostdev) < 0) return NULL; - vmbusdev = udev_device_get_parent(hostdev); - if (!vmbusdev) + if (sd_device_get_parent(hostdev, &vmbusdev) < 0) return NULL; - guid_str = udev_device_get_sysattr_value(vmbusdev, "device_id"); - if (!guid_str) + if (sd_device_get_sysattr_value(vmbusdev, "device_id", &guid_str) < 0) return NULL; if (strlen(guid_str) < guid_str_len || guid_str[0] != '{' || guid_str[guid_str_len-1] != '}') @@ -406,23 +394,23 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char * return parent; } -static struct udev_device *handle_scsi(struct udev_device *parent, char **path, bool *supported_parent) { +static sd_device *handle_scsi(sd_device *parent, char **path, bool *supported_parent) { const char *devtype, *id, *name; - devtype = udev_device_get_devtype(parent); - if (!streq_ptr(devtype, "scsi_device")) + if (sd_device_get_devtype(parent, &devtype) < 0 || + !streq(devtype, "scsi_device")) return parent; /* firewire */ - id = udev_device_get_sysattr_value(parent, "ieee1394_id"); - if (id) { + if (sd_device_get_sysattr_value(parent, "ieee1394_id", &id) >= 0) { path_prepend(path, "ieee1394-0x%s", id); *supported_parent = true; return skip_subsystem(parent, "scsi"); } /* scsi sysfs does not have a "subsystem" for the transport */ - name = udev_device_get_syspath(parent); + if (sd_device_get_syspath(parent, &name) < 0) + return NULL; if (strstr(name, "/rport-")) { *supported_parent = true; @@ -450,11 +438,12 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path, return handle_scsi_default(parent, path); } -static struct udev_device *handle_cciss(struct udev_device *parent, char **path) { +static sd_device *handle_cciss(sd_device *parent, char **path) { const char *str; unsigned controller, disk; - str = udev_device_get_sysname(parent); + if (sd_device_get_sysname(parent, &str) < 0) + return NULL; if (sscanf(str, "c%ud%u%*s", &controller, &disk) != 2) return NULL; @@ -462,30 +451,32 @@ static struct udev_device *handle_cciss(struct udev_device *parent, char **path) return skip_subsystem(parent, "cciss"); } -static void handle_scsi_tape(struct udev_device *dev, char **path) { +static void handle_scsi_tape(sd_device *dev, char **path) { const char *name; /* must be the last device in the syspath */ if (*path) return; - name = udev_device_get_sysname(dev); + if (sd_device_get_sysname(dev, &name) < 0) + return; + if (startswith(name, "nst") && strchr("lma", name[3])) path_prepend(path, "nst%c", name[3]); else if (startswith(name, "st") && strchr("lma", name[2])) path_prepend(path, "st%c", name[2]); } -static struct udev_device *handle_usb(struct udev_device *parent, char **path) { +static sd_device *handle_usb(sd_device *parent, char **path) { const char *devtype, *str, *port; - devtype = udev_device_get_devtype(parent); - if (!devtype) + if (sd_device_get_devtype(parent, &devtype) < 0) return parent; if (!STR_IN_SET(devtype, "usb_interface", "usb_device")) return parent; - str = udev_device_get_sysname(parent); + if (sd_device_get_sysname(parent, &str) < 0) + return parent; port = strchr(str, '-'); if (!port) return parent; @@ -495,11 +486,12 @@ static struct udev_device *handle_usb(struct udev_device *parent, char **path) { return skip_subsystem(parent, "usb"); } -static struct udev_device *handle_bcma(struct udev_device *parent, char **path) { +static sd_device *handle_bcma(sd_device *parent, char **path) { const char *sysname; unsigned core; - sysname = udev_device_get_sysname(parent); + if (sd_device_get_sysname(parent, &sysname) < 0) + return NULL; if (sscanf(sysname, "bcma%*u:%u", &core) != 1) return NULL; @@ -508,38 +500,41 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path) } /* Handle devices of AP bus in System z platform. */ -static struct udev_device *handle_ap(struct udev_device *parent, char **path) { +static sd_device *handle_ap(sd_device *parent, char **path) { const char *type, *func; assert(parent); assert(path); - type = udev_device_get_sysattr_value(parent, "type"); - func = udev_device_get_sysattr_value(parent, "ap_functions"); - - if (type && func) + if (sd_device_get_sysattr_value(parent, "type", &type) >= 0 && + sd_device_get_sysattr_value(parent, "ap_functions", &func) >= 0) path_prepend(path, "ap-%s-%s", type, func); - else - path_prepend(path, "ap-%s", udev_device_get_sysname(parent)); + else { + const char *sysname; + + if (sd_device_get_sysname(parent, &sysname) >= 0) + path_prepend(path, "ap-%s", sysname); + } return skip_subsystem(parent, "ap"); } -static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) { - struct udev_device *parent; +static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) { + sd_device *parent; _cleanup_free_ char *path = NULL; bool supported_transport = false; bool supported_parent = false; + const char *subsystem; assert(dev); /* walk up the chain of devices and compose path */ parent = dev; while (parent) { - const char *subsys; + const char *subsys, *sysname; - subsys = udev_device_get_subsystem(parent); - if (!subsys) { + if (sd_device_get_subsystem(parent, &subsys) < 0 || + sd_device_get_sysname(parent, &sysname) < 0) { ; } else if (streq(subsys, "scsi_tape")) { handle_scsi_tape(parent, &path); @@ -556,40 +551,44 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool parent = handle_bcma(parent, &path); supported_transport = true; } else if (streq(subsys, "serio")) { - path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent)); - parent = skip_subsystem(parent, "serio"); + const char *sysnum; + + if (sd_device_get_sysnum(parent, &sysnum) >= 0 && sysnum) { + path_prepend(&path, "serio-%s", sysnum); + parent = skip_subsystem(parent, "serio"); + } } else if (streq(subsys, "pci")) { - path_prepend(&path, "pci-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "pci-%s", sysname); parent = skip_subsystem(parent, "pci"); supported_parent = true; } else if (streq(subsys, "platform")) { - path_prepend(&path, "platform-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "platform-%s", sysname); parent = skip_subsystem(parent, "platform"); supported_transport = true; supported_parent = true; } else if (streq(subsys, "acpi")) { - path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "acpi-%s", sysname); parent = skip_subsystem(parent, "acpi"); supported_parent = true; } else if (streq(subsys, "xen")) { - path_prepend(&path, "xen-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "xen-%s", sysname); parent = skip_subsystem(parent, "xen"); supported_parent = true; } else if (streq(subsys, "virtio")) { parent = skip_subsystem(parent, "virtio"); supported_transport = true; } else if (streq(subsys, "scm")) { - path_prepend(&path, "scm-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "scm-%s", sysname); parent = skip_subsystem(parent, "scm"); supported_transport = true; supported_parent = true; } else if (streq(subsys, "ccw")) { - path_prepend(&path, "ccw-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "ccw-%s", sysname); parent = skip_subsystem(parent, "ccw"); supported_transport = true; supported_parent = true; } else if (streq(subsys, "ccwgroup")) { - path_prepend(&path, "ccwgroup-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "ccwgroup-%s", sysname); parent = skip_subsystem(parent, "ccwgroup"); supported_transport = true; supported_parent = true; @@ -598,14 +597,14 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool supported_transport = true; supported_parent = true; } else if (streq(subsys, "iucv")) { - path_prepend(&path, "iucv-%s", udev_device_get_sysname(parent)); + path_prepend(&path, "iucv-%s", sysname); parent = skip_subsystem(parent, "iucv"); supported_transport = true; supported_parent = true; } else if (streq(subsys, "nvme")) { - const char *nsid = udev_device_get_sysattr_value(dev, "nsid"); + const char *nsid; - if (nsid) { + if (sd_device_get_sysattr_value(dev, "nsid", &nsid) >= 0) { path_prepend(&path, "nvme-%s", nsid); parent = skip_subsystem(parent, "nvme"); supported_parent = true; @@ -613,12 +612,14 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool } } - if (parent) - parent = udev_device_get_parent(parent); + if (!parent) + break; + if (sd_device_get_parent(parent, &parent) < 0) + break; } if (!path) - return EXIT_FAILURE; + return -ENOENT; /* * Do not return devices with an unknown parent device type. They @@ -626,15 +627,17 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool * unique and predictable name. */ if (!supported_parent) - return EXIT_FAILURE; + return -ENOENT; /* * Do not return block devices without a well-known transport. Some * devices do not expose their buses and do not provide a unique * and predictable name that way. */ - if (streq_ptr(udev_device_get_subsystem(dev), "block") && !supported_transport) - return EXIT_FAILURE; + if (sd_device_get_subsystem(dev, &subsystem) >= 0 && + streq(subsystem, "block") && + !supported_transport) + return -ENOENT; { char tag[UTIL_NAME_SIZE]; @@ -670,7 +673,7 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag); } - return EXIT_SUCCESS; + return 0; } const struct udev_builtin udev_builtin_path_id = { diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c index 695a411a746..72f40dc4d68 100644 --- a/src/udev/udev-builtin-uaccess.c +++ b/src/udev/udev-builtin-uaccess.c @@ -15,7 +15,7 @@ #include "log.h" #include "udev-builtin.h" -static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test) { +static int builtin_uaccess(sd_device *dev, int argc, char *argv[], bool test) { int r; const char *path = NULL, *seat; bool changed_acl = false; @@ -27,18 +27,21 @@ static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool if (!logind_running()) return 0; - path = udev_device_get_devnode(dev); - seat = udev_device_get_property_value(dev, "ID_SEAT"); - if (!seat) + r = sd_device_get_devname(dev, &path); + if (r < 0) + goto finish; + + if (sd_device_get_property_value(dev, "ID_SEAT", &seat) < 0) seat = "seat0"; r = sd_seat_get_active(seat, NULL, &uid); - if (IN_SET(r, -ENXIO, -ENODATA)) { - /* No active session on this seat */ - r = 0; - goto finish; - } else if (r < 0) { - log_error("Failed to determine active user on seat %s.", seat); + if (r < 0) { + if (IN_SET(r, -ENXIO, -ENODATA)) + /* No active session on this seat */ + r = 0; + else + log_error_errno(r, "Failed to determine active user on seat %s: %m", seat); + goto finish; } @@ -64,7 +67,7 @@ finish: } } - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return r; } const struct udev_builtin udev_builtin_uaccess = { diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index aaa06364932..68c08444b04 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -135,13 +135,15 @@ static void set_scsi_type(char *to, const char *from, size_t len) { #define USB_DT_DEVICE 0x01 #define USB_DT_INTERFACE 0x04 -static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) { +static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) { _cleanup_free_ char *filename = NULL; _cleanup_close_ int fd = -1; ssize_t size; unsigned char buf[18 + 65535]; size_t pos = 0; unsigned strpos = 0; + const char *syspath; + int r; struct usb_interface_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -154,7 +156,10 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len uint8_t iInterface; } _packed_; - if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0) + r = sd_device_get_syspath(dev, &syspath); + if (r < 0) + return r; + if (asprintf(&filename, "%s/descriptors", syspath) < 0) return log_oom(); fd = open(filename, O_RDONLY|O_CLOEXEC); @@ -218,7 +223,7 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len * 6.) If the device supplies a serial number, this number * is concatenated with the identification with an underscore '_'. */ -static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) { +static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) { char vendor_str[64] = ""; char vendor_str_enc[256]; const char *vendor_id; @@ -234,116 +239,114 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool const char *driver = NULL; char serial[256]; - struct udev_device *dev_interface = NULL; - struct udev_device *dev_usb = NULL; + sd_device *dev_interface, *dev_usb; const char *if_class, *if_subclass; int if_class_num; int protocol = 0; size_t l; char *s; + const char *syspath, *sysname, *devtype, *interface_syspath; + int r; + assert(dev); + r = sd_device_get_syspath(dev, &syspath); + if (r < 0) + return r; + + r = sd_device_get_sysname(dev, &sysname); + if (r < 0) + return r; + /* shortcut, if we are called directly for a "usb_device" type */ - if (udev_device_get_devtype(dev) != NULL && streq(udev_device_get_devtype(dev), "usb_device")) { + if (sd_device_get_devtype(dev, &devtype) >= 0 && streq(devtype, "usb_device")) { dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str)); dev_usb = dev; goto fallback; } /* usb interface directory */ - dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); - if (dev_interface == NULL) { - log_debug("unable to access usb_interface device of '%s'", - udev_device_get_syspath(dev)); - return EXIT_FAILURE; - } + r = sd_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface", &dev_interface); + if (r < 0) + return log_debug_errno(r, "Failed to access usb_interface device of '%s': %m", syspath); - ifnum = udev_device_get_sysattr_value(dev_interface, "bInterfaceNumber"); - driver = udev_device_get_sysattr_value(dev_interface, "driver"); + r = sd_device_get_syspath(dev_interface, &interface_syspath); + if (r < 0) + return r; + (void) sd_device_get_sysattr_value(dev_interface, "bInterfaceNumber", &ifnum); + (void) sd_device_get_sysattr_value(dev_interface, "driver", &driver); - if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass"); - if (!if_class) { - log_debug("%s: cannot get bInterfaceClass attribute", - udev_device_get_sysname(dev)); - return EXIT_FAILURE; - } + r = sd_device_get_sysattr_value(dev_interface, "bInterfaceClass", &if_class); + if (r < 0) + return log_debug_errno(r, "Failed to get bInterfaceClass attribute of '%s': %m", sysname); if_class_num = strtoul(if_class, NULL, 16); if (if_class_num == 8) { /* mass storage */ - if_subclass = udev_device_get_sysattr_value(dev_interface, "bInterfaceSubClass"); - if (if_subclass != NULL) + if (sd_device_get_sysattr_value(dev_interface, "bInterfaceSubClass", &if_subclass) >= 0) protocol = set_usb_mass_storage_ifsubtype(type_str, if_subclass, sizeof(type_str)-1); - } else { + } else set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); - } - log_debug("%s: if_class %d protocol %d", - udev_device_get_syspath(dev_interface), if_class_num, protocol); + log_debug("%s: if_class %d protocol %d", interface_syspath, if_class_num, protocol); /* usb device directory */ - dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device"); - if (!dev_usb) { - log_debug("unable to find parent 'usb' device of '%s'", - udev_device_get_syspath(dev)); - return EXIT_FAILURE; - } + r = sd_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device", &dev_usb); + if (r < 0) + return log_debug_errno(r, "Failed to find parent 'usb' device of '%s'", syspath); /* all interfaces of the device in a single string */ dev_if_packed_info(dev_usb, packed_if_str, sizeof(packed_if_str)); /* mass storage : SCSI or ATAPI */ if (IN_SET(protocol, 6, 2)) { - struct udev_device *dev_scsi; - const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; + sd_device *dev_scsi; + const char *scsi_sysname, *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; int host, bus, target, lun; /* get scsi device */ - dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); - if (dev_scsi == NULL) { - log_debug("unable to find parent 'scsi' device of '%s'", - udev_device_get_syspath(dev)); + r = sd_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device", &dev_scsi); + if (r < 0) { + log_debug_errno(r, "Unable to find parent 'scsi' device of '%s'", syspath); goto fallback; } - if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { - log_debug("invalid scsi device '%s'", udev_device_get_sysname(dev_scsi)); + if (sd_device_get_sysname(dev_scsi, &scsi_sysname) < 0) + goto fallback; + if (sscanf(scsi_sysname, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { + log_debug("invalid scsi device '%s'", scsi_sysname); goto fallback; } /* Generic SPC-2 device */ - scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor"); - if (!scsi_vendor) { - log_debug("%s: cannot get SCSI vendor attribute", - udev_device_get_sysname(dev_scsi)); + r = sd_device_get_sysattr_value(dev_scsi, "vendor", &scsi_vendor); + if (r < 0) { + log_debug_errno(r, "%s: cannot get SCSI vendor attribute: %m", scsi_sysname); goto fallback; } udev_util_encode_string(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc)); util_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1); util_replace_chars(vendor_str, NULL); - scsi_model = udev_device_get_sysattr_value(dev_scsi, "model"); - if (!scsi_model) { - log_debug("%s: cannot get SCSI model attribute", - udev_device_get_sysname(dev_scsi)); + r = sd_device_get_sysattr_value(dev_scsi, "model", &scsi_model); + if (r < 0) { + log_debug_errno(r, "%s: cannot get SCSI model attribute: %m", scsi_sysname); goto fallback; } udev_util_encode_string(scsi_model, model_str_enc, sizeof(model_str_enc)); util_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1); util_replace_chars(model_str, NULL); - scsi_type = udev_device_get_sysattr_value(dev_scsi, "type"); - if (!scsi_type) { - log_debug("%s: cannot get SCSI type attribute", - udev_device_get_sysname(dev_scsi)); + r = sd_device_get_sysattr_value(dev_scsi, "type", &scsi_type); + if (r < 0) { + log_debug_errno(r, "%s: cannot get SCSI type attribute", scsi_sysname); goto fallback; } set_scsi_type(type_str, scsi_type, sizeof(type_str)-1); - scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev"); - if (!scsi_rev) { - log_debug("%s: cannot get SCSI revision attribute", - udev_device_get_sysname(dev_scsi)); + r = sd_device_get_sysattr_value(dev_scsi, "rev", &scsi_rev); + if (r < 0) { + log_debug_errno(r, "%s: cannot get SCSI revision attribute: %m", scsi_sysname); goto fallback; } util_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1); @@ -357,33 +360,30 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool } fallback: - vendor_id = udev_device_get_sysattr_value(dev_usb, "idVendor"); - product_id = udev_device_get_sysattr_value(dev_usb, "idProduct"); + r = sd_device_get_sysattr_value(dev_usb, "idVendor", &vendor_id); + if (r < 0) + return r; + + r = sd_device_get_sysattr_value(dev_usb, "idProduct", &product_id); + if (r < 0) + return r; /* fallback to USB vendor & device */ if (vendor_str[0] == '\0') { - const char *usb_vendor = NULL; + const char *usb_vendor; - usb_vendor = udev_device_get_sysattr_value(dev_usb, "manufacturer"); - if (!usb_vendor) + if (sd_device_get_sysattr_value(dev_usb, "manufacturer", &usb_vendor) < 0) usb_vendor = vendor_id; - if (!usb_vendor) { - log_debug("No USB vendor information available"); - return EXIT_FAILURE; - } udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); util_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1); util_replace_chars(vendor_str, NULL); } if (model_str[0] == '\0') { - const char *usb_model = NULL; + const char *usb_model; - usb_model = udev_device_get_sysattr_value(dev_usb, "product"); - if (!usb_model) + if (sd_device_get_sysattr_value(dev_usb, "product", &usb_model) < 0) usb_model = product_id; - if (!usb_model) - return EXIT_FAILURE; udev_util_encode_string(usb_model, model_str_enc, sizeof(model_str_enc)); util_replace_whitespace(usb_model, model_str, sizeof(model_str)-1); util_replace_chars(model_str, NULL); @@ -392,8 +392,7 @@ fallback: if (revision_str[0] == '\0') { const char *usb_rev; - usb_rev = udev_device_get_sysattr_value(dev_usb, "bcdDevice"); - if (usb_rev) { + if (sd_device_get_sysattr_value(dev_usb, "bcdDevice", &usb_rev) >= 0) { util_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1); util_replace_chars(revision_str, NULL); } @@ -402,8 +401,7 @@ fallback: if (serial_str[0] == '\0') { const char *usb_serial; - usb_serial = udev_device_get_sysattr_value(dev_usb, "serial"); - if (usb_serial) { + if (sd_device_get_sysattr_value(dev_usb, "serial", &usb_serial) >= 0) { const unsigned char *p; /* http://msdn.microsoft.com/en-us/library/windows/hardware/gg487321.aspx */ @@ -412,11 +410,11 @@ fallback: usb_serial = NULL; break; } - } - if (usb_serial) { - util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); - util_replace_chars(serial_str, NULL); + if (usb_serial) { + util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1); + util_replace_chars(serial_str, NULL); + } } } @@ -445,11 +443,11 @@ fallback: udev_builtin_add_property(dev, test, "ID_BUS", "usb"); if (!isempty(packed_if_str)) udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str); - if (ifnum != NULL) + if (ifnum) udev_builtin_add_property(dev, test, "ID_USB_INTERFACE_NUM", ifnum); - if (driver != NULL) + if (driver) udev_builtin_add_property(dev, test, "ID_USB_DRIVER", driver); - return EXIT_SUCCESS; + return 0; } const struct udev_builtin udev_builtin_usb_id = { diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index da87b2b7030..3a61be10caa 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -4,13 +4,15 @@ #include #include +#include "device-private.h" +#include "device-util.h" #include "string-util.h" +#include "strv.h" #include "udev-builtin.h" -#include "udev.h" static bool initialized; -static const struct udev_builtin *builtins[] = { +static const struct udev_builtin *builtins[_UDEV_BUILTIN_MAX] = { #if HAVE_BLKID [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid, #endif @@ -36,7 +38,7 @@ void udev_builtin_init(void) { if (initialized) return; - for (i = 0; i < ELEMENTSOF(builtins); i++) + for (i = 0; i < _UDEV_BUILTIN_MAX; i++) if (builtins[i] && builtins[i]->init) builtins[i]->init(); @@ -49,7 +51,7 @@ void udev_builtin_exit(void) { if (!initialized) return; - for (i = 0; i < ELEMENTSOF(builtins); i++) + for (i = 0; i < _UDEV_BUILTIN_MAX; i++) if (builtins[i] && builtins[i]->exit) builtins[i]->exit(); @@ -59,7 +61,7 @@ void udev_builtin_exit(void) { bool udev_builtin_validate(void) { unsigned i; - for (i = 0; i < ELEMENTSOF(builtins); i++) + for (i = 0; i < _UDEV_BUILTIN_MAX; i++) if (builtins[i] && builtins[i]->validate && builtins[i]->validate()) return true; return false; @@ -68,12 +70,14 @@ bool udev_builtin_validate(void) { void udev_builtin_list(void) { unsigned i; - for (i = 0; i < ELEMENTSOF(builtins); i++) + for (i = 0; i < _UDEV_BUILTIN_MAX; i++) if (builtins[i]) fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help); } const char *udev_builtin_name(enum udev_builtin_cmd cmd) { + assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX); + if (!builtins[cmd]) return NULL; @@ -81,6 +85,8 @@ const char *udev_builtin_name(enum udev_builtin_cmd cmd) { } bool udev_builtin_run_once(enum udev_builtin_cmd cmd) { + assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX); + if (!builtins[cmd]) return false; @@ -88,23 +94,27 @@ bool udev_builtin_run_once(enum udev_builtin_cmd cmd) { } enum udev_builtin_cmd udev_builtin_lookup(const char *command) { - char name[UTIL_PATH_SIZE]; enum udev_builtin_cmd i; - char *pos; + size_t n; - strscpy(name, sizeof(name), command); - pos = strchr(name, ' '); - if (pos) - pos[0] = '\0'; - for (i = 0; i < ELEMENTSOF(builtins); i++) - if (builtins[i] && streq(builtins[i]->name, name)) + assert(command); + + command += strspn(command, WHITESPACE); + n = strcspn(command, WHITESPACE); + for (i = 0; i < _UDEV_BUILTIN_MAX; i++) + if (builtins[i] && strneq(builtins[i]->name, command, n)) return i; - return UDEV_BUILTIN_MAX; + + return _UDEV_BUILTIN_INVALID; } -int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) { +int udev_builtin_run(sd_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) { _cleanup_strv_free_ char **argv = NULL; + assert(dev); + assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX); + assert(command); + if (!builtins[cmd]) return -EOPNOTSUPP; @@ -117,10 +127,19 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c return builtins[cmd]->cmd(dev, strv_length(argv), argv, test); } -int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val) { - udev_device_add_property(dev, key, val); +int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) { + int r; + + assert(dev); + assert(key); + + r = device_add_property(dev, key, val); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to add property '%s%s%s'", + key, val ? "=" : "", strempty(val)); if (test) printf("%s=%s\n", key, val); + return 0; } diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h index 0a6dc63ec26..e51eefbfb5d 100644 --- a/src/udev/udev-builtin.h +++ b/src/udev/udev-builtin.h @@ -3,7 +3,7 @@ #include -#include "libudev.h" +#include "sd-device.h" enum udev_builtin_cmd { #if HAVE_BLKID @@ -23,12 +23,13 @@ enum udev_builtin_cmd { #if HAVE_ACL UDEV_BUILTIN_UACCESS, #endif - UDEV_BUILTIN_MAX + _UDEV_BUILTIN_MAX, + _UDEV_BUILTIN_INVALID = -1, }; struct udev_builtin { const char *name; - int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test); + int (*cmd)(sd_device *dev, int argc, char *argv[], bool test); const char *help; int (*init)(void); void (*exit)(void); @@ -59,9 +60,9 @@ void udev_builtin_exit(void); enum udev_builtin_cmd udev_builtin_lookup(const char *command); const char *udev_builtin_name(enum udev_builtin_cmd cmd); bool udev_builtin_run_once(enum udev_builtin_cmd cmd); -int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test); +int udev_builtin_run(sd_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test); void udev_builtin_list(void); bool udev_builtin_validate(void); -int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val); -int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *prefix, const char *modalias, +int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val); +int udev_builtin_hwdb_lookup(sd_device *dev, const char *prefix, const char *modalias, const char *filter, bool test); diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 31d4b6e5c44..873f900349d 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -900,8 +900,8 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_ udev_event_apply_format(event, cmd, command, sizeof(command), false); - if (builtin_cmd < UDEV_BUILTIN_MAX) - udev_builtin_run(event->dev, builtin_cmd, command, false); + if (builtin_cmd >= 0 && builtin_cmd < _UDEV_BUILTIN_MAX) + udev_builtin_run(event->dev->device, builtin_cmd, command, false); else { if (event->exec_delay > 0) { log_debug("delay execution of '%s'", command); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 6ae92e24c64..7703e867f8d 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -22,6 +22,7 @@ #include "fileio.h" #include "fs-util.h" #include "glob-util.h" +#include "libudev-device-internal.h" #include "path-util.h" #include "proc-cmdline.h" #include "stat-util.h" @@ -1227,7 +1228,7 @@ static void add_rule(struct udev_rules *rules, char *line, if (value[0] != '/') { const enum udev_builtin_cmd cmd = udev_builtin_lookup(value); - if (cmd < UDEV_BUILTIN_MAX) { + if (cmd >= 0) { LOG_RULE_DEBUG("IMPORT found builtin '%s', replacing", value); rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); continue; @@ -1237,7 +1238,7 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (streq(attr, "builtin")) { const enum udev_builtin_cmd cmd = udev_builtin_lookup(value); - if (cmd >= UDEV_BUILTIN_MAX) + if (cmd < 0) LOG_RULE_WARNING("IMPORT{builtin} '%s' unknown", value); else rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); @@ -1275,12 +1276,12 @@ static void add_rule(struct udev_rules *rules, char *line, if (streq(attr, "builtin")) { const enum udev_builtin_cmd cmd = udev_builtin_lookup(value); - if (cmd < UDEV_BUILTIN_MAX) - rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd); - else + if (cmd < 0) LOG_RULE_ERROR("RUN{builtin}: '%s' unknown", value); + else + rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd); } else if (streq(attr, "program")) { - const enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX; + const enum udev_builtin_cmd cmd = _UDEV_BUILTIN_MAX; rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); } else @@ -2014,10 +2015,11 @@ int udev_rules_apply_to_event( rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); - if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) { + r = udev_builtin_run(event->dev->device, cur->key.builtin_cmd, command, false); + if (r < 0) { /* remember failure */ - log_debug("IMPORT builtin '%s' returned non-zero", - udev_builtin_name(cur->key.builtin_cmd)); + log_debug_errno(r, "IMPORT builtin '%s' fails: %m", + udev_builtin_name(cur->key.builtin_cmd)); event->builtin_ret |= (1 << cur->key.builtin_cmd); if (cur->key.op != OP_NOMATCH) goto nomatch; diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index d516492ade3..7bf7b08a448 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -6,15 +6,13 @@ #include #include -#include "libudev-private.h" -#include "path-util.h" -#include "string-util.h" -#include "strxcpyx.h" +#include "log.h" #include "udev-builtin.h" #include "udevadm.h" +#include "udevadm-util.h" static const char *arg_command = NULL; -static char arg_syspath[UTIL_PATH_SIZE] = {}; +static const char *arg_syspath = NULL; static int help(void) { printf("%s test-builtin [OPTIONS] COMMAND DEVPATH\n\n" @@ -36,7 +34,6 @@ static int parse_argv(int argc, char *argv[]) { {} }; - const char *s; int c; while ((c = getopt_long(argc, argv, "Vh", options, NULL)) >= 0) @@ -57,23 +54,17 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - s = argv[optind++]; - if (!s) { + arg_syspath = argv[optind++]; + if (!arg_syspath) { log_error("syspath missing."); return -EINVAL; } - /* add /sys if needed */ - if (!path_startswith(s, "/sys")) - strscpyl(arg_syspath, sizeof(arg_syspath), "/sys", s, NULL); - else - strscpy(arg_syspath, sizeof(arg_syspath), s); - return 1; } int builtin_main(int argc, char *argv[], void *userdata) { - _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; enum udev_builtin_cmd cmd; int r; @@ -86,21 +77,21 @@ int builtin_main(int argc, char *argv[], void *userdata) { udev_builtin_init(); cmd = udev_builtin_lookup(arg_command); - if (cmd >= UDEV_BUILTIN_MAX) { + if (cmd < 0) { log_error("Unknown command '%s'", arg_command); r = -EINVAL; goto finish; } - dev = udev_device_new_from_syspath(NULL, arg_syspath); - if (!dev) { - r = log_error_errno(errno, "Failed to open device '%s'", arg_syspath); + r = find_device(arg_syspath, "/sys", &dev); + if (r < 0) { + log_error_errno(r, "Failed to open device '%s': %m", arg_syspath); goto finish; } r = udev_builtin_run(dev, cmd, arg_command, true); if (r < 0) - log_debug("error executing '%s', exit code %i", arg_command, r); + log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command); finish: udev_builtin_exit(); diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c index 6cff5ef84c0..1dbcf979b17 100644 --- a/src/udev/udevadm-util.c +++ b/src/udev/udevadm-util.c @@ -2,17 +2,23 @@ #include +#include "alloc-util.h" #include "device-private.h" #include "path-util.h" -#include "string-util.h" #include "udevadm-util.h" int find_device(const char *id, const char *prefix, sd_device **ret) { + _cleanup_free_ char *buf = NULL; + assert(id); assert(ret); - if (prefix && !startswith(id, prefix)) - id = strjoina(prefix, id); + if (prefix && !path_startswith(id, prefix)) { + buf = path_join(NULL, prefix, id); + if (!buf) + return -ENOMEM; + id = buf; + } if (path_startswith(id, "/sys/")) return sd_device_new_from_syspath(ret, id);