lunes, 22 de junio de 2009

Multiterminal en Ubuntu 9.04

El concepto de multiterminal es una particular configuración de un equipo informático de tal modo que permite que el equipo pueda ser utilizado por más de una persona simultáneamente. Dado que el hardware actual tiene sobrada potencia para los requerimientos que pueda exigir la gestión de múltiples escritorios, esta configuración es especialmente interesante en entornos de tipo de trabajo de oficina. La principal ventaja: el ahorro, no sólo en energía sino también en costes de mantenimiento.

Hasta hace algún tiempo, este tipo de configuraciones no eran sencillas y requerían modificar, recompilar o parchear diferentes partes del sistema. En las versiones más recientes, el kernel de Linux ya incluye lo necesario para poder tratar por separado los eventos provenientes p.ej. de diferentes teclados. De esta manera, actualmente se puede conseguir una configuración multiterminal simplemente instalando algún paquete adicional y modificando algún fichero de configuración.

En anteriores ocasiones he preparado tutoriales para configuraciones multiterminal en Ubuntu 6.06 y 8.04, pero esta es la primera ocasión en que publico el tutorial también en castellano.

La configuración es muy similar a la de la versión 8.04, con la diferencia de que algunos componentes de software han sido actualizados consiguiendo así alguna mejora con respecto a versiones anteriores. No obstante, continúa habiendo algunos problemas.





El equipo es el mismo que se utilizó en la anterior versión:
Pentium 4 a 3GHz, con 512MB de RAM y un disco duro de 80GB. La tarjeta de video es una ATI Radeon X300 PCIe de Gigabyte con dos salidas (VGA y DVI). En la salida DVI se utiliza un adaptador VGA de modo que finalmente tenemos dos monitores VGA analógicos en el sistema. Los monitores son pantallas convencionales LCD/TFT con una resolución de 1280x1024.

1.- En primer lugar, instalamos Ubuntu 9.04 en el ordenador. Lo hacemos utilizando un sistema "live" (CD/DVD o USB). Dado que actualmente la mayor parte de los equipos soportan arranque desde USB, recomedamos hacerlo con un USB-live, dado que el proceso de instalación será mucho más rápido que si lo hacemos desde un CD o DVD.

2.- A continuación, actualizamos el sistema para tener los últimos paquetes disponibles. Lo podemos hacer o bien con las herramientas gráficas (Gestor de Actualizaciones / Synaptic) o bien utilizando la línea de comandos desde un terminal:


$ sudo apt-get update


3.- Posteriormente, instalamos unos paquetes adicionales (xserver-xephyr y wmctrl). Estos paquetes no vienen incluidos en la instalación por defecto, pero podemos encontrarlos en los repositorios oficiales, de modo que su instalación es muy sencilla. Dichos paquetes son necesarios para conseguir obtener la configuración multiterminal que estamos buscando.


$ sudo apt-get install xserver-xephyr wmctrl


Antes de comenzar con las modificaciones particulares de la configuración multiterminal, es recomendable hacer los ajustes y configuración necesarios para el escenario de trabajo particular de cada usuario (configuración de red, creación de usuarios, etc). Algunas herramientas y utilidades de Gnome no funcionan al trabajar con múltiples sesiones simultáneas. Al detectar el sistema operativo múltiples sesiones, no es posible generar los necesarios ficheros de bloqueo requeridos por las herramientas de configuración.

Es muy recomendable conservar una copia de los ficheros de configuración en su estado inicial (/etc/X11/xorg.conf y /etc/gdm/gdm.conf). Estos ficheros serán necesarios si el usuario desea volver a la configuración inicial (monousuario) del equipo.

Una vez realizadas estas tareas previas de configuración inicial, procedemos a realizar la configuración específica del equipo multiterminal.



Inicialmente, tras la configuración por defecto, el sistema se inicia con las dos pantallas en modo "clon". si examinamos la salida del comando xrandr podremos ver los detalles de nuestra actual configuración. En nuestro caso particular, obtenemos lo siguiente:


