~ubuntu-branches/ubuntu/raring/consolekit/raring

« back to all changes in this revision

Viewing changes to debian/patches/01-fallback_no_vt_waitevent.patch

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-11-20 18:17:28 UTC
  • mfrom: (0.1.16 sid)
  • Revision ID: james.westby@ubuntu.com-20101120181728-8e5bwe4ttgmk4j41
Tags: 0.4.3-2
Add 01-retry-console-open-on-EIO.patch: As reported in LP: #544139,
ConsoleKit sometimes fails to track the active VT. This particular case
was tracked down to a race condition that happens if you try to open
/dev/console while the current TTY is currently being closed. This yields
an -EIO error, in which case CK should just try again. Thanks Colin Watson
for the patch!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
commit 24dc214f55e7c7c17d888d0ccf94cd3625767462
2
 
Author: Michael Biebl <biebl@debian.org>
3
 
Date:   Mon Sep 20 00:45:16 2010 +0200
4
 
 
5
 
    linux: Check for VT_WAITEVENT ioctl during runtime
6
 
    
7
 
    Since 2782cc8d4950effbc4407455e72bd4750cef6e11 ConsoleKit fails, if it
8
 
    has been compiled on a linux kernel >= 2.6.32 but is run with an older
9
 
    kernel. Check for VT_WAITEVENT ioctl during runtime and fallback to the
10
 
    old behaviour of creating a thread for every possible vt.
11
 
 
12
 
diff --git a/src/ck-vt-monitor.c b/src/ck-vt-monitor.c
13
 
index 369c63e..9310341 100644
14
 
--- a/src/ck-vt-monitor.c
15
 
+++ b/src/ck-vt-monitor.c
16
 
@@ -27,6 +27,7 @@
17
 
 #include <string.h>
18
 
 #include <errno.h>
19
 
 #include <signal.h>
20
 
+#include <sys/ioctl.h>
21
 
 
22
 
 #include <glib.h>
23
 
 #include <glib/gi18n.h>
24
 
@@ -311,6 +312,34 @@ schedule_process_queue (CkVtMonitor *vt_monitor)
25
 
         G_UNLOCK (schedule_lock);
26
 
 }
27
 
 
28
 
+#ifdef VT_WAITEVENT
29
 
+static gboolean
30
 
+vt_waitevent_supported (int fd)
31
 
+{
32
 
+        static int supported = -1;
33
 
+        int res;
34
 
+
35
 
+        if (supported >= 0)
36
 
+                return supported;
37
 
+
38
 
+        res = ioctl(fd, VT_WAITEVENT, NULL);
39
 
+
40
 
+        if (res == ERROR) {
41
 
+                if (errno == EINVAL) {
42
 
+                        g_debug ("VT_WAITEVENT not supported on this system");
43
 
+                        supported = FALSE;
44
 
+                        return FALSE;
45
 
+                } else if (errno == EFAULT) {
46
 
+                        g_debug ("VT_WAITEVENT supported on this system");
47
 
+                        supported = TRUE;
48
 
+                        return TRUE;
49
 
+                }
50
 
+        }
51
 
+        g_debug ("Unexpected result for VT_WAITEVENT check, returning FALSE");
52
 
+        return FALSE;
53
 
+}
54
 
+#endif
55
 
+
56
 
 static void *
57
 
 vt_thread_start (ThreadData *data)
58
 
 {
59
 
@@ -322,6 +351,9 @@ vt_thread_start (ThreadData *data)
60
 
         num = data->num;
61
 
 
62
 
 #ifdef VT_WAITEVENT
63
 
+        if (!vt_waitevent_supported(vt_monitor->priv->vfd))
64
 
+                goto no_waitevent;
65
 
+
66
 
         for (;;) {
67
 
                 res = ck_wait_for_console_switch (vt_monitor->priv->vfd, &num);
68
 
                 if (! res) {
69
 
@@ -340,7 +372,10 @@ vt_thread_start (ThreadData *data)
70
 
                         schedule_process_queue (vt_monitor);
71
 
                 }
72
 
         }
73
 
-#else
74
 
+        goto out;
75
 
+#endif
76
 
+
77
 
+no_waitevent:
78
 
         res = ck_wait_for_active_console_num (vt_monitor->priv->vfd, num);
79
 
         if (! res) {
80
 
                 /* FIXME: what do we do if it fails? */
81
 
@@ -357,8 +392,8 @@ vt_thread_start (ThreadData *data)
82
 
                 /* schedule processing of queue */
83
 
                 schedule_process_queue (vt_monitor);
84
 
         }
85
 
-#endif
86
 
 
87
 
+out:
88
 
         G_LOCK (hash_lock);
89
 
         if (vt_monitor->priv->vt_thread_hash != NULL) {
90
 
                 g_hash_table_remove (vt_monitor->priv->vt_thread_hash, GUINT_TO_POINTER (num));
91
 
@@ -418,19 +453,24 @@ vt_add_watches (CkVtMonitor *vt_monitor)
92
 
         sigaction (SIGPOLL, &act, NULL);
93
 
 
94
 
         ioctl (vt_monitor->priv->vfd, I_SETSIG, S_MSG);
95
 
-#elif defined (VT_WAITEVENT)
96
 
+#else
97
 
+        guint  max_consoles;
98
 
+        int    i;
99
 
+        gint32 current_num;
100
 
         gpointer id;
101
 
 
102
 
+#if defined (VT_WAITEVENT)
103
 
+        if (!vt_waitevent_supported(vt_monitor->priv->vfd))
104
 
+                goto no_waitevent;
105
 
+
106
 
         G_LOCK (hash_lock);
107
 
         id = GINT_TO_POINTER (1);
108
 
         if (g_hash_table_lookup (vt_monitor->priv->vt_thread_hash, id) == NULL)
109
 
                 vt_add_watch_unlocked (vt_monitor, 1);
110
 
-        G_UNLOCK (hash_lock);
111
 
-#else
112
 
-        guint  max_consoles;
113
 
-        int    i;
114
 
-        gint32 current_num;
115
 
+        goto out;
116
 
+#endif
117
 
 
118
 
+no_waitevent:
119
 
         G_LOCK (hash_lock);
120
 
 
121
 
         current_num = vt_monitor->priv->active_num;
122
 
@@ -442,7 +482,6 @@ vt_add_watches (CkVtMonitor *vt_monitor)
123
 
         }
124
 
 
125
 
         for (i = 1; i < max_consoles; i++) {
126
 
-                gpointer id;
127
 
 
128
 
                 /* don't wait on the active vc */
129
 
                 if (i == current_num) {
130
 
@@ -457,6 +496,7 @@ vt_add_watches (CkVtMonitor *vt_monitor)
131
 
                 }
132
 
         }
133
 
 
134
 
+out:
135
 
         G_UNLOCK (hash_lock);
136
 
 #endif
137
 
 }