netlink: fix race that caused stale carrier state signals
Found by Ricardo Salveti de Araujo <ricardo.salveti@openbossa.org> The link cache was updated immediately, but the carrier state signals were emitted a lot later, when the cache data was already stale. So just update the cache at the same time we emit the signals. The carrier-state-request stuff wasn't originally converted to deferred for any netlink-specific reason, just to smooth the initial device creation process in NM.
This commit is contained in:
@@ -399,8 +399,18 @@ deferred_emit_carrier_state (gpointer user_data)
|
|||||||
|
|
||||||
priv->request_status_id = 0;
|
priv->request_status_id = 0;
|
||||||
|
|
||||||
/* Emit each device's new state */
|
/* Update the link cache with latest state, and if there are no errors
|
||||||
nl_cache_foreach_filter (priv->nlh_link_cache, NULL, netlink_object_message_handler, monitor);
|
* emit the link states for all the interfaces in the cache.
|
||||||
|
*/
|
||||||
|
if (nl_cache_refill (priv->nlh, priv->nlh_link_cache))
|
||||||
|
nm_warning ("error updating link cache: %s", nl_geterror ());
|
||||||
|
else {
|
||||||
|
nl_cache_foreach_filter (priv->nlh_link_cache,
|
||||||
|
NULL,
|
||||||
|
netlink_object_message_handler,
|
||||||
|
monitor);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,15 +425,6 @@ nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor,
|
|||||||
priv = NM_NETLINK_MONITOR_GET_PRIVATE (monitor);
|
priv = NM_NETLINK_MONITOR_GET_PRIVATE (monitor);
|
||||||
g_return_val_if_fail (priv->event_id > 0, FALSE);
|
g_return_val_if_fail (priv->event_id > 0, FALSE);
|
||||||
|
|
||||||
/* Update the link cache with latest state */
|
|
||||||
if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) {
|
|
||||||
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
|
||||||
NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE,
|
|
||||||
_("error updating link cache: %s"),
|
|
||||||
nl_geterror ());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Schedule the carrier state emission */
|
/* Schedule the carrier state emission */
|
||||||
if (!priv->request_status_id)
|
if (!priv->request_status_id)
|
||||||
priv->request_status_id = g_idle_add (deferred_emit_carrier_state, monitor);
|
priv->request_status_id = g_idle_add (deferred_emit_carrier_state, monitor);
|
||||||
|
Reference in New Issue
Block a user