manager: fix race condition while enumerating devices at startup
While enumerating devices at startup, we take a snapshot of existing links from platform and we start creating device instances for them. It's possible that in the meantime, while processing netlink events in platform_link_added(), a link gets renamed. If that happens, then we have two different views of the same ifindex: the cached link from `links` and the link in platform. This can cause issues: in platform_link_added() we create the device with the cached name; then in NMDevice's constructor(), we look up from platform the ifindex for the given name. Because of the rename, this lookup can match a newly created, different link. The end result is that the ifindex from the initial snapshot doesn't get a NMDevice and is not handled by NetworkManager. Fix this problem by fetching the latest version of the link from platform to make sure we have a consistent view of the state. https://issues.redhat.com/browse/RHEL-25808 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1897
This commit is contained in:
@@ -4438,10 +4438,25 @@ platform_query_devices(NMManager *self)
|
||||
links = nm_platform_link_get_all(priv->platform);
|
||||
if (!links)
|
||||
return;
|
||||
|
||||
for (i = 0; i < links->len; i++) {
|
||||
const NMPlatformLink *link = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
||||
const NMPlatformLink *elem = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
||||
const NMPlatformLink *link;
|
||||
const NMConfigDeviceStateData *dev_state;
|
||||
|
||||
/*
|
||||
* @links is an immutable snapshot of the platform links captured before
|
||||
* the loop was started. It's possible that in the meantime, while
|
||||
* processing netlink events in platform_link_added(), a link was
|
||||
* renamed. If that happens, we have 2 different views of the same
|
||||
* ifindex: the one from @links and the one from platform. This can
|
||||
* cause race conditions; make sure to use the latest known version of
|
||||
* the link.
|
||||
*/
|
||||
link = nm_platform_link_get(priv->platform, elem->ifindex);
|
||||
if (!link)
|
||||
continue;
|
||||
|
||||
dev_state = nm_config_device_state_get(priv->config, link->ifindex);
|
||||
platform_link_added(self,
|
||||
link->ifindex,
|
||||
|
Reference in New Issue
Block a user