What's the best way to get info about currently unmounted drives?

First, the situation: I've got a Linux computer with two eSATA drive bays that accept removable SSD drives. I'm trying to write a little GUI application that makes it easier for the user to mount/unmount/format/backup/etc the drives that he puts into these bays.

It all mostly works. One small problem, however, is that I don't know how to find out any information about what's on the inserted drive(s) until after the drives have been successfully mounted.

So, for example, if the user inserts a drive that I can't mount (e.g. because it is unformatted, or formatted with an unexpected filesystem), all my app can say about it is "Drive failed to mount".

This isn't very satisfactory, because if the drive is unformatted, the user will probably want to format it... but if the drive contains data from an unrecognized filesystem, the user will probably NOT want to format it.... or at least, I want to be able to warn him that by doing so he'll be erasing potentially valuable data.

So my question is: is there any method for querying some basic information (especially filesystem-type) from a drive that doesn't require that the drive already be mounted? Or do I just have to try to mount it with various known filesystems until one of the mount attempts succeeds, and give a vague "be careful" message if none of them do?

In case it matters, the paths I use to mount the drives in the drive bays are:

/dev/disk/by-path/pci-0000:00:1f.2-scsi-2:0:0:0
/dev/disk/by-path/pci-0000:00:1f.2-scsi-1:0:0:0

If the drives are unmounted there are several things you can do.

You can use a command like fdisk -l or sfdisk -l to list the partitions. Just the partition type may give you some useful information if the partitions where setup correct.y

# sfdisk -l

Disk /dev/sda: 4177 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/sda1   *      0+     30      31-    248976   83  Linux
/dev/sda2         31    4176    4146   33302745   8e  Linux LVM
/dev/sda3          0       -       0          0    0  Empty
/dev/sda4          0       -       0          0    0  Empty

If it is present on your system you can use the command vol_id against a partition to return some useful details (part of the udev package on Debian). This will generally tell you what filesystem is actually being used.

# vol_id /dev/sda1

ID_FS_USAGE=filesystem
ID_FS_TYPE=ext3
ID_FS_VERSION=1.0
ID_FS_UUID=32c44d53-9025-4d10-8f36-75c166547bd5
ID_FS_UUID_ENC=32c44d53-9025-4d10-8f36-75c166547bd5
ID_FS_LABEL=
ID_FS_LABEL_ENC=
ID_FS_LABEL_SAFE=

The command lshw -class disk will give you some details about the type of drive. You might want to use this if you are curious about the actual serial number of the drive.

# lshw -class disk

  *-disk
       description: ATA Disk
       product: VBOX HARDDISK
       physical id: 0.0.0
       bus info: scsi@0:0.0.0
       logical name: /dev/sda
       version: 1.0
       serial: VB169e93fb-d1e0fd97
       size: 32GiB (34GB)
       capabilities: partitioned partitioned:dos
       configuration: ansiversion=5 signature=000d39f8

If you are sure the there is a particular filesystem like ext2/3 on it then you can use the filesystem specific tune2fs tool to examine more details.

# tune2fs -l /dev/sda1

tune2fs 1.41.3 (12-Oct-2008)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          8cbdf102-05c7-4ae4-96ea-681cf9b11914
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      filetype sparse_super
Default mount options:    (none)
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              124496
Block count:              248976
Reserved block count:     12448
Free blocks:              212961
Free inodes:              124467
First block:              1
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         4016
Inode blocks per group:   502
Last mount time:          Thu Oct  7 15:34:42 2010
Last write time:          Thu Oct  7 15:34:42 2010
Mount count:              4
Maximum mount count:      30
Last checked:             Wed Sep 15 09:29:03 2010
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           128

Another useful tool is lsblk.

# lsblk 

NAME                MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                   8:0    0    30G  0 disk 
└─sda1                8:1    0    30G  0 part 
  ├─vg1-root (dm-0) 254:0    0  23.3G  0 lvm  /
  └─vg1-swap (dm-1) 254:1    0   1.9G  0 lvm  [SWAP]
sr0                  11:0    1  1024M  0 rom  

If you have parted installed you can run a command like this

parted /dev/sda print all

Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 34.4GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      32.3kB  255MB   255MB   primary  ext2         boot 
 2      255MB   34.4GB  34.1GB  primary               lvm  

Model: Linux device-mapper (linear) (dm)
Disk /dev/mapper/vg1root: 32.6GB
Sector size (logical/physical): 512B/512B
Partition Table: loop

Number  Start  End     Size    File system  Flags
 1      0.00B  32.6GB  32.6GB  ext3              

Anyway past that I suggest you take a look at the udev or parted source.


Another useful command is blkid - it returns similar information to vol_id but can also scan all devices in the system, rather than requiring a device to be passed in.

To force blkid to scan all devices instead of using cached information, run blkid -c /dev/null (you need read permission on the block devices so you'll usually need to run it as root)


Here's one suggestion from IBM: SCSI - Hot add, remove, rescan of SCSI devices: Rescan of a SCSI Device. This will rescan that SCSI address for new devices, and then you'll be able to read the information in /var/log/messages . Some other disk tools will also work, without you mounting the drive.

echo 1 > /sys/bus/scsi/drivers/sd/<SCSI-ID>/block/device/rescan

I actually tried somethign slightly different yesterday, and it worked (RHEL4 system):

cd /sys/bus/scsi/devices
echo > 0\:0\:0\:0/rescan

A simple overview of all partitions found by the kernel gives

cat /proc/partitions