]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/udev/udev-event.c
Merge pull request #17549 from yuwata/tiny-fixes
[thirdparty/systemd.git] / src / udev / udev-event.c
index b468ce9c034954f72e1ee212913ab17e3a3707b4..fd00a24e991fd09b994ee4f828ab1590be6611a0 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 #include <ctype.h>
 #include <errno.h>
@@ -633,7 +633,7 @@ static int on_spawn_sigchld(sd_event_source *s, const siginfo_t *si, void *userd
                 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;
@@ -747,9 +747,9 @@ int udev_event_spawn(UdevEvent *event,
                         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),
@@ -840,11 +840,6 @@ static int rename_netif(UdevEvent *event) {
         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)
@@ -854,6 +849,22 @@ static int rename_netif(UdevEvent *event) {
         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;
@@ -870,8 +881,7 @@ static int update_devnode(UdevEvent *event) {
                 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);
@@ -930,17 +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 (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)
@@ -949,6 +951,24 @@ static int udev_event_on_move(UdevEvent *event) {
         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,
@@ -981,12 +1001,16 @@ int udev_event_execute_rules(UdevEvent *event,
         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;
         }
@@ -1019,18 +1043,15 @@ int udev_event_execute_rules(UdevEvent *event,
 
         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) {