В отличие от файловых систем COW, таких как BTRFS и ZFS, традиционные файловые системы Linux, такие как ext4 и XFS, не имеют возможности обнаружить медленную деградацию данных (также известную как bitrot), поскольку они не выполняют контрольное суммирование данных.
Однако при использовании этих файловых систем мы можем хранить и проверять информацию о целостности на уровне блоков, используя dm-integrity.
🐧 Как проверить и восстановить файловую систему EXT4 на Linux
В этом руководстве мы узнаем, как создавать устройства dm-integrity с помощью утилиты integritysetup, а при создании контейнеров LUKS – с помощью cryptsetup.
- 🗂️ Что такое Ext2, Ext3 и Ext4 и как создавать и конвертировать файловые системы Linux
- 🗃️ Btrfs или Ext4 – функциональные возможности, сильные и слабые стороны
Имитация битрота на традиционных файловых системах Linux
Как мы уже говорили, традиционные файловые системы Linux, такие как ext4 и XFS, не имеют возможности проверять целостность данных и не способны обнаружить повреждения.
Давайте продемонстрируем это.
Для начала создадим файл с помощью dd, выделив 512 Мбайт пространства:
С помощью приведенной выше команды мы приказали dd считать 512 блоков по 1 Мбайт каждый с псевдоустройства /dev/zero и записать их в файл «blkdevice» в текущем рабочем каталоге.
Создав файл, мы можем использовать его как блочное устройство и построить на нем файловую систему.
В данном примере мы будем использовать ext4:
Мы можем монтировать файловую систему так же, как если бы мы имели дело с любым другим «настоящим» блочным устройством:
В этот момент мы записываем в файл случайные данные, позволяя им заполнить все свободное пространство:
Мы должны получить результат, аналогичный приведенному ниже:
dd: writing to '/mnt/testfile': No space left on device 976521+0 records in 976520+0 records out 499978240 bytes (500 MB, 477 MiB) copied, 3.95061 s, 127 MB/s
Теперь давайте получим контрольную сумму только что созданного файла:
В этом случае мы получаем следующий результат:
22eba8b04d389cd8f89ce055794823baa85c196e7ef81cc2465fb2a50e0f4f1e /mnt/testfile
Мы принимаем это к сведению и размонтируем файловую систему:
Теперь, чтобы имитировать повреждение данных, или битрот, мы можем записывать случайные данные непосредственно на блочное устройство.
В примере ниже мы указываем, что хотим записать один выходной блок (count=1) размером 1 Мбайт (bs=1M) и начать запись со смещением на 15 выходных блоков того же размера от начала целевого устройства (seek=15).
Мы делаем это, чтобы гарантировать, что покроем область файловой системы, в которой находится «testfile»
Наконец, мы используем conv=notrunc, чтобы гарантировать, что наше «блочное устройство» не будет усечено:
В этот момент мы снова монтируем файловую систему и проверяем, изменилась ли контрольная сумма файла «testfile»:
Вот результат, который мы получаем:
fb91581b5ed08eae9f3f8400d27bed0b4ad5a8fb4742f2fbabcc0ed409792160 /mnt/testfile
Как и ожидалось, контрольная сумма файла стала другой.
Изменение произошло бесшумно: традиционные файловые системы не отслеживают контрольные суммы данных, поэтому у них нет возможности заметить «битрот».
Вот здесь-то и может помочь dm-integrity.
Использование dm-integrity на одном диске
Использование dm-integrity на одном диске не так уж полезно: если в системе с несколькими копиями данных, например в RAID1, поврежденные данные могут быть автоматически заменены неповрежденной копией, то на одном диске это, разумеется, невозможно.
Однако возможность заметить повреждение все же может быть полезна, возможно, как признак возможного отказа диска.
Установка утилиты integritysetup
Чтобы использовать dm-integrity, нам нужно отформатировать наше устройство с помощью утилиты integritysetup.
Чтобы установить ее на Fedora и другие дистрибутивы семейства Red Hat, мы можем выполнить команду:
На OpenSuse (Leap/Tumbleweed) мы можем использовать «zypper» для установки одноименного пакета:
В дистрибутивах Debian и Debian-подобных утилита поставляется в пакете «cryptsetup-bin».
Мы можем установить его, выполнив команду:
В Archlinux утилита integritysetup входит в пакет «cryptsetup», доступный в репозитории «core»:
Создание тома dm-integrity
Чтобы создать том dm-integrity, мы используем утилиту «integritysetup» для форматирования раздела/блочного устройства.
Следуя нашим предыдущим примерам, мы работаем с существующим файлом «blkdevice», рассматривая его как блочное устройство.
Чтобы отформатировать его, мы используем следующую команду:
Нам будет предложено подтвердить, что мы хотим выполнить эту операцию, поскольку она перезапишет все данные на устройстве:
WARNING! ======== This will overwrite data on blkdevice irrevocably. Are you sure? (Type 'yes' in capital letters): YES
После создания тома dm-integrity мы должны открыть его и задать для него имя device-mapper.
В данном руководстве мы используем «testdevice»:
На этом этапе мы можем создать новую файловую систему на сопоставленном устройстве (/dev/mapper/testdevice):
Давайте еще раз смонтируем файловую систему и создадим файл «testfile», заполнив его случайными данными:
Как и раньше, мы следим за контрольной суммой файла:
Пришло время размонтировать файловую систему, закрыть устройство integritysetup и снова смоделировать повреждение данных:
В этот момент мы можем перемонтировать файловую систему и попытаться получить контрольную сумму файла:
На этом этапе мы можем создать новую файловую систему на сопоставленном устройстве (/dev/mapper/testdevice):
Давайте еще раз смонтируем файловую систему и создадим файл «testfile», заполнив его случайными данными:
Как и раньше, мы следим за контрольной суммой файла:
Пришло время размонтировать файловую систему, закрыть устройство integritysetup и снова смоделировать повреждение данных:
В этот момент мы можем перемонтировать файловую систему и попытаться получить контрольную сумму файла:
Как только мы пытаемся прочитать файл, мы получаем ошибку:
sha256sum: /mnt/testdevice: Input/output error
Что же случилось?
Поскольку мы теперь используем dm-integrity, повреждение данных было замечено, и файловая система вернула ошибку ввода/вывода.
Более подробную информацию об инциденте мы можем найти, заглянув в журналы ядра:
Мы должны быть в состоянии прочитать что-то подобное:
[32942.115228] device-mapper: integrity: dm-8: Checksum failed at sector 0x5782 [32942.117906] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 [32942.119440] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 [32942.119532] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 [32942.119614] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758
Использование dm-integrity с избыточностью данных
Как мы уже говорили, при использовании одного диска у нас нет возможности исправить повреждения, поскольку у нас есть только одна копия данных.
Ситуация меняется при использовании избыточности данных, например RAID1.
Давайте смоделируем это. Сначала создадим два файла: blkdevice1 и blkdevice2.
Мы будем использовать их в качестве блочных устройств:
На каждом из них мы создадим том dm-integrity.
Ниже мы используем опцию -q (сокращение от –batch-mode), чтобы пропустить запрос на подтверждение:
Давайте откроем их:
Теперь мы можем собрать устройства в RAID1 с помощью утилиты mdadm:
Мы создаем новый массив с помощью опции –create и указываем путь к устройству: /dev/md0.
Мы указываем уровень RAID с помощью опции –level, количество активных устройств с помощью –raid-devices и, наконец, передаем путь к блочным устройствам, которые мы хотим включить в массив.
Когда RAID собран, мы можем создать файловую систему на результирующем устройстве:
Теперь смонтируем только что созданную файловую систему, запишем файл, заполненный случайными данными, и создадим повреждение данных на первом из двух дисков, входящих в массив:
Теперь мы можем выполнить очистку данных: записав «test» в файл /sys/block/md0/md/sync_action, мы заставим RAID прочитать все блоки данных на всех устройствах:
Как мы уже видели, об ошибках целостности сообщается в журналах ядра.
Вот соответствующая часть:
[36735.559800] md: check of RAID array md0 [36735.579268] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b00 [36735.579465] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b80 [36735.579508] device-mapper: integrity: dm-8: Checksum failed at sector 0x5980 [36735.579522] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a00 [36735.579533] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c80 [36735.579544] device-mapper: integrity: dm-8: Checksum failed at sector 0x5900 [36735.579606] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a80 [36735.579617] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c00 [36735.581460] device-mapper: integrity: dm-8: Checksum failed at sector 0x5780 [36735.582377] device-mapper: integrity: dm-8: Checksum failed at sector 0x5e80 [36737.803123] md: md0: check done.
В этот момент, если мы снова запустим data-scrub и проверим журналы ядра, мы не должны заметить никаких сообщений об ошибках:
[37245.887325] md: check of RAID array md0 [37248.101670] md: md0: check done.
Благодаря dm-integrity повреждение данных было обнаружено и автоматически исправлено.
Использование dm-integrity с LUKS
LUKS (Linux Unified Key Setup) – это стандарт для шифрования дисков в Linux.
При форматировании необработанного блочного устройства или раздела как контейнера LUKS мы можем указать, что хотим использовать dm-integrity без использования integritysetup.
Для этого достаточно вызвать cryptsetup с опцией –integrity и передать в качестве аргумента алгоритм целостности, который мы хотим использовать:
Заключение
В этом уроке мы узнали, как использовать dm-integrity для обеспечения контрольного суммирования и проверки данных на уровне блоков при использовании традиционных файловых систем Linux.
Возможность проверки поврежденных данных на носителе (bitrot) действительно важна, и особенно полезна при использовании многодисковых систем, где замеченные повреждения данных могут быть автоматически исправлены.
Включение dm-integrity, однако, стоит недешево: помимо прочего, оно приводит к нарушениям записи, поскольку по умолчанию записывает данные о секторах и метки целостности в журнал.
В этой статье, по понятным причинам, мы упомянули не все возможные опции, которые можно использовать для тонкой настройки dm-integrity. Чтобы узнать об этом больше, пожалуйста, загляните на manpage integritysetup и в соответствующую документацию.







