Blame SOURCES/fix-shutdown.patch

ef3d3d
From 48bf40b905d534ab003722778e0ad16b489e24a5 Mon Sep 17 00:00:00 2001
ef3d3d
From: Ray Strode <rstrode@redhat.com>
ef3d3d
Date: Mon, 6 Oct 2014 10:58:48 -0400
ef3d3d
Subject: [PATCH 1/4] display: don't leak a reference to the display object
ef3d3d
 from the display object
ef3d3d
ef3d3d
It means display objects never get finalized, and so the slave doesn't
ef3d3d
get killed in an orderly way at shutdown.
ef3d3d
---
ef3d3d
 daemon/gdm-display.c | 2 +-
ef3d3d
 1 file changed, 1 insertion(+), 1 deletion(-)
ef3d3d
ef3d3d
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
ef3d3d
index 5d06036..d16c094 100644
ef3d3d
--- a/daemon/gdm-display.c
ef3d3d
+++ b/daemon/gdm-display.c
ef3d3d
@@ -286,61 +286,61 @@ gdm_display_add_user_authorization (GdmDisplay *display,
ef3d3d
         g_object_unref (display);
ef3d3d
 
ef3d3d
         return ret;
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
 on_name_vanished (GDBusConnection *connection,
ef3d3d
                   const char      *name,
ef3d3d
                   gpointer         user_data)
ef3d3d
 {
ef3d3d
         queue_finish (GDM_DISPLAY (user_data));
ef3d3d
 }
ef3d3d
 
ef3d3d
 static gboolean
ef3d3d
 gdm_display_real_set_slave_bus_name (GdmDisplay *display,
ef3d3d
                                      const char *name,
ef3d3d
                                      GError    **error)
ef3d3d
 {
ef3d3d
         g_free (display->priv->slave_bus_name);
ef3d3d
         display->priv->slave_bus_name = g_strdup (name);
ef3d3d
 
ef3d3d
         if (display->priv->slave_name_id > 0) {
ef3d3d
                 g_bus_unwatch_name (display->priv->slave_name_id);
ef3d3d
         }
ef3d3d
 
ef3d3d
         display->priv->slave_name_id = g_bus_watch_name_on_connection (display->priv->connection,
ef3d3d
                                                                        name,
ef3d3d
                                                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
ef3d3d
                                                                        NULL, /* name appeared */
ef3d3d
                                                                        on_name_vanished,
ef3d3d
-                                                                       g_object_ref (display),
ef3d3d
+                                                                       display,
ef3d3d
                                                                        NULL);
ef3d3d
 
ef3d3d
         g_clear_object (&display->priv->slave_bus_proxy);
ef3d3d
         display->priv->slave_bus_proxy = GDM_DBUS_SLAVE (gdm_dbus_slave_proxy_new_sync (display->priv->connection,
ef3d3d
                                                                                         G_DBUS_PROXY_FLAGS_NONE,
ef3d3d
                                                                                         name,
ef3d3d
                                                                                         GDM_SLAVE_PATH,
ef3d3d
                                                                                         NULL, NULL));
ef3d3d
         g_object_bind_property (G_OBJECT (display->priv->slave_bus_proxy),
ef3d3d
                                 "session-id",
ef3d3d
                                 G_OBJECT (display),
ef3d3d
                                 "session-id",
ef3d3d
                                 G_BINDING_DEFAULT);
ef3d3d
 
ef3d3d
         return TRUE;
ef3d3d
 }
ef3d3d
 
ef3d3d
 gboolean
ef3d3d
 gdm_display_set_slave_bus_name (GdmDisplay *display,
ef3d3d
                                 const char *name,
ef3d3d
                                 GError    **error)
ef3d3d
 {
ef3d3d
         gboolean ret;
ef3d3d
 
ef3d3d
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
ef3d3d
 
ef3d3d
         g_debug ("GdmDisplay: Setting slave bus name:%s on display %s", name, display->priv->x11_display_name);
ef3d3d
 
ef3d3d
         g_object_ref (display);
ef3d3d
         ret = GDM_DISPLAY_GET_CLASS (display)->set_slave_bus_name (display, name, error);
ef3d3d
-- 
ef3d3d
1.8.3.1
ef3d3d
ef3d3d
ef3d3d
From 3cacba38e16686aa93ef47c6e0201938863aa6fb Mon Sep 17 00:00:00 2001
ef3d3d
From: Ray Strode <rstrode@redhat.com>
ef3d3d
Date: Mon, 6 Oct 2014 11:00:00 -0400
ef3d3d
Subject: [PATCH 2/4] launch-environment: shutdown worker process as well as
ef3d3d
 environment pgrp
ef3d3d
ef3d3d
The worker isn't part of the environment process group, so it needs to
ef3d3d
be kill explicitly even if the environment group is already getting
ef3d3d
killed.
ef3d3d
---
ef3d3d
 daemon/gdm-launch-environment.c | 11 +++++------
ef3d3d
 1 file changed, 5 insertions(+), 6 deletions(-)
ef3d3d
ef3d3d
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
ef3d3d
index 932cc06..551dc96 100644
ef3d3d
--- a/daemon/gdm-launch-environment.c
ef3d3d
+++ b/daemon/gdm-launch-environment.c
ef3d3d
@@ -502,68 +502,67 @@ gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment)
ef3d3d
                           "session-died",
ef3d3d
                           G_CALLBACK (on_session_died),
ef3d3d
                           launch_environment);
