wayland: Set up initialization X11 socket

This is used by GDK and the X11 bits, but may also be used for
other initialization services we might need to run along with
Xwayland initialization.

However, as the -initfd argument in Xwayland is a fairly new
feature, add some meson build-time checks so that the feature
is handled transparently while allowing to explicitly set/unset
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
This commit is contained in:
Carlos Garnacho 2019-07-19 22:50:31 +02:00 committed by Carlos Garnacho
parent 38e58b837b
commit 166a464515
6 changed files with 93 additions and 25 deletions

View File

@ -67,3 +67,6 @@
/* Either <sys/random.h> or <linux/random.h> */ /* Either <sys/random.h> or <linux/random.h> */
#mesondefine HAVE_SYS_RANDOM #mesondefine HAVE_SYS_RANDOM
#mesondefine HAVE_LINUX_RANDOM #mesondefine HAVE_LINUX_RANDOM
/* Whether Xwayland has -initfd option */
#mesondefine HAVE_XWAYLAND_INITFD

View File

@ -377,6 +377,7 @@ if cc.has_header_symbol('sys/prctl.h', 'prctl')
cdata.set('HAVE_SYS_PRCTL', 1) cdata.set('HAVE_SYS_PRCTL', 1)
endif endif
have_xwayland_initfd = false
if have_wayland if have_wayland
xwayland_path = get_option('xwayland_path') xwayland_path = get_option('xwayland_path')
if xwayland_path == '' if xwayland_path == ''
@ -392,6 +393,19 @@ if have_wayland
else else
error('Required function getrandom not found') error('Required function getrandom not found')
endif endif
# For Xwayland -initfd usage
use_initfd = get_option('xwayland_initfd')
if use_initfd.auto()
xwayland_options = run_command(xwayland_path, '-help')
have_xwayland_initfd = xwayland_options.stderr().contains('-initfd')
else
have_xwayland_initfd = use_initfd.enabled()
endif
if (have_xwayland_initfd)
cdata.set('HAVE_XWAYLAND_INITFD', 1)
endif
endif endif
xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules')
@ -450,6 +464,7 @@ output = [
' Startup notification..... ' + have_startup_notification.to_string(), ' Startup notification..... ' + have_startup_notification.to_string(),
' Introspection............ ' + have_introspection.to_string(), ' Introspection............ ' + have_introspection.to_string(),
' Profiler................. ' + have_profiler.to_string(), ' Profiler................. ' + have_profiler.to_string(),
' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(),
'', '',
' Tests:', ' Tests:',
'', '',

View File

@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules',
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr', value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland' description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland'
) )
option('xwayland_initfd',
type: 'feature',
value: 'auto',
description: 'Whether Xwayland -initfd argument is used'
)

View File

@ -48,11 +48,18 @@ typedef struct
char *lock_file; char *lock_file;
int abstract_fd; int abstract_fd;
int unix_fd; int unix_fd;
char *name;
} MetaXWaylandConnection;
typedef struct
{
MetaXWaylandConnection private_connection;
MetaXWaylandConnection public_connection;
guint xserver_grace_period_id; guint xserver_grace_period_id;
struct wl_display *wayland_display; struct wl_display *wayland_display;
struct wl_client *client; struct wl_client *client;
struct wl_resource *xserver_resource; struct wl_resource *xserver_resource;
char *display_name;
char *auth_file; char *auth_file;
GCancellable *xserver_died_cancellable; GCancellable *xserver_died_cancellable;

View File

@ -446,7 +446,7 @@ meta_wayland_init (void)
if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED) if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
{ {
set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor)); set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor)); set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
} }
@ -462,7 +462,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
const char * const char *
meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor) meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor)
{ {
return compositor->xwayland_manager.display_name; return compositor->xwayland_manager.private_connection.name;
} }
void void

View File

