-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <ctype.h>
#include <errno.h>
if (si->si_status == 0)
log_device_debug(spawn->device, "Process '%s' succeeded.", spawn->cmd);
else
- log_device_full(spawn->device, spawn->accept_failure ? LOG_DEBUG : LOG_WARNING, 0,
+ log_device_full(spawn->device, spawn->accept_failure ? LOG_DEBUG : LOG_WARNING,
"Process '%s' failed with exit code %i.", spawn->cmd, si->si_status);
ret = si->si_status;
break;
return log_device_error_errno(event->dev, errno,
"Failed to create pipe for command '%s': %m", cmd);
- argv = strv_split_full(cmd, NULL, SPLIT_QUOTES|SPLIT_RELAX);
- if (!argv)
- return log_oom();
+ r = strv_split_full(&argv, cmd, NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_RETAIN_ESCAPE);
+ if (r < 0)
+ return log_device_error_errno(event->dev, r, "Failed to split command: %m");
if (isempty(argv[0]))
return log_device_error_errno(event->dev, SYNTHETIC_ERRNO(EINVAL),
if (r < 0)
return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
- r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
- if (r < 0)
- return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
- ifindex, oldname, event->name);
-
/* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
r = device_add_property(dev, "ID_RENAMING", "1");
if (r < 0)
if (r < 0)
return log_device_warning_errno(dev, r, "Failed to update properties with new name '%s': %m", event->name);
+ /* Also set ID_RENAMING boolean property to cloned sd_device object and save it to database
+ * before calling rtnl_set_link_name(). Otherwise, clients (e.g., systemd-networkd) may receive
+ * RTM_NEWLINK netlink message before the database is updated. */
+ r = device_add_property(event->dev_db_clone, "ID_RENAMING", "1");
+ if (r < 0)
+ return log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
+
+ r = device_update_db(event->dev_db_clone);
+ if (r < 0)
+ return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
+
+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
+ if (r < 0)
+ return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
+ ifindex, oldname, event->name);
+
log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, oldname, event->name);
return 1;
return log_device_error_errno(dev, r, "Failed to get devnum: %m");
/* remove/update possible left-over symlinks from old database entry */
- if (event->dev_db_clone)
- (void) udev_node_update_old_links(dev, event->dev_db_clone);
+ (void) udev_node_update_old_links(dev, event->dev_db_clone);
if (!uid_is_valid(event->uid)) {
r = device_get_devnode_uid(dev, &event->uid);
(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 (event->dev_db_clone &&
- 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)
return 0;
}
+static int copy_all_tags(sd_device *d, sd_device *s) {
+ const char *tag;
+ int r;
+
+ assert(d);
+
+ if (!s)
+ return 0;
+
+ for (tag = sd_device_get_tag_first(s); tag; tag = sd_device_get_tag_next(s)) {
+ r = device_add_tag(d, tag, false);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
int udev_event_execute_rules(UdevEvent *event,
usec_t timeout_usec,
int timeout_signal,
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to clone sd_device object: %m");
- if (event->dev_db_clone && sd_device_get_devnum(dev, NULL) >= 0)
+ r = copy_all_tags(dev, event->dev_db_clone);
+ if (r < 0)
+ log_device_warning_errno(dev, r, "Failed to copy all tags from old database entry, ignoring: %m");
+
+ if (sd_device_get_devnum(dev, NULL) >= 0)
/* Disable watch during event processing. */
(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;
}
device_set_is_initialized(dev);
- event->dev_db_clone = sd_device_unref(event->dev_db_clone);
-
return 0;
}
void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_signal) {
const char *command;
void *val;
- Iterator i;
int r;
- ORDERED_HASHMAP_FOREACH_KEY(val, command, event->run_list, i) {
+ ORDERED_HASHMAP_FOREACH_KEY(val, command, event->run_list) {
UdevBuiltinCommand builtin_cmd = PTR_TO_UDEV_BUILTIN_CMD(val);
if (builtin_cmd != _UDEV_BUILTIN_INVALID) {