Package: console-tools
Version: 1:0.2.3dbs-62
Severity: normal
Tags: patch
According to a comment in the kbd source, Linux 2.6.1 fixed the UNIMAP
ioctls to be per-VT rather than operating on the current foreground
console. This means that the VT switches added in 1:0.2.3dbs-51 in
response to bug #226457 are unnecessary if you're running a more recent
kernel. Please apply the attached patch to 220_unimap_vts.patch, which
checks the kernel version and disables the VT switches if possible.
Changelog entry:
* 220_unimap_vts.patch: Linux 2.6.1 fixed the GIO_UNIMAP, PIO_UNIMAP, and
PIO_UNIMAPCLR ioctls to be per-VT rather than always using the current
foreground console. If we're running on Linux 2.6.1 or newer, suppress
the VT switch.
(Yes, I know I should probably switch to kbd, but Ubuntu is currently in
feature freeze so I'm sticking with console-tools for now ...)
Thanks,
--
Colin Watson [EMAIL PROTECTED]
--- console-tools-0.2.3dbs.orig/debian/patches/220_unimap_vts.patch
2006-06-29 10:42:54.000000000 +0100
+++ console-tools-0.2.3dbs/debian/patches/220_unimap_vts.patch 2006-09-08
11:03:45.000000000 +0100
@@ -1,17 +1,45 @@
diff -ruN console-tools-0.2.3-old/lib/sfm-misc.c
console-tools-0.2.3/lib/sfm-misc.c
--- console-tools-0.2.3-old/lib/sfm-misc.c 1999-04-08 22:29:39.000000000
+0100
-+++ console-tools-0.2.3/lib/sfm-misc.c 2004-04-18 11:54:52.000000000 +0100
-@@ -13,15 +13,67 @@
++++ console-tools-0.2.3/lib/sfm-misc.c 2006-09-08 10:55:33.000000000 +0100
+@@ -13,15 +13,95 @@
#include <ctype.h>
#include <fcntl.h>
#include <linux/kd.h>
+#include <linux/vt.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
++#include <sys/utsname.h>
#include <lct/local.h>
#include <lct/console.h>
++/* Linux 2.6.1 introduced per-VT UNIMAP ioctls, so with that kernel or
++ * better we don't need to switch VTs.
++ */
++static int per_vt_unimap(void)
++{
++ static int per_vt = -1;
++ struct utsname uts;
++ int major_high, major_low, minor;
++
++ if (per_vt != -1) {
++ return per_vt;
++ }
++ if (uname(&uts) < 0) {
++ return per_vt = 0;
++ }
++ if (strcmp(uts.sysname, "Linux")) {
++ return per_vt = 0;
++ }
++ if (sscanf(uts.release, "%d.%d.%d", &major_high, &major_low, &minor) < 3) {
++ return per_vt = 0;
++ }
++ if (major_high < 2 || major_low < 6 || minor < 1)
++ return per_vt = 0;
++ else
++ return per_vt = 1;
++}
++
+static int set_fd_foreground(int fd)
+{
+ struct vt_stat vstate;
@@ -69,35 +97,39 @@
/* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP
printf does not work. */
-@@ -30,6 +82,7 @@
+@@ -30,6 +110,8 @@
advice.advised_hashstep = 0;
advice.advised_hashlevel = 1; /* FIXME: 0 or 1 ? */
-+ oldcon = set_fd_foreground(fd);
++ if (!per_vt_unimap())
++ oldcon = set_fd_foreground(fd);
again:
if (ioctl(fd, PIO_UNIMAPCLR, &advice))
{
-@@ -41,6 +94,7 @@
+@@ -41,6 +123,8 @@
}
else
#endif
-+ restore_fd_foreground(fd, oldcon);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, oldcon);
return -1;
}
-@@ -51,9 +105,10 @@
+@@ -51,9 +135,13 @@
advice.advised_hashlevel++;
goto again;
}
-+ restore_fd_foreground(fd, oldcon);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, oldcon);
return -1;
}
--
-+ restore_fd_foreground(fd, oldcon);
+
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, oldcon);
return 0;
}
-@@ -61,15 +116,18 @@
+@@ -61,15 +149,20 @@
int get_kernel_unimap(int fd, struct unimapdesc *descr)
{
int ct;
@@ -106,35 +138,40 @@
descr->entry_ct = 0;
descr->entries = NULL;
-+ con = set_fd_foreground(fd);
++ if (!per_vt_unimap())
++ con = set_fd_foreground(fd);
/* get entry_ct */
if(ioctl(fd, GIO_UNIMAP, (unsigned long) descr)) /* failed */
{
if(errno != ENOMEM || descr->entry_ct == 0)
{
-+ restore_fd_foreground(fd, con);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, con);
perror(_("GIO_UNIMAP (get count)"));
return -1;
}
-@@ -84,10 +142,13 @@
+@@ -84,10 +177,15 @@
/* actually get unipairs */
if(ioctl(fd, GIO_UNIMAP, (unsigned long) descr))
{
-+ restore_fd_foreground(fd, con);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, con);
perror(_("GIO_UNIMAP (get map)"));
return -1;
}
-+ restore_fd_foreground(fd, con);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, con);
+
/* someone could change the unimap between our
* first and second ioctl, so we can have descrepancies
*/
-@@ -106,6 +167,7 @@
+@@ -106,6 +204,8 @@
}
else
{
-+ restore_fd_foreground(fd, con);
++ if (!per_vt_unimap())
++ restore_fd_foreground(fd, con);
/* no valid SFM currently loaded */
errno = ENXIO;
return -1;