summaryrefslogtreecommitdiff
path: root/0001-local-display-factory-Stall-startup-until-main-graph.patch
diff options
context:
space:
mode:
Diffstat (limited to '0001-local-display-factory-Stall-startup-until-main-graph.patch')
-rw-r--r--0001-local-display-factory-Stall-startup-until-main-graph.patch729
1 files changed, 729 insertions, 0 deletions
diff --git a/0001-local-display-factory-Stall-startup-until-main-graph.patch b/0001-local-display-factory-Stall-startup-until-main-graph.patch
new file mode 100644
index 0000000..d88da45
--- /dev/null
+++ b/0001-local-display-factory-Stall-startup-until-main-graph.patch
@@ -0,0 +1,729 @@
+From e88779b0785fe781608b10478ae092e8fd79ae0b Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Tue, 1 Mar 2022 13:25:02 -0500
+Subject: [PATCH 1/4] local-display-factory: Stall startup until main graphics
+ card is ready
+
+At the moment, GDM waits until systemd says the system supports
+graphics (via the CanGraphical logind property).
+
+Unfortunately, this property isn't really what we need, since it flips
+to true when *any* graphics are available, not when the main graphics
+for the system are ready.
+
+This is a problem on hybrid graphics systems, if one card is slower to
+load than another. In particular, the vendor nvidia driver can be slow
+to load because it has multiple kernel modules it loads in series.
+
+Indeed on fast systems, that use the vendor nvidia driver, it's not
+unusual for boot to get to a point where all of userspace up to and
+including GDM is executed before the graphics are ready to go.
+
+This commit tries to mitigate the situation by adding an additional,
+check aside from CanGraphical to test if the system is ready.
+
+This check waits for the graphics card associated with boot to be fully
+up and running before proceeding to start a login screen.
+
+Closes: https://gitlab.gnome.org/GNOME/gdm/-/issues/763
+---
+ daemon/gdm-local-display-factory.c | 168 ++++++++++++++++++++++++++---
+ daemon/meson.build | 4 +
+ meson.build | 2 +
+ 3 files changed, 162 insertions(+), 12 deletions(-)
+
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index ca14c31f5..56be1d9db 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -1,100 +1,112 @@
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+ #include "config.h"
+
+ #include <stdlib.h>
+ #include <stdio.h>
+
+ #include <glib.h>
+ #include <glib/gi18n.h>
+ #include <glib-object.h>
+ #include <gio/gio.h>
+
++#ifdef HAVE_UDEV
++#include <gudev/gudev.h>
++#endif
++
+ #include <systemd/sd-login.h>
+
+ #include "gdm-common.h"
+ #include "gdm-manager.h"
+ #include "gdm-display-factory.h"
+ #include "gdm-local-display-factory.h"
+ #include "gdm-local-display-factory-glue.h"
+
+ #include "gdm-settings-keys.h"
+ #include "gdm-settings-direct.h"
+ #include "gdm-display-store.h"
+ #include "gdm-local-display.h"
+ #include "gdm-legacy-display.h"
+
+ #define GDM_DBUS_PATH "/org/gnome/DisplayManager"
+ #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory"
+ #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory"
+
+ #define MAX_DISPLAY_FAILURES 5
+ #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */
+ #define SEAT0_GRAPHICS_CHECK_TIMEOUT 10 /* seconds */
+
+ struct _GdmLocalDisplayFactory
+ {
+- GdmDisplayFactory parent;
++ GdmDisplayFactory parent;
++#ifdef HAVE_UDEV
++ GUdevClient *gudev_client;
++#endif
+
+ GdmDBusLocalDisplayFactory *skeleton;
+ GDBusConnection *connection;
+ GHashTable *used_display_numbers;
+
+ /* FIXME: this needs to be per seat? */
+ guint num_failures;
+
+ guint seat_new_id;
+ guint seat_removed_id;
+ guint seat_properties_changed_id;
+
++ gboolean seat0_has_platform_graphics;
++ gboolean seat0_has_boot_up_graphics;
++
+ gboolean seat0_graphics_check_timed_out;
+ guint seat0_graphics_check_timeout_id;
+
++ gulong uevent_handler_id;
++
+ #if defined(ENABLE_USER_DISPLAY_SERVER)
+ unsigned int active_vt;
+ guint active_vt_watch_id;
+ guint wait_to_finish_timeout_id;
+ #endif
+
+ gboolean is_started;
+ };
+
+ enum {
+ PROP_0,
+ };
+
+ static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass);
+ static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory);
+ static void gdm_local_display_factory_finalize (GObject *object);
+
+ static void ensure_display_for_seat (GdmLocalDisplayFactory *factory,
+ const char *seat_id);
+
+ static void on_display_status_changed (GdmDisplay *display,
+ GParamSpec *arg1,
+ GdmLocalDisplayFactory *factory);
+
+ static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory);
+ static gpointer local_display_factory_object = NULL;
+ static gboolean lookup_by_session_id (const char *id,
+ GdmDisplay *display,
+ gpointer user_data);
+
+@@ -594,142 +606,236 @@ lookup_by_seat_id (const char *id,
+ gpointer user_data)
+ {
+ const char *looking_for = user_data;
+ char *current;
+ gboolean res;
+
+ g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
+
+ res = g_strcmp0 (current, looking_for) == 0;
+
+ g_free(current);
+
+ return res;
+ }
+
+ static gboolean
+ lookup_prepared_display_by_seat_id (const char *id,
+ GdmDisplay *display,
+ gpointer user_data)
+ {
+ int status;
+
+ status = gdm_display_get_status (display);
+
+ if (status != GDM_DISPLAY_PREPARED)
+ return FALSE;
+
+ return lookup_by_seat_id (id, display, user_data);
+ }
+
++#ifdef HAVE_UDEV
++static gboolean
++udev_is_settled (GdmLocalDisplayFactory *factory)
++{
++ g_autoptr (GUdevEnumerator) enumerator = NULL;
++ GList *devices;
++ GList *node;
++
++ gboolean is_settled = FALSE;
++
++ if (factory->seat0_has_platform_graphics) {
++ g_debug ("GdmLocalDisplayFactory: udev settled, platform graphics enabled.");
++ return TRUE;
++ }
++
++ if (factory->seat0_has_boot_up_graphics) {
++ g_debug ("GdmLocalDisplayFactory: udev settled, boot up graphics available.");
++ return TRUE;
++ }
++
++ if (factory->seat0_graphics_check_timed_out) {
++ g_debug ("GdmLocalDisplayFactory: udev timed out, proceeding anyway.");
++ return TRUE;
++ }
++
++ g_debug ("GdmLocalDisplayFactory: Checking if udev has settled enough to support graphics.");
++
++ enumerator = g_udev_enumerator_new (factory->gudev_client);
++
++ g_udev_enumerator_add_match_name (enumerator, "card*");
++ g_udev_enumerator_add_match_tag (enumerator, "master-of-seat");
++ g_udev_enumerator_add_match_subsystem (enumerator, "drm");
++
++ devices = g_udev_enumerator_execute (enumerator);
++ if (!devices) {
++ g_debug ("GdmLocalDisplayFactory: udev has no candidate graphics devices available yet.");
++ return FALSE;
++ }
++
++ node = devices;
++ while (node != NULL) {
++ GUdevDevice *device = node->data;
++ GList *next_node = node->next;
++ g_autoptr (GUdevDevice) platform_device = NULL;
++ g_autoptr (GUdevDevice) pci_device = NULL;
++
++ platform_device = g_udev_device_get_parent_with_subsystem (device, "platform", NULL);
++
++ if (platform_device != NULL) {
++ g_debug ("GdmLocalDisplayFactory: Found embedded platform graphics, proceeding.");
++ factory->seat0_has_platform_graphics = TRUE;
++ is_settled = TRUE;
++ break;
++ }
++
++ pci_device = g_udev_device_get_parent_with_subsystem (device, "pci", NULL);
++
++ if (pci_device != NULL) {
++ gboolean boot_vga;
++
++ boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
++
++ if (boot_vga == 1) {
++ g_debug ("GdmLocalDisplayFactory: Found primary PCI graphics adapter, proceeding.");
++ factory->seat0_has_boot_up_graphics = TRUE;
++ is_settled = TRUE;
++ break;
++ } else {
++ g_debug ("GdmLocalDisplayFactory: Found secondary PCI graphics adapter, not proceeding yet.");
++ }
++ }
++ node = next_node;
++ }
++
++ g_debug ("GdmLocalDisplayFactory: udev has %ssettled enough for graphics.", is_settled? "" : "not ");
++ g_list_free_full (devices, g_object_unref);
++
++ if (is_settled)
++ g_clear_signal_handler (&factory->uevent_handler_id, factory->gudev_client);
++
++ return is_settled;
++}
++#endif
++
+ static int
+ on_seat0_graphics_check_timeout (gpointer user_data)
+ {
+ GdmLocalDisplayFactory *factory = user_data;
+
+ factory->seat0_graphics_check_timeout_id = 0;
+
+ /* Simply try to re-add seat0. If it is there already (i.e. CanGraphical
+ * turned TRUE, then we'll find it and it will not be created again).
+ */
+ factory->seat0_graphics_check_timed_out = TRUE;
+ ensure_display_for_seat (factory, "seat0");
+
+ return G_SOURCE_REMOVE;
+ }
+
+ static void
+ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
+ const char *seat_id)
+ {
+ int ret;
+ gboolean seat_supports_graphics;
+ gboolean is_seat0;
+ g_auto (GStrv) session_types = NULL;
+ const char *legacy_session_types[] = { "x11", NULL };
+ GdmDisplayStore *store;
+ GdmDisplay *display = NULL;
+ g_autofree char *login_session_id = NULL;
+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
+ g_autofree gchar *preferred_display_server = NULL;
+ gboolean falling_back = FALSE;
++ gboolean waiting_on_udev = FALSE;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
+
+ preferred_display_server = get_preferred_display_server (factory);
+
+ if (g_strcmp0 (preferred_display_server, "none") == 0) {
+ g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
+ return;
+ }
+
+- ret = sd_seat_can_graphical (seat_id);
++#ifdef HAVE_UDEV
++ waiting_on_udev = !udev_is_settled (factory);
++#endif
+
+- if (ret < 0) {
+- g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
+- return;
+- }
++ if (!waiting_on_udev) {
++ ret = sd_seat_can_graphical (seat_id);
+
+- if (ret == 0) {
+- g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
+- seat_supports_graphics = FALSE;
++ if (ret < 0) {
++ g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
++ return;
++ }
++
++ if (ret == 0) {
++ g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
++ seat_supports_graphics = FALSE;
++ } else {
++ g_debug ("GdmLocalDisplayFactory: System supports graphics");
++ seat_supports_graphics = TRUE;
++ }
+ } else {
+- g_debug ("GdmLocalDisplayFactory: System supports graphics");
+- seat_supports_graphics = TRUE;
++ g_debug ("GdmLocalDisplayFactory: udev is still settling, so not creating display yet");
++ seat_supports_graphics = FALSE;
+ }
+
+ if (g_strcmp0 (seat_id, "seat0") == 0) {
+ is_seat0 = TRUE;
+
+ falling_back = factory->num_failures > 0;
+ session_types = gdm_local_display_factory_get_session_types (factory, falling_back);
+
+ if (session_types == NULL) {
+ g_debug ("GdmLocalDisplayFactory: Both Wayland and Xorg are unavailable");
+ seat_supports_graphics = FALSE;
+ } else {
+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
+ session_types[0], falling_back? " fallback" : "");
+ }
+ } else {
+ is_seat0 = FALSE;
+
+ g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
+ /* Force legacy X11 for all auxiliary seats */
+ seat_supports_graphics = TRUE;
+ session_types = g_strdupv ((char **) legacy_session_types);
+ }
+
+ /* For seat0, we have a fallback logic to still try starting it after
+ * SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if
+- * CanGraphical is unset.
++ * CanGraphical is unset or udev otherwise never finds a suitable graphics card.
+ * This is ugly, but it means we'll come up eventually in some
+ * scenarios where no master device is present.
+ * Note that we'll force an X11 fallback even though there might be
+ * cases where an wayland capable device is present and simply not marked as
+ * master-of-seat. In these cases, this should likely be fixed in the
+ * udev rules.
+ *
+ * At the moment, systemd always sets CanGraphical for non-seat0 seats.
+ * This is because non-seat0 seats are defined by having master-of-seat
+ * set. This means we can avoid the fallback check for non-seat0 seats,
+ * which simplifies the code.
+ */
+ if (is_seat0) {
+ if (!seat_supports_graphics) {
+ if (!factory->seat0_graphics_check_timed_out) {
+ if (factory->seat0_graphics_check_timeout_id == 0) {
+ g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics. Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT);
+ factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT,
+ on_seat0_graphics_check_timeout,
+ factory);
+
+ } else {
+ /* It is not yet time to force X11 fallback. */
+ g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout.");
+ }
+
+ return;
+ }
+
+ g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
+@@ -1138,113 +1244,151 @@ on_vt_changed (GIOChannel *source,
+ if (factory->wait_to_finish_timeout_id != 0) {
+ g_debug ("GdmLocalDisplayFactory: deferring previous login screen clean up operation");
+ g_source_remove (factory->wait_to_finish_timeout_id);
+ }
+
+ factory->wait_to_finish_timeout_id = g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT,
+ (GSourceFunc)
+ on_finish_waiting_for_seat0_displays_timeout,
+ factory);
+ }
+ }
+ }
+
+ /* if user jumped back to initial vt and it's empty put a login screen
+ * on it (unless a login screen is already running elsewhere, then
+ * jump to that login screen)
+ */
+ if (factory->active_vt != GDM_INITIAL_VT) {
+ g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring");
+ return G_SOURCE_CONTINUE;
+ }
+
+ g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change");
+
+ ensure_display_for_seat (factory, "seat0");
+
+ return G_SOURCE_CONTINUE;
+ }
+ #endif
+
++#ifdef HAVE_UDEV
++static void
++on_uevent (GUdevClient *client,
++ const char *action,
++ GUdevDevice *device,
++ GdmLocalDisplayFactory *factory)
++{
++ if (!g_udev_device_get_device_file (device))
++ return;
++
++ if (g_strcmp0 (action, "add") != 0 &&
++ g_strcmp0 (action, "change") != 0)
++ return;
++
++ if (!udev_is_settled (factory))
++ return;
++
++ g_signal_handler_disconnect (factory->gudev_client, factory->uevent_handler_id);
++ factory->uevent_handler_id = 0;
++
++ ensure_display_for_seat (factory, "seat0");
++}
++#endif
++
+ static void
+ gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory)
+ {
+ g_autoptr (GIOChannel) io_channel = NULL;
++ const char *subsystems[] = { "drm", NULL };
+
+ factory->seat_new_id = g_dbus_connection_signal_subscribe (factory->connection,
+ "org.freedesktop.login1",
+ "org.freedesktop.login1.Manager",
+ "SeatNew",
+ "/org/freedesktop/login1",
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_seat_new,
+ g_object_ref (factory),
+ g_object_unref);
+ factory->seat_removed_id = g_dbus_connection_signal_subscribe (factory->connection,
+ "org.freedesktop.login1",
+ "org.freedesktop.login1.Manager",
+ "SeatRemoved",
+ "/org/freedesktop/login1",
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_seat_removed,
+ g_object_ref (factory),
+ g_object_unref);
+ factory->seat_properties_changed_id = g_dbus_connection_signal_subscribe (factory->connection,
+ "org.freedesktop.login1",
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ NULL,
+ "org.freedesktop.login1.Seat",
+ G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE,
+ on_seat_properties_changed,
+ g_object_ref (factory),
+ g_object_unref);
++#ifdef HAVE_UDEV
++ factory->gudev_client = g_udev_client_new (subsystems);
++ factory->uevent_handler_id = g_signal_connect (factory->gudev_client,
++ "uevent",
++ G_CALLBACK (on_uevent),
++ factory);
++#endif
+
+ #if defined(ENABLE_USER_DISPLAY_SERVER)
+ io_channel = g_io_channel_new_file ("/sys/class/tty/tty0/active", "r", NULL);
+
+ if (io_channel != NULL) {
+ factory->active_vt_watch_id =
+ g_io_add_watch (io_channel,
+ G_IO_PRI,
+ (GIOFunc)
+ on_vt_changed,
+ factory);
+ }
+ #endif
+ }
+
+ static void
+ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
+ {
++ if (factory->uevent_handler_id) {
++ g_signal_handler_disconnect (factory->gudev_client, factory->uevent_handler_id);
++ factory->uevent_handler_id = 0;
++ }
++ g_clear_object (&factory->gudev_client);
++
+ if (factory->seat_new_id) {
+ g_dbus_connection_signal_unsubscribe (factory->connection,
+ factory->seat_new_id);
+ factory->seat_new_id = 0;
+ }
+ if (factory->seat_removed_id) {
+ g_dbus_connection_signal_unsubscribe (factory->connection,
+ factory->seat_removed_id);
+ factory->seat_removed_id = 0;
+ }
+ if (factory->seat_properties_changed_id) {
+ g_dbus_connection_signal_unsubscribe (factory->connection,
+ factory->seat_properties_changed_id);
+ factory->seat_properties_changed_id = 0;
+ }
+ #if defined(ENABLE_USER_DISPLAY_SERVER)
+ if (factory->active_vt_watch_id) {
+ g_source_remove (factory->active_vt_watch_id);
+ factory->active_vt_watch_id = 0;
+ }
+ if (factory->wait_to_finish_timeout_id != 0) {
+ g_source_remove (factory->wait_to_finish_timeout_id);
+ factory->wait_to_finish_timeout_id = 0;
+ }
+ #endif
+ }
+
+ static void
+ on_display_added (GdmDisplayStore *display_store,
+ const char *id,
+diff --git a/daemon/meson.build b/daemon/meson.build
+index 2e61b6447..41f30abef 100644
+--- a/daemon/meson.build
++++ b/daemon/meson.build
+@@ -177,37 +177,41 @@ gdm_daemon_sources = files(
+ 'gdm-session-record.c',
+ 'gdm-session-worker-common.c',
+ 'gdm-session-worker-job.c',
+ 'gdm-session.c',
+ 'main.c',
+ )
+
+ gdm_daemon_gen_sources = [
+ display_dbus_gen,
+ local_display_factory_dbus_gen,
+ manager_dbus_gen,
+ local_display_dbus_gen,
+ session_dbus_gen,
+ session_worker_dbus_gen,
+ gdm_session_enums,
+ ]
+
+ if xdmcp_dep.found()
+ gdm_daemon_deps += xdmcp_dep
+
+ gdm_daemon_sources = [
+ gdm_daemon_sources,
+ files(
+ 'gdm-xdmcp-display-factory.c',
+ 'gdm-xdmcp-display.c',
+ 'gdm-xdmcp-chooser-display.c',
+ ),
+ ]
+ endif
+
++if gudev_dep.found()
++ gdm_daemon_deps += gudev_dep
++endif
++
+ gdm_daemon = executable('gdm',
+ [ gdm_daemon_sources, gdm_daemon_gen_sources ],
+ dependencies: gdm_daemon_deps,
+ include_directories: config_h_dir,
+ install: true,
+ install_dir: get_option('sbindir')
+ )
+diff --git a/meson.build b/meson.build
+index 02d609dc0..05d8da412 100644
+--- a/meson.build
++++ b/meson.build
+@@ -11,60 +11,61 @@ i18n = import('i18n')
+
+ # Compiler
+ cc = meson.get_compiler('c')
+
+ # Options
+ gdm_prefix = get_option('prefix')
+
+ gdmconfdir = (get_option('sysconfsubdir') == '')? gdm_prefix / get_option('sysconfdir') : gdm_prefix / get_option('sysconfdir') / get_option('sysconfsubdir')
+ dmconfdir = (get_option('dmconfdir') != '')? get_option('dmconfdir') : gdm_prefix / get_option('sysconfdir') / 'dm'
+ udev_dir = get_option('udev-dir')
+ at_spi_registryd_dir = (get_option('at-spi-registryd-dir') != '')? get_option('at-spi-registryd-dir') : gdm_prefix / get_option('libexecdir')
+ lang_config_file = (get_option('lang-file') != '')? get_option('lang-file') : gdm_prefix / get_option('sysconfdir') / 'locale.conf'
+ pam_mod_dir = (get_option('pam-mod-dir') != '')? get_option('pam-mod-dir') : gdm_prefix / get_option('libdir') / 'security'
+ dbus_sys_dir = (get_option('dbus-sys') != '')? get_option('dbus-sys') : get_option('sysconfdir') / 'dbus-1' / 'system.d'
+ gdm_defaults_conf = (get_option('defaults-conf') != '')? get_option('defaults-conf') : gdm_prefix / get_option('datadir') / 'gdm' / 'defaults.conf'
+ gdm_custom_conf = (get_option('custom-conf') != '')? get_option('custom-conf') : gdmconfdir / 'custom.conf'
+ gnome_settings_daemon_dir = (get_option('gnome-settings-daemon-dir') != '')? get_option('gnome-settings-daemon-dir') : gdm_prefix / get_option('libexecdir')
+ gdm_run_dir = (get_option('run-dir') != '')? get_option('run-dir') : gdm_prefix / get_option('localstatedir') / 'run' / 'gdm'
+ gdm_runtime_conf = (get_option('runtime-conf') != '')? get_option('runtime-conf') : gdm_run_dir / 'custom.conf'
+ gdm_pid_file = (get_option('pid-file') != '')? get_option('pid-file') : gdm_run_dir / 'gdm.pid'
+ ran_once_marker_dir = (get_option('ran-once-marker-dir') != '')? get_option('ran-once-marker-dir') : gdm_run_dir
+ working_dir = (get_option('working-dir') != '')? get_option('working-dir') : gdm_prefix / get_option('localstatedir') / 'lib' / 'gdm'
+ gdm_xauth_dir = (get_option('xauth-dir') != '')? get_option('xauth-dir') : gdm_run_dir
+ gdm_screenshot_dir = (get_option('screenshot-dir') != '')? get_option('screenshot-dir') : gdm_run_dir / 'greeter'
+
+ # Common variables
+ config_h_dir = include_directories('.')
+
+ # Dependencies
+ udev_dep = dependency('udev')
++gudev_dep = dependency('gudev-1.0', version: '>= 232')
+
+ glib_min_version = '2.56.0'
+
+ glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
+ gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
+ gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version)
+ gio_unix_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
+ gtk_dep = dependency('gtk+-3.0', version: '>= 2.91.1')
+ libcanberra_gtk_dep = dependency('libcanberra-gtk3', version: '>= 0.4')
+ accountsservice_dep = dependency('accountsservice', version: '>= 0.6.35')
+ xcb_dep = dependency('xcb')
+ keyutils_dep = dependency('libkeyutils', required: false)
+ libselinux_dep = dependency('libselinux', required: get_option('selinux'))
+
+ # udev
+ if udev_dir == ''
+ if udev_dep.found()
+ udev_prefix = udev_dep.get_pkgconfig_variable('udevdir')
+ else
+ udev_prefix = gdm_prefix / 'lib' / 'udev'
+ endif
+ udev_dir = udev_prefix / 'rules.d'
+ endif
+
+ # X11
+ x_deps = declare_dependency(
+ dependencies: [
+ dependency('x11'),
+ dependency('xau'),
+ ],
+@@ -217,60 +218,61 @@ conf.set('HAVE_UTMP_H', have_utmp_header)
+ conf.set('HAVE_UTMPX_H', have_utmpx_header)
+ conf.set('HAVE_POSIX_GETPWNAM_R', have_posix_getpwnam_r)
+ conf.set('UTMP', utmp_struct)
+ conf.set('HAVE_GETUTXENT', cc.has_function('getutxent'))
+ conf.set('HAVE_UPDWTMP', cc.has_function('updwtmp'))
+ conf.set('HAVE_UPDWTMPX', cc.has_function('updwtmpx'))
+ conf.set('HAVE_LOGIN', cc.has_function('login', args: '-lutil'))
+ conf.set('HAVE_LOGOUT', cc.has_function('logout', args: '-lutil'))
+ conf.set('HAVE_LOGWTMP', cc.has_function('logwtmp', args: '-lutil'))
+ conf.set('HAVE_PAM_SYSLOG', have_pam_syslog)
+ conf.set('HAVE_KEYUTILS', keyutils_dep.found())
+ conf.set('SUPPORTS_PAM_EXTENSIONS', pam_extensions_supported)
+ conf.set('HAVE_SELINUX', libselinux_dep.found())
+ conf.set('HAVE_XSERVER_WITH_LISTEN', xserver_has_listen)
+ conf.set('ENABLE_USER_DISPLAY_SERVER', get_option('user-display-server'))
+ conf.set('ENABLE_SYSTEMD_JOURNAL', get_option('systemd-journal'))
+ conf.set('ENABLE_WAYLAND_SUPPORT', get_option('wayland-support'))
+ conf.set('ENABLE_PROFILING', get_option('profiling'))
+ conf.set('GDM_INITIAL_VT', get_option('initial-vt'))
+ conf.set_quoted('GDM_DEFAULTS_CONF', gdm_defaults_conf)
+ conf.set_quoted('GDM_CUSTOM_CONF', gdm_custom_conf)
+ conf.set_quoted('GDM_RUNTIME_CONF', gdm_runtime_conf)
+ conf.set_quoted('GDM_SESSION_DEFAULT_PATH', get_option('default-path'))
+ conf.set_quoted('GDM_USERNAME', get_option('user'))
+ conf.set_quoted('GDM_GROUPNAME', get_option('group'))
+ conf.set('HAVE_LIBXDMCP', xdmcp_dep.found())
+ conf.set_quoted('SYSTEMD_X_SERVER', systemd_x_server)
+ conf.set('WITH_PLYMOUTH', plymouth_dep.found())
+ conf.set_quoted('X_SERVER', x_bin)
+ conf.set_quoted('X_PATH', x_path)
++conf.set('HAVE_UDEV', gudev_dep.found())
+ conf.set('HAVE_UT_UT_HOST', utmp_has_host_field)
+ conf.set('HAVE_UT_UT_PID', utmp_has_pid_field)
+ conf.set('HAVE_UT_UT_ID', utmp_has_id_field)
+ conf.set('HAVE_UT_UT_NAME', utmp_has_name_field)
+ conf.set('HAVE_UT_UT_TYPE', utmp_has_type_field)
+ conf.set('HAVE_UT_UT_EXIT_E_TERMINATION', utmp_has_exit_e_termination_field)
+ conf.set('HAVE_UT_UT_USER', utmp_has_user_field)
+ conf.set('HAVE_UT_UT_TIME', utmp_has_time_field)
+ conf.set('HAVE_UT_UT_TV', utmp_has_tv_field)
+ conf.set('HAVE_UT_UT_SYSLEN', utmp_has_syslen_field)
+ conf.set('ENABLE_IPV6', get_option('ipv6'))
+ configure_file(output: 'config.h', configuration: conf)
+
+ # Subdirs
+ subdir('data')
+ subdir('common')
+ if pam_extensions_supported
+ subdir('pam-extensions')
+ endif
+ subdir('daemon')
+ subdir('libgdm')
+ subdir('utils')
+ subdir('pam_gdm')
+ subdir('po')
+ if libcheck_dep.found()
+ subdir('tests')
+ endif
+ if xdmcp_dep.found()
+ subdir('chooser')
+ endif
+--
+2.40.0
+