terça-feira, 24 de novembro de 2009

Um dia de merda - Por Luis Fernando Veríssimo

Olá pessoal!

Tive conhecimento deste texto através de alguns amigos e achei sensacional, assim sendo decidi postar por aqui.  Sei que é um post não relacionado com informática, mas nem só de "computador" vive o homem....  

Um dia de Merda - Por Luis Fernando Veríssimo
Aeroporto Santos Dumont, 15:30. Senti um pequeno mal estar causado por uma cólica intestinal, mas nada que uma urinada ou uma barrigada não aliviasse. Mas, atrasado para chegar ao ônibus que me levaria para o Galeão, de onde partiria o vôo para Miami, resolvi segurar as pontas. Afinal de contas são só uns 15 minutos de busão. “Chegando lá, tenho tempo de sobra para dar aquela mijadinha esperta, tranqüilo”. O avião só sairia às 16:30.

Entrando no ônibus, sem sanitários, senti a primeira contração e tomei consciência de que minha gravidez fecal chegara ao nono mês e que faria um parto de cócoras assim que entrasse no banheiro do aeroporto. Virei para o meu amigo que me acompanhava e, sutil, falei: “Cara, mal posso esperar para chegar na merda do aeroporto porque preciso largar um barro”. Nesse momento, senti um urubu beliscando minha cueca, mas botei a força de vontade para trabalhar e segurei a onda. O ônibus nem tinha começado a andar quando, para meu desespero, uma voz disse pelo alto falante: “Senhoras e senhores, nossa viagem entre os dois aeroportos levará em torno de 1 hora, devido às obras na pista”. Aí o urubu ficou maluco querendo sair a qualquer custo. Fiz um esforço hercúleo para segurar o trem merda que estava para chegar na estação ânus a qualquer momento. Suava em bicas.

Meu amigo percebeu e, como bom amigo que era, aproveitou para tirar um sarro. O alívio provisório veio em forma de bolhas estomacais, indicando que pelo menos por enquanto as coisas tinham se acomodado. Tentava me distrair vendo TV, mas só conseguia pensar em um banheiro, não com uma privada, mas com um vaso sanitário tão branco e tão limpo que alguém poderia botar seu almoço nele. E o papel higiênico então: branco e macio, com textura e perfume e, ops, senti um volume almofadado entre meu traseiro e o assento do ônibus e percebi, consternado, que havia cagado. Um cocô sólido e comprido daqueles que dão orgulho de pai ao seu autor. Daqueles que dá vontade de ligar pros amigos e parentes e convidá-los a apreciar na privada. Tão perfeita obra, dava pra expor em uma bienal. Mas sem dúvida, a situação tava tensa. Olhei para o meu amigo, procurando um pouco de solidariedade, e confessei sério: “Cara, caguei”.

Quando meu amigo parou de rir, uns cinco minutos depois, aconselhou-me a relaxar, pois agora estava tudo sob controle. “Que se dane, me limpo no aeroporto” – pensei. “Pior que isso não fico”. Mal o ônibus entrou em movimento, a cólica recomeçou forte. Arregalei os olhos, segurei-me na cadeira, mas não pude evitar e, sem muita cerimônia ou anunciação, veio a segunda leva de merda. Dessa vez, como uma pasta morna. Foi merda para tudo que é lado, borrando, esquentando e melando a bunda, cueca, barra da camisa, pernas, panturrilha, calças, meias e pés. E mais uma cólica anunciando mais merda, agora líquida, das que queimam o fiofó do freguês ao sair rumo à liberdade. E depois um peido tipo bufa, que eu nem tentei segurar, afinal de contas o que era um peidinho para quem já estava todo cagado. Já o peido seguinte, foi do tipo que pesa. E me caguei pela quarta vez.


Lembrei de um amigo que certa vez estava com tanta caganeira que resolveu botar modess na cueca, mas colocou as linhas adesivas viradas para cima e quando foi tirá-lo levou metade dos pêlos do rabo junto. Mas era tarde demais para tal artifício absorvente. Tinha menstruado tanta merda que nem uma bomba de cisterna poderia me ajudar a limpar a sujeirada. Finalmente cheguei ao aeroporto e, saindo apressado com passos curtinhos, supliquei ao meu amigo que apanhasse minha mala no bagageiro do ônibus e a levasse ao sanitário do aeroporto para que eu pudesse trocar de roupas. Corri ao banheiro e, entrando de boxe em boxe, constatei a falta de papel higiênico em todos os cinco.

Olhei para cima e blasfemei: “Agora chega, né?” Entrei no último, sem papel mesmo, e tirei a roupa toda para analisar minha situação (que conclui como sendo o fundo do poço) e esperar pela minha salvação, com roupas limpinhas e cheirosinhas e com ela uma lufada de dignidade no meu dia.

Meu amigo entrou no banheiro com pressa, tinha feito o “check-in” e ia correndo tentar segurar o vôo. Jogou por cima do boxe o cartão de embarque e uma maleta de mão e saiu antes de qualquer protesto de minha parte. Ele tinha despachado a mala com roupas. Na mala de mão só tinha um pulôver de gola “V”. A temperatura em Miami era de aproximadamente 35 graus.

Desesperado, comecei a analisar quais de minhas roupas seriam, de algum modo, aproveitáveis. Minha cueca joguei no lixo. A camisa era história. As calças estavam deploráveis e, assim como minhas meias, mudaram de cor tingidas pela merda. Meus sapatos estavam nota 3, numa escala de 1 a 10. Teria que improvisar. A invenção é mãe da necessidade, então transformei uma simples privada em uma magnífica máquina de lavar. Virei a calça do lado avesso, segurei-a pela barra, e mergulhei a parte atingida na água. Comecei a dar descarga até que o grosso da merda se desprendeu.

Estava pronto para embarcar. Saí do banheiro e atravessei o aeroporto em direção ao portão de embarque trajando sapatos sem meias, as calças do lado avesso e molhadas da cintura ao joelho (não exatamente limpas) e o pulôver gola “V”, sem camisa. Mas caminhava com a dignidade de um lorde.

Embarquei no avião, onde todos os passageiros estavam esperando “O RAPAZ QUE ESTAVA NO BANHEIRO” e atravessei todo o corredor até o meu assento, ao lado do meu amigo que sorria. A aeromoça se aproximou e perguntou se precisava de algo. Eu cheguei a pensar em pedir 120 toalhinhas perfumadas para disfarçar o cheiro de fossa transbordante e uma gilete para cortar os pulsos, mas decidi não pedir: “Nada, obrigado. Eu só queria esquecer este dia de merda!”

sexta-feira, 13 de novembro de 2009

Tunando o Sistema de Arquivos - Entendendo o Journal do EXT3

