core: refactor unmanaging devices on shutdown and unmanage Wi-Fi devices

Add new virtual function nm_device_unmanage_on_quit() to determine
whether to unmanage the device on shutdown.

This allows Wi-Fi devices to always be unmanaged. We want that to
reset the initial MAC address.
This commit is contained in:
Thomas Haller
2016-06-21 11:04:38 +02:00
parent 7b585bcc93
commit df8cf1462a
4 changed files with 62 additions and 23 deletions

View File

@@ -3362,7 +3362,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave
static gboolean
nm_device_can_assume_connections (NMDevice *self)
{
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
}
/**
@@ -3378,7 +3378,7 @@ nm_device_can_assume_connections (NMDevice *self)
* if there is no active connection or the active connection cannot be
* assumed.
*/
gboolean
static gboolean
nm_device_can_assume_active_connection (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -3425,6 +3425,45 @@ nm_device_can_assume_active_connection (NMDevice *self)
return TRUE;
}
static gboolean
unmanaged_on_quit (NMDevice *self)
{
/* Leave certain devices alone when quitting so their configuration
* can be taken over when NM restarts. This ensures connectivity while
* NM is stopped.
*/
if (nm_device_uses_assumed_connection (self)) {
/* An assume connection must be left alone */
return FALSE;
}
if (!nm_device_get_act_request (self)) {
/* a device without any active connection is either UNAVAILABLE or DISCONNECTED
* state. Since we don't know whether the device was upped by NetworkManager,
* we must leave it up on exit.
*/
return FALSE;
}
if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (self))) {
/* The device has no layer 3 configuration. Leave it up. */
return FALSE;
}
if (nm_device_can_assume_active_connection (self))
return FALSE;
return TRUE;
}
gboolean
nm_device_unmanage_on_quit (NMDevice *self)
{
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self);
}
static gboolean
nm_device_emit_recheck_assume (gpointer user_data)
{
@@ -12357,6 +12396,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->take_down = take_down;
klass->carrier_changed = carrier_changed;
klass->get_ip_iface_identifier = get_ip_iface_identifier;
klass->unmanaged_on_quit = unmanaged_on_quit;
/* Properties */
obj_properties[PROP_UDI] =

View File

@@ -328,6 +328,8 @@ typedef struct {
gboolean (* owns_iface) (NMDevice *self, const char *iface);
NMConnection * (* new_default_connection) (NMDevice *self);
gboolean (* unmanaged_on_quit) (NMDevice *self);
} NMDeviceClass;
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
@@ -417,7 +419,7 @@ gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnec
gboolean nm_device_uses_assumed_connection (NMDevice *device);
gboolean nm_device_can_assume_active_connection (NMDevice *device);
gboolean nm_device_unmanage_on_quit (NMDevice *self);
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);

View File

@@ -193,6 +193,18 @@ constructed (GObject *object)
priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ());
}
static gboolean
unmanaged_on_quit (NMDevice *self)
{
/* Wi-Fi devices cannot be assumed and are always taken down.
* However, also when being disconnected, we scan and thus
* set the MAC address to a random value.
*
* We must restore the original MAC address when quitting, thus
* signal to unmanage the device. */
return TRUE;
}
static gboolean
supplicant_interface_acquire (NMDeviceWifi *self)
{
@@ -3097,6 +3109,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout;
parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
parent_class->deactivate = deactivate;
parent_class->unmanaged_on_quit = unmanaged_on_quit;
parent_class->state_changed = device_state_changed;

View File

@@ -945,28 +945,12 @@ remove_device (NMManager *self,
nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
unmanage = TRUE;
if (!quitting) {
if (quitting)
unmanage = nm_device_unmanage_on_quit (device);
else {
/* the device is already gone. Unmanage it. */
} else {
/* Leave certain devices alone when quitting so their configuration
* can be taken over when NM restarts. This ensures connectivity while
* NM is stopped.
*/
if (nm_device_uses_assumed_connection (device)) {
/* An assume connection must be left alone */
unmanage = FALSE;
} else if (!nm_device_get_act_request (device)) {
/* a device without any active connection is either UNAVAILABLE or DISCONNECTED
* state. Since we don't know whether the device was upped by NetworkManager,
* we must leave it up on exit. */
unmanage = FALSE;
} else if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (device))) {
/* The device has no layer 3 configuration. Leave it up. */
unmanage = FALSE;
} else if (nm_device_can_assume_active_connection (device))
unmanage = FALSE;
unmanage = TRUE;
}
if (unmanage) {