在 Linux 中确定扇区大小的便携式方法

ves*_*tio 2 c linux hard-drive sysfs

我想用C编写一个小程序,它可以确定硬盘的扇区大小。我想读取位于 中的文件/sys/block/sd[X]/queue/hw_sector_size,它在 CentOS 6/7 中工作。

然而,当我在CentOS的5.11测试,文件hw_sector_size丢失,我只找到max_hw_sectors_kbmax_sectors_kb

因此,我想知道如何确定(API)CentOS 5 中的扇区大小,或者是否有其他更好的方法可以做到这一点。谢谢。

lar*_*sks 9

fdisk实用程序显示此信息(并在比 CentOS 5 上的 2.6.x 版本更旧的内核上成功运行),因此这似乎是一个寻找答案的地方。幸运的是,我们生活在开源的美妙世界中,因此只需要进行一点调查即可。

fdisk程序由util-linux包提供,因此我们首先需要它。

扇区大小显示在如下输出中fdisk

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

如果我们Sector sizeutil-linux代码中查找,我们会在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));
Run Code Online (Sandbox Code Playgroud)

所以,看起来我们需要 find fdisk_get_sector_size,它在libfdisk/src/context.c 中定义:

unsigned long fdisk_get_sector_size(struct fdisk_context *cxt)
{
    assert(cxt);
    return cxt->sector_size;
}
Run Code Online (Sandbox Code Playgroud)

嗯,这不是很有帮助。我们需要找出cxt->sector_size设置的位置:

$ 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
Run Code Online (Sandbox Code Playgroud)

我将从 开始alignment.c,因为该文件名听起来很有希望。通过文件我用来列出文件相同的正则表达式来看,我们发现这个

cxt->sector_size = get_sector_size(cxt->dev_fd);
Run Code Online (Sandbox Code Playgroud)

这导致我:

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;
}
Run Code Online (Sandbox Code Playgroud)

这反过来又导致我的定义blkdev_get_sector_size的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
Run Code Online (Sandbox Code Playgroud)

我们走了。有一个BLKSSZGET ioctl似乎很有用。搜索BLKSSZGET将我们引向这个 stackoverflow question,其中在评论中包含以下信息:

记录:BLKSSZGET = 逻辑块大小,BLKBSZGET = 物理块大小,BLKGETSIZE64 = 设备大小(以字节为单位),BLKGETSIZE = 设备大小/512。至少如果 fs.h 中的评论和我的实验是可信的。– Edward Falk 2012 年 7 月 10 日,19:33