NVidia multiseat
From Multiseat
| Languages: |
English |
Contents |
Introduction
There are three drivers for nVidia hardware. Two are opensource: nv and nouveau, and one is proprietary, closed source: nvidia driver. Currently, the nvidia driver provides more functionality than the open source drivers.
nv is part of the standard xorg distribution. nouveau is still highly experimental and is available only in bleeding edge packages for a few distributions or git.
My goal is to get multi-seat running on top of the binary closed source driver. This page is my documentation in progress for this effort.
Who needs this page?
If you are using single-head cards then you really don't need this page at all. Follow the regular mdm installation instructions. Install the nvidia driver as you would normally. Hand-edit /etc/mdm/xorg.conf.mdm to replace
driver "nv"
with
driver "nvidia"
and you should be all set.
You only need this page if you have multi-head nvidia based cards. CAVEAT: I've only tried this my own nVidia Quadro 285 based cards. I expect any hardware that uses the binary blob driver from nVidia would work the same.
Configuring Xorg
I am running Debian Lenny, which is about to go into stable. Since Xephyr has seen a lot of changes, and I really want to use Xephyr 1.5, I am running xorg from experimental.
sudo echo deb http://ftp.debian.org/debian/ experimental main contrib non-free >> /etc/apt/sources.list sudo apt-get update sudo apt-get upgrade sudo apt-get -t experimental install xserver-xorg xserver-xorg-core
This should install a whole bunch of xorg packages. You also probably want to clean up any unused packages:
sudo apt-get autoremove
This may well hose your system. Please make sure you know how to recover if the packages trash something on your system.
Configuring xorg.conf.mdm
First, install the appropriate nVidia driver for your hardware, distro, and kernel. There are plenty of HOWTOs and other documentation on this. I will assume you have a working nVidia Xsession to start with, with GLX support, on one head.
nVidia provides a utility, nvidia-settings, that will build an appropriate xorg.conf file for multihead. This will not work from inside a Xephyr session.
First, back up your /etc/X11/xorg.conf. Then start X and nvidia-settings. Configure all your hardware for the monitors you have attached. Make sure you select 'Separate X sessions'. When you save the file, de-select the 'Merge xorg.conf' option. You want the new file with nothing carried over from the old file.
NOTE: nvidia-settings will ignore any cards or outputs that don't have monitors attached.
WARNING: This will wipe out your existing xorg.conf file. This is why you need to back it!
Restart X to make sure all your screens come up. You will have a single login, and depending on your window manager, your menus and panels may be spread all over the screens.
Now copy /etc/X11/xorg.conf to /etc/mdm/xorg.conf.mdm.
Make sure you set RECREATE_XORG_CONF='no' in the /etc/mdm/mdm.conf
Shut down your X session, make sure [kgx]dm is stopped, and start mdm.
You should see a login screen on each attached head.
My system has three video cards:
01:00.0 VGA compatible controller: nVidia Corporation NV44 [Quadro NVS 285] (rev a1) 04:00.0 VGA compatible controller: nVidia Corporation NV34GL [Quadro NVS 280 PCI] (rev a1) 04:02.0 VGA compatible controller: nVidia Corporation NV34GL [Quadro NVS 280 PCI] (rev a1)
The Quadro 285 is a dual head card; the others are single head. I can connect a total of 4 monitors to this system.
My xorg.conf.mdm file:
# nvidia-settings: X configuration file generated by nvidia-settings
# nvidia-settings: version 1.0 (buildmeister@builder58) Thu Jul 17 18:39:42 PDT 2008
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
Screen 1 "Screen1" RightOf "Screen0"
Screen 2 "Screen2" RightOf "Screen1"
Screen 3 "Screen3" RightOf "Screen2"
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
EndSection
Section "Files"
# RgbPath "/usr/X11R6/lib/X11/rgb"
EndSection
Section "Module"
Load "dbe"
Load "extmod"
Load "type1"
Load "freetype"
Load "glx"
EndSection
Section "ServerFlags"
Option "Xinerama" "0"
EndSection
Section "InputDevice"
# generated from default
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/psaux"
Option "Emulate3Buttons" "no"
Option "ZAxisMapping" "4 5"
EndSection
Section "InputDevice"
# generated from default
Identifier "Keyboard0"
Driver "kbd"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor0"
VendorName "Unknown"
ModelName "ViewSonic"
HorizSync 31.5 - 64.0
VertRefresh 60.0 - 75.0
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor1"
VendorName "Unknown"
ModelName "Optiquest"
HorizSync 31.5 - 93.8
VertRefresh 56.0 - 85.0
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor2"
VendorName "Unknown"
ModelName "PNR PX212M"
HorizSync 31.0 - 92.0
VertRefresh 56.0 - 86.0
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor3"
VendorName "Unknown"
ModelName "PNR PX212M"
HorizSync 31.0 - 92.0
VertRefresh 56.0 - 86.0
Option "DPMS"
EndSection
Section "Device"
Identifier "Videocard0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:1:0:0"
Screen 0
EndSection
Section "Device"
Identifier "Videocard1"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:1:0:0"
Screen 1
EndSection
Section "Device"
Identifier "Videocard2"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 55/280 PCI"
BusID "PCI:4:0:0"
EndSection
Section "Device"
Identifier "Videocard3"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 55/280 PCI"
BusID "PCI:4:2:0"
EndSection
Section "Screen"
Identifier "Screen0"
Device "Videocard0"
Monitor "Monitor0"
DefaultDepth 24
Option "TwinView" "0"
Option "TwinViewXineramaInfoOrder" "CRT-0"
Option "metamodes" "CRT-0: 1024x768 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Screen"
Identifier "Screen1"
Device "Videocard1"
Monitor "Monitor1"
DefaultDepth 24
Option "TwinView" "0"
Option "metamodes" "CRT-1: 1152x864 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Screen"
Identifier "Screen2"
Device "Videocard2"
Monitor "Monitor2"
DefaultDepth 24
Option "TwinView" "0"
Option "metamodes" "1024x768 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Screen"
Identifier "Screen3"
Device "Videocard3"
Monitor "Monitor3"
DefaultDepth 24
Option "TwinView" "0"
Option "metamodes" "1024x768 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Here's a more sophisticated xorg.conf file, showing how to override the nvidia auto-detection for resolution. This computer has 2 dual-head Quadro 285 cards.
# nvidia-settings: X configuration file generated by nvidia-settings
# nvidia-settings: version 1.0 (buildmeister@builder62) Mon Aug 11 12:30:09 PDT 2008
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
Screen 1 "Screen1" RightOf "Screen0"
Screen 2 "Screen2" RightOf "Screen1"
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
EndSection
Section "Files"
EndSection
Section "Module"
Load "dbe"
Load "extmod"
Load "type1"
Load "freetype"
Load "glx"
EndSection
Section "ServerFlags"
Option "Xinerama" "0"
EndSection
Section "InputDevice"
# generated from default
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/psaux"
Option "Emulate3Buttons" "no"
Option "ZAxisMapping" "4 5"
EndSection
Section "InputDevice"
# generated from default
Identifier "Keyboard0"
Driver "kbd"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor0"
VendorName "Unknown"
ModelName "Niko-1906R"
HorizSync 30.0 - 83.0
VertRefresh 50.0 - 76.0
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor1"
VendorName "Unknown"
ModelName "PNR PX212M"
HorizSync 31.0 - 92.0
VertRefresh 56.0 - 72.0
Modeline "1280x1024@60" 108 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
Modeline "1024x768@75" 78.75 1024 1040 1136 1312 768 769 772 800 +hsync +vsync
Modeline "1024x768@70" 75.00 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
Modeline "1024x768@60" 65.00 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor2"
VendorName "Unknown"
ModelName "HSD CY199"
HorizSync 24.0 - 80.0
VertRefresh 56.0 - 75.0
Option "DPMS"
EndSection
Section "Monitor"
# HorizSync source: edid, VertRefresh source: edid
Identifier "Monitor3"
VendorName "Unknown"
ModelName "Sharp 37U"
HorizSync 31.0 - 92.0
VertRefresh 56.0 - 72.0
ModeLine "1368x720@60" 79.7 1264 1416 1456 1752 688 722 724 758
Option "DPMS"
EndSection
Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:2:0:0"
Screen 0
EndSection
Section "Device"
Identifier "Device1"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:2:0:0"
Screen 1
EndSection
Section "Device"
Identifier "Device2"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:6:0:0"
Screen 0
EndSection
Section "Device"
Identifier "Device3"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro NVS 285"
BusID "PCI:6:0:0"
Screen 1
EndSection
Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
Option "TwinView" "0"
Option "metamodes" "DFP-1: nvidia-auto-select +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Screen"
Identifier "Screen1"
Device "Device1"
Monitor "Monitor1"
DefaultDepth 24
Option "TwinView" "0"
Option "IgnoreEDID" "True"
Option "ExactModeTimingsDVI" "True"
Option "ModeValidation" "NoDFPNativeResolutionCheck"
Option "metamodes" "DFP-0: 1024x768@60 +0+0"
SubSection "Display"
Depth 24
Modes "1024x768@60"
EndSubSection
EndSection
Section "Screen"
Identifier "Screen2"
Device "Device2"
Monitor "Monitor2"
DefaultDepth 24
Option "TwinView" "0"
Option "metamodes" "nvidia-auto-select +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Screen"
Identifier "Screen3"
Device "Device3"
Monitor "Monitor3"
DefaultDepth 24
Option "TwinView" "0"
Option "IgnoreEDID" "True"
Option "ExactModeTimingsDVI" "True"
Option "ModeValidation" "NoDFPNativeResolutionCheck"
Option "metamodes" "DFP-0: 1368x720@60 +0+0"
SubSection "Display"
Depth 24
Modes "1368x720@60"
EndSubSection
EndSection
Patching mdm scripts for nvidia compatibility
From what I understand the nvidia driver doesn't support randr 1.2, so mdm's autodetection of heads doesn't work. Instead, the nvidia driver creates 'virutal' video cards, one for each head. These cards are created when X is started, so mdm's discover-devices script fails to detect them. In order to correctly detect all monitors on all heads, you will need to patch discover-devices, mdm-start-seat, mdm-bin, and create a small utility, nvidia-discover-screens, in /usr/local/bin/.
Don't expect these patches to make it into mainline. The nvidia binary drivers are not supported by Xorg, and making changes to accommodate one closed source vendor is not in the best interest of mdm's developers.
Patch for discover-devices:
diff --git a/mdm/src/discover-devices b/mdm/src/discover-devices
index 2309cc7..fd4a94e 100755
--- a/mdm/src/discover-devices
+++ b/mdm/src/discover-devices
@@ -47,7 +47,6 @@ function discover_input () {
# Prints bus address and drivers of the video cards.
function video_cards () {
-
# calling discover is way toooooo slow!
OUTPUT=$($DISCOVER -t display --vendor-id --model-id)
VENDOR_IDS=($(echo "$OUTPUT" | cut -d' ' -f1))
@@ -55,6 +54,7 @@ function video_cards () {
# There can be empty lines on "drivers"
DRIVERS=($($DISCOVER -t display --data-path=xfree86/server/device/driver \
| sed 's/^$/vesa/g'))
+ NVIDIA=0
for (( i = 0; i < ${#VENDOR_IDS[@]}; i++)); do
# If there are multiple cards with the same IDs, lspci will print
@@ -71,8 +71,12 @@ function video_cards () {
BUS_IDS[i]=$(lspci -d ${VENDOR_IDS[i]}:${MODEL_IDS[i]} |
cut -d' ' -f1 | head -n $((TIMES_USED+1)) | tail -n 1)
+
+ ADRIVER=`lspci -n -k -s ${BUS_IDS[i]} | grep driver | sed 's/^.*: //'`
+ if [[ -n $ADRIVER && $ADRIVER == "nvidia" ]] ; then NVIDIA=1 ; fi
done
+
for (( i=0 ; i < ${#BUS_IDS[@]}; i++ )) ; do
# busid from lspci is in format 00:00.00
# below we split in 00 and 00.00
@@ -83,12 +87,14 @@ function video_cards () {
awk 'BEGIN {FS="."}{print toupper($1), toupper($2)}'`)
# now, we convert the numbers from hexa to decimal base
echo -e "bus\t`echo "obase=10;ibase=16;${NUMS[0]};${SEC_NUMS[0]};${SEC_NUMS[1]};" | bc | paste -s -d":"`"
-
- done
-
- for i in ${DRIVERS[@]}; do
- echo -e "driver\t$i"
done
+ if [[ $NVIDIA == 1 ]] ; then
+ /usr/local/bin/nvidia-discover-screens drivers
+ else
+ for i in ${DRIVERS[@]}; do
+ echo -e "driver\t$i"
+ done
+ fi
} # video_cards
# ******************** MAIN *************************
Patch for mdm-bin
diff --git a/mdm/src/mdm-bin b/mdm/src/mdm-bin
index 79c88c9..2a8d514 100755
--- a/mdm/src/mdm-bin
+++ b/mdm/src/mdm-bin
@@ -86,6 +86,14 @@ function exec_start() {
else
display_manager_start_underneath_xserver >> $MY_LOG 2>&1
+ log --log-file-only "re-detecting cards"
+ VIDEO_CARDS=`$DISCOVER_DEVICES driver | wc -l`
+ log --log-file-only "$VIDEO_CARDS video cards detected"
+ # find out how many seats we actually have
+ OUTPUTS_PER_CARD=$(grep "SCREEN_AMOUNT" $XRANDR_INFO_FILE | cut -d'=' -f2)
+ SEATS=$(echo $OUTPUTS_PER_CARD | sed 's/\s/+/g' | bc)
+ log --log-file-only "$SEATS seats detected"
+
for ((i=0; i < $VIDEO_CARDS; i++)); do
export DISPLAY=:0.$i
xrandr_configure_layout
mdm-start-seat
diff --git a/mdm/src/mdm-start-seat b/mdm/src/mdm-start-seat
index e7a9f1b..6edc31a 100755
--- a/mdm/src/mdm-start-seat
+++ b/mdm/src/mdm-start-seat
@@ -89,7 +89,7 @@ function parse_config_file () {
else
MY_XKB_LAYOUT=$DEFAULT_XKB_LAYOUT
fi
- if [ ! -z ${MODE[SEAT_NUMBER]} ]; then
+ if [[ -n ${MODE[SEAT_DISPLAY]} ]]; then
MY_SCREEN_SIZE=${MODE[VIDEO_CARD_NUMBER]}
else
MY_SCREEN_SIZE=$DEFAULT_MODE
@@ -97,7 +97,7 @@ function parse_config_file () {
}
function select_keyboard () {
- if [ -e "${MDM_DEVICES}/keyboard${SEAT_DISPLAY}" ]; then
+ if [[ -e "${MDM_DEVICES}/keyboard${SEAT_DISPLAY}" ]]; then
return
fi
Discovering nvidia screens
The helper script, nvidia-discover-devices, creates the xrandr.info file and also returns the number of virtual video cards. To use this script, first put it in /usr/local/bin. At this point, it helps to be working with a laptop that lets you ssh into the multiterminal machine.
ssh into your target machine and kill gdm and all running X sessions. Then start X using the xorg.conf from /etc/mdm:
athena:~# X -config /etc/mdm/xorg.conf.mdm
You will get a mottled gray screen on all your displays. Now run nvidia-discover-screens. You should get a xrandr.info file. Once you've verified it, you can place it into /etc/mdm:
athena:~# nvidia-discover-screens > /etc/mdm/xrandr.info
Kill X and start mdm; you should be all set.
athena:~# killall X athena:~# /etc/init.d/mdm start
#!/bin/sh #Xrandr info file generated on: Sat Sep 20 07:58:12 PDT 2008 #DISPLAY=:0.0 #SCREEN_AMOUNT=1 #OUTPUT_NAMES=default #SCREEN_SIZES=1024x768 #SCREEN_X_ORIGIN=0 #------------ end ------------ XAUTHORITY=/var/lib/gdm/:0.Xauth export XAUTHORITY SCREENS=`nvidia-settings --display :0 --ctrl-display :0 -query screens | grep '[.*]' | sed -e 's/(.*)//g' -e 's/\[.*\]//g' -e 's/.*://g'` #echo $SCREENS if [ $1 == 'drivers' ] ; then for screen in $SCREENS ; do echo driver nvidia done else echo Xrandr info file generated on: `date` for screen in $SCREENS; do RES=`nvidia-settings --ctrl-display :$screen -query FrontendResolution | grep Attribute | sed -e 's/^.*): //' -e 's/\.//' -e 's/,/x/'` echo echo DISPLAY=$screen echo SCREEN_AMOUNT=1 echo OUTPUT_NAMES=default echo SCREEN_SIZES=$RES echo SCREEN_X_ORIGIN=0 echo ------------ end ------------ done fi
Problems, issues, and troubleshooting
Black or gray screen on boot
I've had a problem with cold booting the system. The screens will come up either black or with the default X mottley gray background.
If you experience problems with black or gray screens on boot, try adding a longer delay to xephyr-gdm.
athena:~# vi /usr/share/mdm/modes/xephyr-gdm
and find the display_manager_start_underneath_xserver function near the top. The script ships with a delay of 5 seconds. On my system changing the
sleep 5
to
sleep 15
appears to have solved the black screen problem.
function display_manager_start_underneath_xserver () {
# In case we're using nested xservers (like Xephyr), we'll need to start an
# xserver to run the nested servers on top of it
# Don't put login screen on this server!
# We assume $DISPLAY is already set here.
$GDMDYNAMIC -a 0=XNotHandled
$GDMDYNAMIC -r 0
# XXX: find a better way to wait for X to start
sleep 15;
}
Xephyr starts with no devices
If the xephyrs start but keyboard and mouse don't respond, check to see if ps shows Xephyr starting with no mouse and keyboard device specified.
athena:~# ps auxwww | grep Xephyr
Xephyr :1 -br :1 -parent 0x200003 -mouse evdev,,device= -keybd evdev,,device=,xkbmodel=evdev,xkblayout=us -auth /var/lib/gdm/:1.Xauth -nolisten tcp vt9
Note the device= entries. Make sure that /etc/mdm/mdm.conf is configured to reconfigure input:
# Reconfigure the input devices every time (re-creating the links) # Values: 'yes', 'no'. RECONFIGURE_INPUT='yes'
This should be fixed in future releases.
mdm appears to start but nothing happens
You issue a
/etc/init.d/mdm start
command and the system comes back to a command prompt but X doesn't start up.
While there may be lots of reasons for this, I found that in my case, this is apparently due to the nVidia hardware not being included in /usr/share/xserver-xorg/pci.
This is fixed in the latest discover-devices script. Update from git and use that script.