@ -314,6 +314,7 @@ xserver_died (GObject *source,
gpointer user_data) gpointer user_data)
{ {
GSubprocess *proc = G_SUBPROCESS (source); GSubprocess *proc = G_SUBPROCESS (source);
MetaDisplay *display = meta_get_display ();
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
if (!g_subprocess_wait_finish (proc, result, &error)) if (!g_subprocess_wait_finish (proc, result, &error))
@ -338,7 +339,6 @@ xserver_died (GObject *source,
else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND) else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
{ {
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaDisplay *display = meta_get_display ();
if (display->x11_display) if (display->x11_display)
meta_display_shutdown_x11 (display); meta_display_shutdown_x11 (display);
@ -381,6 +381,8 @@ meta_xwayland_override_display_number (int number)
static gboolean static gboolean
open_display_sockets (MetaXWaylandManager *manager, open_display_sockets (MetaXWaylandManager *manager,
int display_index, int display_index,
int *abstract_fd_out,
int *unix_fd_out,
gboolean *fatal) gboolean *fatal)
{ {
int abstract_fd, unix_fd; int abstract_fd, unix_fd;
@ -398,14 +400,15 @@ open_display_sockets (MetaXWaylandManager *manager,
return FALSE; return FALSE;
} }
manager->abstract_fd = abstract_fd; *abstract_fd_out = abstract_fd;
manager->unix_fd = unix_fd; *unix_fd_out = unix_fd;
return TRUE; return TRUE;
} }
static gboolean static gboolean
choose_xdisplay (MetaXWaylandManager *manager) choose_xdisplay (MetaXWaylandManager *manager,
MetaXWaylandConnection *connection)
{ {
int display = 0; int display = 0;
char *lock_file = NULL; char *lock_file = NULL;
@ -425,7 +428,10 @@ choose_xdisplay (MetaXWaylandManager *manager)
return FALSE; return FALSE;
} }
if (!open_display_sockets (manager, display, &fatal)) if (!open_display_sockets (manager, display,
&connection->abstract_fd,
&connection->unix_fd,
&fatal))
{ {
unlink (lock_file); unlink (lock_file);
@ -445,9 +451,9 @@ choose_xdisplay (MetaXWaylandManager *manager)
} }
while (1); while (1);
manager->display_index = display; connection->display_index = display;
manager->display_name = g_strdup_printf (":%d", manager->display_index); connection->name = g_strdup_printf (":%d", connection->display_index);
manager->lock_file = lock_file; connection->lock_file = lock_file;
return TRUE; return TRUE;
} }
@ -611,14 +617,16 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
launcher = g_subprocess_launcher_new (flags); launcher = g_subprocess_launcher_new (flags);
g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3); g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4); g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4);
g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5); g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5);
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6); g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7);
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
manager->proc = g_subprocess_launcher_spawn (launcher, &error, manager->proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name, XWAYLAND_PATH,
manager->public_connection.name,
"-rootless", "-rootless",
"-noreset", "-noreset",
"-accessx", "-accessx",
@ -627,7 +635,13 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
"-listen", "4", "-listen", "4",
"-listen", "5", "-listen", "5",
"-displayfd", "6", "-displayfd", "6",
#ifdef HAVE_XWAYLAND_INITFD
"-initfd", "7",
#else
"-listen", "7",
#endif
NULL); NULL);
if (!manager->proc) if (!manager->proc)
{ {
g_task_return_error (task, error); g_task_return_error (task, error);
@ -728,9 +742,11 @@ meta_xwayland_init (MetaXWaylandManager *manager,
MetaDisplayPolicy policy; MetaDisplayPolicy policy;
gboolean fatal; gboolean fatal;
if (!manager->display_name) if (!manager->public_connection.name)
{ {
if (!choose_xdisplay (manager)) if (!choose_xdisplay (manager, &manager->public_connection))
return FALSE;
if (!choose_xdisplay (manager, &manager->private_connection))
return FALSE; return FALSE;
if (!prepare_auth_file (manager)) if (!prepare_auth_file (manager))
@ -738,7 +754,18 @@ meta_xwayland_init (MetaXWaylandManager *manager,
} }
else else
{ {
if (!open_display_sockets (manager, manager->display_index, &fatal)) if (!open_display_sockets (manager,
manager->public_connection.display_index,
&manager->public_connection.abstract_fd,
&manager->public_connection.unix_fd,
&fatal))
return FALSE;
if (!open_display_sockets (manager,
manager->private_connection.display_index,
&manager->private_connection.abstract_fd,
&manager->private_connection.unix_fd,
&fatal))
return FALSE; return FALSE;
} }
@ -747,7 +774,7 @@ meta_xwayland_init (MetaXWaylandManager *manager,
if (policy == META_DISPLAY_POLICY_ON_DEMAND) if (policy == META_DISPLAY_POLICY_ON_DEMAND)
{ {
g_unix_fd_add (manager->abstract_fd, G_IO_IN, g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
xdisplay_connection_activity_cb, manager); xdisplay_connection_activity_cb, manager);
} }
@ -793,6 +820,13 @@ meta_xwayland_complete_init (MetaDisplay *display,
} }
} }
static void
meta_xwayland_connection_release (MetaXWaylandConnection *connection)
{
unlink (connection->lock_file);
g_clear_pointer (&connection->lock_file, g_free);
}
void void
meta_xwayland_shutdown (MetaXWaylandManager *manager) meta_xwayland_shutdown (MetaXWaylandManager *manager)
{ {
@ -800,18 +834,21 @@ meta_xwayland_shutdown (MetaXWaylandManager *manager)
g_cancellable_cancel (manager->xserver_died_cancellable); g_cancellable_cancel (manager->xserver_died_cancellable);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index); snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index);
unlink (path); unlink (path);
g_clear_pointer (&manager->display_name, g_free); snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index);
unlink (path);
g_clear_pointer (&manager->public_connection.name, g_free);
g_clear_pointer (&manager->private_connection.name, g_free);
meta_xwayland_connection_release (&manager->public_connection);
meta_xwayland_connection_release (&manager->private_connection);
if (manager->auth_file) if (manager->auth_file)
{ {
unlink (manager->auth_file); unlink (manager->auth_file);
g_clear_pointer (&manager->auth_file, g_free); g_clear_pointer (&manager->auth_file, g_free);
} }
if (manager->lock_file)
{
unlink (manager->lock_file);
g_clear_pointer (&manager->lock_file, g_free);
}
} }