For now I use os.stat(path).st_dev
to get the device id. But the id seems to be different for logical disks on same same physical drive. So it doesn't actually works for me. Is there a better or direct solution to it.
Look at the hex output. The first number after the 0x
prefix indicates the device driver:
>>> hex(os.stat("/usr").st_dev)
'0x801L'
This is a 'SCSI' disk, because all of them have ID 8. Reference: https://www.kernel.org/doc/Documentation/devices.txt. Drive ID and partition number are encoded in the remaining part of the st_dev
.
The exact transformation for major ID and minor ID as implemented by glibc
is as follows:
>>> minor = int(os.stat("/lib").st_dev & 0xff)
>>> major = int(os.stat("/lib").st_dev >> 8 & 0xff)
>>> major, minor
(8, 1)
Meaning major number 8 (SCSI host adapter), minor number 1. The minor number encodes drive number as well as partition. As can also be inferred from here, all partitions on the first disk have a minor ID between 1 and 15. All partitions on the second disk have a minor ID between 17 and 31, and so on.
Showcase, same device controller (SCSI):
>>> int(os.stat("/lib").st_dev >> 8 & 0xff)
8
>>> int(os.stat("/usr").st_dev >> 8 & 0xff)
8
Showcase, different device controller (NFS mount in this case):
>>> int(os.stat("/home/*****").st_dev >> 8 & 0xff)
0
Background:
What you get from e.g.
>>> os.stat("/usr").st_dev
2049L
corresponds to the decimal Device
output of the stat
program:
$ stat /usr
File: `/usr'
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 801h/2049d Inode: 1308164 Links: 11
From man 2 stat
(or e.g. http://linux.die.net/man/2/stat) you can then read
The st_dev field describes the device on which this file resides. (The major(3) and minor(3) macros may be useful to decompose the device ID in this field.)
These macros are not defined by POSIX, but implemented in glibc, as can be seen here:
https://github.com/jeremie-koenig/glibc/blob/master-beware-rebase/sysdeps/generic/sys/sysmacros.h
The actual C implementation is:
#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
#define minor(dev) ((int)((dev) & 0xff))
This can easily be translated into Python as I have done above. As of these macros it is also obvious that the hex notation is more intuitive than the decimal one:
>>> hex(os.stat("/usr").st_dev)
'0x801L'
From here you can already see the 8 and the 1 being major device ID and minor device ID, respectively. We can also check this like so:
$ pwd
/usr
$ df -h .
Filesystem Size Used Avail Use% Mounted on
/dev/disk/by-uuid/cba70a49-04a7-40a6-8a53-465f817e51cd 29G 8.6G 19G 32% /
This is the disk, which actually corresponds to /dev/sda1:
$ ls -al /dev/disk/by-uuid/cba70a49-04a7-40a6-8a53-465f817e51cd
0 lrwxrwxrwx 1 root root 10 May 6 16:33 /dev/disk/by-uuid/cba70a49-04a7-40a6-8a53-465f817e51cd -> ../../sda1
Major ID 8 (-> sd
, SCSI device), minor 1 (-> a1
, first disk, first partition).
ls -l /dev
gives me the following:- brw-rw----. 1 root disk 8, 16 Jul 2 18:32 sdb brw-rw----. 1 root disk 8, 17 Jul 2 18:33 sdb1 brw-rw----. 1 root disk 8, 18 Jul 2 18:35 sdb2 brw-rw----. 1 root disk 8, 32 Jul 2 18:32 sdc brw-rw----. 1 root disk 8, 33 Jul 2 18:36 sdc1
So, I see that the major nos. are same for both of them. m confused? :( –
Perfectly © 2022 - 2024 — McMap. All rights reserved.