about summary refs log tree commit diff
path: root/debian/patches/gitlab_connection_ready.patch
blob: 7c25058aa2c66b06570056624cf9bebdcfa8dbe2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

From 1043189ef6bd12475304bbe87f4f8daaf67402ec Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 31 Jan 2020 00:54:46 +0100
Subject: [PATCH 2/2] libnm: hide NMActiveConnection until NMRemoteConnection
 is ready

Generally, libnm's NMClient cache only wants to expose NMObjects that
are fully initalized. Most objects don't require anything special,
except NMRemoteConnection waits for the GetSettings() call to complete.

NMObjects reference each other. For example, NMActiveConnection
references NMDevice and NMRemoteConnection. There is a desire that an
object is only ready, if the objects that it references are ready too.
In practice that is not done, because usually every objects references
other objects, that means all objects would be declared as non-ready
until they are all ready at the same time. Only NMRemoteConnection
implements is_ready() function. All other objects are declared ready
as they appear. This is also done this way, to cope with cycles where
objects reference each other. In practice, such cycles should not be
exposed by NetworkManager. However, libnm should be robust against that.

This has the undesired effect that when you call AddAndActivate(), then
the NMActiveConnection might already be ready while its
NMRemoteConnection isn't. That means, ac.get_connection() will
initially return NULL, until the remote connection becomes ready.
Also add a special handling that NMActiveConnection waits for their
NMRemoteConnection to be ready, before being ready itself.
---
 libnm/nm-active-connection.c | 29 +++++++++++++++++++++++++++++
 libnm/nm-client.c            |  8 ++++++++
 libnm/nm-libnm-utils.h       |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c
index aa8504e61d..ade2edbe73 100644
--- a/libnm/nm-active-connection.c
+++ b/libnm/nm-active-connection.c
@@ -425,6 +425,33 @@ _nm_active_connection_state_changed_commit (NMActiveConnection *self,
 	                                        _notify_event_state_changed,
 	                                        g_object_ref (self));
 }
+/*****************************************************************************/
+
+static gboolean
+is_ready (NMObject *nmobj)
+{
+	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (nmobj);
+
+	/* Usually, we don't want to expose our NMObject instances until they are fully initialized.
+	 * For NMRemoteSetting this means to wait until GetSettings() returns.
+	 *
+	 * Note that most object types reference each other (directly or indirectly). E.g. the
+	 * NMActiveConnection refers to the NMRemoteConnection and the NMDevice instance. So,
+	 * we don't want to hide them too long, otherwise basically the entire set of objects
+	 * will be hidden until they are all initialized. So, usually, when a NMObject references
+	 * objects that are not yet initialized, that reference will just be NULL but the object
+	 * will be considered ready already.
+	 *
+	 * For NMActiveConnection referencing a NMRemoteConnection don't do that. Here we wait for the
+	 * NMRemoteConnection to be ready as well. This is somewhat arbitrary special casing, but
+	 * the effect is that when nm_client_add_and_activate*() returns, the NMActiveConnection already
+	 * references a initialized NMRemoteConnection.
+	 */
+	if (!nml_dbus_property_o_is_ready_fully (&priv->property_o[PROPERTY_O_IDX_CONNECTION]))
+		return FALSE;
+
+	return NM_OBJECT_CLASS (nm_active_connection_parent_class)->is_ready (nmobj);
+}
 
 /*****************************************************************************/
 
@@ -550,6 +577,8 @@ nm_active_connection_class_init (NMActiveConnectionClass *klass)
 	object_class->get_property = get_property;
 	object_class->finalize     = finalize;
 
+	nm_object_class->is_ready = is_ready;
+
 	_NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT (nm_object_class, NMActiveConnection);
 
 	_NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N (nm_object_class, NMActiveConnectionPrivate, property_o);
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 154ad1c992..a93a81c353 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -1594,6 +1594,14 @@ nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o)
 	       || !pr_o->owner_dbobj;
 }
 
+gboolean
+nml_dbus_property_o_is_ready_fully (const NMLDBusPropertyO *pr_o)
+{
+	return    !pr_o->owner_dbobj
+	       || !pr_o->obj_watcher
+	       || pr_o->nmobj;
+}
+
 static void
 nml_dbus_property_o_notify_changed (NMLDBusPropertyO *pr_o,
                                     NMClient *self)
diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h
index f2affc5f62..28c9c1164c 100644
--- a/libnm/nm-libnm-utils.h
+++ b/libnm/nm-libnm-utils.h
@@ -260,6 +260,8 @@ gpointer nml_dbus_property_o_get_obj (NMLDBusPropertyO *pr_o);
 
 gboolean nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o);
 
+gboolean nml_dbus_property_o_is_ready_fully (const NMLDBusPropertyO *pr_o);
+
 void nml_dbus_property_o_clear (NMLDBusPropertyO *pr_o,
                                 NMClient *client);
 
-- 
2.24.1