From: Yu Watanabe Date: Thu, 28 Mar 2024 07:24:59 +0000 (+0900) Subject: udev: make udevadm test and test-builtin not destructive X-Git-Tag: v256-rc1~359^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F31998%2Fhead;p=thirdparty%2Fsystemd.git udev: make udevadm test and test-builtin not destructive Previously, 'udevadm test' performs not only processing udev rules, but made several destructive change on the system; updating udev database, device node permission, devlinks, network interface properties, and so on. Similary, 'udevadm test-builtin' may perform something destructive, especially by 'keyboard', 'kmod', and 'net_setup_link' builtins. Let's make these commands and test executables not change device configurations. --- diff --git a/src/udev/meson.build b/src/udev/meson.build index 824ec478039..e5b52ab6421 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -205,6 +205,7 @@ executables += [ }, udev_test_template + { 'sources' : files('net/test-link-config-tables.c'), + 'include_directories' : includes + include_directories('.'), 'suite' : 'udev', }, udev_test_template + { @@ -240,6 +241,7 @@ executables += [ }, udev_fuzz_template + { 'sources' : files('net/fuzz-link-parser.c'), + 'include_directories' : includes + include_directories('.'), }, udev_fuzz_template + { 'sources' : files('fuzz-udev-rule-parse-value.c'), diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 7f16b17467d..647cdeeb9db 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -483,7 +483,7 @@ int link_get_config(LinkConfigContext *ctx, Link *link) { return -ENOENT; } -static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) { +static int link_apply_ethtool_settings(Link *link, int *ethtool_fd, EventMode mode) { LinkConfig *config; const char *name; int r; @@ -492,6 +492,11 @@ static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) { assert(link->config); assert(ethtool_fd); + if (mode != EVENT_UDEV_WORKER) { + log_link_debug(link, "Running in test mode, skipping application of ethtool settings."); + return 0; + } + config = link->config; name = link->ifname; @@ -684,7 +689,7 @@ finalize: return 0; } -static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl) { +static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl, EventMode mode) { struct hw_addr_data hw_addr = {}; LinkConfig *config; int r; @@ -693,6 +698,11 @@ static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl) { assert(link->config); assert(rtnl); + if (mode != EVENT_UDEV_WORKER) { + log_link_debug(link, "Running in test mode, skipping application of rtnl settings."); + return 0; + } + config = link->config; (void) link_generate_new_hw_addr(link, &hw_addr); @@ -896,7 +906,7 @@ static int sr_iov_configure(Link *link, sd_netlink **rtnl, SRIOV *sr_iov) { return 0; } -static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) { +static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl, EventMode mode) { SRIOV *sr_iov; uint32_t n; int r; @@ -905,6 +915,11 @@ static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) { assert(link->config); assert(link->device); + if (mode != EVENT_UDEV_WORKER) { + log_link_debug(link, "Running in test mode, skipping application of SR-IOV settings."); + return 0; + } + r = sr_iov_set_num_vfs(link->device, link->config->sr_iov_num_vfs, link->config->sr_iov_by_section); if (r < 0) log_link_warning_errno(link, r, "Failed to set the number of SR-IOV virtual functions, ignoring: %m"); @@ -938,7 +953,7 @@ static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) { return 0; } -static int link_apply_rps_cpu_mask(Link *link) { +static int link_apply_rps_cpu_mask(Link *link, EventMode mode) { _cleanup_free_ char *mask_str = NULL; LinkConfig *config; int r; @@ -946,6 +961,11 @@ static int link_apply_rps_cpu_mask(Link *link) { assert(link); config = ASSERT_PTR(link->config); + if (mode != EVENT_UDEV_WORKER) { + log_link_debug(link, "Running in test mode, skipping application of RPS setting."); + return 0; + } + /* Skip if the config is not specified. */ if (!config->rps_cpu_mask) return 0; @@ -981,7 +1001,7 @@ static int link_apply_rps_cpu_mask(Link *link) { return 0; } -static int link_apply_udev_properties(Link *link, bool test) { +static int link_apply_udev_properties(Link *link, EventMode mode) { LinkConfig *config; sd_device *device; @@ -992,7 +1012,7 @@ static int link_apply_udev_properties(Link *link, bool test) { /* 1. apply ImportProperty=. */ STRV_FOREACH(p, config->import_properties) - (void) udev_builtin_import_property(device, link->device_db_clone, test, *p); + (void) udev_builtin_import_property(device, link->device_db_clone, mode, *p); /* 2. apply Property=. */ STRV_FOREACH(p, config->properties) { @@ -1007,15 +1027,15 @@ static int link_apply_udev_properties(Link *link, bool test) { if (!key) return log_oom(); - (void) udev_builtin_add_property(device, test, key, eq + 1); + (void) udev_builtin_add_property(device, mode, key, eq + 1); } /* 3. apply UnsetProperty=. */ STRV_FOREACH(p, config->unset_properties) - (void) udev_builtin_add_property(device, test, *p, NULL); + (void) udev_builtin_add_property(device, mode, *p, NULL); /* 4. set the default properties. */ - (void) udev_builtin_add_property(device, test, "ID_NET_LINK_FILE", config->filename); + (void) udev_builtin_add_property(device, mode, "ID_NET_LINK_FILE", config->filename); _cleanup_free_ char *joined = NULL; STRV_FOREACH(d, config->dropins) { @@ -1029,26 +1049,26 @@ static int link_apply_udev_properties(Link *link, bool test) { return log_oom(); } - (void) udev_builtin_add_property(device, test, "ID_NET_LINK_FILE_DROPINS", joined); + (void) udev_builtin_add_property(device, mode, "ID_NET_LINK_FILE_DROPINS", joined); if (link->new_name) - (void) udev_builtin_add_property(device, test, "ID_NET_NAME", link->new_name); + (void) udev_builtin_add_property(device, mode, "ID_NET_NAME", link->new_name); return 0; } -int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, bool test) { +int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, EventMode mode) { int r; assert(ctx); assert(rtnl); assert(link); - r = link_apply_ethtool_settings(link, &ctx->ethtool_fd); + r = link_apply_ethtool_settings(link, &ctx->ethtool_fd, mode); if (r < 0) return r; - r = link_apply_rtnl_settings(link, rtnl); + r = link_apply_rtnl_settings(link, rtnl, mode); if (r < 0) return r; @@ -1060,19 +1080,15 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, boo if (r < 0) return r; - r = link_apply_sr_iov_config(link, rtnl); + r = link_apply_sr_iov_config(link, rtnl, mode); if (r < 0) return r; - r = link_apply_udev_properties(link, test); + r = link_apply_rps_cpu_mask(link, mode); if (r < 0) return r; - r = link_apply_rps_cpu_mask(link); - if (r < 0) - return r; - - return 0; + return link_apply_udev_properties(link, mode); } int config_parse_udev_property( diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index f6abff89e8b..103343f5a51 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -12,6 +12,7 @@ #include "list.h" #include "net-condition.h" #include "netif-naming-scheme.h" +#include "udev-event.h" typedef struct LinkConfigContext LinkConfigContext; typedef struct LinkConfig LinkConfig; @@ -106,7 +107,7 @@ Link *link_free(Link *link); DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free); int link_get_config(LinkConfigContext *ctx, Link *link); -int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, bool test); +int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, EventMode mode); const char *mac_address_policy_to_string(MACAddressPolicy p) _const_; MACAddressPolicy mac_address_policy_from_string(const char *p) _pure_; diff --git a/src/udev/test-udev-rule-runner.c b/src/udev/test-udev-rule-runner.c index f5aa38ac3e6..10da645d0df 100644 --- a/src/udev/test-udev-rule-runner.c +++ b/src/udev/test-udev-rule-runner.c @@ -142,7 +142,7 @@ static int run(int argc, char *argv[]) { if (r < 0) return log_debug_errno(r, "Failed to open device '%s'", devpath); - assert_se(event = udev_event_new(dev, NULL)); + assert_se(event = udev_event_new(dev, NULL, EVENT_TEST_RULE_RUNNER)); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD) >= 0); diff --git a/src/udev/test-udev-spawn.c b/src/udev/test-udev-spawn.c index 0102d8d707e..7cbccf32a60 100644 --- a/src/udev/test-udev-spawn.c +++ b/src/udev/test-udev-spawn.c @@ -17,7 +17,7 @@ static void test_event_spawn_core(bool with_pidfd, const char *cmd, char *result assert_se(setenv("SYSTEMD_PIDFD", yes_no(with_pidfd), 1) >= 0); assert_se(sd_device_new_from_syspath(&dev, "/sys/class/net/lo") >= 0); - assert_se(event = udev_event_new(dev, NULL)); + assert_se(event = udev_event_new(dev, NULL, EVENT_TEST_SPAWN)); assert_se(udev_event_spawn(event, false, cmd, result_buf, buf_size, NULL) == 0); assert_se(unsetenv("SYSTEMD_PIDFD") >= 0); diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index 11419a3e611..aec36507812 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -34,95 +34,95 @@ #include "strxcpyx.h" #include "udev-builtin.h" -static void print_property(sd_device *dev, bool test, const char *name, const char *value) { +static void print_property(sd_device *dev, EventMode mode, const char *name, const char *value) { char s[256]; s[0] = '\0'; if (streq(name, "TYPE")) { - udev_builtin_add_property(dev, test, "ID_FS_TYPE", value); + udev_builtin_add_property(dev, mode, "ID_FS_TYPE", value); } else if (streq(name, "USAGE")) { - udev_builtin_add_property(dev, test, "ID_FS_USAGE", value); + udev_builtin_add_property(dev, mode, "ID_FS_USAGE", value); } else if (streq(name, "VERSION")) { - udev_builtin_add_property(dev, test, "ID_FS_VERSION", value); + udev_builtin_add_property(dev, mode, "ID_FS_VERSION", value); } else if (streq(name, "UUID")) { blkid_safe_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_UUID", s); + udev_builtin_add_property(dev, mode, "ID_FS_UUID", s); blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s); + udev_builtin_add_property(dev, mode, "ID_FS_UUID_ENC", s); } else if (streq(name, "UUID_SUB")) { blkid_safe_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s); + udev_builtin_add_property(dev, mode, "ID_FS_UUID_SUB", s); blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s); + udev_builtin_add_property(dev, mode, "ID_FS_UUID_SUB_ENC", s); } else if (streq(name, "LABEL")) { blkid_safe_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_LABEL", s); + udev_builtin_add_property(dev, mode, "ID_FS_LABEL", s); blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s); + udev_builtin_add_property(dev, mode, "ID_FS_LABEL_ENC", s); } else if (STR_IN_SET(name, "FSSIZE", "FSLASTBLOCK", "FSBLOCKSIZE")) { strscpyl(s, sizeof(s), "ID_FS_", name + 2, NULL); - udev_builtin_add_property(dev, test, s, value); + udev_builtin_add_property(dev, mode, s, value); } else if (streq(name, "PTTYPE")) { - udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value); + udev_builtin_add_property(dev, mode, "ID_PART_TABLE_TYPE", value); } else if (streq(name, "PTUUID")) { - udev_builtin_add_property(dev, test, "ID_PART_TABLE_UUID", value); + udev_builtin_add_property(dev, mode, "ID_PART_TABLE_UUID", value); } else if (streq(name, "PART_ENTRY_NAME")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s); + udev_builtin_add_property(dev, mode, "ID_PART_ENTRY_NAME", s); } else if (streq(name, "PART_ENTRY_TYPE")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s); + udev_builtin_add_property(dev, mode, "ID_PART_ENTRY_TYPE", s); } else if (startswith(name, "PART_ENTRY_")) { strscpyl(s, sizeof(s), "ID_", name, NULL); - udev_builtin_add_property(dev, test, s, value); + udev_builtin_add_property(dev, mode, s, value); } else if (streq(name, "SYSTEM_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_SYSTEM_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_SYSTEM_ID", s); } else if (streq(name, "PUBLISHER_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_PUBLISHER_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_PUBLISHER_ID", s); } else if (streq(name, "APPLICATION_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_APPLICATION_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_APPLICATION_ID", s); } else if (streq(name, "BOOT_SYSTEM_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_BOOT_SYSTEM_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_BOOT_SYSTEM_ID", s); } else if (streq(name, "VOLUME_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_VOLUME_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_VOLUME_ID", s); } else if (streq(name, "LOGICAL_VOLUME_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_LOGICAL_VOLUME_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_LOGICAL_VOLUME_ID", s); } else if (streq(name, "VOLUME_SET_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_VOLUME_SET_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_VOLUME_SET_ID", s); } else if (streq(name, "DATA_PREPARER_ID")) { blkid_encode_string(value, s, sizeof(s)); - udev_builtin_add_property(dev, test, "ID_FS_DATA_PREPARER_ID", s); + udev_builtin_add_property(dev, mode, "ID_FS_DATA_PREPARER_ID", s); } } -static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) { +static int find_gpt_root(sd_device *dev, blkid_probe pr, EventMode mode) { #if defined(SD_GPT_ROOT_NATIVE) && ENABLE_EFI @@ -201,7 +201,7 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) { /* We found the ESP/XBOOTLDR on this disk, and also found a root partition, nice! Let's export its * UUID */ if (found_esp_or_xbootldr && !sd_id128_is_null(root_id)) - udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", SD_ID128_TO_UUID_STRING(root_id)); + udev_builtin_add_property(dev, mode, "ID_PART_GPT_AUTO_ROOT_UUID", SD_ID128_TO_UUID_STRING(root_id)); #endif return 0; @@ -315,7 +315,7 @@ notloop: return 0; } -static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); const char *devnode, *root_partition = NULL, *data, *name; _cleanup_(blkid_free_probep) blkid_probe pr = NULL; @@ -422,7 +422,7 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) { if (blkid_probe_get_value(pr, i, &name, &data, NULL) < 0) continue; - print_property(dev, test, name, data); + print_property(dev, event->event_mode, name, data); /* Is this a disk with GPT partition table? */ if (streq(name, "PTTYPE") && streq(data, "gpt")) @@ -431,11 +431,11 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) { /* Is this a partition that matches the root partition * property inherited from the parent? */ if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition)) - udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1"); + udev_builtin_add_property(dev, event->event_mode, "ID_PART_GPT_AUTO_ROOT", "1"); } if (is_gpt) - find_gpt_root(dev, pr, test); + find_gpt_root(dev, pr, event->event_mode); r = read_loopback_backing_inode( dev, @@ -446,8 +446,8 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) { if (r < 0) log_device_debug_errno(dev, r, "Failed to read loopback backing inode, ignoring: %m"); else if (r > 0) { - udev_builtin_add_propertyf(dev, test, "ID_LOOP_BACKING_DEVICE", DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(backing_devno)); - udev_builtin_add_propertyf(dev, test, "ID_LOOP_BACKING_INODE", "%" PRIu64, (uint64_t) backing_inode); + udev_builtin_add_propertyf(dev, event->event_mode, "ID_LOOP_BACKING_DEVICE", DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(backing_devno)); + udev_builtin_add_propertyf(dev, event->event_mode, "ID_LOOP_BACKING_INODE", "%" PRIu64, (uint64_t) backing_inode); if (backing_fname) { /* In the worst case blkid_encode_string() will blow up to 4x the string @@ -458,8 +458,8 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[], bool test) { assert(strlen(backing_fname) < ELEMENTSOF(encoded) / 4); blkid_encode_string(backing_fname, encoded, ELEMENTSOF(encoded)); - udev_builtin_add_property(dev, test, "ID_LOOP_BACKING_FILENAME", backing_fname); - udev_builtin_add_property(dev, test, "ID_LOOP_BACKING_FILENAME_ENC", encoded); + udev_builtin_add_property(dev, event->event_mode, "ID_LOOP_BACKING_FILENAME", backing_fname); + udev_builtin_add_property(dev, event->event_mode, "ID_LOOP_BACKING_FILENAME_ENC", encoded); } } diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c index 9b12aebb3ad..fe030d05b91 100644 --- a/src/udev/udev-builtin-btrfs.c +++ b/src/udev/udev-builtin-btrfs.c @@ -12,7 +12,7 @@ #include "strxcpyx.h" #include "udev-builtin.h" -static int builtin_btrfs(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_btrfs(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -EBADF; @@ -27,7 +27,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[], bool test) { /* Driver not installed? Then we aren't ready. This is useful in initrds that lack * btrfs.ko. After the host transition (where btrfs.ko will hopefully become * available) the device can be retriggered and will then be considered ready. */ - udev_builtin_add_property(dev, test, "ID_BTRFS_READY", "0"); + udev_builtin_add_property(dev, event->event_mode, "ID_BTRFS_READY", "0"); return 0; } @@ -39,7 +39,7 @@ static int builtin_btrfs(UdevEvent *event, int argc, char *argv[], bool test) { if (r < 0) return log_device_debug_errno(dev, errno, "Failed to call BTRFS_IOC_DEVICES_READY: %m"); - udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(r == 0)); + udev_builtin_add_property(dev, event->event_mode, "ID_BTRFS_READY", one_zero(r == 0)); return 0; } diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 4540c33d982..e33a7febd6f 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -17,9 +17,13 @@ static sd_hwdb *hwdb; -int udev_builtin_hwdb_lookup(sd_device *dev, - const char *prefix, const char *modalias, - const char *filter, bool test) { +int udev_builtin_hwdb_lookup( + sd_device *dev, + const char *prefix, + const char *modalias, + const char *filter, + EventMode mode) { + _cleanup_free_ char *lookup = NULL; const char *key, *value; int n = 0, r; @@ -38,7 +42,7 @@ int udev_builtin_hwdb_lookup(sd_device *dev, if (filter && fnmatch(filter, key, FNM_NOESCAPE) != 0) continue; - r = udev_builtin_add_property(dev, test, key, value); + r = udev_builtin_add_property(dev, mode, key, value); if (r < 0) return r; n++; @@ -64,9 +68,14 @@ static const char *modalias_usb(sd_device *dev, char *s, size_t size) { return s; } -static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev, - const char *subsystem, const char *prefix, - const char *filter, bool test) { +static int udev_builtin_hwdb_search( + sd_device *dev, + sd_device *srcdev, + const char *subsystem, + const char *prefix, + const char *filter, + EventMode mode) { + char s[LINE_MAX]; bool last = false; int r = 0; @@ -99,7 +108,7 @@ static int udev_builtin_hwdb_search(sd_device *dev, sd_device *srcdev, log_device_debug(dev, "hwdb modalias key: \"%s\"", modalias); - r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test); + r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, mode); if (r > 0) break; @@ -113,7 +122,7 @@ next: return r; } -static int builtin_hwdb(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) { static const struct option options[] = { { "filter", required_argument, NULL, 'f' }, { "device", required_argument, NULL, 'd' }, @@ -160,7 +169,7 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[], bool test) { /* query a specific key given as argument */ if (argv[optind]) { - r = udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, test); + r = udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, event->event_mode); if (r < 0) return log_device_debug_errno(dev, r, "Failed to look up hwdb: %m"); if (r == 0) @@ -175,7 +184,7 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[], bool test) { return log_device_debug_errno(dev, r, "Failed to create sd_device object '%s': %m", device); } - r = udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test); + r = udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, event->event_mode); if (r < 0) return log_device_debug_errno(dev, r, "Failed to look up hwdb: %m"); if (r == 0) diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 295e8d21594..6f75d9df22c 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -44,7 +44,7 @@ static int abs_size_mm(const struct input_absinfo *absinfo) { return (absinfo->maximum - absinfo->minimum) / absinfo->resolution; } -static void extract_info(sd_device *dev, bool test) { +static void extract_info(sd_device *dev, EventMode mode) { char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)]; struct input_absinfo xabsinfo = {}, yabsinfo = {}; _cleanup_close_ int fd = -EBADF; @@ -63,8 +63,8 @@ static void extract_info(sd_device *dev, bool test) { xsprintf(width, "%d", abs_size_mm(&xabsinfo)); xsprintf(height, "%d", abs_size_mm(&yabsinfo)); - udev_builtin_add_property(dev, test, "ID_INPUT_WIDTH_MM", width); - udev_builtin_add_property(dev, test, "ID_INPUT_HEIGHT_MM", height); + udev_builtin_add_property(dev, mode, "ID_INPUT_WIDTH_MM", width); + udev_builtin_add_property(dev, mode, "ID_INPUT_HEIGHT_MM", height); } /* @@ -73,9 +73,13 @@ static void extract_info(sd_device *dev, bool test) { * @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(sd_device *pdev, const char* attr, - unsigned long *bitmask, size_t bitmask_size, - bool test) { +static void get_cap_mask( + sd_device *pdev, + const char* attr, + unsigned long *bitmask, + size_t bitmask_size, + EventMode mode) { + const char *v; char text[4096]; unsigned i; @@ -110,7 +114,7 @@ static void get_cap_mask(sd_device *pdev, const char* attr, else log_device_debug(pdev, "Ignoring %s block %lX which is larger than maximum size", attr, val); - if (test && DEBUG_LOGGING) { + if (mode == EVENT_UDEVADM_TEST_BUILTIN && DEBUG_LOGGING) { log_device_debug(pdev, "%s decoded bit map:", attr); val = bitmask_size / sizeof (unsigned long); @@ -144,14 +148,16 @@ static struct input_id get_input_id(sd_device *dev) { } /* pointer devices */ -static bool test_pointers(sd_device *dev, - const struct input_id *id, - const unsigned long* bitmask_ev, - const unsigned long* bitmask_abs, - const unsigned long* bitmask_key, - const unsigned long* bitmask_rel, - const unsigned long* bitmask_props, - bool test) { +static bool test_pointers( + sd_device *dev, + const struct input_id *id, + const unsigned long* bitmask_ev, + const unsigned long* bitmask_abs, + const unsigned long* bitmask_key, + const unsigned long* bitmask_rel, + const unsigned long* bitmask_props, + EventMode mode) { + bool has_abs_coordinates = false; bool has_rel_coordinates = false; bool has_mt_coordinates = false; @@ -186,7 +192,7 @@ static bool test_pointers(sd_device *dev, is_accelerometer = true; if (is_accelerometer) { - udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_ACCELEROMETER", "1"); return true; } @@ -309,28 +315,29 @@ static bool test_pointers(sd_device *dev, } if (is_pointing_stick) - udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_POINTINGSTICK", "1"); if (is_mouse || is_abs_mouse) - udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_MOUSE", "1"); if (is_touchpad) - udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_TOUCHPAD", "1"); if (is_touchscreen) - udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_TOUCHSCREEN", "1"); if (is_joystick) - udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_JOYSTICK", "1"); if (is_tablet) - udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_TABLET", "1"); if (is_tablet_pad) - udev_builtin_add_property(dev, test, "ID_INPUT_TABLET_PAD", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_TABLET_PAD", "1"); return is_tablet || is_mouse || is_abs_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick; } /* key like devices */ -static bool test_key(sd_device *dev, - const unsigned long* bitmask_ev, - const unsigned long* bitmask_key, - bool test) { +static bool test_key( + sd_device *dev, + const unsigned long* bitmask_ev, + const unsigned long* bitmask_key, + EventMode mode) { bool found = false; @@ -357,19 +364,19 @@ static bool test_key(sd_device *dev, } if (found) - udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_KEY", "1"); /* the first 32 bits are ESC, numbers, and Q to D; if we have all of * those, consider it a full keyboard; do not test KEY_RESERVED, though */ if (FLAGS_SET(bitmask_key[0], 0xFFFFFFFE)) { - udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1"); + udev_builtin_add_property(dev, mode, "ID_INPUT_KEYBOARD", "1"); return true; } return found; } -static int builtin_input_id(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_input_id(UdevEvent *event, int argc, char *argv[]) { sd_device *pdev, *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); unsigned long bitmask_ev[NBITS(EV_MAX)]; unsigned long bitmask_abs[NBITS(ABS_MAX)]; @@ -400,28 +407,28 @@ static int builtin_input_id(UdevEvent *event, int argc, char *argv[], bool test) /* Use this as a flag that input devices were detected, so that this * program doesn't need to be called more than once per device */ - udev_builtin_add_property(dev, test, "ID_INPUT", "1"); - get_cap_mask(pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test); - get_cap_mask(pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test); - get_cap_mask(pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test); - get_cap_mask(pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test); - get_cap_mask(pdev, "properties", bitmask_props, sizeof(bitmask_props), test); + udev_builtin_add_property(dev, event->event_mode, "ID_INPUT", "1"); + get_cap_mask(pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), event->event_mode); + get_cap_mask(pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), event->event_mode); + get_cap_mask(pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), event->event_mode); + get_cap_mask(pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), event->event_mode); + get_cap_mask(pdev, "properties", bitmask_props, sizeof(bitmask_props), event->event_mode); is_pointer = test_pointers(dev, &id, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, - bitmask_props, test); - is_key = test_key(dev, bitmask_ev, bitmask_key, test); + bitmask_props, event->event_mode); + is_key = test_key(dev, bitmask_ev, bitmask_key, event->event_mode); /* Some evdev nodes have only a scrollwheel */ if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) && (test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel))) - udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1"); + udev_builtin_add_property(dev, event->event_mode, "ID_INPUT_KEY", "1"); if (test_bit(EV_SW, bitmask_ev)) - udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1"); + udev_builtin_add_property(dev, event->event_mode, "ID_INPUT_SWITCH", "1"); } if (sd_device_get_sysname(dev, &sysname) >= 0 && startswith(sysname, "event")) - extract_info(dev, test); + extract_info(dev, event->event_mode); return 0; } diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c index 3903bc463f3..e1e6de04269 100644 --- a/src/udev/udev-builtin-keyboard.c +++ b/src/udev/udev-builtin-keyboard.c @@ -159,7 +159,7 @@ static int set_trackpoint_sensitivity(sd_device *dev, const char *value) { return 0; } -static int builtin_keyboard(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_keyboard(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); unsigned release[1024]; unsigned release_count = 0; @@ -167,6 +167,11 @@ static int builtin_keyboard(UdevEvent *event, int argc, char *argv[], bool test) const char *node; int has_abs = -1, r; + if (event->event_mode != EVENT_UDEV_WORKER) { + log_device_debug(dev, "Running in test mode, skipping execution of 'keyboard' builtin command."); + return 0; + } + r = sd_device_get_devname(dev, &node); if (r < 0) return log_device_error_errno(dev, r, "Failed to get device name: %m"); diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index 3ab5c485f80..6d37af88a3a 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -22,10 +22,15 @@ _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(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_kmod(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); int r; + if (event->event_mode != EVENT_UDEV_WORKER) { + log_device_debug(dev, "Running in test mode, skipping execution of 'kmod' builtin command."); + return 0; + } + if (!ctx) return 0; diff --git a/src/udev/udev-builtin-net_driver.c b/src/udev/udev-builtin-net_driver.c index f1642a491dc..90a9e8d22f7 100644 --- a/src/udev/udev-builtin-net_driver.c +++ b/src/udev/udev-builtin-net_driver.c @@ -9,7 +9,7 @@ #include "string-util.h" #include "udev-builtin.h" -static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv, bool test) { +static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); _cleanup_close_ int ethtool_fd = -EBADF; _cleanup_free_ char *driver = NULL; @@ -32,7 +32,7 @@ static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv if (r < 0) return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", sysname); - return udev_builtin_add_property(event->dev, test, "ID_NET_DRIVER", driver); + return udev_builtin_add_property(event->dev, event->event_mode, "ID_NET_DRIVER", driver); } const UdevBuiltin udev_builtin_net_driver = { diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 8ef3abada95..0d87a35288a 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -298,7 +298,7 @@ static int pci_get_onboard_index(sd_device *dev, unsigned *ret) { return 0; } -static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, bool test) { +static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, EventMode mode) { _cleanup_free_ char *port = NULL; unsigned idx = 0; /* avoid false maybe-uninitialized warning */ int r; @@ -318,7 +318,7 @@ static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *pre char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%so%u%s%s", prefix, idx, strempty(port), strempty(suffix))) - udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_ONBOARD", str); log_device_debug(dev, "Onboard index identifier: index=%u port=%s %s %s", idx, strna(port), @@ -327,7 +327,7 @@ static int names_pci_onboard(sd_device *dev, sd_device *pci_dev, const char *pre return 0; } -static int names_pci_onboard_label(sd_device *dev, sd_device *pci_dev, const char *prefix, bool test) { +static int names_pci_onboard_label(sd_device *dev, sd_device *pci_dev, const char *prefix, EventMode mode) { const char *label; int r; @@ -343,7 +343,7 @@ static int names_pci_onboard_label(sd_device *dev, sd_device *pci_dev, const cha if (snprintf_ok(str, sizeof str, "%s%s", naming_scheme_has(NAMING_LABEL_NOPREFIX) ? "" : prefix, label)) - udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str); + udev_builtin_add_property(dev, mode, "ID_NET_LABEL_ONBOARD", str); log_device_debug(dev, "Onboard label from PCI device: %s", label); return 0; @@ -613,7 +613,7 @@ static int get_pci_slot_specifiers( return 0; } -static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, bool test) { +static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix, const char *suffix, EventMode mode) { _cleanup_free_ char *domain = NULL, *bus_and_slot = NULL, *func = NULL, *port = NULL; uint32_t hotplug_slot = 0; /* avoid false maybe-uninitialized warning */ char str[ALTIFNAMSIZ]; @@ -634,7 +634,7 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix /* compose a name based on the raw kernel's PCI bus, slot numbers */ if (snprintf_ok(str, sizeof str, "%s%s%s%s%s%s", prefix, strempty(domain), bus_and_slot, strempty(func), strempty(port), strempty(suffix))) - udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); log_device_debug(dev, "PCI path identifier: domain=%s bus_and_slot=%s func=%s port=%s %s %s", strna(domain), bus_and_slot, strna(func), strna(port), @@ -650,7 +650,7 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix if (snprintf_ok(str, sizeof str, "%s%ss%"PRIu32"%s%s%s", prefix, strempty(domain), hotplug_slot, strempty(func), strempty(port), strempty(suffix))) - udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); log_device_debug(dev, "Slot identifier: domain=%s slot=%"PRIu32" func=%s port=%s %s %s", strna(domain), hotplug_slot, strna(func), strna(port), @@ -659,7 +659,7 @@ static int names_pci_slot(sd_device *dev, sd_device *pci_dev, const char *prefix return 0; } -static int names_vio(sd_device *dev, const char *prefix, bool test) { +static int names_vio(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_free_ char *s = NULL; unsigned slotid; int r; @@ -698,13 +698,13 @@ static int names_vio(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%sv%u", prefix, slotid)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); log_device_debug(dev, "Vio slot identifier: slotid=%u %s %s", slotid, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; } -static int names_platform(sd_device *dev, const char *prefix, bool test) { +static int names_platform(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_free_ char *p = NULL; const char *validchars; char *vendor, *model_str, *instance_str; @@ -760,13 +760,13 @@ static int names_platform(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%sa%s%xi%u", prefix, vendor, model, instance)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); log_device_debug(dev, "Platform identifier: vendor=%s model=%x instance=%u %s %s", vendor, model, instance, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; } -static int names_devicetree(sd_device *dev, const char *prefix, bool test) { +static int names_devicetree(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_(sd_device_unrefp) sd_device *aliases_dev = NULL, *ofnode_dev = NULL, *devicetree_dev = NULL; const char *ofnode_path, *ofnode_syspath, *devicetree_syspath; sd_device *parent; @@ -858,7 +858,7 @@ static int names_devicetree(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%sd%u", prefix, i)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_ONBOARD", str); log_device_debug(dev, "devicetree identifier: alias_index=%u %s \"%s\"", i, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; @@ -867,7 +867,7 @@ static int names_devicetree(sd_device *dev, const char *prefix, bool test) { return -ENOENT; } -static int names_pci(sd_device *dev, const char *prefix, bool test) { +static int names_pci(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL; _cleanup_free_ char *virtfn_suffix = NULL; sd_device *parent; @@ -884,10 +884,10 @@ static int names_pci(sd_device *dev, const char *prefix, bool test) { get_virtfn_info(parent, &physfn_pcidev, &virtfn_suffix) >= 0) parent = physfn_pcidev; else - (void) names_pci_onboard_label(dev, parent, prefix, test); + (void) names_pci_onboard_label(dev, parent, prefix, mode); - (void) names_pci_onboard(dev, parent, prefix, virtfn_suffix, test); - (void) names_pci_slot(dev, parent, prefix, virtfn_suffix, test); + (void) names_pci_onboard(dev, parent, prefix, virtfn_suffix, mode); + (void) names_pci_slot(dev, parent, prefix, virtfn_suffix, mode); return 0; } @@ -950,7 +950,7 @@ static int get_usb_specifier(sd_device *dev, char **ret) { return 0; } -static int names_usb(sd_device *dev, const char *prefix, bool test) { +static int names_usb(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_free_ char *suffix = NULL; sd_device *usbdev, *pcidev; int r; @@ -971,7 +971,7 @@ static int names_usb(sd_device *dev, const char *prefix, bool test) { /* If the USB bus is on PCI bus, then suffix the USB specifier to the name based on the PCI bus. */ r = sd_device_get_parent_with_subsystem_devtype(usbdev, "pci", NULL, &pcidev); if (r >= 0) - return names_pci_slot(dev, pcidev, prefix, suffix, test); + return names_pci_slot(dev, pcidev, prefix, suffix, mode); if (r != -ENOENT || !naming_scheme_has(NAMING_USB_HOST)) return log_device_debug_errno(usbdev, r, "Failed to get parent PCI bus: %m"); @@ -979,7 +979,7 @@ static int names_usb(sd_device *dev, const char *prefix, bool test) { /* Otherwise, e.g. on-chip asics that have USB ports, use the USB specifier as is. */ char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%s%s", prefix, suffix)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); return 0; } @@ -1014,7 +1014,7 @@ static int get_bcma_specifier(sd_device *dev, char **ret) { return 0; } -static int names_bcma(sd_device *dev, const char *prefix, bool test) { +static int names_bcma(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_free_ char *suffix = NULL; sd_device *bcmadev, *pcidev; int r; @@ -1034,10 +1034,10 @@ static int names_bcma(sd_device *dev, const char *prefix, bool test) { if (r < 0) return r; - return names_pci_slot(dev, pcidev, prefix, suffix, test); + return names_pci_slot(dev, pcidev, prefix, suffix, mode); } -static int names_ccw(sd_device *dev, const char *prefix, bool test) { +static int names_ccw(sd_device *dev, const char *prefix, EventMode mode) { sd_device *cdev; const char *bus_id; size_t bus_id_start, bus_id_len; @@ -1079,14 +1079,14 @@ static int names_ccw(sd_device *dev, const char *prefix, bool test) { /* Use the CCW bus-ID as network device name */ char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%sc%s", prefix, bus_id)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); log_device_debug(dev, "CCW identifier: ccw_busid=%s %s \"%s\"", bus_id, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; } /* IEEE Organizationally Unique Identifier vendor string */ -static int ieee_oui(sd_device *dev, const struct hw_addr_data *hw_addr, bool test) { +static int ieee_oui(sd_device *dev, const struct hw_addr_data *hw_addr, EventMode mode) { char str[32]; assert(dev); @@ -1109,10 +1109,10 @@ static int ieee_oui(sd_device *dev, const struct hw_addr_data *hw_addr, bool tes hw_addr->bytes[4], hw_addr->bytes[5]); - return udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test); + return udev_builtin_hwdb_lookup(dev, NULL, str, NULL, mode); } -static int names_mac(sd_device *dev, const char *prefix, bool test) { +static int names_mac(sd_device *dev, const char *prefix, EventMode mode) { unsigned iftype, assign_type; struct hw_addr_data hw_addr; const char *s; @@ -1156,16 +1156,16 @@ static int names_mac(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; xsprintf(str, "%sx%s", prefix, HW_ADDR_TO_STR_FULL(&hw_addr, HW_ADDR_TO_STRING_NO_COLON)); - udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_MAC", str); log_device_debug(dev, "MAC address identifier: hw_addr=%s %s %s", HW_ADDR_TO_STR(&hw_addr), special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); - (void) ieee_oui(dev, &hw_addr, test); + (void) ieee_oui(dev, &hw_addr, mode); return 0; } -static int names_netdevsim(sd_device *dev, const char *prefix, bool test) { +static int names_netdevsim(sd_device *dev, const char *prefix, EventMode mode) { sd_device *netdevsimdev; const char *sysnum, *phys_port_name; unsigned addr; @@ -1200,13 +1200,13 @@ static int names_netdevsim(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%si%un%s", prefix, addr, phys_port_name)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_PATH", str); log_device_debug(dev, "Netdevsim identifier: address=%u, port_name=%s %s %s", addr, phys_port_name, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; } -static int names_xen(sd_device *dev, const char *prefix, bool test) { +static int names_xen(sd_device *dev, const char *prefix, EventMode mode) { _cleanup_free_ char *vif = NULL; const char *p; unsigned id; @@ -1240,7 +1240,7 @@ static int names_xen(sd_device *dev, const char *prefix, bool test) { char str[ALTIFNAMSIZ]; if (snprintf_ok(str, sizeof str, "%sX%u", prefix, id)) - udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + udev_builtin_add_property(dev, mode, "ID_NET_NAME_SLOT", str); log_device_debug(dev, "Xen identifier: id=%u %s %s", id, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), str + strlen(prefix)); return 0; @@ -1300,7 +1300,7 @@ static int device_is_stacked(sd_device *dev) { return ifindex != iflink; } -static int builtin_net_id(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_net_id(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); const char *prefix; int r; @@ -1318,18 +1318,18 @@ static int builtin_net_id(UdevEvent *event, int argc, char *argv[], bool test) { return 0; } - udev_builtin_add_property(dev, test, "ID_NET_NAMING_SCHEME", naming_scheme()->name); - - (void) names_mac(dev, prefix, test); - (void) names_devicetree(dev, prefix, test); - (void) names_ccw(dev, prefix, test); - (void) names_vio(dev, prefix, test); - (void) names_platform(dev, prefix, test); - (void) names_netdevsim(dev, prefix, test); - (void) names_xen(dev, prefix, test); - (void) names_pci(dev, prefix, test); - (void) names_usb(dev, prefix, test); - (void) names_bcma(dev, prefix, test); + udev_builtin_add_property(dev, event->event_mode, "ID_NET_NAMING_SCHEME", naming_scheme()->name); + + (void) names_mac(dev, prefix, event->event_mode); + (void) names_devicetree(dev, prefix, event->event_mode); + (void) names_ccw(dev, prefix, event->event_mode); + (void) names_vio(dev, prefix, event->event_mode); + (void) names_platform(dev, prefix, event->event_mode); + (void) names_netdevsim(dev, prefix, event->event_mode); + (void) names_xen(dev, prefix, event->event_mode); + (void) names_pci(dev, prefix, event->event_mode); + (void) names_usb(dev, prefix, event->event_mode); + (void) names_bcma(dev, prefix, event->event_mode); return 0; } diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index df89679de34..8cfcaa932fb 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -12,7 +12,7 @@ static LinkConfigContext *ctx = NULL; -static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool test) { +static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); _cleanup_(link_freep) Link *link = NULL; int r; @@ -30,13 +30,13 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool device_action_to_string(action)); /* Import previously assigned .link file name. */ - (void) udev_builtin_import_property(dev, event->dev_db_clone, test, "ID_NET_LINK_FILE"); - (void) udev_builtin_import_property(dev, event->dev_db_clone, test, "ID_NET_LINK_FILE_DROPINS"); + (void) udev_builtin_import_property(dev, event->dev_db_clone, event->event_mode, "ID_NET_LINK_FILE"); + (void) udev_builtin_import_property(dev, event->dev_db_clone, event->event_mode, "ID_NET_LINK_FILE_DROPINS"); /* Set ID_NET_NAME= with the current interface name. */ const char *value; if (sd_device_get_sysname(dev, &value) >= 0) - (void) udev_builtin_add_property(dev, test, "ID_NET_NAME", value); + (void) udev_builtin_add_property(dev, event->event_mode, "ID_NET_NAME", value); return 0; } @@ -59,7 +59,7 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool return log_device_error_errno(dev, r, "Failed to get link config: %m"); } - r = link_apply_config(ctx, &event->rtnl, link, test); + r = link_apply_config(ctx, &event->rtnl, link, event->event_mode); if (r == -ENODEV) log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring."); else if (r < 0) diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index dc0630596b9..a23b32db3e9 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -642,7 +642,7 @@ static int find_real_nvme_parent(sd_device *dev, sd_device **ret) { return 0; } -static void add_id_with_usb_revision(sd_device *dev, bool test, char *path) { +static void add_id_with_usb_revision(sd_device *dev, EventMode mode, char *path) { char *p; assert(dev); @@ -659,13 +659,13 @@ static void add_id_with_usb_revision(sd_device *dev, bool test, char *path) { if (p[1] != '-') return; - (void) udev_builtin_add_property(dev, test, "ID_PATH_WITH_USB_REVISION", path); + (void) udev_builtin_add_property(dev, mode, "ID_PATH_WITH_USB_REVISION", path); /* Drop the USB revision specifier for backward compatibility. */ memmove(p - 1, p + 1, strlen(p + 1) + 1); } -static void add_id_tag(sd_device *dev, bool test, const char *path) { +static void add_id_tag(sd_device *dev, EventMode mode, const char *path) { char tag[UDEV_NAME_SIZE]; size_t i = 0; @@ -693,10 +693,10 @@ static void add_id_tag(sd_device *dev, bool test, const char *path) { i--; tag[i] = '\0'; - (void) udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag); + (void) udev_builtin_add_property(dev, mode, "ID_PATH_TAG", tag); } -static int builtin_path_id(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_path_id(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); _cleanup_(sd_device_unrefp) sd_device *dev_other_branch = NULL; _cleanup_free_ char *path = NULL, *compat_path = NULL; @@ -851,11 +851,11 @@ static int builtin_path_id(UdevEvent *event, int argc, char *argv[], bool test) if (device_in_subsystem(dev, "block") && !supported_transport) return -ENOENT; - add_id_with_usb_revision(dev, test, path); + add_id_with_usb_revision(dev, event->event_mode, path); - (void) udev_builtin_add_property(dev, test, "ID_PATH", path); + (void) udev_builtin_add_property(dev, event->event_mode, "ID_PATH", path); - add_id_tag(dev, test, path); + add_id_tag(dev, event->event_mode, path); /* * Compatible link generation for ATA devices @@ -863,7 +863,7 @@ static int builtin_path_id(UdevEvent *event, int argc, char *argv[], bool test) * ID_PATH_ATA_COMPAT */ if (compat_path) - (void) udev_builtin_add_property(dev, test, "ID_PATH_ATA_COMPAT", compat_path); + (void) udev_builtin_add_property(dev, event->event_mode, "ID_PATH_ATA_COMPAT", compat_path); return 0; } diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c index da42ef59b03..805d048e819 100644 --- a/src/udev/udev-builtin-uaccess.c +++ b/src/udev/udev-builtin-uaccess.c @@ -17,13 +17,18 @@ #include "log.h" #include "udev-builtin.h" -static int builtin_uaccess(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_uaccess(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); const char *path = NULL, *seat; bool changed_acl = false; uid_t uid; int r; + if (event->event_mode != EVENT_UDEV_WORKER) { + log_device_debug(dev, "Running in test mode, skipping execution of 'uaccess' builtin command."); + return 0; + } + umask(0022); /* don't muck around with ACLs when the system is not running systemd */ diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index f5b8fe9e9ad..2413f9ce9e0 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -224,7 +224,7 @@ static int dev_if_packed_info(sd_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(UdevEvent *event, int argc, char *argv[], bool test) { +static int builtin_usb_id(UdevEvent *event, int argc, char *argv[]) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); char vendor_str[64] = ""; char vendor_str_enc[256]; @@ -429,55 +429,55 @@ fallback: if (sd_device_get_property_value(dev, "ID_BUS", NULL) >= 0) log_device_debug(dev, "ID_BUS property is already set, setting only properties prefixed with \"ID_USB_\"."); else { - udev_builtin_add_property(dev, test, "ID_BUS", "usb"); + udev_builtin_add_property(dev, event->event_mode, "ID_BUS", "usb"); - udev_builtin_add_property(dev, test, "ID_MODEL", model_str); - udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc); - udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id); + udev_builtin_add_property(dev, event->event_mode, "ID_MODEL", model_str); + udev_builtin_add_property(dev, event->event_mode, "ID_MODEL_ENC", model_str_enc); + udev_builtin_add_property(dev, event->event_mode, "ID_MODEL_ID", product_id); - udev_builtin_add_property(dev, test, "ID_SERIAL", serial); + udev_builtin_add_property(dev, event->event_mode, "ID_SERIAL", serial); if (!isempty(serial_str)) - udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str); + udev_builtin_add_property(dev, event->event_mode, "ID_SERIAL_SHORT", serial_str); - udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str); - udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc); - udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id); + udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR", vendor_str); + udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR_ENC", vendor_str_enc); + udev_builtin_add_property(dev, event->event_mode, "ID_VENDOR_ID", vendor_id); - udev_builtin_add_property(dev, test, "ID_REVISION", revision_str); + udev_builtin_add_property(dev, event->event_mode, "ID_REVISION", revision_str); if (!isempty(type_str)) - udev_builtin_add_property(dev, test, "ID_TYPE", type_str); + udev_builtin_add_property(dev, event->event_mode, "ID_TYPE", type_str); if (!isempty(instance_str)) - udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str); + udev_builtin_add_property(dev, event->event_mode, "ID_INSTANCE", instance_str); } /* Also export the same values in the above by prefixing ID_USB_. */ - udev_builtin_add_property(dev, test, "ID_USB_MODEL", model_str); - udev_builtin_add_property(dev, test, "ID_USB_MODEL_ENC", model_str_enc); - udev_builtin_add_property(dev, test, "ID_USB_MODEL_ID", product_id); - udev_builtin_add_property(dev, test, "ID_USB_SERIAL", serial); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL", model_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL_ENC", model_str_enc); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_MODEL_ID", product_id); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_SERIAL", serial); if (!isempty(serial_str)) - udev_builtin_add_property(dev, test, "ID_USB_SERIAL_SHORT", serial_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_SERIAL_SHORT", serial_str); - udev_builtin_add_property(dev, test, "ID_USB_VENDOR", vendor_str); - udev_builtin_add_property(dev, test, "ID_USB_VENDOR_ENC", vendor_str_enc); - udev_builtin_add_property(dev, test, "ID_USB_VENDOR_ID", vendor_id); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR", vendor_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR_ENC", vendor_str_enc); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_VENDOR_ID", vendor_id); - udev_builtin_add_property(dev, test, "ID_USB_REVISION", revision_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_REVISION", revision_str); if (!isempty(type_str)) - udev_builtin_add_property(dev, test, "ID_USB_TYPE", type_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_TYPE", type_str); if (!isempty(instance_str)) - udev_builtin_add_property(dev, test, "ID_USB_INSTANCE", instance_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_INSTANCE", instance_str); if (!isempty(packed_if_str)) - udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_INTERFACES", packed_if_str); if (ifnum) - udev_builtin_add_property(dev, test, "ID_USB_INTERFACE_NUM", ifnum); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_INTERFACE_NUM", ifnum); if (driver) - udev_builtin_add_property(dev, test, "ID_USB_DRIVER", driver); + udev_builtin_add_property(dev, event->event_mode, "ID_USB_DRIVER", driver); return 0; } diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index 6caea8eccee..1a1cb3734d0 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -99,7 +99,7 @@ UdevBuiltinCommand udev_builtin_lookup(const char *command) { return _UDEV_BUILTIN_INVALID; } -int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command, bool test) { +int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command) { _cleanup_strv_free_ char **argv = NULL; int r; @@ -117,10 +117,10 @@ int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *comma /* we need '0' here to reset the internal state */ optind = 0; - return builtins[cmd]->cmd(event, strv_length(argv), argv, test); + return builtins[cmd]->cmd(event, strv_length(argv), argv); } -int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) { +int udev_builtin_add_property(sd_device *dev, EventMode mode, const char *key, const char *val) { int r; assert(dev); @@ -131,13 +131,13 @@ int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const return log_device_debug_errno(dev, r, "Failed to add property '%s%s%s'", key, val ? "=" : "", strempty(val)); - if (test) + if (mode == EVENT_UDEVADM_TEST_BUILTIN) printf("%s=%s\n", key, strempty(val)); return 0; } -int udev_builtin_add_propertyf(sd_device *dev, bool test, const char *key, const char *valf, ...) { +int udev_builtin_add_propertyf(sd_device *dev, EventMode mode, const char *key, const char *valf, ...) { _cleanup_free_ char *val = NULL; va_list ap; int r; @@ -152,10 +152,10 @@ int udev_builtin_add_propertyf(sd_device *dev, bool test, const char *key, const if (r < 0) return log_oom_debug(); - return udev_builtin_add_property(dev, test, key, val); + return udev_builtin_add_property(dev, mode, key, val); } -int udev_builtin_import_property(sd_device *dev, sd_device *src, bool test, const char *key) { +int udev_builtin_import_property(sd_device *dev, sd_device *src, EventMode mode, const char *key) { const char *val; int r; @@ -171,7 +171,7 @@ int udev_builtin_import_property(sd_device *dev, sd_device *src, bool test, cons if (r < 0) return log_device_debug_errno(src, r, "Failed to get property \"%s\", ignoring: %m", key); - r = udev_builtin_add_property(dev, test, key, val); + r = udev_builtin_add_property(dev, mode, key, val); if (r < 0) return r; diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h index c7a48b0201c..0d82bebf23a 100644 --- a/src/udev/udev-builtin.h +++ b/src/udev/udev-builtin.h @@ -34,7 +34,7 @@ typedef enum UdevBuiltinCommand { typedef struct UdevBuiltin { const char *name; - int (*cmd)(UdevEvent *event, int argc, char *argv[], bool test); + int (*cmd)(UdevEvent *event, int argc, char *argv[]); const char *help; int (*init)(void); void (*exit)(void); @@ -79,11 +79,11 @@ void udev_builtin_exit(void); UdevBuiltinCommand udev_builtin_lookup(const char *command); const char *udev_builtin_name(UdevBuiltinCommand cmd); bool udev_builtin_run_once(UdevBuiltinCommand cmd); -int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command, bool test); +int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command); void udev_builtin_list(void); bool udev_builtin_should_reload(void); -int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val); -int udev_builtin_add_propertyf(sd_device *dev, bool test, const char *key, const char *valf, ...) _printf_(4, 5); -int udev_builtin_import_property(sd_device *dev, sd_device *src, bool test, const char *key); +int udev_builtin_add_property(sd_device *dev, EventMode mode, const char *key, const char *val); +int udev_builtin_add_propertyf(sd_device *dev, EventMode mode, const char *key, const char *valf, ...) _printf_(4, 5); +int udev_builtin_import_property(sd_device *dev, sd_device *src, EventMode mode, const char *key); int udev_builtin_hwdb_lookup(sd_device *dev, const char *prefix, const char *modalias, - const char *filter, bool test); + const char *filter, EventMode mode); diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 68c7fed8a1f..607071a8cf6 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -16,7 +16,7 @@ #include "udev-util.h" #include "user-util.h" -UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker) { +UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode) { int log_level = worker ? worker->log_level : log_get_max_level(); UdevEvent *event; @@ -36,6 +36,7 @@ UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker) { .mode = MODE_INVALID, .log_level_was_debug = log_level == LOG_DEBUG, .default_log_level = log_level, + .event_mode = mode, }; return event; @@ -110,6 +111,9 @@ static int rename_netif(UdevEvent *event) { assert(event); + if (!EVENT_MODE_DESTRUCTIVE(event)) + return 0; + if (!event->name) return 0; /* No new name is requested. */ @@ -222,6 +226,9 @@ static int assign_altnames(UdevEvent *event) { int ifindex, r; const char *s; + if (!EVENT_MODE_DESTRUCTIVE(event)) + return 0; + if (strv_isempty(event->altnames)) return 0; @@ -250,6 +257,9 @@ static int update_devnode(UdevEvent *event) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); int r; + if (!EVENT_MODE_DESTRUCTIVE(event)) + return 0; + r = sd_device_get_devnum(dev, NULL); if (r == -ENOENT) return 0; @@ -291,18 +301,22 @@ static int event_execute_rules_on_remove(UdevEvent *event, UdevRules *rules) { if (r < 0) log_device_debug_errno(dev, r, "Failed to read database under /run/udev/data/: %m"); - r = device_tag_index(dev, NULL, false); - if (r < 0) - log_device_debug_errno(dev, r, "Failed to remove corresponding tag files under /run/udev/tag/, ignoring: %m"); + if (EVENT_MODE_DESTRUCTIVE(event)) { + r = device_tag_index(dev, NULL, false); + if (r < 0) + log_device_debug_errno(dev, r, "Failed to remove corresponding tag files under /run/udev/tag/, ignoring: %m"); - r = device_delete_db(dev); - if (r < 0) - log_device_debug_errno(dev, r, "Failed to delete database under /run/udev/data/, ignoring: %m"); + r = device_delete_db(dev); + if (r < 0) + log_device_debug_errno(dev, r, "Failed to delete database under /run/udev/data/, ignoring: %m"); + } r = udev_rules_apply_to_event(rules, event); - if (sd_device_get_devnum(dev, NULL) >= 0) - (void) udev_node_remove(dev); + if (EVENT_MODE_DESTRUCTIVE(event)) { + if (sd_device_get_devnum(dev, NULL) >= 0) + (void) udev_node_remove(dev); + } return r; } @@ -328,6 +342,9 @@ static int update_clone(UdevEvent *event) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev_db_clone); int r; + if (!EVENT_MODE_DESTRUCTIVE(event)) + return 0; + /* Drop previously added property for safety to make IMPORT{db}="ID_RENAMING" not work. This is * mostly for 'move' uevent, but let's do unconditionally. Why? If a network interface is renamed in * initrd, then udevd may lose the 'move' uevent during switching root. Usually, we do not set the @@ -357,7 +374,9 @@ int udev_event_execute_rules(UdevEvent *event, UdevRules *rules) { sd_device *dev; int r; - dev = ASSERT_PTR(ASSERT_PTR(event)->dev); + assert(event); + assert(IN_SET(event->event_mode, EVENT_UDEV_WORKER, EVENT_UDEVADM_TEST, EVENT_TEST_RULE_RUNNER)); + dev = ASSERT_PTR(event->dev); assert(rules); r = sd_device_get_action(dev, &action); @@ -404,10 +423,12 @@ int udev_event_execute_rules(UdevEvent *event, UdevRules *rules) { if (r < 0) return log_device_debug_errno(dev, r, "Failed to set initialization timestamp: %m"); - /* (re)write database file */ - r = device_tag_index(dev, event->dev_db_clone, true); - if (r < 0) - return log_device_debug_errno(dev, r, "Failed to update tags under /run/udev/tag/: %m"); + if (EVENT_MODE_DESTRUCTIVE(event)) { + /* (re)write database file */ + r = device_tag_index(dev, event->dev_db_clone, true); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to update tags under /run/udev/tag/: %m"); + } /* If the database file for the device will be created below, add ID_PROCESSING=1 to indicate that * the device is still being processed by udevd, as commands specified in RUN are invoked after @@ -418,9 +439,11 @@ int udev_event_execute_rules(UdevEvent *event, UdevRules *rules) { return log_device_warning_errno(dev, r, "Failed to add 'ID_PROCESSING' property: %m"); } - r = device_update_db(dev); - if (r < 0) - return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m"); + if (EVENT_MODE_DESTRUCTIVE(event)) { + r = device_update_db(dev); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m"); + } device_set_is_initialized(dev); diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h index 5ff7bd7ec1b..3dc89365bb3 100644 --- a/src/udev/udev-event.h +++ b/src/udev/udev-event.h @@ -18,6 +18,14 @@ #include "udev-worker.h" #include "user-util.h" +typedef enum EventMode { + EVENT_UDEV_WORKER, + EVENT_UDEVADM_TEST, + EVENT_UDEVADM_TEST_BUILTIN, + EVENT_TEST_RULE_RUNNER, + EVENT_TEST_SPAWN, +} EventMode; + typedef struct UdevEvent { UdevWorker *worker; sd_netlink *rtnl; @@ -47,10 +55,16 @@ typedef struct UdevEvent { bool run_final; bool log_level_was_debug; int default_log_level; + EventMode event_mode; } UdevEvent; -UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker); +UdevEvent *udev_event_new(sd_device *dev, UdevWorker *worker, EventMode mode); UdevEvent *udev_event_free(UdevEvent *event); DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free); int udev_event_execute_rules(UdevEvent *event, UdevRules *rules); + +static inline bool EVENT_MODE_DESTRUCTIVE(UdevEvent *event) { + assert(event); + return IN_SET(event->event_mode, EVENT_UDEV_WORKER, EVENT_TEST_RULE_RUNNER); +} diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 3ec675746bc..89840e3fb92 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -2100,7 +2100,7 @@ static int udev_rule_apply_token_to_event( return false; } - log_event_debug(dev, token, "Running PROGRAM '%s'", buf); + log_event_debug(dev, token, "Running PROGRAM=\"%s\"", buf); r = udev_event_spawn(event, /* accept_failure = */ true, buf, result, sizeof(result), NULL); if (r != 0) { @@ -2264,7 +2264,7 @@ static int udev_rule_apply_token_to_event( log_event_debug(dev, token, "Importing properties from results of builtin command '%s'", buf); - r = udev_builtin_run(event, cmd, buf, false); + r = udev_builtin_run(event, cmd, buf); if (r < 0) { /* remember failure */ log_event_debug_errno(dev, token, r, "Failed to run builtin '%s': %m", buf); diff --git a/src/udev/udev-spawn.c b/src/udev/udev-spawn.c index 8f7c9fec42c..01a6dcdaa82 100644 --- a/src/udev/udev-spawn.c +++ b/src/udev/udev-spawn.c @@ -225,9 +225,19 @@ int udev_event_spawn( int r; assert(event); + assert(IN_SET(event->event_mode, EVENT_UDEV_WORKER, EVENT_UDEVADM_TEST, EVENT_TEST_RULE_RUNNER, EVENT_TEST_SPAWN)); assert(event->dev); + assert(cmd); assert(result || result_size == 0); + if (event->event_mode == EVENT_UDEVADM_TEST && + !STARTSWITH_SET(cmd, "ata_id", "cdrom_id", "dmi_memory_id", "fido_id", "mtd_probe", "scsi_id")) { + log_device_debug(event->dev, "Running in test mode, skipping execution of '%s'.", cmd); + result[0] = '\0'; + ret_truncated = false; + return 0; + } + int timeout_signal = event->worker ? event->worker->timeout_signal : SIGKILL; usec_t timeout_usec = event->worker ? event->worker->timeout_usec : DEFAULT_WORKER_TIMEOUT_USEC; usec_t now_usec = now(CLOCK_MONOTONIC); @@ -333,7 +343,7 @@ void udev_event_execute_run(UdevEvent *event) { if (builtin_cmd != _UDEV_BUILTIN_INVALID) { log_device_debug(event->dev, "Running built-in command \"%s\"", command); - r = udev_builtin_run(event, builtin_cmd, command, false); + r = udev_builtin_run(event, builtin_cmd, command); if (r < 0) log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command); } else { diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c index b038b680993..97c5679b74c 100644 --- a/src/udev/udev-worker.c +++ b/src/udev/udev-worker.c @@ -172,7 +172,7 @@ static int worker_process_device(UdevWorker *worker, sd_device *dev) { log_device_uevent(dev, "Processing device"); - udev_event = udev_event_new(dev, worker); + udev_event = udev_event_new(dev, worker, EVENT_UDEV_WORKER); if (!udev_event) return -ENOMEM; diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index fdbdb6f59a7..88319497176 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -100,7 +100,7 @@ int builtin_main(int argc, char *argv[], void *userdata) { goto finish; } - event = udev_event_new(dev, NULL); + event = udev_event_new(dev, NULL, EVENT_UDEVADM_TEST_BUILTIN); if (!event) { r = log_oom(); goto finish; @@ -115,7 +115,7 @@ int builtin_main(int argc, char *argv[], void *userdata) { } } - r = udev_builtin_run(event, cmd, arg_command, true); + r = udev_builtin_run(event, cmd, arg_command); if (r < 0) { log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command); goto finish; diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 6c4a01a30e3..e2adc866060 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -125,7 +125,7 @@ int test_main(int argc, char *argv[], void *userdata) { /* don't read info from the db */ device_seal(dev); - event = udev_event_new(dev, NULL); + event = udev_event_new(dev, NULL, EVENT_UDEVADM_TEST); assert_se(sigfillset(&mask) >= 0); assert_se(sigprocmask(SIG_SETMASK, &mask, &sigmask_orig) >= 0); diff --git a/test/units/testsuite-17.link-property.sh b/test/units/testsuite-17.link-property.sh index a43ad22b434..517cc3f7d21 100755 --- a/test/units/testsuite-17.link-property.sh +++ b/test/units/testsuite-17.link-property.sh @@ -122,12 +122,12 @@ assert_in "ID_NET_LINK_FILE=/run/systemd/network/10-test.link" "$output" assert_in "ID_NET_LINK_FILE_DROPINS=/run/systemd/network/10-test.link.d/10-override.conf:/run/systemd/network/10-test.link.d/11-override.conf" "$output" assert_in "ID_NET_NAME=test1" "$output" -# check that test command _does_ update udev database. +# check that test command does not update udev database. output=$(udevadm info --query property /sys/class/net/test1) assert_not_in "HOGE=" "$output" -assert_in "HOGE2=foo2" "$output" +assert_not_in "HOGE2=" "$output" assert_not_in "BAR=" "$output" -assert_in "BAR2=baz2" "$output" +assert_not_in "BAR2=" "$output" assert_not_in "SHOULD_BE_UNSET=" "$output" assert_in "ID_NET_LINK_FILE=/run/systemd/network/10-test.link" "$output" assert_in "ID_NET_LINK_FILE_DROPINS=/run/systemd/network/10-test.link.d/10-override.conf:/run/systemd/network/10-test.link.d/11-override.conf" "$output" @@ -165,6 +165,7 @@ udevadm control --reload output=$(udevadm test --action add /sys/class/net/test1) assert_in "LINK_VERSION=$(uname -r)" "$output" +udevadm trigger --settle --action add /sys/class/net/test1 output=$(udevadm info --query property /sys/class/net/test1) assert_in "LINK_VERSION=$(uname -r)" "$output" @@ -185,6 +186,7 @@ assert_in "IFINDEX=" "$output" assert_not_in "IFINDEX=bar" "$output" assert_in "DEVPATH=" "$output" +udevadm trigger --settle --action add /sys/class/net/test1 output=$(udevadm info --query property /sys/class/net/test1) assert_not_in "ACTION=foo" "$output" assert_in "IFINDEX=" "$output"