пятница, 21 сентября 2012 г.

Solaris 10: ZONECFG - Segmentation Fault

В свое время я написал серию статей о конфигурировании зон Solaris 10. Недавно мне пришлось тряхнуть стариной и вспомнить о своем конфигураторе. И вдруг - внезапно! - обнаружилось, что ни на одной машине мой конфигуратор не работает.

Обнаружилась занятная ошибка:

root @ pegasus /patch # zoneinst.sh zone1.cfg
Segmentation Fault - core dumped
zone1: No such zone configured
Cannot set a resource-specific property from the global scope.
The end command only makes sense in the resource scope.
zone1: No such zone configured
zone1: No such zone configured
zone1: No such zone configured
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
The end command only makes sense in the resource scope.
zone1: No such zone configured
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
The end command only makes sense in the resource scope.
zone1: No such zone configured
Cannot set a resource-specific property from the global scope.
Cannot set a resource-specific property from the global scope.
The end command only makes sense in the resource scope.
Zone zone1 configured.
______________________
Press to install zone or to cancel.
^C

Более того, ошибка проявлялась сразу же при первом запуске zonecfg:

+ /usr/sbin/zonecfg -z zone1 create; set autoboot=true; set zonepath=/data/zone1; 
Segmentation Fault - core dumped


Вскрытие сначала привело сюда:

root @ ktulhu /patch # ldd /usr/sbin/zonecfg libz.so.1 => /usr/local/lib/libz.so.1 libz.so.1 (SUNW_1.1) => (version not found)

А затем сюда:

root @ ktulhu /patch # find / -name libz.so.1
/usr/lib/amd64/libz.so.1
/usr/lib/libz.so.1
/usr/local/lib/libz.so.1
^C
root @ ktulhu /patch # echo $LD_LIBRARY_PATH
/lib:/usr/local/lib:/usr/local/ssl/lib:/usr/local/BerkeleyDB.4.2/lib:
root @ ktulhu /patch # export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
root @ ktulhu /patch # echo $LD_LIBRARY_PATH
/usr/lib:/lib:/usr/local/lib:/usr/local/ssl/lib:/usr/local/BerkeleyDB.4.2/lib:
root @ ktulhu /patch # ldd /usr/sbin/zonecfg
libzonecfg.so.1 => /usr/lib/libzonecfg.so.1
libl.so.1 => /usr/lib/libl.so.1
libnsl.so.1 => /usr/lib/libnsl.so.1
libtecla.so.1 => /usr/lib/libtecla.so.1
libzfs.so.2 => /usr/lib/libzfs.so.2
libbrand.so.1 => /usr/lib/libbrand.so.1
libc.so.1 => /usr/lib/libc.so.1
libsocket.so.1 => /usr/lib/libsocket.so.1
libuuid.so.1 => /usr/lib/libuuid.so.1
libnvpair.so.1 => /usr/lib/libnvpair.so.1
libsysevent.so.1 => /usr/lib/libsysevent.so.1
libsec.so.1 => /usr/lib/libsec.so.1
libpool.so.1 => /usr/lib/libpool.so.1
libscf.so.1 => /usr/lib/libscf.so.1
libproc.so.1 => /usr/lib/libproc.so.1
libuutil.so.1 => /usr/lib/libuutil.so.1
libxml2.so.2 => /usr/lib/libxml2.so.2
libmp.so.2 => /usr/lib/libmp.so.2
libmd.so.1 => /usr/lib/libmd.so.1
libcurses.so.1 => /usr/lib/libcurses.so.1
libm.so.2 => /usr/lib/libm.so.2
libdevinfo.so.1 => /usr/lib/libdevinfo.so.1
libdevid.so.1 => /usr/lib/libdevid.so.1
libgen.so.1 => /usr/lib/libgen.so.1
libavl.so.1 => /usr/lib/libavl.so.1
libefi.so.1 => /usr/lib/libefi.so.1
libadm.so.1 => /usr/lib/libadm.so.1
libumem.so.1 => /usr/lib/libumem.so.1
libdoor.so.1 => /usr/lib/libdoor.so.1
libexacct.so.1 => /usr/lib/libexacct.so.1
librtld_db.so.1 => /usr/lib/librtld_db.so.1
libelf.so.1 => /usr/lib/libelf.so.1
libctf.so.1 => /usr/lib/libctf.so.1
libpthread.so.1 => /usr/lib/libpthread.so.1
libz.so.1 => /usr/lib/libz.so.1

