diff options
author | Dan Williams <dcbw@redhat.com> | 2014-09-24 15:13:19 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2015-05-15 09:46:38 -0500 |
commit | 2ac0e142300dbc81e04fc49199ad22a30ad640a9 (patch) | |
tree | ceb334dc31000776666203bdd3be52de5f00736c | |
parent | 453c4865bbdc0ff588d445c403fa76709981cf58 (diff) | |
download | NetworkManager-2ac0e142300dbc81e04fc49199ad22a30ad640a9.tar.gz |
core: add class function for device unrealization
-rw-r--r-- | src/devices/nm-device-vlan.c | 15 | ||||
-rw-r--r-- | src/devices/nm-device.c | 108 | ||||
-rw-r--r-- | src/devices/nm-device.h | 16 | ||||
-rw-r--r-- | src/nm-manager.c | 25 |
4 files changed, 150 insertions, 14 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 2e372df610..8570db5b43 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -220,6 +220,20 @@ create_and_realize (NMDevice *device, return TRUE; } +static gboolean +unrealize (NMDevice *device, gboolean remove_resources, GError **error) +{ + gboolean success; + + success = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->unrealize (device, remove_resources, error); + + NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id = 0; + g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID); + nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), NULL); + + return success; +} + /******************************************************************/ static NMDeviceCapabilities @@ -613,6 +627,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) parent_class->create_and_realize = create_and_realize; parent_class->realize = realize; parent_class->setup = setup; + parent_class->unrealize = unrealize; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->bring_up = bring_up; parent_class->act_stage1_prepare = act_stage1_prepare; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e5b5fc9ad9..196806559e 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1681,6 +1681,92 @@ setup (NMDevice *self, NMPlatformLink *plink) g_object_thaw_notify (G_OBJECT (self)); } +static gboolean +unrealize (NMDevice *self, gboolean remove_resources, GError **error) +{ + int ifindex = nm_device_get_ifindex (self); + + if (ifindex > 0 && nm_device_is_software (self) && remove_resources) + nm_platform_link_delete (NM_PLATFORM_GET, ifindex); + + return TRUE; +} + +/** + * nm_device_unrealize(): + * @self: the #NMDevice + * @remove_resources: if %TRUE, remove backing resources + * @error: location to store error, or %NULL + * + * Clears any properties that depend on backing resources (kernel devices, + * etc) and removes those resources if @remove_resources is %TRUE. + * + * Returns: %TRUE on success, %FALSE on error + */ +gboolean +nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean success = TRUE; + + g_return_val_if_fail (nm_device_is_real (self), FALSE); + g_return_val_if_fail (nm_device_is_software (self), FALSE); + g_return_val_if_fail (priv->iface != NULL, FALSE); + + g_object_freeze_notify (G_OBJECT (self)); + + if (NM_DEVICE_GET_CLASS (self)->unrealize) + success = NM_DEVICE_GET_CLASS (self)->unrealize (self, remove_resources, error); + + if (priv->ifindex > 0) { + priv->ifindex = 0; + g_object_notify (G_OBJECT (self), NM_DEVICE_IFINDEX); + } + priv->ip_ifindex = 0; + if (priv->ip_iface) { + g_clear_pointer (&priv->ip_iface, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + } + if (priv->driver_version) { + g_clear_pointer (&priv->driver_version, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION); + } + if (priv->firmware_version) { + g_clear_pointer (&priv->firmware_version, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION); + } + if (priv->udi) { + g_clear_pointer (&priv->udi, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_UDI); + } + if (priv->hw_addr) { + g_clear_pointer (&priv->hw_addr, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); + } + if (priv->physical_port_id) { + g_clear_pointer (&priv->physical_port_id, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID); + } + + g_clear_pointer (&priv->perm_hw_addr, g_free); + g_clear_pointer (&priv->initial_hw_addr, g_free); + + priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; + g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES); + + priv->real = FALSE; + g_object_notify (G_OBJECT (self), NM_DEVICE_REAL); + + g_object_thaw_notify (G_OBJECT (self)); + + nm_device_state_changed (self, + NM_DEVICE_STATE_UNMANAGED, + remove_resources ? + NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + + return success; +} + /** * nm_device_notify_component_added(): * @self: the #NMDevice @@ -5931,16 +6017,19 @@ delete_on_deactivate_link_delete (gpointer user_data) DeleteOnDeactivateData *data = user_data; NMDevice *self = data->device; + _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", + data->ifindex, data->idle_add_id); + if (data->device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device); g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device); priv->delete_on_deactivate_data = NULL; - } - _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); - nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex); + nm_device_unrealize (data->device, TRUE, NULL); + } else + nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex); + g_free (data); return FALSE; } @@ -6068,14 +6157,20 @@ delete_cb (NMDevice *self, GError *error, gpointer user_data) { + GError *local = NULL; + if (error) { dbus_g_method_return_error (context, error); return; } /* Authorized */ - nm_platform_link_delete (NM_PLATFORM_GET, nm_device_get_ifindex (self)); - dbus_g_method_return (context); + if (nm_device_unrealize (self, TRUE, &local)) + dbus_g_method_return (context); + else { + dbus_g_method_return_error (context, local); + g_clear_error (&local); + } } static void @@ -9114,6 +9209,7 @@ nm_device_class_init (NMDeviceClass *klass) klass->check_connection_available = check_connection_available; klass->can_unmanaged_external_down = can_unmanaged_external_down; klass->setup = setup; + klass->unrealize = unrealize; klass->is_up = is_up; klass->bring_up = bring_up; klass->take_down = take_down; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 955aec2941..5f87e0da07 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -183,6 +183,19 @@ typedef struct { */ void (*setup) (NMDevice *self, NMPlatformLink *plink); + /** + * unrealize(): + * @self: the #NMDevice + * @remove_resources: if %TRUE remove backing resources + * @error: location to store error, or %NULL + * + * Clears any properties that depend on backing resources (kernel devices, + * etc) and removes those resources if @remove_resources is %TRUE. + * + * Returns: %TRUE on success, %FALSE on error + */ + gboolean (*unrealize) (NMDevice *self, gboolean remove_resources, GError **error); + /* Hardware state (IFF_UP) */ gboolean (*can_unmanaged_external_down) (NMDevice *self); gboolean (*is_up) (NMDevice *self); @@ -452,6 +465,9 @@ gboolean nm_device_create_and_realize (NMDevice *self, NMConnection *connection, NMDevice *parent, GError **error); +gboolean nm_device_unrealize (NMDevice *device, + gboolean remove_resources, + GError **error); gboolean nm_device_get_autoconnect (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 909eea4651..158164d583 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1928,19 +1928,28 @@ platform_link_cb (NMPlatform *platform, NMPlatformReason reason, gpointer user_data) { + NMManager *self = NM_MANAGER (user_data); + NMDevice *device; + GError *error = NULL; + switch (change_type) { case NM_PLATFORM_SIGNAL_ADDED: - platform_link_added (NM_MANAGER (user_data), ifindex, plink, reason); + platform_link_added (self, ifindex, plink, reason); break; - case NM_PLATFORM_SIGNAL_REMOVED: { - NMManager *self = NM_MANAGER (user_data); - NMDevice *device; - + case NM_PLATFORM_SIGNAL_REMOVED: device = nm_manager_get_device_by_ifindex (self, ifindex); - if (device) - remove_device (self, device, FALSE, TRUE); + if (!device) + break; + if (nm_device_is_software (device)) { + if (!nm_device_unrealize (device, FALSE, &error)) { + nm_log_warn (LOGD_DEVICE, "(%s): failed to unrealize: %s", + nm_device_get_iface (device), + error->message); + g_clear_error (&error); + } + } + remove_device (self, device, FALSE, TRUE); break; - } default: break; } |