Gentoo Archives: gentoo-commits

From: "Nirbheek Chauhan (nirbheek)" <nirbheek@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in gnome-base/gdm/files: gdm-2.32.0-fix-vt-problems.patch
Date: Tue, 03 May 2011 06:46:20
Message-Id: 20110503064610.0A49020054@flycatcher.gentoo.org
1 nirbheek 11/05/03 06:46:10
2
3 Added: gdm-2.32.0-fix-vt-problems.patch
4 Log:
5 Fix bug 288852, vt detection finally works properly, remove old
6
7 (Portage version: 2.1.9.46/cvs/Linux x86_64)
8
9 Revision Changes Path
10 1.1 gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/gnome-base/gdm/files/gdm-2.32.0-fix-vt-problems.patch?rev=1.1&content-type=text/plain
14
15 Index: gdm-2.32.0-fix-vt-problems.patch
16 ===================================================================
17 From 64002e623fea54ab10040206d164c5fdee4a43d2 Mon Sep 17 00:00:00 2001
18 From: Nirbheek Chauhan <nirbheek@g.o>
19 Date: Fri, 15 Apr 2011 22:13:44 +0530
20 Subject: [PATCH] Fix VT grab race with getty causing X to grab the wrong VT
21
22 On bootup, if X is spawned without any args, it'll take up the first unused VT.
23 If GDM starts up before gettys are spawned, X takes up VT1 or VT2 depending on
24 the init system and bootsplash.
25
26 This is problematic because afterwards getty will come up underneath X, and
27 cause keyboard problems and eventually crash X.
28
29 So we read /etc/inittab, check for open VTs, compare the two values, and take
30 the conservative one.
31 ---
32 configure.ac | 4 ++
33 daemon/Makefile.am | 1 +
34 daemon/gdm-server.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++-
35 3 files changed, 110 insertions(+), 1 deletions(-)
36
37 diff --git a/configure.ac b/configure.ac
38 index ca0f8bb..b9e7462 100644
39 --- a/configure.ac
40 +++ b/configure.ac
41 @@ -302,6 +302,10 @@ AC_CHECK_TYPE(socklen_t,,
42 AC_CHECK_HEADERS(sys/sockio.h)
43 AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv])
44
45 +dnl Needed for querying the kernel for free VTs
46 +AC_CHECK_HEADERS(sys/vt.h)
47 +AC_CHECK_HEADERS(sys/ioctl.h)
48 +
49 dnl checks needed for Darwin compatibility to linux **environ.
50 AC_CHECK_HEADERS(crt_externs.h)
51 AC_CHECK_FUNCS(_NSGetEnviron)
52 diff --git a/daemon/Makefile.am b/daemon/Makefile.am
53 index da18835..c1b6bda 100644
54 --- a/daemon/Makefile.am
55 +++ b/daemon/Makefile.am
56 @@ -14,6 +14,7 @@ AM_CPPFLAGS = \
57 -DLIBEXECDIR=\"$(libexecdir)\" \
58 -DLOGDIR=\"$(logdir)\" \
59 -DSBINDIR=\"$(sbindir)\" \
60 + -DSYSCONFDIR=\""$(sysconfdir)"\" \
61 -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
62 -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \
63 -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \
64 diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
65 index 339f3cc..29d16dc 100644
66 --- a/daemon/gdm-server.c
67 +++ b/daemon/gdm-server.c
68 @@ -26,6 +26,8 @@
69 #include <unistd.h>
70 #include <string.h>
71 #include <sys/types.h>
72 +#include <sys/ioctl.h>
73 +#include <sys/vt.h>
74 #include <sys/wait.h>
75 #include <errno.h>
76 #include <ctype.h>
77 @@ -42,6 +44,7 @@
78 #include <glib/gi18n.h>
79 #include <glib/gstdio.h>
80 #include <glib-object.h>
81 +#include <gio/gio.h>
82
83 #include <X11/Xlib.h> /* for Display */
84
85 @@ -54,6 +57,8 @@ extern char **environ;
86
87 #define GDM_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SERVER, GdmServerPrivate))
88
89 +#define INITTAB SYSCONFDIR"/inittab"
90 +
91 /* These are the servstat values, also used as server
92 * process exit codes */
93 #define SERVER_TIMEOUT 2 /* Server didn't start */
94 @@ -674,6 +679,105 @@ gdm_server_spawn (GdmServer *server,
95 }
96
97 /**
98 + * Parse the inittab file used by getty to spawn VTs to find unused ttys
99 + */
100 +int
101 +get_free_vt_from_inittab ()
102 +{
103 + GFile *gfile;
104 + GFileInputStream *contents;
105 + GDataInputStream *dstream;
106 + GRegex *getty;
107 + GMatchInfo *tty_match = NULL;
108 + GSList *tty_list = NULL;
109 + GError *error = NULL;
110 + gchar *temp = NULL;
111 + int vtno = 0;
112 +
113 + gfile = g_file_new_for_path (INITTAB);
114 + contents = g_file_read (gfile, NULL, &error);
115 + g_object_unref (gfile);
116 + if (!contents) {
117 + if (error) {
118 + g_debug ("Unable to open file %s", INITTAB);
119 + g_error_free (error);
120 + }
121 + goto out;
122 + }
123 +
124 + dstream = g_data_input_stream_new (G_INPUT_STREAM (contents));
125 + getty = g_regex_new ("^c[0-9]+:.+getty.+tty([0-9]+)", 0, 0, NULL);
126 + g_object_unref (contents);
127 +
128 + while (1) {
129 + temp = g_data_input_stream_read_line (dstream, NULL, NULL, &error);
130 + if (!temp)
131 + break;
132 + if (!g_regex_match (getty, temp, 0, &tty_match))
133 + continue;
134 + g_free (temp);
135 + temp = g_match_info_fetch (tty_match, 1);
136 + if (!temp)
137 + continue;
138 + tty_list = g_slist_insert_sorted (tty_list, temp, (GCompareFunc)g_strcmp0);
139 + g_match_info_free (tty_match);
140 + }
141 +
142 + if (error) {
143 + g_debug ("Unable to read line from %s", INITTAB);
144 + g_error_free (error);
145 + goto free;
146 + }
147 +
148 + /* Ignore holes in vt allocation, just take the last one */
149 + temp = g_slist_last (tty_list)->data;
150 + if (temp)
151 + vtno = (int) g_ascii_strtoull (temp, NULL, 10) + 1;
152 +
153 +free:
154 + g_object_unref (dstream);
155 + g_regex_unref (getty);
156 + g_slist_free_full (tty_list, g_free);
157 + g_free (error);
158 +out:
159 + return vtno;
160 +}
161 +
162 +/**
163 + * Query the VT_* kernel ioctls to find an empty tty
164 + */
165 +int
166 +get_free_vt_from_kernel()
167 +{
168 + int fd, vtno = 0;
169 +
170 + fd = open ("/dev/tty0", O_WRONLY, 0);
171 + if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) {
172 + vtno = 0;
173 + g_debug ("Unable to find a free vt, falling back to Xorg autodetect");
174 + }
175 + return vtno;
176 +}
177 +
178 +gchar*
179 +get_free_vt ()
180 +{
181 + int inittab_vtno, kernel_vtno;
182 + gchar* vt = NULL;
183 +
184 + inittab_vtno = get_free_vt_from_inittab();
185 + if (inittab_vtno > 0)
186 + g_debug ("Inittab says vt%i is free\n", inittab_vtno);
187 + kernel_vtno = get_free_vt_from_kernel();
188 + if (kernel_vtno > 0)
189 + g_debug ("Kernel says vt%i is free\n", kernel_vtno);
190 + /* Select the greater of the two because getty will use the others */
191 + if (kernel_vtno != 0 && inittab_vtno != 0)
192 + vt = g_strdup_printf ("vt%i", kernel_vtno > inittab_vtno ? kernel_vtno : inittab_vtno);
193 + return vt;
194 +}
195 +
196 +/**
197 * gdm_server_start:
198 * @disp: Pointer to a GdmDisplay structure
199 *
200 @@ -686,7 +790,7 @@ gdm_server_start (GdmServer *server)
201 gboolean res;
202
203 /* fork X server process */
204 - res = gdm_server_spawn (server, NULL);
205 + res = gdm_server_spawn (server, get_free_vt());
206
207 return res;
208 }
209 --
210 1.7.3.4