То есть, для устранения ошибки достаточно было правильно установить переменную LD_LIBRARY_PATH, причем желательно это сразу сделать в глобальном профиле /etc/profile.

Причем, как обычно и случается, оказалось также, что ничто не ново под луной и все это уже однажды было. :)

Дальнейшее детальное исследование обнаружило, что в свежеустановленных Солярисах данная проблема не наблюдается, но вот в сильно кастомизированных серверах, с установленными дополнительными пакетами, весьма вероятна.

Резюмируя вышесказанное, следует заметить, что в реальных системах следует весьма вдумчиво подходить к формированию окружения и, главное, формировать переменную LD_LIBRARY_PATH таким образом, чтобы системные библиотеки находились первыми.

среда, 19 сентября 2012 г.

Анатомия ZFS часть VI

При написании данного цикла статей использовался документ ZFS On-Disk Specification,Sun Microsystems

1.4.         Adaptive Replacement Cache (ARC)

Адаптивный замещающий кэш (Adaptive Replacement Cache, ARC) – совершенно новое слово в технологиях кэширования*.
Первоначальный алгоритм разработан Мегиддо и Модха (N. Megiddo, D. Modha) в 2003 году (представлен на FAST). Он реализован в ZFS с несколькими существенными отличиями:
·        Согласно модели первоначального алгоритма, любая страница является выгружаемой. Это делает алгоритм вытеснения очень простым – выгружается всегда последняя страница кэша. В ARC используется более сложная модель: часть страниц остается заблокированной на основе подсччета количества ссылок на них. Блокировка вытеснения снимается лишь в отсутствие внешних ссылок на страницу. Существуют периоды, когда вытеснение страниц запрещается. В это время изменение размеров кэша запрещено. С целью избежания неограниченного роста кэша реализовано так называемое «охлаждение кэша», основанное на замедлении загрузки кэша пока запрос на пространство не сможет быть удовлетворен
·        Первоначальный алгоритм использует кэш фиксированного размера. Страницы вытесняются когда кэш полон и начинают фиксироваться кэш-промахи. В ARC используется кэш переменного размера, однако используемый с таким расчетом, чтобы освобождать память по первому требованию в случае поступления запросов на память от операционной системы. Иными словами, кэш будет сокращаться в случае исчерпания памяти, доступной операционной системе
·        Первоначальная модель предполагает фиксированный размер страниц. Модель ARC использует страницы переменного размера (от 512 байт до 128 Кбайт), что позволяет очень просто удовлетворять запросы на память – достаточно освободить страницу необходимого размера. Это позволяет лучше использовать оперативную память и заполнять ее более полно в процессах загрузки и вытеснения страниц**.

ARC использует две модели освобождения страниц – консервативную и агрессивную:

typedef enum arc_reclaim_strategy { 
 ARC_RECLAIM_AGGR, /* Aggressive reclaim strategy */ 
 ARC_RECLAIM_CONS /* Conservative reclaim strategy */ 
 } arc_reclaim_strategy_t;

Консервативная модель используется в обычном режиме работы, агрессивная задействуется в случаях, когда давление на память со стороны операционной системы растет.Интервал проверки возможности увеличения размеров кэша по умолчанию составляет 60 секунд. Страничный буфер ARC может находиться в одном из 6 возможных состояний:

