Blame SOURCES/fix-restarts.patch

1e501a
From 46fadc83c114540c0ec0adb191e0a8f7a7d897c7 Mon Sep 17 00:00:00 2001
1e501a
From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= <jprvita@endlessm.com>
1e501a
Date: Fri, 10 Jul 2015 12:52:04 -0400
1e501a
Subject: [PATCH 1/3] Make gdm-session-worker exit cleanly
1e501a
1e501a
Calling gdm_session_stop_conversation() in gdm_launch_environment_stop()
1e501a
sends a SIGTERM to gdm-session-worker without waiting for it to die. The
1e501a
next step is calling gdm_session_close() to close the session, which
1e501a
stops all conversations of that session object, sending a 2nd SIGTERM to
1e501a
gdm-session-worker, this time waiting on its PID.
1e501a
1e501a
On gdm-session-worker side, the first SIGTERM is caught by
1e501a
on_shutdown_signal(), its custom SIGTERM handler, which quits the
1e501a
mainloop and unrefs the worker object. Quiting the mainloop replaces the
1e501a
custom SIGTERM handler with the system default one (exit immediately).
1e501a
During the worker object class finalization gdm-session-worker may
1e501a
receive the 2nd SIGTERM, which leads to its immediate termination,
1e501a
without waiting for its children, which in turn leads to the main gdm
1e501a
process exit.
1e501a
1e501a
Since systemd relies on the SIGCHLD from the main gdm process to tell
1e501a
when the service has stopped, this behavior breaks any unit that has a
1e501a
Conflicts=gdm.service entry and relies on the X server not being around
1e501a
when it is started.
1e501a
1e501a
This commit removes the call to gdm_session_stop_conversation() in
1e501a
gdm_launch_environment_stop() and leaves it to be stopped in
1e501a
gdm_session_close().
1e501a
1e501a
[endlessm/eos-shell#4921]
1e501a
1e501a
https://bugzilla.gnome.org/show_bug.cgi?id=752388
1e501a
---
1e501a
 daemon/gdm-launch-environment.c | 1 -
1e501a
 1 file changed, 1 deletion(-)
1e501a
1e501a
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
1e501a
index 4aee187..af3bf87 100644
1e501a
--- a/daemon/gdm-launch-environment.c
1e501a
+++ b/daemon/gdm-launch-environment.c
1e501a
@@ -402,61 +402,60 @@ gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment)
1e501a
 
1e501a
         gdm_session_start_conversation (launch_environment->priv->session, "gdm-launch-environment");
1e501a
 
1e501a
         if (launch_environment->priv->dbus_session_bus_address) {
1e501a
                 gdm_session_select_program (launch_environment->priv->session, launch_environment->priv->command);
1e501a
         } else {
1e501a
                 /* wrap it in dbus-launch */
1e501a
                 char *command = g_strdup_printf ("%s %s", DBUS_LAUNCH_COMMAND, launch_environment->priv->command);
1e501a
 
1e501a
                 gdm_session_select_program (launch_environment->priv->session, command);
1e501a
                 g_free (command);
1e501a
         }
1e501a
 
1e501a
         res = TRUE;
1e501a
  out:
1e501a
         if (local_error) {
1e501a
                 g_critical ("GdmLaunchEnvironment: %s", local_error->message);
1e501a
                 g_clear_error (&local_error);
1e501a
         }
1e501a
         return res;
1e501a
 }
1e501a
 
1e501a
 gboolean
1e501a
 gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment)
1e501a
 {
1e501a
         if (launch_environment->priv->pid > 1) {
1e501a
                 gdm_signal_pid (-launch_environment->priv->pid, SIGTERM);
1e501a
         }
1e501a
 
1e501a
         if (launch_environment->priv->session != NULL) {
1e501a
-                gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment");
1e501a
                 gdm_session_close (launch_environment->priv->session);
1e501a
 
1e501a
                 g_clear_object (&launch_environment->priv->session);
1e501a
         }
1e501a
 
1e501a
         g_signal_emit (G_OBJECT (launch_environment), signals [STOPPED], 0);
1e501a
 
1e501a
         return TRUE;
1e501a
 }
