summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-05-27 22:41:55 +0200
committerLudovic Courtès <ludo@gnu.org>2022-05-28 23:23:36 +0200
commitf383838a091835b86d4a6ff1c256498bcdecadad (patch)
tree362738a6238c317e7e668cc0de778f12cb2985f7 /gnu
parentb04ae71defe0bd2a5fbd2df07d55cfe3eb40cba9 (diff)
services: elogind: When started by dbus-daemon, wait for the Shepherd service.
Fixes <https://issues.guix.gnu.org/55444>. Previously shepherd and dbus-daemon would race to start elogind. In some cases (for instance if one logs in quickly enough on the tty), dbus-daemon would "win" and start elogind before shepherd has had a chance to do it. Consequently, shepherd would fail to start elogind and mark it as stopped and disabled, in turn preventing services that depend on it such as 'xorg-server' from starting. * gnu/services/desktop.scm (elogind-dbus-service): Rewrite to refer to a wrapper that waits for the 'elogind' Shepherd service.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/services/desktop.scm58
1 files changed, 54 insertions, 4 deletions
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index 24fd43a207..0499071436 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -1075,10 +1075,60 @@ include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
(define (elogind-dbus-service config)
- (list (wrapped-dbus-service (elogind-package config)
- "libexec/elogind/elogind"
- `(("ELOGIND_CONF_FILE"
- ,(elogind-configuration-file config))))))
+ "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to
+\"start\" elogind. In practice though, our elogind is started when booting by
+shepherd. Thus, the @code{Exec} line of this @file{.service} file does not
+explain how to start elogind; instead, it spawns a wrapper that waits for the
+@code{elogind} shepherd service. This avoids a race condition where both
+@command{shepherd} and @command{dbus-daemon} would attempt to start elogind."
+ ;; For more info on the elogind startup race, see
+ ;; <https://issues.guix.gnu.org/55444>.
+
+ (define elogind
+ (elogind-package config))
+
+ (define wrapper
+ (program-file "elogind-dbus-shepherd-sync"
+ (with-imported-modules '((gnu services herd))
+ #~(begin
+ (use-modules (gnu services herd)
+ (srfi srfi-34))
+
+ (guard (c ((service-not-found-error? c)
+ (format (current-error-port)
+ "no elogind shepherd service~%")
+ (exit 1))
+ ((shepherd-error? c)
+ (format (current-error-port)
+ "elogind shepherd service not \
+started~%")
+ (exit 2)))
+ (wait-for-service 'elogind))))))
+
+ (define build
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils)
+ (ice-9 match))
+
+ (define service-directory
+ "/share/dbus-1/system-services")
+
+ (mkdir-p (dirname (string-append #$output service-directory)))
+ (copy-recursively (string-append #$elogind service-directory)
+ (string-append #$output service-directory))
+ (symlink (string-append #$elogind "/etc") ;for etc/dbus-1
+ (string-append #$output "/etc"))
+
+ ;; Replace the "Exec=" line of the 'org.freedesktop.login1.service'
+ ;; file with one that refers to WRAPPER instead of elogind.
+ (match (find-files #$output "\\.service$")
+ ((file)
+ (substitute* file
+ (("Exec[[:blank:]]*=.*" _)
+ (string-append "Exec=" #$wrapper "\n"))))))))
+
+ (list (computed-file "elogind-dbus-service-wrapper" build)))
(define (pam-extension-procedure config)
"Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM