mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #25221 from enr0n/nic-rename-fallback
udev: set link alternative name if link is already up during rename
This commit is contained in:
commit
2c99e8c6e0
@ -3,7 +3,6 @@
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "io-util.h"
|
||||
#include "memory-util.h"
|
||||
#include "netlink-internal.h"
|
||||
@ -15,7 +14,7 @@
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||
char old_name[IF_NAMESIZE] = {};
|
||||
bool altname_deleted = false;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
@ -36,31 +35,32 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||
return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||
name, ifindex);
|
||||
|
||||
r = format_ifname(ifindex, old_name);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get current name of network interface %i: %m", ifindex);
|
||||
altname_deleted = true;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto fail;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto fail;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(old_name)) {
|
||||
r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||
old_name, ifindex);
|
||||
}
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (altname_deleted) {
|
||||
int q = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||||
if (q < 0)
|
||||
log_debug_errno(q, "Failed to restore '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||
name, ifindex);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtnl_set_link_properties(
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/if_macsec.h>
|
||||
#include <linux/l2tp.h>
|
||||
#include <linux/nl80211.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
#include "macro.h"
|
||||
#include "netlink-genl.h"
|
||||
#include "netlink-internal.h"
|
||||
#include "netlink-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
@ -667,6 +669,30 @@ static void test_genl(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rtnl_set_link_name(sd_netlink *rtnl, int ifindex) {
|
||||
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||
int r;
|
||||
|
||||
log_debug("/* %s */", __func__);
|
||||
|
||||
if (geteuid() != 0)
|
||||
return (void) log_tests_skipped("not root");
|
||||
|
||||
/* Test that the new name (which is currently an alternative name) is
|
||||
* restored as an alternative name on error. Create an error by using
|
||||
* an invalid device name, namely one that exceeds IFNAMSIZ
|
||||
* (alternative names can exceed IFNAMSIZ, but not regular names). */
|
||||
r = rtnl_set_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"));
|
||||
if (r == -EPERM)
|
||||
return (void) log_tests_skipped("missing required capabilities");
|
||||
|
||||
assert_se(r >= 0);
|
||||
assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
|
||||
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||
assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
sd_netlink *rtnl;
|
||||
sd_netlink_message *m;
|
||||
@ -698,6 +724,7 @@ int main(void) {
|
||||
test_pipe(if_loopback);
|
||||
test_event_loop(if_loopback);
|
||||
test_link_configure(rtnl, if_loopback);
|
||||
test_rtnl_set_link_name(rtnl, if_loopback);
|
||||
|
||||
test_get_addresses(rtnl);
|
||||
test_message_link_bridge(rtnl);
|
||||
|
@ -841,8 +841,6 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
||||
}
|
||||
}
|
||||
|
||||
if (link->new_name)
|
||||
strv_remove(altnames, link->new_name);
|
||||
strv_remove(altnames, link->ifname);
|
||||
|
||||
r = rtnl_get_link_alternative_names(rtnl, link->ifindex, ¤t_altnames);
|
||||
|
@ -862,7 +862,6 @@ int udev_event_spawn(
|
||||
static int rename_netif(UdevEvent *event) {
|
||||
const char *oldname;
|
||||
sd_device *dev;
|
||||
unsigned flags;
|
||||
int ifindex, r;
|
||||
|
||||
assert(event);
|
||||
@ -896,16 +895,6 @@ static int rename_netif(UdevEvent *event) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = rtnl_get_link_info(&event->rtnl, ifindex, NULL, &flags, NULL, NULL, NULL);
|
||||
if (r < 0)
|
||||
return log_device_warning_errno(dev, r, "Failed to get link flags: %m");
|
||||
|
||||
if (FLAGS_SET(flags, IFF_UP)) {
|
||||
log_device_info(dev, "Network interface '%s' is already up, refusing to rename to '%s'.",
|
||||
oldname, event->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
|
||||
r = device_add_property(dev, "ID_RENAMING", "1");
|
||||
if (r < 0)
|
||||
@ -927,6 +916,11 @@ static int rename_netif(UdevEvent *event) {
|
||||
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 == -EBUSY) {
|
||||
log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||
oldname, event->name);
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
|
7
test/test-network/conf/12-dummy-rename-to-altname.link
Normal file
7
test/test-network/conf/12-dummy-rename-to-altname.link
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
OriginalName=dummy98
|
||||
|
||||
[Link]
|
||||
Name=dummyalt
|
||||
AlternativeName=dummyalt hogehogehogehogehogehoge
|
@ -933,6 +933,17 @@ class NetworkctlTests(unittest.TestCase, Utilities):
|
||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
|
||||
self.assertRegex(output, 'hogehogehogehogehogehoge')
|
||||
|
||||
@expectedFailureIfAlternativeNameIsNotAvailable()
|
||||
def test_rename_to_altname(self):
|
||||
copy_network_unit('26-netdev-link-local-addressing-yes.network',
|
||||
'12-dummy.netdev', '12-dummy-rename-to-altname.link')
|
||||
start_networkd()
|
||||
self.wait_online(['dummyalt:degraded'])
|
||||
|
||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummyalt', env=env)
|
||||
self.assertIn('hogehogehogehogehogehoge', output)
|
||||
self.assertNotIn('dummy98', output)
|
||||
|
||||
def test_reconfigure(self):
|
||||
copy_network_unit('25-address-static.network', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
|
Loading…
Reference in New Issue
Block a user