Fix "start -- vt7" not working (#1203780)

This commit is contained in:
Hans de Goede 2015-04-30 14:23:15 +02:00
parent c203333e97
commit 3ab4d5ab99
3 changed files with 314 additions and 1 deletions

View File

@ -0,0 +1,236 @@
From cd7063aa899b56d407b57eab06b51925c913399d Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 21 Jan 2015 09:31:39 +0100
Subject: [PATCH 1/2] linux: Add linux_get_vtno 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_get_vtno() 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 <hdegoede@redhat.com>
---
Changes in v2:
-Rename linux_get_vtno to linux_parse_vt_settings
---
hw/xfree86/os-support/linux/linux.h | 32 +++++++++
hw/xfree86/os-support/linux/lnx_init.c | 122 ++++++++++++++++++++-------------
2 files changed, 105 insertions(+), 49 deletions(-)
create mode 100644 hw/xfree86/os-support/linux/linux.h
diff --git a/hw/xfree86/os-support/linux/linux.h b/hw/xfree86/os-support/linux/linux.h
new file mode 100644
index 0000000..8cb8e3d
--- /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 <hdegoede@redhat.com>
+ */
+
+#ifndef XF86_LINUX_H
+#define XF86_LINUX_H
+
+void linux_parse_vt_settings(void);
+int linux_get_keeptty(void);
+
+#endif
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index 9485307..22c61bf 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -31,6 +31,7 @@
#include <X11/Xmd.h>
#include "compiler.h"
+#include "linux.h"
#include "xf86.h"
#include "xf86Priv.h"
@@ -80,71 +81,94 @@ switch_to(int vt, const char *from)
#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 (vt_settings_parsed)
+ return;
- if (fd < 0)
- FatalError("xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
- strerror(errno));
+ /*
+ * setup the virtual terminal manager
+ */
+ if (xf86Info.vtno != -1) {
+ from = X_CMDLINE;
+ }
+ else {
- 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);
+ i = 0;
+ while (tty0[i] != NULL) {
+ if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0)
+ break;
+ i++;
}
- xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+ if (fd < 0)
+ FatalError("parse_vt_settings: Cannot open /dev/tty0 (%s)\n",
+ strerror(errno));
- /* 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 (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);
- if (!KeepTty && current_vt == xf86Info.vtno) {
- xf86Msg(X_PROBED,
- "controlling tty is VT number %d, auto-enabling KeepTty\n",
- current_vt);
- KeepTty = TRUE;
+ /* 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();
--
2.3.6

View File

@ -0,0 +1,70 @@
From 4c5a293c20394bad6abb695aaa0d8ef374ed1080 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 21 Jan 2015 10:13:20 +0100
Subject: [PATCH 2/2] 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 <hdegoede@redhat.com>
---
hw/xfree86/man/Xorg.man | 6 +++---
hw/xfree86/os-support/linux/systemd-logind.c | 9 +++++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man
index 3ff6aef..0864a58 100644
--- 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 platorms support (or can use) this option.
.TP 8
.BI \-keyboard " keyboard-name"
Use the xorg.conf(__filemansuffix__) file
diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 4ad41a3..72f1ae3 100644
--- 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,14 @@ static struct dbus_core_hook core_hook = {
int
systemd_logind_init(void)
{
+ linux_parse_vt_settings();
+ if (!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);
}
--
2.3.6

View File

@ -45,7 +45,7 @@
Summary: X.Org X11 X server
Name: xorg-x11-server
Version: 1.17.1
Release: 9%{?gitdate:.%{gitdate}}%{dist}
Release: 10%{?gitdate:.%{gitdate}}%{dist}
URL: http://www.x.org
License: MIT
Group: User Interface/X
@ -112,6 +112,10 @@ Patch10001: 0001-sdksyms.sh-Make-sdksyms.sh-work-with-gcc5.patch
Patch10002: 0001-int10-Fix-mapping-the-interrupt-vector.patch
Patch10003: 0001-include-Fix-endianness-setup.patch
# rhbz1203780, submitted upstream
Patch10004: 0001-linux-Add-linux_get_vtno-and-linux_get_keeptty-helpe.patch
Patch10005: 0002-systemd-logind-Only-use-systemd-logind-integration-t.patch
%global moduledir %{_libdir}/xorg/modules
%global drimoduledir %{_libdir}/dri
%global sdkdir %{_includedir}/xorg
@ -645,6 +649,9 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog
* Thu Apr 30 2015 Hans de Goede <hdegoede@redhat.com> - 1.17.1-10
- Fix "start -- vt7" not working (#1203780)
* Sat Apr 11 2015 Ray Strode <rstrode@redhat.com> 1.17.1-9
- Handle logind timeouts more gracefuly.
- Bump timeouts so they don't happen in practice