Pesquisar este blog

terça-feira, 24 de agosto de 2010

Como configurar um ambiente Multi-Head ou Multi-seat no linux

Pessoal abaixo mais informações sobre como  Como configurar um ambiente Multi-Head ou Multi-seat no linux - são informações que encontrei na página de Alexandre F. M. Souza localizada em :







    MultiHead vêm do inglês "cabeças múltiplas". Na prática é como colocar várias pessoas usando a mesma máquina sem uma atrapalhar a outra. Muitos dos usuários de computadores não imaginam o que os computadores ainda podem fazer. Vemos nos filmes de ficção coisas engenhosas que controlam e facilitam a vida das pessoas. O que geralmente é um erro de se pensar é que muitas das inovações só virão com a evolução técnica da engenharia e arquitetura. Na prática basta uma idéia simples para que tudo que se evoluiu até o presente momento possa ser abandonado ou potencializado.  Então, além de aumentar a capacidade dos recursos é importante usá-los de forma plena.

    A idéia do multi-head é baseado nesta otimização e melhor aproveitamento dos recursos que temos. Essa é uma idéia que surgiu basicamente da comunidade de software livre. Acho que a maior e primeira referência  no assunto foi Alvils Stoss um letão (nascido na Letônia) que escreveu um patch para o kernel chamado Backstreet Ruby. Esse patch foi bem assimilado pela comunidade e mais tarde possibilitou o servidor X a suportar nativamente o conceito sem adaptações. O servidor X é "um capítulo a parte". Na verdade a concepção dos sistemas Unix definem os recursos de vídeo através de uma aplicação remota cliente-servidor (X). E pelo X já ter esta natureza possibilitou configurações diversas de computadores e terminais. Na prática pode até ser que isso traga um desempenho um pouco menor mas traz um recurso poderoso.

    Os requesitos não são muitos. Os recursos que você precisa para rodar pelo menos 2 terminais são muito baixos. Se você tiver 1 teclado usb, 1 mouse usb, e uma placa com duas saídas de vídeo (até mesmo 1 saída de TV) já existe a possibilidade de configurar o seu multihead. Na teoria o número de usuários podem usar simultaneamente apenas uma CPU é bem grande. Existem placas Desktop com até 6 slots PCI mais 1 AGP ou video onBoard. Todos os slots podem ser usados, e se considerarmos cada slot com uma placa de duas saídas conseguiríamos rodar praticamente um laboratório inteiro!
    Não tem quem veja uma solução pronta rodando e não fique igual criança com brinquedo novo. . . Essa solução deu novas perspectivas a montagem de um laboratório e pode reduzir e muito os custos dos mesmos.

    Os micro-processadores evoluíram muito ao longo da sua história. Os computadores que temos hoje são computadores de grande capacidade de processamento. Enquanto as tarefas básicas, mesmo com todos os recursos gráficos, não são um verdadeiro desafio para o processamento em geral. Os usuários que gostam de ter gráficos com histórico do uso da CPU podem constatar que, há um grande período que a CPU fica ociosa. Você pode fazer um teste habilitando o monitor do sistema na barra do Gnome ou usando o Superkaramba. No uso geral o gráfico se mostra mais ou menos com picos:
Exemplo:
  
    Supondo que este é um histórico de uso esperado dos usuários, se os picos não coincidirem entre eles o resultado(sensação do usuário) vai ser igual a de um computador dedicado. Por outro lado se os picos coincidirem você terá divisão do desempenho pela quantidade de coincidências que ocorrerão. Para teorizar estas informações podemos usar um exemplo. Consideremos "picos" os momentos que a CPU passou de 50% de uso e se manteve por pelo menos 1 segundo e no máximo 2 segundos. Durante o meu teste de uso que abri alguns emails e editei este texto tive 2 picos em 2 minutos. Se tivéssemos 2 usuários, com o mesmo tipo de uso, a probabilidade de haver um momento de colisão dos picos é muito baixa (perto de 5%, dúvidas?). Porém quanto mais usuários, mais alta essa probabilidade vai ser e mais rápido ela cresce (visto que ela não é uma função linear). É possível fazer mais estudos dessa forma, mas isto pode não ser adequado pois não podemos prever o que cada usuário vai fazer. Então a única ferramenta adequada pode ser uma pesquisa com os usuários perguntando a sensação que cada um teve ao usar o computador.

    É claro que algumas aplicações como jogos por exemplo exigem um processamento grande e contínuo. Mas tarefas como tarefas de escritório este gráfico é bem exemplificado. Então podemos partir do princípio que seus usuários não vão jogar pesados jogos 3D (no máximo jogos em flash da internet). Porém nem tudo num computador é CPU. Esse tipo de ambiente traz outros tipos de desafios. Por exemplo: o acesso a disco! Os discos rígidos são dispositivos que eu, particularmente, considero verdadeiros dinossauros da informática. Eles são lentos e tem uma latência muito grande. Pior que isso, tendem a ficar mais lentos quando os acessos são não seqüenciais ou seja em setores distantes. O que nos leva a concluir que um ambiente de multiterminais é o pior ambiente possível para acesso a discos (visto que os usuários são independentes).

    Mesmo tendo estes desafios o Linux nativamente já usa as melhores alternativas de amenização dos problemas. Como por exemplo:

  • Cache de disco em memória.
  • Bibliotecas compartilhadas.
  • Filosofia Unix de multi-usuário.
  • Além da atribuição do Linux como sistema para servidores.
    O cache de disco em memória possibilita que pequenos acessos sejam imperceptíveis. Por outro lado o uso de bibliotecas compartilhadas faz com que programas já abertos sejam aproveitados entre vários usuários de forma transparente. O administrador da máquina pode (e é desejável) configurar o sistema de forma a não possibilitar diversas implementações que não são compartilhadas. Por exemplo, numa mesma máquina instalado KDE e GNOME. Visto que um usa QT e o outro GTK e não compartilham nada entre eles. Essas facilidade que o linux apresenta faz com que  o multiterminal funcione bem até em um Celeron 1.6 Ghz com 128 mb de RAM. Pelo menos 512MB de RAM e HD Sata é recomendado.

    Outra coisa que vale a pena ressaltar: Para configurar seu ambiente multiterminal é necessário ter uma certa experiência com Linux.

Colocando as placas e achando elas no sistema

    Bom, tanto faz a ordem dos dispositivos USB ou então das placas, só coloque-as em qualquer ordem. Procure não fazer a instalação do Linux com elas plugadas. Em distros como o Mandriva, alguns programas de detecção automática travam ou então tentam configurar automaticamente todas elas e ocorrem problemas.


    Agora verifique se está instalado o Xorg, hotplug, udev e tudo configurado no boot. Dentre as formas de fazer escolherei a mais simples. Mais pra frente passarei rapidamente sobre as outras.

    Tendo tudo funcionando, entre no shell e dê um lspci:

$ lspci
....
0000:00:09.0 VGA compatible controller: ATI Technologies Inc Rage 128 RK/VR
0000:00:0a.0 VGA compatible controller: ATI Technologies Inc Rage 128 RK/VR
0000:00:0b.0 VGA compatible controller: ATI Technologies Inc Rage 128 RK/VR
0000:01:00.0 VGA compatible controller: Silicon Integrated Systems [SiS] 661FX/M661FX/M661MX/741/M741/760/M760 PCI/AGP


    Anote os endereços que estão ali no primeiro campo, caso saiam muitos dispositivos, um "grep VGA" ajuda. Descubra também quais módulos são carregados pra cada dispositivo.

    Agora está na hora de verificar os dispositivos USB. Pode parecer bobagem eu falar isso, mas verifique mesmo se estão plugados um número muito grande assim de dispositivos sempre tem um mal encaixado e você perde um dia inteiro à toa. No shell mesmo dê um cat no /proc:

$ cat /proc/bus/input/devices
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
H: Handlers=kbd event0
B: EV=120013
B: KEY=4 2000000 3802078 f840d001 f2ffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7

