No Linux, dado:
- um dispositivo, por exemplo
/dev/sda
, - e seus números maiores e menores, por exemplo
8, 0
,
como posso saber qual módulo / driver está "dirigindo" isso?
Posso cavar /sys
ou /proc
descobrir isso?
No Linux, dado:
/dev/sda
,8, 0
,como posso saber qual módulo / driver está "dirigindo" isso?
Posso cavar /sys
ou /proc
descobrir isso?
Respostas:
Para obter essas informações de sysfs
um arquivo de dispositivo, primeiro determine o número principal / secundário 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 diz 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
dispositivo para caracteres no início.
Se você olhar para baixo /sys/dev
, verá dois diretórios. Um chamado block
e um chamado char
. O acéfalo aqui é que estes são para dispositivos de blocos e caracteres, respectivamente. Cada dispositivo é então acessível por seu número maior / menor neste diretório. Se houver um driver disponível para o dispositivo, ele pode ser encontrado lendo o destino do driver
link neste ou no device
subdiretório. Por exemplo, para o meu /dev/sda
eu posso simplesmente fazer:
$ readlink /sys/dev/block/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd
Isso mostra que o sd
driver é 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 esta peça por uma *
. Isso funciona tão bem:
$ readlink /sys/dev/*/8\:0/device/driver
../../../../../../../bus/scsi/drivers/sd
Os dispositivos de bloco também podem ser acessados diretamente por meio de seus nomes, por meio de /sys/block
ou /sys/class/block
. Por exemplo:
$ readlink /sys/block/sda/device/driver
../../../../../../../bus/scsi/drivers/sd
Observe que a existência de vários diretórios /sys
pode mudar dependendo da configuração do kernel. Além disso, nem todos os dispositivos possuem uma device
subpasta. Por exemplo, este é o caso de arquivos de dispositivos de partição como /dev/sda1
. Aqui você precisa acessar o dispositivo para todo o disco (infelizmente não há sys
links para isso).
Uma coisa final que pode ser útil é listar os drivers de todos os dispositivos para os quais 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 /sys
truque global 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
Observando com mais atenção a saída de udevadm
, ele parece funcionar encontrando o /sys
diretório canônico (como você obteria se referenciasse os diretórios principais / secundários acima) e, em seguida, subindo na árvore de diretórios, imprimindo as informações que encontrar. Dessa forma, você obtém informações sobre os dispositivos pai e todos os drivers que eles usam.
Para experimentar isso, escrevi o script abaixo para subir na á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 incorporados ATTRS
. Em vez de fazer isso, eu mostro o conteúdo dos uevent
arquivos 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 base de todos os links do subsistema que encontro e isso mostra como o dispositivo se encaixa nessa hierarquia. udevadm
não exibe as mesmas informações, portanto, essa é uma boa ferramenta complementar. As informações do dispositivo pai (por exemplo, PCI
informações) também são úteis se você deseja corresponder a saída de outras ferramentas, como lshw
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
udevadm
resposta lhe dará sd
e ahci
. Existe uma maneira de determinar se ahci
está sendo usado também?
device/device/
, então meu readlink
comando parecia readlink /sys/dev/char/XX\:Y/device/device/driver
.
Você pode usar a udevadm
ferramenta para descobrir isso.
O comando seria udevadm info -a -n /dev/sda
e, em seguida, observe os DRIVER==
parâmetros.
# udevadm info -a -n /dev/sda | grep -oP 'DRIVERS?=="\K[^"]+'
sd
ahci
Isso mostra que existem 2 drivers envolvidos no fornecimento deste dispositivo sd
e ahci
. O primeiro, sd
é diretamente responsável pelo /dev/sda
dispositivo, mas usa o ahci
driver de acordo.
A saída do udevadm
comando se parece com isso e inclui uma descrição de como ele funciona.
# udevadm info -a -n /dev/sda
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
DRIVER==""
ATTR{ro}=="0"
ATTR{size}=="500118192"
ATTR{stat}==" 84786 1420 3091333 40215 966488 12528 14804028 2357668 0 1146934 2396653"
ATTR{range}=="16"
ATTR{discard_alignment}=="0"
ATTR{events}==""
ATTR{ext_range}=="256"
ATTR{events_poll_msecs}=="-1"
ATTR{alignment_offset}=="0"
ATTR{inflight}==" 0 0"
ATTR{removable}=="0"
ATTR{capability}=="50"
ATTR{events_async}==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0':
KERNELS=="0:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{rev}=="VZJ4"
ATTRS{type}=="0"
ATTRS{scsi_level}=="6"
ATTRS{model}=="LITEONIT LMT-256"
ATTRS{state}=="running"
ATTRS{queue_type}=="simple"
ATTRS{iodone_cnt}=="0x10daad"
ATTRS{iorequest_cnt}=="0x10ead1"
ATTRS{queue_ramp_up_period}=="120000"
ATTRS{device_busy}=="0"
ATTRS{evt_capacity_change_reported}=="0"
ATTRS{timeout}=="30"
ATTRS{evt_media_change}=="0"
ATTRS{ioerr_cnt}=="0x2"
ATTRS{queue_depth}=="31"
ATTRS{vendor}=="ATA "
ATTRS{evt_soft_threshold_reached}=="0"
ATTRS{device_blocked}=="0"
ATTRS{evt_mode_parameter_change_reported}=="0"
ATTRS{evt_lun_change_reported}=="0"
ATTRS{evt_inquiry_change_reported}=="0"
ATTRS{iocounterbits}=="32"
ATTRS{eh_timeout}=="10"
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0':
KERNELS=="target0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1/host0':
KERNELS=="host0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2/ata1':
KERNELS=="ata1"
SUBSYSTEMS==""
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1f.2':
KERNELS=="0000:00:1f.2"
SUBSYSTEMS=="pci"
DRIVERS=="ahci"
ATTRS{irq}=="41"
ATTRS{subsystem_vendor}=="0x144d"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x010601"
ATTRS{enabled}=="1"
ATTRS{consistent_dma_mask_bits}=="64"
ATTRS{dma_mask_bits}=="64"
ATTRS{local_cpus}=="0f"
ATTRS{device}=="0x1e03"
ATTRS{msi_bus}==""
ATTRS{local_cpulist}=="0-3"
ATTRS{vendor}=="0x8086"
ATTRS{subsystem_device}=="0xc0d3"
ATTRS{numa_node}=="-1"
ATTRS{d3cold_allowed}=="1"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
udevadm
é removido (ou até recomendado)? Eu não consigo encontrar nada, mesmo dando uma dica nisso.
Use o comando hwinfo e modelo e driver de saída. Se não houver driver, ele não será mostrado. Por exemplo, para discos:
# hwinfo --block | grep -Ei "driver \: | modelo \:" Modelo: "Disquete" Modelo: "FUJITSU MHZ2080B" Driver: "ahci", "sd" Modelo: "Partição" Modelo: "Partição" Modelo: "Partição" Modelo: "Cartão múltiplo genérico" Driver: "ums-realtek", "sd" Modelo: "Realtek USB2.0-CRW" Driver: "ums-realtek"
Para placas de rede:
# hwinfo --netcard | grep -Ei "driver \: | modelo \:" Modelo: "Broadcom NetXtreme BCM5764M Gigabit Ethernet PCIe" Driver: "tg3" Modelo: "Intel Wireless WiFi Link 5100" Driver: "iwlwifi"
Para dispositivos USB:
# hwinfo --usb | grep -Ei "driver \: | modelo \:" Modelo: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller" Driver: "hub" Modelo: "Linux 3.11.10-7-desktop uhci_hcd UHCI Host Controller" Driver: "hub" Modelo: "IDEACOM IDC 6680" Driver: "usbhid" [...]
Use hwinfo --help para descobrir quais outros tipos de dispositivos você pode consultar. O hwinfo é instalado por padrão, por exemplo, no SUSE Linux.
--only
opção. Por exemplo hwinfo --block --only /dev/sda | grep ...
.
lshw
é uma ferramenta incrível para listar o hardware encontrado em sua máquina. Você precisará instalá-lo primeiro antes de executar.
$ yum install lshw
$ apt-get install lshw
Use yum
ou apt-get
dependendo do sistema que você está usando. Em seguida, para listar especificamente o hardware de armazenamento:
# lshw -class storage
*-storage
description: SATA controller
product: 5 Series/3400 Series Chipset 4 port SATA AHCI Controller
vendor: Intel Corporation
physical id: 1f.2
bus info: pci@0000:00:1f.2
version: 06
width: 32 bits
clock: 66MHz
capabilities: storage msi pm ahci_1.0 bus_master cap_list
configuration: driver=ahci latency=0
resources: irq:41 ioport:1830(size=8) ioport:1824(size=4) ioport:1828(size=8) ioport:1820(size=4) ioport:1800(size=32) memory:f0305000-f03057ff
Você pode executá-lo root
para obter todas as informações de volta.
Caso contrário, você lspci
também pode fornecer informações sobre o seu hardware:
$ lspci -vv
00:1f.2 SATA controller: Intel Corporation 5 Series/3400 Series Chipset 4 port SATA AHCI Controller (rev 06) (prog-if 01 [AHCI 1.0])
Subsystem: Dell Device 0434
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin B routed to IRQ 41
Region 0: I/O ports at 1830 [size=8]
Region 1: I/O ports at 1824 [size=4]
Region 2: I/O ports at 1828 [size=8]
Region 3: I/O ports at 1820 [size=4]
Region 4: I/O ports at 1800 [size=32]
Region 5: Memory at f0305000 (32-bit, non-prefetchable) [size=2K]
Capabilities: <access denied>
Kernel driver in use: ahci
Para descobrir o número principal e o menor de um dispositivo, basta executá ls
-lo.
$ ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 13 avril 10:54 /dev/sda
Nesta saída, o b
in brw-rw----.
significa que este é um dispositivo de bloco. Os dígitos 8
e 0
são, respectivamente, o número principal e o menor do dispositivo.
lshw
e lspci
você pode ver o módulo usado por um dispositivo: configuration: driver = ahci latency = 0 e o driver do Kernel em uso: ahci .
lsmod
,/proc/modules
emodinfo
?