manager: remove a connection from device if we're activating it on another device
The connection now might be being activated on another device. Defer the removal until we're sure the activation request will proceed and only add the active connection afterwards. https://bugzilla.gnome.org/show_bug.cgi?id=730492
This commit is contained in:
@@ -5908,6 +5908,26 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_steal_connection (NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
_LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
if ( priv->queued_act_request
|
||||
&& connection == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request)))
|
||||
_clear_queued_act_request (priv);
|
||||
|
||||
if ( priv->act_request
|
||||
&& connection == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->act_request))
|
||||
&& priv->state < NM_DEVICE_STATE_DEACTIVATING)
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
||||
{
|
||||
@@ -5929,8 +5949,8 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
||||
|
||||
_LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
|
||||
|
||||
if (priv->act_request) {
|
||||
/* Deactivate existing activation request first */
|
||||
if (priv->act_request) {
|
||||
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
@@ -7390,10 +7410,9 @@ _cleanup_ip_pre (NMDevice *self, gboolean deconfigure)
|
||||
}
|
||||
|
||||
static void
|
||||
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
_cancel_activation (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
|
||||
/* Clean up when device was deactivated during call to firewall */
|
||||
if (priv->fw_call) {
|
||||
@@ -7401,6 +7420,20 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
priv->fw_call = NULL;
|
||||
}
|
||||
|
||||
ip_check_gw_ping_cleanup (self);
|
||||
|
||||
/* Break the activation chain */
|
||||
activation_source_clear (self, TRUE, AF_INET);
|
||||
activation_source_clear (self, TRUE, AF_INET6);
|
||||
}
|
||||
|
||||
static void
|
||||
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
{
|
||||
NMConnection *connection;
|
||||
|
||||
_cancel_activation (self);
|
||||
|
||||
connection = nm_device_get_connection (self);
|
||||
if ( deconfigure
|
||||
&& connection
|
||||
@@ -7410,12 +7443,6 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
NULL);
|
||||
}
|
||||
|
||||
ip_check_gw_ping_cleanup (self);
|
||||
|
||||
/* Break the activation chain */
|
||||
activation_source_clear (self, TRUE, AF_INET);
|
||||
activation_source_clear (self, TRUE, AF_INET6);
|
||||
|
||||
/* Clear any queued transitions */
|
||||
nm_device_queued_state_clear (self);
|
||||
|
||||
@@ -7951,6 +7978,8 @@ _set_state_full (NMDevice *self,
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DEACTIVATING:
|
||||
_cancel_activation (self);
|
||||
|
||||
if (quitting) {
|
||||
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
|
||||
nm_act_request_get_connection (req),
|
||||
|
@@ -387,6 +387,8 @@ void nm_device_queue_state (NMDevice *self,
|
||||
|
||||
gboolean nm_device_get_firmware_missing (NMDevice *self);
|
||||
|
||||
void nm_device_steal_connection (NMDevice *device, NMConnection *connection);
|
||||
|
||||
void nm_device_queue_activation (NMDevice *device, NMActRequest *req);
|
||||
|
||||
gboolean nm_device_supports_vlans (NMDevice *device);
|
||||
|
@@ -2684,7 +2684,7 @@ _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **er
|
||||
static gboolean
|
||||
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
||||
{
|
||||
NMDevice *device, *master_device = NULL;
|
||||
NMDevice *device, *existing, *master_device = NULL;
|
||||
NMConnection *connection;
|
||||
NMConnection *master_connection = NULL;
|
||||
NMActiveConnection *master_ac = NULL;
|
||||
@@ -2836,6 +2836,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
||||
nm_active_connection_get_path (master_ac));
|
||||
}
|
||||
|
||||
/* Disconnect the connection if connected or queued on another device */
|
||||
existing = nm_manager_get_connection_device (self, connection);
|
||||
if (existing)
|
||||
nm_device_steal_connection (existing, connection);
|
||||
|
||||
/* Export the new ActiveConnection to clients and start it on the device */
|
||||
nm_active_connection_export (active);
|
||||
g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
|
||||
@@ -2873,6 +2878,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError
|
||||
* is exported, make sure the manager's activating-connection property
|
||||
* is up-to-date.
|
||||
*/
|
||||
active_connection_add (self, active);
|
||||
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
||||
}
|
||||
|
||||
@@ -2942,18 +2948,6 @@ _new_active_connection (NMManager *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (existing_ac) {
|
||||
NMDevice *existing_device = nm_active_connection_get_device (existing_ac);
|
||||
|
||||
if (existing_device != device) {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
|
||||
"Connection '%s' is already active on %s",
|
||||
nm_connection_get_id (connection),
|
||||
nm_device_get_iface (existing_device));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalize the specific object */
|
||||
if (specific_object && g_strcmp0 (specific_object, "/") == 0)
|
||||
specific_object = NULL;
|
||||
@@ -2985,7 +2979,6 @@ _internal_activation_failed (NMManager *self,
|
||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
|
||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
||||
}
|
||||
active_connection_remove (self, active);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3063,10 +3056,8 @@ nm_manager_activate_connection (NMManager *self,
|
||||
device,
|
||||
subject,
|
||||
error);
|
||||
if (active) {
|
||||
if (active)
|
||||
nm_active_connection_authorize (active, _internal_activation_auth_done, self, NULL);
|
||||
active_connection_add (self, active);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
@@ -3313,7 +3304,6 @@ impl_manager_activate_connection (NMManager *self,
|
||||
goto error;
|
||||
|
||||
nm_active_connection_authorize (active, _activation_auth_done, self, context);
|
||||
active_connection_add (self, active);
|
||||
g_clear_object (&subject);
|
||||
return;
|
||||
|
||||
@@ -3391,8 +3381,6 @@ _add_and_activate_auth_done (NMActiveConnection *active,
|
||||
activation_add_done,
|
||||
info);
|
||||
} else {
|
||||
active_connection_remove (self, active);
|
||||
|
||||
g_assert (error_desc);
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
@@ -3499,7 +3487,6 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
||||
goto error;
|
||||
|
||||
nm_active_connection_authorize (active, _add_and_activate_auth_done, self, context);
|
||||
active_connection_add (self, active);
|
||||
g_object_unref (connection);
|
||||
g_object_unref (subject);
|
||||
return;
|
||||
|
Reference in New Issue
Block a user