From 166a4645159d6f09d5503a5fc5fd34dfed83bfce Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 19 Jul 2019 22:50:31 +0200 Subject: [PATCH] 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 --- config.h.meson | 3 ++ meson.build | 15 ++++++ meson_options.txt | 6 +++ src/wayland/meta-wayland-private.h | 9 +++- src/wayland/meta-wayland.c | 4 +- src/wayland/meta-xwayland.c | 81 ++++++++++++++++++++++-------- 6 files changed, 93 insertions(+), 25 deletions(-) diff --git a/config.h.meson b/config.h.meson index 0bab71848..0edff4d57 100644 --- a/config.h.meson +++ b/config.h.meson @@ -67,3 +67,6 @@ /* Either or */ #mesondefine HAVE_SYS_RANDOM #mesondefine HAVE_LINUX_RANDOM + +/* Whether Xwayland has -initfd option */ +#mesondefine HAVE_XWAYLAND_INITFD diff --git a/meson.build b/meson.build index 666ba68a7..ababd6eb2 100644 --- a/meson.build +++ b/meson.build @@ -377,6 +377,7 @@ if cc.has_header_symbol('sys/prctl.h', 'prctl') cdata.set('HAVE_SYS_PRCTL', 1) endif +have_xwayland_initfd = false if have_wayland xwayland_path = get_option('xwayland_path') if xwayland_path == '' @@ -392,6 +393,19 @@ if have_wayland else error('Required function getrandom not found') 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 xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') @@ -450,6 +464,7 @@ output = [ ' Startup notification..... ' + have_startup_notification.to_string(), ' Introspection............ ' + have_introspection.to_string(), ' Profiler................. ' + have_profiler.to_string(), + ' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(), '', ' Tests:', '', diff --git a/meson_options.txt b/meson_options.txt index 73aa7adde..097809a93 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules', 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' ) + +option('xwayland_initfd', + type: 'feature', + value: 'auto', + description: 'Whether Xwayland -initfd argument is used' +) diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h index aa8e4deab..e28ca06d6 100644 --- a/src/wayland/meta-wayland-private.h +++ b/src/wayland/meta-wayland-private.h @@ -48,11 +48,18 @@ typedef struct char *lock_file; int abstract_fd; int unix_fd; + char *name; +} MetaXWaylandConnection; + +typedef struct +{ + MetaXWaylandConnection private_connection; + MetaXWaylandConnection public_connection; + guint xserver_grace_period_id; struct wl_display *wayland_display; struct wl_client *client; struct wl_resource *xserver_resource; - char *display_name; char *auth_file; GCancellable *xserver_died_cancellable; diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 876b4925a..70c3db87d 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -446,7 +446,7 @@ meta_wayland_init (void) 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)); } @@ -462,7 +462,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor) const char * meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor) { - return compositor->xwayland_manager.display_name; + return compositor->xwayland_manager.private_connection.name; } void diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 530dadc1a..ac55599d4 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -314,6 +314,7 @@ xserver_died (GObject *source, gpointer user_data) { GSubprocess *proc = G_SUBPROCESS (source); + MetaDisplay *display = meta_get_display (); g_autoptr (GError) error = NULL; 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) { MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - MetaDisplay *display = meta_get_display (); if (display->x11_display) meta_display_shutdown_x11 (display); @@ -381,6 +381,8 @@ meta_xwayland_override_display_number (int number) static gboolean open_display_sockets (MetaXWaylandManager *manager, int display_index, + int *abstract_fd_out, + int *unix_fd_out, gboolean *fatal) { int abstract_fd, unix_fd; @@ -398,14 +400,15 @@ open_display_sockets (MetaXWaylandManager *manager, return FALSE; } - manager->abstract_fd = abstract_fd; - manager->unix_fd = unix_fd; + *abstract_fd_out = abstract_fd; + *unix_fd_out = unix_fd; return TRUE; } static gboolean -choose_xdisplay (MetaXWaylandManager *manager) +choose_xdisplay (MetaXWaylandManager *manager, + MetaXWaylandConnection *connection) { int display = 0; char *lock_file = NULL; @@ -425,7 +428,10 @@ choose_xdisplay (MetaXWaylandManager *manager) 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); @@ -445,9 +451,9 @@ choose_xdisplay (MetaXWaylandManager *manager) } while (1); - manager->display_index = display; - manager->display_name = g_strdup_printf (":%d", manager->display_index); - manager->lock_file = lock_file; + connection->display_index = display; + connection->name = g_strdup_printf (":%d", connection->display_index); + connection->lock_file = lock_file; return TRUE; } @@ -611,14 +617,16 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager, launcher = g_subprocess_launcher_new (flags); 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->unix_fd, 5); + g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4); + 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, manager->private_connection.abstract_fd, 7); g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); manager->proc = g_subprocess_launcher_spawn (launcher, &error, - XWAYLAND_PATH, manager->display_name, + XWAYLAND_PATH, + manager->public_connection.name, "-rootless", "-noreset", "-accessx", @@ -627,7 +635,13 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager, "-listen", "4", "-listen", "5", "-displayfd", "6", +#ifdef HAVE_XWAYLAND_INITFD + "-initfd", "7", +#else + "-listen", "7", +#endif NULL); + if (!manager->proc) { g_task_return_error (task, error); @@ -728,9 +742,11 @@ meta_xwayland_init (MetaXWaylandManager *manager, MetaDisplayPolicy policy; 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; if (!prepare_auth_file (manager)) @@ -738,7 +754,18 @@ meta_xwayland_init (MetaXWaylandManager *manager, } 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; } @@ -747,7 +774,7 @@ meta_xwayland_init (MetaXWaylandManager *manager, 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); } @@ -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 meta_xwayland_shutdown (MetaXWaylandManager *manager) { @@ -800,18 +834,21 @@ meta_xwayland_shutdown (MetaXWaylandManager *manager) 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); - 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) { unlink (manager->auth_file); g_clear_pointer (&manager->auth_file, g_free); } - if (manager->lock_file) - { - unlink (manager->lock_file); - g_clear_pointer (&manager->lock_file, g_free); - } }