Quando pensamos em performance no ambiente computacional, sempre direcionamos primeiramente nossa atenção para perguntas como: - Que processador devo escolher?!?!?! Quantos processadores?!?!?! Quanto de memória RAM precisamos ter para rodar determinada aplicação?!?! Com toda a certeza, essas preocupações não são inválidas e temos que nos ater sim as essas características de hardware.
Entretanto, quando falamos em performance sabemos que o dispositivo mais lento de todos os subsistemas que compõem o nosso hardware é o disco (Hard Drive). Mesmo com tecnologias como IDE, SCSI, SATA (SSD's até ficou melhor, mas ainda precisa evoluir e ter o seu custo melhorado), o acesso à disco praticamente será em 90% dos casos o culpado pela lentidão em nossos servidores. 
Para entendermos melhor o funcionamento do Ext3  e como podemos ajustar alguns parâmetros para auxiliar na performance do mesmo, precisamos mencionar a principal diferença que existe entre os sistemas de arquivos Ext2 e Ext3: o journal
Para definirmos o journal de maneira simples e direta, poderíamos dizer que o journal nada mais é do que uma área destinada para registrar todas as transações que serão executadas no disco, cuja a finalidade é, em caso de problemas (ex: desligamento súbito do sistema) obter um histórico de todas as transações e aplicá-las. 
O journal do Ext3 trabalha de três maneiras que podemos configurar: 


  • Ordered (default): Somente os metadados  dos arquivos são escritos na área de journal, porém força a escrita do conteúdo do arquivo no sistema de arquivos principal logo após os metadados terem sido gravados no journal. Este é o que oferece a melhor relação confiabilidade vs performance. 
  • Writeback:  Somente os metadados são escritos na área de journal, porém o kernel irá definir quando o conteúdo do arquivo será escrito no sistema de arquivos principal (sync ou pdflush). O writeback oferece o melhor desempenho, porém em caso de queda do sistema, os dados podem ser reescritos fora de ordem os corrompendo.
  • Journal: metadados e dados do arquivo (conteúdo do arquivo) são escritos na área de journal e depois escritos no sistema de arquivos principal, aumentando a confiabilidade porém oferecendo menos performance. 
Para alterar como o seu sistema de arquivos irá tratar a área de Journaling, basta montá-lo passando o parâmetro  -o data=, como  o exemplo abaixo: 
mount -o data=writeback /dev/sda3 /home
Com essas definições claras, um fato que não será alterado em nenhuma das implementações acima é o seek time. Seek time é o tempo gasto na movimentação da cabeça de leitura/escrita do disco até a trilha/setor desejado. O que quero dizer é, mesmo só gravando os metadados no journal, a cabeça de leitura/escrita do disco necessita se movimentar até os setores destinados para a área de journal gravar os metadados e depois se movimentar para a área destinada aos dados dos arquivos, gerando um movimento demasiado da cabeça para grandes escritas. 
Como uma boa prática para reduzirmos o seek time para essas operações, podemos colocar a área de journal em um disco dedicado, isto é, outro disco para controlar o I/O do journal, minimizando o movimento da cabeça de leitura/escrita do disco principal.  A nova área do journal pode variar de tamanho entre 1024 até 102400 blocos do sistema de arquivos principal. 
Irei demonstrar como podemos retirar o journal de um sistema de arquivos que já o existente: 
[root@mmello ~]# mount | grep /teste
/dev/sda2 on /teste type ext3 (rw,data=journal)
[root@mmello ~]# grep /teste /etc/fstab 
LABEL=/teste /teste ext3 defaults,data=journal 0 1
[root@mmello ~]# umount /teste
[root@mmello ~]# tune2fs -l /dev/sda2 | grep -i has_journal
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype sparse_super large_file
[root@mmello ~]# tune2fs -O ^has_journal /dev/sda2
tune2fs 1.41.9 (22-Aug-2009)
[root@mmello ~]# tune2fs -l /dev/sda2 | grep -i has_journal
Agora o que temos que fazer é criar uma nova área de journal em outro disco e adicionar essa área para o nosso sistema de arquivos principal, contudo, não esqueça que a formatação do journal precisa manter o tamanho do bloco do sistema de arquivo principal: 
[root@mmello ~]# tune2fs  -l /dev/sda2 | grep -i "block size"
Block size:               4096
[root@mmello ~]# mke2fs  -O journal_dev -b 4096 -L journal-ext-sda2 /dev/sdb1 102400
mke2fs 1.41.9 (22-Aug-2009)
Filesystem label=journal-ext-sda2
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
0 inodes, 102400 blocks
0 blocks (0.00%) reserved for the super user
First data block=0
0 block group
32768 blocks per group, 32768 fragments per group
0 inodes per group
Superblock backups stored on blocks: 
Zeroing journal device: done  
root@mmello ~]# tune2fs -j -J device=/dev/sdb1 /dev/sda2
tune2fs 1.41.9 (22-Aug-2009)
Creating journal on device /dev/sdb1: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@mmello ~]# tune2fs -l /dev/sda2 | grep -i journal
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype sparse_super large_file
Journal UUID:             a9d8f11d-65c5-4071-8d07-3abc5adb8b16
Journal device:          0x0811
Journal backup:           inode blocks
[root@mmello ~]# blkid | grep -e "/teste" -e "journal-ext-sda2"
/dev/sda2: LABEL="/teste" UUID="9dc5a7e9-94b4-4836-b73f-363530a64108" EXT_JOURNAL="a9d8f11d-65c5-4071-8d07-3abc5adb8b16" SEC_TYPE="ext2" TYPE="ext3" 
/dev/sdb1: LABEL="journal-ext-sda2" UUID="a9d8f11d-65c5-4071-8d07-3abc5adb8b16" TYPE="jbd" 
[root@mmello ~]# mount | grep /teste
/dev/sda2 on /teste type ext3 (rw,data=journal)
[root@mmello ~]# 


Pronto!!!! Seu sistema de arquivos já possui uma disco dedicado para trabalhar o journal, assim diminuindo o seek time do disco principal do sistema.
Para os que não podem se dar o luxo de ter um disco específico para o journal, o parâmetro commit= define de quanto em quanto tempo em segundos o journal será comitado para disco. Exemplo:  mount -o commit=10 /dev/sda2 /teste
Espero ter ajudado os amigos com algumas técnicas para reduzir o seek time do disco e com isso aumentando a performance de um dos subsistemas mais lentos para acesso que temos atualmente. 
Abraços....

sexta-feira, 6 de novembro de 2009

Evento - TcheLinux 2009 - 14 de Novembro de 2009

Evento promovido pelo Tchelinux em parceria com a Faculdade de Informática da PUC-RS de Porto Alegre, com a finalidade de divulgar o Software Livre através de palestras e demonstrações práticas veiculadas de forma gratuita para estudantes e demais interessados.


 
O temário desta edição será composto por mais de 60 apresentações sobre diversos temas relacionados ao Software Livre. Dentre os palestrantes confirmados para esta edição teremos a presença dos Kernel Hackers da RedHat Luis Claudio Gonçalves, Fábio Olivé Leite e Douglas Landgraf, do criador do TinyCobol Rildo Praganado Global Support Engineer at Red Hat Carlos Maiolino e do Instrutor e Consultor da RedHat Marcelo Moreira de Mello.
>A programação final do evento e as inscrições para as 800 vagas disponíveis estarão disponíveis no site do evento à partir do dia 06/11. Não será cobrada inscrição em dinheiro, contudo cada participante é encorajado a doar dois quilogramas de alimentos não perecíveis que serão encaminhados à instituições de caridade pela Pastoral da PUC.

domingo, 1 de novembro de 2009

Dedicando uma CPU para processos específicos

Primeiramente, gostaria de agradecer a todos que têm me enviado emails solicitando posts e parabenizando o blog. Como prometido, nesse post irei demonstrar como podemos dedicar uma cpu para processos específicos.
A primeira configuração que precisamos fazer é, em tempo de boot passar o parâmetro isolcpus=  para isolarmos uma ou várias cpus do scheduler padrão, para assim enviarmos processos para esses cpu's isolados. 
No laptop que estou utilizando, tenho1 processador Dual Core, portanto o kernel reconhecerá os processadores com id 0 e 1. Como precisamos de pelo menos 1 processador para bootar a máquina, irei escolher o processador com o ID1 para ficar isolado do scheduler.

