Grub - Debian автоматическая загрузка при сбое 1 диска в RAID массиве
Для Debian Stretch:
- Открываем скрипт:
mcedit /usr/share/initramfs-tools/scripts/local-block/mdadm
- Заменяем параметр --assemble на --incremental
#!/bin/sh PREREQ="multipath" prereqs() { echo "$PREREQ" } case $1 in # get pre-requisites prereqs) prereqs exit 0 ;; esac . /scripts/functions # Poor man's mdadm-last-resort@.timer # That kicks in 2/3rds into the ROOTDELAY if [ ! -f /run/count.mdadm.initrd ] then COUNT=0 # Unfortunately raid personalities can be registered _after_ block # devices have already been added, and their rules processed, try # triggering again. See #830770 udevadm trigger --action=add -s block || true wait_for_udev 10 else COUNT=$(cat /run/count.mdadm.initrd) fi COUNT=$((COUNT + 1)) echo $COUNT > /run/count.mdadm.initrd # Run pure assemble command, even though we default to incremental # assembly it is supported for users to export variables via # param.conf such as IMSM_NO_PLATFORM. See #830300 mdadm -q --incremental --scan --no-degraded || true MAX=30 if [ ${ROOTDELAY:-0} -gt $MAX ]; then MAX=$ROOTDELAY fi MAX=$((MAX*2/3)) if [ "$COUNT" = "$MAX" ] then # Poor man's mdadm-last-resort@.service for incremental devices mdadm -q --run /dev/md?* # And last try for all others mdadm -q --incremental --scan --run rm -f /run/count.mdadm.initrd fi exit 0
- Обновляем образ initramfs.
update-initramfs -kall -u
Для Debian Jessie:
Для Debian 8.6 данная статья уже не очень актуальна, т.к. там всё уже грузится "из коробки", даже при деградированном массиве с загрузочным разделом, однако я оставлю нижеследующий текст в исторических целях, да и мало ли где ещё такая проблема всплывёт, плюс часть о собственно восстановлении массивов по-прежнему актуальна, хотя это в общем-то элементарная вещь, легко находимая гуглом.
В последней (восьмой на момент написания статьи) версии Debian восстановление развалившегося загрузочного software-raid-массива, как оказалось - дело не совсем тривиальное. Когда-то давно, во времена первого GRUB-а - компьютер спокойно загружался при отсутствии части дисков в массиве, однако в 7 и 8 версиях Debian - что-то сломали. Система выдаёт примерно такое: ALERT /dev/disks/by-uuid/куча-разных-кракозябликов does not exist.
Dropping to a shell!
Мне, если честно, лень искать что именно и где там изменилось в поведении mdadm и в загрузочных скриптах. Однако факт остаётся фактом - если в процессе загрузки какой-либо из массивов окажется в деградированном состоянии - этот массив будет неактивен, и если он нужен для загрузки - операционка просто не стартует, выдав вместо этого командную строку busybox, а там возможность что-то исправить - крайне ограничена. И если восстановить массивы на загрузившейся системе - человек, не имеющий серьёзного опыта настройки linux ещё сможет (нагуглить про sfdisk и "магические" mdadm -r / mdadm -a не сложно), то встретившись с куцым busybox, в котором из текстовых редакторов только vi (а он в неумелых руках лишь бибикает и всё портит) - ему не останется ничего иного, кроме как вызванивать вас вечером в субботу. А это, согласитесь, не очень приятно :).
Поэтому распишу вкратце, во-первых, о том, что стоит сразу же подшаманить в установленном на программный raid Debian-е, во-вторых - как это дело быстро восстановить. Здесь не будет ничего о том, как устанавливать систему на raid или как перевести существующую. Кроме того, крайне рекомендуется помнить о том, что манипуляции с raid и дисками могут привести к необратимой потере данных, поэтому убедитесь, что для всего важного есть бекап.
Первым делом - подшаманим загрузочный скрипт. Это позволит системе загружаться даже с деградировавшего массива.
nano -w /usr/share/initramfs-tools/scripts/local-top/mdadm
Открываем файл /usr/share/initramfs-tools/scripts/local-top/mdadm, находим там все вхождения --assemble и заменяем их на --incremental - скорее всего, это нужно будет сделать в двух строчках. Обновляем образ initramfs.
update-initramfs -kall -u
Опции означают, что обновляются образы для всех имеющихся версий ядра (-kall), в том числе те, которые уже существуют (-u).
Теперь, даже если массив деградировал - система всё равно загрузится полностью, что значительно упрощает разбивку и подключение к raid нового жёсткого диска. Однако если вы в эту ситуацию уже попали - проще будет загрузиться с чего-то навроде SystemRescueCD и либо поправить загрузочный скрипт и образ initramfs с помощью chroot, либо прямо из загруженной спасательной системы восстанавливать raid-массивы. Возможно, подобное поведение Debian - не бага а фича, т.е. так и задумано - мол, если raid развалился - не трогать его во-избежание, и пусть юзверь занимается камасутрой с busybox, вероятно это действительно где-то оправдано... однако raid - всё равно не backup, а главная его задача - обеспечение бесперебойной работы, поэтому ценность подобной фичи - имхо крайне сомнительна.
Дальше - важно, чтобы загрузчик (по умолчанию в Debian используется GRUB) был установлен на все загрузочные жёсткие диски. Предположим, у вас два жёстких диска, на которых расположена корневая файловая система вместе с /boot и лежит это всё в виде зеркалки - raid1. По-умолчанию, если в таком виде всё изначально устанавливалось - инсталлятор debian установит GRUB только на один жёсткий диск. Поэтому имеет смысл повторить установку для обоих жёстких дисков - выполнить от root-а примерно такие команды:
grub-install /dev/sda grub-install /dev/sdb
Здесь /dev/sda и /dev/sdb - ваши два диска. В результате система будет загружаться с любого из имеющихся дисков. Если система даже после этих мер не грузится - проверьте настройки BIOS, не пытается ли он грузиться с какого-нибудь флоппика? Подобное тоже бывает в некоторых материнках после удаления одного из дисков (приоритет в загрузке для оставшегося диска оказывается ниже, чем DVD-привода, например).
Теперь перейдём к восстановлению. Допустим, у нас два одинаковых по объёму жёстких диска, на которых в raid1 работают два массива - md0 и md1. На md1 у нас лежит swap (оно нужно на случай умирания диска в процессе работы, чтобы запущенным процессам не стало плохо при обращении к сбойной странице памяти). На md0 - корневая файловая система с /boot и всеми остальными файлами. Т.е. предельно упрощённый вариант, без всяческих выделений под /boot или /home отдельных разделов. Допустим, диски у нас обозначаются /dev/sda и /dev/sdb. И вот, работал себе /dev/sdb, работал... и внезапно умер. Печальный итог его жизни. В случае если вы не подшаманили скрипт загрузки - теперь при попытке стартовать система будет выдавать вышеприведённый ALERT и выкидываться в busybox. С подшаманенным же скриптом - система, скорее всего, загрузится. Если вы не настроили никаких действий и уведомлений на сбой raid - вы о проблеме с диском можете даже не узнать, но настройка уведомлений - выходит за рамки этой статьи. Чтобы проверить состояние raid-а вручную - достаточно выполнить вот такую команду:
cat /proc/mdstat
Или посмотреть содержимое файлика любым другим способом. В файле будет что-то примерно такое:
md0 : active raid1 sda1[1] 2926528 blocks super 1.2 [2/2] [_U] md1 : active raid1 sda2[1] 5855168 blocks super 1.2 [2/2] [_U]
Здесь для каждого массива перечислены оставшиеся в массиве разделы (как видно, расположенные на sda) + видно, что из двух разделов в массиве работает только один - в норме в квадратных скобках было бы написано [UU].
Итак, диск умер, но raid жив. Отключаем компьютер. Достаём где-нибудь новый (или выдранный из потрохов другого компа) винчестер такого-же или бОльшего размера. Подключаем его на место умершего. Включаем комп и тут же лезем в BIOS - нужно убедиться, что загрузка пойдёт с выжившего старого винта, а не с только что добавленного. Загружаем операцинку. Теперь нужно удалить разделы на новом жёстком диске (если имеются) и заново разбить его - так, чтобы /dev/sdb1 и /dev/sdb2 совпадали по размерам с /dev/sda1 и /dev/sda2 соответственно. Можно сделать это с помощью fdisk. Можно воспользоваться графическим gparted. Кто-то сделает это webmin-ом. Выбор за вами. Меня больше всего устраивает parted. Вызываем его и смотрим, что есть на дисках.
root@testserver:~# parted GNU Parted 3.2 Using /dev/sda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) unit s (parted) print /dev/sda Model: ATA ST3802110AS (scsi) Disk /dev/sda: 156299375s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 2048s 5859327s 5857280s primary boot, raid 2 5859328s 17577983s 11718656s primary raid (parted) print /dev/sdb Model: ATA ST3802110AS (scsi) Disk /dev/sda: 156299375s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: (parted)
Красным цветом - обозначены команды, введённые пользователем. Итак, у нас два диска по 80 гиг, на /dev/sda - разделы raid-а, на /dev/sdb - пусто. Команда unit s заставляет parted показывать размеры и смещения в секторах, в противном случае - parted показывает эти цифры в человеко-читаемой и усреднённой форме (типа 7,45GB), установить по которым точное количество байт не представляется возможным. Значения в секторах удобнее тем, что один сектор по умолчанию равен 512 байтам (см. строку Sector size в выводе parted). Строчка "Using /dev/sda" означает, что отданные пользователем команды по умолчанию будут применяться к диску /dev/sda. Нас это не устраивает. Поступаем следующим образом:
(parted) select /dev/sdb Using /dev/sdb
Теперь команды будут применяться ко второму диску. На оном, как видно - уже есть таблица разделов типа msdos. Если бы её не было - пришлось бы создавать командой mklabel. Этим же способом можно быстро удалить старую таблицу разделов, если там сейчас что-то старое и не нужное.
(parted) mklabel msdos
Теперь, когда диск пуст и таблица разделов создана - создаём два новых раздела с теми же размерами, какие видно на первом диске.
(parted) mkpart primary 2048s 5859327s (parted) set 1 lba off (parted) set 1 raid on (parted) set 1 boot on (parted) mkpart primary 5859328s 17577983s (parted) set 2 lba off (parted) set 2 raid on (parted) print /dev/sdb Model: ATA MAXTOR STM380215 (scsi) Disk /dev/sdb: 156299375s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 2048s 5859327s 5857280s primary boot, raid 2 5859328s 17577983s 11718656s primary raid (parted)
Как видно, размеры указываются в секторах - такие же, какие видны на /dev/sda. Команды set на разделы - включают и отключают нужные и ненужные флаги - например, флаг lba ставится по-умолчанию, но он нам особо не нужен, в то же время нужен флаг raid и флаг boot для загрузочного раздела. Теперь можно восстановить деградировавшие массивы. Это весьма просто:
mdadm /dev/md0 -a /dev/sdb1 mdadm /dev/md1 -a /dev/sdb2 cat /proc/mdstat
Последняя команда должна вывести информацию по массивам, в которых будет что-то вроде прогрессбара (полоски с процентами) для процесса восстановления. Эпизодически посматривая содержимое /proc/mdstat можно отслеживать этот процесс. Либо можно делать это в реальном времени примерно такой командой:
watch -n 1 cat /proc/mdstat
Команда будет выводить содержимое файла на экран раз в секунду.
ИСТОЧНИКИ