udev

13
Detecção e ativação de dispositivos e a função do udev nesse processo Introdução Udev (Userspace devfs) é um sistema de arquivos presente desde o kernel 2.6 e substitui o devfs completamente. É responsável por gerenciar os arquivos de dispositivos do diretório /dev , criando e removendo os mesmos dinamicamente. O udev também tem função do hotplug, trabalhando em conjunto com o HAL (Hardware Abstraction Layer), adicionando os dispositivos conforme são instalados na máquina. Sem ele, seria impossível acessar seu pendrive, webcam e impressora, por exemplo, quando conectados. Funcionamento Entendendo como os dispositivos são detectados e adicionados no sistema GNU/Linux . O sistema GNU/Linux faz uso do kernel e de serviços para detectar e adicionar dispositivos ao sistema, para que os mesmos fiquem disponíveis para uso do usuário e do próprio sistema. Abaixo, é mostrada a hierarquia no processo de detecção e adição de dispositivos:

Upload: spyderlinuxrgm

Post on 28-Apr-2015

19 views

Category:

Documents


4 download

DESCRIPTION

funcionamento e regras

TRANSCRIPT

Page 1: udev

Detecção e ativação de dispositivos e a função do udev nesse processo

IntroduçãoUdev (Userspace devfs) é um sistema de arquivos presente desde o kernel 2.6 e substituio devfs completamente.

É responsável por gerenciar os arquivos de dispositivos do diretório /dev, criando e removendo os mesmosdinamicamente. O udev também tem função do hotplug, trabalhando em conjunto com o HAL (HardwareAbstraction Layer), adicionando os dispositivos conforme são instalados na máquina. Sem ele, seria impossívelacessar seu pendrive, webcam e impressora, por exemplo, quando conectados.

FuncionamentoEntendendo como os dispositivos são detectados e adicionados no sistema GNU/Linux.

O sistema GNU/Linux faz uso do kernel e de serviços para detectar e adicionar dispositivos ao sistema, paraque os mesmos fiquem disponíveis para uso do usuário e do próprio sistema.

Abaixo, é mostrada a hierarquia no processo de detecção e adição de dispositivos:

Page 2: udev

Como visto na figura acima, existe todo um processo até os dispositivos estarem disponíveis para uso do sistemae/ou usuários, que vai desde a detecção do device pelo kernel até a criação de um arquivo de dispositivo nodiretório /dev pelo udev.

Todo processo começa com o kernel detectando os dispositivos e exportando informações sobre os mesmospara o sistema de arquivos virtual Sysfs (que está montado no diretório /sys) e ao mesmo tempo, enviando umevento para o daemon do serviço udev.

O evento informa ao udev uma ação no dispositivo, esta ação pode ser um adição, remoção ou alteração de umdispositivo conectado à máquina.

Quando o udev é informado pelo kernel sobre o evento, trata de usar as informações do diretório /sys paraidentificar o device conectado, carregar o módulo correto e criar um arquivo especial no diretório /dev comexceção da placa de rede que é tratada no kernel.

Aí você pergunta: E o HAL?

Simples, o HAL é um serviço que informa aos programas do sistema se um dispositivo está disponível, foialterado ou removido a todo tempo.

Page 3: udev

Na verdade, o HAL já não é essencial para este trabalho, pois algumas distribuições atualmente, conseguemfazer todo este trabalho somente pelo udev, ou em conjunto com o serviço D­Bus. No entanto, para outrasdistribuições, isso torna­se essencial.

É importante destacar que todo este processo de detectar e ativar os devices explicado anteriormente, não sóacontece em Hotplug, ou seja, os dispositivos são instalados com o sistema em uso, mas também em Coldplug,os dispositivos são conectados (instalados) com a máquina desligada e o sistema, quando em uso, detecta­os.

Observe que quem realmente faz o trabalho de hotplug, é o udev.

Os arquivos de dispositivos criados no diretório /dev nada mais são que arquivos especiais, obtidos pelacombinação de dois endereços do kernel, um chamado de major number e outro de minor number.

Sendo que:

major number → É usado para identificar uma categoria de dispositivos.minor number → Identifica o dispositivo.

Veja na figura abaixo, um exemplo destes números:

Hierarquia dos dispositivos e chaves do udev

Hierarquia dos dispositivosAntes de começar a trabalhar com regras no udev, é necessário saber como o kernel representa os dispositivosem sua estrutura. O kernel do Linux organiza e representa os dispositivos conectados à máquina em uma

Page 4: udev

em sua estrutura. O kernel do Linux organiza e representa os dispositivos conectados à máquina em umaestrutura de árvore, ou seja, existe uma hierarquia onde cada device é "filho" de um device "pai".

Toda esta estrutura está exposta no diretório /sys contendo informações de cada device. Para poder ter maisdetalhes sobre os devices, use o comando udevadm e poderá ver todas as chaves dos dispositivos.

Veja o exemplo do arquivo de dispositivo /dev/usb/lp0 da minha máquina, que representa a impressora,rodando o comando abaixo como root:

# udevadm info ­a ­p $(sudo udevadm info ­q path ­n /dev/usb/lp0)

A saída do comando mostra bem a organização e hierarquia do device. Sendo que /dev/usb/lp0 é filho dodevice "usb", e neste device o kernel nomeia­o de "lp0", justamente o nome dado pelo udev, que por sua vez éfilho do device pai, também chamado de "usb" e o kernel nomeia­o de "2­2:1.1", carregando o driver "usblp",que por sua vez é filho do device "pci" e o kernel nomeia­o neste subsistema de "0000:00:1d.0", carregando odriver "uhci_hcd".

Veja o exemplo do arquivo de dispositivo /dev/sda que representa o primeiro disco rígido da minha máquina:

# udevadm info ­a ­p $(sudo udevadm info ­q path ­n /dev/sda)

Page 5: udev

O device /dev/sda nesta hierarquia, é filho do device "block", ou seja, é um dispositivo de bloco e o kernelnomeia­o de "sda", que por sua vez, é filho do device chamado de "scsi", e o kernel nomeia­o de "0:0:0:0",carregando o driver "sd", que por sua vez é filho do device chamado também de "scsi", e o kernel nomeia­o de"target0:0:0".

Observe que, na hierarquia mostrada na saída do comando udevadm, os devices de baixo são pais dos de cima"filhos".

As chaves do udevChaves no udev são informações de dispositivos e podem ser classificadas em dois tipos, existindo as chaves decombinação e de atributos. Ambas serão abordadas a seguir, e o seu uso torna­se necessário para aplicar asregras do udev.

As chaves de combinação mais usadas, são as listadas abaixo:

KERNEL → Esta chave informa o nome atribuído pelo kernel ao dispositivo em questão;SUBSYSTEM → Chave que informa o tipo de dispositivo, seja o dispositivo pai ou filho;DRIVER → Chave que informa o driver para o dispositivo;ATTR → Esta chave tem informações adicionais sobre o dispositivo;OWNER → Usuário que será o proprietário do dispositivo criado no /dev;GROUP → Grupo do dispositivo criado no /dev;MODE → Atribui a umask padrão para o dispositivo criado em /dev.

Além das chaves de combinação já vistas, é possível usar outras descritas abaixo:

Page 6: udev

NAME → Esta chave contém o nome que será usado para o dispositivo;SYMLINK → Nesta chave, configura­se um link simbólico;RUN → Adiciona um programa que será executado;ACTION → Ação do evento do dispositivo, se o dispositivo está sendo conectado, removido oualterado.

Chaves de combinação KERNELS, SUBSYSTEMS e DRIVERS, contêm informações similares às chaves decombinação apresentadas acima, no entanto, estas chaves de combinação são usadas em dispositivos pais(parent devices).

As chaves de atributo ATTR, contêm informação adicional a um dispositivo e a chave de atributo ATTRS ésimilar a ATTR, no entanto, é usada em devices pais (parent devices).

A observação é que em uma regra, não pode ser atribuído mais de uma chave de atributo e/ou de combinaçãode dispositivos "pai" (device parent) junto à chave de combinação "filho" e nem combinar chaves de atributos dediferentes dispositivos pais em um único dispositivo pai. Caso isso aconteça, a regra não irá funcionar.

Para a regra funcionar, podemos colocar uma ou mais chaves de combinação "filho" seguida de uma chave deatributo ou de combinação "pai" na mesma regra e/ou, caso queira atribuir mais de uma chave de atributo "pai", énecessário informar o dispositivo a qual ela pertence, basta usar a chave de combinação "pai" SUBSYSTEMS.

Se ficou confuso, na próxima página irei exemplificar para ter um melhor entendimento.

Para aplicar as regras, além das chaves já mencionadas, podemos fazer uso de strings e é necessário usaroperadores. Veja abaixo as strings e operadores que podemos usar.

Strings que podem ser usadas nas regras:

* → Corresponde a tudo naquela posição (é similar ao coringa asterisco).? → Qualquer caractere naquela posição.[] → Corresponde a qualquer caractere especificado dentro dos colchetes.

Por exemplo, a sequência de caracteres 'tty[SR]' iria corresponder tanto 'ttyS' quanto a 'ttyR'. Você podetambém especificar intervalos usando a faixa através do caractere '­'. Se o primeiro caractere após o '[' éum '!', há uma exceção.

Operadores mais usados nas regras:

== → Compara se é igual (atribui uma valor de igualdade);!= → Compara se é diferente (atribui um valor de diferença);= → Atribui um valor à chave (é usado quando se quer mudar o nome do device, por exemplo);+= → Adiciona um valor à chave e pode manter uma lista de entradas ­ Pode, por exemplo, usar nachave RUN e especificar vários comandos.

Page 7: udev

Depois de toda esta explicação, vamos começar a aplicar as regras na próxima página.

Regras do udev

O udev é muito poderoso quanto à aplicação das regras, pois permite desde nomear um dispositivo até executaraplicações, e/ou scripts quando conectamos ou desconectamos, ou quando o dispositivo é alterado.

Para aplicar tais regras, é necessário ter informações obtidas através das chaves de cada device.

Os arquivos que contém as regras do udev estão contidos no diretório /etc/udev/rules.d e devem ter a extensão".rules", caso algum arquivo dentro do diretório não use essa extensão, o seu conteúdo não será processado.

Eles são lidos em ordem numérico alfabética, por exemplo: se dentro do diretório /etc/udev/rules.d, temos osarquivos "025_usb­ regras.rules" e "035_usb­regras.rules", o arquivo "025_usb­regras.rules" será lido antes queo "035_usb­regras.rules".

Agora, sintaxe das regras e exemplos de regras que funcionam e não funcionam.

Cada arquivo com extensão ".rules" tem regras que seguem a seguinte sintaxe:

<chave de combinação>, <chave de combinação e ou chave de atributo>, <Ação>

Page 8: udev

Para obter as informações de cada chave dos devices, usamos o comando udevadm para pegar um relatório.

Não vou entrar em detalhes de uso do comando, mas deixo o link para o manual:

http://linux.die.net/man/8/udevadm

Será usado, para extrair o relatório, a opção "info" que é utilizada para obter informações e "­p", que indica alocalização do dispositivo, e "­a" irá listar informações das propriedades do dispositivo.

Vou listar as propriedades do arquivo de dispositivo /dev/sdc1 que é meu pendrive da SanDisk, usando ocomando udevadm como root:

# udevadm info ­a ­p $(udevadm info ­q path ­n /dev/sdc1)

looking at device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0/block/sdc/sdc1': KERNEL=="sdc1" SUBSYSTEM=="block" DRIVER=="" ATTRpartition=="1" ATTRstart=="2048" ATTRsize=="7852032" ATTRro=="0" ATTRalignment_offset=="0" ATTRdiscard_alignment=="0" ATTRstat==" 54 112 426 36 5 1 48 0 0 36 36" ATTRinflight==" 0 0" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0/block/sdc': KERNELS=="sdc" SUBSYSTEMS=="block" DRIVERS=="" ATTRSrange=="16" ATTRSext_range=="256" ATTRSremovable=="1" ATTRSro=="0" ATTRSsize=="7856127" ATTRSalignment_offset=="0" ATTRSdiscard_alignment=="0" ATTRScapability=="51" ATTRSstat==" 251 1491 2002 216 5 1 48 0 0 216 216" ATTRSinflight==" 0 0" ATTRSevents=="media_change" ATTRSevents_async=="" ATTRSevents_poll_msecs=="-1" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0':

Page 9: udev

KERNELS=="4:0:0:0" SUBSYSTEMS=="scsi" DRIVERS=="sd" ATTRSdevice_blocked=="0" ATTRStype=="0" ATTRSscsi_level=="0" ATTRSvendor=="SanDisk " ATTRSmodel=="Cruzer Blade" ATTRSrev=="8.02" ATTRSstate=="running" ATTRStimeout=="30" ATTRSiocounterbits=="32" ATTRSiorequest_cnt=="0x2763" ATTRSiodone_cnt=="0x2763" ATTRSioerr_cnt=="0x19" ATTRSmodalias=="scsi:t-0x00" ATTRSevt_media_change=="0" ATTRSqueue_depth=="1" ATTRSqueue_type=="none" ATTRSmax_sectors=="240" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0': KERNELS=="target4:0:0" SUBSYSTEMS=="scsi" DRIVERS=="" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4': KERNELS=="host4" SUBSYSTEMS=="scsi" DRIVERS=="" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0': KERNELS=="1-8:1.0" SUBSYSTEMS=="usb" DRIVERS=="usb-storage" ATTRSbInterfaceNumber=="00" ATTRSbAlternateSetting==" 0" ATTRSbNumEndpoints=="02" ATTRSbInterfaceClass=="08" ATTRSbInterfaceSubClass=="06" ATTRSbInterfaceProtocol=="50" ATTRSmodalias=="usb:v0781p5567d0200dc00dsc00dp00ic08isc06ip50" ATTRSsupports_autosuspend=="1"

Veja que não postei toda a saída do comando pois é muito longa. Agora, abaixo mostro duas regras:

ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd??", ATTRSvendor=="SanDisk",DRIVERS=="usb­storage", SYMLINK+="PENDRIVE"ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd??", ATTRSvendor=="SanDisk",SYMLINK+="PENDRIVE"

Page 10: udev

Ambas as regras têm a ação de criar um link para a partição do pendrive. No entanto, somente a segunda regrairá funcionar.

Explicação da primeira regra:

1º → É conferido se o dispositivo que está sendo conectado;2º → É conferido se o dispositivo conectado é do tipo bloco (armazenamento), ou seja, se filho dodispositivo de bloco;3º → É conferido se o nome do dispositivo atribuído pelo kernel na chave de combinação KERNEL"filho" é igual a o informado na regra;4º → Verifica em um dos atributos "pais" se existe o atributo com valor SanDisk, isso garante que a regrasó será executada se o pendrive for do fabricante SanDisk;5º → Verifica se o driver carregado em um dos devices parents é igual ao especificado;6º → Caso tudo esteja certo na regra, o link chamado PENDRIVE é atribuído à partição do pendrive.

Mesmo toda informação conferindo na primeira regra, não pode funcionar, pois foi atribuído junto à chave decombinação do dispositivo filho (como já foi informado na segunda página), uma chave de atributo (ATTRS) eoutra de combinação (DRIVERS) de dispositivos "pais".

Deixo mais uma vez claro, que a regra não irá funcionar caso seja atribuído mais de uma chave de atributo ou decombinação de um parent device junto à uma chave de combinação de um device filho.

A segunda regra tem quase todos as chaves da primeira regra, com exceção da chave de combinaçãoDRIVERS de um dispositivo pai. E esta regra irá funcionar por que apenas uma chave, seja de atributo ou decombinação (no exemplo, uma foi de atributo) de dispositivo pai está atribuída junto às chaves de combinaçãodo dispositivo filho que são ACTION, SUBSYSTEM e KERNEL.

Agora, veja um exemplo de regra usada para executar um script:

ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd??", SUBSYSTEMS=="usb",RUN+="/usr/local/bin/usb­mount.sh"

Veja que esta regra é similar às duas mostradas anteriormente. No entanto, o valor atribuído à chave decombinação SUBSYSTEM do dispositivo filho, indica que deve ser aplicada a um dispositivo de bloco, ou seja,de armazenamento.

E a chave de combinação (do device parent) SUBSYSTEMS, indica que a regra só será aplicada a dispositivospais do tipo USB; dessa forma, a regra só será aplicada a um pendrive, HD externo e/ou cartão de memória, enão a discos rígidos internos, por exemplo.

Veja abaixo, o conteúdo do script /usr/local/bin/usb­mount.sh:

Page 11: udev

#!/bin/bashusb="/dev/"$(ls -1 /sys/block/"$(ls -1 /sys/block |grep sd |tail-1)" |grep sd |tail -1)""tipo=$(blkid -o list "$usb" |awk -F" " 'print $2' |tail -1)label=$(blkid -o list "$usb" |awk -F" " 'print $3' |tail -1)dir="/media/"$label""[ -d "$dir" ]&& sleep 1 || mkdir "$dir"if [ "$tipo" = "ext3" ];thenmount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"elif [ "$tipo" = "ext4" ];thenmount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"elif [ "$tipo" = "vfat" ];thenmount -t "$tipo" -orelatime,noexec,rw,user,umask=0022,uid=1000,gid=1000 "$usb" "$dir"elif [ "$tipo" = "ntfs" ];thenmount -t ntfs-3g -orelatime,noexec,rw,user,umask=0022,uid=1000,gid=1000 "$usb" "$dir"elif [ "$tipo" = "xfs" ];thenmount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"elif [ "$tipo" = "jfs" ];thenmount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"elif [ "$tipo" = "btrfs" ];thenmount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"fi

A finalidade do script é montar o pendrive, HD externo ou cartões de memória desabilitando a execução deexecutáveis, dando mais segurança quando "espetar" um destes dispositivos na máquina (afinal, nunca se sabe oque pode ter em um HD externo ou pendrive de alguém, não é verdade?) evitando a execução de vírus e outraspragas.

Podemos também renomear dispositivos como placas de rede. Para ver como fazer isso, veja a saída docomando udevadm para o dispositivo Wlan0 e em seguida, irei mostrar uma regra para isso:

# udevadm info ­a ­p /sys/class/net/wlan0

looking at device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/net/wlan0': KERNEL=="wlan0" SUBSYSTEM=="net" DRIVER=="" ATTRaddr_assign_type=="0" ATTRaddr_len=="6" ATTRdev_id=="0x0" ATTRifalias=="" ATTRiflink=="5" ATTRifindex=="5" ATTRtype=="1"

Page 12: udev

ATTRlink_mode=="1" ATTRaddress=="00:1a:3f:7c:2e:f4" ATTRbroadcast=="ff:ff:ff:ff:ff:ff" ATTRcarrier=="0" ATTRdormant=="0" ATTRoperstate=="down" ATTRmtu=="1500" ATTRflags=="0x1003" ATTRtx_queue_len=="1000" ATTRnetdev_group=="0" looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0': KERNELS=="1-8:1.0" SUBSYSTEMS=="usb" DRIVERS=="ath9k_htc" ATTRSbInterfaceNumber=="00" ATTRSbAlternateSetting==" 0" ATTRSbNumEndpoints=="06" ATTRSbInterfaceClass=="ff" ATTRSbInterfaceSubClass=="00" ATTRSbInterfaceProtocol=="00" ATTRSmodalias=="usb:v0CF3p7015d0202dcFFdscFFdpFFicFFisc00ip00" ATTRSsupports_autosuspend=="0"

O adaptador USB está recebendo este nome de "wlan0" porque, quando o sistema o detectou, o udev atribuiu aregra abaixo:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTRaddress=="00:1a:3f:7c:2e:f4",ATTRdev_id=="0x0", ATTRtype=="1", KERNEL=="wlan*", NAME="wlan0"

Mas, com estas informações da saída do comando udevadm podemos mudar o nome do device para, porexemplo, Wireless0 como mostra a regra abaixo:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTRaddress=="00:1a:3f:7c:2e:f4",ATTRdev_id=="0x0", ATTRtype=="1", KERNEL=="*", NAME="wireless0"

Explicando a regra:

1º → É verificado se o dispositivo filho conectado é do tipo net (rede);2º → Verifica se o dispositivo acabou de se conectado;3º → Na chave de combinação DRIVERS informa que pode ser usado qualquer driver para o respectivodevice parent;4º → Na chave de atributo ATTRaddress é verificado o endereço MAC address do device;5º e 6º → São verificados mais duas chaves de atributos da mesma (note que ambas foram atribuídasjunto ao dispositivo filho, por isso a regra funciona);7º → Na chave KERNEL é verificado qual o nome atribuído pelo kernel, no exemplo informei que pode

Page 13: udev

ser qualquer um;8º → Na última chave de combinação informei o novo nome do dispositivo que é wireless0.

Podemos fazer muitas personalizações, além das quais já foram mostradas, podemos, por exemplo, automatizarum processo de backup toda vez que o dispositivo for conectado à máquina de forma similar à regra acima, queexecuta um script.

Após aplicar uma regra em um dos arquivos com extensão ".rules", torna­se necessário reiniciar o serviço doudev para as alterações entrarem em vigor (pelo menos nas distribuições Debian e CentOS, por exemplo).

ReferênciasBuilt­in persistent naming schemes « www.reactivated.netudev(7)­Linux man page « linux.die.netDispositivos e sistemas de arquivos « www.linuxnewmedia.com.br