diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 0465ae36b..ae9543e4e 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -42,6 +42,7 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) typedef struct { gboolean is_partition; + int parent_ifindex, p_key; } NMDeviceInfinibandPrivate; enum { @@ -235,16 +236,16 @@ create_and_realize (NMDevice *device, const NMPlatformLink **out_plink, GError **error) { + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); NMSettingInfiniband *s_infiniband; - int parent_ifindex, p_key; NMPlatformError plerr; s_infiniband = nm_connection_get_setting_infiniband (connection); g_assert (s_infiniband); /* Can only create partitions at this time */ - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - if (p_key < 0) { + priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband); + if (priv->p_key < 0) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "only InfiniBand partitions can be created"); return FALSE; @@ -263,15 +264,15 @@ create_and_realize (NMDevice *device, return FALSE; } - parent_ifindex = nm_device_get_ifindex (parent); - if (parent_ifindex <= 0) { + priv->parent_ifindex = nm_device_get_ifindex (parent); + if (priv->parent_ifindex <= 0) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "failed to get InfiniBand parent %s ifindex", nm_device_get_iface (parent)); return FALSE; } - plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, parent_ifindex, p_key, out_plink); + plerr = nm_platform_link_infiniband_add (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key, out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create InfiniBand P_Key interface '%s' for '%s': %s", @@ -281,7 +282,33 @@ create_and_realize (NMDevice *device, return FALSE; } - NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->is_partition = TRUE; + priv->is_partition = TRUE; + return TRUE; +} + +static gboolean +unrealize (NMDevice *device, GError **error) +{ + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); + NMPlatformError plerr; + + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE); + + if (priv->p_key < 0) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + "Only InfiniBand partitions can be removed"); + return FALSE; + } + + plerr = nm_platform_link_infiniband_delete (NM_PLATFORM_GET, priv->parent_ifindex, priv->p_key); + if (plerr != NM_PLATFORM_ERROR_SUCCESS) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to remove InfiniBand P_Key interface '%s': %s", + nm_device_get_iface (device), + nm_platform_error_to_string (plerr)); + return FALSE; + } + return TRUE; } @@ -335,6 +362,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) object_class->set_property = set_property; parent_class->create_and_realize = create_and_realize; + parent_class->unrealize = unrealize; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 1c6612df8..499a624c8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2138,8 +2138,12 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) _LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0); if (remove_resources) { - if (ifindex > 0) + if (NM_DEVICE_GET_CLASS (self)->unrealize) { + if (!NM_DEVICE_GET_CLASS (self)->unrealize (self, error)) + return FALSE; + } else if (ifindex > 0) { nm_platform_link_delete (NM_PLATFORM_GET, ifindex); + } } NM_DEVICE_GET_CLASS (self)->unrealize_notify (self); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 368e77f74..2221ede12 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -179,6 +179,14 @@ typedef struct { */ void (*realize_start_notify) (NMDevice *self, const NMPlatformLink *plink); + /** + * unrealize(): + * @self: the #NMDevice + * + * Remove the device backing resources. + */ + gboolean (*unrealize) (NMDevice *self, GError **error); + /** * unrealize_notify(): * @self: the #NMDevice