$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1200
VGA-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 60.0
832x624 74.6
800x600 75.0 60.3
640x480 75.0 59.9
720x400 70.1
DVI-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 70.1 60.0
832x624 74.6
800x600 72.2 75.0 60.3
640x480 75.0 72.8 59.9
720x400 70.1
S-video disconnected (normal left inverted right x axis y axis)


El siguiente paso es modificar /etc/X11/xorg.conf para indicar cómo obtener un "escritorio extendido". En caso de tener dudas sobre este tema, en el wiki de ubuntu se puede encontrar información adicional para configurar y definir manualmente sistemas multipantalla.

En las últimas versiones de Linux, algunos aspectos relacionados con la gestión de dispositivos están siendo modificados y se gestionan desde diferentes partes del sistema, como hal y udev. Vemos que ya no es necesario indicar nada relacionado con ratón y teclado en el fichero xorg.conf

Tras haber hecho nuestra copia del fichero xorg.conf inical, lo modificamos para describir nuestra configuración con dos monitores. Incluimos también algunas opciones convenientes (las indicadas en la sección "ServerFlags") para un sistema multiterminal.


Section "Device"
Identifier "Card0"
BoardName "ATI Technologies Inc RV370 5B60 [Radeon X300 (PCIE)]"
Driver "ati"
BusID "PCI:1:0:0"
Option "Monitor-VGA-0" "Mon-VGA"
Option "Monitor-DVI-0" "Mon-DVI"
EndSection

Section "Monitor"
Identifier "Mon-VGA"
Option "DPMS"
EndSection

Section "Monitor"
Identifier "Mon-DVI"
Option "DPMS"
Option "Below" "Mon-VGA"
EndSection

Section "Screen"
Identifier "Screen-base"
Device "Card0"
Monitor "Mon-VGA"
DefaultDepth 24
Subsection "Display"
Depth 24
Modes "1280x1024"
Virtual 1280 2048
EndSubSection
EndSection

Section "ServerFlags"
# Even if mouse detection fails, X will start
Option "AllowMouseOpenFail" "yes"

# VT switching is disabled
Option "DontVTSwitch" "yes"

# X restart (Ctrl+Alt+Backspace) is disabled
Option "DontZap" "yes"
EndSection


En esta ocasión hemos elegido una distribución vertical de los monitores. Ha sido únicamente como prueba para ver si la aceleración 3D funciona al mantener las dimensiones de la pantalla virtual menores (o iguales) que un cuadrado de 2048 pixels de lado. Si el usuario prefiere una distribución horizontal, basta con utilizar leftOf o rightOf en lugar de below, en la sección correspondiente al segundo monitor. Además, se deberá de ajustar el tamaño del escritorio virtual al requerido en función de la distribución deseada.

Tras haber hecho estos cambios, si reiniciamos el servidor X veremos un escritorio ocupando los dos monitores en vertical y con estas características:


$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 2048, maximum 1280 x 2048
VGA-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 60.0
832x624 74.6
800x600 75.0 60.3
640x480 75.0 59.9
720x400 70.1
DVI-0 connected 1280x1024+0+1024 (normal left inverted right x axis y axis) 338mm x 270mm
1280x1024 60.0*+ 75.0 60.0*
1152x864 75.0
1024x768 75.0 70.1 60.0
832x624 74.6
800x600 72.2 75.0 60.3
640x480 75.0 72.8 59.9
720x400 70.1
S-video disconnected (normal left inverted right x axis y axis)


Tras haber modificado el fichero xorg.conf y teniendo ya un escritorio extendido que cubre los dos monitores (tanto si utuilizamos una distribución vertical como una horizontal) el siguiente paso es configurar gdm para lanzar dos sesiones Xephyr, una para cada puesto.

Previamente, tenemos que obtener información acerca de los eventos de entrada (los dos teclados y ratones) del sistema.


$ ls -la /dev/input/by-path/ | grep event | grep kbd
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 pci-0000:00:1d.2-usb-0:2:1.0-event-kbd -> ../event5
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 platform-i8042-serio-0-event-kbd -> ../event3

$ ls -la /dev/input/by-path/ | grep event | grep mouse
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 pci-0000:00:1d.2-usb-0:1:1.0-event-mouse -> ../event4
lrwxrwxrwx 1 root root 9 2009-06-18 13:11 platform-i8042-serio-1-event-mouse -> ../event8


En nuestro caso, tenemos una pareja de teclado y ratón conectados por puerto PS2 para uno de los puestos, y para el segundo una pareja de teclado y ratón USB. Los valores que obtengamos aquí serán usados posteriormente para configurar los dispositivos de entrada que corresponden a cada puesto.

A continuación se crea un lanzador con el objeto de ejecutar Xephyr con los parámetros adecuados y relacionando a cada uno con sus eventos de entrada. Para lograr esto, creamos un fichero que se utilizará a modo de script de lanzamiento. podemos nombrar y crear el fichero del modo que nos parezca más conveniente. En nuestro caso, lo creamos como /usr/sbin/Xephyr-path.sh

Se escoge un editor (vi, gedit, ...) para crear el fichero en cuestión, sin olvidar que tiene que tener permisos para poder ser ejecutado por root (el propietario del fichero).


$ sudo gedit /usr/sbin/Xephyr-path.sh
$ sudo chmod 744 /usr/sbin/Xephyr-path.sh


El fichero en cuestión tendrña un contenido similar a esto (cambiando el parámetro xkblayout en función del lenguaje de teclado del usuario):


$ cat /usr/sbin/Xephyr-path.sh



#!/bin/bash

# 200906 - josean
# http://netpatia.blogspot.com/

trap "" usr1

XEPHYR=/usr/bin/Xephyr
DISPLAY=:0
XAUTHORITY=/var/lib/gdm/:0.Xauth

args=()

while [ ! -z "$1" ]; do
if [[ "$1" == "-kbdpath" ]]; then
shift
if [ ! -z "$1" ]; then
args=("${args[@]}" "-keybd")
args=("${args[@]}" "evdev,,device=/dev/input/by-path/$1,xkbrules=xorg,xkbmodel=evdev,xkblayout=es")
fi
elif [[ "$1" == "-mousepath" ]]; then
shift
if [ ! -z "$1" ]; then
args=("${args[@]}" "-mouse")
args=("${args[@]}" "evdev,,device=/dev/input/by-path/$1")
fi
else
args=("${args[@]}" "$1")
# echo "+++ args $1 +++" >> /tmp/logXephyr
fi
shift
done

# Next line is just to create a log file with the invocation parameters, for debug purposes
# echo $XEPHYR -ac "${args[@]}" >> /tmp/logXephyr
exec $XEPHYR -ac "${args[@]}"


Tras haber creado este script, continuamos con las modificaciones en el fichero /etc/gdm/gdm.conf

En la sección [servers] de gdm.conf comentamos las reglas correspondientes a la distribución inicial y definimos lo necesario para la nueva distribución. Modificamos el fichero para lanzar las X de base y dos sesiones Xephyr (una por puesto) ejecutandose sobre las X de base.


# ****************************************************************************

[servers]

# 0=Standard
#
# Means that DISPLAY ":0" will start an X server as defined in the
# [server-Standard] section.

# ****************************************************************************

# Multiseat setup (200906)

0=Xephyr0
1=Xephyr1
2=Xephyr2

[server-Xephyr0]
name=Xephyr0
command=/usr/bin/X -br -dpms -s 0
handled=false
flexible=false

[server-Xephyr1]
name=Xephyr1
command=/usr/sbin/Xephyr-path.sh -br -screen 1280x1024 -kbdpath platform-i8042-serio-0-event-kbd -mousepath platform-i8042-serio-1-event-mouse
handled=true
flexible=false

[server-Xephyr2]
name=Xephyr2
command=/usr/sbin/Xephyr-path.sh -br -screen 1280x1024 -kbdpath pci-0000:00:1d.2-usb-0:2:1.0-event-kbd -mousepath pci-0000:00:1d.2-usb-0:1:1.0-event-mouse
handled=true
flexible=false

