Skip to content

Commit d31c9da

Browse files
cgwaltersrh-atomic-bot
authored andcommitted
app: Call RegisterClient with well-known name, use retry loop
This closes a race condition for having the daemon idle exit. After the daemon has released its bus name, the dbus-daemon will no longer allow messages through that targeted its unique name. Since the intention of the `RegisterClient` method is to be the "knock on the door", fix this by directly sending a message to the well-known name. Second, we need to handle the case where the daemon exits without replying; @jlebon added a `sleep(10)` invocation after the daemon mainloop quit but before we `ReleaseName`, and I verified these two things combine to fix that case. Closes: #606 Approved by: jlebon
1 parent 3f367db commit d31c9da

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

src/app/rpmostree-dbus-helpers.c

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,6 @@ rpmostree_load_sysroot (gchar *sysroot,
140140
{
141141
const char *bus_name = NULL;
142142
glnx_unref_object GDBusConnection *connection = NULL;
143-
glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
144-
g_autoptr(GVariantBuilder) options_builder =
145-
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
146143
_cleanup_peer_ GPid peer_pid = 0;
147144

148145
connection = get_connection_for_path (sysroot, force_peer, &peer_pid,
@@ -153,15 +150,6 @@ rpmostree_load_sysroot (gchar *sysroot,
153150
if (g_dbus_connection_get_unique_name (connection) != NULL)
154151
bus_name = BUS_NAME;
155152

156-
sysroot_proxy = rpmostree_sysroot_proxy_new_sync (connection,
157-
G_DBUS_PROXY_FLAGS_NONE,
158-
bus_name,
159-
"/org/projectatomic/rpmostree1/Sysroot",
160-
NULL,
161-
error);
162-
if (sysroot_proxy == NULL)
163-
return FALSE;
164-
165153
/* Try to register if we can; it doesn't matter much now since the daemon doesn't
166154
* auto-exit, though that might change in the future. But only register if we're active or
167155
* root; the daemon won't allow it otherwise. */
@@ -178,14 +166,52 @@ rpmostree_load_sysroot (gchar *sysroot,
178166
should_register = FALSE;
179167
}
180168

181-
if (should_register)
182-
{
183-
if (!rpmostree_sysroot_call_register_client_sync (sysroot_proxy,
184-
g_variant_builder_end (options_builder),
185-
cancellable, error))
186-
return FALSE;
169+
/* First, call RegisterClient directly for the well-known name, to
170+
* cause bus activation and allow race-free idle exit.
171+
* https://github.com/projectatomic/rpm-ostree/pull/606
172+
* If we get unlucky and try to talk to the daemon in FLUSHING
173+
* state, then it won't reply, and we should try again.
174+
*/
175+
static const char sysroot_objpath[] = "/org/projectatomic/rpmostree1/Sysroot";
176+
while (should_register)
177+
{
178+
g_autoptr(GError) local_error = NULL;
179+
g_autoptr(GVariantBuilder) options_builder =
180+
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
181+
g_autoptr(GVariant) res =
182+
g_dbus_connection_call_sync (connection, bus_name, sysroot_objpath,
183+
"org.projectatomic.rpmostree1.Sysroot",
184+
"RegisterClient",
185+
g_variant_new ("(@a{sv})", g_variant_builder_end (options_builder)),
186+
(GVariantType*)"()",
187+
G_DBUS_CALL_FLAGS_NONE, -1,
188+
cancellable, &local_error);
189+
if (res)
190+
break; /* Success! */
191+
192+
if (g_dbus_error_is_remote_error (local_error))
193+
{
194+
g_autofree char *remote_err = g_dbus_error_get_remote_error (local_error);
195+
/* If this is true, we caught the daemon after it was doing an
196+
* idle exit, but while it still owned the name. Retry.
197+
*/
198+
if (g_str_equal (remote_err, "org.freedesktop.DBus.Error.NoReply"))
199+
continue;
200+
/* Otherwise, fall through */
201+
}
202+
203+
/* Something else went wrong */
204+
g_propagate_error (error, g_steal_pointer (&local_error));
205+
return FALSE;
187206
}
188207

208+
glnx_unref_object RPMOSTreeSysroot *sysroot_proxy =
209+
rpmostree_sysroot_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
210+
bus_name, "/org/projectatomic/rpmostree1/Sysroot",
211+
NULL, error);
212+
if (sysroot_proxy == NULL)
213+
return FALSE;
214+
189215
*out_sysroot_proxy = g_steal_pointer (&sysroot_proxy);
190216
*out_peer_pid = peer_pid; peer_pid = 0;
191217
return TRUE;

0 commit comments

Comments
 (0)