diff --git a/shell-completion/bash/udevadm b/shell-completion/bash/udevadm index 34b24eccb8..f1d907aec8 100644 --- a/shell-completion/bash/udevadm +++ b/shell-completion/bash/udevadm @@ -110,7 +110,7 @@ _udevadm() { ) local verbs=(info trigger settle control monitor test-builtin test verify cat wait lock) - local builtins=(blkid btrfs hwdb input_id keyboard kmod net_driver net_id net_setup_link path_id uaccess usb_id) + local builtins=(blkid btrfs factory_reset hwdb input_id keyboard kmod net_driver net_id net_setup_link path_id uaccess usb_id) for ((i=0; i < COMP_CWORD; i++)); do if __contains_word "${COMP_WORDS[i]}" "${verbs[@]}"; then diff --git a/shell-completion/zsh/_udevadm b/shell-completion/zsh/_udevadm index 71f75a549c..685dece055 100644 --- a/shell-completion/zsh/_udevadm +++ b/shell-completion/zsh/_udevadm @@ -103,7 +103,7 @@ _udevadm_test-builtin(){ '(- *)'{-h,--help}'[Print help]' \ '(- *)'{-V,--version}'[Print version of the program]' \ '--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \ - '*::builtins:(blkid btrfs hwdb input_id net_driver net_id net_setup_link kmod path_id uaccess usb_id)' + '*::builtins:(blkid btrfs factory_reset hwdb input_id keyboard kmod net_driver net_id net_setup_link path_id uaccess usb_id)' elif (( CURRENT == 3 )); then _arguments \ '--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \ diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c index b166b228f3..a1238f1e1b 100644 --- a/src/udev/udev-builtin-btrfs.c +++ b/src/udev/udev-builtin-btrfs.c @@ -16,8 +16,24 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); int r; - if (argc != 3 || !streq(argv[1], "ready")) - return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid arguments"); + if (!IN_SET(argc, 2, 3) || !streq(argv[1], "ready")) + return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid arguments."); + + const char *node; + r = sd_device_get_devname(dev, &node); + if (r < 0) + return log_device_error_errno(dev, r, "Failed to get device node: %m"); + + if (argc == 3 && !streq(argv[2], node)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device node '%s' is not owned by the device, it must be '%s'.", argv[2], node); + + if (strlen(node) >= sizeof_field(struct btrfs_ioctl_vol_args, name)) + return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device name too long for BTRFS_IOC_DEVICES_READY call: %s", node); + + if (event->event_mode != EVENT_UDEV_WORKER) { + log_device_debug(dev, "Running in test mode, skipping execution of 'btrfs' builtin command."); + return 0; + } _cleanup_close_ int fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC|O_NOCTTY); if (fd < 0) { @@ -33,10 +49,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { } struct btrfs_ioctl_vol_args args = {}; - if (strlen(argv[2]) >= sizeof(args.name)) - return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Device name too long for BTRFS_IOC_DEVICES_READY call: %s", argv[2]); - - strncpy(args.name, argv[2], sizeof(args.name)-1); + strncpy(args.name, node, sizeof(args.name)-1); r = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); if (r < 0) return log_device_debug_errno(dev, errno, "Failed to call BTRFS_IOC_DEVICES_READY: %m"); diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index fd4b23c1cc..8df25e1603 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -12,24 +12,24 @@ static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = { #if HAVE_BLKID - [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid, + [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid, #endif - [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs, + [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs, [UDEV_BUILTIN_FACTORY_RESET] = &udev_builtin_factory_reset, - [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb, - [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id, - [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard, + [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb, + [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id, + [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard, #if HAVE_KMOD - [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod, + [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod, #endif - [UDEV_BUILTIN_NET_DRIVER] = &udev_builtin_net_driver, - [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id, - [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link, - [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id, + [UDEV_BUILTIN_NET_DRIVER] = &udev_builtin_net_driver, + [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id, + [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link, + [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id, #if HAVE_ACL - [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess, + [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess, #endif - [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id, + [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id, }; void udev_builtin_init(void) { diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h index 4064b25f57..d01d8d9875 100644 --- a/src/udev/udev-def.h +++ b/src/udev/udev-def.h @@ -61,25 +61,26 @@ typedef enum UdevBuiltinCommand { typedef enum UdevReloadFlags { #if HAVE_BLKID - UDEV_RELOAD_BUILTIN_BLKID = 1u << UDEV_BUILTIN_BLKID, + UDEV_RELOAD_BUILTIN_BLKID = 1u << UDEV_BUILTIN_BLKID, #endif - UDEV_RELOAD_BUILTIN_BTRFS = 1u << UDEV_BUILTIN_BTRFS, - UDEV_RELOAD_BUILTIN_HWDB = 1u << UDEV_BUILTIN_HWDB, - UDEV_RELOAD_BUILTIN_INPUT_ID = 1u << UDEV_BUILTIN_INPUT_ID, - UDEV_RELOAD_BUILTIN_KEYBOARD = 1u << UDEV_BUILTIN_KEYBOARD, + UDEV_RELOAD_BUILTIN_BTRFS = 1u << UDEV_BUILTIN_BTRFS, + UDEV_RELOAD_BUILTIN_FACTORY_RESET = 1u << UDEV_BUILTIN_FACTORY_RESET, + UDEV_RELOAD_BUILTIN_HWDB = 1u << UDEV_BUILTIN_HWDB, + UDEV_RELOAD_BUILTIN_INPUT_ID = 1u << UDEV_BUILTIN_INPUT_ID, + UDEV_RELOAD_BUILTIN_KEYBOARD = 1u << UDEV_BUILTIN_KEYBOARD, #if HAVE_KMOD - UDEV_RELOAD_BUILTIN_KMOD = 1u << UDEV_BUILTIN_KMOD, + UDEV_RELOAD_BUILTIN_KMOD = 1u << UDEV_BUILTIN_KMOD, #endif - UDEV_RELOAD_BUILTIN_DRIVER = 1u << UDEV_BUILTIN_NET_DRIVER, - UDEV_RELOAD_BUILTIN_NET_ID = 1u << UDEV_BUILTIN_NET_ID, - UDEV_RELOAD_BUILTIN_NET_LINK = 1u << UDEV_BUILTIN_NET_LINK, - UDEV_RELOAD_BUILTIN_PATH_ID = 1u << UDEV_BUILTIN_PATH_ID, + UDEV_RELOAD_BUILTIN_DRIVER = 1u << UDEV_BUILTIN_NET_DRIVER, + UDEV_RELOAD_BUILTIN_NET_ID = 1u << UDEV_BUILTIN_NET_ID, + UDEV_RELOAD_BUILTIN_NET_LINK = 1u << UDEV_BUILTIN_NET_LINK, + UDEV_RELOAD_BUILTIN_PATH_ID = 1u << UDEV_BUILTIN_PATH_ID, #if HAVE_ACL - UDEV_RELOAD_BUILTIN_UACCESS = 1u << UDEV_BUILTIN_UACCESS, + UDEV_RELOAD_BUILTIN_UACCESS = 1u << UDEV_BUILTIN_UACCESS, #endif - UDEV_RELOAD_BUILTIN_USB_ID = 1u << UDEV_BUILTIN_USB_ID, - UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0), - UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1), + UDEV_RELOAD_BUILTIN_USB_ID = 1u << UDEV_BUILTIN_USB_ID, + UDEV_RELOAD_KILL_WORKERS = 1u << (_UDEV_BUILTIN_MAX + 0), + UDEV_RELOAD_RULES = 1u << (_UDEV_BUILTIN_MAX + 1), } UdevReloadFlags; /* udev properties are conceptually close to environment variables. Let's validate names, values, and diff --git a/test/units/TEST-17-UDEV.10.sh b/test/units/TEST-17-UDEV.10.sh index 796d8dc5d2..d7e69ef673 100755 --- a/test/units/TEST-17-UDEV.10.sh +++ b/test/units/TEST-17-UDEV.10.sh @@ -159,26 +159,18 @@ udevadm test --json=short /sys/class/net/$netdev | jq . >/dev/null udevadm test --json=help udevadm test -h -# udevadm test-builtin path_id "$loopdev" -udevadm test-builtin net_id /sys/class/net/$netdev -udevadm test-builtin net_id "$(systemd-escape -p --suffix device /sys/devices/virtual/net/$netdev)" -udevadm test-builtin -a add net_id /sys/class/net/$netdev -udevadm test-builtin -a remove net_id /sys/class/net/$netdev -udevadm test-builtin -a change net_id /sys/class/net/$netdev -udevadm test-builtin -a move net_id /sys/class/net/$netdev -udevadm test-builtin -a online net_id /sys/class/net/$netdev -udevadm test-builtin -a offline net_id /sys/class/net/$netdev -udevadm test-builtin -a bind net_id /sys/class/net/$netdev -udevadm test-builtin -a unbind net_id /sys/class/net/$netdev -udevadm test-builtin -a help net_id /sys/class/net/$netdev -udevadm test-builtin net_setup_link /sys/class/net/$netdev +# Builtins +(! udevadm test-builtin aaaaa /dev/null) udevadm test-builtin blkid "$loopdev" -udevadm test-builtin input_id /sys/class/net/$netdev -udevadm test-builtin keyboard /dev/null -# udevadm test-builtin kmod /sys/class/net/$netdev -udevadm test-builtin uaccess /dev/null -# udevadm test-builtin usb_id dev/null -(! udevadm test-builtin hello /sys/class/net/$netdev) +(! udevadm test-builtin "btrfs" "$loopdev") +(! udevadm test-builtin "btrfs aaaaa" "$loopdev") +(! udevadm test-builtin "btrfs ready aaa" "$loopdev") +udevadm test-builtin "btrfs ready" "$loopdev" +udevadm test-builtin "btrfs ready $loopdev" "$loopdev" +(! udevadm test-builtin factory_reset "$loopdev") +(! udevadm test-builtin "factory_reset aaa" "$loopdev") +udevadm test-builtin "factory_reset status" "$loopdev" + # systemd-hwdb update is extremely slow when combined with sanitizers and run # in a VM without acceleration, so let's just skip the one particular test # if we detect this combination @@ -199,6 +191,28 @@ EOF systemd-hwdb update fi +udevadm test-builtin input_id /dev/null +udevadm test-builtin keyboard /dev/null +udevadm test-builtin kmod /dev/null +udevadm test-builtin net_driver /sys/class/net/$netdev | grep -F 'ID_NET_DRIVER=dummy' +(! udevadm test-builtin net_driver /dev/null) +udevadm test-builtin net_id /sys/class/net/$netdev +udevadm test-builtin net_id "$(systemd-escape -p --suffix device /sys/devices/virtual/net/$netdev)" +(! udevadm test-builtin net_id /dev/null) +udevadm test-builtin -a add net_id /sys/class/net/$netdev +udevadm test-builtin -a remove net_id /sys/class/net/$netdev +udevadm test-builtin -a change net_id /sys/class/net/$netdev +udevadm test-builtin -a move net_id /sys/class/net/$netdev +udevadm test-builtin -a online net_id /sys/class/net/$netdev +udevadm test-builtin -a offline net_id /sys/class/net/$netdev +udevadm test-builtin -a bind net_id /sys/class/net/$netdev +udevadm test-builtin -a unbind net_id /sys/class/net/$netdev +udevadm test-builtin -a help net_id /sys/class/net/$netdev +udevadm test-builtin net_setup_link /sys/class/net/$netdev +(! udevadm net_setup_link /dev/null) +(! udevadm test-builtin path_id /dev/null) +udevadm test-builtin uaccess /dev/null +(! udevadm test-builtin usb_id /dev/null) udevadm trigger udevadm trigger /dev/null