Описание

Описание

Описание

У меня есть массив 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больше не жалуется на несоответствие размера.

Связанный контент