Multiseat mit Debian 11

PCs sind seit geraumer Zeit so schnell, dass sie sich die meiste Zeit mit Nichtstun beschäftigen können. Es ist daher naheliegend, einen einzigen Computer für mehrere Benutzer an mehreren Arbeitsplätzen zu verwenden, mit je einer Tastatur, Bildschirm und Maus. So spart man außerdem Geld, Zeit, Platz und Nerven. Und man lernt was.

Was braucht’s?

Der PC braucht pro Arbeitsplatz eine eigene Grafikkarte, und natürlich jeweils Monitor, Tastatur und Maus. Ich gehe unten mal von zwei Arbeitsplätzen aus. Im Rechner stecken also zwei Grafikkarten, und es sind zwei Tastaturen und zwei Mäuse angesteckt.

Wie funktioniert’s?

Jede Grafikkarte wird fest einem Arbeitsplatz (“seat”) zugeordnet, genauso die Tastaturen und Mäuse. Die Soundkarte wird gemeinsam genutzt: Die Benutzer können sich so gegenseitig die Lautstärke verstellen, was je nach Charakter Vor- und Nachteil sein kann. USB-Geräte werden ebenfalls gemeinsam verwendet: USB-Sticks können von allen benutzt werden. Ebenso DVD-Brenner, Drucker usw.

Grundsätzlich kann man auch mehrere Soundkarten einsetzen und alle USB-Ports ganz streng Benutzern zuordnen. Ich gehe hier jedoch von einem Heimbüro aus in dem Bequemlichkeit zählt.

Los geht’s!

Soundkarte gemeinsam nutzen

Normalerweise startet systemd für jeden Benutzer, der sich am Rechner anmeldet, eine eigene Pulseaudio-Instanz. Der aktive Nutzer bekommt die Soundkarte zugeteilt. Da bei Multiseat aber mehrerer Nutzer gleichzeitig angemeldet sind kann das so nicht funktionieren.

Man könnte nun für jeden Benutzer eine eigene Soundkarte kaufen, aber das ist unnötig.

Die Lösung: Nur eine einzige, systemweite Pulseaudio-Instanz für alle Benutzer verwenden.

  1. Zuerst das Starten der User-Instanzen abschalten:
    systemctl --global --now mask pulseaudio.service
    systemctl --global --now mask pulseaudio.socket
  2. Einen neuen systemd-Service für Pulseaudio erstellen. Dazu folgende Datei “/etc/systemd/system/pulseaudio.service” anlegen:
    Description=PulseAudio Sound System
    After=dbus.service avahi-daemon.service network-online.target
    [Service]
    Type=notify
    ExecStart=/usr/bin/pulseaudio --system --daemonize=no --realtime --disallow-module-loading=0 --disallow-exit --log-target=journal
    Restart=always
    [Install]
    WantedBy=multi-user.target sound.target
  3. Den neuen Pulseaudio-Service aktivieren: systemctl daemon-reload; systemctl --now enable pulseaudio.service
  4. Damit die Benutzern den neuen systemweiten Pulseaudio-Service nutzen dürfen, müssen sie Mitglied in der Gruppe pulse-access sein. Hinzufügen eines einzelnen Benutzers  geht so: adduser <username> pulse-access

Wichtig zu wissen: Im systemweiten Modus – also ab jetzt – verwendet Pulseaudio nicht mehr die Konfigurationsdatei /etc/pulse/default.pa sondern /etc/pulse/system.pa

Grafikkarte, Tastatur und Maus den Arbeitsplätzen zuordnen

Ein normales Linux-System kennt bereits das Konzept mehrerer Arbeitsplätze pro Rechner – standardmäßig werden schlicht alle Geräte dem “seat0” zugewiesen: Stecken zwei Mäuse am Rechner, steuern beide den gleichen Mauszeiger.

# loginctl list-seats

SEAT 
seat0

Die dem seat0 zugeteilten Geräte – und das sind zur Zeit noch alle – kann man mit loginctl seat-status seat0 anzeigen lassen:

seat0
         Devices:
                  ├─/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input6
                  │ input:input6 "Power Button"
                  ├─/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input5
                  │ input:input5 "Power Button"
