【问题标题】:Python: check if two Linux paths are on same physical diskPython:检查两个 Linux 路径是否在同一个物理磁盘上
【发布时间】:2013-06-20 09:52:15
【问题描述】:

现在我使用os.stat(path).st_dev 来获取设备ID。但是同一物理驱动器上的逻辑磁盘的 id 似乎不同。所以它实际上对我不起作用。有没有更好或直接的解决方案。

【问题讨论】:

  • 虽然您可能会得到一个对许多情况都有用的答案,但请注意,这可能没有一个完全通用的答案,您可能需要重新思考您认为需要它的确切原因。例如,您可能有一个文件系统存在于环回挂载文件中,该文件存在于另一个文件系统中,该文件系统位于 LVM2 逻辑卷中,该逻辑卷跨多个“物理磁盘”条带化,这些“物理磁盘”实际上是 8 个独立硬盘驱动器上的 RAID10 md 设备恰好也是硬件 RAID 设备...

标签: python linux disk-partitioning


【解决方案1】:

查看十六进制输出。 0x 前缀后的第一个数字表示设备驱动程序:

>>> hex(os.stat("/usr").st_dev)
'0x801L'

这是一个“SCSI”磁盘,因为它们的 ID 都是 8。参考:https://www.kernel.org/doc/Documentation/devices.txt。驱动器 ID 和分区号编码在 st_dev 的其余部分。

glibc 实现的主要 ID 和次要 ID 的确切转换如下:

>>> minor = int(os.stat("/lib").st_dev & 0xff)
>>> major = int(os.stat("/lib").st_dev >> 8 & 0xff)
>>> major, minor
(8, 1)

表示主编号 8(SCSI 主机适配器),次编号 1。次编号编码驱动器编号以及分区。从here 也可以推断,第一个磁盘上的所有分区都有一个介于 1 和 15 之间的次要 ID。第二个磁盘上的所有分区都有一个介于 17 和 31 之间的次要 ID,依此类推。

展示柜,相同的设备控制器 (SCSI):

>>> int(os.stat("/lib").st_dev >> 8 & 0xff)
8
>>> int(os.stat("/usr").st_dev >> 8 & 0xff)
8

Showcase,不同的设备控制器(本例为NFS挂载):

>>> int(os.stat("/home/*****").st_dev >> 8 & 0xff)
0

背景:

你从中得到什么,例如

>>> os.stat("/usr").st_dev
2049L

对应于stat程序的十进制Device输出:

$ stat /usr
  File: `/usr'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d  Inode: 1308164     Links: 11

然后您可以从man 2 stat(或例如http://linux.die.net/man/2/stat)阅读

st_dev 字段描述了该文件所在的设备。 (这 major(3) 和 minor(3) 宏可能有助于分解设备 ID 在这个领域。)

这些宏不是由 POSIX 定义的,而是在 glibc 中实现的,如下所示:

https://github.com/jeremie-koenig/glibc/blob/master-beware-rebase/sysdeps/generic/sys/sysmacros.h

实际的C实现是:

#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
#define minor(dev) ((int)((dev) & 0xff))

正如我在上面所做的那样,这可以很容易地翻译成 Python。对于这些宏,很明显十六进制表示法比十进制表示法更直观:

>>> hex(os.stat("/usr").st_dev)
'0x801L'

从这里您已经可以看到 8 和 1 分别是主要设备 ID 和次要设备 ID。我们也可以这样检查:

$ 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% /

这是磁盘,其实对应的是/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

主要 ID 8(-> sd,SCSI 设备),次要 ID 1(-> a1,第一个磁盘,第一个分区)。

【讨论】:

  • 嘿,抱歉回复晚了。正如您所说,Major ID 对应于物理磁盘号,并且这个概念很好地解释了。现在我有以下观察结果:- 我的机器上有 2 个物理磁盘:- --/dev/sdb/ 逻辑 /dev/sdb1/ 和 /dev/sdb2/ --/dev/sdc/ 逻辑 /dev/ sdc1
  • 但是ls -l /dev 给了我以下信息:- 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 所以,我看到了主要的号码。对他们来说都是一样的。米糊涂? :(
  • major and minor numbers...我认为major no是针对设备驱动程序的,并且由该设备驱动程序管理的所有设备都将具有相同的major no。
  • 您在那里找到了很好的参考资料。重要引语:“同一设备驱动程序控制的所有设备都有一个共同的主设备号。次设备号用于区分不同的设备及其控制器。”、“所有 SCSI 驱动器的主设备号是 8。次设备号是基于驱动器号,它是乘以 16 而不是 64,就像 IDE 驱动器一样。然后将分区号添加到此数字以给出次要。"
  • 我已经更新了答案。我想现在一切对我来说也很清楚:-)。其实很简单,最好的参考是kernel.org/doc/Documentation/devices.txt
猜你喜欢
  • 2012-07-13
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 2020-04-21
  • 2021-08-06
  • 2014-11-27
  • 1970-01-01
  • 2013-06-01
相关资源
最近更新 更多