infiniband: remove the partitions on unrealizing
The infiniband drivers don't implement the rtnetlink link deletions. Therefore we unrealize the NMDevice instance but the backing resources stay around, preventing us from ever realizing the device again.
This commit is contained in:
@@ -42,6 +42,7 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean is_partition;
|
gboolean is_partition;
|
||||||
|
int parent_ifindex, p_key;
|
||||||
} NMDeviceInfinibandPrivate;
|
} NMDeviceInfinibandPrivate;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -235,16 +236,16 @@ create_and_realize (NMDevice *device,
|
|||||||
const NMPlatformLink **out_plink,
|
const NMPlatformLink **out_plink,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device);
|
||||||
NMSettingInfiniband *s_infiniband;
|
NMSettingInfiniband *s_infiniband;
|
||||||
int parent_ifindex, p_key;
|
|
||||||
NMPlatformError plerr;
|
NMPlatformError plerr;
|
||||||
|
|
||||||
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
||||||
g_assert (s_infiniband);
|
g_assert (s_infiniband);
|
||||||
|
|
||||||
/* Can only create partitions at this time */
|
/* Can only create partitions at this time */
|
||||||
p_key = nm_setting_infiniband_get_p_key (s_infiniband);
|
priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband);
|
||||||
if (p_key < 0) {
|
if (priv->p_key < 0) {
|
||||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
||||||
"only InfiniBand partitions can be created");
|
"only InfiniBand partitions can be created");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -263,15 +264,15 @@ create_and_realize (NMDevice *device,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_ifindex = nm_device_get_ifindex (parent);
|
priv->parent_ifindex = nm_device_get_ifindex (parent);
|
||||||
if (parent_ifindex <= 0) {
|
if (priv->parent_ifindex <= 0) {
|
||||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
||||||
"failed to get InfiniBand parent %s ifindex",
|
"failed to get InfiniBand parent %s ifindex",
|
||||||
nm_device_get_iface (parent));
|
nm_device_get_iface (parent));
|
||||||
return FALSE;
|
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) {
|
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
||||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
||||||
"Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
|
"Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
|
||||||
@@ -281,7 +282,33 @@ create_and_realize (NMDevice *device,
|
|||||||
return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,6 +362,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
|
|||||||
object_class->set_property = set_property;
|
object_class->set_property = set_property;
|
||||||
|
|
||||||
parent_class->create_and_realize = create_and_realize;
|
parent_class->create_and_realize = create_and_realize;
|
||||||
|
parent_class->unrealize = unrealize;
|
||||||
parent_class->get_generic_capabilities = get_generic_capabilities;
|
parent_class->get_generic_capabilities = get_generic_capabilities;
|
||||||
parent_class->check_connection_compatible = check_connection_compatible;
|
parent_class->check_connection_compatible = check_connection_compatible;
|
||||||
parent_class->complete_connection = complete_connection;
|
parent_class->complete_connection = complete_connection;
|
||||||
|
@@ -2138,9 +2138,13 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||||||
_LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
|
_LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
|
||||||
|
|
||||||
if (remove_resources) {
|
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_platform_link_delete (NM_PLATFORM_GET, ifindex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NM_DEVICE_GET_CLASS (self)->unrealize_notify (self);
|
NM_DEVICE_GET_CLASS (self)->unrealize_notify (self);
|
||||||
|
|
||||||
|
@@ -179,6 +179,14 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
void (*realize_start_notify) (NMDevice *self, const NMPlatformLink *plink);
|
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():
|
* unrealize_notify():
|
||||||
* @self: the #NMDevice
|
* @self: the #NMDevice
|
||||||
|
Reference in New Issue
Block a user