Описание
У меня есть массив IMSM RAID 5, содержащий 6 SSD-дисков. Один из дисков вышел из строя несколько месяцев назад, и я до сих пор не смог его заменить. (Да, я знаю, что иногда я ленивый. Пожалуйста, не судите меня строго.) Но я уже удалил его из RAID.
Однако вчера другой диск, похоже, вышел из строя. Массив не собирается. Поскольку даже BIOS не может создать RAID, я не могу ничего загрузить. При более близком рассмотрении кажется, что диск в порядке. Я могу получить к нему доступ и сделать резервные копии с помощью dd. Но теперь у него, похоже, есть запись MBR в начале. Может быть, какой-то процесс перезаписал суперблок RAID таблицей MBR? Если это так, данные должны быть там. Мне просто нужно иметь возможность указать mdadm
правильные метаданные. Когда я думаю об этом, то то же самое могло произойти с первым диском, который предположительно «вышел из строя». Поскольку он все еще был читаемым. Но тогда я не стал разбираться.
Тем не менее, я сейчас пытаюсь найти способ собрать массив заново, чтобы получить доступ к его данным (если это возможно). Я знаю размер фрагмента, точный порядок дисков и уровень RAID. Разве этого не должно быть достаточно?
Некоторая информация
Первое, что я сделал, это создал образы оставшихся 5 дисков с помощью dd
(названного sd[a-e].backup
). Я также проверил все диски с помощью --examine
и сохранил вывод. Вы можете прочитать вывод вэта суть. Как вы можете видеть, mdadm считывает заголовок MBR sdb
и переходит к следующему диску, не обнаруживая никакой информации RAID. Для всех остальных дисков mdadm выводит правильные метаданные. Пока мы этим занимаемся, вот выводcat /proc/mdstat
Personalities:
md127 : inactive sda[3](S) sdd[2](S) sde[1](S) sdc[0](S)
13049 blocks super external:imsm
unused devices: <none>
Что я пробовал
- Разумеется, я попытался «выключить и включить его снова»:
# mdadm --stop /dev/md127
mdadm: stopped /dev/md127
# mdadm --assemble /dev/md0 /dev/sdb missing /dev/sda /dev/sdc /dev/sde /dev/sdd
mdadm: Cannot assemble mbr metadata on /dev/sdb
mdadm: /dev/sdb has no superblock - assembly aborted
# mdadm --assemble --scan
После последнего вызова mdadm /proc/mdstat
снова выглядит так же, как и вывод выше.
Затем я создал циклические устройства, доступные только для чтения:
# losetup --show -rf /mnt/backup/sdX.backup
[...]
# losetup -a
/dev/loop1: [...] (/mnt/backup/sda.backup)
/dev/loop2: [...] (/mnt/backup/sdb.backup)
/dev/loop3: [...] (/mnt/backup/sdc.backup)
/dev/loop4: [...] (/mnt/backup/sdd.backup)
/dev/loop5: [...] (/mnt/backup/sde.backup)
- Далее я попытался использовать ,
--build
поскольку он не требует никакой информации о суперблоке и все метаданные можно указать вручную:
# mdadm --build /dev/md0 --raid-devices=6 --level=5 --chunk=32 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Raid level 5 not permitted with --build
Но, видимо, мне не разрешено использовать его --build
в контексте рейдов 5-го уровня.
- Следующее, что я попробовал, было использование
--assemble
, но без использования информации OROM о RAID.
# IMSM_NO_PLATFORM=1 mdadm --assemble /dev/md0 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Cannot assemble mbr metadata on /dev/loop2
mdadm: /dev/loop2 has no superblock - assembly aborted
Я думаю, это было бы слишком просто. Могу ли я как-то сказать mdadm, чтобы он просто предположил, что loop2
это первое устройство в этом массиве, и использовал метаданные с других дисков?
- Последнее, что я бы попробовал, это перемонтировать устройства цикла как чтение-запись и пересоздать массив. Однако все примеры, которые я нашел (как этотилиВот этот) предположим, что массив был создан с помощью mdadm. Но это не так. Изначально он был создан утилитой в BIOS и имеет формат IMSM или Intel Rapid Storage. Думаю, мне нужно иметь более подробные знания о нем, такие как макет или смещение данных. Я не уверен, какие значения по умолчанию для IMSM или где их можно найти. Но что еще важнее, меня беспокоит, что формат метаданных mdadm использует больше места и больший суперблок, чем IMSM, и перезаписывает данные при сохранении метаданных. Может быть, также возможно воссоздать массив с помощью IMSM? Или, может быть, возможно сохранить метаданные извне. Короче говоря, я понятия не имею, как вручную воссоздать массив IMSM с помощью mdadm.
Другие вопросы на StackExchange
- Я в курсеэтот вопрос. Но я не уверен, можно ли это применить к моей ситуации, поскольку я использую IMSM, в котором есть другие суперблоки (если они вообще есть).
- Я также прочиталэтот вопрос. Однако он имеет дело с RAID 0, а ответ предлагает использовать ,
--build
который не работает с RAID 5. - Я также знаю оВот этот. Но
--force
это не применимо в моей ситуации, поскольку рассматриваемый диск не просто отмечен как неисправный или несинхронизированный. И снова я не уверен, как мне следует пересоздать массив конкретно с IMSM.
решение1
Эврика - Введение
Итак, я узнал, как снова получить доступ к своим данным. К сожалению, я не смог воссоздать массив с помощью mdadm
. Проблема в том, что с IMSM мне сначала нужно создать контейнер. Но контейнер не принимает отсутствующие устройства. Мне понадобятся все мои исходные 6 жестких дисков, но сейчас у меня только 5. Я также не могу использовать виртуальные жесткие диски, поскольку они должны быть подключены к RAID-контроллеру. Кроме того, я не уверен, начнет ли и как mdadm
начнется синхронизация дисков сразу после создания тома. Однако я нашел способ, который включает dmsetup
. Я снова могу получить доступ ко всем своим файлам.
Выполняя несколько резервных копий дисков для работы с ними, я также понял, что один диск, который больше не является частью массива, иногда выходит из строя с ошибками ввода-вывода. Я все еще мог делать резервные копии, поскольку эти ошибки возникали только примерно при каждом третьем вызове dd
. Я предполагаю, что как только произошла одна из ошибок ввода-вывода, диск, вероятно, был выброшен из массива IMSM, и все его метаданные были удалены.
Я также понял, что этот диск был первым в массиве. Поскольку у меня есть таблица GPT и поскольку данные массива начинаются с первого сектора, логично, что они начинаются с MBR. Таким образом, суперсектор диска не был перезаписан MBR. Он всегда был там.
Чтение данных
Я пытаюсь дать здесь пошаговое решение, которое объясняет все команды, используемые в процессе. Надеюсь, это поможет кому-то там.
(Необязательно) Сделайте резервную копию всех дисков.
Это не является строго необходимым. Тем более, что позже мы будем использовать петлевые устройства только для чтения. Однако я особенно параноидально отношусь к серьезным сбоям в моем решении для хранения данных. Поэтому я стараюсь избегать использования реальных данных, насколько это возможно. Кроме того, использование резервных файлов показывает, что этот метод вообще не требует оригинальных жестких дисков или BIOS. Все, что вам нужно, это образ dd. Если вы пропускаете этот раздел, убедитесь, что вы действительно создали петлевые устройства в следующем разделе как только для чтения, иначе вы рискуете, что ваши данные станут еще более деградированными и могут быть потеряны навсегда.
Тем не менее, вот команда для резервного копирования вашего жесткого диска. Вы, возможно, уже знакомы с dd. Но если вы еще не знакомы, запустите эту команду для каждого жесткого диска, который является частью вашего массива:
# dd if=/dev/sdX of=/path/to/backups/sdX.img status=progress
# dd if=/dev/sdY of=/path/to/backups/sdY.img status=progress
# [...]
Входной файл if=/dev/sdX
— ваш жесткий диск. Замените sdX
на sda
, sdb
, и т. д. Выходной файл of=/path/to/backups/sdX.img
указывает на изображение, которое должно быть записано. Снова замените sdX
соответствующим образом. status=progress
просто сообщает GNU-версии dd о необходимости вывести текущий прогресс на stderr.
Создать петлевые устройства
Далее мы собираемся создать петлевые устройства. В случае, если мы используем резервные образы, это гарантирует, что они будут распознаны как блочный файл. Хотя это может быть не обязательно. Но в любом случае это гарантирует, что образ будет только прочитан, так как мы используем флаг только для чтения-r
# losetup --show -rf /path/to/backups/sdX.img
# losetup --show -rf /path/to/backups/sdY.img
[...]
-r
: только читать из файла, не записывать в него-f
: используйте следующий доступный номер для устройства петли, чтобы нам не пришлось угадывать его самостоятельно.--show
: вывести выбранное имя-f
. Обычно это довольно полезно. Хотя мы в любом случае выведем эти значения на печать на следующем шаге.
Чтобы получить наглядное представление о только что созданных нами петлевых устройствах, можно использовать следующую команду:
# losetup -a
/dev/loop1: [2129]:251265027 (/path/to/backups/sdX.img)
/dev/loop2: [2129]:251265027 (/path/to/backups/sdY.img)
[...]
Постарайтесь запомнить, какое петлевое устройство относится к какому изображению.
Сбор метаданных
Далее нам нужно узнать некоторую информацию о RAID. В частности, нам нужно узнать, с какого сектора начинается RAID (особенно в случае матричного RAID), сколько секторов он охватывает, каков размер его фрагмента и его структура, а также в каком порядке диски были добавлены в массив.
Если есть хотя бы один диск, который все еще является частью массива и к которому прикреплены метаданные, вы можете использовать его для извлечения большей части необходимой информации. Выполните следующую команду на диске, sdX
который все еще является частью массива:
# mdadm --examine /dev/sdX
/dev/sdX:
Magic : Intel Raid ISM Cfg Sig.
Version : 1.3.00
Orig Family : aa0b2c12
Family : 48d867fb
Generation : 0018f99c
Attributes : All supported
UUID : 0312fa14:fa8db3c2:2a76dc3f:299ed5b4
Checksum : 084869b8 correct
MPB Sectors : 6
Disks : 6
RAID Devices : 1
Disk02 Serial : S21PNSBG710576N
State : active
Id : 00000000
Usable Size : 488391936 (232.88 GiB 250.06 GB)
Bad Block Management Log:
Log Size : 2040
Signature : abadb10c
Entry Count : 254
[NameOfYourArray]:
UUID : 24b1e785:14f37ee5:41f6a4ab:d8b89e11
RAID Level : 5
Members : 6
Slots : [__UUUU]
Failed disk : 1
This Slot : 2
Sector Size : 512
Array Size : 2441959424 (1164.42 GiB 1250.28 GB)
Per Dev Size : 488392200 (232.88 GiB 250.06 GB)
Sector Offset : 0
Num Stripes : 7631124
Chunk Size : 32 KiB
Reserved : 0
Migrate State : idle
Map State : failed
Dirty State : clean
RWH Policy : off
Вывод продолжается, но вы можете игнорировать остальное. Вывод, показанный выше, дает следующую ценную информацию:
Sector Offset : 0 # Where the data starts
# (right at the first sector in my case)
Array Size : 2441959424 # Size of the volume (data) inside the array
Chunk Size : 32 KiB # Size of a single chunk
Вы даже можете определить, где в вашем массиве находится этот конкретный диск.
This Slot : 2
Это означает, что это третий диск в массиве. (Номер слота начинается с нуля.) Альтернативно Disk## Serial : [...]
также указывает на номер слота:
Disk02 Serial : S21PNSBG710576N
Запустите эту команду для всех дисков. Для тех, которые все еще дают допустимые результаты, запишите номер слота.
Есть еще один трюк, который вы можете использовать для определения первого диска в массиве. Поскольку RAID записывается блоками, а не байтами, первые 32 КБ находятся на первом диске. Вторые 32 КБ на втором диске и так далее. Это означает, что на первом диске должно быть достаточно секторов, содержащих начало вашей таблицы разделов. Это означает, что в начале должен быть MBR (даже если вы используете GPT, так как он начинается с защитного MBR). mdadm --examine
уже говорит вам, что он нашел MBR, когда нет метаданных. Но вы также можете использовать fdisk -l
.
В моем случае мне удалось узнать номера слотов четырех дисков через их метаданные. Мне повезло, что пятый диск содержал MBR, поэтому я автоматически знал, что это первый. 5 из 6 дисков достаточно для запуска массива. Если вы не знаете точных номеров слотов достаточного количества дисков, вы можете попробовать использовать различные перестановки, пока этот метод не сработает.
Это означает, что правильный порядок моих приводов и, следовательно, моих петлевых устройств следующий:
Слот | Водить машину | Устройство петли |
---|---|---|
МБР (0) | /dev/sdb | /dev/loop2 |
1 | отсутствующий | - |
2 | /dev/sda | /dev/loop1 |
3 | /dev/sdc | /dev/loop3 |
4 | /dev/sde | /dev/loop5 |
5 | /dev/sdd | /dev/loop4 |
Последнее, что нужно выяснить, это макет. К сожалению, mdadm
он не дает нам никакой информации об этом. Однако, когда мы смотрим наОпределения RAID от Intelпохоже, что макет для RAID 5 всегда остается асимметричным. Я не уверен, можно ли вообще настроить массивы IMSM с другим макетом, но мне это кажется маловероятным. Если все это вам не подходит, то вы можете попробовать другие макеты. Посмотритев источникечтобы узнать больше о других макетах.
Ниже представлен обзор всех уровней RAID, поддерживаемых IMSM. Ключевое слово dmsetup используется в следующей главе.
уровень RAID | Макет | Синтаксис dmsetup |
---|---|---|
0 | Н/Д | рейд0 |
1 | Н/Д | рейд1 |
5 | левый асимметричный | raid5_la |
10 | по умолчанию (без 1E или копирования) | рейд10 |
Если вы не можете собрать какие-либо метаданные с любого диска, то вам придется угадывать значения и/или пробовать разные комбинации. В качестве помощи вот разные режимы, которые поддерживает IMSM:
Информация | Возможные значения |
---|---|
Уровни RAID | 0, 1, 5, 10 |
Размеры кусков | 4 кБ, 8 кБ, 16 кБ, 32 кБ, 64 кБ, 128 кБ |
Для начального сектора и размера лучше всего предположить ноль и размер наименьшего диска в массиве, умноженный на количество дисков без контроля четности, если вы не уверены. Вы можете получить размер диска в секторах, выполнив следующую команду:
blockdev --getsize /dev/sdX
Если ваши данные на самом деле не начинаются с нуля, вы все равно можете получить правильное смещение позже,поиск заголовка разделаили, может быть, дажепоиск файловых систем.
Сборка массива с помощью dmsetup
К сожалению, нет возможности вручную предоставить метаданные при использовании mdadm
. Единственное исключение — дляУровни RAID 0 и 1, где вы можете использовать--build
:
mdadm --build /dev/md0 --raid-devices=2 --level=0 --chunk=32 /dev/loop0 /dev/loop1
Поскольку нам здесь не повезло, нам нужно использовать другой инструмент. Поэтому мы воспользуемся dmsetup
вместо этого. dmsetup
— это команда, которая создает виртуальные жесткие диски, которые отображаются на реальные диски или другие источники. Эти отображения состоят из нескольких разделов, и каждый раздел может отображаться на другой диск. В нашем случае нам нужен только один раздел, и мы отображаем на RAID, метаданные которого мы предоставим вручную.
Но сначала нам нужно поговорить о числах. Как мы определили ранее, размер блока в моем случае был 32 КБ. Однако dmsetup
требует секторов. Почти во всех случаях один сектор равен 512 байтам. Если вы хотите быть в безопасности, вы можете проверить размер сектора с помощью blockdev --getss /dev/sdX
. В моем случае это означает 32 kiB / (512 bytes/sector) = 64 sectors
. Мы уже знаем размер данных в массиве в секторах (т. е. 2441959424). Но есть проблема. У меня 6 устройств. При одном блоке четности на полосу количество блоков должно делиться на 5. Но количество секторов не делится на 5. В моем случае оно, по крайней мере, делится на количество секторов на блок. Но я даже не уверен, гарантируется ли это. Похоже, что данные останавливаются на полпути через последнюю полосу. К сожалению, dmsetup не допускает этого. Это означает, что нам нужно округлить до ближайшего целого числа, которое делится на 5 дисков и на 64 сектора (измените эти числа в соответствии с вашей ситуацией). В моем случае это: 2441959680. Это будет означать, что fdisk
может возникнуть проблема с неправильным размером диска и отсутствием таблицы резервного копирования. Но мы можем это исправить, обрезав образ dd.
Теперь создайте файл (например table.txt
, ), который будет содержать одну строку для одного раздела.
<start> <size> raid <raid layout> 2 <chunk size> nosync <num devices>[ - /dev/loopN|-]*num_devices
Сначала вам нужно указать начало и размер в секторах. Следующий аргумент говорит, что это RAID. Для макета RAID см. таблицу в предыдущем разделе. «2» в следующем аргументе означает два специальных параметра для RAID. Первый — это размер фрагмента. Второй предотвратит любую синхронизацию. После этого вам нужно описать свои диски, сначала указав количество устройств, а затем указав пару метаданных и путь к устройству для каждого устройства. Поскольку мы не хотим предоставлять никаких метаданных, мы используем тире, чтобы указать это. Если устройство отсутствует, мы пишем два тире, указывая, что ни метаданные, ни устройство недоступны. Рекомендуется исключить хотя бы одно устройство, если уровень RAID это позволяет. Если вы уже подозреваете, что один диск может содержать неисправные данные, выберите его.
Например, в моем случае файл выглядит так. Обратите внимание, что второе устройство отсутствует.
0 2441959680 raid raid5_la 2 64 nosync 6 - /dev/loop2 - - - /dev/loop1 - /dev/loop3 - /dev/loop5 - /dev/loop4
Теперь выполните следующую команду, чтобы создать новый файл блока, который сопоставляется с нашим массивом:
# dmsetup create sdr /path/to/table.txt
Это может выдать кучу ошибок ввода-вывода. В этом случае размер в секторах, вероятно, не делится на размер фрагмента. Вы можете удалить файл блока, чтобы повторить последний шаг, с помощью следующей команды:
# dmsetup remove sdr
Теперь давайте посмотрим на этот недавно созданный файл устройства. Если вы запустите
# fdisk -l /dev/mapper/sdr
вы должны увидеть таблицу разделов. Не беспокойтесь о двух ошибках, которые появятся, если у вас таблица GPT. Несоответствие размеров и отсутствие резервной таблицы связаны с тем, что мы выбрали слишком большой размер для нашего RAID.
Мой выглядит так:
Device Start End Sectors Size Type
/dev/mapper/sdr-part1 2048 923647 921600 450M Windows recovery environment
/dev/mapper/sdr-part2 923648 1128447 204800 100M EFI System
/dev/mapper/sdr-part3 1128448 1161215 32768 16M Microsoft reserved
/dev/mapper/sdr-part4 1161216 679840003 678678788 323.6G Microsoft basic data
/dev/mapper/sdr-part5 679841792 680902655 1060864 518M Windows recovery environment
/dev/mapper/sdr-part6 680904704 2295472127 1614567424 769.9G Linux filesystem
/dev/mapper/sdr-part7 2295472128 2441957375 146485248 69.9G Linux swap
Используя столбец start и sector в этой таблице, мы даже можем смонтировать некоторые из этих разделов. Обратите внимание, что все числа указаны в секторах и должны быть преобразованы в байты путем умножения на 512.
# mount -o ro,noload,loop,offset=348623208448,sizelimit=826658521088 /dev/mapper/sdr /mnt
Это означает, что мой раздел Linux теперь смонтирован в /mnt, и я могу просматривать все свои файлы в ro
режиме (т.е. только для чтения). Это noload
необходимо длязапретить ext4 выполнять операции записи.
И теперь наконец-то мы выполним полное резервное копирование с помощью dd.
# dd if=/dev/mapper/sdr of=/path/to/backups/raid.img status=progress
Помните, как мы создали RAID, который оказался немного больше, чем должен быть? Мы можем воспользоваться этой возможностью, чтобы исправить эту ошибку, обрезав образ до правильного размера. Количество секторов необходимо преобразовать в байты: 2441959424*512 = 1250283225088
.
# truncate -s 1250283225088 /path/to/backups/raid.img
Теперь fdisk -l
больше не жалуется на несоответствие размера.