diff options
author | Dan Williams <dcbw@redhat.com> | 2014-09-24 15:13:19 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-12-11 10:07:41 -0600 |
commit | db602934cc509c27cc7ce0f11dc3d48dd1865b48 (patch) | |
tree | 7818fd4f2646b7db343b763f96012fe66f58c9f2 | |
parent | 594a58120ad9bf91c054270d38ed63f5d883948c (diff) | |
download | NetworkManager-db602934cc509c27cc7ce0f11dc3d48dd1865b48.tar.gz |
core: add class function for device unrealization
-rw-r--r-- | src/devices/nm-device-vlan.c | 9 | ||||
-rw-r--r-- | src/devices/nm-device.c | 82 | ||||
-rw-r--r-- | src/devices/nm-device.h | 17 | ||||
-rw-r--r-- | src/nm-manager.c | 25 |
4 files changed, 120 insertions, 13 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 4f50d7481a..cd639de7d7 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -169,6 +169,14 @@ create_and_realize (NMDevice *device, return TRUE; } +static gboolean +unrealize (NMDevice *device, gboolean link_deleted, GError **error) +{ + NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id = 0; + nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), NULL); + return TRUE; +} + static guint32 get_generic_capabilities (NMDevice *dev) { @@ -564,6 +572,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 e2c9db4d5c..e4d7f765f7 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1488,6 +1488,67 @@ setup (NMDevice *self, NMPlatformLink *plink) g_object_notify (G_OBJECT (self), NM_DEVICE_REAL); } +static gboolean +unrealize (NMDevice *self, gboolean link_deleted, GError **error) +{ + int ifindex = nm_device_get_ifindex (self); + + if (ifindex > 0 && nm_device_is_software (self) && !link_deleted) + nm_platform_link_delete (ifindex); + + return TRUE; +} + +/** + * nm_device_unrealize(): + * @self: the #NMDevice + * @error: location to store error, or %NULL + * + * Release any backing resources (kernel devices, etc) created for this + * device and clear properties associated with external resources. + * + * Returns: %TRUE on success, %FALSE on error + */ +gboolean +nm_device_unrealize (NMDevice *self, gboolean link_deleted, 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); + + if (NM_DEVICE_GET_CLASS (self)->unrealize) + success = NM_DEVICE_GET_CLASS (self)->unrealize (self, link_deleted, error); + + priv->ifindex = 0; + priv->ip_ifindex = 0; + g_clear_pointer (&priv->ip_iface, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + g_clear_pointer (&priv->driver_version, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION); + g_clear_pointer (&priv->firmware_version, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION); + g_clear_pointer (&priv->udi, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_UDI); + g_clear_pointer (&priv->hw_addr, g_free); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); + 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); + + return success; +} + /** * nm_device_notify_component_added(): * @self: the #NMDevice @@ -5603,16 +5664,20 @@ 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; + + nm_device_unrealize (data->device, FALSE, NULL); + } else { + nm_platform_link_delete (data->ifindex); } - _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); - nm_platform_link_delete (data->ifindex); g_free (data); return FALSE; } @@ -5731,14 +5796,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_device_get_ifindex (self)); - dbus_g_method_return (context); + if (nm_device_unrealize (self, FALSE, &local)) + dbus_g_method_return (context); + else { + dbus_g_method_return_error (context, local); + g_clear_error (&local); + } } static void @@ -8488,6 +8559,7 @@ nm_device_class_init (NMDeviceClass *klass) klass->check_connection_compatible = check_connection_compatible; klass->check_connection_available = check_connection_available; 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 9c5e264dd4..25429deff8 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -154,6 +154,20 @@ typedef struct { */ void (*setup) (NMDevice *self, NMPlatformLink *plink); + /** + * unrealize(): + * @self: the #NMDevice + * @link_deleted: if %TRUE, the backing kernel resources are already deleted + * @error: location to store error, or %NULL + * + * Releases any backing resources (kernel devices, etc) created for this + * device and clears properties that depend on them. Does not destroy + * the device object itself. + * + * Returns: %TRUE on success, %FALSE on error + */ + gboolean (*unrealize) (NMDevice *self, gboolean link_deleted, GError **error); + /* Hardware state (IFF_UP) */ gboolean (*is_up) (NMDevice *self); gboolean (*bring_up) (NMDevice *self, gboolean *no_firmware); @@ -390,6 +404,9 @@ gboolean nm_device_create_and_realize (NMDevice *self, NMConnection *connection, NMDevice *parent, GError **error); +gboolean nm_device_unrealize (NMDevice *device, + gboolean link_deleted, + GError **error); gboolean nm_device_get_autoconnect (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3b8e30b94c..4889517742 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1897,19 +1897,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, TRUE, &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; } |