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 "sd-netlink.h"
|
||||||
|
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "format-util.h"
|
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "netlink-internal.h"
|
#include "netlink-internal.h"
|
||||||
@ -15,7 +14,7 @@
|
|||||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
_cleanup_strv_free_ char **alternative_names = NULL;
|
_cleanup_strv_free_ char **alternative_names = NULL;
|
||||||
char old_name[IF_NAMESIZE] = {};
|
bool altname_deleted = false;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rtnl);
|
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",
|
return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||||
name, ifindex);
|
name, ifindex);
|
||||||
|
|
||||||
r = format_ifname(ifindex, old_name);
|
altname_deleted = true;
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to get current name of network interface %i: %m", ifindex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto fail;
|
||||||
|
|
||||||
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto fail;
|
||||||
|
|
||||||
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto fail;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
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(
|
int rtnl_set_link_properties(
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <linux/if_macsec.h>
|
#include <linux/if_macsec.h>
|
||||||
#include <linux/l2tp.h>
|
#include <linux/l2tp.h>
|
||||||
#include <linux/nl80211.h>
|
#include <linux/nl80211.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-netlink.h"
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
@ -16,6 +17,7 @@
|
|||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "netlink-genl.h"
|
#include "netlink-genl.h"
|
||||||
#include "netlink-internal.h"
|
#include "netlink-internal.h"
|
||||||
|
#include "netlink-util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "stdio-util.h"
|
#include "stdio-util.h"
|
||||||
#include "string-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) {
|
int main(void) {
|
||||||
sd_netlink *rtnl;
|
sd_netlink *rtnl;
|
||||||
sd_netlink_message *m;
|
sd_netlink_message *m;
|
||||||
@ -698,6 +724,7 @@ int main(void) {
|
|||||||
test_pipe(if_loopback);
|
test_pipe(if_loopback);
|
||||||
test_event_loop(if_loopback);
|
test_event_loop(if_loopback);
|
||||||
test_link_configure(rtnl, if_loopback);
|
test_link_configure(rtnl, if_loopback);
|
||||||
|
test_rtnl_set_link_name(rtnl, if_loopback);
|
||||||
|
|
||||||
test_get_addresses(rtnl);
|
test_get_addresses(rtnl);
|
||||||
test_message_link_bridge(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);
|
strv_remove(altnames, link->ifname);
|
||||||
|
|
||||||
r = rtnl_get_link_alternative_names(rtnl, link->ifindex, ¤t_altnames);
|
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) {
|
static int rename_netif(UdevEvent *event) {
|
||||||
const char *oldname;
|
const char *oldname;
|
||||||
sd_device *dev;
|
sd_device *dev;
|
||||||
unsigned flags;
|
|
||||||
int ifindex, r;
|
int ifindex, r;
|
||||||
|
|
||||||
assert(event);
|
assert(event);
|
||||||
@ -896,16 +895,6 @@ static int rename_netif(UdevEvent *event) {
|
|||||||
return 0;
|
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. */
|
/* 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");
|
r = device_add_property(dev, "ID_RENAMING", "1");
|
||||||
if (r < 0)
|
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");
|
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);
|
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)
|
if (r < 0)
|
||||||
return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
|
return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
|
||||||
ifindex, oldname, event->name);
|
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)
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
|
||||||
self.assertRegex(output, 'hogehogehogehogehogehoge')
|
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):
|
def test_reconfigure(self):
|
||||||
copy_network_unit('25-address-static.network', '12-dummy.netdev')
|
copy_network_unit('25-address-static.network', '12-dummy.netdev')
|
||||||
start_networkd()
|
start_networkd()
|
||||||
|
Loading…
Reference in New Issue
Block a user