
commit
e29007c16a
25 changed files with 10035 additions and 0 deletions
@ -0,0 +1,159 @@
@@ -0,0 +1,159 @@
|
||||
From f6ebcec5d48aeff718a9db9b8ff812fd404a61ed Mon Sep 17 00:00:00 2001 |
||||
From: Rui Matos <tiagomatos@gmail.com> |
||||
Date: Mon, 23 Jan 2017 20:19:51 +0100 |
||||
Subject: [PATCH] Honor initial setup being disabled by distro installer |
||||
|
||||
Sysadmins might want to disable any kind of initial setup for their |
||||
users, perhaps because they pre-configure their environments. We |
||||
already provide a configuration file option for this but distro |
||||
installers might have their own way of requesting this. |
||||
|
||||
At least the anaconda installer provides an option to skip any kind |
||||
post-install setup tools so, for now we're only adding support for |
||||
that but more might be added in the future. |
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=777708 |
||||
--- |
||||
daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++ |
||||
1 file changed, 29 insertions(+) |
||||
|
||||
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c |
||||
index 34467856..9438fe72 100644 |
||||
--- a/daemon/gdm-display.c |
||||
+++ b/daemon/gdm-display.c |
||||
@@ -1621,103 +1621,132 @@ kernel_cmdline_initial_setup_force_state (gboolean *force_state) |
||||
GError *error = NULL; |
||||
gchar *contents = NULL; |
||||
gchar *setup_argument = NULL; |
||||
|
||||
g_return_val_if_fail (force_state != NULL, FALSE); |
||||
|
||||
if (!g_file_get_contents ("/proc/cmdline", &contents, NULL, &error)) { |
||||
g_debug ("GdmDisplay: Could not check kernel parameters, not forcing initial setup: %s", |
||||
error->message); |
||||
g_clear_error (&error); |
||||
return FALSE; |
||||
} |
||||
|
||||
g_debug ("GdmDisplay: Checking kernel command buffer %s", contents); |
||||
|
||||
if (!kernel_cmdline_initial_setup_argument (contents, &setup_argument, &error)) { |
||||
g_debug ("GdmDisplay: Failed to read kernel commandline: %s", error->message); |
||||
g_clear_pointer (&contents, g_free); |
||||
return FALSE; |
||||
} |
||||
|
||||
g_clear_pointer (&contents, g_free); |
||||
|
||||
/* Poor-man's check for truthy or falsey values */ |
||||
*force_state = setup_argument[0] == '1'; |
||||
|
||||
g_free (setup_argument); |
||||
return TRUE; |
||||
} |
||||
|
||||
+static gboolean |
||||
+initial_setup_disabled_by_anaconda (void) |
||||
+{ |
||||
+ GKeyFile *key_file; |
||||
+ const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda"; |
||||
+ gboolean disabled = FALSE; |
||||
+ GError *error = NULL; |
||||
+ |
||||
+ key_file = g_key_file_new (); |
||||
+ if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) { |
||||
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) && |
||||
+ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { |
||||
+ g_warning ("Could not read %s: %s", file_name, error->message); |
||||
+ } |
||||
+ g_error_free (error); |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ disabled = g_key_file_get_boolean (key_file, "General", |
||||
+ "post_install_tools_disabled", NULL); |
||||
+ out: |
||||
+ g_key_file_unref (key_file); |
||||
+ return disabled; |
||||
+} |
||||
+ |
||||
static gboolean |
||||
wants_initial_setup (GdmDisplay *self) |
||||
{ |
||||
GdmDisplayPrivate *priv; |
||||
gboolean enabled = FALSE; |
||||
gboolean forced = FALSE; |
||||
|
||||
priv = gdm_display_get_instance_private (self); |
||||
|
||||
if (already_done_initial_setup_on_this_boot ()) { |
||||
return FALSE; |
||||
} |
||||
|
||||
if (kernel_cmdline_initial_setup_force_state (&forced)) { |
||||
if (forced) { |
||||
g_debug ("GdmDisplay: Forcing gnome-initial-setup"); |
||||
return TRUE; |
||||
} |
||||
|
||||
g_debug ("GdmDisplay: Forcing no gnome-initial-setup"); |
||||
return FALSE; |
||||
} |
||||
|
||||
/* don't run initial-setup on remote displays |
||||
*/ |
||||
if (!priv->is_local) { |
||||
return FALSE; |
||||
} |
||||
|
||||
/* don't run if the system has existing users */ |
||||
if (priv->have_existing_user_accounts) { |
||||
return FALSE; |
||||
} |
||||
|
||||
/* don't run if initial-setup is unavailable */ |
||||
if (!can_create_environment ("gnome-initial-setup")) { |
||||
return FALSE; |
||||
} |
||||
|
||||
if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) { |
||||
return FALSE; |
||||
} |
||||
|
||||
+ if (initial_setup_disabled_by_anaconda ()) { |
||||
+ return FALSE; |
||||
+ } |
||||
+ |
||||
return enabled; |
||||
} |
||||
|
||||
void |
||||
gdm_display_start_greeter_session (GdmDisplay *self) |
||||
{ |
||||
GdmDisplayPrivate *priv; |
||||
GdmSession *session; |
||||
char *display_name; |
||||
char *seat_id; |
||||
char *hostname; |
||||
char *auth_file = NULL; |
||||
|
||||
priv = gdm_display_get_instance_private (self); |
||||
g_return_if_fail (g_strcmp0 (priv->session_class, "greeter") == 0); |
||||
|
||||
g_debug ("GdmDisplay: Running greeter"); |
||||
|
||||
display_name = NULL; |
||||
seat_id = NULL; |
||||
hostname = NULL; |
||||
|
||||
g_object_get (self, |
||||
"x11-display-name", &display_name, |
||||
"seat-id", &seat_id, |
||||
"remote-hostname", &hostname, |
||||
NULL); |
||||
if (priv->access_file != NULL) { |
||||
auth_file = gdm_display_access_file_get_path (priv->access_file); |
||||
} |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
From aa1c4a7708df2edbc12f2ada7249208aef586d1e Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> |
||||
Date: Tue, 8 Jun 2021 20:45:00 +0200 |
||||
Subject: [PATCH] data: Disable network configuration on login screen |
||||
|
||||
--- |
||||
data/meson.build | 10 ++++++++++ |
||||
data/org.gnome.gdm.rules.in | 8 ++++++++ |
||||
2 files changed, 18 insertions(+) |
||||
create mode 100644 data/org.gnome.gdm.rules.in |
||||
|
||||
diff --git a/data/meson.build b/data/meson.build |
||||
index 7c5222ea..20d39a36 100644 |
||||
--- a/data/meson.build |
||||
+++ b/data/meson.build |
||||
@@ -130,60 +130,70 @@ pam_data_files_map = { |
||||
], |
||||
'arch': [ |
||||
'gdm-autologin', |
||||
'gdm-launch-environment', |
||||
'gdm-fingerprint', |
||||
'gdm-smartcard', |
||||
'gdm-password', |
||||
], |
||||
'none': [], |
||||
# We should no longer have 'autodetect' at this point |
||||
} |
||||
|
||||
pam_data_files = pam_data_files_map[default_pam_config] |
||||
pam_prefix = (get_option('pam-prefix') != '')? get_option('pam-prefix') : get_option('sysconfdir') |
||||
foreach _pam_filename : pam_data_files |
||||
install_data('pam-@0@/@1@.pam'.format(default_pam_config, _pam_filename), |
||||
rename: _pam_filename, |
||||
install_dir: pam_prefix / 'pam.d', |
||||
) |
||||
endforeach |
||||
|
||||
gdm_rules = configure_file( |
||||
input: '61-gdm.rules.in', |
||||
output: '@BASENAME@', |
||||
configuration: { |
||||
'libexecdir': gdm_prefix / get_option('libexecdir'), |
||||
}, |
||||
install_dir: udev_dir, |
||||
) |
||||
|
||||
+# Polkit rules |
||||
+polkit_rules = configure_file( |
||||
+ input: 'org.gnome.gdm.rules.in', |
||||
+ output: '@BASENAME@', |
||||
+ configuration: { |
||||
+ 'GDM_USERNAME': get_option('user'), |
||||
+ }, |
||||
+ install_dir: get_option('datadir') / 'polkit-1' / 'rules.d', |
||||
+) |
||||
+ |
||||
# DBus service files |
||||
service_config = configuration_data() |
||||
service_config.set('sbindir', gdm_prefix / get_option('sbindir')) |
||||
service_config.set('GDM_INITIAL_VT', get_option('initial-vt')) |
||||
service_config.set('LANG_CONFIG_FILE', lang_config_file) |
||||
if plymouth_dep.found() |
||||
service_config.set('PLYMOUTH_QUIT_SERVICE', 'plymouth-quit.service') |
||||
else |
||||
service_config.set('PLYMOUTH_QUIT_SERVICE', '') |
||||
endif |
||||
|
||||
if get_option('systemdsystemunitdir') != '' |
||||
systemd_systemunitdir = get_option('systemdsystemunitdir') |
||||
else |
||||
systemd_systemunitdir = systemd_dep.get_pkgconfig_variable('systemdsystemunitdir') |
||||
endif |
||||
|
||||
if get_option('systemduserunitdir') != '' |
||||
systemd_userunitdir = get_option('systemduserunitdir') |
||||
else |
||||
systemd_userunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir', |
||||
define_variable: ['prefix', get_option('prefix')]) |
||||
endif |
||||
|
||||
configure_file( |
||||
input: 'gdm.service.in', |
||||
output: '@BASENAME@', |
||||
configuration: service_config, |
||||
install_dir: systemd_systemunitdir, |
||||
format: 'cmake' |
||||
diff --git a/data/org.gnome.gdm.rules.in b/data/org.gnome.gdm.rules.in |
||||
new file mode 100644 |
||||
index 00000000..09544f11 |
||||
--- /dev/null |
||||
+++ b/data/org.gnome.gdm.rules.in |
||||
@@ -0,0 +1,8 @@ |
||||
+polkit.addRule(function(action, subject) { |
||||
+ if (action.id == "org.freedesktop.NetworkManager.network-control" && |
||||
+ subject.user == "@GDM_USERNAME@") { |
||||
+ return polkit.Result.NO; |
||||
+ } |
||||
+ |
||||
+ return polkit.Result.NOT_HANDLED; |
||||
+}); |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
From 3e62d7b423175102bd2376adc9cf58ad736b23b0 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Wed, 31 Jul 2013 17:32:55 -0400 |
||||
Subject: [PATCH] data: add system dconf databases to gdm profile |
||||
|
||||
This way system settings can affect the login screen. |
||||
--- |
||||
data/dconf/gdm.in | 4 ++++ |
||||
1 file changed, 4 insertions(+) |
||||
|
||||
diff --git a/data/dconf/gdm.in b/data/dconf/gdm.in |
||||
index 4d8bf174..9694078f 100644 |
||||
--- a/data/dconf/gdm.in |
||||
+++ b/data/dconf/gdm.in |
||||
@@ -1,2 +1,6 @@ |
||||
user-db:user |
||||
+system-db:gdm |
||||
+system-db:local |
||||
+system-db:site |
||||
+system-db:distro |
||||
file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
From a4743b9b2b355f84da3904e7da93ec3c7a521895 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Fri, 26 Jul 2019 14:06:16 -0400 |
||||
Subject: [PATCH] data: reap gdm sessions on shutdown |
||||
|
||||
If GDM gets shutdown we should make sure all sessions get shutdown too. |
||||
|
||||
This is a bit of a safety net in case any processes in the session are |
||||
lingering after the orderly shutdown. |
||||
--- |
||||
data/gdm.service.in | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/data/gdm.service.in b/data/gdm.service.in |
||||
index 17e8a8de..195bd0fd 100644 |
||||
--- a/data/gdm.service.in |
||||
+++ b/data/gdm.service.in |
||||
@@ -1,33 +1,34 @@ |
||||
[Unit] |
||||
Description=GNOME Display Manager |
||||
|
||||
# replaces the getty |
||||
Conflicts=getty@tty${GDM_INITIAL_VT}.service |
||||
After=getty@tty${GDM_INITIAL_VT}.service |
||||
|
||||
# replaces plymouth-quit since it quits plymouth on its own |
||||
Conflicts=${PLYMOUTH_QUIT_SERVICE} |
||||
After=${PLYMOUTH_QUIT_SERVICE} |
||||
|
||||
# Needs all the dependencies of the services it's replacing |
||||
# pulled from getty@.service and ${PLYMOUTH_QUIT_SERVICE} |
||||
# (except for plymouth-quit-wait.service since it waits until |
||||
# plymouth is quit, which we do) |
||||
After=rc-local.service plymouth-start.service systemd-user-sessions.service |
||||
|
||||
# GDM takes responsibility for stopping plymouth, so if it fails |
||||
# for any reason, make sure plymouth still stops |
||||
OnFailure=plymouth-quit.service |
||||
|
||||
[Service] |
||||
ExecStart=${sbindir}/gdm |
||||
+ExecStopPost=-/usr/bin/bash -c 'for f in /run/systemd/sessions/*; do [ -f $f ] && /usr/bin/fgrep -q SERVICE=gdm $f && loginctl terminate-session $(basename $f); done' |
||||
KillMode=mixed |
||||
Restart=always |
||||
IgnoreSIGPIPE=no |
||||
BusName=org.gnome.DisplayManager |
||||
EnvironmentFile=-${LANG_CONFIG_FILE} |
||||
ExecReload=/bin/kill -SIGHUP $MAINPID |
||||
KeyringMode=shared |
||||
|
||||
[Install] |
||||
Alias=display-manager.service |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,325 @@
@@ -0,0 +1,325 @@
|
||||
From 9261fcd05667fc5f8b81880577e41a566db821a8 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Wed, 15 Sep 2021 11:23:17 -0400 |
||||
Subject: [PATCH] local-display-factory: Don't try to respawn displays on |
||||
shutdown |
||||
|
||||
At the moment in the shutdown path we may try to respawn displays |
||||
that just got killed. |
||||
|
||||
The respawning happens when things are half torn down leading to |
||||
crashes. |
||||
|
||||
This commit makes sure we turn off the respawn logic in the shutdown |
||||
path. |
||||
--- |
||||
daemon/gdm-local-display-factory.c | 11 ++++++++++- |
||||
daemon/gdm-manager.c | 2 ++ |
||||
2 files changed, 12 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||
index 141d64c6..bca41f6e 100644 |
||||
--- a/daemon/gdm-local-display-factory.c |
||||
+++ b/daemon/gdm-local-display-factory.c |
||||
@@ -46,60 +46,62 @@ |
||||
#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; |
||||
|
||||
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_graphics_check_timed_out; |
||||
guint seat0_graphics_check_timeout_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); |
||||
|
||||
G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) |
||||
|
||||
GQuark |
||||
gdm_local_display_factory_error_quark (void) |
||||
{ |
||||
static GQuark ret = 0; |
||||
if (ret == 0) { |
||||
@@ -416,60 +418,64 @@ on_session_registered_cb (GObject *gobject, |
||||
GParamSpec *pspec, |
||||
gpointer user_data) |
||||
{ |
||||
GdmDisplay *display = GDM_DISPLAY (gobject); |
||||
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); |
||||
gboolean registered; |
||||
|
||||
g_object_get (display, "session-registered", ®istered, NULL); |
||||
|
||||
if (!registered) |
||||
return; |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); |
||||
|
||||
finish_waiting_displays_on_seat (factory, "seat0"); |
||||
} |
||||
|
||||
static void |
||||
on_display_status_changed (GdmDisplay *display, |
||||
GParamSpec *arg1, |
||||
GdmLocalDisplayFactory *factory) |
||||
{ |
||||
int status; |
||||
int num; |
||||
char *seat_id = NULL; |
||||
char *session_type = NULL; |
||||
char *session_class = NULL; |
||||
gboolean is_initial = TRUE; |
||||
gboolean is_local = TRUE; |
||||
|
||||
+ |
||||
+ if (!factory->is_started) |
||||
+ return; |
||||
+ |
||||
num = -1; |
||||
gdm_display_get_x11_display_number (display, &num, NULL); |
||||
|
||||
g_object_get (display, |
||||
"seat-id", &seat_id, |
||||
"is-initial", &is_initial, |
||||
"is-local", &is_local, |
||||
"session-type", &session_type, |
||||
"session-class", &session_class, |
||||
NULL); |
||||
|
||||
status = gdm_display_get_status (display); |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); |
||||
switch (status) { |
||||
case GDM_DISPLAY_FINISHED: |
||||
/* remove the display number from factory->used_display_numbers |
||||
so that it may be reused */ |
||||
if (num != -1) { |
||||
g_hash_table_remove (factory->used_display_numbers, GUINT_TO_POINTER (num)); |
||||
} |
||||
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); |
||||
|
||||
/* if this is a local display, do a full resync. Only |
||||
* seats without displays will get created anyway. This |
||||
* ensures we get a new login screen when the user logs out, |
||||
* if there isn't one. |
||||
*/ |
||||
if (is_local && g_strcmp0 (session_class, "greeter") != 0) { |
||||
/* reset num failures */ |
||||
@@ -1204,99 +1210,102 @@ on_display_added (GdmDisplayStore *display_store, |
||||
|
||||
display = gdm_display_store_lookup (display_store, id); |
||||
|
||||
if (display != NULL) { |
||||
g_signal_connect_object (display, "notify::status", |
||||
G_CALLBACK (on_display_status_changed), |
||||
factory, |
||||
0); |
||||
|
||||
g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
on_display_removed (GdmDisplayStore *display_store, |
||||
GdmDisplay *display, |
||||
GdmLocalDisplayFactory *factory) |
||||
{ |
||||
g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory); |
||||
g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); |
||||
} |
||||
|
||||
static gboolean |
||||
gdm_local_display_factory_start (GdmDisplayFactory *base_factory) |
||||
{ |
||||
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); |
||||
GdmDisplayStore *store; |
||||
|
||||
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); |
||||
|
||||
+ factory->is_started = TRUE; |
||||
+ |
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
|
||||
g_signal_connect_object (G_OBJECT (store), |
||||
"display-added", |
||||
G_CALLBACK (on_display_added), |
||||
factory, |
||||
0); |
||||
|
||||
g_signal_connect_object (G_OBJECT (store), |
||||
"display-removed", |
||||
G_CALLBACK (on_display_removed), |
||||
factory, |
||||
0); |
||||
|
||||
gdm_local_display_factory_start_monitor (factory); |
||||
return gdm_local_display_factory_sync_seats (factory); |
||||
} |
||||
|
||||
static gboolean |
||||
gdm_local_display_factory_stop (GdmDisplayFactory *base_factory) |
||||
{ |
||||
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); |
||||
GdmDisplayStore *store; |
||||
|
||||
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); |
||||
|
||||
gdm_local_display_factory_stop_monitor (factory); |
||||
|
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (store), |
||||
G_CALLBACK (on_display_added), |
||||
factory); |
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (store), |
||||
G_CALLBACK (on_display_removed), |
||||
factory); |
||||
- |
||||
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); |
||||
|
||||
+ factory->is_started = FALSE; |
||||
+ |
||||
return TRUE; |
||||
} |
||||
|
||||
static void |
||||
gdm_local_display_factory_set_property (GObject *object, |
||||
guint prop_id, |
||||
const GValue *value, |
||||
GParamSpec *pspec) |
||||
{ |
||||
switch (prop_id) { |
||||
default: |
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static void |
||||
gdm_local_display_factory_get_property (GObject *object, |
||||
guint prop_id, |
||||
GValue *value, |
||||
GParamSpec *pspec) |
||||
{ |
||||
switch (prop_id) { |
||||
default: |
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static gboolean |
||||
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||
index 4c2752fe..cc61efc9 100644 |
||||
--- a/daemon/gdm-manager.c |
||||
+++ b/daemon/gdm-manager.c |
||||
@@ -2741,60 +2741,62 @@ unexport_display (const char *id, |
||||
GdmDisplay *display, |
||||
GdmManager *manager) |
||||
{ |
||||
if (!g_dbus_connection_is_closed (manager->priv->connection)) |
||||
g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); |
||||
} |
||||
|
||||
static void |
||||
finish_display (const char *id, |
||||
GdmDisplay *display, |
||||
GdmManager *manager) |
||||
{ |
||||
gdm_display_stop_greeter_session (display); |
||||
if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) |
||||
gdm_display_unmanage (display); |
||||
gdm_display_finish (display); |
||||
} |
||||
|
||||
static void |
||||
gdm_manager_dispose (GObject *object) |
||||
{ |
||||
GdmManager *manager; |
||||
|
||||
g_return_if_fail (object != NULL); |
||||
g_return_if_fail (GDM_IS_MANAGER (object)); |
||||
|
||||
manager = GDM_MANAGER (object); |
||||
|
||||
g_return_if_fail (manager->priv != NULL); |
||||
|
||||
+ gdm_manager_stop (manager); |
||||
+ |
||||
g_clear_weak_pointer (&manager->priv->automatic_login_display); |
||||
|
||||
#ifdef HAVE_LIBXDMCP |
||||
g_clear_object (&manager->priv->xdmcp_factory); |
||||
#endif |
||||
g_clear_object (&manager->priv->local_factory); |
||||
g_clear_pointer (&manager->priv->open_reauthentication_requests, |
||||
g_hash_table_unref); |
||||
g_clear_pointer (&manager->priv->transient_sessions, |
||||
g_hash_table_unref); |
||||
|
||||
g_list_foreach (manager->priv->user_sessions, |
||||
(GFunc) gdm_session_close, |
||||
NULL); |
||||
g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); |
||||
manager->priv->user_sessions = NULL; |
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), |
||||
G_CALLBACK (on_display_added), |
||||
manager); |
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), |
||||
G_CALLBACK (on_display_removed), |
||||
manager); |
||||
|
||||
if (!g_dbus_connection_is_closed (manager->priv->connection)) { |
||||
gdm_display_store_foreach (manager->priv->display_store, |
||||
(GdmDisplayStoreFunc)unexport_display, |
||||
manager); |
||||
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); |
||||
} |
||||
-- |
||||
2.32.0 |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,729 @@
@@ -0,0 +1,729 @@
|
||||
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 |
||||
|
@ -0,0 +1,344 @@
@@ -0,0 +1,344 @@
|
||||
From 2e7965beae81e0e93d3f475f2ea29a7af6c23f29 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Thu, 20 Dec 2018 14:51:38 -0500 |
||||
Subject: [PATCH 1/3] manager: allow multiple xdmcp logins for the same user |
||||
|
||||
--- |
||||
common/gdm-settings-keys.h | 1 + |
||||
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++---------- |
||||
data/gdm.schemas.in | 5 +++ |
||||
3 files changed, 59 insertions(+), 18 deletions(-) |
||||
|
||||
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h |
||||
index 87685d3c..4b3a1ffe 100644 |
||||
--- a/common/gdm-settings-keys.h |
||||
+++ b/common/gdm-settings-keys.h |
||||
@@ -30,37 +30,38 @@ G_BEGIN_DECLS |
||||
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable" |
||||
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin" |
||||
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable" |
||||
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin" |
||||
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay" |
||||
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable" |
||||
#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer" |
||||
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable" |
||||
#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable" |
||||
|
||||
#define GDM_KEY_DEBUG "debug/Enable" |
||||
|
||||
#define GDM_KEY_INCLUDE "greeter/Include" |
||||
#define GDM_KEY_EXCLUDE "greeter/Exclude" |
||||
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll" |
||||
|
||||
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP" |
||||
#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin" |
||||
|
||||
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable" |
||||
#define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter" |
||||
#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending" |
||||
#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions" |
||||
#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait" |
||||
#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost" |
||||
#define GDM_KEY_UDP_PORT "xdmcp/Port" |
||||
#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect" |
||||
#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect" |
||||
#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds" |
||||
#define GDM_KEY_WILLING "xdmcp/Willing" |
||||
+#define GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER "xdmcp/AllowMultipleSessionsPerUser" |
||||
|
||||
#define GDM_KEY_MULTICAST "chooser/Multicast" |
||||
#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr" |
||||
|
||||
G_END_DECLS |
||||
|
||||
#endif /* _GDM_SETTINGS_KEYS_H */ |
||||
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||
index cc61efc9..dc839aeb 100644 |
||||
--- a/daemon/gdm-manager.c |
||||
+++ b/daemon/gdm-manager.c |
||||
@@ -566,93 +566,106 @@ get_display_and_details_for_bus_sender (GdmManager *self, |
||||
*out_tty = get_tty_for_session_id (session_id, &error); |
||||
|
||||
if (error != NULL) { |
||||
g_debug ("GdmManager: Error while retrieving tty for session: %s", |
||||
error->message); |
||||
g_clear_error (&error); |
||||
} |
||||
} |
||||
|
||||
display = gdm_display_store_find (self->priv->display_store, |
||||
lookup_by_session_id, |
||||
(gpointer) session_id); |
||||
|
||||
out: |
||||
if (out_display != NULL) { |
||||
*out_display = display; |
||||
} |
||||
|
||||
g_free (session_id); |
||||
} |
||||
|
||||
static gboolean |
||||
switch_to_compatible_user_session (GdmManager *manager, |
||||
GdmSession *session, |
||||
gboolean fail_if_already_switched) |
||||
{ |
||||
gboolean res; |
||||
gboolean ret; |
||||
const char *username; |
||||
const char *seat_id; |
||||
- const char *ssid_to_activate; |
||||
+ const char *ssid_to_activate = NULL; |
||||
GdmSession *existing_session; |
||||
|
||||
ret = FALSE; |
||||
|
||||
username = gdm_session_get_username (session); |
||||
seat_id = gdm_session_get_display_seat_id (session); |
||||
|
||||
- if (!fail_if_already_switched) { |
||||
- session = NULL; |
||||
- } |
||||
+ if (!fail_if_already_switched) |
||||
+ ssid_to_activate = gdm_session_get_session_id (session); |
||||
|
||||
- existing_session = find_session_for_user_on_seat (manager, username, seat_id, session); |
||||
+ if (ssid_to_activate == NULL) { |
||||
+ if (!seat_id || !sd_seat_can_multi_session (seat_id)) { |
||||
+ g_debug ("GdmManager: unable to activate existing sessions from login screen unless on seat0"); |
||||
+ goto out; |
||||
+ } |
||||
|
||||
- if (existing_session != NULL) { |
||||
- ssid_to_activate = gdm_session_get_session_id (existing_session); |
||||
- if (seat_id != NULL) { |
||||
- res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); |
||||
- if (! res) { |
||||
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); |
||||
- goto out; |
||||
- } |
||||
+ if (!fail_if_already_switched) { |
||||
+ session = NULL; |
||||
} |
||||
|
||||
- res = session_unlock (manager, ssid_to_activate); |
||||
- if (!res) { |
||||
- /* this isn't fatal */ |
||||
- g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate); |
||||
+ existing_session = find_session_for_user_on_seat (manager, username, seat_id, session); |
||||
+ |
||||
+ if (existing_session != NULL) { |
||||
+ ssid_to_activate = gdm_session_get_session_id (existing_session); |
||||
} |
||||
- } else { |
||||
+ } |
||||
+ |
||||
+ if (ssid_to_activate == NULL) { |
||||
goto out; |
||||
} |
||||
|
||||
+ if (seat_id != NULL) { |
||||
+ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); |
||||
+ if (! res) { |
||||
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); |
||||
+ goto out; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ res = session_unlock (manager, ssid_to_activate); |
||||
+ if (!res) { |
||||
+ /* this isn't fatal */ |
||||
+ g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate); |
||||
+ } |
||||
+ |
||||
ret = TRUE; |
||||
|
||||
out: |
||||
return ret; |
||||
} |
||||
|
||||
static GdmDisplay * |
||||
get_display_for_user_session (GdmSession *session) |
||||
{ |
||||
return g_object_get_data (G_OBJECT (session), "gdm-display"); |
||||
} |
||||
|
||||
static GdmSession * |
||||
get_user_session_for_display (GdmDisplay *display) |
||||
{ |
||||
if (display == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
return g_object_get_data (G_OBJECT (display), "gdm-user-session"); |
||||
} |
||||
|
||||
static gboolean |
||||
add_session_record (GdmManager *manager, |
||||
GdmSession *session, |
||||
GPid pid, |
||||
SessionRecord record) |
||||
{ |
||||
const char *username; |
||||
char *display_name, *hostname, *display_device; |
||||
@@ -1089,92 +1102,114 @@ open_temporary_reauthentication_channel (GdmManager *self, |
||||
g_signal_connect (session, |
||||
"client-disconnected", |
||||
G_CALLBACK (on_reauthentication_client_disconnected), |
||||
self); |
||||
g_signal_connect (session, |
||||
"client-rejected", |
||||
G_CALLBACK (on_reauthentication_client_rejected), |
||||
self); |
||||
g_signal_connect (session, |
||||
"cancelled", |
||||
G_CALLBACK (on_reauthentication_cancelled), |
||||
self); |
||||
g_signal_connect (session, |
||||
"conversation-started", |
||||
G_CALLBACK (on_reauthentication_conversation_started), |
||||
self); |
||||
g_signal_connect (session, |
||||
"conversation-stopped", |
||||
G_CALLBACK (on_reauthentication_conversation_stopped), |
||||
self); |
||||
g_signal_connect (session, |
||||
"verification-complete", |
||||
G_CALLBACK (on_reauthentication_verification_complete), |
||||
self); |
||||
|
||||
address = gdm_session_get_server_address (session); |
||||
|
||||
return g_strdup (address); |
||||
} |
||||
|
||||
+static gboolean |
||||
+remote_users_can_log_in_more_than_once (GdmManager *manager) |
||||
+{ |
||||
+ gboolean enabled; |
||||
+ |
||||
+ enabled = FALSE; |
||||
+ |
||||
+ gdm_settings_direct_get_boolean (GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER, &enabled); |
||||
+ |
||||
+ g_debug ("GdmDisplay: Remote users allowed to log in more than once: %s", enabled? "yes" : "no"); |
||||
+ |
||||
+ return enabled; |
||||
+} |
||||
+ |
||||
static gboolean |
||||
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager, |
||||
GDBusMethodInvocation *invocation, |
||||
const char *username) |
||||
{ |
||||
GdmManager *self = GDM_MANAGER (manager); |
||||
const char *sender; |
||||
GdmDisplay *display = NULL; |
||||
GdmSession *session; |
||||
GDBusConnection *connection; |
||||
char *seat_id = NULL; |
||||
char *session_id = NULL; |
||||
GPid pid = 0; |
||||
uid_t uid = (uid_t) -1; |
||||
gboolean is_login_screen = FALSE; |
||||
gboolean is_remote = FALSE; |
||||
|
||||
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username); |
||||
|
||||
sender = g_dbus_method_invocation_get_sender (invocation); |
||||
connection = g_dbus_method_invocation_get_connection (invocation); |
||||
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote); |
||||
|
||||
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) { |
||||
g_dbus_method_invocation_return_error_literal (invocation, |
||||
G_DBUS_ERROR, |
||||
G_DBUS_ERROR_ACCESS_DENIED, |
||||
_("No session available")); |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
+ if (is_login_screen && is_remote && remote_users_can_log_in_more_than_once (self)) { |
||||
+ g_dbus_method_invocation_return_error_literal (invocation, |
||||
+ G_DBUS_ERROR, |
||||
+ G_DBUS_ERROR_ACCESS_DENIED, |
||||
+ "Login screen creates new sessions for remote connections"); |
||||
+ return TRUE; |
||||
+ } |
||||
+ |
||||
if (is_login_screen) { |
||||
g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id); |
||||
session = find_session_for_user_on_seat (self, |
||||
username, |
||||
seat_id, |
||||
NULL); |
||||
} else { |
||||
g_debug ("GdmManager: looking for user session on display"); |
||||
session = get_user_session_for_display (display); |
||||
} |
||||
|
||||
if (session != NULL && gdm_session_is_running (session)) { |
||||
gdm_session_start_reauthentication (session, pid, uid); |
||||
g_hash_table_insert (self->priv->open_reauthentication_requests, |
||||
GINT_TO_POINTER (pid), |
||||
invocation); |
||||
} else if (is_login_screen) { |
||||
g_dbus_method_invocation_return_error_literal (invocation, |
||||
G_DBUS_ERROR, |
||||
G_DBUS_ERROR_ACCESS_DENIED, |
||||
"Login screen only allowed to open reauthentication channels for running sessions"); |
||||
return TRUE; |
||||
} else { |
||||
char *address; |
||||
address = open_temporary_reauthentication_channel (self, |
||||
seat_id, |
||||
session_id, |
||||
pid, |
||||
uid, |
||||
is_remote); |
||||
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in |
||||
index a1035f95..929d13d9 100644 |
||||
--- a/data/gdm.schemas.in |
||||
+++ b/data/gdm.schemas.in |
||||
@@ -112,33 +112,38 @@ |
||||
<schema> |
||||
<key>xdmcp/DisplaysPerHost</key> |
||||
<signature>i</signature> |
||||
<default>1</default> |
||||
</schema> |
||||
<schema> |
||||
<key>xdmcp/Port</key> |
||||
<signature>i</signature> |
||||
<default>177</default> |
||||
</schema> |
||||
<schema> |
||||
<key>xdmcp/HonorIndirect</key> |
||||
<signature>b</signature> |
||||
<default>true</default> |
||||
</schema> |
||||
<schema> |
||||
<key>xdmcp/MaxWaitIndirect</key> |
||||
<signature>i</signature> |
||||
<default>30</default> |
||||
</schema> |
||||
<schema> |
||||
<key>xdmcp/PingIntervalSeconds</key> |
||||
<signature>i</signature> |
||||
<default>0</default> |
||||
</schema> |
||||
<schema> |
||||
<key>xdmcp/Willing</key> |
||||
<signature>s</signature> |
||||
<default>@gdmconfdir@/Xwilling</default> |
||||
</schema> |
||||
+ <schema> |
||||
+ <key>xdmcp/AllowMultipleSessionsPerUser</key> |
||||
+ <signature>b</signature> |
||||
+ <default>false</default> |
||||
+ </schema> |
||||
</schemalist> |
||||
</gdmschemafile> |
||||
|
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,144 @@
@@ -0,0 +1,144 @@
|
||||
From b8caa1a18f284cc9b59a2e0273780a51b6fd7528 Mon Sep 17 00:00:00 2001 |
||||
From: Alan Coopersmith <alan.coopersmith@oracle.com> |
||||
Date: Thu, 7 Oct 2021 18:22:11 -0700 |
||||
Subject: [PATCH 1/2] meson: Fix detection of Xorg versions that need -listen |
||||
tcp |
||||
|
||||
Closes #704 |
||||
--- |
||||
meson.build | 4 ++++ |
||||
1 file changed, 4 insertions(+) |
||||
|
||||
diff --git a/meson.build b/meson.build |
||||
index 64b98628..52ac1941 100644 |
||||
--- a/meson.build |
||||
+++ b/meson.build |
||||
@@ -42,60 +42,63 @@ udev_dep = dependency('udev') |
||||
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'), |
||||
], |
||||
) |
||||
+# Xserver 1.17 & later default to -nolisten and require -listen for remote access |
||||
+xserver_deps = dependency('xorg-server', version : '>=1.17', required : false) |
||||
+xserver_nolisten_default = xserver_deps.found() |
||||
find_x_server_script = find_program('build-aux/find-x-server.sh', native: true) |
||||
find_x_server_out = run_command(find_x_server_script).stdout().strip() |
||||
if find_x_server_out != '' |
||||
x_bin = find_x_server_out |
||||
x_bin_path_split = x_bin.split('/') |
||||
i = 0 |
||||
x_path = '/' |
||||
foreach dir : x_bin_path_split |
||||
if i < x_bin_path_split.length() - 1 |
||||
x_path = x_path / dir |
||||
endif |
||||
i = i + 1 |
||||
endforeach |
||||
else |
||||
# what to do, what to do, this is wrong, but this just sets the |
||||
# defaults, perhaps this user is cross compiling or some such |
||||
x_path = '/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin' |
||||
x_bin = '/usr/bin/X' |
||||
endif |
||||
xdmcp_dep = cc.find_library('Xdmcp', required: get_option('xdmcp')) |
||||
if xdmcp_dep.found() and get_option('tcp-wrappers') |
||||
libwrap_dep = cc.find_library('wrap') |
||||
endif |
||||
# systemd |
||||
systemd_dep = dependency('systemd') |
||||
libsystemd_dep = dependency('libsystemd') |
||||
if meson.version().version_compare('>= 0.53') |
||||
systemd_multiseat_x = find_program('systemd-multi-seat-x', |
||||
required: false, |
||||
dirs: [ |
||||
@@ -197,60 +200,61 @@ conf.set_quoted('SYSCONFDIR', gdm_prefix / get_option('sysconfdir')) |
||||
conf.set_quoted('BINDIR', gdm_prefix / get_option('bindir')) |
||||
conf.set_quoted('LIBDIR', gdm_prefix / get_option('libdir')) |
||||
conf.set_quoted('LIBEXECDIR', gdm_prefix / get_option('libexecdir')) |
||||
conf.set_quoted('LOGDIR', get_option('log-dir')) |
||||
conf.set_quoted('DMCONFDIR', dmconfdir) |
||||
conf.set_quoted('GDMCONFDIR', gdmconfdir) |
||||
conf.set_quoted('GDM_SCREENSHOT_DIR', gdm_screenshot_dir) |
||||
conf.set_quoted('GDM_XAUTH_DIR', gdm_xauth_dir) |
||||
conf.set_quoted('GDM_RAN_ONCE_MARKER_DIR', ran_once_marker_dir) |
||||
conf.set_quoted('GDM_RUN_DIR', gdm_run_dir) |
||||
conf.set_quoted('GNOMELOCALEDIR', gdm_prefix / get_option('localedir')) |
||||
conf.set_quoted('AT_SPI_REGISTRYD_DIR', at_spi_registryd_dir) |
||||
conf.set_quoted('GDM_PID_FILE', gdm_pid_file) |
||||
conf.set_quoted('GNOME_SETTINGS_DAEMON_DIR', gnome_settings_daemon_dir) |
||||
conf.set_quoted('LANG_CONFIG_FILE', lang_config_file) |
||||
conf.set('HAVE_ADT', have_adt) |
||||
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_THAT_DEFAULTS_TO_LOCAL_ONLY', xserver_nolisten_default) |
||||
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_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 |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,89 @@
@@ -0,0 +1,89 @@
|
||||
From 8a29f79124f38e2106b263bacb6b5ab4cdb255d0 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Wed, 9 Mar 2022 10:46:21 -0500 |
||||
Subject: [PATCH] session-settings: Fetch session from user even if user isn't |
||||
cached |
||||
|
||||
Now that accountsservice supports session templates, GDM can't assume |
||||
that no-cache file means, there's nothing worth reading. |
||||
|
||||
Unfortunately, GDM does exactly that. It bypasses fetching the users |
||||
session if it doesn't think the user has one. |
||||
|
||||
This commit removes that no-longer-correct optimization. |
||||
--- |
||||
daemon/gdm-session-settings.c | 4 ---- |
||||
1 file changed, 4 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c |
||||
index 5b64cb65..fbf6897b 100644 |
||||
--- a/daemon/gdm-session-settings.c |
||||
+++ b/daemon/gdm-session-settings.c |
||||
@@ -270,64 +270,60 @@ gdm_session_settings_new (void) |
||||
GdmSessionSettings *settings; |
||||
|
||||
settings = g_object_new (GDM_TYPE_SESSION_SETTINGS, |
||||
NULL); |
||||
|
||||
return settings; |
||||
} |
||||
|
||||
gboolean |
||||
gdm_session_settings_is_loaded (GdmSessionSettings *settings) |
||||
{ |
||||
if (settings->priv->user == NULL) { |
||||
return FALSE; |
||||
} |
||||
|
||||
return act_user_is_loaded (settings->priv->user); |
||||
} |
||||
|
||||
static void |
||||
load_settings_from_user (GdmSessionSettings *settings) |
||||
{ |
||||
const char *session_name; |
||||
const char *session_type; |
||||
const char *language_name; |
||||
|
||||
if (!act_user_is_loaded (settings->priv->user)) { |
||||
g_warning ("GdmSessionSettings: trying to load user settings from unloaded user"); |
||||
return; |
||||
} |
||||
|
||||
- /* if the user doesn't have saved state, they don't have any settings worth reading */ |
||||
- if (!act_user_get_saved (settings->priv->user)) |
||||
- goto out; |
||||
- |
||||
session_type = act_user_get_session_type (settings->priv->user); |
||||
session_name = act_user_get_session (settings->priv->user); |
||||
|
||||
g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type); |
||||
|
||||
if (session_type != NULL && session_type[0] != '\0') { |
||||
gdm_session_settings_set_session_type (settings, session_type); |
||||
} |
||||
|
||||
if (session_name != NULL && session_name[0] != '\0') { |
||||
gdm_session_settings_set_session_name (settings, session_name); |
||||
} |
||||
|
||||
language_name = act_user_get_language (settings->priv->user); |
||||
|
||||
g_debug ("GdmSessionSettings: saved language is %s", language_name); |
||||
if (language_name != NULL && language_name[0] != '\0') { |
||||
gdm_session_settings_set_language_name (settings, language_name); |
||||
} |
||||
|
||||
out: |
||||
g_object_notify (G_OBJECT (settings), "is-loaded"); |
||||
} |
||||
|
||||
static void |
||||
on_user_is_loaded_changed (ActUser *user, |
||||
GParamSpec *pspec, |
||||
GdmSessionSettings *settings) |
||||
{ |
||||
if (act_user_is_loaded (settings->priv->user)) { |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
From 26705ee64f4d3628eaaf45db980c435fa26e112a Mon Sep 17 00:00:00 2001 |
||||
From: Chingkai Chu <3013329+chuchingkai@users.noreply.github.com> |
||||
Date: Thu, 12 Aug 2021 10:34:01 +0800 |
||||
Subject: [PATCH] session-worker: Set session_vt=0 out of pam uninitialization |
||||
|
||||
MR GNOME/gdm!123 moved jump_to_vt and session_vt reseting to a |
||||
separate function, so we don't need to reset session_vt in pam |
||||
uninitialization. |
||||
|
||||
https://gitlab.gnome.org/GNOME/gdm/-/issues/719 |
||||
--- |
||||
daemon/gdm-session-worker.c | 2 -- |
||||
1 file changed, 2 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c |
||||
index 7d7d2496..3ad94e2a 100644 |
||||
--- a/daemon/gdm-session-worker.c |
||||
+++ b/daemon/gdm-session-worker.c |
||||
@@ -1076,62 +1076,60 @@ gdm_session_worker_set_state (GdmSessionWorker *worker, |
||||
|
||||
static void |
||||
gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, |
||||
int status) |
||||
{ |
||||
g_debug ("GdmSessionWorker: uninitializing PAM"); |
||||
|
||||
if (worker->priv->pam_handle == NULL) |
||||
return; |
||||
|
||||
gdm_session_worker_get_username (worker, NULL); |
||||
|
||||
if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { |
||||
pam_close_session (worker->priv->pam_handle, 0); |
||||
gdm_session_auditor_report_logout (worker->priv->auditor); |
||||
} else { |
||||
gdm_session_auditor_report_login_failure (worker->priv->auditor, |
||||
status, |
||||
pam_strerror (worker->priv->pam_handle, status)); |
||||
} |
||||
|
||||
if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) { |
||||
pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED); |
||||
} |
||||
|
||||
pam_end (worker->priv->pam_handle, status); |
||||
worker->priv->pam_handle = NULL; |
||||
|
||||
gdm_session_worker_stop_auditor (worker); |
||||
|
||||
- worker->priv->session_vt = 0; |
||||
- |
||||
g_debug ("GdmSessionWorker: state NONE"); |
||||
gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE); |
||||
} |
||||
|
||||
static char * |
||||
_get_tty_for_pam (const char *x11_display_name, |
||||
const char *display_device) |
||||
{ |
||||
#ifdef __sun |
||||
return g_strdup (display_device); |
||||
#else |
||||
return g_strdup (x11_display_name); |
||||
#endif |
||||
} |
||||
|
||||
#ifdef PAM_XAUTHDATA |
||||
static struct pam_xauth_data * |
||||
_get_xauth_for_pam (const char *x11_authority_file) |
||||
{ |
||||
FILE *fh; |
||||
Xauth *auth = NULL; |
||||
struct pam_xauth_data *retval = NULL; |
||||
gsize len = sizeof (*retval) + 1; |
||||
|
||||
fh = fopen (x11_authority_file, "r"); |
||||
if (fh) { |
||||
auth = XauReadAuth (fh); |
||||
fclose (fh); |
||||
} |
||||
if (auth) { |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
From 36b9fd4f6e055e236175979d9a1527df71aeac1f Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Tue, 14 Sep 2021 11:00:33 -0400 |
||||
Subject: [PATCH 1/5] xdmcp-display-factory: Set supported session types for |
||||
XDMCP displays |
||||
|
||||
The lower levels of GDM now expect the session types supported by a |
||||
display to be specified up front. |
||||
|
||||
This commit makes sure XDMCP displays do that. |
||||
--- |
||||
daemon/gdm-xdmcp-display-factory.c | 6 ++++++ |
||||
1 file changed, 6 insertions(+) |
||||
|
||||
diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c |
||||
index ce8f026e..abb58fae 100644 |
||||
--- a/daemon/gdm-xdmcp-display-factory.c |
||||
+++ b/daemon/gdm-xdmcp-display-factory.c |
||||
@@ -2104,94 +2104,100 @@ on_display_status_changed (GdmDisplay *display, |
||||
break; |
||||
case GDM_DISPLAY_MANAGED: |
||||
if (session != NULL) { |
||||
g_signal_connect_object (G_OBJECT (session), |
||||
"client-disconnected", |
||||
G_CALLBACK (on_client_disconnected), |
||||
display, G_CONNECT_SWAPPED); |
||||
g_signal_connect_object (G_OBJECT (session), |
||||
"disconnected", |
||||
G_CALLBACK (on_client_disconnected), |
||||
display, G_CONNECT_SWAPPED); |
||||
} |
||||
break; |
||||
default: |
||||
g_assert_not_reached (); |
||||
break; |
||||
} |
||||
|
||||
g_clear_object (&launch_environment); |
||||
} |
||||
|
||||
static GdmDisplay * |
||||
gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, |
||||
const char *hostname, |
||||
GdmAddress *address, |
||||
int displaynum) |
||||
{ |
||||
GdmDisplay *display; |
||||
GdmDisplayStore *store; |
||||
gboolean use_chooser; |
||||
+ const char *session_types[] = { "x11", NULL }; |
||||
|
||||
g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d", |
||||
hostname ? hostname : "(null)", displaynum); |
||||
|
||||
use_chooser = FALSE; |
||||
if (factory->honor_indirect) { |
||||
IndirectClient *ic; |
||||
|
||||
ic = indirect_client_lookup (factory, address); |
||||
|
||||
/* This was an indirect thingie and nothing was yet chosen, |
||||
* use a chooser */ |
||||
if (ic != NULL && ic->chosen_address == NULL) { |
||||
use_chooser = TRUE; |
||||
} |
||||
} |
||||
|
||||
if (use_chooser) { |
||||
display = gdm_xdmcp_chooser_display_new (hostname, |
||||
displaynum, |
||||
address, |
||||
get_next_session_serial (factory)); |
||||
g_signal_connect (display, "hostname-selected", G_CALLBACK (on_hostname_selected), factory); |
||||
} else { |
||||
display = gdm_xdmcp_display_new (hostname, |
||||
displaynum, |
||||
address, |
||||
get_next_session_serial (factory)); |
||||
} |
||||
|
||||
if (display == NULL) { |
||||
goto out; |
||||
} |
||||
|
||||
+ g_object_set (G_OBJECT (display), |
||||
+ "session-type", session_types[0], |
||||
+ "supported-session-types", session_types, |
||||
+ NULL); |
||||
+ |
||||
if (! gdm_display_prepare (display)) { |
||||
gdm_display_unmanage (display); |
||||
g_object_unref (display); |
||||
display = NULL; |
||||
goto out; |
||||
} |
||||
|
||||
g_signal_connect_after (display, |
||||
"notify::status", |
||||
G_CALLBACK (on_display_status_changed), |
||||
factory); |
||||
|
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
gdm_display_store_add (store, display); |
||||
|
||||
factory->num_pending_sessions++; |
||||
out: |
||||
|
||||
return display; |
||||
} |
||||
|
||||
static void |
||||
gdm_xdmcp_send_accept (GdmXdmcpDisplayFactory *factory, |
||||
GdmAddress *address, |
||||
CARD32 session_id, |
||||
ARRAY8Ptr authentication_name, |
||||
ARRAY8Ptr authentication_data, |
||||
ARRAY8Ptr authorization_name, |
||||
ARRAY8Ptr authorization_data) |
||||
{ |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,356 @@
@@ -0,0 +1,356 @@
|
||||
From d3e073fa1cd314b344db1ec22f0add2702a6c299 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Tue, 15 Feb 2022 14:33:22 -0500 |
||||
Subject: [PATCH 2/4] common: Add API to reload settings from disk |
||||
|
||||
Ideally we would reread /run/gdm/custom.conf after we've decided |
||||
graphics setup is complete. This is because the file may not |
||||
get written out by udev until after GDM is already started and waiting. |
||||
|
||||
As a first step to get there, this commit adds an API for rereading |
||||
the file, and changes the SIGHUP handler to use it (instead of |
||||
the complete teardown and reinitialization it was doing before). |
||||
--- |
||||
common/gdm-settings-direct.c | 9 +++++++++ |
||||
common/gdm-settings-direct.h | 2 ++ |
||||
common/gdm-settings.c | 14 ++++++++++++-- |
||||
common/gdm-settings.h | 1 + |
||||
daemon/main.c | 12 ++---------- |
||||
5 files changed, 26 insertions(+), 12 deletions(-) |
||||
|
||||
diff --git a/common/gdm-settings-direct.c b/common/gdm-settings-direct.c |
||||
index ddb31908..5fbe0326 100644 |
||||
--- a/common/gdm-settings-direct.c |
||||
+++ b/common/gdm-settings-direct.c |
||||
@@ -224,35 +224,44 @@ hashify_list (GdmSettingsEntry *entry, |
||||
|
||||
gboolean |
||||
gdm_settings_direct_init (GdmSettings *settings, |
||||
const char *file, |
||||
const char *root) |
||||
{ |
||||
GSList *list; |
||||
|
||||
g_return_val_if_fail (file != NULL, FALSE); |
||||
g_return_val_if_fail (root != NULL, FALSE); |
||||
|
||||
g_debug ("Settings Direct Init"); |
||||
if (schemas != NULL) { |
||||
g_hash_table_unref (schemas); |
||||
schemas = NULL; |
||||
} |
||||
|
||||
if (! gdm_settings_parse_schemas (file, root, &list)) { |
||||
g_warning ("Unable to parse schemas"); |
||||
return FALSE; |
||||
} |
||||
|
||||
schemas = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)gdm_settings_entry_free); |
||||
g_slist_foreach (list, (GFunc)hashify_list, NULL); |
||||
|
||||
settings_object = settings; |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
+void |
||||
+gdm_settings_direct_reload (void) |
||||
+{ |
||||
+ if (!settings_object) |
||||
+ return; |
||||
+ |
||||
+ gdm_settings_reload (settings_object); |
||||
+} |
||||
+ |
||||
void |
||||
gdm_settings_direct_shutdown (void) |
||||
{ |
||||
|
||||
} |
||||
diff --git a/common/gdm-settings-direct.h b/common/gdm-settings-direct.h |
||||
index 156489cd..6754955f 100644 |
||||
--- a/common/gdm-settings-direct.h |
||||
+++ b/common/gdm-settings-direct.h |
||||
@@ -3,48 +3,50 @@ |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef __GDM_SETTINGS_DIRECT_H |
||||
#define __GDM_SETTINGS_DIRECT_H |
||||
|
||||
#include <glib-object.h> |
||||
#include "gdm-settings.h" |
||||
|
||||
G_BEGIN_DECLS |
||||
|
||||
gboolean gdm_settings_direct_init (GdmSettings *settings, |
||||
const char *schemas_file, |
||||
const char *root); |
||||
+ |
||||
+void gdm_settings_direct_reload (void); |
||||
void gdm_settings_direct_shutdown (void); |
||||
|
||||
gboolean gdm_settings_direct_get (const char *key, |
||||
GValue *value); |
||||
gboolean gdm_settings_direct_set (const char *key, |
||||
GValue *value); |
||||
gboolean gdm_settings_direct_get_int (const char *key, |
||||
int *value); |
||||
gboolean gdm_settings_direct_get_uint (const char *key, |
||||
uint *value); |
||||
gboolean gdm_settings_direct_get_boolean (const char *key, |
||||
gboolean *value); |
||||
gboolean gdm_settings_direct_get_string (const char *key, |
||||
char **value); |
||||
|
||||
G_END_DECLS |
||||
|
||||
#endif /* __GDM_SETTINGS_DIRECT_H */ |
||||
diff --git a/common/gdm-settings.c b/common/gdm-settings.c |
||||
index e6f46ec3..96c2f8d3 100644 |
||||
--- a/common/gdm-settings.c |
||||
+++ b/common/gdm-settings.c |
||||
@@ -157,84 +157,94 @@ gdm_settings_class_init (GdmSettingsClass *klass) |
||||
object_class->finalize = gdm_settings_finalize; |
||||
|
||||
signals [VALUE_CHANGED] = |
||||
g_signal_new ("value-changed", |
||||
G_TYPE_FROM_CLASS (object_class), |
||||
G_SIGNAL_RUN_LAST, |
||||
0, |
||||
NULL, |
||||
NULL, |
||||
g_cclosure_marshal_generic, |
||||
G_TYPE_NONE, |
||||
3, |
||||
G_TYPE_STRING, |
||||
G_TYPE_STRING, |
||||
G_TYPE_STRING); |
||||
} |
||||
|
||||
static void |
||||
backend_value_changed (GdmSettingsBackend *backend, |
||||
const char *key, |
||||
const char *old_value, |
||||
const char *new_value, |
||||
GdmSettings *settings) |
||||
{ |
||||
g_debug ("Emitting value-changed %s %s %s", key, old_value, new_value); |
||||
|
||||
/* proxy it to internal listeners */ |
||||
g_signal_emit (settings, signals [VALUE_CHANGED], 0, key, old_value, new_value); |
||||
} |
||||
|
||||
-static void |
||||
-gdm_settings_init (GdmSettings *settings) |
||||
+void |
||||
+gdm_settings_reload (GdmSettings *settings) |
||||
{ |
||||
GList *l; |
||||
GdmSettingsBackend *backend; |
||||
|
||||
+ g_list_foreach (settings->backends, (GFunc) g_object_unref, NULL); |
||||
+ g_list_free (settings->backends); |
||||
+ settings->backends = NULL; |
||||
+ |
||||
backend = gdm_settings_desktop_backend_new (GDM_CUSTOM_CONF); |
||||
if (backend) |
||||
settings->backends = g_list_prepend (NULL, backend); |
||||
|
||||
backend = gdm_settings_desktop_backend_new (GDM_RUNTIME_CONF); |
||||
if (backend) |
||||
settings->backends = g_list_prepend (settings->backends, backend); |
||||
|
||||
for (l = settings->backends; l; l = g_list_next (l)) { |
||||
backend = l->data; |
||||
|
||||
g_signal_connect (backend, |
||||
"value-changed", |
||||
G_CALLBACK (backend_value_changed), |
||||
settings); |
||||
} |
||||
} |
||||
|
||||
+static void |
||||
+gdm_settings_init (GdmSettings *settings) |
||||
+{ |
||||
+ gdm_settings_reload (settings); |
||||
+} |
||||
+ |
||||
static void |
||||
gdm_settings_finalize (GObject *object) |
||||
{ |
||||
GdmSettings *settings; |
||||
|
||||
g_return_if_fail (object != NULL); |
||||
g_return_if_fail (GDM_IS_SETTINGS (object)); |
||||
|
||||
settings = GDM_SETTINGS (object); |
||||
|
||||
g_return_if_fail (settings != NULL); |
||||
|
||||
g_list_foreach (settings->backends, (GFunc) g_object_unref, NULL); |
||||
g_list_free (settings->backends); |
||||
settings->backends = NULL; |
||||
|
||||
settings_object = NULL; |
||||
|
||||
G_OBJECT_CLASS (gdm_settings_parent_class)->finalize (object); |
||||
} |
||||
|
||||
GdmSettings * |
||||
gdm_settings_new (void) |
||||
{ |
||||
if (settings_object != NULL) { |
||||
g_object_ref (settings_object); |
||||
} else { |
||||
settings_object = g_object_new (GDM_TYPE_SETTINGS, NULL); |
||||
} |
||||
|
||||
diff --git a/common/gdm-settings.h b/common/gdm-settings.h |
||||
index 786868a9..07b64785 100644 |
||||
--- a/common/gdm-settings.h |
||||
+++ b/common/gdm-settings.h |
||||
@@ -13,45 +13,46 @@ |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef __GDM_SETTINGS_H |
||||
#define __GDM_SETTINGS_H |
||||
|
||||
#include <glib-object.h> |
||||
|
||||
G_BEGIN_DECLS |
||||
|
||||
#define GDM_TYPE_SETTINGS (gdm_settings_get_type ()) |
||||
G_DECLARE_FINAL_TYPE (GdmSettings, gdm_settings, GDM, SETTINGS, GObject) |
||||
|
||||
typedef enum |
||||
{ |
||||
GDM_SETTINGS_ERROR_GENERAL, |
||||
GDM_SETTINGS_ERROR_KEY_NOT_FOUND |
||||
} GdmSettingsError; |
||||
|
||||
#define GDM_SETTINGS_ERROR gdm_settings_error_quark () |
||||
|
||||
GQuark gdm_settings_error_quark (void); |
||||
|
||||
GdmSettings * gdm_settings_new (void); |
||||
+void gdm_settings_reload (GdmSettings *settings); |
||||
|
||||
/* exported */ |
||||
|
||||
gboolean gdm_settings_get_value (GdmSettings *settings, |
||||
const char *key, |
||||
char **value, |
||||
GError **error); |
||||
gboolean gdm_settings_set_value (GdmSettings *settings, |
||||
const char *key, |
||||
const char *value, |
||||
GError **error); |
||||
|
||||
G_END_DECLS |
||||
|
||||
#endif /* __GDM_SETTINGS_H */ |
||||
diff --git a/daemon/main.c b/daemon/main.c |
||||
index 1b893fe0..344d1b74 100644 |
||||
--- a/daemon/main.c |
||||
+++ b/daemon/main.c |
||||
@@ -240,70 +240,62 @@ gdm_daemon_lookup_user (uid_t *uidp, |
||||
if G_UNLIKELY (gid == 0) { |
||||
gdm_fail (_("The GDM group should not be root. Aborting!")); |
||||
} |
||||
|
||||
if (uidp != NULL) { |
||||
*uidp = uid; |
||||
} |
||||
|
||||
if (gidp != NULL) { |
||||
*gidp = gid; |
||||
} |
||||
|
||||
g_free (username); |
||||
g_free (groupname); |
||||
} |
||||
|
||||
static gboolean |
||||
on_shutdown_signal_cb (gpointer user_data) |
||||
{ |
||||
GMainLoop *mainloop = user_data; |
||||
|
||||
g_main_loop_quit (mainloop); |
||||
|
||||
return FALSE; |
||||
} |
||||
|
||||
static gboolean |
||||
on_sighup_cb (gpointer user_data) |
||||
{ |
||||
g_debug ("Got HUP signal"); |
||||
- /* Reread config stuff like system config files, VPN service |
||||
- * files, etc |
||||
- */ |
||||
- g_object_unref (settings); |
||||
- settings = gdm_settings_new (); |
||||
- if (settings != NULL) { |
||||
- if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) { |
||||
- g_warning ("Unable to initialize settings"); |
||||
- } |
||||
- } |
||||
+ |
||||
+ gdm_settings_reload (settings); |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
static gboolean |
||||
is_debug_set (void) |
||||
{ |
||||
gboolean debug; |
||||
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); |
||||
return debug; |
||||
} |
||||
|
||||
/* SIGUSR1 is used by the X server to tell us that we're ready, so |
||||
* block it. We'll unblock it in the worker thread in gdm-server.c |
||||
*/ |
||||
static void |
||||
block_sigusr1 (void) |
||||
{ |
||||
sigset_t mask; |
||||
|
||||
sigemptyset (&mask); |
||||
sigaddset (&mask, SIGUSR1); |
||||
sigprocmask (SIG_BLOCK, &mask, NULL); |
||||
} |
||||
|
||||
int |
||||
main (int argc, |
||||
char **argv) |
||||
{ |
||||
GMainLoop *main_loop; |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
From b09ab8a73d5a4133f72846d529bbbfb7802ca535 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Mon, 6 Sep 2021 08:40:46 -0400 |
||||
Subject: [PATCH 2/5] daemon: Don't update session type if no saved session |
||||
|
||||
At the moment we always set the session type when the session name |
||||
is read. But users don't always have a session type specified. |
||||
|
||||
If they don't, then don't set the session type. |
||||
|
||||
https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/153 |
||||
--- |
||||
daemon/gdm-session.c | 23 +++++++++++++---------- |
||||
1 file changed, 13 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c |
||||
index 2b941e5e..b54687d5 100644 |
||||
--- a/daemon/gdm-session.c |
||||
+++ b/daemon/gdm-session.c |
||||
@@ -995,73 +995,76 @@ worker_on_reauthenticated (GdmDBusWorker *worker, |
||||
static void |
||||
worker_on_saved_language_name_read (GdmDBusWorker *worker, |
||||
const char *language_name, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSession *self = conversation->session; |
||||
|
||||
if (strlen (language_name) > 0) { |
||||
g_free (self->saved_language); |
||||
self->saved_language = g_strdup (language_name); |
||||
|
||||
if (self->greeter_interface != NULL) { |
||||
gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface, |
||||
language_name); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void |
||||
worker_on_saved_session_name_read (GdmDBusWorker *worker, |
||||
const char *session_name, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSession *self = conversation->session; |
||||
|
||||
if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) { |
||||
/* ignore sessions that don't exist */ |
||||
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); |
||||
g_free (self->saved_session); |
||||
self->saved_session = NULL; |
||||
- } else if (strcmp (session_name, |
||||
- get_default_session_name (self)) != 0) { |
||||
- g_free (self->saved_session); |
||||
- self->saved_session = g_strdup (session_name); |
||||
- |
||||
- if (self->greeter_interface != NULL) { |
||||
- gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, |
||||
- session_name); |
||||
+ update_session_type (self); |
||||
+ } else { |
||||
+ if (strcmp (session_name, |
||||
+ get_default_session_name (self)) != 0) { |
||||
+ g_free (self->saved_session); |
||||
+ self->saved_session = g_strdup (session_name); |
||||
+ |
||||
+ if (self->greeter_interface != NULL) { |
||||
+ gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, |
||||
+ session_name); |
||||
+ } |
||||
} |
||||
+ if (self->saved_session_type != NULL) |
||||
+ set_session_type (self, self->saved_session_type); |
||||
} |
||||
|
||||
- update_session_type (self); |
||||
- |
||||
} |
||||
|
||||
static void |
||||
worker_on_saved_session_type_read (GdmDBusWorker *worker, |
||||
const char *session_type, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSession *self = conversation->session; |
||||
|
||||
g_free (self->saved_session_type); |
||||
self->saved_session_type = g_strdup (session_type); |
||||
} |
||||
|
||||
static GdmSessionConversation * |
||||
find_conversation_by_pid (GdmSession *self, |
||||
GPid pid) |
||||
{ |
||||
GHashTableIter iter; |
||||
gpointer key, value; |
||||
|
||||
g_hash_table_iter_init (&iter, self->conversations); |
||||
while (g_hash_table_iter_next (&iter, &key, &value)) { |
||||
GdmSessionConversation *conversation; |
||||
|
||||
conversation = (GdmSessionConversation *) value; |
||||
|
||||
if (conversation->worker_pid == pid) { |
||||
return conversation; |
||||
} |
||||
} |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,327 @@
@@ -0,0 +1,327 @@
|
||||
From cc67c8de39358031fddc5ca7d8c993271d6606a7 Mon Sep 17 00:00:00 2001 |
||||
From: Alan Coopersmith <alan.coopersmith@oracle.com> |
||||
Date: Thu, 7 Oct 2021 18:22:11 -0700 |
||||
Subject: [PATCH 2/2] daemon: Support X servers built with -Dlisten_tcp=true |
||||
|
||||
Xorg since version 1.17 doesn't listen to tcp sockets by default |
||||
unless it's explicitly built with -Dlisten_tcp=true. |
||||
|
||||
GDM currently assumes X servers 1.17 and later are always built |
||||
without specifying -Dlisten_tcp=true and doesn't work properly |
||||
otherwise. |
||||
|
||||
This commit enhances GDM to better handle these non-standard builds by |
||||
always passing '-nolisten tcp' on the command line when tcp should |
||||
be disabled, and likewise always passing '-listen tcp' on the command |
||||
line, assuming the X server is new enough to support it, when tcp |
||||
should be enabled. |
||||
|
||||
Related #704 |
||||
--- |
||||
daemon/gdm-server.c | 21 +++++++++++---------- |
||||
daemon/gdm-x-session.c | 12 ++++++------ |
||||
meson.build | 4 ++-- |
||||
3 files changed, 19 insertions(+), 18 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c |
||||
index 1ba00d45..e5d23521 100644 |
||||
--- a/daemon/gdm-server.c |
||||
+++ b/daemon/gdm-server.c |
||||
@@ -290,72 +290,73 @@ gdm_server_resolve_command_line (GdmServer *server, |
||||
if (strcmp (arg, "-query") == 0 || |
||||
strcmp (arg, "-indirect") == 0) |
||||
query_in_arglist = TRUE; |
||||
} |
||||
|
||||
argv = g_renew (char *, argv, len + 12); |
||||
/* shift args down one */ |
||||
for (i = len - 1; i >= 1; i--) { |
||||
argv[i+1] = argv[i]; |
||||
} |
||||
|
||||
/* server number is the FIRST argument, before any others */ |
||||
argv[1] = g_strdup (server->display_name); |
||||
len++; |
||||
|
||||
if (server->auth_file != NULL) { |
||||
argv[len++] = g_strdup ("-auth"); |
||||
argv[len++] = g_strdup (server->auth_file); |
||||
} |
||||
|
||||
if (server->display_seat_id != NULL) { |
||||
argv[len++] = g_strdup ("-seat"); |
||||
argv[len++] = g_strdup (server->display_seat_id); |
||||
} |
||||
|
||||
/* If we were compiled with Xserver >= 1.17 we need to specify |
||||
* '-listen tcp' as the X server dosen't listen on tcp sockets |
||||
* by default anymore. In older versions we need to pass |
||||
* -nolisten tcp to disable listening on tcp sockets. |
||||
*/ |
||||
-#ifdef HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY |
||||
- if (!server->disable_tcp && ! query_in_arglist) { |
||||
- argv[len++] = g_strdup ("-listen"); |
||||
- argv[len++] = g_strdup ("tcp"); |
||||
- } |
||||
-#else |
||||
- if (server->disable_tcp && ! query_in_arglist) { |
||||
- argv[len++] = g_strdup ("-nolisten"); |
||||
- argv[len++] = g_strdup ("tcp"); |
||||
- } |
||||
+ if (!query_in_arglist) { |
||||
+ if (server->disable_tcp) { |
||||
+ argv[len++] = g_strdup ("-nolisten"); |
||||
+ argv[len++] = g_strdup ("tcp"); |
||||
+ } |
||||
|
||||
+#ifdef HAVE_XSERVER_WITH_LISTEN |
||||
+ if (!server->disable_tcp) { |
||||
+ argv[len++] = g_strdup ("-listen"); |
||||
+ argv[len++] = g_strdup ("tcp"); |
||||
+ } |
||||
#endif |
||||
+ } |
||||
|
||||
if (vtarg != NULL && ! gotvtarg) { |
||||
argv[len++] = g_strdup (vtarg); |
||||
} |
||||
|
||||
argv[len++] = NULL; |
||||
|
||||
*argvp = argv; |
||||
*argcp = len; |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
static void |
||||
rotate_logs (const char *path, |
||||
guint n_copies) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = n_copies - 1; i > 0; i--) { |
||||
char *name_n; |
||||
char *name_n1; |
||||
|
||||
name_n = g_strdup_printf ("%s.%d", path, i); |
||||
if (i > 1) { |
||||
name_n1 = g_strdup_printf ("%s.%d", path, i - 1); |
||||
} else { |
||||
name_n1 = g_strdup (path); |
||||
} |
||||
|
||||
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c |
||||
index 5962da57..0b07ab5b 100644 |
||||
--- a/daemon/gdm-x-session.c |
||||
+++ b/daemon/gdm-x-session.c |
||||
@@ -233,70 +233,70 @@ spawn_x_server (State *state, |
||||
|
||||
if (g_getenv ("XDG_VTNR") != NULL) { |
||||
int vt; |
||||
|
||||
vt = atoi (g_getenv ("XDG_VTNR")); |
||||
|
||||
if (vt > 0 && vt < 64) { |
||||
vt_string = g_strdup_printf ("vt%d", vt); |
||||
} |
||||
} |
||||
|
||||
display_fd_string = g_strdup_printf ("%d", DISPLAY_FILENO); |
||||
|
||||
g_ptr_array_add (arguments, X_SERVER); |
||||
|
||||
if (vt_string != NULL) { |
||||
g_ptr_array_add (arguments, vt_string); |
||||
} |
||||
|
||||
g_ptr_array_add (arguments, "-displayfd"); |
||||
g_ptr_array_add (arguments, display_fd_string); |
||||
|
||||
g_ptr_array_add (arguments, "-auth"); |
||||
g_ptr_array_add (arguments, auth_file); |
||||
|
||||
/* If we were compiled with Xserver >= 1.17 we need to specify |
||||
* '-listen tcp' as the X server doesn't listen on tcp sockets |
||||
* by default anymore. In older versions we need to pass |
||||
* -nolisten tcp to disable listening on tcp sockets. |
||||
*/ |
||||
-#ifdef HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY |
||||
- if (allow_remote_connections) { |
||||
- g_ptr_array_add (arguments, "-listen"); |
||||
- g_ptr_array_add (arguments, "tcp"); |
||||
- } |
||||
-#else |
||||
if (!allow_remote_connections) { |
||||
g_ptr_array_add (arguments, "-nolisten"); |
||||
g_ptr_array_add (arguments, "tcp"); |
||||
} |
||||
+ |
||||
+#ifdef HAVE_XSERVER_WITH_LISTEN |
||||
+ if (allow_remote_connections) { |
||||
+ g_ptr_array_add (arguments, "-listen"); |
||||
+ g_ptr_array_add (arguments, "tcp"); |
||||
+ } |
||||
#endif |
||||
|
||||
g_ptr_array_add (arguments, "-background"); |
||||
g_ptr_array_add (arguments, "none"); |
||||
|
||||
g_ptr_array_add (arguments, "-noreset"); |
||||
g_ptr_array_add (arguments, "-keeptty"); |
||||
g_ptr_array_add (arguments, "-novtswitch"); |
||||
|
||||
g_ptr_array_add (arguments, "-verbose"); |
||||
if (state->debug_enabled) { |
||||
g_ptr_array_add (arguments, "7"); |
||||
} else { |
||||
g_ptr_array_add (arguments, "3"); |
||||
} |
||||
|
||||
if (state->debug_enabled) { |
||||
g_ptr_array_add (arguments, "-core"); |
||||
} |
||||
g_ptr_array_add (arguments, NULL); |
||||
|
||||
subprocess = g_subprocess_launcher_spawnv (launcher, |
||||
(const char * const *) arguments->pdata, |
||||
&error); |
||||
g_free (display_fd_string); |
||||
g_clear_object (&launcher); |
||||
g_ptr_array_free (arguments, TRUE); |
||||
|
||||
if (subprocess == NULL) { |
||||
g_debug ("could not start X server: %s", error->message); |
||||
diff --git a/meson.build b/meson.build |
||||
index 52ac1941..02d609dc 100644 |
||||
--- a/meson.build |
||||
+++ b/meson.build |
||||
@@ -44,61 +44,61 @@ 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'), |
||||
], |
||||
) |
||||
# Xserver 1.17 & later default to -nolisten and require -listen for remote access |
||||
xserver_deps = dependency('xorg-server', version : '>=1.17', required : false) |
||||
-xserver_nolisten_default = xserver_deps.found() |
||||
+xserver_has_listen = xserver_deps.found() |
||||
find_x_server_script = find_program('build-aux/find-x-server.sh', native: true) |
||||
find_x_server_out = run_command(find_x_server_script).stdout().strip() |
||||
if find_x_server_out != '' |
||||
x_bin = find_x_server_out |
||||
x_bin_path_split = x_bin.split('/') |
||||
i = 0 |
||||
x_path = '/' |
||||
foreach dir : x_bin_path_split |
||||
if i < x_bin_path_split.length() - 1 |
||||
x_path = x_path / dir |
||||
endif |
||||
i = i + 1 |
||||
endforeach |
||||
else |
||||
# what to do, what to do, this is wrong, but this just sets the |
||||
# defaults, perhaps this user is cross compiling or some such |
||||
x_path = '/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin' |
||||
x_bin = '/usr/bin/X' |
||||
endif |
||||
xdmcp_dep = cc.find_library('Xdmcp', required: get_option('xdmcp')) |
||||
if xdmcp_dep.found() and get_option('tcp-wrappers') |
||||
libwrap_dep = cc.find_library('wrap') |
||||
endif |
||||
# systemd |
||||
systemd_dep = dependency('systemd') |
||||
libsystemd_dep = dependency('libsystemd') |
||||
if meson.version().version_compare('>= 0.53') |
||||
systemd_multiseat_x = find_program('systemd-multi-seat-x', |
||||
required: false, |
||||
dirs: [ |
||||
@@ -200,61 +200,61 @@ conf.set_quoted('SYSCONFDIR', gdm_prefix / get_option('sysconfdir')) |
||||
conf.set_quoted('BINDIR', gdm_prefix / get_option('bindir')) |
||||
conf.set_quoted('LIBDIR', gdm_prefix / get_option('libdir')) |
||||
conf.set_quoted('LIBEXECDIR', gdm_prefix / get_option('libexecdir')) |
||||
conf.set_quoted('LOGDIR', get_option('log-dir')) |
||||
conf.set_quoted('DMCONFDIR', dmconfdir) |
||||
conf.set_quoted('GDMCONFDIR', gdmconfdir) |
||||
conf.set_quoted('GDM_SCREENSHOT_DIR', gdm_screenshot_dir) |
||||
conf.set_quoted('GDM_XAUTH_DIR', gdm_xauth_dir) |
||||
conf.set_quoted('GDM_RAN_ONCE_MARKER_DIR', ran_once_marker_dir) |
||||
conf.set_quoted('GDM_RUN_DIR', gdm_run_dir) |
||||
conf.set_quoted('GNOMELOCALEDIR', gdm_prefix / get_option('localedir')) |
||||
conf.set_quoted('AT_SPI_REGISTRYD_DIR', at_spi_registryd_dir) |
||||
conf.set_quoted('GDM_PID_FILE', gdm_pid_file) |
||||
conf.set_quoted('GNOME_SETTINGS_DAEMON_DIR', gnome_settings_daemon_dir) |
||||
conf.set_quoted('LANG_CONFIG_FILE', lang_config_file) |
||||
conf.set('HAVE_ADT', have_adt) |
||||
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_THAT_DEFAULTS_TO_LOCAL_ONLY', xserver_nolisten_default) |
||||
+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_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 |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
From 618dfea6563d4f0bad0583b38b63746e44969d5e Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Wed, 5 Feb 2020 15:20:48 -0500 |
||||
Subject: [PATCH 2/3] gdm-x-session: run session bus on non-seat0 seats |
||||
|
||||
GNOME doesn't deal very well with multiple sessions |
||||
running on a multiple seats at the moment. |
||||
|
||||
Until that's fixed, ensure sessions run on auxillary |
||||
seats get their own session bus. |
||||
--- |
||||
daemon/gdm-session.c | 11 ++++++++++- |
||||
1 file changed, 10 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c |
||||
index a65fa0f9..f13b54af 100644 |
||||
--- a/daemon/gdm-session.c |
||||
+++ b/daemon/gdm-session.c |
||||
@@ -2864,119 +2864,128 @@ on_start_program_cb (GdmDBusWorker *worker, |
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) || |
||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
||||
return; |
||||
|
||||
self = conversation->session; |
||||
service_name = conversation->service_name; |
||||
|
||||
if (worked) { |
||||
self->session_pid = pid; |
||||
self->session_conversation = conversation; |
||||
|
||||
g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid); |
||||
g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, pid); |
||||
} else { |
||||
gdm_session_stop_conversation (self, service_name); |
||||
|
||||
g_debug ("GdmSession: Emitting 'session-start-failed' signal"); |
||||
g_signal_emit (self, signals[SESSION_START_FAILED], 0, service_name, error->message); |
||||
} |
||||
} |
||||
|
||||
void |
||||
gdm_session_start_session (GdmSession *self, |
||||
const char *service_name) |
||||
{ |
||||
GdmSessionConversation *conversation; |
||||
GdmSessionDisplayMode display_mode; |
||||
gboolean is_x11 = TRUE; |
||||
gboolean run_launcher = FALSE; |
||||
gboolean allow_remote_connections = FALSE; |
||||
+ gboolean run_separate_bus = FALSE; |
||||
char *command; |
||||
char *program; |
||||
gboolean register_session; |
||||
|
||||
g_return_if_fail (GDM_IS_SESSION (self)); |
||||
g_return_if_fail (self->session_conversation == NULL); |
||||
|
||||
conversation = find_conversation_by_name (self, service_name); |
||||
|
||||
if (conversation == NULL) { |
||||
g_warning ("GdmSession: Tried to start session of " |
||||
"nonexistent conversation %s", service_name); |
||||
return; |
||||
} |
||||
|
||||
stop_all_other_conversations (self, conversation, FALSE); |
||||
|
||||
display_mode = gdm_session_get_display_mode (self); |
||||
|
||||
#ifdef ENABLE_WAYLAND_SUPPORT |
||||
is_x11 = g_strcmp0 (self->session_type, "wayland") != 0; |
||||
#endif |
||||
|
||||
if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED || |
||||
display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) { |
||||
run_launcher = TRUE; |
||||
} |
||||
|
||||
register_session = !gdm_session_session_registers (self); |
||||
|
||||
+ if (g_strcmp0 (self->display_seat_id, "seat0") != 0 && !run_launcher) { |
||||
+ run_separate_bus = TRUE; |
||||
+ } |
||||
+ |
||||
if (self->selected_program == NULL) { |
||||
gboolean run_xsession_script; |
||||
|
||||
command = get_session_command (self); |
||||
|
||||
run_xsession_script = !gdm_session_bypasses_xsession (self); |
||||
|
||||
if (self->display_is_local) { |
||||
gboolean disallow_tcp = TRUE; |
||||
gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp); |
||||
allow_remote_connections = !disallow_tcp; |
||||
} else { |
||||
allow_remote_connections = TRUE; |
||||
} |
||||
|
||||
if (run_launcher) { |
||||
if (is_x11) { |
||||
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"", |
||||
register_session ? "--register-session " : "", |
||||
run_xsession_script? "--run-script " : "", |
||||
allow_remote_connections? "--allow-remote-connections " : "", |
||||
command); |
||||
} else { |
||||
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"", |
||||
register_session ? "--register-session " : "", |
||||
command); |
||||
} |
||||
} else if (run_xsession_script) { |
||||
- program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); |
||||
+ if (run_separate_bus) { |
||||
+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command); |
||||
+ } else { |
||||
+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); |
||||
+ } |
||||
} else { |
||||
program = g_strdup (command); |
||||
} |
||||
|
||||
g_free (command); |
||||
} else { |
||||
/* FIXME: |
||||
* Always use a separate DBus bus for each greeter session. |
||||
* Firstly, this means that if we run multiple greeter session |
||||
* (which we really should not do, but have to currently), then |
||||
* each one will get its own DBus session bus. |
||||
* But, we also explicitly do this for seat0, because that way |
||||
* it cannot make use of systemd to run the GNOME session. This |
||||
* prevents the session lookup logic from getting confused. |
||||
* This has a similar effect as passing --builtin to gnome-session. |
||||
* |
||||
* We really should not be doing this. But the fix is to use |
||||
* separate dynamically created users and that requires some |
||||
* major refactorings. |
||||
*/ |
||||
if (run_launcher) { |
||||
if (is_x11) { |
||||
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"", |
||||
register_session ? "--register-session " : "", |
||||
self->selected_program); |
||||
} else { |
||||
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"", |
||||
register_session ? "--register-session " : "", |
||||
self->selected_program); |
||||
} |
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
From a9928bfcc9c6d81d60e047b7838d4107835b8f89 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Tue, 15 Feb 2022 14:33:22 -0500 |
||||
Subject: [PATCH 3/4] common: Reload settings when graphics initialize |
||||
|
||||
If GDM starts faster than graphics initialize, then the |
||||
udev rules that write out /run/gdm/custom.conf might get |
||||
run too late for GDM to notice. |
||||
|
||||
This commit changes GDM to reread its config after graphicals |
||||
initialization completes. |
||||
|
||||
https://gitlab.gnome.org/GNOME/gdm/-/issues/763 |
||||
--- |
||||
daemon/gdm-local-display-factory.c | 7 +++++-- |
||||
1 file changed, 5 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||
index 0b1d3482..8bca8ce9 100644 |
||||
--- a/daemon/gdm-local-display-factory.c |
||||
+++ b/daemon/gdm-local-display-factory.c |
||||
@@ -1023,64 +1023,66 @@ on_seat_properties_changed (GDBusConnection *connection, |
||||
g_autoptr(GVariant) changed_prop = NULL; |
||||
g_autofree const gchar **invalidated_props = NULL; |
||||
gboolean changed = FALSE; |
||||
int ret; |
||||
|
||||
/* Extract seat id, i.e. the last element of the object path. */ |
||||
seat = strrchr (object_path, '/'); |
||||
if (seat == NULL) |
||||
return; |
||||
seat += 1; |
||||
|
||||
/* Valid seat IDs must start with seat, i.e. ignore "auto" */ |
||||
if (!g_str_has_prefix (seat, "seat")) |
||||
return; |
||||
|
||||
g_variant_get (parameters, "(s@a{sv}^a&s)", NULL, &changed_props, &invalidated_props); |
||||
|
||||
changed_prop = g_variant_lookup_value (changed_props, "CanGraphical", NULL); |
||||
if (changed_prop) |
||||
changed = TRUE; |
||||
if (!changed && g_strv_contains (invalidated_props, "CanGraphical")) |
||||
changed = TRUE; |
||||
|
||||
if (!changed) |
||||
return; |
||||
|
||||
ret = sd_seat_can_graphical (seat); |
||||
if (ret < 0) |
||||
return; |
||||
|
||||
- if (ret != 0) |
||||
+ if (ret != 0) { |
||||
+ gdm_settings_direct_reload (); |
||||
ensure_display_for_seat (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); |
||||
- else |
||||
+ } else { |
||||
delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); |
||||
+ } |
||||
} |
||||
|
||||
static gboolean |
||||
lookup_by_session_id (const char *id, |
||||
GdmDisplay *display, |
||||
gpointer user_data) |
||||
{ |
||||
const char *looking_for = user_data; |
||||
const char *current; |
||||
|
||||
current = gdm_display_get_session_id (display); |
||||
return g_strcmp0 (current, looking_for) == 0; |
||||
} |
||||
|
||||
static gboolean |
||||
lookup_by_tty (const char *id, |
||||
GdmDisplay *display, |
||||
gpointer user_data) |
||||
{ |
||||
const char *tty_to_find = user_data; |
||||
g_autofree char *tty_to_check = NULL; |
||||
const char *session_id; |
||||
int ret; |
||||
|
||||
session_id = gdm_display_get_session_id (display); |
||||
|
||||
if (!session_id) |
||||
return FALSE; |
||||
|
||||
ret = sd_session_get_tty (session_id, &tty_to_check); |
||||
@@ -1260,60 +1262,61 @@ on_vt_changed (GIOChannel *source, |
||||
} |
||||
|
||||
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; |
||||
|
||||
+ gdm_settings_direct_reload (); |
||||
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); |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
From 7084aea50bdc16ccecb4474ca79403429e79ec0e Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Wed, 29 Sep 2021 11:03:41 -0400 |
||||
Subject: [PATCH 3/5] daemon: Infer session type from desktop file if user has |
||||
no saved session type |
||||
|
||||
The accountsservice user cache file can specify a session type |
||||
associated with the saved session. This is optional though. If one |
||||
isn't specified GDM needs to figure out the session type based on the |
||||
list of preferred session types for the system and the session file |
||||
itself. |
||||
|
||||
It was failing to do the latter, though. This commit fixes that. |
||||
--- |
||||
daemon/gdm-session.c | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c |
||||
index b54687d5..a65fa0f9 100644 |
||||
--- a/daemon/gdm-session.c |
||||
+++ b/daemon/gdm-session.c |
||||
@@ -1009,60 +1009,62 @@ worker_on_saved_language_name_read (GdmDBusWorker *worker, |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void |
||||
worker_on_saved_session_name_read (GdmDBusWorker *worker, |
||||
const char *session_name, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSession *self = conversation->session; |
||||
|
||||
if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) { |
||||
/* ignore sessions that don't exist */ |
||||
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); |
||||
g_free (self->saved_session); |
||||
self->saved_session = NULL; |
||||
update_session_type (self); |
||||
} else { |
||||
if (strcmp (session_name, |
||||
get_default_session_name (self)) != 0) { |
||||
g_free (self->saved_session); |
||||
self->saved_session = g_strdup (session_name); |
||||
|
||||
if (self->greeter_interface != NULL) { |
||||
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, |
||||
session_name); |
||||
} |
||||
} |
||||
if (self->saved_session_type != NULL) |
||||
set_session_type (self, self->saved_session_type); |
||||
+ else |
||||
+ update_session_type (self); |
||||
} |
||||
|
||||
} |
||||
|
||||
static void |
||||
worker_on_saved_session_type_read (GdmDBusWorker *worker, |
||||
const char *session_type, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSession *self = conversation->session; |
||||
|
||||
g_free (self->saved_session_type); |
||||
self->saved_session_type = g_strdup (session_type); |
||||
} |
||||
|
||||
static GdmSessionConversation * |
||||
find_conversation_by_pid (GdmSession *self, |
||||
GPid pid) |
||||
{ |
||||
GHashTableIter iter; |
||||
gpointer key, value; |
||||
|
||||
g_hash_table_iter_init (&iter, self->conversations); |
||||
while (g_hash_table_iter_next (&iter, &key, &value)) { |
||||
GdmSessionConversation *conversation; |
||||
|
||||
conversation = (GdmSessionConversation *) value; |
||||
|
||||
if (conversation->worker_pid == pid) { |
||||
return conversation; |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
From f30e557a8afcdfe5d571a625b4c99606315ed3b4 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Mon, 11 Feb 2019 10:32:55 -0500 |
||||
Subject: [PATCH 3/3] session: ensure login screen over XDMCP connects to its |
||||
session |
||||
|
||||
Right now GTK preferentially picks the wayland display over an |
||||
X11 display if it finds one. |
||||
|
||||
That causes a problem for XDMCP sessions, since there may be a |
||||
wayland display running on the local console for the GDM user. |
||||
|
||||
This commit addresses the issue by forcing the X11 backend if |
||||
the session is X11. |
||||
--- |
||||
daemon/gdm-session.c | 19 +++++++++++++++++++ |
||||
1 file changed, 19 insertions(+) |
||||
|
||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c |
||||
index f13b54af..9f68166e 100644 |
||||
--- a/daemon/gdm-session.c |
||||
+++ b/daemon/gdm-session.c |
||||
@@ -2739,60 +2739,79 @@ set_up_session_environment (GdmSession *self) |
||||
} |
||||
|
||||
static void |
||||
send_display_mode (GdmSession *self, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
GdmSessionDisplayMode mode; |
||||
|
||||
mode = gdm_session_get_display_mode (self); |
||||
gdm_dbus_worker_call_set_session_display_mode (conversation->worker_proxy, |
||||
gdm_session_display_mode_to_string (mode), |
||||
conversation->worker_cancellable, |
||||
NULL, NULL); |
||||
} |
||||
|
||||
static void |
||||
send_session_type (GdmSession *self, |
||||
GdmSessionConversation *conversation) |
||||
{ |
||||
const char *session_type = "x11"; |
||||
|
||||
if (self->session_type != NULL) { |
||||
session_type = self->session_type; |
||||
} |
||||
|
||||
gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, |
||||
"XDG_SESSION_TYPE", |
||||
session_type, |
||||
conversation->worker_cancellable, |
||||
NULL, NULL); |
||||
+ |
||||
+ /* If the session type is x11, then set GDK_BACKEND to x11 as well. |
||||
+ * This is so gnome-session-check-accelerated from an XDMCP connection doesn't |
||||
+ * try to use the wayland display running on the local console for the gdm |
||||
+ * user login screen session. |
||||
+ * |
||||
+ * That's the only case where we let a user log in more than once, so it's |
||||
+ * the only situation that matters. |
||||
+ * |
||||
+ * We can drop this code if we ever switch the login screen to use systemd's |
||||
+ * DynamicUser feature. |
||||
+ */ |
||||
+ if (g_strcmp0 (session_type, "x11") == 0) { |
||||
+ gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, |
||||
+ "GDK_BACKEND", |
||||
+ "x11", |
||||
+ conversation->worker_cancellable, |
||||
+ NULL, NULL); |
||||
+ } |
||||
} |
||||
|
||||
void |
||||
gdm_session_open_session (GdmSession *self, |
||||
const char *service_name) |
||||
{ |
||||
GdmSessionConversation *conversation; |
||||
|
||||
g_return_if_fail (GDM_IS_SESSION (self)); |
||||
|
||||
conversation = find_conversation_by_name (self, service_name); |
||||
|
||||
if (conversation != NULL) { |
||||
send_display_mode (self, conversation); |
||||
send_session_type (self, conversation); |
||||
|
||||
gdm_dbus_worker_call_open (conversation->worker_proxy, |
||||
conversation->worker_cancellable, |
||||
(GAsyncReadyCallback) on_opened, conversation); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
stop_all_other_conversations (GdmSession *self, |
||||
GdmSessionConversation *conversation_to_keep, |
||||
gboolean now) |
||||
{ |
||||
GHashTableIter iter; |
||||
gpointer key, value; |
||||
|
||||
-- |
||||
2.32.0 |
||||
|
@ -0,0 +1,559 @@
@@ -0,0 +1,559 @@
|
||||
From d76d6ff0761d47df938f1dab0daeeecac2feb56e Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Mon, 6 Sep 2021 08:43:28 -0400 |
||||
Subject: [PATCH 4/5] daemon: Consolidate session-type and |
||||
supported-session-types list |
||||
|
||||
There's currently a bug in computing the session-type to use. |
||||
|
||||
The `i > 0` check means wayland will overwrite x11 in the |
||||
transient session type list. |
||||
|
||||
Morever, the separation between "session-type" and |
||||
"supported-session-types" is a little redundant. Since |
||||
supported-session-types is a sorted list, the first item should |
||||
always be the same as "session-type". |
||||
|
||||
This commit addresses the bug and the redundant logic, by computing |
||||
the supported session types early in the function and indexing into |
||||
it to get the session-type. |
||||
|
||||
A future cleanup could probably get rid of session-type entirely. |
||||
|
||||
https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/153 |
||||
--- |
||||
daemon/gdm-local-display-factory.c | 193 +++++++++++++++++------------ |
||||
1 file changed, 116 insertions(+), 77 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||
index 141d64c6..eba38671 100644 |
||||
--- a/daemon/gdm-local-display-factory.c |
||||
+++ b/daemon/gdm-local-display-factory.c |
||||
@@ -197,164 +197,226 @@ get_preferred_display_server (GdmLocalDisplayFactory *factory) |
||||
} |
||||
|
||||
if (!wayland_enabled && !xorg_enabled) { |
||||
return g_strdup ("none"); |
||||
} |
||||
|
||||
gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server); |
||||
|
||||
if (g_strcmp0 (preferred_display_server, "wayland") == 0) { |
||||
if (wayland_enabled) |
||||
return g_strdup (preferred_display_server); |
||||
else |
||||
return g_strdup ("xorg"); |
||||
} |
||||
|
||||
if (g_strcmp0 (preferred_display_server, "xorg") == 0) { |
||||
if (xorg_enabled) |
||||
return g_strdup (preferred_display_server); |
||||
else |
||||
return g_strdup ("wayland"); |
||||
} |
||||
|
||||
if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { |
||||
if (xorg_enabled) |
||||
return g_strdup (preferred_display_server); |
||||
} |
||||
|
||||
return g_strdup ("none"); |
||||
} |
||||
|
||||
+struct GdmDisplayServerConfiguration { |
||||
+ const char *display_server; |
||||
+ const char *key; |
||||
+ const char *binary; |
||||
+ const char *session_type; |
||||
+} display_server_configuration[] = { |
||||
+#ifdef ENABLE_WAYLAND_SUPPORT |
||||
+ { "wayland", GDM_KEY_WAYLAND_ENABLE, "/usr/bin/Xwayland", "wayland" }, |
||||
+#endif |
||||
+ { "xorg", GDM_KEY_XORG_ENABLE, "/usr/bin/Xorg", "x11" }, |
||||
+ { NULL, NULL, NULL }, |
||||
+}; |
||||
+ |
||||
+static gboolean |
||||
+display_server_enabled (GdmLocalDisplayFactory *factory, |
||||
+ const char *display_server) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ for (i = 0; display_server_configuration[i].display_server != NULL; i++) { |
||||
+ const char *key = display_server_configuration[i].key; |
||||
+ const char *binary = display_server_configuration[i].binary; |
||||
+ gboolean enabled = FALSE; |
||||
+ |
||||
+ if (!g_str_equal (display_server_configuration[i].display_server, |
||||
+ display_server)) |
||||
+ continue; |
||||
+ |
||||
+ if (!gdm_settings_direct_get_boolean (key, &enabled) || !enabled) |
||||
+ return FALSE; |
||||
+ |
||||
+ if (!g_file_test (binary, G_FILE_TEST_IS_EXECUTABLE)) |
||||
+ return FALSE; |
||||
+ |
||||
+ return TRUE; |
||||
+ } |
||||
+ |
||||
+ return FALSE; |
||||
+} |
||||
+ |
||||
static const char * |
||||
-gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory, |
||||
- gboolean should_fall_back) |
||||
+get_session_type_for_display_server (GdmLocalDisplayFactory *factory, |
||||
+ const char *display_server) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ for (i = 0; display_server_configuration[i].display_server != NULL; i++) { |
||||
+ if (!g_str_equal (display_server_configuration[i].display_server, |
||||
+ display_server)) |
||||
+ continue; |
||||
+ |
||||
+ return display_server_configuration[i].session_type; |
||||
+ } |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static char ** |
||||
+gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory, |
||||
+ gboolean should_fall_back) |
||||
{ |
||||
- const char *session_types[3] = { NULL }; |
||||
- gsize i, session_type_index = 0; |
||||
g_autofree gchar *preferred_display_server = NULL; |
||||
+ const char *fallback_display_server = NULL; |
||||
+ gboolean wayland_preferred = FALSE; |
||||
+ gboolean xorg_preferred = FALSE; |
||||
+ g_autoptr (GPtrArray) session_types_array = NULL; |
||||
+ char **session_types; |
||||
+ |
||||
+ session_types_array = g_ptr_array_new (); |
||||
|
||||
preferred_display_server = get_preferred_display_server (factory); |
||||
|
||||
- if (g_strcmp0 (preferred_display_server, "wayland") != 0 && |
||||
- g_strcmp0 (preferred_display_server, "xorg") != 0) |
||||
- return NULL; |
||||
+ g_debug ("GdmLocalDisplayFactory: Getting session type (prefers %s, falling back: %s)", |
||||
+ preferred_display_server, should_fall_back? "yes" : "no"); |
||||
|
||||
- for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) { |
||||
-#ifdef ENABLE_WAYLAND_SUPPORT |
||||
- if (i > 0 || |
||||
- g_strcmp0 (preferred_display_server, "wayland") == 0) { |
||||
- gboolean wayland_enabled = FALSE; |
||||
- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { |
||||
- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE)) { |
||||
- session_types[i] = "wayland"; |
||||
- continue; |
||||
- } |
||||
- } |
||||
- } |
||||
-#endif |
||||
+ wayland_preferred = g_str_equal (preferred_display_server, "wayland"); |
||||
+ xorg_preferred = g_str_equal (preferred_display_server, "xorg"); |
||||
+ |
||||
+ if (wayland_preferred) |
||||
+ fallback_display_server = "xorg"; |
||||
+ else if (xorg_preferred) |
||||
+ fallback_display_server = "wayland"; |
||||
+ else |
||||
+ return NULL; |
||||
|
||||
- if (i > 0 || |
||||
- g_strcmp0 (preferred_display_server, "xorg") == 0) { |
||||
- gboolean xorg_enabled = FALSE; |
||||
- if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) { |
||||
- if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE)) { |
||||
- session_types[i] = "x11"; |
||||
- continue; |
||||
- } |
||||
- } |
||||
- } |
||||
+ if (!should_fall_back) { |
||||
+ if (display_server_enabled (factory, preferred_display_server)) |
||||
+ g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, preferred_display_server)); |
||||
} |
||||
|
||||
- if (should_fall_back) |
||||
- session_type_index++; |
||||
+ if (display_server_enabled (factory, fallback_display_server)) |
||||
+ g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server)); |
||||
|
||||
- return session_types[session_type_index]; |
||||
+ if (session_types_array->len == 0) |
||||
+ return NULL; |
||||
+ |
||||
+ g_ptr_array_add (session_types_array, NULL); |
||||
+ |
||||
+ session_types = g_strdupv ((char **) session_types_array->pdata); |
||||
+ |
||||
+ return session_types; |
||||
} |
||||
|
||||
static void |
||||
on_display_disposed (GdmLocalDisplayFactory *factory, |
||||
GdmDisplay *display) |
||||
{ |
||||
g_debug ("GdmLocalDisplayFactory: Display %p disposed", display); |
||||
} |
||||
|
||||
static void |
||||
store_display (GdmLocalDisplayFactory *factory, |
||||
GdmDisplay *display) |
||||
{ |
||||
GdmDisplayStore *store; |
||||
|
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
gdm_display_store_add (store, display); |
||||
} |
||||
|
||||
/* |
||||
Example: |
||||
dbus-send --system --dest=org.gnome.DisplayManager \ |
||||
--type=method_call --print-reply --reply-timeout=2000 \ |
||||
/org/gnome/DisplayManager/Manager \ |
||||
org.gnome.DisplayManager.Manager.GetDisplays |
||||
*/ |
||||
gboolean |
||||
gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, |
||||
char **id, |
||||
GError **error) |
||||
{ |
||||
gboolean ret; |
||||
GdmDisplay *display = NULL; |
||||
gboolean is_initial = FALSE; |
||||
const char *session_type; |
||||
g_autofree gchar *preferred_display_server = NULL; |
||||
|
||||
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); |
||||
|
||||
ret = FALSE; |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: Creating transient display"); |
||||
|
||||
preferred_display_server = get_preferred_display_server (factory); |
||||
|
||||
#ifdef ENABLE_USER_DISPLAY_SERVER |
||||
if (g_strcmp0 (preferred_display_server, "wayland") == 0 || |
||||
g_strcmp0 (preferred_display_server, "xorg") == 0) { |
||||
- session_type = gdm_local_display_factory_get_session_type (factory, FALSE); |
||||
+ g_auto(GStrv) session_types = NULL; |
||||
|
||||
- if (session_type == NULL) { |
||||
+ session_types = gdm_local_display_factory_get_session_types (factory, FALSE); |
||||
+ |
||||
+ if (session_types == NULL) { |
||||
g_set_error_literal (error, |
||||
GDM_DISPLAY_ERROR, |
||||
GDM_DISPLAY_ERROR_GENERAL, |
||||
"Both Wayland and Xorg are unavailable"); |
||||
return FALSE; |
||||
} |
||||
|
||||
display = gdm_local_display_new (); |
||||
- g_object_set (G_OBJECT (display), "session-type", session_type, NULL); |
||||
+ g_object_set (G_OBJECT (display), |
||||
+ "session-type", session_types[0], |
||||
+ "supported-session-tyes", session_types, |
||||
+ NULL); |
||||
is_initial = TRUE; |
||||
} |
||||
#endif |
||||
if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { |
||||
if (display == NULL) { |
||||
guint32 num; |
||||
|
||||
num = take_next_display_number (factory); |
||||
|
||||
display = gdm_legacy_display_new (num); |
||||
} |
||||
} |
||||
|
||||
if (display == NULL) { |
||||
g_set_error_literal (error, |
||||
GDM_DISPLAY_ERROR, |
||||
GDM_DISPLAY_ERROR_GENERAL, |
||||
"Invalid preferred display server configured"); |
||||
return FALSE; |
||||
} |
||||
|
||||
g_object_set (display, |
||||
"seat-id", "seat0", |
||||
"allow-timed-login", FALSE, |
||||
"is-initial", is_initial, |
||||
NULL); |
||||
|
||||
store_display (factory, display); |
||||
|
||||
if (! gdm_display_manage (display)) { |
||||
@@ -549,243 +611,220 @@ lookup_prepared_display_by_seat_id (const char *id, |
||||
|
||||
if (status != GDM_DISPLAY_PREPARED) |
||||
return FALSE; |
||||
|
||||
return lookup_by_seat_id (id, display, user_data); |
||||
} |
||||
|
||||
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; |
||||
- const char *session_type = "wayland"; |
||||
+ 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; |
||||
+ gboolean falling_back = 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); |
||||
|
||||
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; |
||||
} |
||||
|
||||
if (g_strcmp0 (seat_id, "seat0") == 0) { |
||||
is_seat0 = TRUE; |
||||
|
||||
falling_back = factory->num_failures > 0; |
||||
- session_type = gdm_local_display_factory_get_session_type (factory, falling_back); |
||||
+ session_types = gdm_local_display_factory_get_session_types (factory, falling_back); |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s", |
||||
- session_type, falling_back? " fallback" : ""); |
||||
+ 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_type = "x11"; |
||||
+ 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. |
||||
* 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!"); |
||||
g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev."); |
||||
seat_supports_graphics = TRUE; |
||||
- session_type = "x11"; |
||||
wayland_enabled = FALSE; |
||||
+ g_strfreev (session_types); |
||||
+ session_types = g_strdupv ((char **) legacy_session_types); |
||||
} else { |
||||
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); |
||||
} |
||||
} |
||||
|
||||
if (!seat_supports_graphics) |
||||
return; |
||||
|
||||
- if (session_type != NULL) |
||||
+ if (session_types != NULL) |
||||
g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", |
||||
- session_type, seat_id); |
||||
+ session_types[0], seat_id); |
||||
else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) |
||||
g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested", |
||||
seat_id); |
||||
|
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
|
||||
if (is_seat0) |
||||
display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); |
||||
else |
||||
display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); |
||||
|
||||
/* Ensure we don't create the same display more than once */ |
||||
if (display != NULL) { |
||||
g_debug ("GdmLocalDisplayFactory: display already created"); |
||||
return; |
||||
} |
||||
|
||||
/* If we already have a login window, switch to it */ |
||||
if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { |
||||
GdmDisplay *display; |
||||
|
||||
display = gdm_display_store_find (store, |
||||
lookup_by_session_id, |
||||
(gpointer) login_session_id); |
||||
if (display != NULL && |
||||
(gdm_display_get_status (display) == GDM_DISPLAY_MANAGED || |
||||
gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) { |
||||
g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); |
||||
g_debug ("GdmLocalDisplayFactory: session %s found, activating.", |
||||
login_session_id); |
||||
gdm_activate_session_by_id (factory->connection, seat_id, login_session_id); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); |
||||
|
||||
#ifdef ENABLE_USER_DISPLAY_SERVER |
||||
if (g_strcmp0 (preferred_display_server, "wayland") == 0 || |
||||
g_strcmp0 (preferred_display_server, "xorg") == 0) { |
||||
if (is_seat0) { |
||||
- g_autoptr (GPtrArray) supported_session_types = NULL; |
||||
- |
||||
- if (session_type == NULL) { |
||||
- g_warning ("GdmLocalDisplayFactory: Both Wayland and Xorg sessions are unavailable"); |
||||
- return; |
||||
- } |
||||
- |
||||
- supported_session_types = g_ptr_array_new (); |
||||
- |
||||
- if (g_strcmp0 (preferred_display_server, "wayland") == 0) { |
||||
- if (wayland_enabled) |
||||
- g_ptr_array_add (supported_session_types, "wayland"); |
||||
- } else { |
||||
- if (xorg_enabled) |
||||
- g_ptr_array_add (supported_session_types, "x11"); |
||||
- } |
||||
- |
||||
- if (!falling_back) { |
||||
- if (g_strcmp0 (preferred_display_server, "wayland") == 0) { |
||||
- if (xorg_enabled) |
||||
- g_ptr_array_add (supported_session_types, "x11"); |
||||
- } else { |
||||
- if (wayland_enabled) |
||||
- g_ptr_array_add (supported_session_types, "wayland"); |
||||
- } |
||||
- } |
||||
- |
||||
- g_ptr_array_add (supported_session_types, NULL); |
||||
- |
||||
display = gdm_local_display_new (); |
||||
- g_object_set (G_OBJECT (display), "session-type", session_type, NULL); |
||||
- g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types->pdata, NULL); |
||||
+ g_object_set (G_OBJECT (display), |
||||
+ "session-type", session_types[0], |
||||
+ "supported-session-types", session_types, |
||||
+ NULL); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
if (display == NULL) { |
||||
guint32 num; |
||||
- const char *supported_session_types[] = { "x11", NULL }; |
||||
|
||||
num = take_next_display_number (factory); |
||||
|
||||
display = gdm_legacy_display_new (num); |
||||
- g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types, NULL); |
||||
+ g_object_set (G_OBJECT (display), |
||||
+ "session-type", legacy_session_types[0], |
||||
+ "supported-session-types", legacy_session_types, |
||||
+ NULL); |
||||
} |
||||
|
||||
g_object_set (display, "seat-id", seat_id, NULL); |
||||
g_object_set (display, "is-initial", is_seat0, NULL); |
||||
|
||||
store_display (factory, display); |
||||
|
||||
/* let store own the ref */ |
||||
g_object_unref (display); |
||||
|
||||
if (! gdm_display_manage (display)) { |
||||
gdm_display_unmanage (display); |
||||
} |
||||
|
||||
return; |
||||
} |
||||
|
||||
static void |
||||
delete_display (GdmLocalDisplayFactory *factory, |
||||
const char *seat_id) { |
||||
|
||||
GdmDisplayStore *store; |
||||
|
||||
g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id); |
||||
|
||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||
gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); |
||||
} |
||||
|
||||
static gboolean |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
From 0131864b339dc0cc5f23def75e6caa5872c9ed11 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Mon, 7 Mar 2022 10:16:39 -0500 |
||||
Subject: [PATCH 4/4] data: Use latest upstream udev rules |
||||
|
||||
This pulls in the latest udev rule from upstream that gives us |
||||
wayland on nvidia when we can, and disables wayland on nvidia |
||||
when we should. |
||||
|
||||
It also pulls in the latest handling for passthrough gpus. |
||||
--- |
||||
data/61-gdm.rules.in | 139 +++++++++++++++++++++++++++++++++++++++++-- |
||||
1 file changed, 135 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in |
||||
index b1da191f..5dae00ea 100644 |
||||
--- a/data/61-gdm.rules.in |
||||
+++ b/data/61-gdm.rules.in |
||||
@@ -1,6 +1,137 @@ |
||||
+# identify virtio graphics cards to find passthrough setups |
||||
+SUBSYSTEM!="virtio", GOTO="gdm_virtio_device_end" |
||||
+ACTION!="add", GOTO="gdm_virtio_device_end" |
||||
+ATTR{vendor}=="0x1af4", ATTR{device}=="0x0010", RUN+="/usr/bin/touch /run/udev/gdm-machine-has-virtual-gpu", ENV{GDM_MACHINE_HAS_VIRTUAL_GPU}="1", GOTO="gdm_virtio_device_end" |
||||
+LABEL="gdm_virtio_device_end" |
||||
+ |
||||
+SUBSYSTEM!="pci", GOTO="gdm_pci_device_end" |
||||
+ACTION!="bind", GOTO="gdm_pci_device_end" |
||||
+ |
||||
+# identify virtio graphics cards to find passthrough setups |
||||
+# cirrus |
||||
+ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="/usr/bin/touch /run/udev/gdm-machine-has-virtual-gpu", ENV{GDM_MACHINE_HAS_VIRTUAL_GPU}="1", GOTO="gdm_pci_device_end" |
||||
+# vga |
||||
+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", RUN+="/usr/bin/touch /run/udev/gdm-machine-has-virtual-gpu", ENV{GDM_MACHINE_HAS_VIRTUAL_GPU}="1", GOTO="gdm_pci_device_end" |
||||
+# qxl |
||||
+ATTR{vendor}=="0x1234", ATTR{device}=="0x1111", RUN+="/usr/bin/touch /run/udev/gdm-machine-has-virtual-gpu", ENV{GDM_MACHINE_HAS_VIRTUAL_GPU}="1", GOTO="gdm_pci_device_end" |
||||
+ |
||||
# disable Wayland on Hi1710 chipsets |
||||
-ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" |
||||
-# disable Wayland when using the proprietary nvidia driver |
||||
-DRIVER=="nvidia", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" |
||||
+ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", GOTO="gdm_disable_wayland" |
||||
+ |
||||
+# disable Wayland on Matrox chipsets |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", GOTO="gdm_disable_wayland" |
||||
+ |
||||
+# disable Wayland on aspeed chipsets |
||||
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", GOTO="gdm_disable_wayland" |
||||
+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", GOTO="gdm_disable_wayland" |
||||
+ |
||||
+LABEL="gdm_pci_device_end" |
||||
+ |
||||
# disable Wayland if modesetting is disabled |
||||
-IMPORT{cmdline}="nomodeset", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" |
||||
+KERNEL!="card[0-9]*", GOTO="gdm_nomodeset_end" |
||||
+SUBSYSTEM!="drm", GOTO="gdm_nomodeset_end" |
||||
+IMPORT{parent}="GDM_MACHINE_HAS_VIRTUAL_GPU" |
||||
+ENV{GDM_MACHINE_HAS_VIRTUAL_GPU}!="1", RUN+="/usr/bin/touch /run/udev/gdm-machine-has-hardware-gpu" |
||||
+# but keep it enabled for simple framebuffer drivers |
||||
+DRIVERS=="simple-framebuffer", GOTO="gdm_nomodeset_end" |
||||
+IMPORT{cmdline}="nomodeset", GOTO="gdm_disable_wayland" |
||||
+LABEL="gdm_nomodeset_end" |
||||
+ |
||||
+# The vendor nvidia driver has multiple modules that need to be loaded before GDM can make an |
||||
+# informed choice on which way to proceed, so force GDM to wait until NVidia's modules are |
||||
+# loaded before starting up. |
||||
+KERNEL!="nvidia", GOTO="gdm_nvidia_end" |
||||
+SUBSYSTEM!="module", GOTO="gdm_nvidia_end" |
||||
+ACTION!="add", GOTO="gdm_nvidia_end" |
||||
+RUN+="/usr/bin/touch /run/udev/gdm-machine-has-vendor-nvidia-driver" |
||||
+ |
||||
+# Check if suspend/resume services necessary for working wayland support is available |
||||
+TEST{0711}!="/usr/bin/nvidia-sleep.sh", GOTO="gdm_disable_wayland" |
||||
+TEST{0711}!="/usr/lib/systemd/system-sleep/nvidia", GOTO="gdm_disable_wayland" |
||||
+IMPORT{program}="/bin/sh -c \"sed -e 's/: /=/g' -e 's/\([^[:upper:]]\)\([[:upper:]]\)/\1_\2/g' -e 's/[[:lower:]]/\U&/g' -e 's/^/NVIDIA_/' /proc/driver/nvidia/params\"" |
||||
+ENV{NVIDIA_PRESERVE_VIDEO_MEMORY_ALLOCATIONS}!="1", GOTO="gdm_disable_wayland" |
||||
+IMPORT{program}="/bin/sh -c 'echo NVIDIA_HIBERNATE=`systemctl is-enabled nvidia-hibernate`'" |
||||
+ENV{NVIDIA_HIBERNATE}!="enabled", GOTO="gdm_disable_wayland" |
||||
+IMPORT{program}="/bin/sh -c 'echo NVIDIA_RESUME=`systemctl is-enabled nvidia-resume`'" |
||||
+ENV{NVIDIA_RESUME}!="enabled", GOTO="gdm_disable_wayland" |
||||
+IMPORT{program}="/bin/sh -c 'echo NVIDIA_SUSPEND=`systemctl is-enabled nvidia-suspend`'" |
||||
+ENV{NVIDIA_SUSPEND}!="enabled", GOTO="gdm_disable_wayland" |
||||
+LABEL="gdm_nvidia_end" |
||||
+ |
||||
+# If this machine has an internal panel, take note, since it's probably a laptop |
||||
+# FIXME: It could be "ghost connectors" make this pop positive for some workstations |
||||
+# in the wild. If so, we may have to fallback to looking at the chassis type from |
||||
+# dmi data or acpi |
||||
+KERNEL!="card[0-9]-eDP-*", GOTO="gdm_laptop_check_end" |
||||
+SUBSYSTEM!="drm", GOTO="gdm_laptop_check_end" |
||||
+ACTION!="add", GOTO="gdm_laptop_check_end" |
||||
+RUN+="/usr/bin/touch /run/udev/gdm-machine-is-laptop" |
||||
+GOTO="gdm_hybrid_nvidia_laptop_check" |
||||
+LABEL="gdm_laptop_check_end" |
||||
+ |
||||
+# If this is a hybrid graphics setup, take note |
||||
+KERNEL!="card[1-9]*", GOTO="gdm_hybrid_graphics_check_end" |
||||
+KERNEL=="card[1-9]-*", GOTO="gdm_hybrid_graphics_check_end" |
||||
+SUBSYSTEM!="drm", GOTO="gdm_hybrid_graphics_check_end" |
||||
+ACTION!="add", GOTO="gdm_hybrid_graphics_check_end" |
||||
+RUN+="/usr/bin/touch /run/udev/gdm-machine-has-hybrid-graphics" |
||||
+LABEL="gdm_hybrid_graphics_check_end" |
||||
+ |
||||
+# If this is a hybrid graphics laptop with vendor nvidia driver, disable wayland |
||||
+LABEL="gdm_hybrid_nvidia_laptop_check" |
||||
+TEST!="/run/udev/gdm-machine-is-laptop", GOTO="gdm_hybrid_nvidia_laptop_check_end" |
||||
+TEST!="/run/udev/gdm-machine-has-hybrid-graphics", GOTO="gdm_hybrid_nvidia_laptop_check_end" |
||||
+TEST!="/run/udev/gdm-machine-has-vendor-nvidia-driver", GOTO="gdm_hybrid_nvidia_laptop_check_end" |
||||
+GOTO="gdm_disable_wayland" |
||||
+LABEL="gdm_hybrid_nvidia_laptop_check_end" |
||||
+ |
||||
+# Disable wayland in situation where we're in a guest with a virtual gpu and host passthrough gpu |
||||
+LABEL="gdm_virt_passthrough_check" |
||||
+TEST!="/run/udev/gdm-machine-has-hybrid-graphics", GOTO="gdm_virt_passthrough_check_end" |
||||
+TEST!="/run/udev/gdm-machine-has-virtual-gpu", GOTO="gdm_virt_passthrough_check_end" |
||||
+TEST!="/run/udev/gdm-machine-has-hardware-gpu", GOTO="gdm_virt_passthrough_check_end" |
||||
+GOTO="gdm_disable_wayland" |
||||
+LABEL="gdm_virt_passthrough_check_end" |
||||
+ |
||||
+# Disable wayland when there are multiple virtual gpus |
||||
+LABEL="gdm_virt_multi_gpu_check" |
||||
+TEST!="/run/udev/gdm-machine-has-hybrid-graphics", GOTO="gdm_virt_multi_gpu_check_end" |
||||
+TEST!="/run/udev/gdm-machine-has-virtual-gpu", GOTO="gdm_virt_multi_gpu_check_end" |
||||
+TEST=="/run/udev/gdm-machine-has-hardware-gpu", GOTO="gdm_virt_multi_gpu_check_end" |
||||
+LABEL="gdm_virt_multi_gpu_check_end" |
||||
+ |
||||
+# Disable wayland when nvidia modeset is disabled or when drivers are a lower |
||||
+# version than 470, |
||||
+# For versions above 470 but lower than 510 prefer Xorg, |
||||
+# Above 510, prefer Wayland. |
||||
+KERNEL!="nvidia_drm", GOTO="gdm_nvidia_drm_end" |
||||
+SUBSYSTEM!="module", GOTO="gdm_nvidia_drm_end" |
||||
+ACTION!="add", GOTO="gdm_nvidia_drm_end" |
||||
+# disable wayland if nvidia-drm modeset is not enabled |
||||
+ATTR{parameters/modeset}!="Y", GOTO="gdm_disable_wayland" |
||||
+# disable wayland for nvidia drivers versions lower than 470 |
||||
+ATTR{version}=="4[0-6][0-9].*|[0-3][0-9][0-9].*|[0-9][0-9].*|[0-9].*", GOTO="gdm_disable_wayland" |
||||
+# For nvidia drivers versions Above 510, keep Wayland by default |
||||
+ATTR{version}=="[5-9][1-9][0-9].*", GOTO="gdm_end" |
||||
+# For nvidia drivers versions 470-495, prefer Xorg by default |
||||
+GOTO="gdm_prefer_xorg" |
||||
+LABEL="gdm_nvidia_drm_end" |
||||
+ |
||||
+GOTO="gdm_end" |
||||
+ |
||||
+LABEL="gdm_prefer_xorg" |
||||
+RUN+="@libexecdir@/gdm-runtime-config set daemon PreferredDisplayServer xorg" |
||||
+GOTO="gdm_end" |
||||
+ |
||||
+LABEL="gdm_disable_wayland" |
||||
+RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" |
||||
+GOTO="gdm_end" |
||||
+ |
||||
+LABEL="gdm_end" |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
From 0e467e3fb32d9e2a7499069699527638eb2c2be1 Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
Date: Thu, 7 Oct 2021 15:34:27 -0400 |
||||
Subject: [PATCH 5/5] local-display-factory: Don't crash if Xorg and Wayland |
||||
are both unavailable |
||||
|
||||
At the moment if Wayland doesn't work, the login screen will fall back |
||||
to Xorg, and if Xorg doesn't work the login screen will fall back to |
||||
Wayland. |
||||
|
||||
But if the fall back choice is disabled explicitly, GDM will just crash. |
||||
|
||||
This commit fixes the crash. |
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/gdm/-/issues/739 |
||||
--- |
||||
daemon/gdm-local-display-factory.c | 9 +++++++-- |
||||
1 file changed, 7 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||
index eba38671..120847f9 100644 |
||||
--- a/daemon/gdm-local-display-factory.c |
||||
+++ b/daemon/gdm-local-display-factory.c |
||||
@@ -651,62 +651,67 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory, |
||||
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); |
||||
|
||||
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; |
||||
} |
||||
|
||||
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); |
||||
|
||||
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s", |
||||
- session_types[0], falling_back? " fallback" : ""); |
||||
+ 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. |
||||
* 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, |
||||
-- |
||||
2.34.1 |
||||
|
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
load-module module-device-restore |
||||
load-module module-card-restore |
||||
load-module module-udev-detect |
||||
load-module module-native-protocol-unix |
||||
load-module module-default-device-restore |
||||
load-module module-always-sink |
||||
load-module module-intended-roles |
||||
load-module module-suspend-on-idle |
||||
load-module module-position-event-sounds |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
[org.gnome.login-screen] |
||||
logo='/usr/share/pixmaps/fedora-gdm-logo.png' |
||||
enable-smartcard-authentication=false |
Loading…
Reference in new issue