[root@mmello ~]# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mmello_vg0/lv.root
#          initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$trwxdaUZ$Ae.coXq5yTQQsLduydi6z0
title Red Hat Enterprise Linux Server (2.6.18-164.2.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-164.2.1.el5 ro root=/dev/mmello_vg0/lv.root rhgb quiet isolcpus=1
 
        initrd /initrd-2.6.18-164.2.1.el5.img 
 [root@mmello ~]# cat /proc/cmdline
ro root=/dev/mmello_vg0/lv.root rhgb quiet isolcpus=1

Configurado o GRub e inicializada a máquina, conforme evidências acima, podemos listar todos os processos da máquina. Os processos estarão atribuídos somente ao processador incluso no scheduler, no caso o CPU 0.
[root@mmello ~]# ps axo pid,comm,psr
  PID COMMAND         PSR
    1 init              0
    2 migration/0       0
    3 ksoftirqd/0       0
    4 watchdog/0        0
    5 migration/1       1
    6 ksoftirqd/1       1
    7 watchdog/1        1
    8 events/0          0
    9 events/1          1
   10 khelper           0
   11 kthread           0
   15 kblockd/0         0
   16 kblockd/1         1
   17 kacpid            0
  135 cqueue/0          0
  136 cqueue/1          1
  139 khubd             0
  141 kseriod           0
  208 pdflush           0
  209 pdflush           0
  210 kswapd0           0
  211 aio/0             0
  212 aio/1             1
  367 pccardd           0
  377 kpsmoused         0
  409 ata/0             0
  410 ata/1             1
  411 ata_aux           0
  415 scsi_eh_0         0
  416 scsi_eh_1         0
  417 scsi_eh_2         0
  418 scsi_eh_3         0
  425 kstriped          0
  438 ksnapd            0
  453 kjournald         0
  481 kauditd           0
  514 udevd             0
 1178 iwl3945/0         0
 1179 iwl3945/1         1
 1181 iwl3945           0
 1508 hd-audio0         0
 2061 kcryptd_io        0
 2062 kcryptd           0
 2071 kmpathd/0         0
 2072 kmpathd/1         1
 2073 kmpath_handlerd   0
 2162 kjournald         0
 2170 kjournald         0
 2175 kjournald         0
 2413 kondemand/0       0
 2414 kondemand/1       1
 2503 auditd            0
 2505 audispd           0
 2537 syslogd           0
 2540 klogd             0
 2576 portmap           0
 2606 rpciod/0          0
 2607 rpciod/1          1
 2614 rpc.idmapd        0
 2639 dbus-daemon       0
 2665 acpid             0
 2679 hald              0
 2680 hald-runner       0
 2687 hald-addon-acpi   0
 2694 hald-addon-keyb   0
 2703 hald-addon-keyb   0
 2706 hald-addon-keyb   0
 2709 hald-addon-keyb   0
 2715 hald-addon-stor   0
 2754 sshd              0
 2768 cupsd             0
 2769 cups-polld        0
 2784 xinetd            0
 2807 sendmail          0
 2815 sendmail          0
 2830 gpm               0
 2844 nasd              0
 2858 crond             0
 2890 xfs               0
 2917 atd               0
 2948 libvirtd          0
 2963 rhnsd             0
 3031 NetworkManager    0
 3054 wpa_supplicant    0
 3056 nm-system-setti   0
 3058 dnsmasq           0
 3072 smartd            0
 3098 mingetty          0
 3099 mingetty          0
 3102 mingetty          0
 3105 mingetty          0
 3120 mingetty          0
 3122 mingetty          0
 3123 gdm-binary        0
 3184 gdm-binary        0
 3186 gdm-rh-security   0
 3189 Xorg              0
 3237 yum-updatesd      0
 3239 gam_server        0
 3251 gnome-session     0
 3287 ssh-agent         0
 3316 dbus-launch       0
 3317 dbus-daemon       0
 3323 gconfd-2          0
 3326 gnome-keyring-d   0
 3328 gnome-settings-   0
 3348 metacity          0
 3352 gnome-panel       0
 3354 nautilus          0
 3355 gnome-volume-ma   0
 3357 bonobo-activati   0
 3360 pidgin            0
 3362 gnome-vfs-daemo   0
 3366 eggcups           0
 3376 bt-applet         0
 3380 nm-applet         0
 3385 puplet            0
 3400 escd              0
 3401 gnome-power-man   0
 3418 mapping-daemon    0
 3425 gweather-applet   0
 3427 wnck-applet       0
 3455 trashapplet       0
 3482 gam_server        0
 3501 stickynotes_app   0
 3504 mixer_applet2     0
 3506 clock-applet      0
 3511 pam-panel-icon    0
 3512 pam_timestamp_c   0
 3516 notification-ar   0
 3518 dhclient          0
 3551 gnome-screensav   0
 3566 gnome-terminal    0
 3568 gnome-pty-helpe   0
 3569 bash              0
 3595 su                0
 3598 bash              0
 3702 bash              0
 3741 run-mozilla.sh    0
 3766 firefox           0
 3803 npviewer.bin      0
 3822 bash              0
 3847 vim               0
 3849 su                0
 3852 bash              0
 3891 bash              0
 3918 su                0
 3921 bash              0
 3955 ps                0
[root@mmello ~]#

Obs.: Por mais que se isole um ou vários processadores do scheduler, alguns processos a nível de kernel-space já estarão alocados aguardando por tarefas user-space
Isolada a CPU1, podemos agora utilizar um mecanismo implementado pelo kernel que permite atribuir processos específicos para determinadas CPUs chamado de cpuset
Para utilizar a facilidade do cpuset, necessitamos primeiramente montar um sistema de arquivos especial no sistema do tipo cpuset que será utilizado para atribuirmos as tarefas. 
[root@mmello ~]# mkdir /cpuset
[root@mmello ~]# mount -t cpuset none /cpuset/
[root@mmello ~]# mount| grep cpuset
none on /cpuset type cpuset (rw)
[root@mmello ~]# ls /cpuset/
cpu_exclusive  mem_exclusive   memory_pressure          memory_spread_page  mems               sched_relax_domain_level
cpus           memory_migrate  memory_pressure_enabled  memory_spread_slab  notify_on_release  tasks
[root@mmello ~]#

    Cada conjunto cpuset é representado por um diretório do tipo cpuset que contém os alguns arquivos, dentre eles os principais: 
          * cpus: lista de CPU's no cpuset
          * mems: lista de Memory Nodes disponível no conjunto cpuset (basicamente a área de memória cache de cada processador). Em arquitetura NUMA, deve-se visualizar mais do que 1 área. 
          * tasks: lista dos processos (PID) atribuídos ao cpuset.
     Como o laptop que estou usando não possui NUMA, o conteúdo do arquivos mems exibirá somente 1 área de memória e o arquivo cpus exibirá os 2 processadores (cores) que possuo. Já o arquivo tasks irá reportar todos os processos das cpus 0 e 1.
    [root@mmello cpuset]# cat /cpuset/mems
    0
    [root@mmello cpuset]# cat /cpuset/cpus
    0-1
    [root@mmello cpuset]# wc -l /cpuset/tasks
    170 /cpuset/tasks
    [root@mmello cpuset]# 

    Para facilitar o gerenciamento dos processos por parte do administrador, iremos criar 1 diretório chamado cpu1 dentro do sistema de arquivos cpuset, que automaticamente será populado com os arquivos do cpuset.
    [root@mmello cpuset]# mkdir cpu1
    [root@mmello cpuset]# cd /cpuset/cpu1/
    [root@mmello cpu1]# ls
    cpu_exclusive  mem_exclusive   memory_pressure     memory_spread_slab  notify_on_release         tasks
    cpus           memory_migrate  memory_spread_page  mems                sched_relax_domain_level
    [root@mmello cpu1]#

    Os arquivos cpus, mems, tasks foram criados automaticamente, porém sem valor algum. É nesse ponto que iremos escolher qual CPU, área de memória (L2) e processos serão atribuídos para esse conjunto cpuset. 
    [root@mmello cpu1]# cat /cpuset/cpu1/cpus
    [root@mmello cpu1]# cat /cpuset/cpu1/mems
    [root@mmello cpu1]# cat /cpuset/cpu1/tasks
    [root@mmello cpu1]# echo 1 > /cpuset/cpu1/cpus
    [root@mmello cpu1]# echo 0 > /cpuset/cpu1/mems
    [root@mmello cpu1]# cat /cpuset/cpu1/cpus
    1
    [root@mmello cpu1]# cat /cpuset/cpu1/mems
    0
    [root@mmello cpu1]#


    Defimos acima que para esse conjunto cpuset iremos utilizar a CPU1 e a área de memória 0. Tudo que temos que fazer agora é enviar o(s) PID(s) do(s) processo(s) que queremos dedicar para a CPU1.  Para exemplificar, irei pegar 2 processos: init e vsftpd e verificar qual processador foi atríbuido originalmente pelo scheduler. 
     [root@mmello cpu1]# service vsftpd start
    Starting vsftpd for vsftpd:                                [  OK  ]
    [root@mmello cpu1]# ps axo pid,comm,psr | grep -e COMMAND -e init -e vsftpd
      PID COMMAND         PSR
        1 init                    0
     4328 vsftpd            0
    [root@mmello cpu1]#

    Como podemos constatar, o scheduler atribuiu o CPU0 para as 2 tarefas. O que faremos agora é dedicar a CPU1 para os processos init e vsftpd.
    [root@mmello cpu1]# echo $(pidof init) > /cpuset/cpu1/tasks
    [root@mmello cpu1]# echo $(pidof vsftpd) > /cpuset/cpu1/tasks
    [root@mmello cpu1]# ps axo pid,comm,psr | grep -e COMMAND -e init -e vsftpd
      PID COMMAND         PSR
        1 init                    1
     4328 vsftpd            1
    [root@mmello cpu1]#


    Pronto!!! Os processos init e vsftpd já estão rodando exclusivamente na CPU1. Outro recurso interessante do cpuset é que se o processo trabalhar com FORK, o processo filho irá herdar a cpu dedicada do processo pai, como no caso do vsftpd.
    [marcelo@mmello ~]$ ftp localhost
    Connected to localhost.localdomain.
    220 (vsFTPd 2.0.5)
    530 Please login with USER and PASS.
    530 Please login with USER and PASS.
    KERBEROS_V4 rejected as an authentication type
    Name (localhost:marcelo): ftp
    331 Please specify the password.
    Password:
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp>

    Em outro terminal:

    [root@mmello cpu1]# ps axo pid,comm,psr | grep -e COMMAND -e init -e vsftpd
      PID COMMAND         PSR
        1 init                    1
     4328 vsftpd            1
     4352 vsftpd            1

    A cada novo processo, o scheduler sempre irá atribuir a CPU0, afinal é a única CPU disponível (lembrem-se que isolamos a CPU1 do scheduler com o parâmetro isolcpus=1). Assim sendo, é extremamente recomendado a criação de um script que obtenha o PID do processo à ser isolado e envie para o conjunto cpuset desejado. Outra consideração também é que os diretórios criados dentro do /cpuset não são persistentes e portanto precisam ser recriados a cada reboot.

    Grande abraço!!!!!

    sábado, 24 de outubro de 2009

    Ativando e Desativando CPU's sob demanda

    Olá pessoal,
    Após 1 semana sem escrever algum post (semana corrida) hoje irei demonstrar como podemos ativar ou desativar CPU's sob demanda no seu linux.
    Antes de começarmos, necessitamos checar se o kernel utilizado tem suporte a CPU Hotplug ( o kernel do Red Hat Entreprise Linux e o Fedora 11 tem).
    [root@mmello boot]# grep HOTPLUG config-2.6.18-164.el5   | grep -v PCI
    CONFIG_HOTPLUG=y
    CONFIG_HOTPLUG_CPU=y
    CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
    CONFIG_ACPI_HOTPLUG_CPU=y
    [root@mmello boot]# uname -a
    Linux mmello.gru.redhat.com 2.6.18-164.2.1.el5xen #1 SMP Mon Sep 21 04:52:16 EDT 2009 i686 i686 i386 GNU/Linux
    [root@mmello boot]#

    Pronto!!! Se seu kernel tem esse suporte, podemos começar a brincar com as CPU's, entretanto se o kernel utilizado não tem suporte, você pode adicionar o suporte.
    Q: How to i enable my kernel to support CPU hotplug?
    A: When doing make defconfig, Enable CPU hotplug support

       "Processor type and Features" -> Support for Hotpluggable CPUs
       Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
    You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support as well.
    Fonte: /usr/share/doc/kernel-doc-*/Documentation/cpu-hotplug.txt
     Visualizando a quantidade de CPUs utilizados no momento: 
    [root@mmello cpu]# cd /sys/devices/system/cpu/
    [root@mmello cpu]# ls
    cpu0  cpu1
    [root@mmello cpu]# cat /proc/cpuinfo  | grep -e processor -e "model name"
    processor       : 0
    model name      : Genuine Intel(R) CPU           T2400  @ 1.83GHz
    processor       : 1
    model name      : Genuine Intel(R) CPU           T2400  @ 1.83GHz
    [root@mmello cpu]#

    [root@mmello cpu]# cat /proc/interrupts
               CPU0              CPU1             
      1:      15838          0        Phys-irq  i8042
      8:          1          0        Phys-irq  rtc
      9:      15563          0        Phys-irq  acpi
     12:    1419340          0        Phys-irq  i8042
     14:     196343          0        Phys-irq  ide0
     16:          2          0        Phys-irq  yenta, uhci_hcd:usb2, radeon@pci:0000:01:00.0
     21:         27          0        Phys-irq  ehci_hcd:usb1, uhci_hcd:usb5
     22:       1635          0        Phys-irq  uhci_hcd:usb3, HDA Intel
     23:          0          0        Phys-irq  uhci_hcd:usb4
    248:     563615       4974        Phys-irq  iwl3945
    249:      11012          0        Phys-irq  peth0
    250:     111120          0        Phys-irq  ahci
    256:    3211767          0     Dynamic-irq  timer0
    257:     456846          0     Dynamic-irq  resched0
    258:         51          0     Dynamic-irq  callfunc0
    259:          0     725421     Dynamic-irq  resched1
    260:          0        123     Dynamic-irq  callfunc1
    261:          0    1709771     Dynamic-irq  timer1
    262:        771          0     Dynamic-irq  xenbus
    263:          0          0     Dynamic-irq  console
    264:          2          0     Dynamic-irq  vif1.0
    265:          1          0     Dynamic-irq  blkif-backend
    NMI:          0          0
    LOC:          0          0
    ERR:          0
    MIS:          0

     Como podemos perceber, dentro do diretório /sys/devices/system/cpu existem 2 diretórios (cpu0 e cpu1) que na verdade refletem a quantidade de CPU's reconhecida pelo kernel.
    Um detalhe interessante é que dentro do diretório /sys/devices/system/cpu/cpu0 não existe o arquivo online, pois a CPU0 é utilizada para iniciar outros componentes de hardware.
    [root@mmello cpu0]# pwd
    /sys/devices/system/cpu/cpu0
    [root@mmello cpu0]# ls
    cache  cpufreq  crash_notes  topology
    [root@mmello cpu0]# cd ../cpu1/
    [root@mmello cpu1]# ls
    cache  cpufreq  crash_notes  online  topology
    [root@mmello cpu1]#

    Para desligar a CPU, basta alterarmos o valor do arquivo online e o kernel irá desligar essa CPU sendo totalmente ignorada pelo sistema.
    [root@mmello cpu1]# pwd
    /sys/devices/system/cpu/cpu1
    [root@mmello cpu1]# ls
    cache  cpufreq  crash_notes  online  topology
    [root@mmello cpu1]# cat online
    1
    [root@mmello cpu1]# echo 0 > online
    [root@mmello cpu1]# cat /proc/cpuinfo  | grep -e processor -e "model name"
    processor       : 0
    model name      : Genuine Intel(R) CPU           T2400  @ 1.83GHz
    [root@mmello cpu1]# cat /proc/interrupts
               CPU0             
      1:      18028        Phys-irq  i8042
      8:          1        Phys-irq  rtc
      9:      15808        Phys-irq  acpi
     12:    1459630        Phys-irq  i8042
     14:     199799        Phys-irq  ide0
     16:          2        Phys-irq  yenta, uhci_hcd:usb2, radeon@pci:0000:01:00.0
     21:         27        Phys-irq  ehci_hcd:usb1, uhci_hcd:usb5
     22:       1657        Phys-irq  uhci_hcd:usb3, HDA Intel
     23:          0        Phys-irq  uhci_hcd:usb4
    248:     572614        Phys-irq  iwl3945
    249:      11206        Phys-irq  peth0
    250:     111818        Phys-irq  ahci
    256:    3282320     Dynamic-irq  timer0
    257:     479545     Dynamic-irq  resched0
    258:         51     Dynamic-irq  callfunc0
    262:        771     Dynamic-irq  xenbus
    263:          0     Dynamic-irq  console
    264:          2     Dynamic-irq  vif1.0
    265:          1     Dynamic-irq  blkif-backend
    NMI:          0
    LOC:          0
    ERR:          0
    MIS:          0
    [root@mmello cpu1]#


    Agora sim!!! :)  O kernel esta reconhecendo somente 1 processador (core) em meu sistema e fez o recálculo das IRQ's e dos processos para serem executados somente pela CPU0.
    Para habilitar novamente a CPU1, basta alterar o arquivo online para 1.
    [root@mmello cpu1]# pwd
    /sys/devices/system/cpu/cpu1
    [root@mmello cpu1]# ls
    crash_notes  online
    [root@mmello cpu1]# cat online
    0
    [root@mmello cpu1]# echo 1 > online
    [root@mmello cpu1]# cat /proc/cpuinfo  | grep -e processor -e "model name"
    processor       : 0
    model name      : Genuine Intel(R) CPU           T2400  @ 1.83GHz
    processor       : 1
    model name      : Genuine Intel(R) CPU           T2400  @ 1.83GHz
    [root@mmello cpu1]# cat /proc/interrupts
               CPU0              CPU1             
      1:      19194          0        Phys-irq  i8042
      8:          1          0        Phys-irq  rtc
      9:      15923          0        Phys-irq  acpi
     12:    1467238          0        Phys-irq  i8042
     14:     201365          0        Phys-irq  ide0
     16:          2          0        Phys-irq  yenta, uhci_hcd:usb2, radeon@pci:0000:01:00.0
     21:         27          0        Phys-irq  ehci_hcd:usb1, uhci_hcd:usb5
     22:       1660          0        Phys-irq  uhci_hcd:usb3, HDA Intel
     23:          0          0        Phys-irq  uhci_hcd:usb4
    248:     576780       4974        Phys-irq  iwl3945
    249:      11294          0        Phys-irq  peth0
    250:     112381          0        Phys-irq  ahci
    256:    3316395          0     Dynamic-irq  timer0
    257:     480164          0     Dynamic-irq  resched0
    258:         51          0     Dynamic-irq  callfunc0
    259:          0     761653     Dynamic-irq  resched1
    260:          0        123     Dynamic-irq  callfunc1
    261:          0    1759641     Dynamic-irq  timer1
    262:        771          0     Dynamic-irq  xenbus
    263:          0          0     Dynamic-irq  console
    264:          2          0     Dynamic-irq  vif1.0
    265:          1          0     Dynamic-irq  blkif-backend
    NMI:          0          0
    LOC:          0          0
    ERR:          0
    MIS:          0
    [root@mmello cpu1]#

    No próximo post, demonstrarei como podemos dedicar algumas CPU's para tarefas/processos específicos no sistema, como por exemplo, executar o Oracle em um processador físico com exclusividade em uma máquina bi-processada por exemplo.

    Era isso aí!!!
    Abraços.

    sábado, 17 de outubro de 2009

    Utilizando o RPM como ferramenta de recovery e auditoria

    Olá pessoal,
    Depois de alguns dias, estou retornando com mais um post. Hoje, pretendo demonstrar como podemos utilizar o sistema RPM para recuperarmos permissões de arquivos e verificarmos quando um arquivo ou binário foi alterado no sistema.
    O RPM (Red Hat Package Manager) é uma ferramenta poderosa que nos permite não só instalar ou remover softwares, mas também verificar o estado de cada arquivo do sistema que foi oferecido por pacotes RPM.
    Quem nunca acidentalmente executou um chmod 777 -R / ou até mesmo um chown nobody:nobody -R / ?!?!  (é... esse eu peguei pesado, mas vale como exemplo :P )  Ou até mesmo se perguntou será que o binário /bin/ls foi alterado no servidor de produção!?!
    Podemos verificar as situações colocadas acima, utilizando o comando RPM com parâmetro --verify (V), que consiste em pesquisar no banco de dados do rpm (/var/lib/rpm) quais arquivos foram modificados desde a instalação do pacote.
     Se quiséssemos verificar se o binário /bin/ls foi alterado em nosso sistema, a primeira informação que precisamos adquirir será saber qual o pacote RPM que ofereceu o binário /bin/ls. Para isso, podemos:
    [root@mmello ~]# rpm -qf /bin/ls
    coreutils-5.97-12.1.el5

    Uma vez descoberto o pacote de origem do binário, podemos verificar se todos os arquivos oferecidos pelo pacote coreutils foram alterados desde a sua instalação na máquina.
    [root@mmello ~]# rpm -V coreutils
    [root@mmello ~]#
     
    A saída do comando acima nos mostrou que nenhum binário foi alterado no sistema desde a sua instalação.  O que iremos fazer agora é forçar um erro, isto é, substituir algum binário que foi instalado pelo pacote coreutils e fazer a verificação novamente.
    [root@mmello ~]# cp /bin/date  /bin/ls
    cp: overwrite `/bin/ls'? y
    [root@mmello ~]# ls
    Sat Oct 17 11:23:07 BRT 2009
    [root@mmello ~]#
     

    Pronto! Substituímos o binário /bin/ls pelo comando /bin/date e agora iremos refazer a checagem através do RPM.
    [root@mmello ~]# rpm -V coreutils
    S.5....T   /bin/ls
    [root@mmello ~]#

    A saída do comando nos mostrou que o  Size (S), o MD5 (5) e o Timestamp (T) foram alterados no binário /bin/ls desde a instalação. Podemos concluir se o MD5 do binário esta diferente logo o binário foi alterado. Para corrigirmos, teremos que reinstalar o RPM no sistema.
    [root@mmello ~]# rpm -ivh coreutils-5.97-12.1.el5.i386.rpm --replacepkgs
    warning: coreutils-5.97-12.1.el5.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
    Preparing...                ########################################### [100%]
       1:coreutils              ########################################### [100%]
    [root@mmello ~]# ls
    anaconda-ks.cfg                   install.log
    coreutils-5.97-12.1.el5.i386.rpm  install.log.syslog

    [root@mmello ~]# rpm -V coreutils
    [root@mmello ~]#
     

    Se quisessemos realizar uma checagem em todo os arquivos do sistema, podemos executar o comando rpm -Va 
    Esse recurso também é interessante para controlarmos mudanças em arquivos texto e gerenciarmos permissões e proprietários de arquivos.
    Primeiro, iremos verificar qual pacote RPM oferece o arquivo /etc/inittab e checar se quais arquivos foram alterados desde a  instalação do pacote.
     [root@mmello ~]# rpm -qf /etc/inittab
    initscripts-8.45.17.EL

    [root@mmello ~]# rpm -V initscripts
    ..5....T c /etc/inittab
    S.5....T c /etc/rc.d/rc.local
    [root@mmello ~]#

    Como podemos ver acima, o arquivo /etc/inittab teve o conteúdo alterado 5(MD5) e o T(Timestamp) e o arquivo /etc/rc.d/rc.local além do conteúdo, o tamanho  também foi alterado.
    Poderíamos piorar a situação, fazendo o seguinte: 
    [root@mmello ~]# ls -la /etc/inittab
    -rw-r--r-- 1 root root 1666 Oct 17 09:41 /etc/inittab
    [root@mmello ~]# chmod  777 /etc/inittab

    [root@mmello ~]# chown  nobody:nobody /etc/inittab
    [root@mmello ~]# ls -la /etc/inittab
    -rwxrwxrwx 1 nobody nobody 1666 Oct 17 09:41 /etc/inittab
     
    Se consultarmos agora, veremos que as permissões do arquivo foram alteradas M(Mode) bem como o proprietário U(User) e grupo G(Group).
    [root@mmello ~]# rpm -V initscripts
    .M5..UGT c /etc/inittab
    S.5....T c /etc/rc.d/rc.local
     
    Podemos usar o RPM para recuperar as permissões e proprietários dos arquivos chamando as opções --setperms e --setugids respectivamente.
    [root@mmello ~]# rpm -q initscripts --setperms
    [root@mmello ~]# ls -la /etc/inittab
    -rw-r--r-- 1 nobody nobody 1666 Oct 17 09:41 /etc/inittab
    [root@mmello ~]# rpm -V initscripts
    ..5..UGT c /etc/inittab
    S.5....T c /etc/rc.d/rc.local
    [root@mmello ~]# rpm -q initscripts --setugids
    [root@mmello ~]# ls -la /etc/inittab
    -rw-r--r-- 1 root root 1666 Oct 17 09:41 /etc/inittab
    [root@mmello ~]# rpm -V initscripts
    ..5....T c /etc/inittab
    S.5....T c /etc/rc.d/rc.local


    Como podemos ver, o RPM restaurou as permissões e proprietários originais do arquivo. Isto é, se um dia algum administrador descuidado executar chmod 777 -R / , você poderia executar o comando rpm -qa --setperms para recuperar todos os arquivos que originalmente foram criados por pacotes RPM.

    Acho que era isso aí.. ;)
    Abraços..

    segunda-feira, 12 de outubro de 2009

    Ataque de Dicionário com OpenSSL - Quebrando senhas

    Olá,
    Você já deve ter se perguntado: Como que o linux faz para autenticar um usuário no arquivo /etc/shadow?!?!
    Hoje vou mostrar como podemos utilizar o openssl para realizar um ataque de dicionário contra as senhas armazenadas no arquivo /etc/shadow.
    Primeiramente, irei setar a senha do usuário marcelo para finger. Coloquei finger?!?! Porque é uma palavra que está cadastrada no arquivo /usr/share/dict/linux.words que será o arquivo de dicionário que irei utilizar como fonte de senhas. 

    [root@mmello ~]# echo finger | passwd --stdin marcelo
    Changing password for user marcelo.
    passwd: all authentication tokens updated successfully.

    Sim, podemos dizer que o arquivo /usr/share/dict/linux.words pode ser chamado de dicionário hacker, embora existam muito mais arquivos utilizados para essa finalidade e alguns com gigabytes de tamanho.
    Para quebrarmos a senha com sucesso, precisamos entender como funciona o campo de senha do arquivo /etc/shadow.

    [root@mmello ~]# grep marcelo /etc/shadow
    marcelo:$1$zFsqshA3$Sol9g2OAEwswwladdDCax0:14529:0:99999:7:::


    Note que o caracter $ é utilizado como separador de argumentos dentro do campo de senha.
    $1$ - Indica que estamos trabalhando com hashes em MD5. Algoritmos de MD5 são chamados de também de algoritmos de hash e possuem a característica de ser one-way, isto é, você fornece um arquivo ou uma string e ele gerará um conjunto de números (hash) que servirá como integridade do arquivo. Quando esse número for diferente, o arquivo ou a entrada foram alterados. One-way por você nunca irá pegar o hash gerado e converter novamente na entrada ou arquivo original.
     [root@mmello ~]# echo linux rocks | md5sum
    6453bea88e9acdd8d3ccead424063432  -
    [root@mmello ~]# echo Linux Rocks | md5sum
    9d96c752c61fd1f96ddce20ec0be1dd4  -

     
    $zFsqshA3$ - Campo destinado para o salt. Salt é uma string randomizada que é gerada no momento em que você cadastra a senha. Como trabalhamos com senhas com hash MD5, se não utilizássemos o salt, dois ou mais usuários que tivessem a mesma senha iriam ter o mesmo hash armazenado no arquivo /etc/shadow.
    $Sol9g2OAEwswwladdDCax0 - A senha do usuário. Esse campo é a composição da senha + salt | hash md5
    Vamos ao que interessa. Utilizaremos o comando openssl, chamando a função passwd para interpretar as informações do arquivo /etc/shadow e fazer um ataque de dicionário. 
    [root@mmello ~]# openssl  passwd --help
    Usage: passwd [options] [passwords]
    where options are
    -crypt             standard Unix password algorithm (default)
    -1                   MD5-based password algorithm
    -apr1              MD5-based password algorithm, Apache variant
    -salt string     use provided salt
    -in file            read passwords from file
    -stdin             read passwords from stdin
    -noverify        never verify when reading password from terminal
    -quiet             no warnings
    -table             format output as table
    -reverse         switch table columns


    Agrupando as informações:
    [root@mmello ~]# openssl  passwd -1 -salt 'zFsqshA3' -table -in /usr/share/dict/linux.words  | grep 'Sol9g2OAEwswwladdDCax0'
    finger  $1$zFsqshA3$Sol9g2OAEwswwladdDCax0


    Depois de 49 segundos, a senha do usuário foi descoberta.
    Faça o teste em seu servidor, teste a complexidade de sua senha e sempre lembre: Alterne ao máximo o caracteres de sua senha com números, caracteres especiais,  maiúsculas e minúsculas. 

    Grande abraço.

    Criando devices persistentes com udev

    Olá pessoal,

    Resolvi escrever o primeiro post desse blog, explicando como podemos utilizar o udev para criarmos dispositivos de maneira persistente em servidores linux.

    Para que vocês possam entender melhor em que situação vamos utilizá-lo vamos imaginar o seguinte cenário: como todo bom administrador, devemos nos preocupar com a realização de backups de maneira constante e isso não poderia ser diferente em sua estação de trabalho. Assim, você acaba de adquirir um HD externo via usb para realizar seus backups. Como esse HD é um dispositivo de armazenamento via usb, o kernel irá reconhece-lo através do módulo chamado usb_storage. Todo dispositivo  que é acessado via o módulo usb_storage, será reconhecido pelo kernel como se fosse um dispositivo SCSI ou SATA e por esse motivo acessado através  /dev/sd*.

    Baseando-se nessas informações, a ordem em que os dispositivos são conectados  é de suma importância para com os nomes que esses dispositivos irão receber, isto é, se já houver um dispositivo SCSI ou SATA na máquina e o HD for conectado, o kernel irá reconhece-lo como /dev/sdb, por outro lado, se já existirem 2 dispositivos e o HD for conectado, o kernel irá reconhece-lo como /dev/sdc.

    Sabendo dessas características, imaginemos aquele script de backup que você fez, para  sempre copiar os dados do seu diretório pessoa para esse HD (um script utilizando o rsync, e diga-se de passagem que é uma ótima ferramenta para sincronizar arquivos) como iremos garantir que o HD sempre será reconhecido como /dev/sdb1 ou até mesmo como /dev/bkp-disc por exemplo?

    Para isso, agora damos sentido e motivação para criarmos regras através do udev para reconhecimento dos dispositivos de maneira automática e persistente, de modo que a ordem em que o dispositivo for conectado no sistema não modifique o nome do dispositivo no sistema.

    No exemplo abaixo, irei utilizar o meu pendrive como dispositivo de armazenamento de dados e criar uma regra no udev para que o kernel sempre o reconheça através do dispositivo /dev/backup/pendrive-corsair.

    1) Reconhecendo o dispositivo:

    Para criarmos a regra, é importantíssimo a aquisição do máximo de informações possíveis sobre o dispositivo para que essas informações sejam combinadas com a finalidade de reconhecer esse dispositivo como único.  Para isso, poderemos utilizar informações como SYSFS{serial}, Model, Vendor, Label de cada dispositivo.

    Para a visualização das informações do dispositivo que serão utilizadas como base para a criação da regra, podemos utilizar o comando udevmonitor. Lembre-se de executar o comando antes de conectar o pendrive no sistema.

    [root@mmello ~]# udevmonitor
    udevmonitor prints the received event from the kernel [UEVENT]
    and the event which udev sends out after rule processing [UDEV]



    Com o udevmonitor em execução, conecte  o pendrive drive e teremos uma saída parecida com a abaixo:

    UEVENT[1255310436.834501] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5
    UEVENT[1255310436.834558] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/usbdev1.3_ep00
    UEVENT[1255310436.835214] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0
    UEVENT[1255310436.835258] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/usbdev1.3_ep81
    UEVENT[1255310436.835309] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/usbdev1.3_ep02
    UEVENT[1255310436.836472] add@/class/usb_device/usbdev1.3
    UDEV  [1255310436.836472] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5
    UDEV  [1255310437.067368] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/usbdev1.3_ep00
    UEVENT[1255310437.127863] add@/module/usb_storage
    UEVENT[1255310437.129329] add@/bus/usb/drivers/usb-storage
    UEVENT[1255310437.130821] add@/class/scsi_host/host4
    UDEV  [1255310437.147745] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0
    UDEV  [1255310437.352425] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/usbdev1.3_ep81
    UDEV  [1255310437.354021] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/usbdev1.3_ep02
    UDEV  [1255310437.372298] add@/class/scsi_host/host4
    UDEV  [1255310437.661869] add@/class/usb_device/usbdev1.3
    UEVENT[1255310442.132037] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/host4/target4:0:0/4:0:0:0
    UEVENT[1255310442.132079] add@/class/scsi_disk/4:0:0:0
    UEVENT[1255310442.196681] add@/block/sdb
    UEVENT[1255310442.196720] add@/block/sdb/sdb1
    UEVENT[1255310442.196760] add@/class/scsi_device/4:0:0:0
    UEVENT[1255310442.196797] add@/class/scsi_generic/sg1
    UDEV  [1255310442.300359] add@/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/host4/target4:0:0/4:0:0:0
    UDEV  [1255310442.527154] add@/class/scsi_generic/sg1
    UDEV  [1255310442.527193] add@/class/scsi_disk/4:0:0:0
    UDEV  [1255310442.543947] add@/block/sdb
    UDEV  [1255310442.710674] add@/class/scsi_device/4:0:0:0
    UDEV  [1255310442.902840] add@/block/sdb/sdb1
    UEVENT[1255310443.306232] add@/module/fat
    UEVENT[1255310443.335451] add@/module/vfat
    UEVENT[1255310443.339346] mount@/block/sdb/sdb1
    UDEV  [1255310443.340535] mount@/block/sdb/sdb1


    Na listagem gerada pelo udevmonitor acima, podemos notar desde o processo da identificação do dispositvo, a carga do módulo usb_storage, o nome do dispositivo que foi atribuído pelo kernel ao dispositivo e finalizando com a montagem do mesmo.

    A linha mais importante no momento é UEVENT[1255310442.196681] add@/block/sdb que informa como o kernel reconheceu e nomeou o dispositivo.

    O udev alimenta o SYSFS, isto é, se nos posicionarmos no diretório /sys/block/sdb teremos algumas informações sobre o pendrive conectado.

    [root@mmello sdb]# pwd
    /sys/block/sdb
    [root@mmello sdb]# ls
    dev  device  holders  queue  range  removable  sdb1  size  slaves  stat  subsystem  uevent
    [root@mmello sdb]#



    Para facilitar a localização de informações do dispositivo, podemos utilizar o comando udevinfo passando como argumento a localização do dispositivo reconhecido.

    [root@mmello sdb]# udevinfo  -a -p /block/sdb | less

    O comando acima listará uma série de informações sobre o dispositivo. Nosso trabalho agora é escolher algumas informações de modo com que quando combinadas, reconheçam o dispositivo como único no mundo, e o udev possa ajudar o kernel a reconhece-lo sempre pelo mesmo nome.  Escolhi essas informações:

    BUS=="usb"
    DRIVER=="usb"
    SYSFS{serial}=="A110000000026017"
    SYSFS{product}=="Flash Voyager"
    SYSFS{manufacturer}=="Corsair"



    2) Criando a regra

    Precisamos criar um arquivo dentro do diretório /etc/udev/rules.d, devemos respeitar 2 regras:

     a) o arquivo precisa iniciar com um número que indicará a ordem que o mesmo será processado;
     b) o arquivo precisa finalizar com a extensão .rules

    Retire o pendrive do computador, e vamos criar nossa regra:

    [root@mmello rules.d]# vim /etc/udev/rules.d/62-pendrive.rules

    DRIVER=="usb", SYSFS{serial}=="A110000000026017", SYSFS{product}=="Flash Voyager", SYSFS{manufacturer}=="Corsair", NAME="backup/pendrive-corsair", SYMLINK="pendrive-corsair"

    Na regra acima, mapeamos que sempre que conectado um dispositivo que for USB, o fabricante Corsair, o modelo Flash Voyager e com o serial A110000000026017 será criado o dispositivo /dev/backup/pendrive-corsair e com um link simbólico para /dev/pendrive-corsair.

    Para testarmos, salve o arquivo e digite o comando udevtrigger para recarregar as configurações do udev.

    Conecte o pendrive e pronto, sua regra já esta funcionando!!!

    [root@mmello rules.d]# ls -la /dev/backup/pendrive-corsair
    brw-r----- 1 root disk 8, 17 Oct 11 22:48 /dev/backup/pendrive-corsair

    [root@mmello rules.d]# ls -la /dev/pendrive-corsair
    lrwxrwxrwx 1 root root 23 Oct 11 22:48 /dev/pendrive-corsair -> backup/pendrive-corsair

    [root@mmello rules.d]# df -h /dev/backup/pendrive-corsair
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/backup/pendrive-corsair
                          1.9G   20K  1.9G   1% /media/mmello

    Ainda seria possível adicionar nessa regra os parâmetros OWNER, GROUP, MODE para personalizar as permissões do dispositivo.

    OWNER="user", GROUP="group", MODE="0755"

    Para maiores informações, man udev e consulte o diretório /usr/share/doc/udev-***/writing_udev_rules

    Grande abraço.

    domingo, 11 de outubro de 2009

    Bem Vindos!!!!

    lá pessoal,

    Já faz algum tempo que esse blog vem se ensaiando para sair do forno.. e eis que aqui estamos..

    Arrumei um tempo para criar a conta e deixar tudo pronto para começar alimentar esse blog com minhas experiências profissionais, pessoais e dividir um pouco alguns momentos com vocês...

    Enfim... bem-vindos...

    Abs.. e até breve...



    Gtalk: tchello.mello@gmail.com
    MSN: tchello.mello@gmail.com