ef3d3d
 
ef3d3d
         gdm_session_start_conversation (launch_environment->priv->session, "gdm-launch-environment");
ef3d3d
 
ef3d3d
         if (launch_environment->priv->dbus_session_bus_address) {
ef3d3d
                 gdm_session_select_program (launch_environment->priv->session, launch_environment->priv->command);
ef3d3d
         } else {
ef3d3d
                 /* wrap it in dbus-launch */
ef3d3d
                 char *command = g_strdup_printf ("%s %s", DBUS_LAUNCH_COMMAND, launch_environment->priv->command);
ef3d3d
 
ef3d3d
                 gdm_session_select_program (launch_environment->priv->session, command);
ef3d3d
                 g_free (command);
ef3d3d
         }
ef3d3d
 
ef3d3d
         res = TRUE;
ef3d3d
  out:
ef3d3d
         if (local_error) {
ef3d3d
                 g_critical ("GdmLaunchEnvironment: %s", local_error->message);
ef3d3d
                 g_clear_error (&local_error);
ef3d3d
         }
ef3d3d
         return res;
ef3d3d
 }
ef3d3d
 
ef3d3d
 gboolean
ef3d3d
 gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment)
ef3d3d
 {
ef3d3d
         if (launch_environment->priv->pid > 1) {
ef3d3d
                 gdm_signal_pid (-launch_environment->priv->pid, SIGTERM);
ef3d3d
-        } else {
ef3d3d
-                if (launch_environment->priv->session != NULL) {
ef3d3d
-                        gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment");
ef3d3d
-                        gdm_session_close (launch_environment->priv->session);
ef3d3d
+        }
ef3d3d
 
ef3d3d
-                        g_clear_object (&launch_environment->priv->session);
ef3d3d
-                }
ef3d3d
+        if (launch_environment->priv->session != NULL) {
ef3d3d
+                gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment");
ef3d3d
+                gdm_session_close (launch_environment->priv->session);
ef3d3d
 
ef3d3d
+                g_clear_object (&launch_environment->priv->session);
ef3d3d
                 g_signal_emit (G_OBJECT (launch_environment), signals [STOPPED], 0);
ef3d3d
         }
ef3d3d
 
ef3d3d
         return TRUE;
ef3d3d
 }
ef3d3d
 
ef3d3d
 GdmSession *
ef3d3d
 gdm_launch_environment_get_session (GdmLaunchEnvironment *launch_environment)
ef3d3d
 {
ef3d3d
         return launch_environment->priv->session;
ef3d3d
 }
ef3d3d
 
ef3d3d
 char *
ef3d3d
 gdm_launch_environment_get_session_id (GdmLaunchEnvironment *launch_environment)
ef3d3d
 {
ef3d3d
         return g_strdup (launch_environment->priv->session_id);
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
 _gdm_launch_environment_set_verification_mode (GdmLaunchEnvironment           *launch_environment,
ef3d3d
                                                GdmSessionVerificationMode      verification_mode)
ef3d3d
 {
ef3d3d
         launch_environment->priv->verification_mode = verification_mode;
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
 _gdm_launch_environment_set_x11_display_name (GdmLaunchEnvironment *launch_environment,
ef3d3d
                                               const char           *name)
ef3d3d
 {
ef3d3d
         g_free (launch_environment->priv->x11_display_name);
ef3d3d
-- 
ef3d3d
1.8.3.1
ef3d3d
ef3d3d
ef3d3d
From 4703ecbca68b4798e95630fced0274e17ee0d5f4 Mon Sep 17 00:00:00 2001
ef3d3d
From: Ray Strode <rstrode@redhat.com>
ef3d3d
Date: Mon, 6 Oct 2014 11:01:10 -0400
ef3d3d
Subject: [PATCH 3/4] slave: stop from dispose not finalize
ef3d3d
ef3d3d
gdm_slave_stop will reference the passed in object,
ef3d3d
so doing it after the object is finalized, is wrong.
ef3d3d
ef3d3d
This commit moves the stopping to dispose.
ef3d3d
---
ef3d3d
 daemon/gdm-simple-slave.c | 11 +++++------
ef3d3d
 1 file changed, 5 insertions(+), 6 deletions(-)
ef3d3d
ef3d3d
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
ef3d3d
index 5057eb4..1ce0284 100644
ef3d3d
--- a/daemon/gdm-simple-slave.c
ef3d3d
+++ b/daemon/gdm-simple-slave.c
ef3d3d
@@ -86,61 +86,61 @@ struct GdmSimpleSlavePrivate
ef3d3d
         GdmSession        *session;
ef3d3d
 
ef3d3d
         /* this spawns and controls the greeter session */
ef3d3d
         GdmLaunchEnvironment *greeter_environment;
ef3d3d
 
ef3d3d
         GHashTable        *open_reauthentication_requests;
ef3d3d
 
ef3d3d
         GDBusProxy        *accountsservice_proxy;
ef3d3d
         guint              have_existing_user_accounts : 1;
ef3d3d
         guint              accountsservice_ready : 1;
ef3d3d
         guint              waiting_to_connect_to_display : 1;
ef3d3d
 
ef3d3d
         guint              start_session_when_ready : 1;
ef3d3d
         guint              waiting_to_start_session : 1;
ef3d3d
         guint              session_is_running : 1;
ef3d3d
 #ifdef  HAVE_LOGINDEVPERM
ef3d3d
         gboolean           use_logindevperm;
ef3d3d
 #endif
ef3d3d
 #ifdef  WITH_PLYMOUTH
ef3d3d
         guint              plymouth_is_running : 1;
ef3d3d
 #endif
ef3d3d
         guint              doing_initial_setup : 1;
ef3d3d
 };
ef3d3d
 
ef3d3d
 enum {
ef3d3d
         PROP_0,
ef3d3d
 };
ef3d3d
 
ef3d3d
 static void     gdm_simple_slave_class_init     (GdmSimpleSlaveClass *klass);
ef3d3d
 static void     gdm_simple_slave_init           (GdmSimpleSlave      *simple_slave);
ef3d3d
-static void     gdm_simple_slave_finalize       (GObject             *object);
ef3d3d
+static void     gdm_simple_slave_dispose        (GObject             *object);
ef3d3d
 static void     gdm_simple_slave_open_reauthentication_channel (GdmSlave             *slave,
ef3d3d
                                                                 const char           *username,
ef3d3d
                                                                 GPid                  pid_of_caller,
ef3d3d
                                                                 uid_t                 uid_of_caller,
ef3d3d
                                                                 GAsyncReadyCallback   callback,
ef3d3d
                                                                 gpointer              user_data,
ef3d3d
                                                                 GCancellable         *cancellable);
ef3d3d
 
ef3d3d
 static gboolean wants_initial_setup (GdmSimpleSlave *slave);
ef3d3d
 G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE)
ef3d3d
 
ef3d3d
 static void create_new_session (GdmSimpleSlave  *slave);
ef3d3d
 static void start_session      (GdmSimpleSlave  *slave);
ef3d3d
 static void queue_start_session (GdmSimpleSlave *slave,
ef3d3d
                                  const char     *service_name);
ef3d3d
 
ef3d3d
 static gboolean
ef3d3d
 chown_file (GFile   *file,
ef3d3d
             uid_t    uid,
ef3d3d
             gid_t    gid,
ef3d3d
             GError **error)
ef3d3d
 {
ef3d3d
         if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
ef3d3d
                                           G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
ef3d3d
                                           NULL, error)) {
ef3d3d
                 return FALSE;
ef3d3d
         }
