Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAuto-detect how keyboard is attached (USB or not) #2736
Comments
jpouellet
referenced this issue
Apr 2, 2017
Open
provide GUI mechanism (Qubes Manager, Settings, etc) for enabling USB keyboard #2329
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
A first attempt:
[user@dom0 ~]$ cat /tmp/x
awk '
function clr() {
kbd=0
usb=0
n=""
}
BEGIN {
clr()
}
/^$/ {
if (kbd)
print (usb ? "usb" : "non-usb") " keyboard found: " n
clr()
}
/^H: Handlers=.*kbd/ {
kbd=1
}
/^S: Sysfs=.*\/usb[0-9]+\// {
usb=1
}
/N: Name=/{
sub(/[^"]*"/, "")
sub(/"$/, "")
n=$0
}
' < /proc/bus/input/devices
Does not produce reliable enough results:
[user@dom0 ~]$ sh /tmp/x
non-usb keyboard found: Sleep Button
non-usb keyboard found: Power Button
non-usb keyboard found: AT Translated Set 2 keyboard
non-usb keyboard found: Video Bus
non-usb keyboard found: PC Speaker
non-usb keyboard found: ThinkPad Extra Buttons
[user@dom0 ~]$ qvm-run -p sys-usb sh < /tmp/x
non-usb keyboard found: PC Speaker
usb keyboard found: Apple, Inc Apple Keyboard
usb keyboard found: Apple, Inc Apple Keyboard
There are non-usb "keyboards" present, and one could similarly imagine a laptop having yes-usb "keyboards" as well.
|
A first attempt:
Does not produce reliable enough results:
There are non-usb "keyboards" present, and one could similarly imagine a laptop having yes-usb "keyboards" as well. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Presence of non-keyboard buttons (extra media keys, random switches, etc.) make just checking for existence of usb or non-usb "keyboard" give false positives/negatives.
At least for autodetection in the installer we might monitor all /dev/input/eventX while the user types something, then find the corresponding device that's actually being used to type on and see what driver it's using? Not sure if this is suitable for qubes-hcl-report as we may not want to require any input for it to complete (for example, I've run it on a remote server once). It would be nice if there were a way to determine the last time a device gave input, but looking through the linux docs the closest thing seems to be MSC_TIMESTAMP which talks about "reset" (apparently not related to EV_KEY). Maybe some higher layer tracks this?
There must be a better way. My knowledge of the linux input stack is not as strong as it could be.
|
Presence of non-keyboard buttons (extra media keys, random switches, etc.) make just checking for existence of usb or non-usb "keyboard" give false positives/negatives. At least for autodetection in the installer we might monitor all /dev/input/eventX while the user types something, then find the corresponding device that's actually being used to type on and see what driver it's using? Not sure if this is suitable for qubes-hcl-report as we may not want to require any input for it to complete (for example, I've run it on a remote server once). It would be nice if there were a way to determine the last time a device gave input, but looking through the linux docs the closest thing seems to be MSC_TIMESTAMP which talks about "reset" (apparently not related to EV_KEY). Maybe some higher layer tracks this? There must be a better way. My knowledge of the linux input stack is not as strong as it could be. |
jpouellet
changed the title from
HCL: report how keyboard is attached
to
Auto-detect how keyboard is attached (USB or not)
Apr 2, 2017
jpouellet
referenced this issue
in QubesOS/qubes-app-linux-input-proxy
Apr 2, 2017
Merged
Move security warning to qubes-doc #4
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
unman
Apr 2, 2017
Member
|
On Sat, Apr 01, 2017 at 07:44:29PM -0700, Jean-Philippe Ouellet wrote:
Presence of non-keyboard buttons (extra media keys, random switches, etc.) make just checking for existence of usb or non-usb "keyboard" give false positives/negatives.
Maybe monitor all /dev/input/eventX while the user types something in the installer, then find the corresponding device that's actually being used to type on and see what driver it's using?
Must be a better way. My knowledge of the linux input stack is not as strong as it could be.
Try parsing /proc/bus/input/devices
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Tried that, doesn't work as hoped. See above.
I see you're replying from email, and I've edited the comments a bit so you may be missing context I've added later. I have a bad habit of editing perhaps a bit too often... sorry about that.
|
Tried that, doesn't work as hoped. See above. I see you're replying from email, and I've edited the comments a bit so you may be missing context I've added later. I have a bad habit of editing perhaps a bit too often... sorry about that. |
andrewdavidwong
added
C: core
enhancement
labels
Apr 2, 2017
andrewdavidwong
added this to the Far in the future milestone
Apr 2, 2017
andrewdavidwong
added
C: installer
and removed
C: core
labels
Apr 2, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
marmarek
Apr 2, 2017
Member
Not a perfect solution, but udev have some clues: https://github.com/QubesOS/qubes-installer-qubes-os/blob/master/qubes-anaconda-addon/org_qubes_os_initial_setup/gui/spokes/qubes_os.py#L63-L66
|
Not a perfect solution, but udev have some clues: https://github.com/QubesOS/qubes-installer-qubes-os/blob/master/qubes-anaconda-addon/org_qubes_os_initial_setup/gui/spokes/qubes_os.py#L63-L66 |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
I believe having both Phys= contain /serio and Handlers= contain kdb could reliably detect a PS/2 keyboard. But that's only a 5min assessment. Actually, you could probably do this just by looking at the names in /dev/input/by-path, where -serio- and -kbd are both present.
Also, search seems to indicate i8042 is some near-universal controller for PS/2 ports? But I don't know if we'd want to specify that.
I'd also want to know if functioning-but-empty PS/2 ports were available.
tasket
commented
Apr 2, 2017
|
I believe having both Also, search seems to indicate I'd also want to know if functioning-but-empty PS/2 ports were available. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
In bash...
for file in /dev/input/by-path/*-serio-*-kbd ; do
if [[ -c $file ]]; then
ps2present=true
fi
done
tasket
commented
Apr 2, 2017
|
In bash...
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Yethal
commented
Apr 2, 2017
|
@tasket I have a PS/2 keyboard if you want test results from real hardware |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
unman
Apr 2, 2017
Member
@jpouellet Keyboards will always have EV=120013 in /proc/bus/input/devices, so you can combine that with the usb test for clear result. This is much cleaner than Phys or Handlers tests.
|
@jpouellet Keyboards will always have EV=120013 in /proc/bus/input/devices, so you can combine that with the usb test for clear result. This is much cleaner than Phys or Handlers tests. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
@unman Interesting. That does work reliably on my machines, but it seems it would be valid for keyboards to also appear with some superset of that bitmask as well?
|
@unman Interesting. That does work reliably on my machines, but it seems it would be valid for keyboards to also appear with some superset of that bitmask as well? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Maybe possible to have valid keyboards without EV_LED bit set as well?
|
Maybe possible to have valid keyboards without EV_LED bit set as well? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
marmarek
Apr 2, 2017
Member
AFAIR this is very similar to what udev check when decide on adding ID_INPUT_KEYBOARD=1 additionally it check for actual keys presence.
|
AFAIR this is very similar to what udev check when decide on adding |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
@Yethal You could try the above code, with and without the keyboard attached. Actually, here is a shorter version that does the job:
if [ -n "$( find /dev/input/by-path -name '*-serio-*-kbd' )" ]; then echo "PS/2 Detected"; fi
There's a developer wiki with PS/2 information. It indicates that i8042 is the controller used on PC compatibles (and they list a different controller for ARM):
http://wiki.osdev.org/PS/2
tasket
commented
Apr 2, 2017
|
@Yethal You could try the above code, with and without the keyboard attached. Actually, here is a shorter version that does the job:
There's a developer wiki with PS/2 information. It indicates that i8042 is the controller used on PC compatibles (and they list a different controller for ARM): |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Yethal
Apr 2, 2017
@tasket above code echoes "PS/2 detected" regardless of whether the keyboard is actually connected to the PC or not.
Yethal
commented
Apr 2, 2017
|
@tasket above code echoes "PS/2 detected" regardless of whether the keyboard is actually connected to the PC or not. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Here's a shot using udev:
#!/bin/sh
udevadm info -e | awk '
BEGIN {
found_usb=0
found_nonusb=0
kbd=0
usb=0
}
/^$/ {
if (kbd) {
if (usb)
found_usb++
else
found_nonusb++
}
kbd=0
usb=0
}
/^E: ID_INPUT_KEYBOARD=1$/ { kbd=1 }
/^E: ID_USB/ { usb=1 }
END {
if (found_usb && !found_nonusb)
print "USB"
else if (!found_usb && found_nonusb)
print "non-USB"
else if (found_usb && found_nonusb)
print "both"
else
print "none"
}
'
I'm admittedly not very familiar with udev, and there didn't seem to be a way to query for a device matching particular attributes (like you'd do when matching rules), rather udevadm info seems to expect you to query a specific device, or dump everything? I'd like to be wrong about this.
|
Here's a shot using udev:
I'm admittedly not very familiar with udev, and there didn't seem to be a way to query for a device matching particular attributes (like you'd do when matching rules), rather |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Enumerating with pyudev like in the installer would be cleaner, but we don't have pyudev in dom0 by default and idk if we'd like to bring it in just for qubes-hcl-report (which is currently all shell anyway).
|
Enumerating with pyudev like in the installer would be cleaner, but we don't have pyudev in dom0 by default and idk if we'd like to bring it in just for qubes-hcl-report (which is currently all shell anyway). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
@Yethal Can you post a list of your dir /dev/input/by-path with the keyboard unplugged? Its possibly detecting the empty port (which is good).
tasket
commented
Apr 2, 2017
|
@Yethal Can you post a list of your dir /dev/input/by-path with the keyboard unplugged? Its possibly detecting the empty port (which is good). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jpouellet
Apr 2, 2017
Contributor
Its possibly detecting the empty port (which is good).
Good... unless the laptop simply has a PS/2 controller somewhere with no actual PS/2 port exposed, and the built-in keyboard is attached via internal USB. If udev has logic to attempt to differentiate this case, then I think it makes sense to take advantage of it.
Good... unless the laptop simply has a PS/2 controller somewhere with no actual PS/2 port exposed, and the built-in keyboard is attached via internal USB. If udev has logic to attempt to differentiate this case, then I think it makes sense to take advantage of it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
I don't know what use case would justify a PS/2 controller + internal USB keyboard. Assuming there is, (though I doubt udev can tell between an internal and external PS/2 port) then I'd guess we're looking at involving the user in a hardware test of some kind... "Press the Z and SHIFT keys on your keyboard" for each detected keyboard. But since we're also looking for the ability to plug in a PS/2 keyboard (not so much whether such a keyboard is presently attached) then we may have to ask the user to plug in a PS/2 keyboard if one is available.
More realistic would be detecting PS/2 keyboard devices as above, instruct user to press keys on the "internal laptop keyboard (if any)" ... and ask a separate question "Does your computer have external PS/2 ports"?
This would return multiple pieces of information, and it could be represented on the HCL under a PS/2 Keyboard column with indications 'Controller present', 'Detected' or 'Answered yes'.
Another possibility is 'KISS'... simply show whether a PS/2 keyboard controller was detected and add a footnote explaining what that means. But I like the above idea of having the user answer a question and tap keys.
tasket
commented
Apr 2, 2017
|
I don't know what use case would justify a PS/2 controller + internal USB keyboard. Assuming there is, (though I doubt udev can tell between an internal and external PS/2 port) then I'd guess we're looking at involving the user in a hardware test of some kind... "Press the Z and SHIFT keys on your keyboard" for each detected keyboard. But since we're also looking for the ability to plug in a PS/2 keyboard (not so much whether such a keyboard is presently attached) then we may have to ask the user to plug in a PS/2 keyboard if one is available. More realistic would be detecting PS/2 keyboard devices as above, instruct user to press keys on the "internal laptop keyboard (if any)" ... and ask a separate question "Does your computer have external PS/2 ports"? This would return multiple pieces of information, and it could be represented on the HCL under a Another possibility is 'KISS'... simply show whether a PS/2 keyboard controller was detected and add a footnote explaining what that means. But I like the above idea of having the user answer a question and tap keys. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tasket
Apr 2, 2017
To clarify:
Ideally we should look for a PS/2 "internal" laptop keyboard and/or external PS/2 ports.
If we're going to encounter systems with odd combinations like USB internal keyboard + PS/2 touchpad + unused PS/2 keyboard port (or a PS/2 special-key device) then we'll probably need user input to discern what is a real keyboard or accessible port. The alternative is to report simply that PS/2 was detected along with a footnote/disclaimer.
I don't know if Linux distros (or any equipment vendor) ever had reason to care whether a PS/2 device was internal or external...
tasket
commented
Apr 2, 2017
|
To clarify: Ideally we should look for a PS/2 "internal" laptop keyboard and/or external PS/2 ports. If we're going to encounter systems with odd combinations like USB internal keyboard + PS/2 touchpad + unused PS/2 keyboard port (or a PS/2 special-key device) then we'll probably need user input to discern what is a real keyboard or accessible port. The alternative is to report simply that PS/2 was detected along with a footnote/disclaimer. I don't know if Linux distros (or any equipment vendor) ever had reason to care whether a PS/2 device was internal or external... |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Yethal
Apr 3, 2017
@tasket here are by-path contents:
platform-i8042-serio-0-event-kbd platform-pcspkr-event-spkr
There is also a possibility that an external PS/2 port is internally connected to a PS/2 to USB converter which is then connected to a USB controller.
Yethal
commented
Apr 3, 2017
|
@tasket here are by-path contents: There is also a possibility that an external PS/2 port is internally connected to a PS/2 to USB converter which is then connected to a USB controller. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
relevant: #2781 (comment) Keyboards can be weird... |
jpouellet commentedApr 2, 2017
•
edited
Edited 1 time
-
jpouellet
edited Apr 2, 2017 (most recent)
How the keyboard attaches to the system (over some spi/i2c (via the EC), or through USB) is a very useful property to know when considering to buy a laptop for Qubes.
This is especially true if we intend to move towards sys-usb by default. (I remember some discussion somewhere stating intent to remove "experimental" label in the installer option and enable it by default, but can't seem to find it right now.)
See also #2329.
I'm opening an issue rather than just submitting a PR because I don't know how to reliably determine this information.
xinput?/proc/bus/input/devices?lsusb? something else?/cc @tasket
edit: issue was originally just because this would be nice to have in the HCL, but we would need to reliably autodetect this in the installer as well if we want to enable sys-usb by default (so we could know whether or not to enable the input proxy). Issue title updated accordingly.