Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine Device of Filesystem in Python

Tags:

python

linux

How do you use Python to determine which Linux device/partition contains a given filesystem?

e.g.

>>> get_filesystem_device('/')
/dev/sda
>>> get_filesystem_partition('/')
/dev/sda1
like image 702
Cerin Avatar asked Oct 10 '11 20:10

Cerin


People also ask

How do I know if a file system is mounted Python?

path. ismount() method in Python is used to check whether the given path is a mount point or not. A mount point is a point in a file system where different file system has been mounted.

How you identify if particular device have filesystem on it or not?

The first command you can use is lsblk , which shows information about available block devices. This command can read information of a block device whether or not it is mounted. When run wlith -f option, it shows filesystem type of every mounted or unmounted block device.


2 Answers

Your question was about Linux, so this is (more or less) linux specific.

Below is code example for three variants for mapping major/minor to a device name.

  • Parse /proc/partitions.
  • Ask hal. Hal also keeps track of "parent" device, meaning you can easily get the disk aswell as the partition.
  • Check sysfs yourself. This is where hal gets its information from.

I'd say that /proc/partitions is simplest - it is just one file to open and check. hal gives you most information, and abstracts away lots of details. sysfs may be viewed as more correct that /proc/partitions and doesn't require hal to be running.

For a desktop program I would go for hal. On an embedded system I'd go with sysfs.


import os

def main():
    dev = os.stat("/home/").st_dev
    major, minor = os.major(dev), os.minor(dev)

    print "/proc/partitions says:", ask_proc_partitions(major, minor)
    print "HAL says:", ask_hal(major, minor)
    print "/sys says:", ask_sysfs(major, minor)

def _parse_proc_partitions():
    res = {}
    for line in file("/proc/partitions"):
        fields = line.split()
        try:
            tmaj = int(fields[0])
            tmin = int(fields[1])
            name = fields[3]
            res[(tmaj, tmin)] = name
        except:
            # just ignore parse errors in header/separator lines
            pass

    return res

def ask_proc_partitions(major, minor):
    d = _parse_proc_partitions()
    return d[(major, minor)]

def ask_hal(major, minor):
    import dbus

    bus = dbus.SystemBus()
    halobj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
    hal = dbus.Interface(halobj, 'org.freedesktop.Hal.Manager')

    def getdevprops(p):
        bdevi = dbus.Interface(bus.get_object('org.freedesktop.Hal', p),
                               "org.freedesktop.Hal.Device")
        return bdevi.GetAllProperties()

    bdevs = hal.FindDeviceByCapability("block")
    for bdev in bdevs:
        props = getdevprops(bdev)
        if (props['block.major'], props['block.minor']) == (major, minor):
            parentprops = getdevprops(props['info.parent'])
            return (str(props['block.device']), 
                    str(parentprops['block.device']))

def ask_sysfs(major, minor):
    from glob import glob
    needle = "%d:%d" % (major, minor)

    files = glob("/sys/class/block/*/dev")
    for f in files:
        if file(f).read().strip() == needle:
            return os.path.dirname(f)

    return None

if __name__ == '__main__':
    main()
like image 57
Anders Waldenborg Avatar answered Sep 18 '22 05:09

Anders Waldenborg


It looks like this post has some of your answer (still not sure just how to grab the major/minor out of the /dev/sda2 entry to match it up with what os.stat() returns for /:

Device number in stat command output

>>> import os
>>> print hex(os.stat('/')[2])
0x802
  \ \minor device number
   \major device number

[me@server /]$ ls -l /dev/sda2
brw-rw----    1 root     disk       8,   2 Jun 24  2004 /dev/sda2
[me@server jgaines2]$               \    \minor device number
                                     \major device number
like image 24
John Gaines Jr. Avatar answered Sep 20 '22 05:09

John Gaines Jr.