From 5340320ff261985e32c2b312984bc6be873fff5baeca975b6188baa58646624c Mon Sep 17 00:00:00 2001 From: Stefan Dirsch Date: Thu, 30 Jul 2015 10:50:09 +0000 Subject: [PATCH] Accepting request 319540 from home:tiwai:branches:X11:XOrg - Backport a few upstream fixes for systemd/VT handling (boo#939838): U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch U_systemd-logind-Only-use-systemd-logind-integration-t.patch U_systemd-logind-do-not-rely-on-directed-signals.patch OBS-URL: https://build.opensuse.org/request/show/319540 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=582 --- ...fail-paramter-to-linux_parse_vt_sett.patch | 114 +++++++++ ...parse_vt_settings-and-linux_get_keep.patch | 229 ++++++++++++++++++ ...nly-use-systemd-logind-integration-t.patch | 64 +++++ ...gind-do-not-rely-on-directed-signals.patch | 58 +++++ xorg-x11-server.changes | 9 + xorg-x11-server.spec | 12 +- 6 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch create mode 100644 U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch create mode 100644 U_systemd-logind-Only-use-systemd-logind-integration-t.patch create mode 100644 U_systemd-logind-do-not-rely-on-directed-signals.patch diff --git a/U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch b/U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch new file mode 100644 index 0000000..569a0d6 --- /dev/null +++ b/U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch @@ -0,0 +1,114 @@ +From 81bcada14e339fe2a2fb3f3a040566d94dc20bad Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 13 May 2015 13:17:09 +0200 +Subject: [PATCH] linux: Add a may_fail paramter to linux_parse_vt_settings + +linux_parse_vt_settings() was split out of xf86OpenConsole so that it can +be called earlier during systemd-logind init, but it is possible to run +the xserver in such a way that xf86OpenConsole() is never used. + +The FatalError calls in linux_parse_vt_settings() may stop the Xorg xserver +from working when e.g. no /dev/tty0 is present in such a setup. + +This commit adds a may_fail parameter to linux_parse_vt_settings() which +can be used to make linux_parse_vt_settings() fail silenty with an error +return in this case, rather then calling FatalError(). + +Signed-off-by: Hans de Goede +Reviewed-by: Peter Hutterer +--- + hw/xfree86/os-support/linux/linux.h | 2 +- + hw/xfree86/os-support/linux/lnx_init.c | 29 +++++++++++++++++++++-------- + 2 files changed, 22 insertions(+), 9 deletions(-) + +--- a/hw/xfree86/os-support/linux/linux.h ++++ b/hw/xfree86/os-support/linux/linux.h +@@ -26,7 +26,7 @@ + #ifndef XF86_LINUX_H + #define XF86_LINUX_H + +-void linux_parse_vt_settings(void); ++int linux_parse_vt_settings(int may_fail); + int linux_get_keeptty(void); + + #endif +--- a/hw/xfree86/os-support/linux/lnx_init.c ++++ b/hw/xfree86/os-support/linux/lnx_init.c +@@ -87,8 +87,8 @@ switch_to(int vt, const char *from, Bool + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + +-void +-linux_parse_vt_settings(void) ++int ++linux_parse_vt_settings(int may_fail) + { + int i, fd = -1, ret, current_vt = -1; + struct vt_stat vts; +@@ -100,7 +100,7 @@ linux_parse_vt_settings(void) + static int vt_settings_parsed = 0; + + if (vt_settings_parsed) +- return; ++ return 1; + + /* + * setup the virtual terminal manager +@@ -117,24 +117,36 @@ linux_parse_vt_settings(void) + i++; + } + +- if (fd < 0) ++ if (fd < 0) { ++ if (may_fail) ++ return 0; + FatalError("parse_vt_settings: Cannot open /dev/tty0 (%s)\n", + strerror(errno)); ++ } + + if (xf86Info.ShareVTs) { + SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts)); +- if (ret < 0) ++ if (ret < 0) { ++ if (may_fail) ++ return 0; + FatalError("parse_vt_settings: Cannot find the current" + " VT (%s)\n", strerror(errno)); ++ } + xf86Info.vtno = vts.v_active; + } + else { + SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno)); +- if (ret < 0) ++ if (ret < 0) { ++ if (may_fail) ++ return 0; + FatalError("parse_vt_settings: Cannot find a free VT: " + "%s\n", strerror(errno)); +- if (xf86Info.vtno == -1) ++ } ++ if (xf86Info.vtno == -1) { ++ if (may_fail) ++ return 0; + FatalError("parse_vt_settings: Cannot find a free VT\n"); ++ } + } + close(fd); + } +@@ -158,6 +170,7 @@ linux_parse_vt_settings(void) + } + + vt_settings_parsed = 1; ++ return 1; + } + + int +@@ -175,7 +188,7 @@ xf86OpenConsole(void) + const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; + + if (serverGeneration == 1) { +- linux_parse_vt_settings(); ++ linux_parse_vt_settings(FALSE); + + if (!KeepTty) { + pid_t ppid = getppid(); diff --git a/U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch b/U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch new file mode 100644 index 0000000..d83656d --- /dev/null +++ b/U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch @@ -0,0 +1,229 @@ +From 1dba5a0b194653b0effb01a918bd7338b0c6bcb9 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 21 Jan 2015 09:31:39 +0100 +Subject: [PATCH] linux: Add linux_parse_vt_settings and linux_get_keeptty + helpers + +systemd-logind integration does not work when starting X on a new tty, as +that detaches X from the current session and after hat systemd-logind revokes +all rights on any already open fds and refuses to open new fds for X. + +This means that currently e.g. "startx -- vt7" breaks, and breaks badly, +requiring ssh access to the system to kill X. + +The fix for this is easy, we must not use systemd-logind integration when +not using KeepTty, or iow we may only use systemd-logind integration together +with KeepTty. + +But the final KeepTty value is not known until the code to chose which vtno to +run on has been called, which currently happens after intializing +systemd-logind. + +This commit is step 1 in fixing the "startx -- vt7" breakage, it factors out +the linux xf86OpenConsole bits which set xf86Info.vtno and keepTty so that +these can be called earlier. Calling this earlier is safe as this code has +no side effects other than setting xf86Info.vtno and keepTty. + +Note this basically only moves a large chunk of xf86OpenConsole() into +linux_parse_vt_settings() without changing a single line of it, this is +hard to see in the diff because the identation level has changed. + +Signed-off-by: Hans de Goede +Reviewed-by: Peter Hutterer +--- + hw/xfree86/os-support/linux/linux.h | 32 ++++++++ + hw/xfree86/os-support/linux/lnx_init.c | 126 +++++++++++++++++++-------------- + 2 files changed, 107 insertions(+), 51 deletions(-) + create mode 100644 hw/xfree86/os-support/linux/linux.h + +--- /dev/null ++++ b/hw/xfree86/os-support/linux/linux.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright © 2015 Red Hat, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Hans de Goede ++ */ ++ ++#ifndef XF86_LINUX_H ++#define XF86_LINUX_H ++ ++void linux_parse_vt_settings(void); ++int linux_get_keeptty(void); ++ ++#endif +--- a/hw/xfree86/os-support/linux/lnx_init.c ++++ b/hw/xfree86/os-support/linux/lnx_init.c +@@ -31,6 +31,7 @@ + #include + + #include "compiler.h" ++#include "linux.h" + + #include "xf86.h" + #include "xf86Priv.h" +@@ -87,71 +88,94 @@ switch_to(int vt, const char *from, Bool + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + + void +-xf86OpenConsole(void) ++linux_parse_vt_settings(void) + { + int i, fd = -1, ret, current_vt = -1; +- struct vt_mode VT; + struct vt_stat vts; + struct stat st; + MessageType from = X_PROBED; + const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; +- const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; + +- if (serverGeneration == 1) { +- /* +- * setup the virtual terminal manager +- */ +- if (xf86Info.vtno != -1) { +- from = X_CMDLINE; +- } +- else { ++ /* Only do this once */ ++ static int vt_settings_parsed = 0; + +- i = 0; +- while (tty0[i] != NULL) { +- if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0) +- break; +- i++; +- } +- +- if (fd < 0) +- FatalError("xf86OpenConsole: Cannot open /dev/tty0 (%s)\n", +- strerror(errno)); +- +- if (xf86Info.ShareVTs) { +- SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts)); +- if (ret < 0) +- FatalError("xf86OpenConsole: Cannot find the current" +- " VT (%s)\n", strerror(errno)); +- xf86Info.vtno = vts.v_active; +- } +- else { +- SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno)); +- if (ret < 0) +- FatalError("xf86OpenConsole: Cannot find a free VT: " +- "%s\n", strerror(errno)); +- if (xf86Info.vtno == -1) +- FatalError("xf86OpenConsole: Cannot find a free VT\n"); +- } +- close(fd); +- } ++ if (vt_settings_parsed) ++ return; + +- xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); ++ /* ++ * setup the virtual terminal manager ++ */ ++ if (xf86Info.vtno != -1) { ++ from = X_CMDLINE; ++ } ++ else { + +- /* Some of stdin / stdout / stderr maybe redirected to a file */ +- for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) { +- ret = fstat(i, &st); +- if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) { +- current_vt = minor(st.st_rdev); ++ i = 0; ++ while (tty0[i] != NULL) { ++ if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0) + break; +- } ++ i++; + } + +- if (!KeepTty && current_vt == xf86Info.vtno) { +- xf86Msg(X_PROBED, +- "controlling tty is VT number %d, auto-enabling KeepTty\n", +- current_vt); +- KeepTty = TRUE; ++ if (fd < 0) ++ FatalError("parse_vt_settings: Cannot open /dev/tty0 (%s)\n", ++ strerror(errno)); ++ ++ if (xf86Info.ShareVTs) { ++ SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts)); ++ if (ret < 0) ++ FatalError("parse_vt_settings: Cannot find the current" ++ " VT (%s)\n", strerror(errno)); ++ xf86Info.vtno = vts.v_active; + } ++ else { ++ SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno)); ++ if (ret < 0) ++ FatalError("parse_vt_settings: Cannot find a free VT: " ++ "%s\n", strerror(errno)); ++ if (xf86Info.vtno == -1) ++ FatalError("parse_vt_settings: Cannot find a free VT\n"); ++ } ++ close(fd); ++ } ++ ++ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); ++ ++ /* Some of stdin / stdout / stderr maybe redirected to a file */ ++ for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) { ++ ret = fstat(i, &st); ++ if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) { ++ current_vt = minor(st.st_rdev); ++ break; ++ } ++ } ++ ++ if (!KeepTty && current_vt == xf86Info.vtno) { ++ xf86Msg(X_PROBED, ++ "controlling tty is VT number %d, auto-enabling KeepTty\n", ++ current_vt); ++ KeepTty = TRUE; ++ } ++ ++ vt_settings_parsed = 1; ++} ++ ++int ++linux_get_keeptty(void) ++{ ++ return KeepTty; ++} ++ ++void ++xf86OpenConsole(void) ++{ ++ int i, ret; ++ struct vt_stat vts; ++ struct vt_mode VT; ++ const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; ++ ++ if (serverGeneration == 1) { ++ linux_parse_vt_settings(); + + if (!KeepTty) { + pid_t ppid = getppid(); diff --git a/U_systemd-logind-Only-use-systemd-logind-integration-t.patch b/U_systemd-logind-Only-use-systemd-logind-integration-t.patch new file mode 100644 index 0000000..2b464ab --- /dev/null +++ b/U_systemd-logind-Only-use-systemd-logind-integration-t.patch @@ -0,0 +1,64 @@ +From c88a325899381d1133e63e6c33c29db079e20a87 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 21 Jan 2015 10:13:20 +0100 +Subject: [PATCH] systemd-logind: Only use systemd-logind integration together + with keeptty + +systemd-logind integration does not work when starting X on a new tty, as +that detaches X from the current session and after hat systemd-logind revokes +all rights any already open fds and refuses to open new fds for X. + +This means that currently e.g. "startx -- vt7" breaks, and breaks badly, +requiring ssh access to the system to kill X. + +The fix for this is easy, we must not use systemd-logind integration when +not using KeepTty, or iow we may only use systemd-logind integration together +with KeepTty. + +Signed-off-by: Hans de Goede +Reviewed-by: Peter Hutterer +Tested-by: Aaron Plattner +--- + hw/xfree86/man/Xorg.man | 6 +++--- + hw/xfree86/os-support/linux/systemd-logind.c | 8 ++++++++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +--- a/hw/xfree86/man/Xorg.man ++++ b/hw/xfree86/man/Xorg.man +@@ -271,9 +271,9 @@ is ignored if + is anything other than \(oqPCI\(cq. + .TP 8 + .B \-keeptty +-Prevent the server from detaching its initial controlling terminal. +-This option is only useful when debugging the server. Not all platforms +-support (or can use) this option. ++Prevent the server from detaching its initial controlling terminal. If you ++want to use systemd-logind integration you must specify this option. ++Not all platforms support (or can use) this option. + .TP 8 + .BI \-keyboard " keyboard-name" + Use the xorg.conf(__filemansuffix__) file +--- a/hw/xfree86/os-support/linux/systemd-logind.c ++++ b/hw/xfree86/os-support/linux/systemd-logind.c +@@ -34,6 +34,7 @@ + + #include "os.h" + #include "dbus-core.h" ++#include "linux.h" + #include "xf86.h" + #include "xf86platformBus.h" + #include "xf86Xinput.h" +@@ -596,6 +597,13 @@ static struct dbus_core_hook core_hook = + int + systemd_logind_init(void) + { ++ if (linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) { ++ LogMessage(X_INFO, ++ "systemd-logind: logind integration requires -keeptty and " ++ "-keeptty was not provided, disabling logind integration\n"); ++ return 1; ++ } ++ + return dbus_core_add_hook(&core_hook); + } + diff --git a/U_systemd-logind-do-not-rely-on-directed-signals.patch b/U_systemd-logind-do-not-rely-on-directed-signals.patch new file mode 100644 index 0000000..8197e10 --- /dev/null +++ b/U_systemd-logind-do-not-rely-on-directed-signals.patch @@ -0,0 +1,58 @@ +From 780a69aff0ff57ef813179a2f09556eaf488cdfc Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Mon, 22 Jun 2015 21:13:05 +0200 +Subject: [PATCH] systemd-logind: do not rely on directed signals + +Right now, Xorg does not install DBus matches for "PauseDevice" / +"ResumeDevice". Therefore, it should usually not receive those DBus +signals from logind. It is just a coincidence that systemd-logind sends +those signals in a directed manner right now. Therefore, dbus-daemon +bypasses the broadcast matches. + +However, this is not ABI and Xorg should not rely on this. systemd-logind +is free to send those signals as broadcasts, in which case Xorg will +freeze the VT. Fix this by always installing those matches. + +Cc: Hans de Goede +Cc: Keith Packard +Reported-by: Jan Alexander Steffens +Signed-off-by: David Herrmann +Reviewed-by: Hans de Goede +Tested-by: Hans de Goede +Signed-off-by: Hans de Goede +--- + hw/xfree86/os-support/linux/systemd-logind.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c +index 69e2f673d4bb..2612d9e23bc4 100644 +--- a/hw/xfree86/os-support/linux/systemd-logind.c ++++ b/hw/xfree86/os-support/linux/systemd-logind.c +@@ -507,6 +507,24 @@ connect_hook(DBusConnection *connection, void *data) + goto cleanup; + } + ++ dbus_bus_add_match(connection, ++ "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='PauseDevice'", ++ &error); ++ if (dbus_error_is_set(&error)) { ++ LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", ++ error.message); ++ goto cleanup; ++ } ++ ++ dbus_bus_add_match(connection, ++ "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='ResumeDevice'", ++ &error); ++ if (dbus_error_is_set(&error)) { ++ LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", ++ error.message); ++ goto cleanup; ++ } ++ + /* + * HdG: This is not useful with systemd <= 208 since the signal only + * contains invalidated property names there, rather than property, val +-- +2.4.6 + diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index 921a851..9c0595b 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Thu Jul 30 12:10:08 CEST 2015 - tiwai@suse.de + +- Backport a few upstream fixes for systemd/VT handling (boo#939838): + U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch + U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch + U_systemd-logind-Only-use-systemd-logind-integration-t.patch + U_systemd-logind-do-not-rely-on-directed-signals.patch + ------------------------------------------------------------------- Mon Jul 27 11:52:32 UTC 2015 - eich@suse.com diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 1114c49..a5ced46 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -1,7 +1,7 @@ # # spec file for package xorg-x11-server # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -178,6 +178,11 @@ Patch115: N_Force-swcursor-for-KMS-drivers-without-hw-cursor-sup.patch Patch117: xorg-x11-server-byte-order.patch +Patch201: U_linux-Add-linux_parse_vt_settings-and-linux_get_keep.patch +Patch202: U_linux-Add-a-may_fail-paramter-to-linux_parse_vt_sett.patch +Patch203: U_systemd-logind-Only-use-systemd-logind-integration-t.patch +Patch204: U_systemd-logind-do-not-rely-on-directed-signals.patch + Patch1000: n_xserver-optimus-autoconfig-hack.patch Patch1162: b_cache-xkbcomp-output-for-fast-start-up.patch @@ -272,6 +277,11 @@ cp %{SOURCE90} . %patch117 -p1 +%patch201 -p1 +%patch202 -p1 +%patch203 -p1 +%patch204 -p1 + %patch1000 -p1 ### disabled for now