# ****************************************************************************


Vemos que éste es el script en e que hay que indicar qué dispositivos de entrada (sus puntos físicos de conexión) son los que corresponden con cada uno de los puestos.

El segundo cambio en el fichero gdm.conf está relacionado con la petición de autentificación. En esta parte hay algunas tareas que todavía es necesario realizar de forma manual.

Nos encontramso con el problema ya conocido de colocar cada sesión Xephyr adecuadamente para que cada usuario vea su sesión en su monitor. La versión actual de Xephyr no soporta el parámetro geometry que incluyen muchas aplicaciones X, de modo que no es posible indicar a Xephyr el lugar en el que se tiene que colocar. Para evitar este problema, creamos un script que será invocado en lugar de hacer una llamada directa al script de petición de identificación para iniciar sesión (greeter).

Este script, invocará una serie de comandos destinados a colocar cada ventana Xephyr en el lugar deseado. Para ello haremos uso de las utilidades xwininfo, wmctrl. con ellas podremos identificar una de las ventanas Xephyr y desplazarla al segundo monitor, de manera que resolvamos el problema de solapamiento entre las ventanas de sesión. Este es el motivo por el que anteriormente instalamos el paquete wmctrl.

En la sección [daemon] de gdm.conf cambiamos la referencia al "greeter" original por una referencia a este nuevo script. El script en cuestión no sólo invocará la petición de identificación, sino que se ocupará de colocar cada ventana Xephyr en su posición correcta:


# ****************************************************************************

[daemon]

# The greeter for attached (non-xdmcp) logins. Change gdmlogin to gdmgreeter
# to get the new graphical greeter.
# Greeter=/usr/lib/gdm/gdmgreeter
Greeter=/usr/sbin/Xephyr-login.sh

# ****************************************************************************


Como hemos indicado, creamos el script responsable de solicitar la identificación (en nuestro caso lo hemos llamado /usr/sbin/Xephyr-login.sh). Este script será invocado por el usuario gdm, de modo que creamos el script como propiedad de dicho usuario, dando únicamente permisos de ejecución por éste.


$ sudo gedit /usr/sbin/Xephyr-login.sh
$ sudo chown gdm:gdm /usr/sbin/Xephyr-login.sh
$ sudo chmod 744 /usr/sbin/Xephyr-login.sh


El script que acabamos de crear debería de tener este aspecto:


$ cat /usr/sbin/Xephyr-login.sh


#!/bin/bash
# /usr/sbin/Xephyr-login.sh

XAUTHORITY=/var/lib/gdm/:0.Xauth
XEP=$(xwininfo -root -children -display :0 | grep "Xephyr on :1" --max-count=1)
echo XEP ${XEP} >> /tmp/logXephyrLogin

# assign values to positional parameters to obtain the id (first parameter) of the Xephyr window
set ${XEP}
DISPLAY=:0 wmctrl -i -r $1 -e 0,0,1024,-1,-1
/usr/lib/gdm/gdmlogin


En nuestro caso, desplazamos en vertical una de las sesiones 1024 pixels (recordamos que nuestra distribución consiste en dos pantallas de 1280x1024 alineadas verticalmente).

Vemos que cuando se debería invocar la identificación de sesión, en su lugar se ejecuta el nuevo script (que incluye también esta parte de solicitud de identificación). Desde el punto de vista del usuario, lo que se ve es cada una de las pantallas de identificación ejecutandose en uno de los monitores. El resto de las operaciones realizadas pasan desapercibidas para el usuario.

La versión 9.04 de esta configuración multiterminal consigue algunas mejoras con respecto a versiones anteriores:
* La rueda de scroll vertical del ratón funcina correctamente.
* Los indicadores LED de los teclados funcionan de forma independiente sin mezclarse.

Updated 2009/06/22: Cambios menores

17 comentarios:

cameraphp dijo...