1e501a
 
1e501a
 GdmSession *
1e501a
 gdm_launch_environment_get_session (GdmLaunchEnvironment *launch_environment)
1e501a
 {
1e501a
         return launch_environment->priv->session;
1e501a
 }
1e501a
 
1e501a
 char *
1e501a
 gdm_launch_environment_get_session_id (GdmLaunchEnvironment *launch_environment)
1e501a
 {
1e501a
         return g_strdup (launch_environment->priv->session_id);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
 _gdm_launch_environment_set_verification_mode (GdmLaunchEnvironment           *launch_environment,
1e501a
                                                GdmSessionVerificationMode      verification_mode)
1e501a
 {
1e501a
         launch_environment->priv->verification_mode = verification_mode;
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
-- 
1e501a
2.3.7
1e501a
1e501a
1e501a
From 92564b47a85f9a308f7bfc34b8017f2767bf4677 Mon Sep 17 00:00:00 2001
1e501a
From: Ray Strode <rstrode@redhat.com>
1e501a
Date: Wed, 4 Mar 2015 11:12:24 -0500
1e501a
Subject: [PATCH 2/3] manager: clean up manager in dispose not finalize
1e501a
1e501a
Seems more appropriate.
1e501a
1e501a
https://bugzilla.gnome.org/show_bug.cgi?id=745975
1e501a
---
1e501a
 daemon/gdm-manager.c | 19 ++++++++++++-------
1e501a
 1 file changed, 12 insertions(+), 7 deletions(-)
1e501a
1e501a
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
1e501a
index f060135..e0af40c 100644
1e501a
--- a/daemon/gdm-manager.c
1e501a
+++ b/daemon/gdm-manager.c
1e501a
@@ -75,61 +75,61 @@ struct GdmManagerPrivate
1e501a
         GHashTable             *transient_sessions;
1e501a
         GHashTable             *open_reauthentication_requests;
1e501a
         gboolean                xdmcp_enabled;
1e501a
         GCancellable           *cancellable;
1e501a
 
1e501a
         gboolean                started;
1e501a
         gboolean                wait_for_go;
1e501a
         gboolean                show_local_greeter;
1e501a
 
1e501a
         GDBusProxy               *bus_proxy;
1e501a
         GDBusConnection          *connection;
1e501a
         GDBusObjectManagerServer *object_manager;
1e501a
 };
1e501a
 
1e501a
 enum {
1e501a
         PROP_0,
1e501a
         PROP_XDMCP_ENABLED,
1e501a
         PROP_SHOW_LOCAL_GREETER
1e501a
 };
1e501a
 
1e501a
 enum {
1e501a
         DISPLAY_ADDED,
1e501a
         DISPLAY_REMOVED,
1e501a
         LAST_SIGNAL
1e501a
 };
1e501a
 
1e501a
 static guint signals [LAST_SIGNAL] = { 0, };
1e501a
 
1e501a
 static void     gdm_manager_class_init  (GdmManagerClass *klass);
1e501a
 static void     gdm_manager_init        (GdmManager      *manager);
1e501a
-static void     gdm_manager_finalize    (GObject         *object);
1e501a
+static void     gdm_manager_dispose     (GObject         *object);
1e501a
 static void create_seed_session_for_display (GdmManager *manager,
1e501a
                                              GdmDisplay *display,
1e501a
                                              uid_t       allowed_user);
1e501a
 static void     touch_ran_once_marker_file  (GdmManager *manager);
1e501a
 
1e501a
 static gpointer manager_object = NULL;
1e501a
 
1e501a
 static void manager_interface_init (GdmDBusManagerIface *interface);
1e501a
 
1e501a
 G_DEFINE_TYPE_WITH_CODE (GdmManager,
1e501a
                          gdm_manager,
1e501a
                          GDM_DBUS_TYPE_MANAGER_SKELETON,
1e501a
                          G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_MANAGER,
1e501a
                                                 manager_interface_init));