I: Bus=0011 Vendor=0002 Product=0005 Version=0000
N: Name="ImPS/2 Generic Wheel Mouse"
P: Phys=isa0060/serio1/input0
H: Handlers=event1 mouse0 ts0
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=103

I: Bus=0003 Vendor=0a81 Product=0101 Version=0110
N: Name="CHESEN USB Keyboard"
P: Phys=usb-0000:00:03.0-1/input0
H: Handlers=kbd event2

I: Bus=0003 Vendor=0a81 Product=0101 Version=0110
N: Name="CHESEN USB Keyboard"
P: Phys=usb-0000:00:03.0-1/input1
H: Handlers=kbd event3

I: Bus=0003 Vendor=0566 Product=3002 Version=0100
N: Name="0566:3002"
P: Phys=usb-0000:00:03.0-2/input0
H: Handlers=kbd event4

I: Bus=0003 Vendor=1267 Product=0210 Version=0001
N: Name="PS/2+USB Mouse"
P: Phys=usb-0000:00:03.0-3/input1

.... (e tudo mais lá pra baixo)


    Veja que o mesmo teclado "CHESEN USB Keyboard" tem o mesmo endereço físico, mas tem duas entradas. Isso se deve as teclas especiais como desligar, suspender, navegação na internet e "Windows" que o kernel trata como um teclado separado. Aqui iremos só usar o primeiro input. Anote o endereço físico (PHYS) de cada um.

    Tendo isso agora vamos para o próximo passo.

Começando a por a mão na massa

    Dentre os problemas que envolvem os multiheads, existem alguns realmente chatos. As placas não são projetadas pra funcionar de forma independente. Uma placa sempre derruba a outra, às vezes aparecem caracteres estranhos em uma delas e a tela misteriosamente começa a rodar com um simples mount ou swapon.

Por exemplo, uma interrupção pode ser "entendida" por todas elas. Isto acontece com a int 10. Quando a placa é inicializada. Porém simplesmente tirando a interrupção 10 faz com que as placas secundárias não tenham memória suficiente para inicializar (sem modos de tela válidos).

Mas calma, não é o fim do mundo. Para isso dá-se um jeito, colocando um script simples no boot que chamaremos de "Xorg-multiterminal". Ele só inicializará as placas sem a interrupção 10 pra que depois elas sejam usadas.

Mas primeiro vamos configurar o xorg.conf, edite o /etc/X11/xorg.conf mais ou menos com a seguinte configuração, mudando os endereços pelo qual você anotou:

....
Section "InputDevice"
        Identifier      "Keyboard0"
        Driver          "kbd"
        Option          "Protocol"      "evdev"
        Option          "Dev Phys"      "isa0060/serio0/input0"
        Option          "XkbRules"      "xorg"
        Option          "XkbModel"      "pc104"
        Option          "XkbLayout"     "us"
        Option          "CoreKeyboard"
EndSection

Section "InputDevice"
        Identifier      "Keyboard1"
        Driver          "kbd"
        Option          "Protocol"      "evdev"
        Option          "Dev Phys"      "usb-0000:00:03.0-1/input0"
        Option          "XkbRules"      "xorg"
        Option          "XkbModel"      "pc104"
        Option          "XkbLayout"     "us"
        Option          "CoreKeyboard"
EndSection

Section "InputDevice"
        Identifier      "Keyboard2"
        Driver          "kbd"
        Option          "Protocol"      "evdev"
        Option          "Dev Phys"      "usb-0000:00:03.0-2/input0"
        Option          "XkbRules"      "xorg"
        Option          "XkbModel"      "pc104"
        Option          "XkbLayout"     "us"
        Option          "CoreKeyboard"
EndSection

Section "InputDevice"
        Identifier      "Mouse1"
        Driver          "mouse"
        Option          "Protocol"      "evdev"
        Option          "Dev Phys"      "usb-0000:00:03.2-1/input1"
        Option          "CorePointer"
        Option          "ZAxisMapping"          "4 5"
EndSection

