From 85ea6bed8c994eae9891af1a2fba0e99aa1c3031 Mon Sep 17 00:00:00 2001 From: Mart Raudsepp Date: Wed, 27 Mar 2019 10:37:19 +0200 Subject: gnome-base/gdm: wait for graphics DRM master with systemd gdm currently lacks code to properly wait for the CanGraphical property on a logind seat to switch to "Yes" before gnome-shell is started for the login VT. This is a problem, especially with wayland enabled, when the graphics system isn't fully initialized by the time gdm is started in parallel, because gnome-shell will fail to start graphics and gdm will retry with a X session, which likely succeeds at that point. This unexpectedly ends up in a gdm Xorg session, instead of a gdm Wayland session, which won't be able to start Wayland sessions, or reap itself for memory savings once logged in, etc. For systemd we can grab a workaround used by Ubuntu, which adds an ExecStartPre command to the gdm service, that waits for the DRM master to appear (with a 10 seconds safety fallback) before letting gdm itself start up. For OpenRC this is not effective, but combined with usually slower startup of the system with OpenRC, and xdm service usually starting at the very end (compared to rather early in parallel with systemd) due to various service rules, it should be much more unlikely to be a problem for OpenRC systems, or even impossible if something in init deps ends up waiting for udev to settle. Eventually, in a future release, there should be upstream gdm full CanGraphical waiting on its own, which should solve any OpenRC issues as well, provided that in-use elogind handles CanGraphical correctly (there have been issues in systemd code too). Bug: https://bugs.gentoo.org/613222 Package-Manager: Portage-2.3.52, Repoman-2.3.12 Signed-off-by: Mart Raudsepp --- gnome-base/gdm/files/gdm-CanGraphical-wait.patch | 189 +++++++++++++++++++ gnome-base/gdm/gdm-3.30.3-r2.ebuild | 228 +++++++++++++++++++++++ 2 files changed, 417 insertions(+) create mode 100644 gnome-base/gdm/files/gdm-CanGraphical-wait.patch create mode 100644 gnome-base/gdm/gdm-3.30.3-r2.ebuild diff --git a/gnome-base/gdm/files/gdm-CanGraphical-wait.patch b/gnome-base/gdm/files/gdm-CanGraphical-wait.patch new file mode 100644 index 000000000000..206219d8e059 --- /dev/null +++ b/gnome-base/gdm/files/gdm-CanGraphical-wait.patch @@ -0,0 +1,189 @@ +From 198d6392ff595f330430d92d5c380cd993be73d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 16 Oct 2018 20:59:23 +0200 +Subject: [PATCH] gdm3.service: wait for drm device before trying to start it + +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gdm3/+bug/1794280 +Forwarded: not-needed +--- + configure.ac | 1 + + data/Makefile.am | 1 + + data/gdm.service.in | 1 + + utils/Makefile.am | 9 ++++ + utils/gdm-wait-for-drm.c | 101 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 113 insertions(+) + create mode 100644 utils/gdm-wait-for-drm.c + +diff --git a/configure.ac b/configure.ac +index a8dcfbef..2755c100 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -76,6 +76,7 @@ PKG_CHECK_MODULES(COMMON, + gobject-2.0 >= $GLIB_REQUIRED_VERSION + gio-2.0 >= $GLIB_REQUIRED_VERSION + gio-unix-2.0 >= $GLIB_REQUIRED_VERSION ++ gudev-1.0 + ) + AC_SUBST(COMMON_CFLAGS) + AC_SUBST(COMMON_LIBS) +diff --git a/data/Makefile.am b/data/Makefile.am +index 162074f1..5f426fea 100644 +--- a/data/Makefile.am ++++ b/data/Makefile.am +@@ -204,6 +204,7 @@ systemdsystemunit = + gdm.service: $(srcdir)/gdm.service.in + $(AM_V_GEN)sed \ + -e 's,[@]sbindir[@],$(sbindir),g' \ ++ -e 's,[@]libexecdir[@],$(libexecdir),g' \ + -e 's,[@]GDM_INITIAL_VT[@],$(GDM_INITIAL_VT),g' \ + -e 's,[@]LANG_CONFIG_FILE[@],$(LANG_CONFIG_FILE),g' \ + -e 's,[@]PLYMOUTH_QUIT_SERVICE[@],$(PLYMOUTH_QUIT_SERVICE),g' \ +diff --git a/data/gdm.service.in b/data/gdm.service.in +index 57d60ada..f7630ec4 100644 +--- a/data/gdm.service.in ++++ b/data/gdm.service.in +@@ -30,6 +30,7 @@ StandardError=inherit + EnvironmentFile=-@LANG_CONFIG_FILE@ + ExecReload=/bin/kill -SIGHUP $MAINPID + KeyringMode=shared ++ExecStartPre=@libexecdir@/gdm-wait-for-drm + + [Install] + Alias=display-manager.service +diff --git a/utils/Makefile.am b/utils/Makefile.am +index babe890b..3eb43c30 100644 +--- a/utils/Makefile.am ++++ b/utils/Makefile.am +@@ -35,6 +35,7 @@ bin_PROGRAMS = \ + + libexec_PROGRAMS = \ + gdm-disable-wayland \ ++ gdm-wait-for-drm \ + $(NULL) + + gdmflexiserver_LDADD = \ +@@ -63,6 +64,14 @@ gdm_disable_wayland_SOURCES = \ + gdm-disable-wayland.c \ + $(NULL) + ++gdm_wait_for_drm_LDADD = \ ++ $(COMMON_LIBS) \ ++ $(NULL) ++ ++gdm_wait_for_drm_SOURCES = \ ++ gdm-wait-for-drm.c \ ++ $(NULL) ++ + CLEANFILES = \ + $(NULL) + +diff --git a/utils/gdm-wait-for-drm.c b/utils/gdm-wait-for-drm.c +new file mode 100644 +index 00000000..aeffb3c0 +--- /dev/null ++++ b/utils/gdm-wait-for-drm.c +@@ -0,0 +1,101 @@ ++#include ++#include ++ ++/* ++ * Workaround for LP: #1794280. ++ * ++ * That bug is because the DRM device isn't ready by the time GDM tries to ++ * start wayland/X. ++ * This is a script to add to ExecStartPre of gdm.service. It does the ++ * following: ++ * ++ * 1. Enumerate drm devices from udev, looking for a DRM master. If found, ++ * exit. ++ * 2. Connect to the 'uevent' signal of gudev, watching for the same to be ++ * added. Again exit if any are found. ++ * 3. If, after 10 seconds, we haven't seen anything, try to proceed anyway as ++ * a failsafe. ++ */ ++ ++static gboolean ++handle_device (GUdevDevice *device) ++{ ++ const gchar * const * tags; ++ tags = g_udev_device_get_tags (device); ++ g_debug ("%s\n", g_udev_device_get_name (device)); ++ if (g_strv_contains (tags, "master-of-seat")) ++ { ++ g_debug (" is seat master\n"); ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++static void ++uevent_cb (GUdevClient *client G_GNUC_UNUSED, ++ gchar *action, ++ GUdevDevice *device, ++ gpointer user_data) ++{ ++ GMainLoop *loop; ++ ++ g_debug ("uevent action: %s\n", action); ++ ++ loop = (GMainLoop *) user_data; ++ ++ if (g_strcmp0 (action, "add") == 0) ++ { ++ if (handle_device (device)) ++ { ++ g_debug (" this is good\n"); ++ g_main_loop_quit (loop); ++ } ++ else ++ { ++ g_debug (" this is bad\n"); ++ } ++ } ++} ++ ++int ++main() ++{ ++ const gchar * const subsystems[] = { "drm", NULL }; ++ ++ g_autoptr(GList) devices = NULL; ++ g_autoptr(GMainLoop) loop = NULL; ++ g_autoptr(GUdevClient) udev_client = NULL; ++ g_autoptr(GUdevEnumerator) enumerator = NULL; ++ ++ loop = g_main_loop_new (NULL, FALSE); ++ ++ udev_client = g_udev_client_new (subsystems); ++ enumerator = g_udev_enumerator_new (udev_client); ++ g_udev_enumerator_add_match_is_initialized (enumerator); ++ g_udev_enumerator_add_match_subsystem (enumerator, "drm"); ++ ++ devices = g_udev_enumerator_execute (enumerator); ++ ++ g_debug ("enumerating devices...\n"); ++ ++ for (GList *l = devices; l != NULL; l = l->next) ++ { ++ g_autoptr(GUdevDevice) device = G_UDEV_DEVICE (l->data); ++ ++ if (handle_device (device)) ++ { ++ g_debug (" good enough for gdm\n"); ++ return EXIT_SUCCESS; ++ } ++ } ++ ++ g_signal_connect (udev_client, "uevent", G_CALLBACK (uevent_cb), loop); ++ ++ /* after 10 seconds we try anyway */ ++ g_timeout_add_seconds (10, (GSourceFunc) g_main_loop_quit, loop); ++ ++ g_main_loop_run (loop); ++ ++ return EXIT_SUCCESS; ++} +-- +2.17.0 + diff --git a/gnome-base/gdm/gdm-3.30.3-r2.ebuild b/gnome-base/gdm/gdm-3.30.3-r2.ebuild new file mode 100644 index 000000000000..7acebf2d3d85 --- /dev/null +++ b/gnome-base/gdm/gdm-3.30.3-r2.ebuild @@ -0,0 +1,228 @@ +# Copyright 1999-2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +GNOME2_LA_PUNT="yes" +GNOME2_EAUTORECONF="yes" + +inherit eutils gnome2 pam readme.gentoo-r1 systemd udev user + +DESCRIPTION="GNOME Display Manager for managing graphical display servers and user logins" +HOMEPAGE="https://wiki.gnome.org/Projects/GDM" + +SRC_URI="${SRC_URI} + branding? ( https://www.mail-archive.com/tango-artists@lists.freedesktop.org/msg00043/tango-gentoo-v1.1.tar.gz ) +" + +LICENSE=" + GPL-2+ + branding? ( CC-BY-SA-4.0 ) +" + +SLOT="0" + +IUSE="accessibility audit branding elogind fprint +introspection ipv6 plymouth selinux smartcard systemd tcpd test wayland xinerama" +REQUIRED_USE="^^ ( elogind systemd )" + +KEYWORDS="~alpha ~amd64 ~arm ~ia64 ~ppc ~ppc64 ~sh ~x86" + +# NOTE: x11-base/xorg-server dep is for X_SERVER_PATH etc, bug #295686 +# nspr used by smartcard extension +# dconf, dbus and g-s-d are needed at install time for dconf update +# We need either systemd or >=openrc-0.12 to restart gdm properly, bug #463784 +COMMON_DEPEND=" + app-text/iso-codes + >=dev-libs/glib-2.44:2 + dev-libs/libgudev + >=x11-libs/gtk+-2.91.1:3 + >=gnome-base/dconf-0.20 + >=gnome-base/gnome-settings-daemon-3.1.4 + gnome-base/gsettings-desktop-schemas + >=media-libs/fontconfig-2.5.0:1.0 + >=media-libs/libcanberra-0.4[gtk3] + sys-apps/dbus + >=sys-apps/accountsservice-0.6.35 + + x11-base/xorg-server + x11-libs/libXau + x11-libs/libX11 + x11-libs/libXdmcp + x11-libs/libXext + x11-libs/libxcb + >=x11-misc/xdg-utils-1.0.2-r3 + + virtual/pam + elogind? ( >=sys-auth/elogind-239.3[pam] ) + systemd? ( >=sys-apps/systemd-186:0=[pam] ) + + sys-auth/pambase[elogind?,systemd?] + + audit? ( sys-process/audit ) + introspection? ( >=dev-libs/gobject-introspection-0.9.12:= ) + plymouth? ( sys-boot/plymouth ) + selinux? ( sys-libs/libselinux ) + tcpd? ( >=sys-apps/tcp-wrappers-7.6 ) + xinerama? ( x11-libs/libXinerama ) +" +# XXX: These deps are from session and desktop files in data/ directory +# fprintd is used via dbus by gdm-fingerprint-extension +# gnome-session-3.6 needed to avoid freezing with orca +RDEPEND="${COMMON_DEPEND} + >=gnome-base/gnome-session-3.6 + >=gnome-base/gnome-shell-3.1.90 + x11-apps/xhost + + accessibility? ( + >=app-accessibility/orca-3.10 + gnome-extra/mousetweaks ) + fprint? ( + sys-auth/fprintd + sys-auth/pam_fprint ) + + !gnome-extra/fast-user-switch-applet +" +DEPEND="${COMMON_DEPEND} + app-text/docbook-xml-dtd:4.1.2 + dev-util/gdbus-codegen + dev-util/glib-utils + dev-util/itstool + >=sys-devel/gettext-0.19.8 + virtual/pkgconfig + x11-base/xorg-proto + test? ( >=dev-libs/check-0.9.4 ) + app-text/yelp-tools +" # yelp-tools needed for eautoreconf to not lose help docs (m4_ifdeffed YELP_HELP_INIT call and setup) + +DOC_CONTENTS=" + To make GDM start at boot with systemd, run:\n + # systemctl enable gdm.service\n + \n + To make GDM start at boot with OpenRC, edit /etc/conf.d to have + DISPLAYMANAGER=\"gdm\" and enable the xdm service:\n + # rc-update add xdm + \n + For passwordless login to unlock your keyring, you need to install + sys-auth/pambase with USE=gnome-keyring and set an empty password + on your keyring. Use app-crypt/seahorse for that.\n + \n + You may need to install app-crypt/coolkey and sys-auth/pam_pkcs11 + for smartcard support +" + +pkg_setup() { + enewgroup gdm + enewgroup video # Just in case it hasn't been created yet + enewuser gdm -1 -1 /var/lib/gdm gdm,video + + # For compatibility with certain versions of nvidia-drivers, etc., need to + # ensure that gdm user is in the video group + if ! egetent group video | grep -q gdm; then + # FIXME XXX: is this at all portable, ldap-safe, etc.? + # XXX: egetent does not have a 1-argument form, so we can't use it to + # get the list of gdm's groups + local g=$(groups gdm) + elog "Adding user gdm to video group" + usermod -G video,${g// /,} gdm || die "Adding user gdm to video group failed" + fi +} + +src_prepare() { + # ssh-agent handling must be done at xinitrc.d, bug #220603 + eapply "${FILESDIR}/${PN}-2.32.0-xinitrc-ssh-agent.patch" + + # Gentoo does not have a fingerprint-auth pam stack + eapply "${FILESDIR}/${PN}-3.8.4-fingerprint-auth.patch" + + # Drop legacy argument to pam_systemd.so, included in 3.32 + eapply "${FILESDIR}/${PV}-pam-drop-legacy-arg.patch" + # Support pam_elogind.so in gdm-launch-environment.pam + eapply "${FILESDIR}/pam-elogind.patch" + + # Wait 10 seconds for a DRM master with systemd. Workaround for gdm not waiting for CanGraphical=yes property on the seat. Bug #613222 + eapply "${FILESDIR}/gdm-CanGraphical-wait.patch" # needs eautoreconf + + # Show logo when branding is enabled + use branding && eapply "${FILESDIR}/${PN}-3.30.3-logo.patch" + + gnome2_src_prepare +} + +src_configure() { + # PAM is the only auth scheme supported + # even though configure lists shadow and crypt + # they don't have any corresponding code. + # --with-at-spi-registryd-directory= needs to be passed explicitly because + # of https://bugzilla.gnome.org/show_bug.cgi?id=607643#c4 + # Xevie is obsolete, bug #482304 + + # --with-initial-vt=7 conflicts with plymouth, bug #453392 + # gdm-3.30 now reaps (stops) the login screen when the login VT isn't active, which + # saves on memory. However this means if we don't start on VT1, gdm doesn't start up + # before user manually goes to VT7. Thus as-is we can not keep gdm away from VT1, + # so lets try always having it in VT1 and see if that is an issue for people before + # hacking up workarounds for the initial start case. + # ! use plymouth && myconf="${myconf} --with-initial-vt=7" + local myconf=( + --enable-gdm-xsession + --enable-user-display-server + --with-run-dir=/run/gdm + --localstatedir="${EPREFIX}"/var + --disable-static + --with-xdmcp=yes + --enable-authentication-scheme=pam + --with-default-pam-config=exherbo + --with-pam-mod-dir=$(getpam_mod_dir) + --with-udevdir=$(get_udevdir) + --with-at-spi-registryd-directory="${EPREFIX}"/usr/libexec + --without-xevie + $(use_enable systemd systemd-journal) + --with-systemdsystemunitdir="$(systemd_get_systemunitdir)" + $(use_with audit libaudit) + $(use_enable ipv6) + $(use_with plymouth) + $(use_with selinux) + $(use_with tcpd tcp-wrappers) + $(use_enable wayland wayland-support) + $(use_with xinerama) + ) + + if use elogind; then + myconf+=( + --with-initial-vt=7 # TODO: Revisit together with startDM.sh and other xinit talks; also ignores plymouth possibility + SYSTEMD_CFLAGS=`pkg-config --cflags "libelogind" 2>/dev/null` + SYSTEMD_LIBS=`pkg-config --libs "libelogind" 2>/dev/null` + ) + fi + + gnome2_src_configure "${myconf[@]}" +} + +src_install() { + gnome2_src_install + + if ! use accessibility ; then + rm "${ED}"/usr/share/gdm/greeter/autostart/orca-autostart.desktop || die + fi + + exeinto /etc/X11/xinit/xinitrc.d + newexe "${FILESDIR}/49-keychain-r1" 49-keychain + newexe "${FILESDIR}/50-ssh-agent-r1" 50-ssh-agent + + # gdm user's home directory + keepdir /var/lib/gdm + fowners gdm:gdm /var/lib/gdm + + # install XDG_DATA_DIRS gdm changes + echo 'XDG_DATA_DIRS="/usr/share/gdm"' > 99xdg-gdm + doenvd 99xdg-gdm + + use branding && newicon "${WORKDIR}/tango-gentoo-v1.1/scalable/gentoo.svg" gentoo-gdm.svg + + readme.gentoo_create_doc +} + +pkg_postinst() { + gnome2_pkg_postinst + systemd_reenable gdm.service + readme.gentoo_print_elog +} -- cgit v1.2.3