ef3d3d
         if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
ef3d3d
                                           G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
ef3d3d
                                           NULL, error)) {
ef3d3d
@@ -1621,92 +1621,91 @@ gdm_simple_slave_stop (GdmSlave *slave)
ef3d3d
                 g_free (username);
ef3d3d
 
ef3d3d
 #ifdef  HAVE_LOGINDEVPERM
ef3d3d
                 gdm_simple_slave_revoke_console_permissions (self);
ef3d3d
 #endif
ef3d3d
 
ef3d3d
                 self->priv->session_is_running = FALSE;
ef3d3d
         }
ef3d3d
 
ef3d3d
         if (self->priv->session != NULL) {
ef3d3d
                 gdm_session_close (self->priv->session);
ef3d3d
                 g_clear_object (&self->priv->session);
ef3d3d
         }
ef3d3d
 
ef3d3d
         if (self->priv->server != NULL) {
ef3d3d
                 gdm_server_stop (self->priv->server);
ef3d3d
                 g_clear_object (&self->priv->server);
ef3d3d
         }
ef3d3d
 
ef3d3d
         g_clear_object (&self->priv->accountsservice_proxy);
ef3d3d
 
ef3d3d
         return TRUE;
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
 gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass)
ef3d3d
 {
ef3d3d
         GObjectClass  *object_class = G_OBJECT_CLASS (klass);
ef3d3d
         GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
ef3d3d
 
ef3d3d
-        object_class->finalize = gdm_simple_slave_finalize;
ef3d3d
+        object_class->dispose = gdm_simple_slave_dispose;
ef3d3d
 
ef3d3d
         slave_class->start = gdm_simple_slave_start;
ef3d3d
         slave_class->stop = gdm_simple_slave_stop;
ef3d3d
         slave_class->open_session = gdm_simple_slave_open_session;
ef3d3d
         slave_class->open_reauthentication_channel = gdm_simple_slave_open_reauthentication_channel;
ef3d3d
         slave_class->open_reauthentication_channel_finish = gdm_simple_slave_open_reauthentication_channel_finish;
ef3d3d
 
ef3d3d
         g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
 gdm_simple_slave_init (GdmSimpleSlave *slave)
ef3d3d
 {
ef3d3d
         slave->priv = GDM_SIMPLE_SLAVE_GET_PRIVATE (slave);
ef3d3d
 #ifdef  HAVE_LOGINDEVPERM
ef3d3d
         slave->priv->use_logindevperm = FALSE;
ef3d3d
 #endif
ef3d3d
 
ef3d3d
         slave->priv->open_reauthentication_requests = g_hash_table_new_full (NULL,
ef3d3d
                                                                              NULL,
ef3d3d
                                                                              (GDestroyNotify)
ef3d3d
                                                                              NULL,
ef3d3d
                                                                              (GDestroyNotify)
ef3d3d
                                                                              g_object_unref);
ef3d3d
 }
ef3d3d
 
ef3d3d
 static void
ef3d3d
-gdm_simple_slave_finalize (GObject *object)
ef3d3d
+gdm_simple_slave_dispose (GObject *object)
ef3d3d
 {
ef3d3d
         GdmSimpleSlave *slave;
ef3d3d
 
ef3d3d
         g_return_if_fail (object != NULL);
ef3d3d
         g_return_if_fail (GDM_IS_SIMPLE_SLAVE (object));
ef3d3d
 
ef3d3d
         slave = GDM_SIMPLE_SLAVE (object);
ef3d3d
 
ef3d3d
         g_return_if_fail (slave->priv != NULL);
ef3d3d
 
ef3d3d
         gdm_slave_stop (GDM_SLAVE (slave));
ef3d3d
 
ef3d3d
-        g_hash_table_unref (slave->priv->open_reauthentication_requests);
ef3d3d
+        g_clear_pointer (&slave->priv->open_reauthentication_requests,
ef3d3d
+                         g_hash_table_unref);
ef3d3d
 
ef3d3d
         if (slave->priv->greeter_reset_id > 0) {
ef3d3d
                 g_source_remove (slave->priv->greeter_reset_id);
ef3d3d
                 slave->priv->greeter_reset_id = 0;
ef3d3d
         }
ef3d3d
-
ef3d3d
-        G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object);
ef3d3d
 }