Section "Device"
        Identifier      "Device0"
        Driver          "sis"
        BusID           "PCI:1:0:0"
        Option          "NoInt10"       "Yes"
        Option          "RestoreBySetMode"      "no"
EndSection

Section "Device"
        Identifier      "Device1"
        Driver          "ati"
        BusID           "PCI:0:9:0"
        Option          "NoInt10"       "Yes"
        Option          "RestoreBySetMode"      "no"
EndSection

Section "ServerLayout"
        Identifier      "Layout0"
        Screen          "Screen0"
        InputDevice     "Keyboard0"
        InputDevice     "Mouse0"
        Option          "SingleCard"
EndSection

Section "ServerLayout"
        Identifier      "Layout1"
        Screen          "Screen1"
        InputDevice     "Keyboard1"
        InputDevice     "Mouse1"
        Option          "SingleCard"
        Option "DontZap"  "on"
EndSection

Aqui omiti várias informações, porém o principal ainda se encontra aí. Interessante também é desabilitar a aceleração 3D, já que não vai ser necessário mesmo, coloque Option "NoAccel" em cada device. A opção Dontzap no layout impede que o usuário feche o X com Ctrl+Alt+Backspace. Isso faz com que todos os usuários caiam. Atenção! o BusID usa endereços em decimal.. então converta a =10, b=11, c=12...

Outra coisa muito importante é o driver evdev (event devices), ele é o responsável pela separação dos dispositivos em distros como Mandriva e evdev não vem compilado no Xorg. Infelizmente você vai ter que compilar e o trabalho vai durar semanas. Outra solução é usar o /dev/input ao invés do endereço físico, mas sua distro deve suportar os protocolos.

Agora precisamos configurar o "Xorgmultiterminal" no boot. Pra isso crie um arquivo "xorg.conf.probe", que será baseado no xorg.conf. Ele habilita as placas no boot. Então crie o /etc/X11/xorg.conf.probe começando já da placa secundária:


Section "Device"
        Identifier      "Device1"
        Driver          "ati"
        Screen          0
        BusID           "PCI:0:9:0"
        Option          "NoInt10"       "no"
        Option          "NoAccel"
        Option          "RestoreBySetMode"      "no"
EndSection

.....

Section "ServerLayout"
        Identifier      "probe"
        Screen          "Screen1"
        Screen          "Screen2"   LeftOf  "Screen1"
        Screen          "Screen3"   LeftOf  "Screen2"
        InputDevice     "Keyboard1"
        InputDevice     "Mouse1"
EndSection

A ordem das telas não importa. Note que só são inicializadas as placas secundárias. E a interrupção 10 está como "NO".

Agora precisamos colocar na inicialização. Crie um script /etc/init.d/xorgmultiterminal com a seguinte linha de comando:
[[ -f "/etc/X11/xorg.conf.probe" ]] && /usr/X11R6/bin/X -config /etc/X11/xorg.conf.probe -probeonly

Agora descubra qual runlevel corresponde ao modo multi-usuário com X11 na sua distro dando um cat no /etc/inittab.

Vamos supor que seja o Debian, que é 3. Então entre em /etc/rc3.d e crie um link simbólico com:

$ ln -s /etc/init.d/xorgmultiterminal S80xorgmultiterminal

O número 80 corresponde a prioridade que esse script tem no boot. Quando você parar o X, execute sempre ele novamente na mão pra não precisar reiniciar. Por exemplo:

$ /etc/init.d/gdm stop
$ /etc/init.d/xorgmultiterminal
.......
$ /etc/init.d/gdm start


Configurando o gerenciador de displays (gdm)

Acredito que o gerenciador mais modular de todos é o GDM, justamente por isso que todos os lugares que descrevem conteúdo sobre multiheads explicam mais do GDM. Na verdade não altera muito de um pra outro. Primeiro vamos testar o X. Abra no terminal:

$ Xorg -layout Layout0

Depois feche o X e teste um por um dos layouts:

$ Xorg -layout Layout1
$ Xorg -layout Layout2
$ Xorg -layout Layout3


