core: introduce device::ports property

The property `PROP_PORTS` should be of type g_param_spec_variant() with
variant 'ao'. This way the variant can be cached.

The deprecated property 'device::slaves' in
'src/core/devices/nm-device.c' must have the same getter-implementation,
returning the same GVariant instance.

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
This commit is contained in:
Fernando Fernandez Mancera 2021-10-06 16:09:28 +02:00
parent 5a687da0a4
commit 9d2ed74e74
8 changed files with 88 additions and 45 deletions

View file

@ -30,8 +30,9 @@ n
<!-- <!--
Slaves: Slaves:
Array of object paths representing devices which are currently enslaved to DEPRECATED. Use the "Ports" property in
this device. "org.freedesktop.NetworkManager.Device" instead which exists since
version NetworkManager 1.34.0.
--> -->
<property name="Slaves" type="ao" access="read"/> <property name="Slaves" type="ao" access="read"/>

View file

@ -30,8 +30,10 @@ n
<!-- <!--
Slaves: Slaves:
Array of object paths representing devices which are currently enslaved to DEPRECATED. Use the "Ports" property in
this device. "org.freedesktop.NetworkManager.Device" instead which exists since
version NetworkManager 1.34.0.
--> -->
<property name="Slaves" type="ao" access="read"/> <property name="Slaves" type="ao" access="read"/>

View file

@ -10,8 +10,9 @@
<!-- <!--
Slaves: Slaves:
Array of object paths representing ports which are currently enslaved to DEPRECATED. Use the "Ports" property in
this bridge. "org.freedesktop.NetworkManager.Device" instead which exists since
version NetworkManager 1.34.0.
Since: 1.14 Since: 1.14
--> -->

View file

@ -10,8 +10,9 @@
<!-- <!--
Slaves: Slaves:
Array of object paths representing interfaces which are currently enslaved to DEPRECATED. Use the "Ports" property in
this port. "org.freedesktop.NetworkManager.Device" instead which exists since
version NetworkManager 1.34.0.
Since: 1.14 Since: 1.14
--> -->

View file

@ -30,8 +30,10 @@ n
<!-- <!--
Slaves: Slaves:
Array of object paths representing devices which are currently enslaved to DEPRECATED. Use the "Ports" property in
this device. "org.freedesktop.NetworkManager.Device" instead which exists since
version NetworkManager 1.34.0.
--> -->
<property name="Slaves" type="ao" access="read"/> <property name="Slaves" type="ao" access="read"/>

View file

@ -310,6 +310,19 @@
--> -->
<property name="HwAddress" type="s" access="read"/> <property name="HwAddress" type="s" access="read"/>
<!--
Ports:
The port devices of the controller device.
Array of object paths representing devices which are currently set as
port of this device. This replaces the 'Slaves' properties on the
device-specific D-Bus interfaces.
Since: 1.34
-->
<property name="Ports" type="ao" access="read"/>
<!-- <!--
Reapply: Reapply:
@connection: The optional connection settings that will be reapplied on the device. If empty, the currently active settings-connection will be used. The connection cannot arbitrarily differ from the current applied-connection otherwise the call will fail. Only certain changes are supported, like adding or removing IP addresses. @connection: The optional connection settings that will be reapplied on the device. If empty, the currently active settings-connection will be used. The connection cannot arbitrarily differ from the current applied-connection otherwise the call will fail. Only certain changes are supported, like adding or removing IP addresses.

View file

