You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
31 KiB
729 lines
31 KiB
From e5b3467412874d27c311253e3d5d7e65a61d12a4 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 | 164 ++++++++++++++++++++++++++--- |
|
daemon/meson.build | 4 + |
|
meson.build | 2 + |
|
4 files changed, 159 insertions(+), 12 deletions(-) |
|
|
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
|
index c00e1c47..0b1d3482 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", ¤t, 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 +1240,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 2e61b644..41f30abe 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 02d609dc..05d8da41 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.34.1 |
|
|
|
|