When using a multi-seat configuration on Fedora 17, we need a method to
automatically assign devices to seats. The simplest method is to use
udev as explained rather
tersely in the multiseat documentation. Following
the setup in multi-seat configuration on Fedora 17, this article provides an
example of setting up the correct udev rules.
If you followed the guidelines in multi-seat configuration on Fedora 17
to set up your
configuration, you will find some rules in /etc/udev/rules.d/72-*
that Fedora
automatically sets up for you. Those rules are rather cryptic and hard to
maintain; please move those rules to a backup location (outside rules.d
).
We will continue the example by developing our own udev rules. To recap, here is
the list of hardware that corresponds to seat2
in this example:
Devices:
├ /sys/devices/pci0000:00/0000:00:04.0/0000:02:00.0/drm/card1
│ (drm:card1)
├ /sys/devices/pci0000:00/0000:00:04.0/0000:02:00.0/graphics/fb1
│ (graphics:fb1) "radeondrmfb"
├ /sys/devices/pci0000:00/0000:00:04.0/0000:02:00.1/sound/card2
│ (sound:card2) "HDMI"
│ └ /sys/devices/pci0000:00/0000:00:04.0/0000:02:00.1/sound/card2/input16
│ (input:input16) "HDA ATI HDMI HDMI/DP,pcm=3"
├ /sys/devices/pci0000:00/0000:00:12.1/usb4/4-1/4-1:1.0/input/input2
│ (input:input2) "CHESEN PS2 to USB Converter"
├ /sys/devices/pci0000:00/0000:00:12.1/usb4/4-1/4-1:1.1/input/input3
│ (input:input3) "CHESEN PS2 to USB Converter"
└ /sys/devices/pci0000:00/0000:00:12.1/usb4/4-2/4-2:1.0/input/input4
(input:input4) "Microsoft Microsoft 3-Button Mouse with IntelliEye(TM)"
We need to identify some feature of these devices that can be used to specify
udev rules assigning them to seat2
. In order to do so, we will first need to
see the attributes of these devices and their parents. We will tackle the
keyboard first (a few lines were stripped for brevity):
[root@kaito]$ udevadm info -a -p /devices/pci0000:00/0000:00:12.1/usb4/4-1/4-1:1.0/input/input2
...snip...
looking at device '/devices/pci0000:00/0000:00:12.1/usb4/4-1/4-1:1.0/input/input2':
KERNEL=="input2"
SUBSYSTEM=="input"
DRIVER==""
ATTR{name}=="CHESEN PS2 to USB Converter"
ATTR{phys}=="usb-0000:00:12.1-1/input0"
ATTR{uniq}==""
ATTR{properties}=="0"
looking at parent device '/devices/pci0000:00/0000:00:12.1/usb4/4-1/4-1:1.0':
KERNELS=="4-1:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usbhid"
ATTRS{bInterfaceClass}=="03"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bInterfaceProtocol}=="01"
ATTRS{bNumEndpoints}=="01"
ATTRS{supports_autosuspend}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}=="00"
...snip...
The keyboard can be identified easily by its name and there are no other devices
on the machine with the same name. The udev rule needs to assign an environment
variable called ID_SEAT
to the correct device:
TAG=="seat", ATTRS{name}=="CHESEN PS2 to USB Converter", ENV{ID_SEAT}="seat2"
Note that we have also added a match on the TAG
attribute to ensure that we do
not try to use devices that are not assignable to a seat (such as hard disks). A
similar solution works for the mouse as well. However, the video card is a
little more complex. The udev attributes for the video card is as follows:
[root@kaito]$ udevadm info -a -p /devices/pci0000:00/0000:00:04.0/0000:02:00.0/drm/card1
...snip...
looking at device '/devices/pci0000:00/0000:00:04.0/0000:02:00.0/drm/card1':
KERNEL=="card1"
SUBSYSTEM=="drm"
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:04.0/0000:02:00.0':
KERNELS=="0000:02:00.0"
SUBSYSTEMS=="pci"
DRIVERS=="radeon"
ATTRS{irq}=="45"
ATTRS{subsystem_vendor}=="0x174b"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x030000"
ATTRS{power_method}=="profile"
ATTRS{consistent_dma_mask_bits}=="40"
ATTRS{dma_mask_bits}=="40"
ATTRS{local_cpus}=="00000000,00000000,00000000,0000000f"
ATTRS{device}=="0x9588"
ATTRS{power_profile}=="default"
ATTRS{msi_bus}==""
ATTRS{local_cpulist}=="0-3"
ATTRS{vendor}=="0x1002"
ATTRS{subsystem_device}=="0x2e42"
ATTRS{boot_vga}=="0"
ATTRS{numa_node}=="0"
looking at parent device '/devices/pci0000:00/0000:00:04.0':
KERNELS=="0000:00:04.0"
SUBSYSTEMS=="pci"
DRIVERS=="pcieport"
ATTRS{irq}=="41"
ATTRS{subsystem_vendor}=="0x1849"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x060400"
ATTRS{consistent_dma_mask_bits}=="32"
ATTRS{dma_mask_bits}=="32"
ATTRS{local_cpus}=="00000000,00000000,00000000,0000000f"
ATTRS{device}=="0x597a"
ATTRS{msi_bus}=="1"
ATTRS{local_cpulist}=="0-3"
ATTRS{vendor}=="0x1002"
ATTRS{subsystem_device}=="0x5957"
ATTRS{numa_node}=="0"
...snip...
There does not seem to be an obvious property on which to match. After trawling
through various devices, we find that the one property that is different between
the two video cards: they both have the same vendor id, but different subsystem
device ids. (This makes sense since they are both RadeonHD cards, albeit with
different model numbers.) Then the udev rules follow easily:
# Radeon 2600XT video and HDMI audio
TAG=="seat", ATTRS{vendor}=="0x1002", ATTRS{subsystem_device}=="0x2e42", ENV{ID_SEAT}="seat2"
TAG=="seat", ATTRS{vendor}=="0x1002", ATTRS{subsystem_device}=="0xaa08", ENV{ID_SEAT}="seat2"
Putting all of the rules into a udev rules file completes the process:
# Radeon 2600XT video and HDMI audio
TAG=="seat", ATTRS{vendor}=="0x1002", ATTRS{subsystem_device}=="0x2e42", ENV{ID_SEAT}="seat2"
TAG=="seat", ATTRS{vendor}=="0x1002", ATTRS{subsystem_device}=="0xaa08", ENV{ID_SEAT}="seat2"
# Keyboard
TAG=="seat", ATTRS{name}=="CHESEN PS2 to USB Converter", ENV{ID_SEAT}="seat2"
# Mouse
TAG=="seat", ATTRS{name}=="Microsoft Microsoft 3-Button Mouse with IntelliEye(TM)", ENV{ID_SEAT}="seat2"
On reboot, devices will be assigned correctly to their respective seats. In
theory, everything should work fine. However, our current testing reveals a need
to boot into runlevel 3 and then manually invoke runlevel 5. We believe that
this may have something to do with a udev race in dracut. Until it is fixed,
the manual step of booting into runlevel 3 and changing manually into runlevel 5
will be needed.
Occasionally, we find that the GDM login screen turns blank. Once logged in,
this does not occur (at least with KDE). Our current workaround for this case is
to restart the X server for that particular seat by pressing Ctrl-Alt-Backspace
.