@ -290,7 +290,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice,
PROP_STATISTICS_RX_BYTES, PROP_STATISTICS_RX_BYTES,
PROP_IP4_CONNECTIVITY, PROP_IP4_CONNECTIVITY,
PROP_IP6_CONNECTIVITY, PROP_IP6_CONNECTIVITY,
PROP_INTERFACE_FLAGS, ); PROP_INTERFACE_FLAGS,
PROP_PORTS, );
typedef struct _NMDevicePrivate { typedef struct _NMDevicePrivate {
bool in_state_changed; bool in_state_changed;
@ -710,6 +711,8 @@ typedef struct _NMDevicePrivate {
bool mtu_force_set_done : 1; bool mtu_force_set_done : 1;
NMOptionBool promisc_reset; NMOptionBool promisc_reset;
GVariant *ports_variant; /* Array of port devices D-Bus path */
} NMDevicePrivate; } NMDevicePrivate;
G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
@ -6795,8 +6798,8 @@ nm_device_slave_notify_enslave(NMDevice *self, gboolean success)
priv->is_enslaved = TRUE; priv->is_enslaved = TRUE;
_notify(self, PROP_MASTER); nm_clear_pointer(&priv->ports_variant, g_variant_unref);
_notify(priv->master, PROP_SLAVES); nm_gobject_notify_together(self, PROP_MASTER, PROP_PORTS, PROP_SLAVES);
} else if (activating) { } else if (activating) {
_LOGW(LOGD_DEVICE, _LOGW(LOGD_DEVICE,
"Activation: connection '%s' could not be enslaved", "Activation: connection '%s' could not be enslaved",
@ -6860,8 +6863,8 @@ nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason)
if (priv->is_enslaved) { if (priv->is_enslaved) {
priv->is_enslaved = FALSE; priv->is_enslaved = FALSE;
_notify(self, PROP_MASTER); nm_clear_pointer(&priv->ports_variant, g_variant_unref);
_notify(priv->master, PROP_SLAVES); nm_gobject_notify_together(self, PROP_MASTER, PROP_PORTS, PROP_SLAVES);
} }
} }
@ -18031,6 +18034,37 @@ _activation_func_to_string(ActivationHandleFunc func)
g_return_val_if_reached("unknown"); g_return_val_if_reached("unknown");
} }
static GVariant *
_device_get_ports_variant(NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(device);
SlaveInfo * info;
GVariantBuilder builder;
gboolean any = FALSE;
if (priv->ports_variant)
return priv->ports_variant;
c_list_for_each_entry (info, &priv->slaves, lst_slave) {
const char *path;
if (!NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved)
continue;
path = nm_dbus_object_get_path(NM_DBUS_OBJECT(info->slave));
if (!path)
continue;
if (!any) {
any = TRUE;
g_variant_builder_init(&builder, G_VARIANT_TYPE("ao"));
}
g_variant_builder_add(&builder, "o", path);
}
priv->ports_variant = any ? g_variant_ref_sink(g_variant_builder_end(&builder))
: g_variant_ref(nm_g_variant_singleton_ao());
return priv->ports_variant;
}
/*****************************************************************************/ /*****************************************************************************/
static void static void
@ -18197,29 +18231,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
g_value_set_boolean(value, nm_device_is_real(self)); g_value_set_boolean(value, nm_device_is_real(self));
break; break;
case PROP_SLAVES: case PROP_SLAVES:
{ case PROP_PORTS:
CList *slave_iter; g_value_set_variant(value, _device_get_ports_variant(self));
char **slave_list;
gsize i, n;
n = c_list_length(&priv->slaves);
slave_list = g_new(char *, n + 1);
i = 0;
c_list_for_each (slave_iter, &priv->slaves) {
SlaveInfo * info = c_list_entry(slave_iter, SlaveInfo, lst_slave);
const char *path;
if (!NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved)
continue;
path = nm_dbus_object_get_path(NM_DBUS_OBJECT(info->slave));
if (path)
slave_list[i++] = g_strdup(path);
}
nm_assert(i <= n);
slave_list[i] = NULL;
g_value_take_boxed(value, slave_list);
break; break;
}
case PROP_STATISTICS_REFRESH_RATE_MS: case PROP_STATISTICS_REFRESH_RATE_MS:
g_value_set_uint(value, priv->stats.refresh_rate_ms); g_value_set_uint(value, priv->stats.refresh_rate_ms);
break; break;
@ -18601,6 +18615,8 @@ finalize(GObject *object)
nm_dbus_track_obj_path_deinit(&priv->parent_device); nm_dbus_track_obj_path_deinit(&priv->parent_device);
nm_dbus_track_obj_path_deinit(&priv->act_request); nm_dbus_track_obj_path_deinit(&priv->act_request);
nm_g_variant_unref(priv->ports_variant);
G_OBJECT_CLASS(nm_device_parent_class)->finalize(object); G_OBJECT_CLASS(nm_device_parent_class)->finalize(object);
/* for testing, NMDeviceTest does not invoke NMDevice::constructed, /* for testing, NMDeviceTest does not invoke NMDevice::constructed,
@ -18719,9 +18735,8 @@ static const NMDBusInterfaceInfoExtended interface_info_device = {
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InterfaceFlags", NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InterfaceFlags",
"u", "u",
NM_DEVICE_INTERFACE_FLAGS), NM_DEVICE_INTERFACE_FLAGS),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS),
"s", NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ports", "ao", NM_DEVICE_PORTS), ), ),
NM_DEVICE_HW_ADDRESS), ), ),
}; };
static const NMDBusInterfaceInfoExtended interface_info_device_statistics = { static const NMDBusInterfaceInfoExtended interface_info_device_statistics = {
@ -19016,10 +19031,17 @@ nm_device_class_init(NMDeviceClass *klass)
"", "",
FALSE, FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_SLAVES, obj_properties[PROP_SLAVES] = g_param_spec_variant(NM_DEVICE_SLAVES,
"", "",
"", "",
G_TYPE_STRV, G_VARIANT_TYPE("ao"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_PORTS] = g_param_spec_variant(NM_DEVICE_PORTS,
"",
"",
G_VARIANT_TYPE("ao"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_STATISTICS_REFRESH_RATE_MS] = obj_properties[PROP_STATISTICS_REFRESH_RATE_MS] =

View file

@ -45,6 +45,7 @@
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
#define NM_DEVICE_MTU "mtu" #define NM_DEVICE_MTU "mtu"
#define NM_DEVICE_HW_ADDRESS "hw-address" #define NM_DEVICE_HW_ADDRESS "hw-address"
#define NM_DEVICE_PORTS "ports"
/* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet /* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet
* and NMDeviceWifi. */ * and NMDeviceWifi. */