This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
user:ryoung12:multiseat [2010/12/19 00:37] – ryoung12 | user:ryoung12:multiseat [2010/12/19 02:44] (current) – ryoung12 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | =====Multiseat Configuration on Ubuntu via USB===== | ||
+ | ====What is Multiseat? | ||
+ | <wrap indent> | ||
+ | ====Getting Started==== | ||
+ | <wrap indent> | ||
+ | <WRAP round tip> | ||
+ | To see what version of GDM your machine is running, you can use the following command: | ||
+ | <cli> | ||
+ | $ gdm -version | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <wrap indent> | ||
+ | <WRAP round important> | ||
+ | The remainder of this tutorial will be tailored to a fresh installation of Ubuntu 9.04 and having applied the latest updates using aptitude update and aptitude safe-upgrade. It is also assumed you are using GDM version 2.20. | ||
+ | </ | ||
+ | |||
+ | ====Configuring the DisplayLink Video Adapter==== | ||
+ | <wrap indent> | ||
+ | <WRAP round tip> | ||
+ | To install and prepare the Module Assistant and Git packages, you can use the following command: | ||
+ | <cli> | ||
+ | $ sudo aptitude update && aptitude install -y module-assistant git-core | ||
+ | $ sudo module-assistant prepare | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round info> | ||
+ | Using the following commands, download, compile, and install the udlfb driver. | ||
+ | <cli> | ||
+ | $ mkdir ~/git && cd ~/git | ||
+ | $ git clone http:// | ||
+ | $ cd udlfb | ||
+ | $ make && sudo make install && make clean | ||
+ | $ sudo depmod -a | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <wrap indent> | ||
+ | <WRAP round tip> | ||
+ | To install the PKG Config and Xorg Development packages, you can use the following command: | ||
+ | <cli> | ||
+ | $ sudo aptitude install pkg-config xorg-dev | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round info> | ||
+ | Using the following commands, download, configure, and install the DisplayLink X Server | ||
+ | <cli> | ||
+ | $ cd ~/git | ||
+ | $ git clone http:// | ||
+ | $ cd xf-video-udlfb | ||
+ | $ ./configure | ||
+ | $ make && sudo make install && make clean | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Downloading the Multiseat Config Files==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | To download the files, use the following command: | ||
+ | <cli> | ||
+ | $ cd ~/git | ||
+ | $ get clone http:// | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====The usbseat.rules udev script==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | Using the following commands, copy the file into the directory, and set the owner/group and permissions. | ||
+ | <cli> | ||
+ | $ cd / | ||
+ | $ sudo cp ~/ | ||
+ | $ sudo chown root 50-usbseat.rules && sudo chgrp root 50-usbseat.rules | ||
+ | $ sudo chmod 644 50-usbseat.rules | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the 50-usbseat.rules file at the time of writing. | ||
+ | <file bash 50-usbseat.rules> | ||
+ | # set all DisplayLink devices to configuration 1 | ||
+ | # see http:// | ||
+ | ATTR{idVendor}==" | ||
+ | |||
+ | # aliases for display, kbd, mouse attached to specific hubs | ||
+ | |||
+ | KERNEL==" | ||
+ | KERNEL==" | ||
+ | KERNEL==" | ||
+ | KERNEL==" | ||
+ | |||
+ | # and for when the keyboard and mouse are one more hub downstream. Relying on pnp order to have already set up mouse, keyboard on upstream hub if we're daisy-chaining | ||
+ | KERNEL==" | ||
+ | KERNEL==" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====The usbseat.sh shell script==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | Using the following commands, copy the file into the directory, and set the owner/group and permissions. | ||
+ | <cli> | ||
+ | $ cd /lib/udev/ | ||
+ | $ sudo cp ~/ | ||
+ | $ sudo chown root usbseat.sh && sudo chgrp root usbseat.sh | ||
+ | $ sudo chmod 755 usbseat.sh | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the usbseat.sh file at the time of writing. | ||
+ | <file bash usbseat.sh> | ||
+ | #!/bin/bash | ||
+ | # takes the "seat number" | ||
+ | # the seat number is the kernel device id of the hub the seat's devices are sitting off of | ||
+ | # called once for every usb device that MIGHT be part of a seat, when they arrive or remove | ||
+ | |||
+ | if [[ !(-n `/bin/pidof gdm`) ]]; then | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | seat_running=`/ | ||
+ | |||
+ | # $ACTION environment variable is set by udev subsystem | ||
+ | case " | ||
+ | ' | ||
+ | if [[ -n " | ||
+ | / | ||
+ | fi | ||
+ | ;; | ||
+ | *) | ||
+ | # A device which might be part of a seat has been added | ||
+ | |||
+ | # if we already have a running seat for this #, exit | ||
+ | if [[ -n " | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | if [[ -e / | ||
+ | |||
+ | # We have a newly complete seat. Start it. | ||
+ | TMPFILE=`/ | ||
+ | /bin/sed " | ||
+ | / | ||
+ | #/ | ||
+ | # / | ||
+ | |||
+ | / | ||
+ | fi | ||
+ | ;; | ||
+ | esac | ||
+ | |||
+ | exit 0 | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Xorg Configuration File==== | ||
+ | <warp indent> | ||
+ | <WRAP round info> | ||
+ | Using the following commands, copy the file into the directory, and set the owner/group and permissions. | ||
+ | <cli> | ||
+ | $ cd /lib/udev/ | ||
+ | $ sudo cp ~/ | ||
+ | $ sudo chown root usbseat-xf86.conf.sed && sudo chgrp root usbseat-xf86.conf.sed | ||
+ | $ sudo chmod 644 usbseat-xf86.conf.sed | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the usbseat-xf86.conf.sed file at the time of writing. | ||
+ | <file xorg_conf usbseat-xf86.conf.sed> | ||
+ | Section " | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Load " | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | ModulePath | ||
+ | ModulePath | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | Driver | ||
+ | # | ||
+ | Option " | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | Driver | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | # Suggested options for removing keyboard input quirks | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | Driver | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | Option | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | Device " | ||
+ | Monitor " | ||
+ | EndSection | ||
+ | |||
+ | Section " | ||
+ | Identifier " | ||
+ | Screen | ||
+ | InputDevice " | ||
+ | InputDevice " | ||
+ | EndSection | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Modifying the User Run Level Scripts==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | Open / | ||
+ | <code bash> | ||
+ | oldIFS=$IFS | ||
+ | IFS=/ | ||
+ | for seat in / | ||
+ | set $seat | ||
+ | / | ||
+ | done | ||
+ | IFS=$oldIFS | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the a sample of the rc.local file, after inserting the above referenced lines of code. | ||
+ | <file bash rc.local> | ||
+ | #!/bin/sh -e | ||
+ | # | ||
+ | # rc.local | ||
+ | # | ||
+ | # This script is executed at the end of each multiuser runlevel. | ||
+ | # Make sure that the script will "exit 0" on success or any other | ||
+ | # value on error. | ||
+ | # | ||
+ | # In order to enable or disable this script just change the execution | ||
+ | # bits. | ||
+ | # | ||
+ | # By default this script does nothing. | ||
+ | oldIFS=$IFS | ||
+ | IFS=/ | ||
+ | for seat in / | ||
+ | set $seat | ||
+ | / | ||
+ | done | ||
+ | IFS=$oldIFS | ||
+ | |||
+ | exit 0 | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Patching the GDM==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | Open up / | ||
+ | <code bash> | ||
+ | # Allow usbseat to override the config | ||
+ | if [ -f / | ||
+ | for usbseat in / | ||
+ | seatid=${usbseat## | ||
+ | if [ -e "/ | ||
+ | CONFIG_FILE=" | ||
+ | fi | ||
+ | done | ||
+ | fi | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is a sample / | ||
+ | <file bash gdm> | ||
+ | #! /bin/sh | ||
+ | # | ||
+ | # Originally based on: | ||
+ | # Version: | ||
+ | # | ||
+ | # Modified for gdm, Steve Haslam < | ||
+ | # modified to remove --exec, as it does not work on upgrades. 18jan2000 | ||
+ | # modified to use --name, to detect stale PID files 18mar2000 | ||
+ | # sleep until gdm dies, then restart it 16jul2000 | ||
+ | # get along with other display managers (Branden Robinson, Ryan Murray) 05sep2001 | ||
+ | |||
+ | set -e | ||
+ | |||
+ | # To start gdm even if it is not the default display manager, change | ||
+ | # HEED_DEFAULT_DISPLAY_MANAGER to " | ||
+ | HEED_DEFAULT_DISPLAY_MANAGER=true | ||
+ | DEFAULT_DISPLAY_MANAGER_FILE=/ | ||
+ | PATH=/ | ||
+ | DAEMON=/ | ||
+ | PIDFILE=/ | ||
+ | UPGRADEFILE=/ | ||
+ | |||
+ | if [ -e $UPGRADEFILE -a " | ||
+ | SSD_ARG=" | ||
+ | rm -f $UPGRADEFILE | ||
+ | else | ||
+ | SSD_ARG=" | ||
+ | fi | ||
+ | |||
+ | # Allow cdd to override the config | ||
+ | if [ -f / | ||
+ | CONFIG_FILE=" | ||
+ | fi | ||
+ | |||
+ | # Allow usbseat to override the config | ||
+ | if [ -f / | ||
+ | for usbseat in / | ||
+ | seatid=${usbseat## | ||
+ | if [ -e "/ | ||
+ | CONFIG_FILE=" | ||
+ | fi | ||
+ | done | ||
+ | fi | ||
+ | |||
+ | test -x $DAEMON || exit 0 | ||
+ | |||
+ | if [ -r / | ||
+ | . / | ||
+ | export LANG LANGUAGE | ||
+ | elif [ -r / | ||
+ | . / | ||
+ | export LANG LANGUAGE | ||
+ | fi | ||
+ | |||
+ | . / | ||
+ | |||
+ | case " | ||
+ | start) | ||
+ | if grep -wqs text / | ||
+ | log_warning_msg "Not starting GNOME Display Manager (gdm); found ' | ||
+ | elif [ -e " | ||
+ | log_warning_msg "Not starting GNOME Display Manager (gdm); it is not the default display manager." | ||
+ | else | ||
+ | if [ -z " | ||
+ | log_begin_msg " | ||
+ | fi | ||
+ | # if usplash is running, make sure to stop it now, yes " | ||
+ | if [ " | ||
+ | # usplash was already shut down earlier, so don't | ||
+ | # log success as it will look weird on the console. | ||
+ | log_end_msg=: | ||
+ | elif pidof usplash > /dev/null; then | ||
+ | SPLASH_ORIG_CONSOLE=" | ||
+ | DO_NOT_SWITCH_VT=yes / | ||
+ | # We've just shut down usplash, so don't log | ||
+ | # success as it will look weird on the console. | ||
+ | log_end_msg=: | ||
+ | else | ||
+ | log_end_msg=log_end_msg | ||
+ | fi | ||
+ | start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --name gdm $SSD_ARG -- $CONFIG_FILE >/ | ||
+ | $log_end_msg 0 | ||
+ | |||
+ | if [ " | ||
+ | [ " | ||
+ | # Wait a short while for the active console to | ||
+ | # change, to try to avoid visible console noise from | ||
+ | # later init scripts. | ||
+ | i=0 | ||
+ | while [ " | ||
+ | i=" | ||
+ | if [ " | ||
+ | break | ||
+ | fi | ||
+ | sleep 0.1 | ||
+ | done | ||
+ | fi | ||
+ | fi | ||
+ | ;; | ||
+ | stop) | ||
+ | log_begin_msg " | ||
+ | start-stop-daemon --stop | ||
+ | log_end_msg 0 | ||
+ | ;; | ||
+ | reload) | ||
+ | log_begin_msg " | ||
+ | log_warning_msg " | ||
+ | start-stop-daemon --stop --signal USR1 --quiet --pidfile \ | ||
+ | $PIDFILE --name gdm $SSD_ARG >/ | ||
+ | log_end_msg 0 | ||
+ | ;; | ||
+ | restart|force-reload) | ||
+ | $0 stop || true | ||
+ | $0 start | ||
+ | ;; | ||
+ | status) | ||
+ | status_of_proc -p " | ||
+ | ;; | ||
+ | *) | ||
+ | log_success_msg " | ||
+ | exit 1 | ||
+ | ;; | ||
+ | esac | ||
+ | |||
+ | exit 0 | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Creating the GDM Configuration File==== | ||
+ | <wrap indent> | ||
+ | Using the following commands, copy the file into the directory, and set the owner/group and permissions. | ||
+ | <WRAP round info> | ||
+ | <cli> | ||
+ | $ cd /lib/udev/ | ||
+ | $ sudo cp ~/ | ||
+ | $ sudo chown root usbseat-xf86.conf.sed && sudo chgrp root usbseat-xf86.conf.sed | ||
+ | $ sudo chmod 644 usbseat-xf86.conf.sed | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the gdm-usbseat.conf file at the time of writing. | ||
+ | <file bash gdm-usbseat.conf> | ||
+ | [daemon] | ||
+ | DynamicXServers=true | ||
+ | FlexibleXServers=0 | ||
+ | Greeter=/ | ||
+ | |||
+ | [security] | ||
+ | |||
+ | [xdmcp] | ||
+ | |||
+ | [gui] | ||
+ | |||
+ | [greeter] | ||
+ | |||
+ | [chooser] | ||
+ | |||
+ | [debug] | ||
+ | |||
+ | [servers] | ||
+ | 0=inactive | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Enabling Multiseat Audio==== | ||
+ | <wrap indent> | ||
+ | <WRAP round info> | ||
+ | Using the following commands, copy the file into the directory, and set the owner/group and permissions. | ||
+ | <cli> | ||
+ | $ cd / | ||
+ | $ sudo cp ~/ | ||
+ | $ sudo chown root 50usbseat && sudo chgrp root 50usbseat | ||
+ | $ sudo chmod 644 50usbseat | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP round download> | ||
+ | Below is the 50usbseat file at the time of writing. | ||
+ | <file bash 50usbseat> | ||
+ | oldIFS=$IFS | ||
+ | IFS=: | ||
+ | set $DISPLAY | ||
+ | IFS=. | ||
+ | set $2 | ||
+ | SEAT_ID=$1 | ||
+ | LN=`ls -al / | ||
+ | IFS=C | ||
+ | set $LN | ||
+ | CARD_ID=$2 | ||
+ | export ALSA_CARD=$2 | ||
+ | export ALSA_PCM_CARD=$2 | ||
+ | IFS=$oldIFS | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====Finishing Up==== | ||
+ | <wrap indent> | ||
+ | |||
+ | =====Known Problems===== | ||
+ | ====Zombie User Sessions==== | ||
+ | <WRAP round warning> | ||
+ | <wrap indent> | ||
+ | \\ \\ | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | ====Input Duplication==== | ||
+ | <WRAP round important> | ||
+ | <wrap indent> | ||
+ | </ | ||
+ | |||
+ | ====Flash Drives==== | ||
+ | <WRAP round important> | ||
+ | <wrap indent> | ||
+ | </ |