1e501a
 
1e501a
 #ifdef WITH_SYSTEMD
1e501a
 static char *
1e501a
 get_session_id_for_pid_systemd (pid_t    pid,
1e501a
                                 GError **error)
1e501a
 {
1e501a
         char *session, *gsession;
1e501a
         int ret;
1e501a
 
1e501a
         session = NULL;
1e501a
         ret = sd_pid_get_session (pid, &session);
1e501a
         if (ret < 0) {
1e501a
                 g_set_error (error,
1e501a
                              GDM_DISPLAY_ERROR,
1e501a
                              GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
1e501a
                              "Error getting session id from systemd: %s",
1e501a
@@ -2186,61 +2186,61 @@ gdm_manager_constructor (GType                  type,
1e501a
                          guint                  n_construct_properties,
1e501a
                          GObjectConstructParam *construct_properties)
1e501a
 {
1e501a
         GdmManager      *manager;
1e501a
 
1e501a
         manager = GDM_MANAGER (G_OBJECT_CLASS (gdm_manager_parent_class)->constructor (type,
1e501a
                                                                                        n_construct_properties,
1e501a
                                                                                        construct_properties));
1e501a
 
1e501a
         gdm_dbus_manager_set_version (GDM_DBUS_MANAGER (manager), PACKAGE_VERSION);
1e501a
 
1e501a
         manager->priv->local_factory = gdm_local_display_factory_new (manager->priv->display_store);
1e501a
 
1e501a
 #ifdef HAVE_LIBXDMCP
1e501a
         if (manager->priv->xdmcp_enabled) {
1e501a
                 manager->priv->xdmcp_factory = gdm_xdmcp_display_factory_new (manager->priv->display_store);
1e501a
         }
1e501a
 #endif
1e501a
 
1e501a
         return G_OBJECT (manager);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
 gdm_manager_class_init (GdmManagerClass *klass)
1e501a
 {
1e501a
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
1e501a
 
1e501a
         object_class->get_property = gdm_manager_get_property;
1e501a
         object_class->set_property = gdm_manager_set_property;
1e501a
         object_class->constructor = gdm_manager_constructor;
1e501a
-        object_class->finalize = gdm_manager_finalize;
1e501a
+        object_class->dispose = gdm_manager_dispose;
1e501a
 
1e501a
         signals [DISPLAY_ADDED] =
1e501a
                 g_signal_new ("display-added",
1e501a
                               G_TYPE_FROM_CLASS (object_class),
1e501a
                               G_SIGNAL_RUN_LAST,
1e501a
                               G_STRUCT_OFFSET (GdmManagerClass, display_added),
1e501a
                               NULL,
1e501a
                               NULL,
1e501a
                               g_cclosure_marshal_VOID__STRING,
1e501a
                               G_TYPE_NONE,
1e501a
                               1, G_TYPE_STRING);
1e501a
         signals [DISPLAY_REMOVED] =
1e501a
                 g_signal_new ("display-removed",
1e501a
                               G_TYPE_FROM_CLASS (object_class),
1e501a
                               G_SIGNAL_RUN_LAST,
1e501a
                               G_STRUCT_OFFSET (GdmManagerClass, display_removed),
1e501a
                               NULL,
1e501a
                               NULL,
1e501a
                               g_cclosure_marshal_VOID__STRING,
1e501a
                               G_TYPE_NONE,
1e501a
                               1, G_TYPE_STRING);
1e501a
 
1e501a
         g_object_class_install_property (object_class,
1e501a
                                          PROP_XDMCP_ENABLED,
1e501a
                                          g_param_spec_boolean ("xdmcp-enabled",
1e501a
                                                                NULL,
1e501a
                                                                NULL,
1e501a
                                                                FALSE,
1e501a
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
1e501a
 
1e501a
@@ -2271,100 +2271,105 @@ gdm_manager_init (GdmManager *manager)
1e501a
                           "display-added",
1e501a
                           G_CALLBACK (on_display_added),
1e501a
                           manager);
1e501a
 
1e501a
         g_signal_connect (G_OBJECT (manager->priv->display_store),
1e501a
                           "display-removed",
1e501a
                           G_CALLBACK (on_display_removed),
1e501a
                           manager);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
 unexport_display (const char *id,
1e501a
                   GdmDisplay *display,
1e501a
                   GdmManager *manager)
1e501a
 {
1e501a
         if (!g_dbus_connection_is_closed (manager->priv->connection))
1e501a
                 g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
 finish_display (const char *id,
1e501a
                 GdmDisplay *display,
1e501a
                 GdmManager *manager)
1e501a
 {
1e501a
         if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
1e501a
                 gdm_display_unmanage (display);
1e501a
         gdm_display_finish (display);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
-gdm_manager_finalize (GObject *object)
1e501a
+gdm_manager_dispose (GObject *object)
1e501a
 {
1e501a
         GdmManager *manager;
1e501a
 
1e501a
         g_return_if_fail (object != NULL);
1e501a
         g_return_if_fail (GDM_IS_MANAGER (object));
1e501a
 
1e501a
         manager = GDM_MANAGER (object);
1e501a
 
1e501a
         g_return_if_fail (manager->priv != NULL);
1e501a
 
1e501a
 #ifdef HAVE_LIBXDMCP
1e501a
         g_clear_object (&manager->priv->xdmcp_factory);
1e501a
 #endif
1e501a
         g_clear_object (&manager->priv->local_factory);
1e501a
-        g_hash_table_unref (manager->priv->open_reauthentication_requests);
1e501a
-        g_hash_table_unref (manager->priv->transient_sessions);
1e501a
+        g_clear_pointer (&manager->priv->open_reauthentication_requests,
1e501a
+                         (GDestroyNotify)
1e501a
+                         g_hash_table_unref);
1e501a
+        g_clear_pointer (&manager->priv->transient_sessions,
1e501a
+                         (GDestroyNotify)
1e501a
+                         g_hash_table_unref);
1e501a
+
1e501a
         g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
1e501a
         manager->priv->user_sessions = NULL;
1e501a
 
1e501a
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
1e501a
                                               G_CALLBACK (on_display_added),
1e501a
                                               manager);
1e501a
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
1e501a
                                               G_CALLBACK (on_display_removed),
1e501a
                                               manager);
1e501a
 
1e501a
         if (!g_dbus_connection_is_closed (manager->priv->connection)) {
1e501a
                 gdm_display_store_foreach (manager->priv->display_store,
1e501a
                                            (GdmDisplayStoreFunc)unexport_display,
1e501a
                                            manager);
1e501a
                 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
1e501a
         }
1e501a
 
1e501a
         gdm_display_store_foreach (manager->priv->display_store,
1e501a
                                    (GdmDisplayStoreFunc) finish_display,
1e501a
                                    manager);
1e501a
 
1e501a
         gdm_display_store_clear (manager->priv->display_store);
1e501a
 
1e501a
         g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
1e501a
 
1e501a
         g_clear_object (&manager->priv->connection);
1e501a
         g_clear_object (&manager->priv->object_manager);
1e501a
 
1e501a
-        g_object_unref (manager->priv->display_store);
1e501a
+        g_clear_object (&manager->priv->display_store);
1e501a
 
1e501a
-        G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object);
1e501a
+        G_OBJECT_CLASS (gdm_manager_parent_class)->dispose (object);
1e501a
 }
1e501a
 
1e501a
 GdmManager *
1e501a
 gdm_manager_new (void)
1e501a
 {
1e501a
         if (manager_object != NULL) {
1e501a
                 g_object_ref (manager_object);
1e501a
         } else {
1e501a
                 gboolean res;
1e501a
 
1e501a
                 manager_object = g_object_new (GDM_TYPE_MANAGER, NULL);
1e501a
                 g_object_add_weak_pointer (manager_object,
1e501a
                                            (gpointer *) &manager_object);
1e501a
                 res = register_manager (manager_object);
1e501a
                 if (! res) {
1e501a
                         g_object_unref (manager_object);
1e501a
                         return NULL;
1e501a
                 }
1e501a
         }
1e501a
 
1e501a
         return GDM_MANAGER (manager_object);
1e501a
 }
1e501a
-- 
1e501a
2.3.7
1e501a
1e501a
1e501a
From c6243ccc362cb51bb87043e18108d99117abd6c1 Mon Sep 17 00:00:00 2001
1e501a
From: Ray Strode <rstrode@redhat.com>
1e501a
Date: Wed, 4 Mar 2015 11:17:05 -0500
1e501a
Subject: [PATCH 3/3] manager: make sure to explicitly close user sessions in
1e501a
 dispose
1e501a
1e501a
We don't want ref count leaks to lead to unkilled sessions.
1e501a
1e501a
https://bugzilla.gnome.org/show_bug.cgi?id=745975
1e501a
---
1e501a
 daemon/gdm-manager.c | 3 +++
1e501a
 1 file changed, 3 insertions(+)
1e501a
1e501a
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
1e501a
index e0af40c..12520ac 100644
1e501a
--- a/daemon/gdm-manager.c
1e501a
+++ b/daemon/gdm-manager.c
1e501a
@@ -2293,60 +2293,63 @@ finish_display (const char *id,
1e501a
                 GdmManager *manager)
1e501a
 {
1e501a
         if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
1e501a
                 gdm_display_unmanage (display);
1e501a
         gdm_display_finish (display);
1e501a
 }
1e501a
 
1e501a
 static void
1e501a
 gdm_manager_dispose (GObject *object)
1e501a
 {
1e501a
         GdmManager *manager;
1e501a
 
1e501a
         g_return_if_fail (object != NULL);
1e501a
         g_return_if_fail (GDM_IS_MANAGER (object));
1e501a
 
1e501a
         manager = GDM_MANAGER (object);
1e501a
 
1e501a
         g_return_if_fail (manager->priv != NULL);
1e501a
 
1e501a
 #ifdef HAVE_LIBXDMCP
1e501a
         g_clear_object (&manager->priv->xdmcp_factory);
1e501a
 #endif
1e501a
         g_clear_object (&manager->priv->local_factory);
1e501a
         g_clear_pointer (&manager->priv->open_reauthentication_requests,
1e501a
                          (GDestroyNotify)
1e501a
                          g_hash_table_unref);
1e501a
         g_clear_pointer (&manager->priv->transient_sessions,
1e501a
                          (GDestroyNotify)
1e501a
                          g_hash_table_unref);
1e501a
 
1e501a
+        g_list_foreach (manager->priv->user_sessions,
1e501a
+                        (GFunc) gdm_session_close,
1e501a
+                        NULL);
1e501a
         g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
1e501a
         manager->priv->user_sessions = NULL;
1e501a
 
1e501a
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
1e501a
                                               G_CALLBACK (on_display_added),
1e501a
                                               manager);
1e501a
         g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
1e501a
                                               G_CALLBACK (on_display_removed),
1e501a
                                               manager);
1e501a
 
1e501a
         if (!g_dbus_connection_is_closed (manager->priv->connection)) {
1e501a
                 gdm_display_store_foreach (manager->priv->display_store,
1e501a
                                            (GdmDisplayStoreFunc)unexport_display,
1e501a
                                            manager);
1e501a
                 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
1e501a
         }
1e501a
 
1e501a
         gdm_display_store_foreach (manager->priv->display_store,
1e501a
                                    (GdmDisplayStoreFunc) finish_display,
1e501a
                                    manager);
1e501a
 
1e501a
         gdm_display_store_clear (manager->priv->display_store);
1e501a
 
1e501a
         g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
1e501a
 
1e501a
         g_clear_object (&manager->priv->connection);
1e501a
         g_clear_object (&manager->priv->object_manager);
1e501a
 
1e501a
         g_clear_object (&manager->priv->display_store);
1e501a
 
1e501a
-- 
1e501a
2.3.7
1e501a