ef3d3d
 
ef3d3d
 GdmSlave *
ef3d3d
 gdm_simple_slave_new (const char *id)
ef3d3d
 {
ef3d3d
         GObject *object;
ef3d3d
 
ef3d3d
         object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
ef3d3d
                                "display-id", id,
ef3d3d
                                NULL);
ef3d3d
 
ef3d3d
         return GDM_SLAVE (object);
ef3d3d
 }
ef3d3d
-- 
ef3d3d
1.8.3.1
ef3d3d
ef3d3d
ef3d3d
From dc48d7c3fd45f0c8d623f7766438a5f86e212125 Mon Sep 17 00:00:00 2001
ef3d3d
From: Ray Strode <rstrode@redhat.com>
ef3d3d
Date: Mon, 6 Oct 2014 11:02:50 -0400
ef3d3d
Subject: [PATCH 4/4] systemd: change to KillMode=process
ef3d3d
ef3d3d
By default systemd will kill the entire control-group in one fell
ef3d3d
swoop.  The problem is, things don't get shutdown in the right
ef3d3d
order then, and there's a race where GDM will being restarting
ef3d3d
X servers and slaves as soon as they're killed.
ef3d3d
ef3d3d
This mucks with shutdown.
ef3d3d
---
ef3d3d
 data/gdm.service.in | 1 +
ef3d3d
 1 file changed, 1 insertion(+)
ef3d3d
ef3d3d
diff --git a/data/gdm.service.in b/data/gdm.service.in
ef3d3d
index 29eea4f..a92c745 100644
ef3d3d
--- a/data/gdm.service.in
ef3d3d
+++ b/data/gdm.service.in
ef3d3d
@@ -1,17 +1,18 @@
ef3d3d
 [Unit]
ef3d3d
 Description=GNOME Display Manager
ef3d3d
 Conflicts=getty@tty@GDM_INITIAL_VT@.service plymouth-quit.service
ef3d3d
 After=systemd-user-sessions.service getty@tty@GDM_INITIAL_VT@.service plymouth-quit.service
ef3d3d
 
ef3d3d
 [Service]
ef3d3d
 ExecStart=@sbindir@/gdm
ef3d3d
 ExecStartPost=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1"
ef3d3d
 ExecStop=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1"
ef3d3d
+KillMode=process
ef3d3d
 Restart=always
ef3d3d
 IgnoreSIGPIPE=no
ef3d3d
 BusName=org.gnome.DisplayManager
ef3d3d
 StandardOutput=syslog
ef3d3d
 StandardError=inherit
ef3d3d
 
ef3d3d
 [Install]
ef3d3d
 Alias=display-manager.service
ef3d3d
-- 
ef3d3d
1.8.3.1
ef3d3d