File 1002-udev-persistent-net-rules-support.patch of Package systemd

From a0d557e0aebe9ad2e27e0f22822207f231c8e726 Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Fri, 9 May 2025 16:32:19 +0200
Subject: udev: persistent net rules support

This patch reintroduces the ability to rename a NIC even if the new name is
currently in use by another NIC. In such cases, udev waits until the new name
becomes available, while the previously named NIC is renamed in turn.

This is needed to support upgrades from older systems relying on persistent net
rules.

[fbui: fixes bsc#1241190]
---
 src/libsystemd/sd-netlink/netlink-util.c | 44 +++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index 90616094bc..794e8983b1 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <linux/if.h>
+
 #include "sd-netlink.h"
 
 #include "fd-util.h"
@@ -159,7 +161,7 @@ int rtnl_resolve_ifname_full(
         return -ENODEV;
 }
 
-static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
+static int do_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
         int r;
 
@@ -186,6 +188,46 @@ static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
         return sd_netlink_call(*rtnl, message, 0, NULL);
 }
 
+static int do_set_link_name_wait(sd_netlink **rtnl, int ifindex, const char *name) {
+        char tmp[IFNAMSIZ];
+        int r;
+
+        log_debug("ifindex %i: waiting for name %s to be released", ifindex, name);
+
+        /* free our own name, another process may wait for us */
+        snprintf(tmp, IFNAMSIZ, "rename%d", ifindex);
+        r = do_set_link_name(rtnl, ifindex, tmp);
+        if (r < 0)
+                  return r;
+
+        log_debug("ifindex %i: while waiting, renamed to %s to release our own name", ifindex, tmp);
+
+        /* wait a maximum of 90 seconds for our target to become available */
+        for(int loop = 90 * 20; loop; loop--) {
+                const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 };
+
+                nanosleep(&duration, NULL);
+
+                r = do_set_link_name(rtnl, ifindex, name);
+                if (r >= 0)
+                        break;
+                if (r != -EEXIST)
+                        break;
+        }
+
+        return r;
+}
+
+static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
+        int r;
+
+        r = do_set_link_name(rtnl, ifindex, name);
+        if (r >= 0 || r != -EEXIST)
+                return r;
+
+        return do_set_link_name_wait(rtnl, ifindex, name);
+}
+
 int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name) {
         _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
         int r, ifindex;
-- 
2.43.0

openSUSE Build Service is sponsored by