我应该使用哪个“大小”文件来获取磁盘大小?

我应该使用哪个“大小”文件来获取磁盘大小?

我的磁盘是 sda,我有这些大小的文件:

/sys/dev/block/8:0/size
/sys/class/block/sda/size
/sys/block/sda/size

我应该使用哪一个?第一个由 所使用lsblk。有什么区别吗?

答案1

查看

ls -l /sys/dev/block/8:0 /sys/class/block/sda /sys/block/sda

您将看到所有三个都指向同一目录。

除了路径之外,文件之间没有任何区别。

答案2

如果您有块设备文件的路径,例如/dev/sda/dev/disk/by-id/whateversome/path/to/my/loop/device,则有多种选项可以在 Linux 上获取其大小,包括:

  1. open() 设备并发出BLKGETSIZE64 ioctl().就是这样blockdev --getsize64 path/to/block/device

  2. open() 设备并发出BLKGETSIZE ioctl()类似的blockdev --getsz path/to/block/device操作,并将其乘以 512(不是BLKSSZGETioctl() (as blocksize --getss path/to/block/device)返回的值)。

  3. open() 设备,lseek() 到最后,这将返回当前光标位置。例如,在zsh

    zmodload zsh/system
    { sysseek -w end 0 && print $(( systell(0) )); } < path/to/block/device
    
  4. 假设 sysfs 挂载在 中/sys,找到其中设备文件对应的路径,读取size其中的文件并乘以 512(不是其中任何文件中的值queue/*size)。

对于上面的1到3,您至少需要块设备的读或写权限。

对于 4,由于块设备文件的名称可以是任何内容,因此识别 /sys 路径的可靠方法以及lsblk您发现的方法依赖于通过调用stat()块设备路径获得的主设备号和次设备号(对于该路径,您只需要搜索对父目录的访问权限),然后使用作为块设备树/sys/dev/block/<major>:<minor>中目录的符号链接,并带有主/次设备号。/sys/devices<major><minor>

例如,与zsh

zmodload zsh/stat
stat -sH s path/to/block/device &&
  [[ $s[mode] = b* ]] &&
  print $(( $(</sys/dev/block/$(( s[rdev] >> 8 )):$(( s[rdev] & 0xff ))/size) * 512 ))

或者你可以lsblk为你做这件事:

lsblk -nbdo size path/to/block/device

答案3

/sys/dev/block/8:0/sys/class/block/sda并且/sys/block/sda都只是指向同一位置的符号链接,因此您使用哪个并不重要。

$ realpath /sys/dev/block/8:0
/sys/devices/pci0000:00/0000:00:01.2/0000:02:00.1/ata4/host3/target3:0:0/3:0:0:0/block/sda
$ realpath /sys/class/block/sda
/sys/devices/pci0000:00/0000:00:01.2/0000:02:00.1/ata4/host3/target3:0:0/3:0:0:0/block/sda
$ realpath /sys/block/sda
/sys/devices/pci0000:00/0000:00:01.2/0000:02:00.1/ata4/host3/target3:0:0/3:0:0:0/block/sda

相关内容