How to extract storage device information without using dmesg
I come across this problem in one of my projects. How can I easily retrieve storage device information (such as brand, partition, label, filesystem etc) and integrate to another program ? E.g If an USB storage device is plugged into a machine or a LiveCD is running on an unknown machine and trying to detect what storage devices are connected.
I searched for some answers on the internet but the typical and obvious response is to parse the output from the dmesg command. I find that approach ugly. The dmesg utility is for showing users descriptive system messages since the machine is started and it is event based. In my opinon, the output is not unix commands friendly because the format is not consistent. Hence I need to write more code for the sake of parsing the output. There got to be another simpler way to do it. There must be a command which gives better output than dmesg.
I stumble across several utilities which are pretty useful to dig up the device information and of course, they produce easier output for parsing.
udevinfo – part of the udev package. You can request specific system information under the sysfs directories, /sys/…
Suppose you want to query information inside a storage device, /dev/sda
udevinfo -a -p /sys/block/sda/sda1 –query=env
This gives the following output in name and value pairs:
As you can see, the output is pretty well self descriptive with information like: filesystem, disk label, the hardware model, etc. You can either use awk or source the output inside a shell script to process the data.
With udevinfo, you can also find out the following
- how many storage devices and what partitions are available
- which partition is mountable
First, you can run the following command to list all the available partitions for all the detected devices:
ls -d /sys/block/[sh]d[a-z]*/[sh]d[a-z]*[0-9]*
Then issues the above udevinfo command for each of the partition directory returned from the above ls command.
If the value of ID_FS_USAGE is ‘filesystem’, then the partition is mountable. As long as ID_FS_TYPE has the filesystem type supported by the kernel.
lshw is another tool that offers rich information on hardware devices. The information is organised in tree style that you can output in pure text or in xml/html format. Here is an example of trimmed output:
description: SCSI Disk
logical name: /dev/sdb
size: 963MiB (1010MB)
logical name: /dev/sdb
size: 963MiB (1010MB)
capabilities: partitioned partitioned:dos
description: Windows FAT volume
logical name: /dev/sdb1
logical name: /media/usb0
lshw and udevinfo offers similar detail level on hardware data. However, if you are thinking of integrating the output to another program, perhaps udevinfo’s output is simpler to parse because everything is in name and value pair. On the other hand, lshw gives you the full picture of all the hardware detail in one command.
Alternatively, if you only want hardware level information, another obvious choice is to use hwinfo utility. Simply do, hwinfo –disk. Following is an example of trimmed output:
33: IDE 100.0: 10600 Disk
[Created at block.222]
Hardware Class: disk
Geometry (Logical): CHS 9729/255/63
Size: 156301488 sectors a 512 bytes
Geometry (BIOS EDD): CHS 155058/16/63
Size (BIOS EDD): 156299375 sectors
Geometry (BIOS Legacy): CHS 1024/255/63
Config Status: cfg=new, avail=yes, need=no, active=unknown
Attached to: #14 (IDE interface)
As you can see hwinfo does what it say on the tin, it returns information: disk model and geometry whereas udevinfo and lshw returns additional information on the filesystem level.
Depending on how much information you need to request for the hardware and what to do with the output, both udevinfo and lshw offers higher detail than hwinfo. With udevinfo, you need to drill down to specific level in the sysfs hierarchy but the output is in name and value pairs which is more unix command friendly comparing to lshw. If you need to integrate information for another program, then perhaps udevinfo is a better choice. On the other hand, lshw gives a slightly higher hardware detail (such as partition size) than udevinfo and a single command will extract the whole hierarchy of hardware class, not only storage. Then perhaps worth writing extra code to parse the xml output from lshw.