Повреждение файловой системы ext4 встречается чаще, чем хотелось бы администраторам: сбой питания в момент записи, ошибка контроллера диска, некорректное отключение носителя или баг в ядре оставляют раздел в состоянии, когда стандартные средства монтирования отказываются работать. В такой ситуации TestDisk становится одним из немногих инструментов, способных вернуть доступ к этим без обращения к специализированным лабораториям. Ниже - пошаговое описание процесса от загрузки с Live-носителя до копирования уцелевших файлов на резервный диск.
Подготовка среды и загрузка с Live-USB
Любые манипуляции с повреждённым разделом должны выполняться на отмонтированной файловой системе. Работающая ОС может кэшировать метаданные, а фоновые службы вроде systemd-journald или updatedb периодически обращаются к диску, усугубляя повреждение. Поэтому первым делом подготавливают загрузочную флешку с SystemRescue, GParted Live или любой сборкой на базе Arch и Debian, где уже присутствуют testdisk, ddrescue, e2fsprogs, parted и smartmontools.
Записывают образ на флешку командой dd или через Ventoy, загружаются в UEFI-режиме (или Legacy, если диск разбит по MBR) и сразу проверяют имена блочных устройств:
lsblk -f
Вывод покажет файловую систему, метку, UUID и точку монтирования. Целевой раздел - например, /dev/nvme0n1p3 с типом ext4 - не должен быть смонтирован. Если он примонтирован автоматически, отмонтируют:
umount /dev/nvme0n1p3
Перед запуском TestDisk полезно проверить SMART-атрибуты диска, чтобы оценить физическое состояние:
smartctl -a /dev/nvme0n1
Критические атрибуты - Reallocated_Sector_Ct (05), Current_Pending_Sector (C5), Offline_Uncorrectable (C6). Если значения растут, диск умирает физически и любые попытки восстановления только ускорят конец. В таком случае первым делом делают полный образ через ddrescue на другой носитель, а дальше работают только с образом.
Теперь можно запускать TestDisk. В терминале от root:
testdisk
Программа работает в текстовом интерфейсе на базе ncurses. Навигация - стрелками вверх-вниз, Enter подтверждает выбор, Escape возвращает на уровень выше. В нижней части экрана всегда видна подсказка с доступными клавишами для текущего меню.
Анализ геометрии диска и выбор таблицы разделов
При первом запуске TestDisk предлагает создать лог-файл. Рекомендуют выбрать Create - журнал пригодится для повторного анализа и для передачи специалистам, если самостоятельное восстановление не удастся. Лог пишется в текущий каталог под именем testdisk.log. Если лог не нужен, выбирают No Log, но при сложных случаях отказ от логирования обрекает на повторную работу вслепую.
Следующий экран - список обнаруженных физических дисков. Размеры показаны в секторах и в гигабайтах. Выбирают нужный диск (обычно самый большой или тот, чей размер соответствует ожиданиям) и нажимают Enter. Важно: TestDisk определяет геометрию (цилиндры, головки, секторов на дорожку) автоматически через ioctl HDIO_GETGEO. На современных SSD и NVMe геометрия виртуальна, но для старых HDD иногда приходится скорректировать её вручную через меню Geometry, если программа неправильно определила размер диска.
Теперь программа спрашивает тип таблицы разделов. Для современных накопителей это почти всегда GPT (EFI GPT). Если диск старый или разбит под MBR, выбирают Intel. TestDisk 7.2 умеет определять тип автоматически, но ручной выбор исключает ошибку на гибридных схемах. Есть также варианты Mac partition map для старых PowerPC, Sun Solaris для SPARC, а также None для неразмеченных дисков. После выбора типа нажимают Analyse.
Поиск потерянных суперблоков и проверка структуры
Экран Analyse показывает текущую таблицу разделов. Если раздел ext4 отображается корректно - его начала, конец и тип совпадают с ожидаемыми - можно пробовать восстановить файловую систему на месте. Но часто таблица повреждена: раздел не виден, границы сдвинуты, или тип указан как Unknown. Тогда выбирают Quick Search.
Быстрый скан пробегает по началу и концу диска, ищет сигнатуры файловых систем и остатки таблиц разделов. Для ext4 ключевыми сигнатурами являются суперблоки. Основной суперблок находится в смещении 1024 байт от начала раздела (сектор 2 при размере сектора 512 байт). Резервные суперблоки расставлены по группам блоков - их адреса можно узнать через dumpe2fs на рабочем образе или рассчитать по формуле:
sg = 32768 * (group_index) + 1
где group_index - номер группы блоков, начиная с 1. На диске в 1 Тб с размером блока 4К групп около 7600, поэтому резервных суперблоков много. Quick Search находит их сигнатуры и предлагает восстановить раздел по одной из них.
Если Quick Search не дал результата, запускают Deeper Search. Он читает весь диск сектор за сектором, что на HDD может занять часы, на NVMe - минуты. В процессе на экране появляются строки с найденными разделами: начало, конец, размер в секторах, тип файловой системы. Для каждого кандидата можно нажать p - TestDisk покажет содержимое корневой директории. Если видны привычные каталоги (home, var, etc, lost+found) - это нужный раздел.
Выбирают правильный раздел, нажимают Enter, затем Write - программа записывает восстановленную таблицу разделов на диск. После записи требуется перезагрузиться или выполнить partprobe, чтобы ядро обновило информацию о разделах. Иногда после Write раздел появляется в /dev, но файловая система всё равно не монтируется - значит, повреждены метаданные внутри самого раздела, и нужна работа с суперблоками.
Иногда TestDisk находит раздел, но файловая система внутри всё равно не монтируется. Тогда используют fsck.ext4 с явным указанием резервного суперблока. Сначала узнают адреса суперблоков, не монтируя раздел:
dumpe2fs /dev/nvme0n1p3 | grep -i superblock
Команда выведет список вроде:
Primary superblock at 0, Group descriptors at 1-6
Backup superblock at 32768, Group descriptors at 32769-32774
Backup superblock at 98304, Group descriptors at 98305-98310
Backup superblock at 163840, Group descriptors at 163841-163846
Backup superblock at 229376, Group descriptors at 229377-229382
Backup superblock at 294912, Group descriptors at 294913-294918
...
Адреса указаны в блоках файловой системы. Чтобы перевести в байты, умножают на размер блока (обычно 4096). Но fsck.ext4 принимает параметр -b в блоках, поэтому пересчёт не нужен.
Запускают проверку с первым резервным суперблоком:
fsck.ext4 -b 32768 -y /dev/nvme0n1p3
Флаг -y автоматически подтверждает все исправления. Если первый резервный не помог, пробуют следующий из списка. Полезен также флаг -v для подробного вывода и -f для принудительной проверки даже если файловая система помечена чистой. Важно: fsck изменяет метаданные на диске. Перед запуском делают полный образ диска через ddrescue:
ddrescue -f -n /dev/nvme0n1 /mnt/backup/disk.img /mnt/backup/disk.map
Опция -n пропускает плохие секторы на первом проходе, -f принудительно перезаписывает выходной файл. Карта disk.map позволяет потом дойти до проблемных зон повторными запусками без -n. Для второго прохода используют:
ddrescue -f -r3 -d /dev/nvme0n1 /mnt/backup/disk.img /mnt/backup/disk.map
Флаг -r3 означает три попытки чтения каждого плохого сектора, -d включает прямой ввод-вывод, минуя кэш ядра. Если диск шумит или кликает - останавливают процесс, физическое вмешательство требует лаборатории.
Копирование уцелевших данных на резервный носитель
Когда файловая система прошла fsck и монтируется, не спешат копировать файлы обычным cp или rsync - любое чтение может зависнуть на плохом секторе. Используют ddrescue в режиме файлового копирования или утилиту safecopy. Но проще всего смонтировать раздел только для чтения и примонтировать резервный диск:
mount -o ro /dev/nvme0n1p3 /mnt/source
mount /dev/sdb1 /mnt/target
Затем копируют критически важные каталоги rsync с игнорированием ошибок ввода-вывода:
rsync -avh --ignore-errors --progress /mnt/source/home/ /mnt/target/recovered_home/
Флаг --ignore-errors заставит rsync пропустить нечитаемые файлы и продолжить. Для больших массивов данных лучше разбить копирование на этапы: сначала конфиги и скрипты (маленькие, ценные), потом медиафайлы, в конце - кэши и логи, которые можно отбрасывать.
Если раздел не монтируется даже после fsck, TestDisk умеет копировать файлы напрямую из своего интерфейса. На экране со списком разделов выбирают Advanced, затем List. Программа покажет дерево каталогов. Стрелками перемещаются к нужному файлу или каталогу, нажимают c (copy) - TestDisk спросит целевую директорию. Указывают точку монтирования резервного диска. Копирование идёт через внутренние функции библиотеки libext2fs, что часто обходит ошибки, на которых спотыкается ядро. Клавиша h показывает скрытые файлы, клавиша q возвращает на уровень выше.
Работа с повреждённой таблицей inode и lost+found
После успешного fsck в корне раздела часто появляется каталог lost+found. В него попадают файлы, чьи inode не привязаны к каталогам - "висячие" inode. Имена у них теряются, остаются только номера inode. Восстановить исходные имена автоматически нельзя, но можно определить тип файла командой file и по содержимому угадать назначение:
file /mnt/source/lost+found/#123456
Если это текстовый конфиг, база данных SQLite, JPEG - переименовывают и кладут в соответствующее место. Скрипты на Python или Bash помогают автоматизировать сортировку по MIME-типу. Пример однострочника для разбора lost+found:
for f in /mnt/source/lost+found/*; do mime=$(file -b --mime-type "$f"); case $mime in text/*) mv "$f" "/mnt/target/text_$(basename $f)";; image/*) mv "$f" "/mnt/target/img_$(basename $f)";; application/x-sqlite3) mv "$f" "/mnt/target/db_$(basename $f).sqlite";; esac; done
Помимо lost+found, ext4 хранит журнал (journal) - круговой буфер транзакций. Если журнал повреждён, fsck может его пересоздать (опция -j), но данные, не зафиксированные в журнале к моменту сбоя, потеряны. В ext4 журнал находится в inode 8, его размер по умолчанию 128 Мб. Проверить состояние журнала можно через debugfs:
debugfs -R "dump <8> /tmp/journal.bin" /dev/nvme0n1p3
Проверка целостности скопированных данных
Завершающим этапом считают контрольные суммы исходных и скопированных файлов. Для критичных данных - баз, репозиториев, ключей - используют sha256sum:
cd /mnt/source && find . -type f -exec sha256sum {} + > /mnt/target/checksums_src.txt
cd /mnt/target/recovered_home && find . -type f -exec sha256sum {} + > /mnt/target/checksums_dst.txt
Потом сравнивают списки скриптом, который ищет совпадения по хешу и имени. Файлы с расхождениями помечают для повторного копирования или ручной проверки. Удобно использовать утилиту hashdeep для рекурсивного хеширования с прогресс-баром:
hashdeep -r -c sha256 /mnt/source > /mnt/target/hashes_src.txt
hashdeep -r -c sha256 /mnt/target/recovered_home > /mnt/target/hashes_dst.txt
Дополнительные сценарии с PhotoRec и работой с образами
Когда TestDisk не находит структуру разделов или файловая система безнадежно разрушена, на помощь приходит PhotoRec - компаньон TestDisk, входящий в тот же пакет. PhotoRec игнорирует файловую систему и ищет файлы по сигнатурам (магическим числам) в сырых данных. Он знает сотни форматов: JPEG, PNG, PDF, ZIP, Office, SQLite, исходный код и многое другое. Запуск:
photorec /dev/nvme0n1p3
Интерфейс похож на TestDisk: выбирают диск, тип таблицы, раздел, файловую систему (Other для ext4), затем каталог для восстановленных файлов. PhotoRec создаёт структуру recup_dir.1, recup_dir.2 и так далее, складывая туда найденные файлы с автоматическими именами. После восстановления файлы требуют ручной сортировки, но шанс спасти пользовательские данные выше, чем при работе через слой файловой системы.
Если диск имеет плохие секторы, разумно работать не с физическим устройством, а с образом, созданным ddrescue. TestDisk и PhotoRec принимают файл образа как аргумент:
testdisk /mnt/backup/disk.img
photorec /mnt/backup/disk.img
Это спасает исходный диск от лишнего износа и позволяет делать столько попыток, сколько нужно, не рискуя потерять данные навсегда.
- Запуск fsck на смонтированном разделе - приводит к необратимым повреждениям метаданных; всегда отмонтируйте или загружайтесь с Live-USB.
- Пропуск этапа создания образа диска - любая операция записи на повреждённый носитель может стать последней; образ делают первой командой после загрузки.
- Игнорирование SMART-данных - если диск физически умирает, программное восстановление только ускоряет конец; проверяйте smartctl перед началом.
- Попытка монтирования с опцией -o sync в надежде "принудительно записать" - это не лечит файловую систему, а лишь увеличивает износ.
- Копирование cp -r без проверки ошибок - команда молча прервётся на первом нечитаемом файле, оставив остальные не скопированными; используйте rsync с --ignore-errors или tar с --ignore-failed-read.
- Запуск TestDisk на диске, который используется другой ОС в этот момент - конкурентный доступ к метаданным гарантирует порчу таблицы разделов.
- Отказ от логирования TestDisk - при сложных случаях лог - единственный способ понять, что делалось, и не повторять ошибки.