[gnome-settings-daemon] sharing: Use systemd to track running services
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] sharing: Use systemd to track running services
- Date: Tue, 30 Aug 2016 10:54:34 +0000 (UTC)
commit e0b7f4143bdd201c824499dd09159f5890a07c6a
Author: Bastien Nocera <hadess hadess net>
Date: Thu May 12 15:51:46 2016 +0200
sharing: Use systemd to track running services
Instead of launching network services by hand, and having no way to
track them if gnome-settings-daemon crashes, leaving the services
dangling open when they should have been switched off, use systemd
--user to track the services.
This means that:
- services will not be left on when switching to a network where they
should be disabled
- services will be restarted if they crash
https://bugzilla.gnome.org/show_bug.cgi?id=766329
plugins/sharing/gsd-sharing-manager.c | 116 +++++++++++++++++----------------
1 files changed, 60 insertions(+), 56 deletions(-)
---
diff --git a/plugins/sharing/gsd-sharing-manager.c b/plugins/sharing/gsd-sharing-manager.c
index 13e09b5..170674b 100644
--- a/plugins/sharing/gsd-sharing-manager.c
+++ b/plugins/sharing/gsd-sharing-manager.c
@@ -39,8 +39,6 @@
typedef struct {
const char *name;
GSettings *settings;
- gboolean started;
- GSubprocess *process;
} ServiceInfo;
struct GsdSharingManagerPrivate
@@ -102,48 +100,72 @@ static const char * const services[] = {
};
static void
-gsd_sharing_manager_start_service (GsdSharingManager *manager,
- ServiceInfo *service)
+handle_unit_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GDesktopAppInfo *app;
- const char *exec;
- char *desktop, **argvp;
GError *error = NULL;
+ GVariant *ret;
+ const char *operation = user_data;
- if (service->started)
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
+ res, &error);
+ if (!ret) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to %s service: %s", operation, error->message);
+ g_error_free (error);
return;
- g_debug ("About to start %s", service->name);
+ }
- desktop = g_strdup_printf ("%s.desktop", service->name);
- app = g_desktop_app_info_new (desktop);
- g_free (desktop);
+ g_variant_unref (ret);
- if (!app) {
- g_warning ("Could not find desktop file for service '%s'", service->name);
- return;
- }
+}
- exec = g_app_info_get_commandline (G_APP_INFO (app));
+static void
+gsd_sharing_manager_handle_service (GsdSharingManager *manager,
+ const char *method,
+ GAsyncReadyCallback callback,
+ ServiceInfo *service)
+{
+ char *service_file;
+
+ service_file = g_strdup_printf ("%s.service", service->name);
+ g_dbus_connection_call (manager->priv->connection,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ method,
+ g_variant_new ("(ss)", service_file, "replace"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ manager->priv->cancellable,
+ callback,
+ manager);
+ g_free (service_file);
+}
- if (!g_shell_parse_argv (exec, NULL, &argvp, &error)) {
- g_warning ("Could not parse command-line '%s': %s", exec, error->message);
- g_error_free (error);
- g_object_unref (app);
- return;
- }
+static void
+gsd_sharing_manager_start_service (GsdSharingManager *manager,
+ ServiceInfo *service)
+{
+ g_debug ("About to start %s", service->name);
- service->process = g_subprocess_newv ((const gchar * const*) argvp, G_SUBPROCESS_FLAGS_NONE, &error);
+ /* We use StartUnit, not StartUnitReplace, since the latter would
+ * cancel any pending start we already have going from an
+ * earlier _start_service() call */
+ gsd_sharing_manager_handle_service (manager, "StartUnit",
+ handle_unit_cb, "start");
+}
- if (!service->process) {
- g_warning ("Could not start command-line '%s': %s", exec, error->message);
- g_error_free (error);
- service->started = FALSE;
- } else {
- service->started = TRUE;
- }
+static void
+gsd_sharing_manager_stop_service (GsdSharingManager *manager,
+ ServiceInfo *service)
+{
+ g_debug ("About to stop %s", service->name);
- g_strfreev (argvp);
- g_object_unref (app);
+ gsd_sharing_manager_handle_service (manager, "StopUnit",
+ handle_unit_cb, "stop");
}
#ifdef HAVE_NETWORK_MANAGER
@@ -176,22 +198,6 @@ service_is_enabled_on_current_connection (GsdSharingManager *manager,
#endif /* HAVE_NETWORK_MANAGER */
static void
-gsd_sharing_manager_stop_service (GsdSharingManager *manager,
- ServiceInfo *service)
-{
- if (!service->started ||
- service->process == NULL) {
- return;
- }
-
- g_debug ("About to stop %s", service->name);
-
- g_subprocess_send_signal (service->process, SIGTERM);
- g_clear_object (&service->process);
- service->started = FALSE;
-}
-
-static void
gsd_sharing_manager_sync_services (GsdSharingManager *manager)
{
GList *services, *l;
@@ -206,12 +212,10 @@ gsd_sharing_manager_sync_services (GsdSharingManager *manager)
service_is_enabled_on_current_connection (manager, service))
should_be_started = TRUE;
- if (service->started != should_be_started) {
- if (service->started)
- gsd_sharing_manager_stop_service (manager, service);
- else
- gsd_sharing_manager_start_service (manager, service);
- }
+ if (should_be_started)
+ gsd_sharing_manager_start_service (manager, service);
+ else
+ gsd_sharing_manager_stop_service (manager, service);
}
g_list_free (services);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]