muy bueno el articulo, una pregunta, probaste los pendrives, si es que estos son accesibles de forma independiente en cada terminal?,

josean dijo...

Los pendrives son accesibles desde todas las sesiones iniciadas. El comportamiento de estos, depende de Policy kit (polkit). De hecho, en función de si la sesión está marcada como activa o no, el sistema permitirá (o no) desmontar los pendrives.

Es uno de los detalles a pulir para la siguiente versión.

Anónimo dijo...

Hola, ¿has probado con sonido independiente para cada una de las sesiones?, me refiero a tener dos tarjetas de sonido y hacerlas funcionar independientemente?

Por ejemplo uno está viendo un video con vlc y otro está escuchando música com un reproductor de música.

Un saludo, y gracias por el artículo.

josean dijo...

No he hecho pruebas de sonido, me temo que con eso no te puedo ayudar.

Este entorno se ha preparado para trabajar en un contexto de oficina, donde las necesidades de los usuarios son muy básicas (de hecho casi el 90% del uso de estos equipos es utilizar aplicaciones web de uso interno).

Anónimo dijo...

Para el sonido recomiendo USB.
Puedes tener varios altavoces o microfonos usb y lo configuras para cada aplicación o usuario.
Yo, p.e., tengo en ekiga el timbre de llamada por unos altavoces usb y la conversacion por los auriculares con micro, todos usb.

salu2,
A.

snakekontrol dijo...

no sabes como hacer la configuracion para 4 displays en lugar de 2? saludos y muy buen tutorial

josean dijo...

No, todas las pruebas las he hecho únicamente con una tarjeta con doble salida de video. Pero hay tutoriales para conseguir (aunque con aproximaciones diferentes a la que se expone aquí) múltiples puestos (más de 2)

Anónimo dijo...

pana muy buena publicacion...
Te quiero preguntar como se hace para poner el sonido para los usuarios en multiterminal...
ademas los usuarios no pueden poner device usb por que no las monta me podrias ayudar gracias...
y vuelvo a decirte muy buena publicacion...

josean dijo...

El tema de los dispositivos USB está relacionado con policy-kit y sesiones activas. En ocasiones, el sistema marca las sesiones de los usuarios como no activas (supongo que por el hecho de no estar ejecutándose de manera exclusiva).

Las políticas de policy-kit por defecto no permiten montar dispositivos USB a quienes están en sesiones no activas.

Lo más conveniente es cambiar dichas políticas.

Anónimo dijo...

Hola, ¿con dos buenas placas aceleradoras podría usar juegos desde dos terminales? ¿será posible hacer algo así para jugar juegos 3D tipo WOW o L2?

aneolf dijo...

Enhorabuena por el blog, Josean.
Me gustaría saber que tipo de licencia utilizas en el mismo, para no quebrantar tus derechos de autor.
Un saludo

Ricardo dijo...

OK, me parece excelente tu tutorial. Estoy buscando esta solución para mi sistema Kubuntu 10.04 64 bits. Me podrias colaborar con esto?

josean dijo...

No he hecho ninguna prueba con KDE. Me temo que no te puedo ayudar con eso.

Jorge Luis Mendoza dijo...

Hola Josean.

Quiero presentar este proyecto en mi lugar de estudio me prodrias ayudar con la version 10.04 ubunto.

Me parece muy buen trabajo y me ayudaria con mi materia de sistemas operativos.

Rodrigo Escobar dijo...

buenas quisiera una ayuda con este tutorial pues ya lo hice todo y mi problema que las dos sesiones me aparecen una ensima de la otran en un mismo monitor por lo que en la otra no se ve absolutamente nada como hago para que salga cada una en cada pantalla gracias

cesar dijo...

tengo instalado ubuntu 9.04 , en la etapa de modificar el archivo /etc/gdm/gdm.conf no lo tengo dciho archivo , pero si la carpeta /etc/gdm?

Anónimo dijo...

Muy buen blog por favor nos podria ayudar como podemos modificar el archivo xorg.conf estamos utilizando ubuntu 10.10