Hello Everyone,
I have a boot script which sets the numlock key so I can use the number
keypad on the end of my keyboard without thinking about having to press
the numlock key. I think I got the code from the setleds man page and
it goes like this:
for tty in /dev/tty{1..6}
do setleds -D +num < ${tty}
done
It runs in init 3, at the console. I've had it for years, it's always
run fine without causing me any problems, until recently. With the 3.4
kernel (currently 3.4-rc4) I get an error message printed on the screen
6 times:
KDSKBLED: Invalid argument
and then a big red error message 'cos the bootscript failed as setleds
exited with a non zero return value of 1. Oddly, despite
this, setleds works, it sets the numlock key :/ so I can work around
the error messages by adding a little to the script:
for tty in /dev/tty{1..6}
do setleds -D +num < ${tty} &> /dev/null || true
done
Which works, does the job, sets the numlock and doesn't complain.
However, I'd rather get to the bottom of it and fix it properly rather
than muffle the error message. Does anyone know what has changed in the
3.4 kernel that is causing this? setleds comes from kbd-1.15.2. I've
also tried kbd-1.15.3 and current git with the same results. Digging in
the kernel, it seems that this commit is the culprit:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blobdiff;f=drivers/tty/vt/keyboard.c;h=70d0593d3bc66331f942632130c7ddd802a65fbb;hp=898e359c54240dfa10a9c3c0dfbea5dde77f6cf3;hb=079c9534a96da9a85a2a2f9715851050fbfbf749;hpb=0fb8379dab9f97e4c56de8f9ea772c10eda27561
Specifically this bit:
+int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
+{
+ struct kbd_struct * kbd = kbd_table + console;
+ unsigned long flags;
+ unsigned char ucval;
+
+ switch(cmd) {
+ /* the ioctls below read/set the flags usually shown in the leds */
+ /* don't use them - they will go away without warning */
+ case KDGKBLED:
+ spin_lock_irqsave(&kbd_event_lock, flags);
+ ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
+ spin_unlock_irqrestore(&kbd_event_lock, flags);
+ return put_user(ucval, (char __user *)arg);
+
+ case KDSKBLED:
+ if (!perm)
+ return -EPERM;
+ if (arg & ~0x77)
+ return -EINVAL;
+ spin_lock_irqsave(&kbd_event_lock, flags);
+ kbd->ledflagstate = (arg & 7);
+ kbd->default_ledflagstate = ((arg >> 4) & 7);
+ set_leds();
+ spin_unlock_irqrestore(&kbd_event_lock, flags);
+ break;
+
+ /* the ioctls below only set the lights, not the functions */
+ /* for those, see KDGKBLED and KDSKBLED above */
+ case KDGETLED:
+ ucval = getledstate();
+ return put_user(ucval, (char __user *)arg);
+
+ case KDSETLED:
+ if (!perm)
+ return -EPERM;
+ setledstate(kbd, arg);
+ return 0;
+ }
+ return -ENOIOCTLCMD;
+}
Which looks to me like it's something to do with permissions? But I get
the error if use setleds as root?
The offending code from setleds.c is like this:
if (ioctl(0, KDSKBLED, (ndefflags << 4) | nflags)) {
perror("KDSKBLED");
exit(1);
}
And that's as far as I've got. Can anyone shed any light on this?
Andy
--
http://linuxfromscratch.org/mailman/listinfo/blfs-support
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page