diff options
author | Dan Williams <dcbw@redhat.com> | 2014-09-24 15:13:19 -0500 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-12-04 12:15:12 +0100 |
commit | 0be66bb1ebb0f0ff197c38131bba42dda346df52 (patch) | |
tree | 06b3dceadc05ee9316af318b27ed2c4fb66b419b | |
parent | deb6c5f7143f9f257b79a8c9db724310ef4c9a31 (diff) | |
download | NetworkManager-0be66bb1ebb0f0ff197c38131bba42dda346df52.tar.gz |
core: add class function for device unrealization
When a device is unrealized, its class-specific properties must also be cleared
since the device is no longer valid.
-rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 29 | ||||
-rw-r--r-- | src/devices/nm-device-tun.c | 21 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 11 | ||||
-rw-r--r-- | src/devices/nm-device-vxlan.c | 20 | ||||
-rw-r--r-- | src/devices/nm-device.c | 119 | ||||
-rw-r--r-- | src/devices/nm-device.h | 14 | ||||
-rw-r--r-- | src/nm-manager.c | 12 |
7 files changed, 217 insertions, 9 deletions
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 746fb170d0..922a3489c1 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -728,6 +728,34 @@ setup (NMDevice *device, NMPlatformLink *plink) } static void +unrealize (NMDevice *device, gboolean remove_resources) +{ + NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); + GParamSpec **properties; + guint n_properties, i; + + NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->unrealize (device, remove_resources); + + g_clear_object (&priv->parent); + priv->parent_ifindex = 0; + g_clear_pointer (&priv->local, g_free); + g_clear_pointer (&priv->remote, g_free); + priv->ttl = 0; + priv->tos = 0; + priv->path_mtu_discovery = FALSE; + g_clear_pointer (&priv->input_key, g_free); + g_clear_pointer (&priv->output_key, g_free); + priv->encap_limit = 0; + priv->flow_label = 0; + + properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties); + for (i = 0; i < n_properties; i++) + g_object_notify_by_pspec (G_OBJECT (self), properties[i]); + g_free (properties); +} + +static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { @@ -809,6 +837,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) device_class->create_and_realize = create_and_realize; device_class->realize = realize; device_class->setup = setup; + device_class->unrealize = unrealize; device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME; diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 978c1bace3..214b227030 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -24,9 +24,9 @@ #include <string.h> #include <sys/types.h> +#include "nm-default.h" #include "nm-device-tun.h" #include "nm-device-private.h" -#include "nm-default.h" #include "nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" @@ -265,6 +265,24 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return TRUE; } +static void +unrealize (NMDevice *device, gboolean remove_resources) +{ + NMDeviceTun *self = NM_DEVICE_TUN (device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); + GParamSpec **properties; + guint n_properties, i; + + NM_DEVICE_CLASS (nm_device_tun_parent_class)->unrealize (device, remove_resources); + + memset (&priv->props, 0, sizeof (NMPlatformTunProperties)); + + properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties); + for (i = 0; i < n_properties; i++) + g_object_notify_by_pspec (G_OBJECT (self), properties[i]); + g_free (properties); +} + /**************************************************************/ static void @@ -349,6 +367,7 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) device_class->check_connection_compatible = check_connection_compatible; device_class->create_and_realize = create_and_realize; device_class->realize = realize; + device_class->unrealize = unrealize; device_class->update_connection = update_connection; /* properties */ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 1712a81385..0f7b0d9f80 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -256,6 +256,16 @@ create_and_realize (NMDevice *device, return TRUE; } +static void +unrealize (NMDevice *device, gboolean remove_resources) +{ + NM_DEVICE_CLASS (nm_device_vlan_parent_class)->unrealize (device, remove_resources); + + 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); +} + /******************************************************************/ static NMDeviceCapabilities @@ -663,6 +673,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-vxlan.c b/src/devices/nm-device-vxlan.c index 7fb55f2086..f52d81e0a7 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -22,9 +22,9 @@ #include <string.h> +#include "nm-default.h" #include "nm-device-vxlan.h" #include "nm-device-private.h" -#include "nm-default.h" #include "nm-manager.h" #include "nm-platform.h" #include "nm-utils.h" @@ -142,6 +142,23 @@ setup (NMDevice *device, NMPlatformLink *plink) update_properties (device); } +static void +unrealize (NMDevice *device, gboolean remove_resources) +{ + NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self); + GParamSpec **properties; + guint n_properties, i; + + NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->unrealize (device, remove_resources); + + memset (&priv->props, 0, sizeof (NMPlatformLnkVxlan)); + + properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties); + for (i = 0; i < n_properties; i++) + g_object_notify_by_pspec (G_OBJECT (self), properties[i]); + g_free (properties); +} /**************************************************************/ @@ -231,6 +248,7 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) device_class->link_changed = link_changed; device_class->setup = setup; + device_class->unrealize = unrealize; /* properties */ g_object_class_install_property diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index d55493fff6..f9607685fd 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1858,6 +1858,103 @@ setup (NMDevice *self, NMPlatformLink *plink) g_object_thaw_notify (G_OBJECT (self)); } +static void +unrealize (NMDevice *self, gboolean remove_resources) +{ + int ifindex; + + if (remove_resources) { + ifindex = nm_device_get_ifindex (self); + if ( ifindex > 0 + && nm_device_is_software (self)) + nm_platform_link_delete (NM_PLATFORM_GET, ifindex); + } +} + +/** + * 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; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + if (!nm_device_is_software (self) || !nm_device_is_real (self)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device or is not realized"); + return FALSE; + } + + priv = NM_DEVICE_GET_PRIVATE (self); + + g_return_val_if_fail (priv->iface != NULL, FALSE); + + g_object_freeze_notify (G_OBJECT (self)); + + if (NM_DEVICE_GET_CLASS (self)->unrealize) + NM_DEVICE_GET_CLASS (self)->unrealize (self, remove_resources); + + 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 TRUE; +} + /** * nm_device_notify_new_device_added(): * @self: the #NMDevice @@ -6471,16 +6568,21 @@ 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); + gs_free_error GError *error = NULL; 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); + if (!nm_device_unrealize (data->device, TRUE, &error)) + _LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message); + } else + nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex); + g_free (data); return FALSE; } @@ -6611,6 +6713,8 @@ delete_cb (NMDevice *self, GError *error, gpointer user_data) { + GError *local = NULL; + if (error) { g_dbus_method_invocation_return_gerror (context, error); nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message); @@ -6618,9 +6722,11 @@ delete_cb (NMDevice *self, } /* Authorized */ - nm_platform_link_delete (NM_PLATFORM_GET, nm_device_get_ifindex (self)); - g_dbus_method_invocation_return_value (context, NULL); nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL); + if (nm_device_unrealize (self, TRUE, &local)) + g_dbus_method_invocation_return_value (context, NULL); + else + g_dbus_method_invocation_take_error (context, local); } static void @@ -10219,6 +10325,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 8931b85609..c185184a79 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -183,6 +183,17 @@ 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. + */ + void (*unrealize) (NMDevice *self, gboolean remove_resources); + /* Hardware state (IFF_UP) */ gboolean (*can_unmanaged_external_down) (NMDevice *self); gboolean (*is_up) (NMDevice *self); @@ -466,6 +477,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 4bc0dc3413..5c6bdb2a14 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1949,10 +1949,20 @@ _platform_link_cb_idle (PlatformLinkCbData *data) platform_link_added (self, data->ifindex, &pllink); } else { NMDevice *device; + GError *error = NULL; device = nm_manager_get_device_by_ifindex (self, data->ifindex); - if (device) + if (device) { + 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); + } } g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self); } |