merge: more isolated pieces of dcbw/devices-for-all (bgo #749401)

(cherry picked from commit c428935d9f)
This commit is contained in:
Dan Williams 2015-05-19 09:28:25 -05:00 committed by Thomas Haller
commit b8e9b91531
11 changed files with 256 additions and 95 deletions

View file

@ -64,7 +64,7 @@ enum {
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
return NM_DEVICE_CAP_CARRIER_DETECT;
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean

View file

@ -62,7 +62,7 @@ enum {
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
return NM_DEVICE_CAP_CARRIER_DETECT;
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean

View file

@ -44,12 +44,15 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE)
#define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate))
#define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition"
typedef struct {
int dummy;
gboolean is_partition;
} NMDeviceInfinibandPrivate;
enum {
PROP_0,
PROP_IS_PARTITION,
LAST_PROP
};
@ -62,7 +65,12 @@ nm_device_infiniband_init (NMDeviceInfiniband * self)
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
return NM_DEVICE_CAP_CARRIER_DETECT;
guint32 caps = NM_DEVICE_CAP_CARRIER_DETECT;
if (NM_DEVICE_INFINIBAND_GET_PRIVATE (dev)->is_partition)
caps |= NM_DEVICE_CAP_IS_SOFTWARE;
return caps;
}
static NMActStageReturn
@ -213,8 +221,8 @@ update_connection (NMDevice *device, NMConnection *connection)
{
NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection);
const char *mac = nm_device_get_hw_address (device);
char *mode_path, *contents = NULL;
const char *transport_mode = "datagram";
int ifindex;
if (!s_infiniband) {
s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new ();
@ -224,16 +232,10 @@ update_connection (NMDevice *device, NMConnection *connection)
if (mac && !nm_utils_hwaddr_matches (mac, -1, NULL, INFINIBAND_ALEN))
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL);
mode_path = g_strdup_printf ("/sys/class/net/%s/mode",
ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (device)));
contents = nm_platform_sysctl_get (NM_PLATFORM_GET, mode_path);
g_free (mode_path);
if (contents) {
if (strstr (contents, "datagram"))
ifindex = nm_device_get_ifindex (device);
if (ifindex > 0) {
if (!nm_platform_infiniband_get_info (NM_PLATFORM_GET, ifindex, NULL, NULL, &transport_mode))
transport_mode = "datagram";
else if (strstr (contents, "connected"))
transport_mode = "connected";
g_free (contents);
}
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL);
}
@ -243,6 +245,9 @@ get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_IS_PARTITION:
g_value_set_boolean (value, NM_DEVICE_INFINIBAND_GET_PRIVATE (object)->is_partition);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -254,6 +259,9 @@ set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_IS_PARTITION:
NM_DEVICE_INFINIBAND_GET_PRIVATE (object)->is_partition = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -281,6 +289,12 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
parent_class->ip4_config_pre_commit = ip4_config_pre_commit;
/* properties */
g_object_class_install_property
(object_class, PROP_IS_PARTITION,
g_param_spec_boolean (NM_DEVICE_INFINIBAND_IS_PARTITION, "", "",
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
@ -299,6 +313,7 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, gboolean *out_ignore,
NM_DEVICE_PLATFORM_DEVICE, plink,
NM_DEVICE_TYPE_DESC, "InfiniBand",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND,
NM_DEVICE_INFINIBAND_IS_PARTITION, (plink->parent > 0),
NULL);
}
@ -342,6 +357,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
NM_DEVICE_DRIVER, nm_device_get_driver (parent),
NM_DEVICE_TYPE_DESC, "InfiniBand",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND,
NM_DEVICE_INFINIBAND_IS_PARTITION, TRUE,
NULL);
}

View file

