2011-10-14 10:13:49 -04:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
|
|
|
/* NetworkManager -- Network link manager
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
*
|
|
|
|
|
* Copyright 2011 Red Hat, Inc.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-default.h"
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
#include "nm-device-infiniband.h"
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
#include <linux/if_infiniband.h>
|
|
|
|
|
|
|
|
|
|
#include "NetworkManagerUtils.h"
|
|
|
|
|
#include "nm-device-private.h"
|
2016-09-28 19:37:10 +02:00
|
|
|
#include "nm-act-request.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-ip4-config.h"
|
2016-11-21 00:43:52 +01:00
|
|
|
#include "platform/nm-platform.h"
|
2014-09-05 16:07:43 -05:00
|
|
|
#include "nm-device-factory.h"
|
2014-10-21 22:09:52 -04:00
|
|
|
#include "nm-core-internal.h"
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
#define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition"
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
/*****************************************************************************/
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
|
|
|
|
PROP_IS_PARTITION,
|
|
|
|
|
);
|
2014-09-24 17:46:15 -05:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
typedef struct {
|
2014-09-24 17:46:15 -05:00
|
|
|
gboolean is_partition;
|
2016-09-29 13:49:01 +02:00
|
|
|
int parent_ifindex;
|
|
|
|
|
int p_key;
|
2011-10-14 10:13:49 -04:00
|
|
|
} NMDeviceInfinibandPrivate;
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
struct _NMDeviceInfiniband {
|
|
|
|
|
NMDevice parent;
|
|
|
|
|
NMDeviceInfinibandPrivate _priv;
|
|
|
|
|
};
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
struct _NMDeviceInfinibandClass {
|
|
|
|
|
NMDeviceClass parent;
|
2011-10-14 10:13:49 -04:00
|
|
|
};
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE)
|
|
|
|
|
|
|
|
|
|
#define NM_DEVICE_INFINIBAND_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceInfiniband, NM_IS_DEVICE_INFINIBAND)
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2015-04-17 15:15:38 +02:00
|
|
|
static NMDeviceCapabilities
|
2016-09-29 13:49:01 +02:00
|
|
|
get_generic_capabilities (NMDevice *device)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
2014-09-24 17:46:15 -05:00
|
|
|
guint32 caps = NM_DEVICE_CAP_CARRIER_DETECT;
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
if (NM_DEVICE_INFINIBAND_GET_PRIVATE ((NMDeviceInfiniband *) device)->is_partition)
|
2014-09-24 17:46:15 -05:00
|
|
|
caps |= NM_DEVICE_CAP_IS_SOFTWARE;
|
|
|
|
|
|
|
|
|
|
return caps;
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
2011-11-14 14:52:40 -05:00
|
|
|
static NMActStageReturn
|
2017-04-18 12:09:02 +02:00
|
|
|
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
2011-11-14 14:52:40 -05:00
|
|
|
{
|
2016-12-08 15:05:15 +01:00
|
|
|
nm_auto_close int dirfd = -1;
|
2013-09-11 09:19:21 -05:00
|
|
|
NMActStageReturn ret;
|
2011-11-14 14:52:40 -05:00
|
|
|
NMSettingInfiniband *s_infiniband;
|
2016-12-08 15:05:15 +01:00
|
|
|
char ifname_verified[IFNAMSIZ];
|
2011-11-14 14:52:40 -05:00
|
|
|
const char *transport_mode;
|
2016-01-05 14:43:57 +01:00
|
|
|
gboolean ok, no_firmware = FALSE;
|
2011-11-14 14:52:40 -05:00
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
ret = NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->act_stage1_prepare (device, out_failure_reason);
|
2013-09-11 09:19:21 -05:00
|
|
|
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
s_infiniband = (NMSettingInfiniband *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_INFINIBAND);
|
2017-02-22 17:04:00 +01:00
|
|
|
g_return_val_if_fail (s_infiniband, NM_ACT_STAGE_RETURN_FAILURE);
|
2011-11-14 14:52:40 -05:00
|
|
|
|
|
|
|
|
transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband);
|
|
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
dirfd = nm_platform_sysctl_open_netdir (nm_device_get_platform (device), nm_device_get_ifindex (device), ifname_verified);
|
2016-12-08 15:05:15 +01:00
|
|
|
if (dirfd < 0) {
|
2011-11-14 14:52:40 -05:00
|
|
|
if (!strcmp (transport_mode, "datagram"))
|
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
else {
|
2017-02-22 17:04:00 +01:00
|
|
|
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_INFINIBAND_MODE);
|
2011-11-14 14:52:40 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-05 14:43:57 +01:00
|
|
|
/* With some drivers the interface must be down to set transport mode */
|
2017-04-18 12:09:02 +02:00
|
|
|
nm_device_take_down (device, TRUE);
|
|
|
|
|
ok = nm_platform_sysctl_set (nm_device_get_platform (device), NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname_verified, "mode"), transport_mode);
|
|
|
|
|
nm_device_bring_up (device, TRUE, &no_firmware);
|
2011-11-14 14:52:40 -05:00
|
|
|
|
|
|
|
|
if (!ok) {
|
2017-02-22 17:04:00 +01:00
|
|
|
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
2011-11-14 14:52:40 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-11 09:19:21 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2011-11-14 14:52:40 -05:00
|
|
|
}
|
|
|
|
|
|
2017-01-14 17:04:17 +01:00
|
|
|
static guint32
|
|
|
|
|
get_configured_mtu (NMDevice *device, gboolean *out_is_user_config)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
2018-06-12 14:51:28 +02:00
|
|
|
return nm_device_get_configured_mtu_from_connection (device,
|
|
|
|
|
NM_TYPE_SETTING_INFINIBAND,
|
|
|
|
|
out_is_user_config);
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2014-05-30 13:44:53 -05:00
|
|
|
check_connection_compatible (NMDevice *device, NMConnection *connection)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
|
2014-05-30 13:44:53 -05:00
|
|
|
if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection))
|
2013-03-07 07:44:36 -05:00
|
|
|
return FALSE;
|
|
|
|
|
|
2014-05-30 13:44:53 -05:00
|
|
|
if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME))
|
2011-10-14 10:13:49 -04:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
2014-05-30 13:44:53 -05:00
|
|
|
if (!s_infiniband)
|
2011-10-14 10:13:49 -04:00
|
|
|
return FALSE;
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
if (nm_device_is_real (device)) {
|
2014-07-30 10:57:45 -04:00
|
|
|
const char *mac;
|
2016-06-15 14:11:16 +02:00
|
|
|
const char *hw_addr;
|
2014-07-30 10:57:45 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
2016-06-15 14:11:16 +02:00
|
|
|
if (mac) {
|
2016-10-13 18:52:12 +02:00
|
|
|
hw_addr = nm_device_get_permanent_hw_address (device);
|
2016-06-15 14:11:16 +02:00
|
|
|
if ( !hw_addr
|
|
|
|
|
|| !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1))
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2012-09-27 12:12:15 -04:00
|
|
|
complete_connection (NMDevice *device,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *specific_object,
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
NMConnection *const*existing_connections,
|
2012-09-27 12:12:15 -04:00
|
|
|
GError **error)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
2014-07-30 10:57:45 -04:00
|
|
|
const char *setting_mac;
|
2014-06-21 12:44:56 -04:00
|
|
|
const char *hw_address;
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
nm_utils_complete_generic (nm_device_get_platform (device),
|
2016-03-08 13:57:20 +01:00
|
|
|
connection,
|
2011-10-14 10:13:49 -04:00
|
|
|
NM_SETTING_INFINIBAND_SETTING_NAME,
|
|
|
|
|
existing_connections,
|
|
|
|
|
NULL,
|
2014-08-25 16:21:59 +02:00
|
|
|
_("InfiniBand connection"),
|
2014-08-05 17:11:57 -04:00
|
|
|
NULL,
|
2011-10-14 10:13:49 -04:00
|
|
|
TRUE);
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
|
|
|
|
if (!s_infiniband) {
|
|
|
|
|
s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new ();
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_infiniband));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
2016-10-13 18:52:12 +02:00
|
|
|
hw_address = nm_device_get_permanent_hw_address (device);
|
2011-10-14 10:13:49 -04:00
|
|
|
if (setting_mac) {
|
|
|
|
|
/* Make sure the setting MAC (if any) matches the device's MAC */
|
2014-07-30 10:57:45 -04:00
|
|
|
if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) {
|
2011-10-14 10:13:49 -04:00
|
|
|
g_set_error_literal (error,
|
libnm-core: merge NMSetting*Error into NMConnectionError
Each setting type was defining its own error type, but most of them
had exactly the same three errors ("unknown", "missing property", and
"invalid property"), and none of the other values was of much use
programmatically anyway.
So, this commit merges NMSettingError, NMSettingAdslError, etc, all
into NMConnectionError. (The reason for merging into NMConnectionError
rather than NMSettingError is that we also already have
"NMSettingsError", for errors related to the settings service, so
"NMConnectionError" is a less-confusable name for settings/connection
errors than "NMSettingError".)
Also, make sure that all of the affected error messages are localized,
and (where appropriate) prefix them with the relevant property name.
Renamed error codes:
NM_SETTING_ERROR_PROPERTY_NOT_FOUND -> NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND
NM_SETTING_ERROR_PROPERTY_NOT_SECRET -> NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET
Remapped error codes:
NM_SETTING_*_ERROR_MISSING_PROPERTY -> NM_CONNECTION_ERROR_MISSING_PROPERTY
NM_SETTING_*_ERROR_INVALID_PROPERTY -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_BLUETOOTH_ERROR_TYPE_SETTING_NOT_FOUND -> NM_CONNECTION_ERROR_INVALID_SETTING
NM_SETTING_BOND_ERROR_INVALID_OPTION -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_BOND_ERROR_MISSING_OPTION -> NM_CONNECTION_ERROR_MISSING_PROPERTY
NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND -> NM_CONNECTION_ERROR_MISSING_SETTING
NM_SETTING_CONNECTION_ERROR_SLAVE_SETTING_NOT_FOUND -> NM_CONNECTION_ERROR_MISSING_SETTING
NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_VLAN_ERROR_INVALID_PARENT -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING -> NM_CONNECTION_ERROR_MISSING_SETTING
NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME -> NM_CONNECTION_ERROR_MISSING_PROPERTY
NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP -> NM_CONNECTION_ERROR_INVALID_PROPERTY
NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND -> NM_CONNECTION_ERROR_MISSING_PROPERTY
Dropped error codes (were previously defined but unused):
NM_SETTING_CDMA_ERROR_MISSING_SERIAL_SETTING
NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED
NM_SETTING_GSM_ERROR_MISSING_SERIAL_SETTING
NM_SETTING_PPP_ERROR_REQUIRE_MPPE_NOT_ALLOWED
NM_SETTING_PPPOE_ERROR_MISSING_PPP_SETTING
NM_SETTING_SERIAL_ERROR_MISSING_PPP_SETTING
NM_SETTING_WIRELESS_ERROR_MISSING_SECURITY_SETTING
2014-10-20 13:52:23 -04:00
|
|
|
NM_CONNECTION_ERROR,
|
|
|
|
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
|
|
|
|
_("connection does not match device"));
|
|
|
|
|
g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS);
|
2011-10-14 10:13:49 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Lock the connection to this device by default */
|
2014-07-30 10:57:45 -04:00
|
|
|
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, hw_address, NULL);
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
2012-03-16 13:48:11 -04:00
|
|
|
if (!nm_setting_infiniband_get_transport_mode (s_infiniband))
|
2012-03-16 15:20:58 -05:00
|
|
|
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL);
|
2012-03-16 13:48:11 -04:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-07 16:07:28 -06:00
|
|
|
static void
|
|
|
|
|
update_connection (NMDevice *device, NMConnection *connection)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
2013-11-07 16:07:28 -06:00
|
|
|
NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection);
|
2016-10-13 18:52:12 +02:00
|
|
|
const char *mac = nm_device_get_permanent_hw_address (device);
|
2013-11-07 16:07:28 -06:00
|
|
|
const char *transport_mode = "datagram";
|
2014-10-06 09:37:34 -05:00
|
|
|
int ifindex;
|
2013-11-07 16:07:28 -06:00
|
|
|
|
|
|
|
|
if (!s_infiniband) {
|
|
|
|
|
s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new ();
|
|
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_infiniband);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
if (mac && !nm_utils_hwaddr_matches (mac, -1, NULL, INFINIBAND_ALEN))
|
|
|
|
|
g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL);
|
2013-11-07 16:07:28 -06:00
|
|
|
|
2014-10-06 09:37:34 -05:00
|
|
|
ifindex = nm_device_get_ifindex (device);
|
|
|
|
|
if (ifindex > 0) {
|
2017-04-18 12:09:02 +02:00
|
|
|
if (!nm_platform_link_infiniband_get_properties (nm_device_get_platform (device), ifindex, NULL, NULL, &transport_mode))
|
2013-11-07 16:07:28 -06:00
|
|
|
transport_mode = "datagram";
|
|
|
|
|
}
|
|
|
|
|
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL);
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
static gboolean
|
|
|
|
|
create_and_realize (NMDevice *device,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice *parent,
|
2015-12-09 15:13:57 +01:00
|
|
|
const NMPlatformLink **out_plink,
|
2014-09-05 08:50:02 -05:00
|
|
|
GError **error)
|
|
|
|
|
{
|
2016-09-29 13:49:01 +02:00
|
|
|
NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE ((NMDeviceInfiniband *) device);
|
2014-09-05 08:50:02 -05:00
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
NMPlatformError plerr;
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
2016-04-19 11:59:36 +02:00
|
|
|
g_assert (s_infiniband);
|
2014-09-05 08:50:02 -05:00
|
|
|
|
|
|
|
|
/* Can only create partitions at this time */
|
2016-04-20 09:16:41 +02:00
|
|
|
priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband);
|
|
|
|
|
if (priv->p_key < 0) {
|
2016-04-19 13:17:18 +02:00
|
|
|
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
2014-09-05 08:50:02 -05:00
|
|
|
"only InfiniBand partitions can be created");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
device: check for a parent device
The device creation can be attempted if the name can be determined. It
alone is doesn't mean that there's a parent device -- the name could
just have been hardcoded in the connection.
NetworkManager[21519]: nm_device_get_ifindex: assertion 'NM_IS_DEVICE (self)' failed
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x5555557fb2e5 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd3d0) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4ec88c3 in g_logv (log_domain=0x5555557fb2e5 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd3d0) at gmessages.c:1046
#1 0x00007ffff4ec8a3f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1079
#2 0x00005555555d2090 in nm_device_get_ifindex (self=0x0) at devices/nm-device.c:562
#3 0x00005555555ef77a in nm_device_supports_vlans (self=0x0) at devices/nm-device.c:9865
#4 0x00005555555bf2f9 in create_and_realize (device=0x555555c549b0 [NMDeviceVlan], connection=0x555555b451e0, parent=0x0, out_plink=0x7fffffffd5f8, error=0x7fffffffd700) at devices/nm-device-vlan.c:225
#5 0x00005555555d5757 in nm_device_create_and_realize (self=0x555555c549b0 [NMDeviceVlan], connection=0x555555b451e0, parent=0x0, error=0x7fffffffd700) at devices/nm-device.c:1783
#6 0x0000555555688601 in system_create_virtual_device (self=0x555555af51c0 [NMManager], connection=0x555555b451e0) at nm-manager.c:1120
#7 0x000055555568894e in connection_changed (settings=0x555555ae8220 [NMSettings], connection=0x555555b451e0, manager=0x555555af51c0 [NMManager]) at nm-manager.c:1172
#8 0x0000555555693448 in nm_manager_start (self=0x555555af51c0 [NMManager], error=0x7fffffffda30) at nm-manager.c:4466
#9 0x00005555555d166f in main (argc=1, argv=0x7fffffffdba8) at main.c:454
(gdb)
Fixes: 332994f1b19ded7cb343ef573443916bab05aaec
2016-04-19 12:02:02 +02:00
|
|
|
if (!parent) {
|
2017-09-14 09:26:51 +02:00
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES,
|
device: check for a parent device
The device creation can be attempted if the name can be determined. It
alone is doesn't mean that there's a parent device -- the name could
just have been hardcoded in the connection.
NetworkManager[21519]: nm_device_get_ifindex: assertion 'NM_IS_DEVICE (self)' failed
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x5555557fb2e5 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd3d0) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4ec88c3 in g_logv (log_domain=0x5555557fb2e5 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd3d0) at gmessages.c:1046
#1 0x00007ffff4ec8a3f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1079
#2 0x00005555555d2090 in nm_device_get_ifindex (self=0x0) at devices/nm-device.c:562
#3 0x00005555555ef77a in nm_device_supports_vlans (self=0x0) at devices/nm-device.c:9865
#4 0x00005555555bf2f9 in create_and_realize (device=0x555555c549b0 [NMDeviceVlan], connection=0x555555b451e0, parent=0x0, out_plink=0x7fffffffd5f8, error=0x7fffffffd700) at devices/nm-device-vlan.c:225
#5 0x00005555555d5757 in nm_device_create_and_realize (self=0x555555c549b0 [NMDeviceVlan], connection=0x555555b451e0, parent=0x0, error=0x7fffffffd700) at devices/nm-device.c:1783
#6 0x0000555555688601 in system_create_virtual_device (self=0x555555af51c0 [NMManager], connection=0x555555b451e0) at nm-manager.c:1120
#7 0x000055555568894e in connection_changed (settings=0x555555ae8220 [NMSettings], connection=0x555555b451e0, manager=0x555555af51c0 [NMManager]) at nm-manager.c:1172
#8 0x0000555555693448 in nm_manager_start (self=0x555555af51c0 [NMManager], error=0x7fffffffda30) at nm-manager.c:4466
#9 0x00005555555d166f in main (argc=1, argv=0x7fffffffdba8) at main.c:454
(gdb)
Fixes: 332994f1b19ded7cb343ef573443916bab05aaec
2016-04-19 12:02:02 +02:00
|
|
|
"InfiniBand partitions can not be created without a parent interface");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-19 11:59:36 +02:00
|
|
|
if (!NM_IS_DEVICE_INFINIBAND (parent)) {
|
2017-09-14 09:26:51 +02:00
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES,
|
2016-04-19 11:59:36 +02:00
|
|
|
"Parent interface %s must be an InfiniBand interface",
|
|
|
|
|
nm_device_get_iface (parent));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 09:16:41 +02:00
|
|
|
priv->parent_ifindex = nm_device_get_ifindex (parent);
|
|
|
|
|
if (priv->parent_ifindex <= 0) {
|
2017-09-14 09:26:51 +02:00
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES,
|
2014-09-05 08:50:02 -05:00
|
|
|
"failed to get InfiniBand parent %s ifindex",
|
|
|
|
|
nm_device_get_iface (parent));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
plerr = nm_platform_link_infiniband_add (nm_device_get_platform (device), priv->parent_ifindex, priv->p_key, out_plink);
|
2016-01-25 13:03:51 +01:00
|
|
|
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
|
2014-09-05 08:50:02 -05:00
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
|
|
|
|
|
"Failed to create InfiniBand P_Key interface '%s' for '%s': %s",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
nm_connection_get_id (connection),
|
2017-08-21 19:18:45 +02:00
|
|
|
nm_platform_error_to_string_a (plerr));
|
2014-09-05 08:50:02 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 09:16:41 +02:00
|
|
|
priv->is_partition = TRUE;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
unrealize (NMDevice *device, GError **error)
|
|
|
|
|
{
|
2016-09-29 13:49:01 +02:00
|
|
|
NMDeviceInfinibandPrivate *priv;
|
2016-04-20 09:16:41 +02:00
|
|
|
NMPlatformError plerr;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE);
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
priv = NM_DEVICE_INFINIBAND_GET_PRIVATE ((NMDeviceInfiniband *) device);
|
|
|
|
|
|
2016-04-20 09:16:41 +02:00
|
|
|
if (priv->p_key < 0) {
|
|
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
|
|
|
|
"Only InfiniBand partitions can be removed");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
plerr = nm_platform_link_infiniband_delete (nm_device_get_platform (device), priv->parent_ifindex, priv->p_key);
|
2016-04-20 09:16:41 +02:00
|
|
|
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),
|
2017-08-21 19:18:45 +02:00
|
|
|
nm_platform_error_to_string_a (plerr));
|
2016-04-20 09:16:41 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-05 08:50:02 -05:00
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
static void
|
|
|
|
|
get_property (GObject *object, guint prop_id,
|
|
|
|
|
GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
switch (prop_id) {
|
2014-09-24 17:46:15 -05:00
|
|
|
case PROP_IS_PARTITION:
|
2016-09-29 13:49:01 +02:00
|
|
|
g_value_set_boolean (value, NM_DEVICE_INFINIBAND_GET_PRIVATE ((NMDeviceInfiniband *) object)->is_partition);
|
2014-09-24 17:46:15 -05:00
|
|
|
break;
|
2011-10-14 10:13:49 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_property (GObject *object, guint prop_id,
|
2016-09-29 13:49:01 +02:00
|
|
|
const GValue *value, GParamSpec *pspec)
|
2011-10-14 10:13:49 -04:00
|
|
|
{
|
|
|
|
|
switch (prop_id) {
|
2014-09-24 17:46:15 -05:00
|
|
|
case PROP_IS_PARTITION:
|
2016-09-29 13:49:01 +02:00
|
|
|
NM_DEVICE_INFINIBAND_GET_PRIVATE ((NMDeviceInfiniband *) object)->is_partition = g_value_get_boolean (value);
|
2014-09-24 17:46:15 -05:00
|
|
|
break;
|
2011-10-14 10:13:49 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_device_infiniband_init (NMDeviceInfiniband * self)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
static const NMDBusInterfaceInfoExtended interface_info_device_infiniband = {
|
|
|
|
|
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT (
|
|
|
|
|
NM_DBUS_INTERFACE_DEVICE_INFINIBAND,
|
|
|
|
|
.signals = NM_DEFINE_GDBUS_SIGNAL_INFOS (
|
|
|
|
|
&nm_signal_info_property_changed_legacy,
|
|
|
|
|
),
|
|
|
|
|
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS (
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
.legacy_property_changed = TRUE,
|
|
|
|
|
};
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
static void
|
|
|
|
|
nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass);
|
2011-10-14 10:13:49 -04:00
|
|
|
NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
|
|
|
|
|
|
2014-10-09 12:42:29 -05:00
|
|
|
NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_INFINIBAND_SETTING_NAME, NM_LINK_TYPE_INFINIBAND)
|
|
|
|
|
|
2011-10-14 10:13:49 -04:00
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_infiniband);
|
|
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
parent_class->create_and_realize = create_and_realize;
|
2016-04-20 09:16:41 +02:00
|
|
|
parent_class->unrealize = unrealize;
|
2012-09-27 12:12:15 -04:00
|
|
|
parent_class->get_generic_capabilities = get_generic_capabilities;
|
|
|
|
|
parent_class->check_connection_compatible = check_connection_compatible;
|
|
|
|
|
parent_class->complete_connection = complete_connection;
|
2013-11-07 16:07:28 -06:00
|
|
|
parent_class->update_connection = update_connection;
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2012-09-27 12:12:15 -04:00
|
|
|
parent_class->act_stage1_prepare = act_stage1_prepare;
|
2017-01-14 17:04:17 +01:00
|
|
|
parent_class->get_configured_mtu = get_configured_mtu;
|
2011-10-14 10:13:49 -04:00
|
|
|
|
2016-09-29 13:49:01 +02:00
|
|
|
obj_properties[PROP_IS_PARTITION] =
|
|
|
|
|
g_param_spec_boolean (NM_DEVICE_INFINIBAND_IS_PARTITION, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
2011-10-14 10:13:49 -04:00
|
|
|
}
|
2014-09-05 16:07:43 -05:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-05 16:07:43 -05:00
|
|
|
|
2016-10-07 17:00:59 +02:00
|
|
|
#define NM_TYPE_INFINIBAND_DEVICE_FACTORY (nm_infiniband_device_factory_get_type ())
|
|
|
|
|
#define NM_INFINIBAND_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INFINIBAND_DEVICE_FACTORY, NMInfinibandDeviceFactory))
|
2014-09-05 16:07:43 -05:00
|
|
|
|
|
|
|
|
static NMDevice *
|
2014-09-05 08:50:02 -05:00
|
|
|
create_device (NMDeviceFactory *factory,
|
|
|
|
|
const char *iface,
|
2016-01-10 15:13:20 +01:00
|
|
|
const NMPlatformLink *plink,
|
2014-09-05 08:50:02 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean *out_ignore)
|
2014-09-05 16:07:43 -05:00
|
|
|
{
|
2014-09-05 08:50:02 -05:00
|
|
|
gboolean is_partition = FALSE;
|
|
|
|
|
|
|
|
|
|
if (plink)
|
2015-08-17 17:48:37 +02:00
|
|
|
is_partition = (plink->parent > 0 || plink->parent == NM_PLATFORM_LINK_OTHER_NETNS);
|
2014-09-05 08:50:02 -05:00
|
|
|
else if (connection) {
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
|
|
|
|
g_return_val_if_fail (s_infiniband, NULL);
|
|
|
|
|
is_partition = !!nm_setting_infiniband_get_parent (s_infiniband)
|
|
|
|
|
|| ( nm_setting_infiniband_get_p_key (s_infiniband) >= 0
|
|
|
|
|
&& nm_setting_infiniband_get_mac_address (s_infiniband));
|
2014-09-05 16:07:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND,
|
|
|
|
|
NM_DEVICE_IFACE, iface,
|
|
|
|
|
NM_DEVICE_TYPE_DESC, "InfiniBand",
|
|
|
|
|
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND,
|
2015-12-08 14:51:12 +01:00
|
|
|
NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_INFINIBAND,
|
2018-01-23 12:24:29 +01:00
|
|
|
/* NOTE: Partition should probably be a different link type! */
|
2014-09-05 08:50:02 -05:00
|
|
|
NM_DEVICE_INFINIBAND_IS_PARTITION, is_partition,
|
2014-09-05 16:07:43 -05:00
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
static const char *
|
|
|
|
|
get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME), NULL);
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
|
|
|
|
g_assert (s_infiniband);
|
|
|
|
|
|
|
|
|
|
return nm_setting_infiniband_get_parent (s_infiniband);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2016-02-17 15:11:02 +01:00
|
|
|
get_connection_iface (NMDeviceFactory *factory,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *parent_iface)
|
2014-09-18 17:50:47 -05:00
|
|
|
{
|
|
|
|
|
NMSettingInfiniband *s_infiniband;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME), NULL);
|
|
|
|
|
|
|
|
|
|
s_infiniband = nm_connection_get_setting_infiniband (connection);
|
|
|
|
|
g_assert (s_infiniband);
|
|
|
|
|
|
2015-07-02 22:58:12 +02:00
|
|
|
if (!parent_iface)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
g_return_val_if_fail (g_strcmp0 (parent_iface, nm_setting_infiniband_get_parent (s_infiniband)) == 0, NULL);
|
|
|
|
|
|
|
|
|
|
return g_strdup (nm_setting_infiniband_get_virtual_interface_name (s_infiniband));
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
NM_DEVICE_FACTORY_DEFINE_INTERNAL (INFINIBAND, Infiniband, infiniband,
|
|
|
|
|
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_INFINIBAND)
|
|
|
|
|
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_INFINIBAND_SETTING_NAME),
|
2016-10-07 16:05:43 +02:00
|
|
|
factory_class->create_device = create_device;
|
|
|
|
|
factory_class->get_connection_parent = get_connection_parent;
|
|
|
|
|
factory_class->get_connection_iface = get_connection_iface;
|
|
|
|
|
);
|