Tendo todos os layouts funcionando, teste o teclado com o numlock, se todos os leds piscarem juntos, não está funcionando. Tem que ser independente. Configure o gdm em /etc/gdm/gdm.conf da seguinte maneira na seção servidores:

0=XServer0
1=XServer1
....
[server-XServer0]
name=Standard_server0
command=/usr/X11R6/bin/X -layout Layout0 :0 vt7 -sharevts
flexible=true
[server-XServer1]
name=Standard_server1
command=/usr/X11R6/bin/X -layout Layout1 :1 vt8 -sharevts
flexible=true

Em algumas distros como o Mandrake, é necessário um módulo do kernel chamado Faketty, que cria terminais virtuais 50, 51, 52.... ao invés de 7, 8, 9. Estes vts "falsos" tem menos rigor no controle dos dispositivos. Mas isso é desnecessário pra distros menos userfriendlys, como Debian, Slackware, Gentoo e SuSE.

Para usar o XDM ou KDM é praticamente a mesma coisa, só chame a mesma linha de comando pra cada servidor. Em cada um deles você provavelmente tenha um resultado diferente. Mas o que eu tenho percebido é que GDM e XDM são os mais adequados.

Testando e usando

Agora é só usar. Procure não logar dois usuários iguais. Eles costumam interferir um no outro. Note também que com um "ps -aux" dá pra ver vários X sendo executados. Sempre procure logar 1 gerenciador de janela só, faça testes de desempenho e veja com é ruim usar vários gerenciadores grandes diferentes.

Essa configuração ainda tem problemas de estabilidade, mas nada preocupante. Você como administrador do sistema pode colocar só uma categoria de software e fazer com que os usuários usem da forma que você quiser.

Outro problema são as mensagens de erro. O kernel não se dá conta do multihead e sempre imprime na tela principal. Isso causa uma rotação da tela. Pode-se ser resolvido com redirecionamento do erro 1> para /dev/null ou recompilar o kernel sem suporte a console.

Um problema que tive e ainda não resolvi é o logout. Todos os usuários caem, mas isso não acontece em todas as placas. Isso depende muito do driver da placa de vídeo.. alguns são mal escritos.

Agradeço ao site

Que é de um carinha que desenvolveu um patch pro kernel pra fazer multiheads. Ele explica MUITA coisa! A melhor fonte da net com certeza.

Outro link interessante de onde tirei bastante informação:

Multi-head usando udev e Xnest

Esta montagem contempla uma solução usada em algumas ferramentas proprietárias de multi terminais. Utiliza-se apenas um servidor X estendido (não xinerama) e coloca várias janelas do tamanho da tela para o uso do usuário. Cada janela é um processo que recebe o event fornecido pelo udev. A camada de baixo (X) o usuário não pode ver, só o Xnest que está na sua tela, que não pode ser redimensionado. Para ter acesso ao servidor X nest modificado pelo patch desenvolvido na UFPR faça o download aqui:

Você precisará também do script feito por mim :)

Tendo todos estes arquivos vamos começar a por a mão na massa.

Plugando e achando tudo

Primeiro precisamos nos certificar que as placas estão devidamente conectadas. Verifique isso executando o comando abaixo como root:

# lspci | grep VGA
00:0a.0 VGA compatible controller: (FABRICANTE / MARCA)
00:0b.0 VGA compatible controller: (FABRICANTE / MARCA)

Cada linha corresponde a uma placa do seu computador. O primeiro campo corresponde a identificação do barramento pci. Anote estes endereços para configurar o servidor X. Agora edite o arquivo/etc/X11/xorg.conf da seguinte maneira:

OBS: Note que os dispositivos recebem endereço BusID em decimal e o lspci mostra em hexa-decimal, para isto, substituir a por 10, b por 11 e assim por diante... preciso também conhecer previamente qual driver adequado para cada placa.

Section "Device"
        Identifier      "Device 1"
        Driver  "vesa" # vai depender do driver da sua placa de vídeo
        BusID   "PCI:0:10:0"
EndSection