[...]
                  ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/card0
                  │ [MASTER] drm:card0
                  │ ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/card0/card0-DP-1
                  │ │ [MASTER] drm:card0-DP-1
                  │ ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/card0/card0-DVI-D-1
                  │ │ [MASTER] drm:card0-DVI-D-1
                  │ └─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/card0/card0-HDMI-A-1
                  │   [MASTER] drm:card0-HDMI-A-1
                  ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/renderD128
                  │ drm:renderD128
                  ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/graphics/fb0
                  │ [MASTER] graphics:fb0 "amdgpudrmfb"
                  ├─/sys/devices/pci0000:00/0000:00:03.1/0000:08:00.1/sound/card0
[...]
                  ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1
                  │ [MASTER] drm:card1
                  │ ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1/card1-DP-2
                  │ │ [MASTER] drm:card1-DP-2
                  │ ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1/card1-DP-3
                  │ │ [MASTER] drm:card1-DP-3
                  │ ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1/card1-DVI-D-2
                  │ │ [MASTER] drm:card1-DVI-D-2
                  │ ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1/card1-HDMI-A-2
                  │ │ [MASTER] drm:card1-HDMI-A-2
                  │ └─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/card1/card1-HDMI-A-3
                  │   [MASTER] drm:card1-HDMI-A-3
                  ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/drm/renderD129
                  │ drm:renderD129
                  ├─/sys/devices/pci0000:00/0000:00:03.2/0000:09:00.0/graphics/fb1
                  │ [MASTER] graphics:fb1 "amdgpudrmfb"
[...]
                  ├─/sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5
                  │ usb:usb5
                  │ └─/sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5/5-2
                  │   usb:5-2
                  │   ├─/sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5/5-2/5-2.1/5-2.1:1.0/0003:0557:2213.0002/input/input1
                  │   │ input:input1 "ATEN Advance Tech Inc. KVM V1.2.116"
                  │   └─/sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5/5-2/5-2.1/5-2.1:1.1/0003:0557:2213.0004/input/input3
                  │     input:input3 "ATEN Advance Tech Inc. KVM V1.2.116"
                  └─/sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb6
                    usb:usb6
[...]

Man muss also nur die Geräte, die dem zweiten Arbeitsplatz gehören sollen, einem anderen Seat, z.B. “seat-anna”, zuteilen. Das sollte eine Grafikkarte (endet mit …/drm/cardN) sein:

loginctl attach seat-anna /sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0/drm/card0

Und Annas Tastatur und Maus:

loginctl attach seat-anna /sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5/5-2/5-2.1/5-2.1:1.0/0003:0557:2213.0002/input/input1
loginctl attach seat-anna /sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5/5-2/5-2.1/5-2.1:1.1/0003:0557:2213.0004/input/input3

Wenn man will kann man auch ganze USB-Hubs einem Benutzer zuteilen. Alles, was daran angeschlossen wird, gehört dann ausschließlich diesem Benutzer. Da Annas Eingabegeräte beide an “usb5” hängen würde statt der obigen zwei Befehle auch das hier funktionieren:

loginctl attach seat-anna /sys/devices/pci0000:00/0000:00:07.1/0000:0a:00.3/usb5

loginctl baut udev-Regeln und speichert diese unter “/etc/udev/rules.d/<irgendeineNummer>-seat-<device>.rules”. Der Name des Seats wird als Tag zu den Geräten hinzugefügt. Mit loginctl flush-devices könnte man sämtliche Zuordnungen wieder aufheben.

Display-Manager konfigurieren

Nach einigem Ausprobieren hat sich lightdm als der am besten geeignete Display Manager herausgestellt. Mit sddm, dem Standard-Display Manager von KDE/Plasma dagegen ging Multiseat dagegen gar nicht.

Bei lightdm müssen für jeden Seat lediglich ein paar Zeilen am Ende der “/etc/lightdm/lightdm.conf” hinzugefügt werden:

[Seat:seat0]
xserver-command=/usr/lib/xorg/Xorg

[Seat:seat-anna]
xserver-command=/usr/lib/xorg/Xorg
xserver-share=true

Laut “Quelle: Internet” sollte bei allen Seats außer “seat0” “xserver-share=true” stehen.

