diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-10-14 17:49:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-14 17:49:37 +0200 |
commit | fc8bc57f6b25266ab52166c917b39a3abf2fa54d (patch) | |
tree | 546a8bccaafed177d07faf3c2c67635caed34707 | |
parent | Merge pull request #17338 from poettering/close-range (diff) | |
parent | test: add test for device renaming issue #16967 (diff) | |
download | systemd-fc8bc57f6b25266ab52166c917b39a3abf2fa54d.tar.xz systemd-fc8bc57f6b25266ab52166c917b39a3abf2fa54d.zip |
Merge pull request #16968 from yuwata/remove-old-device-on-move-event
core, udev: remove old device on move event
-rw-r--r-- | rules.d/80-net-setup-link.rules | 2 | ||||
-rw-r--r-- | rules.d/99-systemd.rules.in | 4 | ||||
-rw-r--r-- | src/core/device.c | 26 | ||||
-rw-r--r-- | src/shared/ethtool-util.c | 8 | ||||
-rw-r--r-- | src/shared/ethtool-util.h | 8 | ||||
-rw-r--r-- | src/udev/net/link-config.c | 292 | ||||
-rw-r--r-- | src/udev/net/link-config.h | 4 | ||||
-rw-r--r-- | src/udev/udev-event.c | 11 | ||||
-rwxr-xr-x | test/TEST-29-UDEV-ID_RENAMING/test.sh | 15 | ||||
-rwxr-xr-x | test/units/testsuite-29.sh | 16 |
10 files changed, 259 insertions, 127 deletions
diff --git a/rules.d/80-net-setup-link.rules b/rules.d/80-net-setup-link.rules index 6e411a91f0..bafc3fbc84 100644 --- a/rules.d/80-net-setup-link.rules +++ b/rules.d/80-net-setup-link.rules @@ -4,7 +4,7 @@ SUBSYSTEM!="net", GOTO="net_setup_link_end" IMPORT{builtin}="path_id" -ACTION!="add", GOTO="net_setup_link_end" +ACTION=="remove", GOTO="net_setup_link_end" IMPORT{builtin}="net_setup_link" diff --git a/rules.d/99-systemd.rules.in b/rules.d/99-systemd.rules.in index 1c60eec587..9e2772388d 100644 --- a/rules.d/99-systemd.rules.in +++ b/rules.d/99-systemd.rules.in @@ -46,9 +46,9 @@ SUBSYSTEM=="block", KERNEL=="nbd*", ENV{DEVTYPE}=="disk", TEST!="pid", ENV{SYSTE # http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n955 SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name" -SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k" +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k", \ + ENV{SYSTEMD_WANTS}+="bluetooth.target", ENV{SYSTEMD_USER_WANTS}+="bluetooth.target" -SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target", ENV{SYSTEMD_USER_WANTS}+="bluetooth.target" SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0b????:*", ENV{ID_SMARTCARD_READER}="1" ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target", ENV{SYSTEMD_USER_WANTS}+="smartcard.target" SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target", ENV{SYSTEMD_USER_WANTS}+="sound.target" diff --git a/src/core/device.c b/src/core/device.c index 595b009cd9..134c6ee5bb 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -894,6 +894,29 @@ static void device_propagate_reload_by_sysfs(Manager *m, const char *sysfs) { } } +static int device_remove_old(Manager *m, sd_device *dev) { + _cleanup_free_ char *syspath_old = NULL, *e = NULL; + const char *devpath_old; + int r; + + r = sd_device_get_property_value(dev, "DEVPATH_OLD", &devpath_old); + if (r < 0) { + log_device_debug_errno(dev, r, "Failed to get DEVPATH_OLD= property on 'move' uevent, ignoring: %m"); + return 0; + } + + syspath_old = path_join("/sys", devpath_old); + if (!syspath_old) + return log_oom(); + + r = unit_name_from_path(syspath_old, ".device", &e); + if (r < 0) + return log_device_error_errno(dev, r, "Failed to generate unit name from old device path: %m"); + + device_update_found_by_sysfs(m, syspath_old, 0, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP); + return 0; +} + static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) { Manager *m = userdata; DeviceAction action; @@ -918,6 +941,9 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void * if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_REMOVE, DEVICE_ACTION_MOVE)) device_propagate_reload_by_sysfs(m, sysfs); + if (action == DEVICE_ACTION_MOVE) + (void) device_remove_old(m, dev); + /* A change event can signal that a device is becoming ready, in particular if the device is using * the SYSTEMD_READY logic in udev so we need to reach the else block of the following if, even for * change events */ diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c index 9326d2856e..adbf8d1db3 100644 --- a/src/shared/ethtool-util.c +++ b/src/shared/ethtool-util.c @@ -414,7 +414,7 @@ int ethtool_set_wol(int *ethtool_fd, const char *ifname, WakeOnLan wol) { return 0; } -int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, netdev_ring_param *ring) { +int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netdev_ring_param *ring) { struct ethtool_ringparam ecmd = { .cmd = ETHTOOL_GRINGPARAM }; @@ -543,7 +543,7 @@ static int set_features_bit( return found ? 0 : -ENODATA; } -int ethtool_set_features(int *ethtool_fd, const char *ifname, int *features) { +int ethtool_set_features(int *ethtool_fd, const char *ifname, const int *features) { _cleanup_free_ struct ethtool_gstrings *strings = NULL; struct ethtool_sfeatures *sfeatures; struct ifreq ifr = {}; @@ -754,7 +754,7 @@ int ethtool_set_glinksettings( int *fd, const char *ifname, int autonegotiation, - uint32_t advertise[static N_ADVERTISE], + const uint32_t advertise[static N_ADVERTISE], uint64_t speed, Duplex duplex, NetDevPort port) { @@ -813,7 +813,7 @@ int ethtool_set_glinksettings( return r; } -int ethtool_set_channels(int *fd, const char *ifname, netdev_channels *channels) { +int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *channels) { struct ethtool_channels ecmd = { .cmd = ETHTOOL_GCHANNELS }; diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h index 4730241708..9e3f1ed51a 100644 --- a/src/shared/ethtool-util.h +++ b/src/shared/ethtool-util.h @@ -101,12 +101,12 @@ int ethtool_get_link_info(int *ethtool_fd, const char *ifname, int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct ether_addr *ret); int ethtool_set_speed(int *ethtool_fd, const char *ifname, unsigned speed, Duplex duplex); int ethtool_set_wol(int *ethtool_fd, const char *ifname, WakeOnLan wol); -int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, netdev_ring_param *ring); -int ethtool_set_features(int *ethtool_fd, const char *ifname, int *features); +int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netdev_ring_param *ring); +int ethtool_set_features(int *ethtool_fd, const char *ifname, const int *features); int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname, - int autonegotiation, uint32_t advertise[static N_ADVERTISE], + int autonegotiation, const uint32_t advertise[static N_ADVERTISE], uint64_t speed, Duplex duplex, NetDevPort port); -int ethtool_set_channels(int *ethtool_fd, const char *ifname, netdev_channels *channels); +int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels); int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg); const char *duplex_to_string(Duplex d) _const_; diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 03fd429b27..c23c2bdd20 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -11,6 +11,7 @@ #include "conf-files.h" #include "conf-parser.h" #include "def.h" +#include "device-private.h" #include "device-util.h" #include "ethtool-util.h" #include "fd-util.h" @@ -241,6 +242,7 @@ bool link_config_should_reload(link_config_ctx *ctx) { } int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) { + unsigned name_assign_type = NET_NAME_UNKNOWN; struct ether_addr permanent_mac = {}; unsigned short iftype = 0; link_config *link; @@ -267,38 +269,89 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) if (r < 0) log_device_debug_errno(device, r, "Failed to get permanent MAC address, ignoring: %m"); + (void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type); + LIST_FOREACH(links, link, ctx->links) { if (net_match_config(link->match_mac, link->match_permanent_mac, link->match_path, link->match_driver, link->match_type, link->match_name, link->match_property, NULL, NULL, NULL, device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL)) { - if (link->match_name && !strv_contains(link->match_name, "*")) { - unsigned name_assign_type = NET_NAME_UNKNOWN; - (void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type); + if (link->match_name && !strv_contains(link->match_name, "*") && name_assign_type == NET_NAME_ENUM) + log_device_warning(device, "Config file %s is applied to device based on potentially unpredictable interface name.", + link->filename); + else + log_device_debug(device, "Config file %s is applied", link->filename); - if (name_assign_type == NET_NAME_ENUM) { - log_device_warning(device, "Config file %s applies to device based on potentially unpredictable interface name", - link->filename); - *ret = link; + *ret = link; + return 0; + } + } - return 0; - } else if (name_assign_type == NET_NAME_RENAMED) { - log_device_warning(device, "Config file %s matches device based on renamed interface name, ignoring", - link->filename); + return -ENOENT; +} - continue; - } - } +static int link_config_apply_ethtool_settings(int *ethtool_fd, const link_config *config, sd_device *device) { + const char *name; + int r; - log_device_debug(device, "Config file %s is applied", link->filename); + assert(ethtool_fd); + assert(config); + assert(device); - *ret = link; - return 0; + r = sd_device_get_sysname(device, &name); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get sysname: %m"); + + r = ethtool_set_glinksettings(ethtool_fd, name, + config->autonegotiation, config->advertise, + config->speed, config->duplex, config->port); + if (r < 0) { + if (config->port != _NET_DEV_PORT_INVALID) + log_device_warning_errno(device, r, "Could not set port '%s', ignoring: %m", port_to_string(config->port)); + + if (!eqzero(config->advertise)) + log_device_warning_errno(device, r, "Could not set advertise mode, ignoring: %m"); /* TODO: include modes in the log message. */ + + if (config->speed) { + unsigned speed = DIV_ROUND_UP(config->speed, 1000000); + if (r == -EOPNOTSUPP) { + r = ethtool_set_speed(ethtool_fd, name, speed, config->duplex); + if (r < 0) + log_device_warning_errno(device, r, "Could not set speed to %uMbps, ignoring: %m", speed); + } } + + if (config->duplex != _DUP_INVALID) + log_device_warning_errno(device, r, "Could not set duplex to %s, ignoring: %m", duplex_to_string(config->duplex)); } - *ret = NULL; - return -ENOENT; + r = ethtool_set_wol(ethtool_fd, name, config->wol); + if (r < 0) + log_device_warning_errno(device, r, "Could not set WakeOnLan to %s, ignoring: %m", wol_to_string(config->wol)); + + r = ethtool_set_features(ethtool_fd, name, config->features); + if (r < 0) + log_device_warning_errno(device, r, "Could not set offload features, ignoring: %m"); + + if (config->channels.rx_count_set || config->channels.tx_count_set || config->channels.other_count_set || config->channels.combined_count_set) { + r = ethtool_set_channels(ethtool_fd, name, &config->channels); + if (r < 0) + log_device_warning_errno(device, r, "Could not set channels, ignoring: %m"); + } + + if (config->ring.rx_pending_set || config->ring.rx_mini_pending_set || config->ring.rx_jumbo_pending_set || config->ring.tx_pending_set) { + r = ethtool_set_nic_buffer_size(ethtool_fd, name, &config->ring); + if (r < 0) + log_device_warning_errno(device, r, "Could not set ring buffer, ignoring: %m"); + } + + if (config->rx_flow_control >= 0 || config->tx_flow_control >= 0 || config->autoneg_flow_control >= 0) { + r = ethtool_set_flow_control(ethtool_fd, name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control); + if (r < 0) + log_device_warning_errno(device, r, "Could not set flow control, ignoring: %m"); + } + + return 0; } static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr *mac) { @@ -357,80 +410,41 @@ static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr return 1; } -int link_config_apply(link_config_ctx *ctx, link_config *config, - sd_device *device, const char **name) { - _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL; - struct ether_addr generated_mac; - struct ether_addr *mac = NULL; - const char *new_name = NULL; - const char *old_name; - unsigned speed, name_type = NET_NAME_UNKNOWN; - NamePolicy policy; - int r, ifindex; +static int link_config_apply_rtnl_settings(sd_netlink **rtnl, const link_config *config, sd_device *device) { + struct ether_addr generated_mac, *mac = NULL; + int ifindex, r; - assert(ctx); + assert(rtnl); assert(config); assert(device); - assert(name); - r = sd_device_get_sysname(device, &old_name); + r = sd_device_get_ifindex(device, &ifindex); if (r < 0) - return r; + return log_device_error_errno(device, r, "Could not find ifindex: %m"); - r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, - config->autonegotiation, config->advertise, - config->speed, config->duplex, config->port); - if (r < 0) { - - if (config->port != _NET_DEV_PORT_INVALID) - log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name); - - if (!eqzero(config->advertise)) - log_warning_errno(r, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */ - - if (config->speed) { - speed = DIV_ROUND_UP(config->speed, 1000000); - if (r == -EOPNOTSUPP) { - r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex); - if (r < 0) - log_warning_errno(r, "Could not set speed of %s to %u Mbps: %m", old_name, speed); - } - } - - if (config->duplex != _DUP_INVALID) - log_warning_errno(r, "Could not set duplex of %s to %s: %m", old_name, duplex_to_string(config->duplex)); - } - - r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol); - if (r < 0) - log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m", - old_name, wol_to_string(config->wol)); + if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM)) { + if (get_mac(device, config->mac_address_policy, &generated_mac) > 0) + mac = &generated_mac; + } else + mac = config->mac; - r = ethtool_set_features(&ctx->ethtool_fd, old_name, config->features); + r = rtnl_set_link_properties(rtnl, ifindex, config->alias, mac, config->mtu); if (r < 0) - log_warning_errno(r, "Could not set offload features of %s: %m", old_name); - - if (config->channels.rx_count_set || config->channels.tx_count_set || config->channels.other_count_set || config->channels.combined_count_set) { - r = ethtool_set_channels(&ctx->ethtool_fd, old_name, &config->channels); - if (r < 0) - log_warning_errno(r, "Could not set channels of %s: %m", old_name); - } + log_device_warning_errno(device, r, "Could not set Alias=, MACAddress= or MTU=, ignoring: %m"); - if (config->ring.rx_pending_set || config->ring.rx_mini_pending_set || config->ring.rx_jumbo_pending_set || config->ring.tx_pending_set) { - r = ethtool_set_nic_buffer_size(&ctx->ethtool_fd, old_name, &config->ring); - if (r < 0) - log_warning_errno(r, "Could not set ring buffer of %s: %m", old_name); - } + return 0; +} - if (config->rx_flow_control >= 0 || config->tx_flow_control >= 0 || config->autoneg_flow_control >= 0) { - r = ethtool_set_flow_control(&ctx->ethtool_fd, old_name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control); - if (r < 0) - log_warning_errno(r, "Could not set flow control of %s: %m", old_name); - } +static int link_config_generate_new_name(const link_config_ctx *ctx, const link_config *config, sd_device *device, const char **ret_name) { + unsigned name_type = NET_NAME_UNKNOWN; + const char *new_name = NULL; + NamePolicy policy; + int r; - r = sd_device_get_ifindex(device, &ifindex); - if (r < 0) - return log_device_warning_errno(device, r, "Could not find ifindex: %m"); + assert(ctx); + assert(config); + assert(device); + assert(ret_name); (void) link_unsigned_attribute(device, "name_assign_type", &name_type); @@ -482,24 +496,43 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, break; } - if (new_name) + if (new_name) { log_device_debug(device, "Policy *%s* yields \"%s\".", name_policy_to_string(policy), new_name); - else if (config->name) { - new_name = config->name; - log_device_debug(device, "Policies didn't yield a name, using specified Name=%s.", new_name); - } else - log_device_debug(device, "Policies didn't yield a name and Name= is not given, not renaming."); - no_rename: + *ret_name = new_name; + return 0; + } - if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM)) { - if (get_mac(device, config->mac_address_policy, &generated_mac) > 0) - mac = &generated_mac; - } else - mac = config->mac; + if (config->name) { + log_device_debug(device, "Policies didn't yield a name, using specified Name=%s.", config->name); + *ret_name = config->name; + return 0; + } + + log_device_debug(device, "Policies didn't yield a name and Name= is not given, not renaming."); +no_rename: + r = sd_device_get_sysname(device, ret_name); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get sysname: %m"); + + return 0; +} + +static int link_config_apply_alternative_names(sd_netlink **rtnl, const link_config *config, sd_device *device, const char *new_name) { + _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL; + const char *current_name; + int ifindex, r; + + assert(rtnl); + assert(config); + assert(device); + + r = sd_device_get_sysname(device, ¤t_name); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get sysname: %m"); - r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac, config->mtu); + r = sd_device_get_ifindex(device, &ifindex); if (r < 0) - return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name); + return log_device_error_errno(device, r, "Could not find ifindex: %m"); if (config->alternative_names) { altnames = strv_copy(config->alternative_names); @@ -539,11 +572,11 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, if (new_name) strv_remove(altnames, new_name); - strv_remove(altnames, old_name); + strv_remove(altnames, current_name); - r = rtnl_get_link_alternative_names(&ctx->rtnl, ifindex, ¤t_altnames); + r = rtnl_get_link_alternative_names(rtnl, ifindex, ¤t_altnames); if (r < 0) - log_debug_errno(r, "Failed to get alternative names on %s, ignoring: %m", old_name); + log_device_debug_errno(device, r, "Failed to get alternative names, ignoring: %m"); char **p; STRV_FOREACH(p, current_altnames) @@ -551,14 +584,63 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, strv_uniq(altnames); strv_sort(altnames); - r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); - if (r == -EOPNOTSUPP) - log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name); - else if (r < 0) - return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name); + r = rtnl_set_link_alternative_names(rtnl, ifindex, altnames); + if (r < 0) + log_device_full_errno(device, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r, + "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m"); + + return 0; +} + +int link_config_apply(link_config_ctx *ctx, const link_config *config, sd_device *device, const char **ret_name) { + const char *new_name; + DeviceAction a; + int r; + + assert(ctx); + assert(config); + assert(device); + assert(ret_name); + + r = device_get_action(device, &a); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get ACTION= property: %m"); + + if (!IN_SET(a, DEVICE_ACTION_ADD, DEVICE_ACTION_BIND, DEVICE_ACTION_MOVE)) { + log_device_debug(device, "Skipping to apply .link settings on '%s' uevent.", device_action_to_string(a)); - *name = new_name; + r = sd_device_get_sysname(device, ret_name); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get sysname: %m"); + + return 0; + } + + r = link_config_apply_ethtool_settings(&ctx->ethtool_fd, config, device); + if (r < 0) + return r; + + r = link_config_apply_rtnl_settings(&ctx->rtnl, config, device); + if (r < 0) + return r; + + if (a == DEVICE_ACTION_MOVE) { + log_device_debug(device, "Skipping to apply Name= and NamePolicy= on '%s' uevent.", device_action_to_string(a)); + + r = sd_device_get_sysname(device, &new_name); + if (r < 0) + return log_device_error_errno(device, r, "Failed to get sysname: %m"); + } else { + r = link_config_generate_new_name(ctx, config, device, &new_name); + if (r < 0) + return r; + } + + r = link_config_apply_alternative_names(&ctx->rtnl, config, device, new_name); + if (r < 0) + return r; + *ret_name = new_name; return 0; } diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index 827ebf436c..8b5801c003 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -77,8 +77,8 @@ int link_load_one(link_config_ctx *ctx, const char *filename); int link_config_load(link_config_ctx *ctx); bool link_config_should_reload(link_config_ctx *ctx); -int link_config_get(link_config_ctx *ctx, sd_device *device, struct link_config **ret); -int link_config_apply(link_config_ctx *ctx, struct link_config *config, sd_device *device, const char **name); +int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret); +int link_config_apply(link_config_ctx *ctx, const link_config *config, sd_device *device, const char **ret_name); int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret); const char *name_policy_to_string(NamePolicy p) _const_; diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 7c78b4c680..ede8e3aef7 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -940,16 +940,9 @@ static void event_execute_rules_on_remove( (void) udev_node_remove(dev); } -static int udev_event_on_move(UdevEvent *event) { - sd_device *dev = event->dev; +static int udev_event_on_move(sd_device *dev) { int r; - if (sd_device_get_devnum(dev, NULL) < 0) { - r = device_copy_properties(dev, event->dev_db_clone); - if (r < 0) - log_device_debug_errno(dev, r, "Failed to copy properties from cloned sd_device object, ignoring: %m"); - } - /* Drop previously added property */ r = device_add_property(dev, "ID_RENAMING", NULL); if (r < 0) @@ -1017,7 +1010,7 @@ int udev_event_execute_rules(UdevEvent *event, (void) udev_watch_end(event->dev_db_clone); if (action == DEVICE_ACTION_MOVE) { - r = udev_event_on_move(event); + r = udev_event_on_move(event->dev); if (r < 0) return r; } diff --git a/test/TEST-29-UDEV-ID_RENAMING/test.sh b/test/TEST-29-UDEV-ID_RENAMING/test.sh index 4feafc04d7..ddf6db9735 100755 --- a/test/TEST-29-UDEV-ID_RENAMING/test.sh +++ b/test/TEST-29-UDEV-ID_RENAMING/test.sh @@ -1,9 +1,24 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="UDEV ID_RENAMING property" +IMAGE_NAME="udev-id-renaming" TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 +test_create_image() { + create_empty_image_rootdir + + # Create what will eventually be our root filesystem onto an overlay + ( + LOG_LEVEL=5 + setup_basic_environment + mask_supporting_services + + instmods dummy + generate_module_dependencies + ) +} + do_test "$@" 29 diff --git a/test/units/testsuite-29.sh b/test/units/testsuite-29.sh index 5abdb53eb3..5c62556895 100755 --- a/test/units/testsuite-29.sh +++ b/test/units/testsuite-29.sh @@ -38,6 +38,22 @@ STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo rm -f /run/udev/rules.d/50-testsuite.rules udevadm control --reload --timeout=600 +# test for issue #16967 + +ip link add hoge type dummy +udevadm info --wait-for-initialization=10s /sys/devices/virtual/net/hoge +sleep 1 +if ! systemctl status sys-devices-virtual-net-hoge.device; then exit 1; fi +if ! systemctl status sys-subsystem-net-devices-hoge.device; then exit 1; fi + +ip link set hoge name foobar +udevadm info --wait-for-initialization=10s /sys/devices/virtual/net/foobar +sleep 1 +if systemctl status sys-devices-virtual-net-hoge.device; then exit 1; fi +if systemctl status sys-subsystem-net-devices-hoge.device; then exit 1; fi +if ! systemctl status sys-devices-virtual-net-foobar.device; then exit 1; fi +if ! systemctl status sys-subsystem-net-devices-foobar.device; then exit 1; fi + echo OK > /testok exit 0 |