Get the size of a Linux block special device in C
Tested on |
Debian (Lenny, Squeeze) |
Ubuntu (Lucid, Precise, Trusty) |
Objective
To get the size of a Linux block special device in C
Background
A block special device typically represents a logical or physical storage device such as a hard disc drive, a disc partition or a logical volume. Unlike a regular file, the size of a block special device cannot be obtained by means such as the stat
or lseek
functions.
Scenario
Suppose that you wish to determine the size of the block device /dev/sda
.
Method
On Linux-based systems the size of a block special device can be obtained using the ioctl
request BLKGETSIZE64
. It requires an open file descriptor and produces a 64-bit result which is the size in bytes:
#include <stdint.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/fs.h> // ... const char* pathname="/dev/sda"; int fd=open(pathname,O_RDONLY); if (fd==-1) { die("%s",strerror(errno)); } uint64_t size; if (ioctl(fd,BLKGETSIZE64,&size)==-1) { die("%s",strerror(errno)); } close(fd);
The need for an open file descriptor implies that the caller must have at least read-only access to the block device.
Notes
BLKGETSIZE
There is another ioctl
with similar functionality to BLKGETSIZE64
called BLKGETSIZE
. It returns the device size as a number of 512-byte blocks, but because it does so in the form of an unsigned long
it may fail if the size is 2TB or greater. For this reason it is better to use BLKGETSIZE64
where possible, but if you require compatibility with very old versions of Linux (prior to 2.4.10) then it may be appropriate to use BLKGETSIZE
as a fallback.
Tags: c