@ -52,12 +52,10 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate))
typedef struct {
gboolean disposed;
gboolean invalid;
NMDevice *parent;
guint parent_state_id;
int vlan_id;
} NMDeviceVlanPrivate;
@ -73,38 +71,6 @@ enum {
/******************************************************************/
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
/* We assume VLAN interfaces always support carrier detect */
return NM_DEVICE_CAP_CARRIER_DETECT;
}
static gboolean
bring_up (NMDevice *dev, gboolean *no_firmware)
{
gboolean success = FALSE;
guint i = 20;
while (i-- > 0 && !success) {
success = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->bring_up (dev, no_firmware);
g_usleep (50);
}
return success;
}
/******************************************************************/
static gboolean
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
if (!NM_DEVICE_VLAN_GET_PRIVATE (device)->parent)
return FALSE;
return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->is_available (device, flags);
}
static void
parent_state_changed (NMDevice *parent,
NMDeviceState new_state,
@ -163,6 +129,38 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent, gboolean constr
g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_PARENT);
}
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *dev)
{
/* We assume VLAN interfaces always support carrier detect */
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean
bring_up (NMDevice *dev, gboolean *no_firmware)
{
gboolean success = FALSE;
guint i = 20;
while (i-- > 0 && !success) {
success = NM_DEVICE_CLASS (nm_device_vlan_parent_class)->bring_up (dev, no_firmware);
g_usleep (50);
}
return success;
}
/******************************************************************/
static gboolean
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
if (!NM_DEVICE_VLAN_GET_PRIVATE (device)->parent)
return FALSE;
return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->is_available (device, flags);
}
static gboolean
component_added (NMDevice *device, GObject *component)
{
@ -553,16 +551,7 @@ set_property (GObject *object, guint prop_id,
static void
dispose (GObject *object)
{
NMDeviceVlan *self = NM_DEVICE_VLAN (object);
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
if (priv->disposed) {
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
return;
}
priv->disposed = TRUE;
nm_device_vlan_set_parent (self, NULL, FALSE);
nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), NULL, FALSE);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
}

View file

