2016-10-16 13 views
0

Я хочу написать небольшую программу на C, которая может определить размер сектора на жестком диске. Я хотел прочитать файл, расположенный в /sys/block/sd[X]/queue/hw_sector_size, и он работал в CentOS 6/7.Портативный способ определения размера сектора в Linux

Однако, когда я тестировал в CentOS 5.11, отсутствует файл hw_sector_size, и я нашел только max_hw_sectors_kb и max_sectors_kb.

Таким образом, я хотел бы знать, как определить (API) размер сектора в CentOS 5, или есть другой лучший способ сделать это. Благодарю.

ответ

3

Утилита fdisk отображает эту информацию (и работает успешно на ядрах старше, чем на 2.6.x vintage на CentOS 5), поэтому кажется вероятным местом поиска ответа. К счастью, мы живем в прекрасном мире с открытым исходным кодом, поэтому все, что требуется, - это небольшое исследование.

Программа 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 

Если мы ищем Sector size в util-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)); 

Итак, это похоже, нам нужно найти fdisk_get_sector_size, который определен в libfdisk/src/context.c:

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

Ну, это было не очень полезно. Нам нужно выяснить, где 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 

Я собираюсь начать с alignment.c, так что имя файла звучит многообещающе. Просматривая этот файл для того же регулярное выражение, я использовал список файлов, мы находим this:

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

Что приводит меня к:

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; 
} 

Который в свою очередь, приводит меня к определению 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 

И вот мы идем. Существует BLKSSZGETioctl, что кажется полезным. Поиски BLKSSZGET приводит нас к this stackoverflow question, который включает в себя следующую информацию в комментариях:

Для записи: BLKSSZGET = размер логического блока, BLKBSZGET = физический размер блока, BLKGETSIZE64 = размер устройства в байтах, BLKGETSIZE = устройство размер/512. По крайней мере, если комментарии в fs.h и моих экспериментах могут быть доверенным. - Edward Falk Jul 10 '12 at 19:33

+1

Это абсолютно потрясающе! Спасибо много larsks! – vesontio