Damit ist das Gröbste erledigt, das Anmelden sollte jetzt an beiden Arbeitsplätzen gelingen.

Feinschliff

USB-Geräte

Damit angestöpselte USB-Geräte von allen Arbeitsplätzen aus verwendet werden können (sofern der angemeldete Benutzer Mitglied der Gruppe “plugdev” ist) folgende Datei anlegen:

“/etc/polkit-1/localauthority/50-local.d/20-org.freedesktop.udisks2.pkla”

[Storage Permissions]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks2.*;org.blueman.*;org.freedesktop.pulseaudio;org.gtk.vfs.file-operations
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Und damit von allen Arbeitsplätzen aus der Rechner heruntergefahren werden kann (sofern der angemeldete Benutzer Mitglied der Gruppe “powerdev” ist):

“/etc/polkit-1/localauthority/50-local.d/10-org.freedesktop.upower.pkla”

[Suspend/hibernate permissions]
Identity=unix-group:powerdev
Action=org.freedesktop.upower.*
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Bluetooth und Audio

Da abweichend vom Standard Pulseaudio als systemweite Instanz läuft und nicht jeweils eine für jeden angemeldeten Benutzer, müssen einige Kleinigkeiten angepasst werden damit Audio über Bluetooth funktioniert:

Der User “pulse” muss Mitglied der Gruppe “bluetooth” werden:

adduser pulse bluetooth

Dann “/etc/dbus-1/system.d/pulseaudio-system.conf” mit folgendem Inhalt anlegen:

<?xml version="1.0"?><!--*-nxml-*-->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<policy user="pulse">
 <allow own="org.pulseaudio.Server"/>
 <allow send_destination="org.pulseaudio.Server"/>
 <allow receive_sender="org.pulseaudio.Server"/>
 <allow send_destination="org.ofono"/>
</policy>

Anschließend Dbus seine Konfigurationsdateien mit systemctl reload dbus neu einlesen lassen.

Jetzt Pulseaudio das Nachladen von Modulen – in diesem Fall speziell das bluetooth-device-Modul, das für jedes Bluetooth-Gerät nachgeladen wird – erlauben:

Dafür in “/etc/pulse/daemon.conf” diese Zeile hinzufügen:

allow-module-loading = yes

Und in “/etc/pulse/system.pa” das hier hinzufügen um die Bluetooth-Basisunterstützung einzuschalten:

.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif

.ifexists module-bluez5-discover.so
load-module module-bluez5-discover
.endif

Andere Einträge in dieser Datei, die “bluez” oder “bluetooth” enthalten müssen entfernt werden.

Pulseaudio darf beim Systemstart erst nach Bluetooth/bluez gestartet werden. Dazu in “/etc/systemd/system/pulseaudio.service” die Zeile

After=dbus.service avahi-daemon.service network.target

erweitern zu:

After=dbus.service avahi-daemon.service network.target bluetooth.target

Anschließend Pulseaudio neu starten: systemctl daemon-reload; systemctl restart pulseaudio

Das war’s!

Updates:

Update 2019:

Alles funktioniert monatelang ganz wunderbar hervorragend – bis ich beschloss, eine zusätzliche PCIe-Karte in den Rechner einzubauen: Dadurch wurden die PCI-IDs zum Teil durcheinandergewirbelt die oben mit “loginctl attach” den Seats zugewiesenen wurden. Auch wenn es nervt: Einfach die Geräte wie oben beschrieben nochmal den Seats zuteilen, nach 10 Minuten läuft alles wieder wie gehabt.

Update 2020:

Ich verwende AMD-Grafikkarten. Seit Mitte 2019(?) müssen alle Bildschirme spätestens beim Start des Loginmanagers eingeschaltet sein, sonst bleibt der Bildschirm dauerhaft schwarz – bis man den Loginmanager oder X neu startet . Betroffen sind alle Bildschirme außer dem primären, also alle außer dem, auf dem beim Booten was angezeigt wird. Wenn jemand eine Lösung weiß: Her damit!

Update 2021:

Update auf Debian 11 durchgeführt: Keine Probleme, keine Nacharbeit erforderlich. Daher Titel dieses Beitrags angepasst.