· ARC_anon - анонимный
· ARC_mru  - недавно использовался, кэширован
· ARC_mru_ghost            - давно использовался, больше не в кэше
· ARC_mfu           - часто использовался, в настоящее время в кэше
· ARC_mfu_ghost            - часто использовался, больше не в кэше
· ARC_l2c_only   - существует в кэше второго вроня, но не в одном из других состояний

Когда буфер не имеет ни одной внешней ссылки, он присоединяется к одному из данных списков. Только буферы без ссылок могут быть удалены или вытеснены. В каждом из списков данные разделены на группы – метаданные и собственно данные.
Анонимные буферы – это буферы, с которыми не ассоциированы никакие DVA (см. Главу 1.2.1). Данные буферы содержат грязные копии блоков, которые должны быть записаны в стабильный пул. По определению, данные буферы считаются ссылаемыми (на них существуют ссылки) и являются частью списка, который не может быть освобожден (ARC_mru). В общем случае, они получают DVA при записи и помещаются в список ARC_mru.
ARC использует модель интеллектуальной адаптивной предвыборки и быстрого прогрева (turbo warmup).
Мы не будем в деталях обсуждать механизмы предвыборки, заметим лишь, что требования по оперативной памяти к ARC достаточно высоки, однако это не мешает эффективно использовать ARC на системах с объемом оперативной памяти 1-2 Гб.
При нормальных условиях ARC, используя механизмы быстрого прогрева, достаточно быстро заполняет свободную оперативную память. Такое же поведение характерно и для кэшей UFS, разница, однако, в том, что память, занимаемая буферами UFS, считается (и показывается) свободной. Следует помнить, однако, что ZFS освобождает память по первому требованию, следовательно, данная память может считаться условно свободной.
ZFS использует кэширование на двух уровнях –файловом уровне и уровне vdev. Используя DTrace, ZFS определяет паттерны чтения программных модулей, и затем формирует очереди предвыборки в соответствие с этими паттернами. Таким образом обеспечивается интеллектуальная предвыборка данных в соответствие с запросами приложений.
В некоторых приложениях, использующих собственные механизмы кэширования и/или нуждающихся непосредственно в свободной памяти, существует механизм уменьшения предпочитаемого размера ARC до заданной величины.

Это ограничение устанавливается параметром zfs:zfs_arc_max файла /etc/system, размер задается в байтах, например: 

set zfs:zfs_arc_max=1073741824
Существует утилита  Бена Роквуда (Ben Rockwood, benr@cuddletech.com), arc_summary.pl, написанная на perl, позволяющая получать аггрегированную статистику работы ARC:
 
root @ pegasus / # arc_summary.pl
System Memory:
         Physical RAM:  1491 MB
         Free Memory :  346 MB
         LotsFree:      23 MB
 
ZFS Tunables (/etc/system):
 
ARC Size:
         Current Size:             198 MB (arcsize)
         Target Size (Adaptive):   474 MB (c)
         Min Size (Hard Limit):    64 MB (zfs_arc_min)
         Max Size (Hard Limit):    474 MB (zfs_arc_max)
 
ARC Size Breakdown:
         Most Recently Used Cache Size:          49%    236 MB (p)
         Most Frequently Used Cache Size:        50%    237 MB (c-p)
 
ARC Efficency:
         Cache Access Total:             76283
         Cache Hit Ratio:      91%       69456          [Defined State for buffer]
         Cache Miss Ratio:      8%       6827           [Undefined State for Buffer]
         REAL Hit Ratio:       80%       61217          [MRU/MFU Hits Only]
 
         Data Demand   Efficiency:    95%
         Data Prefetch Efficiency:    23%
 
        CACHE HITS BY CACHE LIST:
          Anon:                       11%        8207                   [ New Customer, First Cache Hit ]
          Most Recently Used:         22%        15867 (mru)            [ Return Customer ]
          Most Frequently Used:       65%        45350 (mfu)            [ Frequent Customer ]
          Most Recently Used Ghost:    0%        16 (mru_ghost) [ Return Customer Evicted, Now Back ]
          Most Frequently Used Ghost:  0%        16 (mfu_ghost) [ Frequent Customer Evicted, Now Back ]
        CACHE HITS BY DATA TYPE:
          Demand Data:                67%        47080 
          Prefetch Data:               0%        556 
          Demand Metadata:            20%        13925 
          Prefetch Metadata:          11%        7895 
        CACHE MISSES BY DATA TYPE:
          Demand Data:                35%        2407 
          Prefetch Data:              26%        1802 
          Demand Metadata:            18%        1257 
          Prefetch Metadata:          19%        1361 
---------------------------------------------
 
Данная утилита является одной из наиболее удобных и используется автором для мониторинга систем, использующих ZFS.

1.4.         Тома ZFS (ZVOL)

Тома ZFS (ZVOL) предоставляют механизм создания логических устройств. Тома ZFS экспортируются как блочные устройства и могут использоваться подобно другим блочным устройствам:

root @ pegasus / # zfs list |grep test
root @ pegasus / # zpool status data2
  pool: data2
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        data2       ONLINE       0     0     0
          c4t0d0    ONLINE       0     0     0
        logs
          c4t1d0    ONLINE       0     0     0

errors: No known data errors
root @ pegasus / # zfs create -V 1g data2/test1
root @ pegasus / # zfs create -V 1g data2/test2
root @ pegasus / # zfs list | grep test
data2/test1                       1G  3.00G    16K  -
data2/test2                       2G  3.00G    16K  -

root @ pegasus / # newfs /dev/zvol/dsk/data2/test2       
newfs: construct a new file system /dev/zvol/rdsk/data2/test2: (y/n)? y
Warning: 2082 sector(s) in last cylinder unallocated
/dev/zvol/rdsk/data2/test:      4194270 sectors in 683 cylinders of 48 tracks, 128 sectors
        2048.0MB in 43 cyl groups (16 c/g, 48.00MB/g, 11648 i/g)
super-block backups (for fsck -F ufs -o b=#) at:
 32, 98464, 196896, 295328, 393760, 492192, 590624, 689056, 787488, 885920,
 3248288, 3346720, 3445152, 3543584, 3642016, 3740448, 3838880, 3937312,
 4035744, 4134176
root @ pegasus / # mount -F ufs /dev/zvol/dsk/data2/test /test1
root @ pegasus / # df –h | grep test1
/dev/zvol/dsk/data2/test   1.9G   2.0M   1.9G     1%    /test1
root @ pegasus / # umount /test1
root @ pegasus / # zfs destroy data2/test2

Тома ZFS представлены как объекты типа DMU_OST_ZVOL. Объект ZVOL имеет очень простой формат и содержит два объекта: объект свойств и объект данных, DMU_OT_ZVOL_PROP и DMU_OT_ZVOL соответственно. Оба объекта имеют статически назначенный ID. Объекты описаны ниже:
· DMU_OT_ZVOL_PROPZAP-объект, содержащий атрибуты тома, такие, например, как размер (volsize, может быть изменен динамически) и др.
· DMU_OT_ZVOL – объект содержит виртуальное блочное устройство

 ____________________
* Данная статья основана на исходных текстах ARC, доступных по ссылке http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/zfs/arc.c
** См. также "ARC: A Self-Tuning, Low Overhead Replacement Cache" by N. Megiddo & D. Modha, FAST 2003

Анатомия ZFS часть V

При написании данного цикла статей использовался документ ZFS On-Disk Specification,Sun Microsystems

1.4.         ZAP – ZFS Attribute Processor

ZAP – Процессор артибутов ZFS – это модуль, который находится на вершине DMU и управляет объектами ZAP. Объекты ZAP – это объекты DMU, хранящиеся в виде пар «имя-значение». Именная часть имеет размер до 256 байт, включая концевой NULL, часть «значение» является массивом целых чисел, размер которого лимитируется только размером блока ZAP.
ZAP-объекты используются для хранения свойств датасетов, нахождения объектов файловой системы, хранения свойств пулов и других подобных задач.
ZAP-объекты используются в двух формах: микроZAP объекты и большие ZAP-объекты (microzap и fatzap). МикроZAP объекты представляют собой облегченную версию больших ZAP-объектов и предоставляют простой и быстрый механизм доступа к относительно малому количеству атрибутов. В свою очередь, большие ZAP-объекты лучше подходят в ситуациях, когда атрибутов много.
Следующий набор правил определяет, когда будет использована та или иная форма ZAP-объектов:
МикроZAP объекты будут использованы в случае, если выполняются все три правила:
· Все пары «имя-значение» целиком помещаются в один блок. Максимальный размер блока 128 Кбайт и в него помещается 2047 значений микроZAP.
· Значение для всех атрибутов является беззнаковым целым.
· Длина имени в парах «имя-значение» не превышает 50 символов (включая терминирующий NULL).

Если хотя бы одно условие из вышеперечисленных не выполняется, используются большие ZAP-объекты.

1.4.         ZPL – ZFS POSIX Layer

ZPLZFS POSIX Layer – заставляет DMU выглядеть как объекты файловой системы POSIX. ZFS, таким образом, предоставляет все необходимые сервисы POSIX.
ZPL представляет файловые системы как объект DMU_OST_ZFS. Все снапшоты, клоны и файловые системы представлены (и реализованы) как объект данного типа.

Устройство файловой системы ZPL
Объектный набор ZPL представлен одним объектом в фиксированной позиции и фиксированного размера. Этот объект называется главной нодой (master node) и всегда имеет номер объекта, равный 1. Главная нода – это ZAP-объект, содержащий три атрибута: DELETE_QUEUE, VERSION и ROOT.
· DELETE_QUEUE – представляет очередь удаления в случаях, когда файловая система находилась в переходном состоянии, например, в результате принудительного размонтирования или отказа питания. В следующее успешное монтирование очередь удаления применяется к файловой системе с целью приведения ее в целостное состояние. Данный механизм используется с целью предотвращения так называемых утечек файлов и директорий.
· VERSIONZPL-версия, используемая для данной файловой системы. Текущее значение равно 1.
· ROOT – 64-битное целое. Данный атрибут содержит вершинный номер объекта директории верхнего уровня иерархии данной файловой системы, корневой директории.

Директории и обход директорий
Директории файловых систем реализованы в виде ZAP-объекта типа DMU_OT_DIRECTORY. Каждая директория содержит пары «имя-значение», которые водержат имена и номера объектов, содержащихся в директории. Обход дерева директории, таким образом, представляет собой простой просмотр значений и нахождение требуемых номеров объектов.
Все объекты файловой системы содержат физическую структуру znode_phys_t в бонусном буфере своей d-ноды. Данная структура содержит атрибуты объекта файловой системы:
·   zp_atime – два 64-битных целых, содержащие время последнего доступа в секундах(zp_atime[0]) и наносекундах(zp_atime[1]) после 1 января 1970 года
·   zp_mtime - два 64-битных целых, содержащие время последней модификации объекта в секундах(zp_mtime[0]) и наносекундах(zp_mtime[1]) после 1 января 1970 года
·   zp_ctime - два 64-битных целых, содержащие время последнего изменения файла в секундах(zp_ctime[0]) и наносекундах(zp_ctime[1]) после 1 января 1970 года
· zp_crtime - два 64-битных целых, содержащие время создания файла в секундах(zp_crtime[0]) и наносекундах(zp_crtime[1]) после 1 января 1970 года
·   zp_gen 64-битный номер группы транзакции на момент создания объекта
·  zp-mode – 64-битное целое, содержащиее режим (mode) файла и его тип. Младшие 8 бит содержат флаги доступа, например, 755. 9й бит представляет бит-липучку (sticky). Биты 13-16 представляют из себя биты типа файла и описаны в таблице ниже.

Тип
Описание
Битовое значение
S_IFIFO
Fifo
0x1
S_IFCHR
Character Special Device
0x2
S_IFDIR
Directory
0x4
S_IFBLK
Block Special Device
0x6
S_IFREG
Regular file
0x8
S_IFLINK
Symbolic link
0xA
S_IFSOCK
Socket
0xC
S_IFDOOR
Door
0xD
S_IFPORT
Event port
0xE

Рис.8 Таблица типов файлов и ассоциированных битовых значений

·  zp_size – размер файла в байтах
·  zp_parent ID объекта родительской директории, содержащей данный файл
·  zp_linksколичество хардлинков на данный файл
· zp_xattrID ZAP-объекта, содержащий скрытый атрибут директории. Он обрабатывается как нормальный атрибут ZFS, исключая случаи, когда установлен и приложению необходимо войти в него посредством функции openat()
·  zp_rdev dev_t для файлов типа S_IFCHR и S_IFBLK
·  zp_flags – постоянные флаги файлов:
o       ZFS_XATTR – 0x1
o       ZFS_INHERIT_ACE – 0x2
·  zp_uid64-битное целое uid_t владельца файла
·  zp_gid64-битное целое gid_t группы файла
· zp_aclСтруктура zfs_znode_acl, содержащая все ACL данного файла. Данная структура описывается ниже.

Списки контроля доступа ZFS (ZFS Access Control Lists)
Списки контроля доступа (ACL) предоставляют механизм выборочного ограничения и/или предоставления доступа к объектам файловой системы. ACL реализованы в ZFS как таблица, содержащая ACE (Access Control Entries).

Структура zfs_znode_acl следующая:
o       z_acl_extern_obj – Номер (ID) объекта, используемого для хранения ACL, не помещающихся в znode (свыше 6 ACE). Тип объекта внешнего ACL всегда будет DMU_OT_ACL
o       z_acl_countсчетчик ACE для ACL
o       z_acl_versionзарезервировано для будущего использования
o       z_acl_padзарезервировано для будущего использования
o       z_ace_data массив, содержащий до 6 ACE

Структура каждого ACE следующая:

·        a_who -  данное поле имеет смысл лишь тогда, когда флаги ACE_OWNER, ACE_GROUP или ACE_EVERYONE (устанавливаемые для a_flag, описывается ниже) не используются. Если в a_flag установлено значение ACE_IDENTIFIER_GROUP, поле содержит GID. Во всех остальных случаях поле будет содержать UID.
·        a_access_mask32-битная маска доступа. Значения приведены в таблице:
Атрибут
Значение
ACE_READ_DATA
0x00000001
ACE_LIST_DIRECTORY
0x00000001
ACE_WRITE_DATA
0x00000002
ACE_ADD_FILE
0x00000002
ACE_APPEND_DATA
0x00000004
ACE_ADD_SUBDIRECTORY
0x00000004
ACE_READ_NAMED_ATTRS
0x00000008
ACE_WRITE_NAMED_ATTRS
0x00000010
ACE_EXECUTE
0x00000020
ACE_DELETE_CHILD
0x00000040
ACE_READ_ATTRIBUTES
0x00000080
ACE_WRITE_ATTRIBUTES
0x00000100
ACE_DELETE
0x00010000
ACE_READ_ACL
0x00020000
ACE_WRITE_ACL
0x00040000
ACE_WRITE_OWNER
0x00080000
ACE_SYNCHRONIZE
0x00100000

·        a_flags16-битное целое, представляющее тип записи ACL и флаги наследования.
Флаг ACE
Значение
ACE_FILE_INHERIT_ACE
0x0001
ACE_DIRECTORY_INHERIT_ACE
0x0002
ACE_NO_PROPAGATE_INHERIT_ACE
0x0004
ACE_INHERIT_ONLY_ACE
0x0008
ACE_SUCCESSFUL_ACCESS_ACE_FLAG
0x0010
ACE_FAILED_ACCESS_ACE_FLAG
0x0020
ACE_IDENTIFIER_GROUP
0x0040
ACE_OWNER
0x1000
ACE_GROUP
0x2000
ACE_EVERYONE
0x4000
·        a_type – тип ACE:

Тип
Значение
Описание
ACE_ACCESS_ALLOWED_ACE_TYPE
0x0000
Предоставляет доступ как описано в a_access_mask
ACE_ACCESS_DENIED_ACE_TYPE
0x0001
Запрещает доступ как описано в a_access_mask
ACE_ACCESS_AUDIT_ACE_TYPE
0x0002
Флаг аудита – в текущей версии не реализовано
ACE_ACCESS_ALARM_ACE_TYPE
0x0003
Флаг тревоги – в текущей версии не реализовано



1.4.         ZFS Intent Log (ZIL)

Журнал намерений (ZFS Intent Log, ZIL) сохраняет системные вызовы транзакционных записей, изменяющих состояние файловой системы в памяти, с достаточным количеством информации для последующего воспроизведения. Эти изменения сохраняются в памяти до тех пор, пока транзакционная группа DMU не будет сохранена в стабильный пул (тогда записанные изменения могут быть стерты) либо изменения сбрасываются в стабильный лог (также принадлежащий пулу) в рамках вызова fsync или O_DSYNC.
На каждую файловую систему создается один лог. Лог может находиться внутри файловой системы или создан на отдельном устройстве (устройствах):

root @ pegasus / # zpool create data2 c4t0d0 log c4t1d0
root @ pegasus / # zpool status data2
  pool: data2
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        data2       ONLINE       0     0     0
          c4t0d0    ONLINE       0     0     0
        logs
          c4t1d0    ONLINE       0     0     0

errors: No known data errors

 Лог содержит три типа записей:
·        Заголовок ZIL (ZIL header)
·        Блоки ZIL
·        Записи ZIL



Записи ZIL содержат системные вызовы дисковых транзакций. Блоки содержат транзакции и образуют цепочки. Каждый блок содержит указатель (blkptr_t) на следующий блок в цепочке. Блоки могут быть разного размера. Заголовок ZIL указывает на первый блок в цепочке. Блоки располагаются не на фиксированных позициях, а динамически выделяются и освобождаются по мере необходимости.
Заголовок журнала один на весь журнал и имеет очень простую структуру. Блоки ZIL содержат записи. Блоки выделяются по необходимости и имеют различный размер. Размер является частью записи блочного указателя blkptr_t. Блоки заполнены записями и содержат трейлер zil_trailer_t в конце каждого блока.
Запись ZIL содержит общую структуру, за которой следует специфичная для записи структура. Каждая транзакция в общей структуре помечается флагом типа транзакции:

Флаг
Значение
Описание
TX_CREATE
1
Create file
TX_MKDIR
2
Make directory
TX_MKXATTR
3
Make XATTR directory
TX_SYMLINK
4
Create symbolic link
TX_REMOVE
5
Remove file
TX_RMDIR
6
Remove directory
TX_LINK
7
Create hard link
TX_RENAME
8
Rename file
TX_WRITE
9
File write
TX_TRUNCATE
10
Truncate file
TX_SETATTR
11
Set file attributes
TX_ACL
12
Set ACL

Для каждой записи (транзакции) перечисленного выше общего типа есть специфическая внутренняя структура с данными, необходимыми для воспроизведения транзакции (обычно один вызов VOP). Уровень VOP ввыполняет передачу указателей из памяти к v-нодам. Затем они конвертируются в объектные идентификаторы стабильного пула. При воспроизведении транзакций уровень VOP вызывается еще раз. Для этого объект повторно открывается и передается к v-нодам. 


(продолжение следует)