Skip to content

Instantly share code, notes, and snippets.

@kiler129
Forked from Roliga/iommu.sh
Last active December 20, 2023 02:34
Show Gist options
  • Save kiler129/d511aab51280079f1205db6a0c260211 to your computer and use it in GitHub Desktop.
Save kiler129/d511aab51280079f1205db6a0c260211 to your computer and use it in GitHub Desktop.
#!/bin/bash
### Improved IOMMU/PCIe list script
# The script was originally authored by Roliga (https://gist.github.com/Roliga/d81418b0a55ca7682227d57af277881b)
# This version changes:
# 1) enable listing of devices even if IOMMU is disabled
# 2) add support for NVMe & SAS block devices
# 3) display disks serial & firmware (if available)
# 4) QOL improvements: disabled paging by default; don't crash on missing lsusb
### Default config
useColors=true
usePager=false
usage() {
echo "\
Usage: $(basename $0) [OPTIONS]
Shows information about IOMMU groups relevant for working with PCI-passthrough
If IOMMU groups are not supported/enabled, it will print list of devices with details.
-c -C enables/disables colored output, respectively
-p -P enables/disables pager (less), respectively
-h display this help message"
}
color() {
if ! $useColors; then
cat
return
fi
rset=$'\E[0m'
case "$1" in
black) colr=$'\E[22;30m' ;;
red) colr=$'\E[22;31m' ;;
green) colr=$'\E[22;32m' ;;
yellow) colr=$'\E[22;33m' ;;
blue) colr=$'\E[22;34m' ;;
magenta) colr=$'\E[22;35m' ;;
cyan) colr=$'\E[22;36m' ;;
white) colr=$'\E[22;37m' ;;
intenseBlack) colr=$'\E[01;30m' ;;
intenseRed) colr=$'\E[01;31m' ;;
intenseGreen) colr=$'\E[01;32m' ;;
intenseYellow) colr=$'\E[01;33m' ;;
intenseBlue) colr=$'\E[01;34m' ;;
intenseMagenta) colr=$'\E[01;35m' ;;
intenseCyan) colr=$'\E[01;36m' ;;
intenseWhite) colr=$'\E[01;37m' ;;
esac
sed "s/^/$colr/;s/\$/$rset/"
}
indent() {
sed 's/^/\t/'
}
pager() {
if $usePager; then
less -SR
else
cat
fi
}
print_block_details() {
local type="$1"
local blockDevice="$2"
local dev="$3"
echo "$type block device:" | color cyan
if [[ -f "$blockDevice/../model" ]]; then
echo "Model: $(cat "$blockDevice/../model")" | indent | color green
fi
if [[ -f "$blockDevice/../serial" ]]; then
echo "S/N: $(cat "$blockDevice/../serial")" | indent | color green
fi
if [[ -f "$blockDevice/../firmware_rev" ]]; then
echo "F/w rev.: $(cat "$blockDevice/../firmware_rev")" | indent | color green
fi
lsblk -no NAME,SIZE,MOUNTPOINT "/dev/${dev}" | indent | color green
}
print_device() {
local device="$1"
devicePath="/sys/bus/pci/devices/${device}/"
# Print pci device
lspci -nns "$device" | color intenseBlue
# Print drivers
driverPath=$(readlink "$devicePath/driver")
if [ -z "$driverPath" ]; then
echo "Driver: none"
else
echo "Driver: $(basename $driverPath)"
fi | indent | color cyan
# Print usb devices
usbBuses=$(find $devicePath -maxdepth 2 -path '*usb*/busnum')
for usb in $usbBuses; do
# todo: sometimes "lsusb" is not available but /sys/kernel/debug/usb/devices is, but the format isn't easy
if command -v lsusb &> /dev/null; then
echo 'Usb bus:' | color cyan
lsusb -s $(cat "$usb"): | indent | color green
else
echo "Cannot print USB bus & devices - lsusb not installed" | color yellow
fi
done | indent
# Print SCSI block devices
for scsi in $(find $devicePath -mindepth 5 -maxdepth 6 -name 'block'); do
print_block_details 'SCSI' "${scsi}" "$(ls -1 $scsi)"
done | indent
# Print NVMe block devices
for nvme in $(find $devicePath -mindepth 3 -maxdepth 3 -regextype posix-extended -regex '.*/nvme[0-9]+n[0-9]+'); do
print_block_details 'NVMe' "${nvme}" "$(basename $nvme)"
done | indent
}
while getopts cCpPh opt; do
case $opt in
c)
useColors=true
;;
C)
useColors=false
;;
p)
usePager=true
;;
P)
usePager=false
;;
h)
usage
exit
;;
esac
done
iommuGroups=$(find '/sys/kernel/iommu_groups/' -maxdepth 1 -mindepth 1 -type d)
if [ -z "$iommuGroups" ]; then
echo "*****************************************************" | color red
echo "No IOMMU groups found. Are you sure IOMMU is enabled?" | color red
echo "*****************************************************" | color red
echo "All PCI devices" | color red
for device in $(ls -1 "/sys/bus/pci/devices/"); do
print_device "${device}"
done | indent
else
for iommuGroup in $iommuGroups; do
echo "IOMMU group $(basename "$iommuGroup")" | color red
for device in $(ls -1 "$iommuGroup/devices/"); do
print_device "${device}"
done | indent
done | pager
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment