This allows us to only shut down the P2P daemon in the installed tests.
The easy fix would have been to use something like:
gdbus call --address unix:path=/run/fwupd.sock --object-path / --method org.freedesktop.fwupd.Quit'
...but the daemon does not implement an ObjectManager, which gdbus requires.
This worked correctly for so long because the p2p tests were being run after
the bus tests, so shutting down the system daemon had no effect.
Fedora 37 seems to have flipped the order for some reason -- and now it
*sometimes* matters that we were doing the worng thing...
'local-install'
'modify-config'
'modify-remote'
+ 'quit'
'reinstall'
'refresh'
'report-history'
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a verify-update -d 'Update the stored cryptographic hash with current ROM contents'
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a inhibit -d 'Inhibit the system to prevent upgrades'
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a uninhibit -d 'Uninhibit the system to allow upgrades'
+complete -c fwupdmgr -n '__fish_use_subcommand' -x -a quit -d 'Asks the daemon to quit'
# commands exclusively consuming device IDs
set -l deviceid_consumers activate clear-results downgrade get-releases get-results get-updates reinstall switch-branch unlock update verify verify-update
# ---
echo "Shutting down P2P daemon..."
-gdbus call --system --dest org.freedesktop.fwupd --object-path / --method org.freedesktop.fwupd.Quit
+fwupdmgr quit
# success!
exit 0
return TRUE;
}
+static void
+fwupd_client_quit_cb(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ FwupdClientHelper *helper = (FwupdClientHelper *)user_data;
+ helper->ret = fwupd_client_quit_finish(FWUPD_CLIENT(source), res, &helper->error);
+ g_main_loop_quit(helper->loop);
+}
+
+/**
+ * fwupd_client_quit: (skip)
+ * @self: a #FwupdClient
+ * @cancellable: (nullable): optional #GCancellable
+ * @error: (nullable): optional return location for an error
+ *
+ * Asks the daemon to quit. This can only be called by the root user.
+ *
+ * NOTE: This will only actually quit if an install is not already in progress.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 1.8.11
+ **/
+gboolean
+fwupd_client_quit(FwupdClient *self, GCancellable *cancellable, GError **error)
+{
+ g_autoptr(FwupdClientHelper) helper = NULL;
+
+ g_return_val_if_fail(FWUPD_IS_CLIENT(self), FALSE);
+ g_return_val_if_fail(cancellable == NULL || G_IS_CANCELLABLE(cancellable), FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ /* call async version and run loop until complete */
+ helper = fwupd_client_helper_new(self);
+ fwupd_client_quit_async(self, cancellable, fwupd_client_quit_cb, helper);
+ g_main_loop_run(helper->loop);
+ if (!helper->ret) {
+ g_propagate_error(error, g_steal_pointer(&helper->error));
+ return FALSE;
+ }
+ return TRUE;
+}
+
static void
fwupd_client_get_devices_cb(GObject *source, GAsyncResult *res, gpointer user_data)
{
fwupd_client_connect(FwupdClient *self,
GCancellable *cancellable,
GError **error) G_GNUC_WARN_UNUSED_RESULT;
+gboolean
+fwupd_client_quit(FwupdClient *self,
+ GCancellable *cancellable,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT;
GPtrArray *
fwupd_client_get_devices(FwupdClient *self,
GCancellable *cancellable,
return TRUE;
}
+static void
+fwupd_client_quit_cb(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GTask) task = G_TASK(user_data);
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GVariant) val = NULL;
+
+ val = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
+ if (val == NULL) {
+ fwupd_client_fixup_dbus_error(error);
+ g_task_return_error(task, g_steal_pointer(&error));
+ return;
+ }
+
+ /* success */
+ g_task_return_boolean(task, TRUE);
+}
+
+/**
+ * fwupd_client_quit_async:
+ * @self: a #FwupdClient
+ * @cancellable: (nullable): optional #GCancellable
+ * @callback: the function to run on completion
+ * @callback_data: the data to pass to @callback
+ *
+ * Asks the daemon to quit. This can only be called by the root user.
+ *
+ * NOTE: This will only actually quit if an install is not already in progress.
+ *
+ * Since: 1.8.11
+ **/
+void
+fwupd_client_quit_async(FwupdClient *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer callback_data)
+{
+ FwupdClientPrivate *priv = GET_PRIVATE(self);
+ g_autoptr(GTask) task = NULL;
+
+ g_return_if_fail(FWUPD_IS_CLIENT(self));
+ g_return_if_fail(cancellable == NULL || G_IS_CANCELLABLE(cancellable));
+ g_return_if_fail(priv->proxy != NULL);
+
+ /* call into daemon */
+ task = g_task_new(self, cancellable, callback, callback_data);
+ g_dbus_proxy_call(priv->proxy,
+ "Quit",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ FWUPD_CLIENT_DBUS_PROXY_TIMEOUT,
+ cancellable,
+ fwupd_client_quit_cb,
+ g_steal_pointer(&task));
+}
+
+/**
+ * fwupd_client_quit_finish:
+ * @self: a #FwupdClient
+ * @res: (not nullable): the asynchronous result
+ * @error: (nullable): optional return location for an error
+ *
+ * Gets the result of [method@FwupdClient.quit_async].
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 1.8.11
+ **/
+gboolean
+fwupd_client_quit_finish(FwupdClient *self, GAsyncResult *res, GError **error)
+{
+ g_return_val_if_fail(FWUPD_IS_CLIENT(self), FALSE);
+ g_return_val_if_fail(g_task_is_valid(res, self), FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+ return g_task_propagate_boolean(G_TASK(res), error);
+}
+
static void
fwupd_client_fixup_dbus_error(GError *error)
{
gboolean
fwupd_client_disconnect(FwupdClient *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
void
+fwupd_client_quit_async(FwupdClient *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer callback_data);
+gboolean
+fwupd_client_quit_finish(FwupdClient *self,
+ GAsyncResult *res,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT;
+void
fwupd_client_get_devices_async(FwupdClient *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
fwupd_client_inhibit;
fwupd_client_inhibit_async;
fwupd_client_inhibit_finish;
+ fwupd_client_quit;
+ fwupd_client_quit_async;
+ fwupd_client_quit_finish;
fwupd_client_uninhibit;
fwupd_client_uninhibit_async;
fwupd_client_uninhibit_finish;
return fwupd_client_uninhibit(priv->client, values[0], priv->cancellable, error);
}
+static gboolean
+fu_util_quit(FuUtilPrivate *priv, gchar **values, GError **error)
+{
+ /* success */
+ return fwupd_client_quit(priv->client, priv->cancellable, error);
+}
+
static gboolean
fu_util_device_test(FuUtilPrivate *priv, gchar **values, GError **error)
{
/* TRANSLATORS: command description */
_("Uninhibit the system to allow upgrades"),
fu_util_uninhibit);
+ fu_util_cmd_array_add(cmd_array,
+ "quit",
+ NULL,
+ /* TRANSLATORS: command description */
+ _("Asks the daemon to quit"),
+ fu_util_quit);
fu_util_cmd_array_add(
cmd_array,
"get-bios-settings,get-bios-setting",