Portable way to determine sector size in Linux

て烟熏妆下的殇ゞ 提交于 2019-12-11 05:52:43

问题


I want to write a small program in C which can determine the sector size of a hard disk. I wanted to read the file located in /sys/block/sd[X]/queue/hw_sector_size, and it worked in CentOS 6/7.

However when I tested in CentOS 5.11, the file hw_sector_size is missing, and I have only found max_hw_sectors_kb and max_sectors_kb.

Thus, I'd like to know how can I determine (APIs) the sector size in CentOS 5, or is there an other better way to do so. Thanks.


回答1:


The fdisk utility displays this information (and runs successfully on kernels older even than than the 2.6.x vintage on CentOS 5), so that seems a likely place to look for an answer. Fortunately, we're living in the wonderful world of open source, so all it requires is a little investigation.

The fdisk program is provided by the util-linux package, so we need that first.

The sector size is displayed in the output of fdisk like this:

Disk /dev/sda: 477 GiB, 512110190592 bytes, 1000215216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes

If we look for Sector size in the util-linux code, we find it in disk-utils/fdisk-list.c:

fdisk_info(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"),
            fdisk_get_sector_size(cxt),
            fdisk_get_physector_size(cxt));

So, it looks like we need to find fdisk_get_sector_size, which is defined in libfdisk/src/context.c:

unsigned long fdisk_get_sector_size(struct fdisk_context *cxt)
{
    assert(cxt);
    return cxt->sector_size;
}

Well, that wasn't super helpful. We need to find out where cxt->sector_size is set:

$ grep -lri 'cxt->sector_size.*=' | grep -v tests
libfdisk/src/alignment.c
libfdisk/src/context.c
libfdisk/src/dos.c
libfdisk/src/gpt.c
libfdisk/src/utils.c

I'm going to start with alignment.c, since that filename sounds promising. Looking through that file for the same regex I used to list the files, we find this:

cxt->sector_size = get_sector_size(cxt->dev_fd);

Which leads me to:

static unsigned long get_sector_size(int fd)
{
    int sect_sz;

    if (!blkdev_get_sector_size(fd, &sect_sz))
        return (unsigned long) sect_sz;
    return DEFAULT_SECTOR_SIZE;
}

Which in turn leads me to the definition of blkdev_get_sector_size in lib/blkdev.c:

#ifdef BLKSSZGET
int blkdev_get_sector_size(int fd, int *sector_size)
{
    if (ioctl(fd, BLKSSZGET, sector_size) >= 0)
        return 0;
    return -1;
}
#else
int blkdev_get_sector_size(int fd __attribute__((__unused__)), int *sector_size)
{
    *sector_size = DEFAULT_SECTOR_SIZE;
    return 0;
}
#endif

And there we go. There is a BLKSSZGET ioctl that seems useful. A search for BLKSSZGET leads us to this stackoverflow question, which includes the following information in a comment:

For the record: BLKSSZGET = logical block size, BLKBSZGET = physical block size, BLKGETSIZE64 = device size in bytes, BLKGETSIZE = device size/512. At least if the comments in fs.h and my experiments can be trusted. – Edward Falk Jul 10 '12 at 19:33



来源:https://stackoverflow.com/questions/40068904/portable-way-to-determine-sector-size-in-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!