Commit 69c6037a authored by Thomas Haller's avatar Thomas Haller

fixup! libnm: refactor caching of D-Bus objects in NMClient

parent 0f089773
Pipeline #80588 failed with stages
in 0 seconds
......@@ -2149,11 +2149,11 @@ _nml_dbus_notify_update_prop_o (NMClient *self,
/*****************************************************************************/
static void
_obj_notify_update_prop (NMClient *self,
NMLDBusObject *dbobj,
NMLDBusObjIfaceData *db_iface_data,
guint dbus_property_idx,
GVariant *value)
_obj_handle_dbus_prop_changes (NMClient *self,
NMLDBusObject *dbobj,
NMLDBusObjIfaceData *db_iface_data,
guint dbus_property_idx,
GVariant *value)
{
const NMLDBusMetaIface *meta_iface = db_iface_data->dbus_iface.meta;
const NMLDBusMetaProperty *meta_property = &meta_iface->dbus_properties[dbus_property_idx];
......@@ -2347,9 +2347,9 @@ notify:
}
static void
_obj_notify_update_iface (NMClient *self,
NMLDBusObject *dbobj,
NMLDBusObjIfaceData *db_iface_data)
_obj_handle_dbus_iface_changes (NMClient *self,
NMLDBusObject *dbobj,
NMLDBusObjIfaceData *db_iface_data)
{
NMLDBusObjPropData *db_prop_data;
gboolean is_self = (G_OBJECT (self) == dbobj->nmobj);
......@@ -2385,11 +2385,11 @@ _obj_notify_update_iface (NMClient *self,
if (is_removed) {
for (i_prop = 0; i_prop < db_iface_data->dbus_iface.meta->n_dbus_properties; i_prop++) {
_obj_notify_update_prop (self,
dbobj,
db_iface_data,
i_prop,
NULL);
_obj_handle_dbus_prop_changes (self,
dbobj,
db_iface_data,
i_prop,
NULL);
}
} else {
while ((db_prop_data = c_list_first_entry (&db_iface_data->changed_prop_lst_head, NMLDBusObjPropData, changed_prop_lst))) {
......@@ -2401,24 +2401,28 @@ _obj_notify_update_iface (NMClient *self,
nm_assert (db_prop_data < &db_iface_data->prop_datas[db_iface_data->dbus_iface.meta->n_dbus_properties]);
nm_assert (db_prop_data->prop_data_value);
/* currently NMLDBusObject forgets about the variant. Theoretically, it could cache
/* Currently NMLDBusObject forgets about the variant. Theoretically, it could cache
* it, but there is no need because we update the property in nmobj (which extracts and
* keeps the property value itself). */
* keeps the property value itself).
*
* Note that we only consume the variant here when we process it.
* That implies that we already created a NMObject for the dbobj
* instance. Unless that happens, we cache the last seen property values. */
prop_data_value = g_steal_pointer (&db_prop_data->prop_data_value);
i_prop = (db_prop_data - &db_iface_data->prop_datas[0]);
_obj_notify_update_prop (self,
dbobj,
db_iface_data,
i_prop,
prop_data_value);
_obj_handle_dbus_prop_changes (self,
dbobj,
db_iface_data,
i_prop,
prop_data_value);
}
}
}
static void
_obj_notify_update (NMClient *self,
NMLDBusObject *dbobj)
_obj_handle_dbus_changes (NMClient *self,
NMLDBusObject *dbobj)
{
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
NMLDBusObjIfaceData *db_iface_data;
......@@ -2427,13 +2431,22 @@ _obj_notify_update (NMClient *self,
_ASSERT_dbobj (dbobj, self);
/* In a first step we only remember all the changes that that a D-Bus message brings
* and queue the object to process them.
*
* Now (step 2) , we look at what changed on D-Bus and react on that.
*
* Note that here we still must not emit any GObject signals. That follows later,
* and again if the object changes, we will just queue that we handle the changes
* later. */
c_list_for_each_entry_safe (db_iface_data, db_iface_data_safe, &dbobj->iface_lst_head, iface_lst) {
if (!db_iface_data->iface_removed)
continue;
c_list_unlink (&db_iface_data->iface_lst);
if ( db_iface_data->dbus_iface_is_wellknown
&& dbobj->nmobj)
_obj_notify_update_iface (self, dbobj, db_iface_data);
_obj_handle_dbus_iface_changes (self, dbobj, db_iface_data);
nml_dbus_obj_iface_data_destroy (db_iface_data);
}
......@@ -2499,7 +2512,7 @@ _obj_notify_update (NMClient *self,
if (c_list_is_empty (&db_iface_data->changed_prop_lst_head))
continue;
if (dbobj->nmobj)
_obj_notify_update_iface (self, dbobj, db_iface_data);
_obj_handle_dbus_iface_changes (self, dbobj, db_iface_data);
}
if ( c_list_is_empty (&dbobj->iface_lst_head)
......@@ -2623,7 +2636,7 @@ _dbus_handle_obj_changed_dbus (NMClient *self,
dbobj_unref = nml_dbus_object_ref (dbobj);
_obj_notify_update (self, dbobj);
_obj_handle_dbus_changes (self, dbobj);
if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED)
continue;
......
......@@ -160,6 +160,9 @@ typedef struct _NMLDBusPropertyO NMLDBusPropertyO;
typedef struct _NMLDBusPropertyAO NMLDBusPropertyAO;
typedef enum {
/* See comments below for NMLDBusMetaIface.interface_prio.
*
* Higher numbers means more important to detect the GObject type. */
NML_DBUS_META_INTERFACE_PRIO_NONE = 0,
NML_DBUS_META_INTERFACE_PRIO_NMCLIENT = 1,
NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE = 2,
......@@ -401,18 +404,67 @@ typedef struct {
struct _NMLDBusMetaIface {
const char *dbus_iface_name;
GType (*get_type_fcn) (void);
/* Usually there is a one-to-one correspondence between the properties
* on D-Bus (dbus_properties) and the GObject properties (obj_properties).
*
* With:
* meta_iface->obj_properties[o_idx] (o_idx < n_obj_properties)
* &meta_iface->dbus_properties[d_idx] (d_idx < n_dbus_properties)
* it follows that
* assert (meta_iface->obj_properties_reverse_idx[o_idx] == d_idx)
* assert (meta_iface->dbus_properties[d_idx].obj_properties_idx == o_idx)
* if (and only if) two properties correspond.
*/
const GParamSpec *const*obj_properties;
const NMLDBusMetaProperty *dbus_properties;
const guint8 *obj_properties_reverse_idx;
guint8 n_dbus_properties;
guint8 n_obj_properties;
/* The offsets in NMLDBusMetaProperty are based on some base struct.
* If this is 0, then the base struct is the GObject pointer itself.
* If this is non-null, then we expect at that location a pointer
* to the offset. */
/* The offsets "prop_struct_offset" in NMLDBusMetaProperty are based on some base
* struct. If "base_struct_offset" is 0, then the base struct is the GObject pointer
* itself.
* If this is non-null, then we expect at that location a pointer to the offset.
* In this case we need to first find the base pointer via
* *((gpointer *) ((char *) nmobj + meta_iface->base_struct_offset)).
*
* This covers NMDeviceBridge._priv vs. NMDevice._priv. In the second case,
* _priv is a pointer that we first need to follow.
*/
guint8 base_struct_offset;
/* We create the appropriate NMObject GType based on the D-Bus interfaces that
* are present. For example, if we see a "org.freedesktop.NetworkManager.Device.Bridge"
* interface, we create a NMDeviceBridge. Basically, if it looks like a certain
* object (based on the D-Bus interface), we assume it is.
*
* Some interfaces are purely additional ("org.freedesktop.NetworkManager.Device.Statistics")
* and don't determine the NMObject type (%NML_DBUS_META_INTERFACE_PRIO_NONE).
*
* Some interfaces are of a parent type ("org.freedesktop.NetworkManager.Device" for
* NMDevice), and don't determine the type either (%NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE).
*
* Some interfaces ("org.freedesktop.NetworkManager.AgentManager") belong to NMClient
* itself. Those have priority %NML_DBUS_META_INTERFACE_PRIO_NMCLIENT.
*
* In most cases, each D-Bus object is expected to have only one D-Bus interface
* to determine the "org.freedesktop.NetworkManager.Device.Bridge". While theoretically
* "/org/freedesktop/NetworkManager/Devices/3" could have interfaces "org.freedesktop.NetworkManager.Device.Bridge"
* and "org.freedesktop.NetworkManager.Device.Bond" at the same time, in practice it doesn't.
* Note that we also assume that once a D-Bus object gets a NMObject, it cannot change.
* NetworkManager's API does not add/remove interfaces after exporting the object the
* first time, so in practice each D-Bus object is expected to have a suitable D-Bus
* interface (and only one, which doesn't change). Those have interface priority
* %NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH.
*
* One exception is "org.freedesktop.NetworkManager.Connection.Active". This can either
* be a NMActiveConnection or a NMVpnConnection. Hence, this profile has priority
* %NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW, and depending on whether there is
* a "org.freedesktop.NetworkManager.VPN.Connection" (with high priority), we create
* one or the other type.
*/
NMLDBusMetaInteracePrio interface_prio:3;
};
......
  • https://desktopqe-jenkins.rhev-ci-vms.eng.rdu2.redhat.com/job/beaker-NetworkManager-gitlab-trigger-code-upstream/889/

    Result: UNSTABLE: Some tests failing

    Passed: 944, Failed: 13

    nmcli_device_wifi_with_two_devices libnm_snapshot_rollback libnm_snapshot_rollback_all_devices libnm_snapshot_rollback_all_devices_with_timeout libnm_snapshot_rollback_unmanaged_timeout libnm_snapshot_rollback_managed_timeout libnm_snapshot_rollback_soft_device_timeout libnm_snapshot_destroy_after_rollback_timeout ifup_ifdown_scripts secret_key_file_permissions libnm_addconnection2_block_autoconnect libnm_update2_block_autoconnect wireguard_activate_connection

Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment