If my target has one device connected and many drivers for that device loaded, how can I understand what device is using which driver?
8 Answers
Just use /sys.
Example. I want to find the driver for my Ethernet card:
$ sudo lspci
...
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01)
$ find /sys | grep drivers.*02:00
/sys/bus/pci/drivers/r8169/0000:02:00.0
That is r8169.
First I need to find coordinates of the device using lspci; then I find driver that is used for the devices with these coordinates.
- 1,096
- 8
- 11
-
55`lspci -v` does it by itself. – poige Jul 01 '12 at 04:50
-
14`lspci -nk` will show you attached drivers. In general the sysfs is the right place to search for. – 0andriy Nov 18 '15 at 20:03
-
@AndyShevchenko thank you! This will be a *great* timesaver for me :-D – pepoluan Nov 29 '16 at 03:19
-
3I know the OP asked for "drivers being used", but what if the driver is not installed nor being used? How to find out just by the `vendorID:productID`? Also, what if it is not a PCI device, and you only see it in `lsusb` for example? – DrBeco Jun 26 '17 at 18:48
-
2@DrBeco: But if driver is not installed, what do you want to find? You should just google in this case – Igor Chubin Jun 27 '17 at 15:18
-
Well, not an option if you are trying to find the correct driver to load for a bunch of network cards that are not working (so, no google, unless you keep moving to another machine, or booting something that work, which takes time) – DrBeco Jun 28 '17 at 00:13
-
And if it's USB? Is there a generic way to do this? Looking at /sys or /proc or something? – Owl Sep 12 '18 at 12:26
-
`lspci -vk | grep -A 6 -i ethernet` but you have to adjust the number of lines printed after the matching line with `-A`. – Ludovic Kuty Apr 06 '20 at 06:54
Here's a little script I wrote:
#!/bin/bash
for f in /sys/class/net/*; do
dev=$(basename $f)
driver=$(readlink $f/device/driver/module)
if [ $driver ]; then
driver=$(basename $driver)
fi
addr=$(cat $f/address)
operstate=$(cat $f/operstate)
printf "%10s [%s]: %10s (%s)\n" "$dev" "$addr" "$driver" "$operstate"
done
Sample output:
$ ~/what_eth_drivers.sh
eth0 [52:54:00:aa:bb:cc]: virtio_net (up)
eth1 [52:54:00:dd:ee:ff]: virtio_net (up)
eth2 [52:54:00:99:88:77]: virtio_net (up)
lo [00:00:00:00:00:00]: (unknown)
- 1,821
- 1
- 16
- 20
-
1
-
Thanks! Way better than the unreliable 'dmesg|grep' (ring buffer...) – Dominik R Feb 10 '16 at 15:04
-
I'd like to find solution which would find also `veth` and other virtual drivers. IMHO the only solution is to use `ethtool` or `lshw`. – pevik Jul 20 '17 at 21:37
sudo lspci -v will show it. like this:
$ sudo lspci -v
00:01.0 VGA compatible controller: Advanced Micro Devices, Inc......
...
Kernel driver in use: radeon
Kernel modules: radeon
You can also combine it with grep like this:
$ sudo lspci -v | grep -A 20 VGA
- 1,821
- 1
- 16
- 20
- 1,271
- 1
- 13
- 21
For USB based devices you can see the driver name by using the lsusb command:
lsusb -t
And/or you use lshw which enumerates the devices on all buses including USB, PCI, etc so you can see which driver it uses:
sudo lshw
- 661
- 9
- 9
-
FTR: the driver is shown at line titled `configuration`, for example:
configuration: driver=btusb maxpower=100mA speed=12Mbit/s– Hi-Angel Mar 21 '21 at 13:41
If you just want to plainly use sysfs and doesn't want to deal with all these commands which eventually looks inside sysfs anyways, here's how:
say, what is the module/driver for eth6? "sfc" it is
# ls -l /sys/class/net/eth6/device/driver
lrwxrwxrwx 1 root root 0 Jan 22 12:30 /sys/class/net/eth6/device/driver ->
../../../../bus/pci/drivers/sfc
or better yet.. let readlink resolve the path for you.
# readlink -f /sys/class/net/eth6/device/driver
/sys/bus/pci/drivers/sfc
so... to figure out what are the drivers for all of your network interfaces:
# ls -1 /sys/class/net/ | grep -v lo | xargs -n1 -I{} bash -c 'echo -n {} :" " ; basename `readlink -f /sys/class/net/{}/device/driver`'
eth0 : tg3
eth1 : tg3
eth10 : mlx4_core
eth11 : mlx4_core
eth2 : tg3
eth3 : tg3
eth4 : mlx4_core
eth5 : mlx4_core
eth6 : sfc
eth7 : sfc
eth8 : sfc
eth9 : sfc
- 55,929
- 26
- 146
- 227
- 161
- 1
- 3
-
how is this one better than the one Jonathan Reinhart posted ? https://unix.stackexchange.com/a/225496/47663 – nhed Feb 08 '18 at 04:58
-
2Probably same... but I love one liner... I can easily adjust things right at the command line... just for those who don't have time to open a file and write a script. – Monty Montemayor Feb 13 '18 at 17:37
You can use the lsmod command to get the status of loaded modules / devices drivers in the Linux Kernel.
For a specific device, you can use dmesg |grep <device-name> to get the details too.
-
1Thanks. But if i loaded two drivers for a device with same major no and different minor no ,and if only one driver is being used for the device ,how can I find which driver is used for that device? – Jun 27 '12 at 06:34
-
perhaps [this](http://stackoverflow.com/questions/3096411/how-to-get-free-minor-number-for-a-linux-device-driver) SO question can help you further. – Jun 27 '12 at 06:49
-
If your system has not been online so long that the ring buffer has re-started, sure dmesg | grep
will work ; this doesn't work on any of my routers, however. – cjac Mar 07 '16 at 01:47
When ethtool is installed you can simply use:
$ ethtool -i enp2s0 | grep driver | awk '{print $2}'
r8169
where enp2s0 is the device name. ethtool provides detailed information about the interface:
$ ethtool -i enp2s0
driver: r8169
version: 2.3LK-NAPI
firmware-version: rtl8168e-3_0.0.4 03/27/12
expansion-rom-version:
bus-info: 0000:02:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no
In order to install on Debian/Ubuntu:
apt install ethtool
- 2,630
- 5
- 26
- 39
For me I needed a way to link network device names to driver pci names, here is a one-liner (adjust or remove the "grep ens" to whatever name network device name you want to search for)
for i in $(ip -br addr show | awk '{print$1}' | grep ens); do echo "$i: $(ethtool -i $i| grep bus-info)" ; done
- 522
- 4
- 18