Para obter essas informações de sysfs
para um arquivo de dispositivo, primeiro determine o número maior / menor observando a saída de ls -l
, por exemplo
$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Apr 17 12:26 /dev/sda
O 8, 0
nos informa que o número principal é 8
e o menor é 0
. O b
no início da listagem também nos diz que é um dispositivo de bloco. Outros dispositivos podem ter um c
para o dispositivo de caractere no início.
Se você olhar abaixo de /sys/dev
, verá que há dois diretórios. Um chamado block
e um chamado char
. O básico aqui é que eles são para dispositivos de bloco e caractere, respectivamente. Cada dispositivo é então acessível pelo seu maior / menor número é este diretório. Se houver um driver disponível para o dispositivo, ele poderá ser encontrado lendo o destino do link driver
neste ou no subdiretório device
. Por exemplo, para o meu /dev/sda
, posso simplesmente fazer:
$ readlink /sys/dev/block/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd
Isso mostra que o driver sd
é usado para o dispositivo. Se você não tiver certeza se o dispositivo é um dispositivo de bloco ou caractere, no shell você pode simplesmente substituir essa peça por um *
. Isso funciona da mesma maneira:
$ readlink /sys/dev/*/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd
Os dispositivos de bloco também podem ser acessados diretamente pelo nome por meio de /sys/block
ou /sys/class/block
. Por exemplo:
$ readlink /sys/block/sda/device/driver
../../../../../../../bus/scsi/drivers/sd
Note que a existência de vários diretórios em /sys
pode mudar dependendo da configuração do kernel. Além disso, nem todos os dispositivos têm uma subpasta device
. Por exemplo, esse é o caso de arquivos de dispositivos de partição como /dev/sda1
. Aqui você tem que acessar o dispositivo para todo o disco (infelizmente não há links sys
para isso).
Uma última coisa que pode ser útil é listar os drivers para todos os dispositivos para os quais eles estão disponíveis. Para isso, você pode usar globs para selecionar todos os diretórios nos quais os links do driver estão presentes. Por exemplo:
$ ls -l /sys/dev/*/*/device/driver ls -l /sys/dev/*/*/driver
ls: cannot access ls: No such file or directory
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/block/11:0/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:16/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/block/8:32/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:0/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:1024/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:128/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:256/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:384/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:512/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:513/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:514/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:640/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/189:643/driver -> ../../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:768/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 20:38 /sys/dev/char/189:896/driver -> ../../../../bus/usb/drivers/usb
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:1/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/char/21:2/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/21:3/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:0/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:1/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/250:2/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:0/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:1/device/driver -> ../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 12:27 /sys/dev/char/252:2/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/252:3/device/driver -> ../../../../../../../../../bus/scsi/drivers/sd
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/254:0/device/driver -> ../../../bus/pnp/drivers/rtc_cmos
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/29:0/device/driver -> ../../../bus/platform/drivers/simple-framebuffer
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:64/device/driver -> ../../../bus/pnp/drivers/serial
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:65/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:66/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 19:53 /sys/dev/char/4:67/device/driver -> ../../../bus/platform/drivers/serial8250
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/6:0/device/driver -> ../../../bus/pnp/drivers/parport_pc
lrwxrwxrwx 1 root root 0 Apr 17 12:26 /sys/dev/char/99:0/device/driver -> ../../../bus/pnp/drivers/parport_pc
Finalmente, para divergir um pouco da questão, adicionarei outro truque /sys
glob para obter uma perspectiva muito mais ampla sobre quais drivers estão sendo usados por quais dispositivos (embora não necessariamente aqueles com um arquivo de dispositivo):
find /sys/bus/*/drivers/* -maxdepth 1 -lname '*devices*' -ls
Atualizar
Examinando mais de perto a saída de udevadm
, parece funcionar encontrando o diretório canonical /sys
(como você faria se desreferenciasse os diretórios principal / secundário acima) e, então, subindo a árvore de diretórios. , imprimindo qualquer informação que encontrar. Dessa forma, você obtém informações sobre dispositivos pais e quaisquer drivers que eles usam também.
Para experimentar isso, escrevi o script abaixo para percorrer a árvore de diretórios e exibir informações em cada nível relevante. udev
parece procurar arquivos legíveis em cada nível, com seus nomes e conteúdos sendo incorporados em ATTRS
. Em vez de fazer isso, exibo o conteúdo dos arquivos uevent
em cada nível (aparentemente, a presença disso define um nível distinto, em vez de apenas um subdiretório). Também mostro o nome de base de quaisquer links de subsistema que eu encontre e isso mostrando como o dispositivo se encaixa nessa hierarquia. udevadm
não exibe as mesmas informações, portanto, essa é uma ferramenta complementar agradável. As informações do dispositivo pai (por exemplo, PCI
information) também são úteis se você quiser corresponder a saída de outras ferramentas como lshw
para dispositivos de nível superior.
#!/bin/bash
dev=$(readlink -m $1)
# test for block/character device
if [ -b "$dev" ]; then
mode=block
elif [ -c "$dev" ]; then
mode=char
else
echo "$dev is not a device file" >&2
exit 1
fi
# stat outputs major/minor in hex, convert to decimal
data=( $(stat -c '%t %T' $dev) ) || exit 2
major=$(( 0x${data[0]} ))
minor=$(( 0x${data[1]} ))
echo -e "Given device: $1"
echo -e "Canonical device: $dev"
echo -e "Major: $major"
echo -e "Minor: $minor\n"
# sometimes nodes have been created for devices that are not present
dir=$(readlink -f /sys/dev/$mode/$major\:$minor)
if ! [ -e "$dir" ]; then
echo "No /sys entry for $dev" >&2
exit 3
fi
# walk up the /sys hierarchy one directory at a time
# stop when there are three levels left
while [[ $dir == /*/*/* ]]; do
# it seems the directory is only of interest if there is a 'uevent' file
if [ -e "$dir/uevent" ]; then
echo "$dir:"
echo " Uevent:"
sed 's/^/ /' "$dir/uevent"
# check for subsystem link
if [ -d "$dir/subsystem" ]; then
subsystem=$(readlink -f "$dir/subsystem")
echo -e "\n Subsystem:\n ${subsystem##*/}"
fi
echo
fi
# strip a subdirectory
dir=${dir%/*}
done