Если вы обратили внимание, утилиты для работы с zfs: zfs и zpool выводят все размерные характеристики: размер пула, квоты на файловую систему и т.п. в т.н. Human-Readable Format, то есть в мегабайтах и гигабайтах - десятичными дробями. Никакой опции для изменения подобного поведения не существует. Все дело в том, что административная библиотека libzfs всегда вызывает функцию zfs_nicenum:
libzfs_pool.c#270
Посмотрим, каким образом можно узнать точный размер пула. Для начала я обратился к mdb -k и его командам для работы со spa. Однако в самой структуре spa_t я не нашел поля, отвечающего за размер всего пула - только используя spa_config смог узнать размер VDEVов, в пул входящих:
> ::spa
ADDR STATE NAME
e2693480 ACTIVE tank
> e2693480::spa_config
version=000000000000000a
name='tank'
<cut>
vdev_tree
type='root'
id=0000000000000000
guid=46a625bc361d7d57
children[0]
type='disk'
<cut>
asize=0000000012a80000
<cut>
Соответственно поле asize - и есть размер диска в VDEV. Тогда я вспомнил, что в DTrace есть замечательный провайдер pid, служащий для отладки пользовательских приложений. Почему бы не воспользоваться им для выковыривания информации напрямую из libzfs?
Анализ кода показал, что для получения свойств пула (нам потребуется только имя и собственно размер) - вызывается функция zfs_get_prop: libzfs_pool.c#zpool_get_prop , второй параметр которой - номер свойства. 0 - ZPOOL_PROP_NAME - имя пула, 1 - ZPOOL_PROP_SIZE - его размер. Для получения непосредственно значений свойств вызываются zpool_get_prop_string и zpool_get_prop_int.
Создадим простой скрипт для получения данных:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target:libzfs:zpool_get_prop:entry
/arg1 == 1/
{
self->getsize = 1;
}
pid$target:libzfs:zpool_get_prop:entry
/arg1 == 0/
{
self->getname = 1;
}
pid$target:libzfs:zpool_get_prop_int:return
/self->getsize/
{
printf(" - %d \n", arg1);
self->getsize = 0;
}
pid$target:libzfs:zpool_get_prop_string:return
/self->getname/
{
printf("%s", copyinstr(arg1));
self->getname = 0;
}
Соответственно при вызове zpool_get_prop со значениями 0 или 1 будет установлен флаг self->getname и self->getsize соответственно. После этого сработают пробы на функции zpool_get_prop_string и zpool_get_prop_int. Они выведут необходимую информацию на пробе return и сбросят флаги.
Запускаем скрипт на команде zpool list:
root@tiger # dtrace -s /zpoolan.d -c 'zpool list'
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
tank 298M 111K 298M 0% ONLINE -
tank - 312475648
tank - 312475648
Размер пула tank - 312 475 648 байт.