Содержание

Восстановление загрузки XCP-ng с RAID-1 массива

После загрузки в Windows (AdminPE) с подключенными дисками XCP-ng перестала загружаться, выдавая следующие ошибки:

error: failure reading sector 0xb30 from ‘fd0’
error: disk ‘muuid/b54704e0e324e4ad96f8599beb2247c2,1’ not found.
Entering rescue mode…

XCP-ng создаёт RAID, используя метаданные версии 1.0:

python

# install.img/install/opt/xensource/installer/diskutil.py

def create_raid(configuration):
  ...
  cmd = ['mdadm', '--create', raid_device, '--run', '--metadata=1.0', '--level=mirror',
          '--raid-devices=%s' % (len(members))] + members
  ...

Как мы знаем, метаданные в версии 1.0 пишутся в конец диска.

Также мы знаем, что GPT содержит рабочий заголовок и таблицу в начале диска и резервную копию в конце диска.

Структура дисков выглядит следующим образом:

text

Рабочая разметка GPT
----------------------
Данные
----------------------
Резервная разметка GPT
----------------------
Метаданные 1.0 RAID

Windows в лице AdminPE решила сделать доброе дело. Видя, что резервная копия GPT находится не в конце диска, … она перенесла его, затерев метеданные RAID.

Таблица GPT диска sda
Последний используемый сектор не совпадает с границей последнего раздела

План таков:

  1. Восстановить RAID-массив;
  2. Восстановить резервную копию GPT внутри массива.

Перед восстановлением желательно отключить остальные диски, оставив только первый.

Загружаемся с установочного диска XCP-ng в терминал (F2-shell-Enter): Загрузка с установочного диска XCP-ng

Перед восстановлением нужно сделать резервную копию разметки GPT:

shell-session

sgdisk -b sda-backup.gpt /dev/sda

Или в gdisk:

sh

gdisk /dev/sda
b
sda-backup.gpt

Для восстановления RAID-1 нужно просто пересоздать массив - метаданные запишутся в конец диска, остальная область останется нетронутой.

Создадим деградированный массив с одним диском и прежним UUID:

shell-session

mdadm --create /dev/md127 --run --uuid=b54704e0e324e4ad96f8599beb2247c2 --metadata=1.0 --level=mirror --raid-devices=2 /dev/sda missing

Если создали без UUID, то его можно переназначить:

shell-session

mdadm --stop /dev/md127
mdadm --assemble /dev/md127 --update=uuid --uuid=b54704e0e324e4ad96f8599beb2247c2

Если устройство используется, нужно деактивировать LVM:

shell-session

vgchange -a n

Когда массив собран, можно восстановить резервную область GPT внутри массива.

Заходим в gdisk:

shell-session

gdisk /dev/md127
p

Таблица GPT на md127 до восстановления
Таблица GPT на md127 до восстановления

Проверяем на ошибки (r, v):

Проверка GPT на md127 на ошибки
Проверка GPT на md127 на ошибки

Восстанавливаем резервный заголовок и таблицу (d, e, w):

Восстановление резервной области GPT на md127
Восстановление резервной области GPT на md127

Ещё раз запускаем gdisk, проверяем на ошибки (r, v) - ошибок нет:

Проверка GPT на md127 на ошибки после восстановления
Проверка GPT на md127 на ошибки после восстановления

Выключаем хост.

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

shell-session

mdadm --add /dev/md127 /dev/sdb

Начало диска (сначала посмотреть, где начинается первый раздел, размер сектора):

shell-session

dd if=/dev/sda of=sda-0-2047s.img bs=512 count=2048 skip=0

Конец диска (сначала посмотреть, где заканчивается последний раздел и размер диска, размер сектора):

shell-session

dd if=/dev/sdb of=sdb-488396767-488397167s.img bs=512 count=401 skip=488396767
  1. RAID superblock formats
  2. A guide to mdadm
  3. GUID Partition Table
  4. How-to Recover a RAID array after having Zero-ized Superblocks
  5. Repairing GPT Disks
  6. mdadm(8) - Linux man page
  7. Activating and Deactivating Volume Groups
  8. Getting dd’s skip and seek straight once and for all