summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2019-10-04 17:09:18 +0200
committerBenjamin Berg <bberg@redhat.com>2019-10-04 17:11:34 +0200
commit20948032bafe839d95bbf48c78cf45bc40fde8d9 (patch)
treee313e4831955e5eab37a7d5d8a7e90f42694af70
parent14abdd1bcfc1c96c2cfe16f8995a59972ee2999a (diff)
downloadgnome-session-benzea/systemd-issue-35.tar.gz
Delay XDG autostart applications on systemdbenzea/systemd-issue-35
When launching on systemd we did not synchronize the phases after the shell is loaded. Due to this, applications may start up before g-s-d is started, which should not be the case. Add a further one-way synchronization point so that gnome-session only starts launching applications after gnome-session.target has been reached. Fixes: #35
-rw-r--r--data/gnome-session-initialized.target4
-rw-r--r--data/gnome-session-manager@.service.in2
-rw-r--r--data/gnome-session-signal-phase@.service.in (renamed from data/gnome-session-signal-init.service.in)2
-rw-r--r--data/gnome-session.target6
-rw-r--r--data/meson.build2
-rw-r--r--gnome-session/gsm-manager.c58
-rw-r--r--gnome-session/org.gnome.SessionManager.xml9
-rw-r--r--tools/gnome-session-ctl.c16
8 files changed, 63 insertions, 36 deletions
diff --git a/data/gnome-session-initialized.target b/data/gnome-session-initialized.target
index 3ef2ecfe..959a83c0 100644
--- a/data/gnome-session-initialized.target
+++ b/data/gnome-session-initialized.target
@@ -15,5 +15,5 @@ Before=gnome-session.target
# Signal gnome-session that we reached the initialized target and
# that it may start applications.
-Requires=gnome-session-signal-init.service
-Before=gnome-session-signal-init.service
+Requires=gnome-session-signal-phase@4.service
+Before=gnome-session-signal-phase@4.service
diff --git a/data/gnome-session-manager@.service.in b/data/gnome-session-manager@.service.in
index b06dbeb3..13bfc73d 100644
--- a/data/gnome-session-manager@.service.in
+++ b/data/gnome-session-manager@.service.in
@@ -15,5 +15,5 @@ Before=gnome-session-manager.target
[Service]
Type=notify
-ExecStart=@libexecdir@/gnome-session-binary --systemd-service --session=%i
+ExecStart=@libexecdir@/gnome-session-binary --systemd-service --debug --session=%i
ExecStopPost=-@libexecdir@/gnome-session-ctl --shutdown
diff --git a/data/gnome-session-signal-init.service.in b/data/gnome-session-signal-phase@.service.in
index e3d2c463..84c40b55 100644
--- a/data/gnome-session-signal-init.service.in
+++ b/data/gnome-session-signal-phase@.service.in
@@ -5,4 +5,4 @@ PartOf=gnome-session.target
[Service]
Type=oneshot
-ExecStart=@libexecdir@/gnome-session-ctl --signal-init
+ExecStart=@libexecdir@/gnome-session-ctl --signal-phase=%I
diff --git a/data/gnome-session.target b/data/gnome-session.target
index 55cfc751..ba7ba3f4 100644
--- a/data/gnome-session.target
+++ b/data/gnome-session.target
@@ -14,5 +14,11 @@ Before=graphical-session.target
BindsTo=gnome-session-monitor.service
After=gnome-session-monitor.service
+# Signal gnome-session that the desktop is fully loaded at this point.
+# Note that this signal is one-way only and prevents XDG autostart
+# applications from loading early.
+Requires=gnome-session-signal-phase@7.service
+Before=gnome-session-signal-phase@7.service
+
# Pull in timer to mark session as stable (and unstable as long as the timer is active)
Requires=gnome-session-stable.timer
diff --git a/data/meson.build b/data/meson.build
index ef35c494..647483a3 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -100,7 +100,7 @@ if enable_systemd_session
systemd_userunitdir = join_paths(session_prefix, 'lib', 'systemd', 'user')
systemd_service = ['gnome-session-manager@.service',
- 'gnome-session-signal-init.service',
+ 'gnome-session-signal-phase@.service',
'gnome-session-restart-dbus.service',
'gnome-session-monitor.service',
'gnome-session-failed.service']
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index d41bdcac..1e1a1ed3 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -126,8 +126,8 @@ struct GsmManagerPrivate
{
gboolean failsafe;
gboolean systemd_managed;
- gboolean systemd_initialized;
- gboolean manager_initialized;
+ gint systemd_phase;
+ gboolean manager_waiting_systemd;
GsmStore *clients;
GsmStore *inhibitors;
GsmInhibitorFlag inhibited_actions;
@@ -540,16 +540,24 @@ end_phase (GsmManager *manager)
case GSM_MANAGER_PHASE_DISPLAY_SERVER:
break;
case GSM_MANAGER_PHASE_INITIALIZATION:
- manager->priv->manager_initialized = TRUE;
- /* Wait for systemd if it isn't initialized yet*/
- if (manager->priv->systemd_managed && !manager->priv->systemd_initialized) {
+ /* Wait for systemd to reach the same state */
+ if (manager->priv->systemd_managed && manager->priv->systemd_phase < GSM_MANAGER_PHASE_INITIALIZATION) {
sd_notify (0, "STATUS=GNOME Session Manager waiting for gnome-session-initialized.target (via signal)");
+ manager->priv->manager_waiting_systemd = TRUE;
start_next_phase = FALSE;
}
break;
case GSM_MANAGER_PHASE_WINDOW_MANAGER:
case GSM_MANAGER_PHASE_PANEL:
+ break;
case GSM_MANAGER_PHASE_DESKTOP:
+ /* Wait for systemd to reach the same state */
+ if (manager->priv->systemd_managed && manager->priv->systemd_phase < GSM_MANAGER_PHASE_APPLICATION) {
+ sd_notify (0, "STATUS=GNOME Session Manager waiting for gnome-session.target (via signal)");
+ manager->priv->manager_waiting_systemd = TRUE;
+ start_next_phase = FALSE;
+ }
+ break;
case GSM_MANAGER_PHASE_APPLICATION:
break;
case GSM_MANAGER_PHASE_RUNNING:
@@ -2676,36 +2684,44 @@ gsm_manager_setenv (GsmExportedManager *skeleton,
}
static gboolean
-gsm_manager_initialized (GsmExportedManager *skeleton,
- GDBusMethodInvocation *invocation,
- GsmManager *manager)
+gsm_manager_systemd_phase (GsmExportedManager *skeleton,
+ GDBusMethodInvocation *invocation,
+ gint phase_done,
+ GsmManager *manager)
{
- /* Signaled by helper when gnome-session-initialized.target is reached. */
+ /* Signaled by helper when gnome-session-initialized.target
+ * or gnome-session.target are reached. */
if (!manager->priv->systemd_managed) {
g_dbus_method_invocation_return_error (invocation,
GSM_MANAGER_ERROR,
GSM_MANAGER_ERROR_GENERAL,
"Initialized interface is only available when gnome-session is managed by systemd");
- } else if (manager->priv->systemd_initialized) {
+ } else if (manager->priv->systemd_phase >= phase_done) {
g_dbus_method_invocation_return_error (invocation,
GSM_MANAGER_ERROR,
GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
- "Systemd initialization was already signaled");
- } else if (manager->priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
+ "Systemd already signalled equal or higher phase");
+ } else if (manager->priv->phase > GSM_MANAGER_PHASE_DESKTOP) {
g_dbus_method_invocation_return_error (invocation,
GSM_MANAGER_ERROR,
GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
"Initialized interface is only available during startup");
} else {
- manager->priv->systemd_initialized = TRUE;
-
- if (manager->priv->manager_initialized) {
- g_assert (manager->priv->phase == GSM_MANAGER_PHASE_INITIALIZATION);
- manager->priv->phase++;
- start_phase (manager);
+ manager->priv->systemd_phase = phase_done;
+ g_debug ("Systemd startup signalled phase %i as reached, waiting: %i, internal phase: %i",
+ phase_done,
+ manager->priv->manager_waiting_systemd,
+ manager->priv->systemd_phase);
+
+ if (manager->priv->manager_waiting_systemd) {
+ if (manager->priv->phase <= manager->priv->systemd_phase) {
+ manager->priv->manager_waiting_systemd = FALSE;
+ manager->priv->phase++;
+ start_phase (manager);
+ }
}
- gsm_exported_manager_complete_initialized (skeleton, invocation);
+ gsm_exported_manager_complete_phase_done (skeleton, invocation);
}
return TRUE;
@@ -3308,8 +3324,8 @@ register_manager (GsmManager *manager)
G_CALLBACK (gsm_manager_set_reboot_to_firmware_setup), manager);
g_signal_connect (skeleton, "handle-setenv",
G_CALLBACK (gsm_manager_setenv), manager);
- g_signal_connect (skeleton, "handle-initialized",
- G_CALLBACK (gsm_manager_initialized), manager);
+ g_signal_connect (skeleton, "handle-phase-done",
+ G_CALLBACK (gsm_manager_systemd_phase), manager);
g_signal_connect (skeleton, "handle-shutdown",
G_CALLBACK (gsm_manager_shutdown), manager);
g_signal_connect (skeleton, "handle-uninhibit",
diff --git a/gnome-session/org.gnome.SessionManager.xml b/gnome-session/org.gnome.SessionManager.xml
index ce4b8c07..be792306 100644
--- a/gnome-session/org.gnome.SessionManager.xml
+++ b/gnome-session/org.gnome.SessionManager.xml
@@ -59,10 +59,15 @@
</doc:doc>
</method>
- <method name="Initialized">
+ <method name="PhaseDone">
+ <arg type="i" name="phase" direction="in">
+ <doc:doc>
+ <doc:summary>The reached phase, must be 4 or 7 for the Initialization or Desktop phases</doc:summary>
+ </doc:doc>
+ </arg>
<doc:doc>
<doc:description>
- <doc:para>Run from systemd to signal that gnome-session-initialized.target has been reached.</doc:para>
+ <doc:para>Run from systemd to signal that gnome-session-initialized.target or gnome-session.target have been reached.</doc:para>
</doc:description>
</doc:doc>
</method>
diff --git a/tools/gnome-session-ctl.c b/tools/gnome-session-ctl.c
index 9276a0ad..7f46955c 100644
--- a/tools/gnome-session-ctl.c
+++ b/tools/gnome-session-ctl.c
@@ -59,7 +59,7 @@ get_session_bus (void)
}
static void
-do_signal_init (void)
+do_signal_phase (gint opt_signal_phase)
{
g_autoptr(GDBusConnection) connection = NULL;
g_autoptr(GVariant) reply = NULL;
@@ -73,8 +73,8 @@ do_signal_init (void)
GSM_SERVICE_DBUS,
GSM_PATH_DBUS,
GSM_INTERFACE_DBUS,
- "Initialized",
- NULL,
+ "PhaseDone",
+ g_variant_new ("(i)", opt_signal_phase),
NULL,
G_DBUS_CALL_FLAGS_NO_AUTO_START,
-1, NULL, &error);
@@ -236,14 +236,14 @@ main (int argc, char *argv[])
g_autoptr(GError) error = NULL;
static gboolean opt_shutdown;
static gboolean opt_monitor;
- static gboolean opt_signal_init;
+ static gint opt_signal_phase;
static gboolean opt_restart_dbus;
int conflicting_options;
GOptionContext *ctx;
static const GOptionEntry options[] = {
{ "shutdown", '\0', 0, G_OPTION_ARG_NONE, &opt_shutdown, N_("Start gnome-session-shutdown.target"), NULL },
{ "monitor", '\0', 0, G_OPTION_ARG_NONE, &opt_monitor, N_("Start gnome-session-shutdown.target when receiving EOF or a single byte on stdin"), NULL },
- { "signal-init", '\0', 0, G_OPTION_ARG_NONE, &opt_signal_init, N_("Signal initialization done to gnome-session"), NULL },
+ { "signal-phase", '\0', 0, G_OPTION_ARG_INT, &opt_signal_phase, N_("Signal finished phase to gnome-session"), NULL },
{ "restart-dbus", '\0', 0, G_OPTION_ARG_NONE, &opt_restart_dbus, N_("Restart dbus.service if it is running"), NULL },
{ NULL },
};
@@ -267,7 +267,7 @@ main (int argc, char *argv[])
conflicting_options++;
if (opt_monitor)
conflicting_options++;
- if (opt_signal_init)
+ if (opt_signal_phase)
conflicting_options++;
if (opt_restart_dbus)
conflicting_options++;
@@ -278,8 +278,8 @@ main (int argc, char *argv[])
sd_notify (0, "READY=1");
- if (opt_signal_init) {
- do_signal_init ();
+ if (opt_signal_phase) {
+ do_signal_phase (opt_signal_phase);
} else if (opt_restart_dbus) {
do_restart_dbus ();
} else if (opt_shutdown) {