Section "Device"
        Identifier      "Device 2"
        Driver  "vesa" # vai depender do drvier da sua placa de vídeo
        BusID   "PCI:0:11:0"
EndSection

Section "Monitor"
        Identifier      "Monitor X"
EndSection


Section "Monitor"
        Identifier      "Monitor Y"
EndSection

Section "Screen"
        Identifier      "Screen X"
        Device  "Device 1"
        Monitor "Monitor X"
        DefaultDepth    16
        SubSection "Display"
                Depth   16
                Modes   "1024x768"
        EndSubSection
EndSection



Section "Screen"
        Identifier      "Screen Y"
        Device  "Device 2"
        Monitor "Monitor Y"
        DefaultDepth    16
        SubSection "Display"
                Depth   16
                Modes   "1024x768"
        EndSubSection
EndSection

Section "ServerLayout"
        Identifier      "Layout"
        Screen  "Screen X"
        Screen  "Screen Y"      Below   "Screen X"
        InputDevice     "Keyboard1"
        InputDevice     "Mouse1"
        Option  "DontZap"       "on" # evita que o usuário derrube o X com ctrl alt backspace
        Option  "DontVTSwitch"  "on" # evita que o usuário troque os vts
        Option  "BlankTime"     "0"
        Option  "StandbyTime"   "0"
        Option  "SuspendTime"   "0"
        Option  "OffTime"       "0"
EndSection

Aqui a configuração está feita para dois terminais. Para fazer com mais é só usar a mesma coisa, mas com vários devices, vários monitores, vários screens. Se não conseguir editar o arquivo, use o xorgcfg.

Agora execute o X e teste se abre todos os monitores. Se não, volte a configuração do X. Esta parte não deve ser complicada, pois o próprio configurador deve fazer.

Depois renomeie e mova o arquivo com os comandos:

# mv multiXnest-0.1.3 /usr/local/bin/multiXnest
# mv multiXnest.sh /usr/sbin/


Para verificar se os dispositivos estão devidamente conectados, execute:

# cat /proc/bus/input/devices 

Então olhe em cada seção se está plugado o dispositivo. Agora vem a parte automática e legal.

Execute o script veevent.sh que está linkado na primeira página e descubra qual o event de cada dispositivo.

Edite o arquivo /etc/X11/gdm/gdm.conf na seção "Servers":

[servers]
0=Principal
1=Xnest1
2=Xnest2

[server-Principal]
name=Principal
command=/usr/X11R6/bin/X
handled=false # faz com que este servidor não seja usado para login 
flexible=false

[server-Xnest1]
name=Xnest1
command=/usr/sbin/multiXnest.sh -display :0.0 -xauthority /var/lib/gdm/:0.Xauth -geometry 1024x768+0+0 -kbd /dev/input/event0 -ptr /dev/input/event1 -dpi 92
handled=true
flexible=false

[server-Xnest2]
name=Xnest2
command=/usr/sbin/multiXnest.sh -display :0.1 -xauthority /var/lib/gdm/:0.Xauth -geometry 1024x768+0+0
-kbd /dev/input/event2 -ptr /dev/input/event5 -dpi 92
handled=true
flexible=false

Agora mude event0, event1, event2, event5 pelos valores que você descobriu no veevent.sh. Para cada terminal mude o valor do display 0.X.

Agora é só configurar o GDM no boot e usar.


MultiXnest possui alguns probleminhas de visualização, menus do qt e etc.. A aceleração 3D por exemplo é desabilitada. Mesmo assim esta solução eu considero bem melhor que a anterior (MultiHeads no Linux)

Exemplos de uso

    Muitos laboratórios já foram montados dessa forma. A redução de custos gira em torno de 50% visto que os monitores ainda são uma parcela expressiva.
    No departamendo de informática da UFPR os multiterminais rodam como servidores remotos sem HD. Então as máquinas não são responsáveis por imprimir uma tela somente, mas 4 telas de uma vez só. Por sua vez cada máquina dessa não processa nada localmente.

Nenhum comentário:

Postar um comentário

Observação: somente um membro deste blog pode postar um comentário.