More fixes with wayland->xorg fallback

Related: RHEL-35045
Resolves: RHEL-50393
This commit is contained in:
Ray Strode 2024-07-24 08:42:58 -04:00
parent 218a123863
commit a858c6f29b
4 changed files with 386 additions and 6 deletions

View File

@ -1,7 +1,7 @@
From f7295f73f424e22eacb940c92e43326d75c901e1 Mon Sep 17 00:00:00 2001 From f7295f73f424e22eacb940c92e43326d75c901e1 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com> From: Ray Strode <rstrode@redhat.com>
Date: Mon, 22 Jul 2024 14:58:47 -0400 Date: Mon, 22 Jul 2024 14:58:47 -0400
Subject: [PATCH 1/2] display: Add new FAILING state Subject: [PATCH 1/3] display: Add new FAILING state
We need to be able to detect failure and quit plymouth before We need to be able to detect failure and quit plymouth before
reacting to the failure (and starting Xorg). reacting to the failure (and starting Xorg).

View File

@ -1,14 +1,135 @@
From d806a124b6b3bb8b265d6e99e86a787ccd22386d Mon Sep 17 00:00:00 2001 From 27c78eb4efc598281eed9cd521ba1b05ee08e3d2 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com> From: Ray Strode <rstrode@redhat.com>
Date: Mon, 22 Jul 2024 14:59:43 -0400 Date: Mon, 22 Jul 2024 14:59:43 -0400
Subject: [PATCH 2/2] manager: Quit plymouth at first sign of failure Subject: [PATCH 2/3] manager: Quit plymouth at first sign of failure
Rather than quit plymouth after a replacement X server is already Rather than quit plymouth after a replacement X server is already
started, this commit does it a bit earlier, so there is a battle started, this commit does it a bit earlier, so there is a battle
of display servers. of display servers.
--- ---
daemon/gdm-manager.c | 5 +++++ common/gdm-address.c | 4 ++--
1 file changed, 5 insertions(+) daemon/gdm-manager.c | 5 +++++
daemon/gdm-xdmcp-display-factory.c | 10 ++++++----
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/common/gdm-address.c b/common/gdm-address.c
index a8b73e286..3a507d0af 100644
--- a/common/gdm-address.c
+++ b/common/gdm-address.c
@@ -107,61 +107,61 @@ gdm_address_new_from_sockaddr (struct sockaddr *sa,
g_return_val_if_fail (sa != NULL, NULL);
g_return_val_if_fail (size >= sizeof (struct sockaddr), NULL);
g_return_val_if_fail (size <= sizeof (struct sockaddr_storage), NULL);
addr = g_new0 (GdmAddress, 1);
addr->ss = g_new0 (struct sockaddr_storage, 1);
memcpy (addr->ss, sa, size);
return addr;
}
/**
* gdm_address_get_sockaddr_storage:
* @address: A #GdmAddress
*
* This function tanslates @address into a equivalent
* sockaddr_storage
*
* Return value: A newly allocated sockaddr_storage structure the caller must free
* or %NULL if @address did not point to a valid #GdmAddress.
**/
struct sockaddr_storage *
gdm_address_get_sockaddr_storage (GdmAddress *address)
{
struct sockaddr_storage *ss;
g_return_val_if_fail (address != NULL, NULL);
g_return_val_if_fail (address->ss != NULL, NULL);
- ss = g_memdup (address->ss, sizeof (struct sockaddr_storage));
+ ss = g_memdup2 (address->ss, sizeof (struct sockaddr_storage));
return ss;
}
struct sockaddr_storage *
gdm_address_peek_sockaddr_storage (GdmAddress *address)
{
g_return_val_if_fail (address != NULL, NULL);
return address->ss;
}
static gboolean
v4_v4_equal (const struct sockaddr_in *a,
const struct sockaddr_in *b)
{
return a->sin_addr.s_addr == b->sin_addr.s_addr;
}
#ifdef ENABLE_IPV6
static gboolean
v6_v6_equal (struct sockaddr_in6 *a,
struct sockaddr_in6 *b)
{
return IN6_ARE_ADDR_EQUAL (&a->sin6_addr, &b->sin6_addr);
}
#endif
#define SA(__s) ((struct sockaddr *) __s)
#define SIN(__s) ((struct sockaddr_in *) __s)
@@ -502,50 +502,50 @@ gdm_address_is_local (GdmAddress *address)
while (list != NULL) {
GdmAddress *addr = list->data;
if (gdm_address_equal (address, addr)) {
return TRUE;
}
list = list->next;
}
return FALSE;
}
/**
* gdm_address_copy:
* @address: A #GdmAddress.
*
* Duplicates @address.
*
* Return value: Duplicated @address or %NULL if @address was not valid.
**/
GdmAddress *
gdm_address_copy (GdmAddress *address)
{
GdmAddress *addr;
g_return_val_if_fail (address != NULL, NULL);
addr = g_new0 (GdmAddress, 1);
- addr->ss = g_memdup (address->ss, sizeof (struct sockaddr_storage));
+ addr->ss = g_memdup2 (address->ss, sizeof (struct sockaddr_storage));
return addr;
}
/**
* gdm_address_free:
* @address: A #GdmAddress.
*
* Frees the memory allocated for @address.
**/
void
gdm_address_free (GdmAddress *address)
{
g_return_if_fail (address != NULL);
g_free (address->ss);
g_free (address);
}
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 08c3cc177..100b967fb 100644 index 08c3cc177..100b967fb 100644
@ -90,6 +211,165 @@ index 08c3cc177..100b967fb 100644
char *id; char *id;
gdm_display_get_id (display, &id, NULL); gdm_display_get_id (display, &id, NULL);
diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c
index abb58faeb..e82cfe1b4 100644
--- a/daemon/gdm-xdmcp-display-factory.c
+++ b/daemon/gdm-xdmcp-display-factory.c
@@ -891,87 +891,87 @@ gdm_xdmcp_send_unwilling (GdmXdmcpDisplayFactory *factory,
header.length = 4 + factory->servhost.length + status.length;
header.version = XDM_PROTOCOL_VERSION;
XdmcpWriteHeader (&factory->buf, &header);
XdmcpWriteARRAY8 (&factory->buf, &factory->servhost);
XdmcpWriteARRAY8 (&factory->buf, &status);
XdmcpFlush (factory->socket_fd,
&factory->buf,
(XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address),
(int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address)));
last_time = time (NULL);
}
#define SIN(__s) ((struct sockaddr_in *) __s)
#define SIN6(__s) ((struct sockaddr_in6 *) __s)
static void
set_port_for_request (GdmAddress *address,
ARRAY8 *port)
{
struct sockaddr_storage *ss;
ss = gdm_address_peek_sockaddr_storage (address);
/* we depend on this being 2 elsewhere as well */
port->length = 2;
switch (ss->ss_family) {
case AF_INET:
- port->data = (CARD8 *)g_memdup (&(SIN (ss)->sin_port), port->length);
+ port->data = (CARD8 *)g_memdup2 (&(SIN (ss)->sin_port), port->length);
break;
case AF_INET6:
- port->data = (CARD8 *)g_memdup (&(SIN6 (ss)->sin6_port), port->length);
+ port->data = (CARD8 *)g_memdup2 (&(SIN6 (ss)->sin6_port), port->length);
break;
default:
port->data = NULL;
break;
}
}
static void
set_address_for_request (GdmAddress *address,
ARRAY8 *addr)
{
struct sockaddr_storage *ss;
ss = gdm_address_peek_sockaddr_storage (address);
switch (ss->ss_family) {
case AF_INET:
addr->length = sizeof (struct in_addr);
- addr->data = g_memdup (&SIN (ss)->sin_addr, addr->length);
+ addr->data = g_memdup2 (&SIN (ss)->sin_addr, addr->length);
break;
case AF_INET6:
addr->length = sizeof (struct in6_addr);
- addr->data = g_memdup (&SIN6 (ss)->sin6_addr, addr->length);
+ addr->data = g_memdup2 (&SIN6 (ss)->sin6_addr, addr->length);
break;
default:
addr->length = 0;
addr->data = NULL;
break;
}
}
static void
gdm_xdmcp_send_forward_query (GdmXdmcpDisplayFactory *factory,
IndirectClient *ic,
GdmAddress *address,
GdmAddress *display_address,
ARRAYofARRAY8Ptr authlist)
{
XdmcpHeader header;
int i;
ARRAY8 addr;
ARRAY8 port;
char *host;
char *serv;
g_assert (ic != NULL);
g_assert (ic->chosen_address != NULL);
host = NULL;
gdm_address_get_numeric_info (ic->chosen_address, &host, NULL);
g_debug ("GdmXdmcpDisplayFactory: Sending forward query to %s",
host ? host : "(null)");
@@ -2063,60 +2063,62 @@ on_display_status_changed (GdmDisplay *display,
{
int status;
GdmLaunchEnvironment *launch_environment;
GdmSession *session;
GdmAddress *address;
gint32 session_number;
int display_number;
launch_environment = NULL;
g_object_get (display, "launch-environment", &launch_environment, NULL);
session = NULL;
if (launch_environment != NULL) {
session = gdm_launch_environment_get_session (launch_environment);
}
status = gdm_display_get_status (display);
g_debug ("GdmXdmcpDisplayFactory: xdmcp display status changed: %d", status);
switch (status) {
case GDM_DISPLAY_FINISHED:
g_object_get (display,
"remote-address", &address,
"x11-display-number", &display_number,
"session-number", &session_number,
NULL);
gdm_xdmcp_send_alive (factory, address, display_number, session_number);
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
break;
+ case GDM_DISPLAY_FAILING:
+ break;
case GDM_DISPLAY_FAILED:
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
break;
case GDM_DISPLAY_UNMANAGED:
if (session != NULL) {
g_signal_handlers_disconnect_by_func (G_OBJECT (session),
G_CALLBACK (on_client_disconnected),
display);
}
break;
case GDM_DISPLAY_PREPARED:
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);
-- --
2.44.0 2.44.0

View File

@ -0,0 +1,94 @@
From 190a9f31446ddab66c8b5c2e246a6253f85bde76 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 24 Jul 2024 08:40:08 -0400
Subject: [PATCH 3/3] manager: Quit plymouth synchronously
Plymouth needs to finish quitting before we start Xorg, so we can't
run it async. This command makes sure it gets run synchronously.
---
daemon/gdm-manager.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 100b967fb..d4ad949fe 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -167,67 +167,72 @@ plymouth_prepare_for_transition (void)
error = NULL;
res = g_spawn_command_line_sync ("plymouth deactivate",
NULL, NULL, NULL, &error);
if (! res) {
g_warning ("Could not deactivate plymouth: %s", error->message);
g_error_free (error);
}
}
static gboolean
plymouth_quit_with_transition (void)
{
gboolean res;
GError *error;
error = NULL;
res = g_spawn_command_line_async ("plymouth quit --retain-splash", &error);
if (! res) {
g_warning ("Could not quit plymouth: %s", error->message);
g_error_free (error);
}
return G_SOURCE_REMOVE;
}
static void
plymouth_quit_without_transition (void)
{
gboolean res;
- GError *error;
+ g_autoptr (GError) error = NULL;
+ g_autofree char *standard_error = NULL;
+ int wait_status = 0;
error = NULL;
- res = g_spawn_command_line_async ("plymouth quit", &error);
+ res = g_spawn_command_line_sync ("plymouth quit", NULL, &standard_error, &wait_status, &error);
if (! res) {
g_warning ("Could not quit plymouth: %s", error->message);
- g_error_free (error);
+ } else if (!WIFEXITED (wait_status) || WEXITSTATUS (wait_status) != 0) {
+ g_warning ("plymouth errored on quit command%s%s",
+ standard_error? ":" : "",
+ standard_error?: "");
}
}
#endif
static char *
get_session_id_for_pid (pid_t pid,
GError **error)
{
char *session, *gsession;
int ret;
session = NULL;
ret = sd_pid_get_session (pid, &session);
if (ret < 0) {
g_set_error (error,
GDM_DISPLAY_ERROR,
GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
"Error getting session id from systemd: %s",
g_strerror (-ret));
return NULL;
}
if (session != NULL) {
gsession = g_strdup (session);
free (session);
return gsession;
} else {
return NULL;
}
--
2.44.0

View File

@ -11,7 +11,7 @@
Name: gdm Name: gdm
Epoch: 1 Epoch: 1
Version: 40.1 Version: 40.1
Release: 26%{?dist} Release: 27%{?dist}
Summary: The GNOME Display Manager Summary: The GNOME Display Manager
License: GPLv2+ License: GPLv2+
@ -56,6 +56,7 @@ Patch100002: 0002-local-display-factory-Fix-user-switching-with-legacy.patch
Patch110001: 0001-display-Add-new-FAILING-state.patch Patch110001: 0001-display-Add-new-FAILING-state.patch
Patch110002: 0002-manager-Quit-plymouth-at-first-sign-of-failure.patch Patch110002: 0002-manager-Quit-plymouth-at-first-sign-of-failure.patch
Patch110003: 0003-manager-Quit-plymouth-synchronously.patch
# Non-upstreamable workarounds # Non-upstreamable workarounds
Patch66610001: 0001-data-reap-gdm-sessions-on-shutdown.patch Patch66610001: 0001-data-reap-gdm-sessions-on-shutdown.patch
@ -359,6 +360,11 @@ dconf update || :
%{_libdir}/pkgconfig/gdm-pam-extensions.pc %{_libdir}/pkgconfig/gdm-pam-extensions.pc
%changelog %changelog
* Wed Jul 24 2024 Ray Strode <rstrode@redhat.com> - 40.1-27
- More fixes with wayland->xorg fallback
Related: RHEL-35045
Resolves: RHEL-50393
* Tue Jul 23 2024 Ray Strode <rstrode@redhat.com> - 40.1-26 * Tue Jul 23 2024 Ray Strode <rstrode@redhat.com> - 40.1-26
- Fix failure doing wayland->xorg fallback - Fix failure doing wayland->xorg fallback
Related: RHEL-35045 Related: RHEL-35045