@ -185,7 +185,6 @@ typedef struct {
char * path;
char * iface; /* may change, could be renamed by user */
int ifindex;
gboolean is_software;
char * ip_iface;
int ip_ifindex;
NMDeviceType type;
@ -538,9 +537,7 @@ nm_device_get_ifindex (NMDevice *self)
gboolean
nm_device_is_software (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
return priv->is_software;
return NM_FLAGS_HAS (NM_DEVICE_GET_PRIVATE (self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE);
}
const char *
@ -1057,7 +1054,7 @@ nm_device_finish_init (NMDevice *self)
nm_device_enslave_slave (priv->master, self, NULL);
if (priv->ifindex > 0) {
if (priv->platform_link_initialized || (priv->is_nm_owned && priv->is_software)) {
if (priv->platform_link_initialized || (priv->is_nm_owned && nm_device_is_software (self))) {
nm_platform_link_get_unmanaged (NM_PLATFORM_GET, priv->ifindex, &platform_unmanaged);
nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_DEFAULT, platform_unmanaged);
} else {
@ -8434,6 +8431,12 @@ constructor (GType type,
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
if (priv->ifindex > 0) {
priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
nm_platform_link_get_driver_info (NM_PLATFORM_GET,
priv->ifindex,
NULL,
@ -8441,6 +8444,9 @@ constructor (GType type,
&priv->firmware_version);
}
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
/* Watch for external IP config changes */
platform = nm_platform_get ();
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self);
@ -8517,16 +8523,6 @@ constructed (GObject *object)
priv->carrier = TRUE;
}
if (priv->ifindex > 0) {
priv->is_software = nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex);
priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
}
/* Indicate software device in capabilities. */
if (priv->is_software)
priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
/* Enslave ourselves */
master = nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex);
if (master)

View file

@ -74,7 +74,7 @@ static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team);
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_CARRIER_DETECT;
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean

View file

@ -470,20 +470,6 @@ _config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeF
/************************************************************************/
static NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
{
GSList *iter;
g_return_val_if_fail (udi != NULL, NULL);
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
return NM_DEVICE (iter->data);
}
return NULL;
}
static NMDevice *
nm_manager_get_device_by_path (NMManager *manager, const char *path)
{
@ -545,6 +531,18 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface)
return NULL;
}
static NMDevice *
find_device_by_iface (NMManager *self, const gchar *iface)
{
GSList *iter;
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
if (g_strcmp0 (nm_device_get_iface (NM_DEVICE (iter->data)), iface) == 0)
return NM_DEVICE (iter->data);
}
return NULL;
}
static gboolean
manager_sleeping (NMManager *self)
{
@ -1751,9 +1749,13 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume)
RfKillType rtype;
GSList *iter, *remove = NULL;
gboolean connection_assumed = FALSE;
int ifindex;
/* No duplicates */
if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device)))
ifindex = nm_device_get_ifindex (device);
if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex))
return;
if (find_device_by_iface (self, nm_device_get_iface (device)))
return;
/* Remove existing devices owned by the new device; eg remove ethernet

View file

@ -47,6 +47,7 @@ typedef struct {
char *udi;
GBytes *address;
int vlan_id;
int ib_p_key;
} NMFakePlatformLink;
#define NM_FAKE_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_FAKE_PLATFORM, NMFakePlatformPrivate))
@ -688,18 +689,42 @@ vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to)
static gboolean
infiniband_partition_add (NMPlatform *platform, int parent, int p_key, NMPlatformLink *out_link)
{
NMFakePlatformLink *parent_device;
char *name;
gboolean success;
NMFakePlatformLink *device, *parent_device;
gs_free char *name = NULL;
parent_device = link_get (platform, parent);
g_return_val_if_fail (parent_device != NULL, FALSE);
name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key);
success = link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link);
g_free (name);
if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link))
return FALSE;
return success;
device = link_get (platform, link_get_ifindex (platform, name));
g_return_val_if_fail (device, FALSE);
device->ib_p_key = p_key;
device->link.parent = parent;
return TRUE;
}
static gboolean
infiniband_get_info (NMPlatform *platform, int ifindex, int *parent, int *p_key, const char **mode)
{
NMFakePlatformLink *device;
device = link_get (platform, ifindex);
g_return_val_if_fail (device, FALSE);
g_return_val_if_fail (device->link.type == NM_LINK_TYPE_INFINIBAND, FALSE);
if (parent)
*parent = device->link.parent;
if (p_key)
*p_key = device->ib_p_key;
if (mode)
*mode = "datagram";
return TRUE;
}
static gboolean
@ -1464,6 +1489,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->vlan_set_egress_map = vlan_set_egress_map;
platform_class->infiniband_partition_add = infiniband_partition_add;
platform_class->infiniband_get_info = infiniband_get_info;
platform_class->veth_get_properties = veth_get_properties;
platform_class->tun_get_properties = tun_get_properties;

View file

@ -3175,6 +3175,115 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, NMPlatfor
return success;
}
typedef struct {
int p_key;
const char *mode;
} IpoibInfo;
/* IFLA_IPOIB_* were introduced in the 3.7 kernel, but the kernel headers
* we're building against might not have those properties even though the
* running kernel might.
*/
#define IFLA_IPOIB_UNSPEC 0
#define IFLA_IPOIB_PKEY 1
#define IFLA_IPOIB_MODE 2
#define IFLA_IPOIB_UMCAST 3
#undef IFLA_IPOIB_MAX
#define IFLA_IPOIB_MAX IFLA_IPOIB_UMCAST
#define IPOIB_MODE_DATAGRAM 0 /* using unreliable datagram QPs */
#define IPOIB_MODE_CONNECTED 1 /* using connected QPs */
static const struct nla_policy infiniband_info_policy[IFLA_IPOIB_MAX + 1] = {
[IFLA_IPOIB_PKEY] = { .type = NLA_U16 },
[IFLA_IPOIB_MODE] = { .type = NLA_U16 },
[IFLA_IPOIB_UMCAST] = { .type = NLA_U16 },
};
static int
infiniband_info_data_parser (struct nlattr *info_data, gpointer parser_data)
{
IpoibInfo *info = parser_data;
struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
int err;
err = nla_parse_nested (tb, IFLA_IPOIB_MAX, info_data,
(struct nla_policy *) infiniband_info_policy);
if (err < 0)
return err;
if (!tb[IFLA_IPOIB_PKEY] || !tb[IFLA_IPOIB_MODE])
return -EINVAL;
info->p_key = nla_get_u16 (tb[IFLA_IPOIB_PKEY]);
switch (nla_get_u16 (tb[IFLA_IPOIB_MODE])) {
case IPOIB_MODE_DATAGRAM:
info->mode = "datagram";
break;
case IPOIB_MODE_CONNECTED:
info->mode = "connected";
break;
default:
return -NLE_PARSE_ERR;
}
return 0;
}
static gboolean
infiniband_get_info (NMPlatform *platform, int ifindex, int *parent, int *p_key, const char **mode)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
auto_nl_object struct rtnl_link *rtnllink = NULL;
IpoibInfo info = { -1, NULL };
rtnllink = link_get (platform, ifindex);
if (!rtnllink)
return FALSE;
if (parent)
*parent = rtnl_link_get_link (rtnllink);
if (nm_rtnl_link_parse_info_data (priv->nlh,
ifindex,
infiniband_info_data_parser,
&info) != 0) {
const char *iface = rtnl_link_get_name (rtnllink);
char *path, *contents = NULL;
/* Fall back to reading sysfs */
path = g_strdup_printf ("/sys/class/net/%s/mode", ASSERT_VALID_PATH_COMPONENT (iface));
contents = nm_platform_sysctl_get (platform, path);
g_free (path);
if (!contents)
return FALSE;
if (strstr (contents, "datagram"))
info.mode = "datagram";
else if (strstr (contents, "connected"))
info.mode = "connected";
g_free (contents);
path = g_strdup_printf ("/sys/class/net/%s/pkey", ASSERT_VALID_PATH_COMPONENT (iface));
contents = nm_platform_sysctl_get (platform, path);
g_free (path);
if (!contents)
return FALSE;
info.p_key = (int) _nm_utils_ascii_str_to_int64 (contents, 16, 0, 0xFFFF, -1);
g_free (contents);
if (info.p_key < 0)
return FALSE;
}
if (p_key)
*p_key = info.p_key;
if (mode)
*mode = info.mode;
return TRUE;
}
static gboolean
veth_get_properties (NMPlatform *platform, int ifindex, NMPlatformVethProperties *props)
{
@ -4849,6 +4958,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->vlan_set_egress_map = vlan_set_egress_map;
platform_class->infiniband_partition_add = infiniband_partition_add;
platform_class->infiniband_get_info = infiniband_get_info;
platform_class->veth_get_properties = veth_get_properties;
platform_class->tun_get_properties = tun_get_properties;

View file

@ -1596,6 +1596,22 @@ nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, N
return klass->infiniband_partition_add (self, parent, p_key, out_link);
}
gboolean
nm_platform_infiniband_get_info (NMPlatform *self,
int ifindex,
int *parent,
int *p_key,
const char **mode)
{
_CHECK_SELF (self, klass, FALSE);
reset_error (self);
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_val_if_fail (klass->infiniband_get_info, FALSE);
return klass->infiniband_get_info (self, ifindex, parent, p_key, mode);
}
gboolean
nm_platform_veth_get_properties (NMPlatform *self, int ifindex, NMPlatformVethProperties *props)
{

View file

@ -439,6 +439,11 @@ typedef struct {
gboolean (*vlan_set_egress_map) (NMPlatform *, int ifindex, int from, int to);
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link);
gboolean (*infiniband_get_info) (NMPlatform *,
int ifindex,
int *parent,
int *p_key,
const char **mode);
gboolean (*veth_get_properties) (NMPlatform *, int ifindex, NMPlatformVethProperties *properties);
gboolean (*tun_get_properties) (NMPlatform *, int ifindex, NMPlatformTunProperties *properties);
@ -602,6 +607,7 @@ gboolean nm_platform_vlan_set_ingress_map (NMPlatform *self, int ifindex, int fr
gboolean nm_platform_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to);
gboolean nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, NMPlatformLink *out_link);
gboolean nm_platform_infiniband_get_info (NMPlatform *self, int ifindex, int *parent, int *p_key, const char **mode);
gboolean nm_platform_veth_get_properties (NMPlatform *self, int ifindex, NMPlatformVethProperties *properties);
gboolean nm_platform_tun_get_properties (NMPlatform *self, int ifindex, NMPlatformTunProperties *properties);