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;
|
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
|
void
|
||||||
nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
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");
|
_LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
|
||||||
|
|
||||||
|
/* Deactivate existing activation request first */
|
||||||
if (priv->act_request) {
|
if (priv->act_request) {
|
||||||
/* Deactivate existing activation request first */
|
|
||||||
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
|
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
|
||||||
nm_device_state_changed (self,
|
nm_device_state_changed (self,
|
||||||
NM_DEVICE_STATE_DEACTIVATING,
|
NM_DEVICE_STATE_DEACTIVATING,
|
||||||
@@ -7390,10 +7410,9 @@ _cleanup_ip_pre (NMDevice *self, gboolean deconfigure)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
_cancel_activation (NMDevice *self)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
NMConnection *connection;
|
|
||||||
|
|
||||||
/* Clean up when device was deactivated during call to firewall */
|
/* Clean up when device was deactivated during call to firewall */
|
||||||
if (priv->fw_call) {
|
if (priv->fw_call) {
|
||||||
@@ -7401,6 +7420,20 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
|||||||
priv->fw_call = NULL;
|
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);
|
connection = nm_device_get_connection (self);
|
||||||
if ( deconfigure
|
if ( deconfigure
|
||||||
&& connection
|
&& connection
|
||||||
@@ -7410,12 +7443,6 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
|||||||
NULL);
|
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 */
|
/* Clear any queued transitions */
|
||||||
nm_device_queued_state_clear (self);
|
nm_device_queued_state_clear (self);
|
||||||
|
|
||||||
@@ -7951,6 +7978,8 @@ _set_state_full (NMDevice *self,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NM_DEVICE_STATE_DEACTIVATING:
|
case NM_DEVICE_STATE_DEACTIVATING:
|
||||||
|
_cancel_activation (self);
|
||||||
|
|
||||||
if (quitting) {
|
if (quitting) {
|
||||||
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
|
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
|
||||||
nm_act_request_get_connection (req),
|
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);
|
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);
|
void nm_device_queue_activation (NMDevice *device, NMActRequest *req);
|
||||||
|
|
||||||
gboolean nm_device_supports_vlans (NMDevice *device);
|
gboolean nm_device_supports_vlans (NMDevice *device);
|
||||||
|
@@ -2684,7 +2684,7 @@ _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **er
|
|||||||
static gboolean
|
static gboolean
|
||||||
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
||||||
{
|
{
|
||||||
NMDevice *device, *master_device = NULL;
|
NMDevice *device, *existing, *master_device = NULL;
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
NMConnection *master_connection = NULL;
|
NMConnection *master_connection = NULL;
|
||||||
NMActiveConnection *master_ac = NULL;
|
NMActiveConnection *master_ac = NULL;
|
||||||
@@ -2836,6 +2836,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||||||
nm_active_connection_get_path (master_ac));
|
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 */
|
/* Export the new ActiveConnection to clients and start it on the device */
|
||||||
nm_active_connection_export (active);
|
nm_active_connection_export (active);
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
|
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 exported, make sure the manager's activating-connection property
|
||||||
* is up-to-date.
|
* is up-to-date.
|
||||||
*/
|
*/
|
||||||
|
active_connection_add (self, active);
|
||||||
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2942,18 +2948,6 @@ _new_active_connection (NMManager *self,
|
|||||||
return NULL;
|
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 */
|
/* Normalize the specific object */
|
||||||
if (specific_object && g_strcmp0 (specific_object, "/") == 0)
|
if (specific_object && g_strcmp0 (specific_object, "/") == 0)
|
||||||
specific_object = NULL;
|
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_DEACTIVATING);
|
||||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
||||||
}
|
}
|
||||||
active_connection_remove (self, active);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3063,10 +3056,8 @@ nm_manager_activate_connection (NMManager *self,
|
|||||||
device,
|
device,
|
||||||
subject,
|
subject,
|
||||||
error);
|
error);
|
||||||
if (active) {
|
if (active)
|
||||||
nm_active_connection_authorize (active, _internal_activation_auth_done, self, NULL);
|
nm_active_connection_authorize (active, _internal_activation_auth_done, self, NULL);
|
||||||
active_connection_add (self, active);
|
|
||||||
}
|
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3313,7 +3304,6 @@ impl_manager_activate_connection (NMManager *self,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
nm_active_connection_authorize (active, _activation_auth_done, self, context);
|
nm_active_connection_authorize (active, _activation_auth_done, self, context);
|
||||||
active_connection_add (self, active);
|
|
||||||
g_clear_object (&subject);
|
g_clear_object (&subject);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3391,8 +3381,6 @@ _add_and_activate_auth_done (NMActiveConnection *active,
|
|||||||
activation_add_done,
|
activation_add_done,
|
||||||
info);
|
info);
|
||||||
} else {
|
} else {
|
||||||
active_connection_remove (self, active);
|
|
||||||
|
|
||||||
g_assert (error_desc);
|
g_assert (error_desc);
|
||||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||||
@@ -3499,7 +3487,6 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
nm_active_connection_authorize (active, _add_and_activate_auth_done, self, context);
|
nm_active_connection_authorize (active, _add_and_activate_auth_done, self, context);
|
||||||
active_connection_add (self, active);
|
|
||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
g_object_unref (subject);
|
g_object_unref (subject);
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user