Getting block device size? [Solved I think]


#1

Hello,

Is there a way to get block device size(namely disk size) in Rust reliably?

Using std::fs::File to grab the metadata of, say /dev/sda, then getting meta.len() seems to always return 0, so I presume that way doesn’t work.

I am aware of ioctl library bindings, but then I’m stuck on how to get the same results on Windows and OSX relaibly.

Also curious if there are better ways of doing this than using platform specific library for each OS.

Thanks!


#2

Getting volume/partition info is very platform-specific, and not supported by any published crate that I know of. Windows has the GetVolumeInformation API, usable in Rust through the winapi crate, and macOS the DADisk_ family of objects and functions, not available in Rust AFAIK.


#3

Also curious if there are better ways of doing this than using platform specific library for each OS.

Sounds like you have an idea for a crate. On Linux, all this information is available in text files in /sys/class/block.


#4

Will certainly think about it.

Still feels a bit weird since in OCaml the stdlib takes care of this, not entirely sure why Rust doesn’t.

EDIT : Actually it does make sense, since it should respect actual metadata handling behaviour of the OS, while OCaml wasn’t providing access to metadata directly in the specific function.


#5

Turns out seeking to the end of the device and getting the position seems to work, so that’s solved i suppose.

Woosh.


#6

not entirely sure why Rust doesn’t

I’d think it’s doable. Every OS has a concept of a device. You just have to put some effort into standardizing it. On Linux, you can get this information from the kernel through /sys/class/block:

mmstick:~# ls /sys/class/block
loop0  loop3  loop6  sda1  sda4  sdb   sdb3  sdc   sdd	 sde   sde3
loop1  loop4  loop7  sda2  sda5  sdb1  sdb4  sdc1  sdd1  sde1  sr0
loop2  loop5  sda    sda3  sda6  sdb2  sdb5  sdc2  sdd2  sde2
mmstick:~# 

Then you can get more specific information about a block device in that directory (note that partitions on a block device are also block devices themselves):

mmstick:~# ls -l /sys/class/block/sda/
total 0
-r--r--r-- 1 root root 4096 Apr  7 20:34 alignment_offset
lrwxrwxrwx 1 root root    0 Apr  7 20:34 bdi -> ../../../../../../../../virtual/bdi/8:0
-r--r--r-- 1 root root 4096 Apr  7 20:34 capability
-r--r--r-- 1 root root 4096 Apr  6 21:55 dev
lrwxrwxrwx 1 root root    0 Apr  6 21:57 device -> ../../../3:0:0:0
-r--r--r-- 1 root root 4096 Apr  7 20:34 discard_alignment
-r--r--r-- 1 root root 4096 Apr  7 20:34 events
-r--r--r-- 1 root root 4096 Apr  7 20:34 events_async
-rw-r--r-- 1 root root 4096 Apr  7 20:34 events_poll_msecs
-r--r--r-- 1 root root 4096 Apr  6 21:57 ext_range
-r--r--r-- 1 root root 4096 Apr  7 20:34 hidden
drwxr-xr-x 2 root root    0 Apr  6 21:55 holders
-r--r--r-- 1 root root 4096 Apr  7 20:34 inflight
drwxr-xr-x 2 root root    0 Apr  6 21:55 integrity
drwxr-xr-x 2 root root    0 Apr  6 21:55 power
drwxr-xr-x 3 root root    0 Apr  6 21:55 queue
-r--r--r-- 1 root root 4096 Apr  7 20:34 range
-r--r--r-- 1 root root 4096 Apr  6 21:55 removable
-r--r--r-- 1 root root 4096 Apr  6 21:55 ro
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda1
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda2
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda3
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda4
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda5
drwxr-xr-x 5 root root    0 Apr  6 21:55 sda6
-r--r--r-- 1 root root 4096 Apr  6 21:55 size
drwxr-xr-x 2 root root    0 Apr  6 21:55 slaves
-r--r--r-- 1 root root 4096 Apr  6 21:55 stat
lrwxrwxrwx 1 root root    0 Apr  6 21:55 subsystem -> ../../../../../../../../../class/block
drwxr-xr-x 2 root root    0 Apr  6 21:55 trace
-rw-r--r-- 1 root root 4096 Apr  7 18:57 uevent

And you can get the size of a device, in sectors (512 bytes), from the size file:

mmstick:~# cat /sys/class/block/sdb/size
60604416

Which 60604416 * 512 / 1_000_000_000 = 31 GB