Пример решения проблемы, от которой холодок пробегает по коже, когда ее видишь на рабочем сервере в продакшене. После плановой перезагрузки виртуальная машина не загрузилась, показав ошибку и перейдя в grub rescue. Я уже не первый раз сталкиваюсь с подобным и примерный план восстановления в голове присутствует. Делюсь информацией с вами.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Содержание:
Введение
Есть сильно нагруженная виртуальная машина, для которой нужно было добавить ядер и оперативной памяти. Аптайм у нее был примерно пол года. Ничего не предвещало беды. Я предупредил, что простой будет секунд 30 и ребутнул машину. Как только увидел консоль виртуалки, понял, что дальше начинается веселье с непредсказуемым результатом. Адреналина добавила информация от разработчиков, что бэкапов у них нет :)
Machine UUID... Booting from Hard Disk... error: disk 'lvmid/....' not found. Entering rescue mode... grub rescue>
Для тех, кто еще не знаком с подобным, поясню. Начальный загрузчик не смог найти /boot раздел для продолжения загрузки. Вместо этого он сообщил, что раздел с указанным lvmid, где располагается boot, он не видит и дальше загрузиться не может. Машина находится в режиме grub rescue. Причин появления этого режима может быть много. Мне всегда приходится с чем-то новым сталкиваться, но методика решения проблемы примерно одна, и я дальше о ней расскажу. А потом поясню, что было с этой конкретной виртуалкой.
grub rescue
В grub rescue mode доступно всего четыре команды:
- ls
- set
- unset
- insmod
Для начала воспользуемся командой ls и посмотрим, какие разделы видит grub.
В моем случае несколько отдельных разделов диска и lvm том. К слову сказать, в моем случае раздел /boot расположен на lvm разделе, но по какой-то причине загрузчик не смог с него загрузиться. У вас может вообще не быть lvm, а проблема в чем-то другом. Например, если у вас в grub.cfg указан UUID раздела, с которого надо грузиться (это может быть массив mdadm), а раздел этот по какой-то причине исчез, или изменил свой uuid, вы как раз получите эту ошибку.
Сейчас нам нужно найти раздел, на котором расположен загрузчик. Первая часть загрузчика, которая записана в MBR диска очень примитивная и почти ничего не умеет. Она даже разделы диска толком не определила, решив почему-то, что там файловая система msdos, хотя это не она. Нам нужно проверить все разделы диска hd0 и найти реальный загрузчик. Проверяем это командами:
> ls (hd0,msdos5)/ > ls (hd0,msdos1)/
Я нашел на msdos1 искомый раздел /boot. Понял это по содержимому. В разделе есть директория /grub, где располагается вторая часть загрузчика. Искомая директория может называться /grub2 или /boot/grub. Указываем загрузчику использовать этот раздел при выполнении дальнейших команд.
> set prefix=(hd0,msdos1)/grub > set root=(hd0,msdos1)
Далее загружаем необходимые модули. Какие будут нужны, зависит от конкретной ситуации. На всякий случай показываю самые популярные:
> insmod ext2 > insmod lvm > insmod part_msdos
Начать стоит вообще без модулей, а потом добавлять, в зависимости от вашей ситуации. В завершении загружаем модуль normal и вводим одноименную команду:
> insmod normal > normal
После этого вы должны увидеть стандартное меню загрузчика grub. Дальше вы загрузитесь в операционную систему.
Обновление загрузчика
Дальнейшее решение проблемы с загрузкой будет зависеть от того, что у вас сломалось. Возможно будет достаточно просто переустановить загрузчик:
# grub-install /dev/sda
Эта команда переустановит в MBR код загрузчика, который будет подхватывать тот раздел /boot, с которого вы в данный момент загрузились. Если это не поможет, то внесите необходимые изменения в в конфиг grub и пересоздайте его командой:
# grub-mkconfig -o /boot/grub/grub.cfg
А после этого установите на диск:
# grub-install /dev/sda
Конфиг груба находится в разных дистрибутивах в разных местах. Какие туда вносить изменения, заранее тоже не могу сказать, будет зависеть от проблем. Скорее всего все это придется вам гуглить, если не получится сходу починиться по моим рекомендациям.
Почему система не загрузилась
Теперь рассказываю, что было в моем случае. Корень системы / располагался на lvm разделе вместе с /boot разделом. В какой-то момент корневой раздел был увеличен в размере за счет расширения тома lvm еще одним диском. Все это было сделано на лету, без перезагрузки системы. Причем сделано было мной давно, и с тех пор сервер ни разу не перезагружался до настоящего времени. Я не знаю почему, но данная операция привела к тому, что grub перестал загружаться с этого lvm раздела.
UUID физического тома и логического раздела не поменялись. То есть там информация, в начале загрузки, с ошибкой загрузки диска с lvmid, верная. Уиды правильные. Я понял, что причина в изменении размера диска только по аналогичным сообщениям в интернете. Наткнулся на несколько человек, которые обращались с похожей проблемой, где перед этим они тоже изменяли корневой раздел. Похоже это какой-то системный баг, возможно даже конкретной системы.
В моем случае на диске почему-то оказался отдельный раздел на 500 мб с файловой системой ext2. На нем как раз и был загрузчик, с которого я загрузился в rescue boot. Откуда взялся этот раздел, я не знаю. По идее, если он был создан автоматически во время установки системы, на нем бы и должен быть актуальный раздел /boot. Но нет, его не было в fstab и он не использовался. Я не стал долго разбираться, почему так получилось, а просто подмонтировал этот раздел в систему, обновил на нем grub и записал обновленный grub в MBR. После этого система благополучно загрузилась с этого раздела.
Если кто-то знает, почему мой загрузчик не смог загрузиться с lvm раздела, при том, что uuid указан правильно, прошу подсказки. Самому очень интересно, так как ситуация получилась неприятная и совершенно мне не понятная. Я часто расширяю корневой lvm раздел на ходу, но первый раз сталкиваюсь с тем, что это приводит к поломке загрузчика. Grub уже давно умеет грузиться с lvm раздела и каких-то дополнительных действий для этого делать не надо.
Что еще предпринять, чтобы починить загрузку
Если ничего из описанного не помогает, то дальше могут быть такие варианты:
- У вас проблемы с самими данными на разделе. Раздел /boot или корневой, просто не читаются, уничтожены или развалилась файловая система. Попробуйте починить с помощью fsck.
- Если починить /boot не получилось, то его нужно создать заново. Загрузитесь с livecd. Найдите раздел с загрузчиком, либо создайте новый. Отформатируйте его, установите на него загрузчик и запишите его в MBR с указанием на вновь созданный раздел.
Если ничего не помогло и вы не понимаете, что нужно сделать, то посмотрите вот это руководство по grub. Здесь очень хорошо и подробно все описано.
Еще совет. Если у вас живы сами данные, то зачастую бывает проще настроить новую виртуалку, подключить к ней диск от старой и перенести все данные. Так вы точно сможете спрогнозировать время восстановления системы. Обычно за час на все про все можно уложиться. Когда вы начинаете чинить упавшую систему, никогда точно не знаете, сколько времени уйдет на восстановление. В моем случае я загрузку за 30 минут и запустил машину. Потом еще 2 часа разбирался на копии виртуальной машины, что случилось и пытался найти решение проблемы без переустановки виртулаки. Получил некоторый опыт, но если бы я сразу все перенес на новую виртуальную машину, то потратил бы меньше времени.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
В аналогичной ситуации помогла загрузка с с установочного iso debian в режиме resque, сборка raid, затем выбор корня на lvm, после загрузка в корень и исполнение update-grub, grub-mkconfig /boot/grub/grub.cfg, update-initramfs -k all -u. Возможно что присутствуют избыточные, не проверял.
Возникла та же ситуация после попытки переезда крайней версии proxmox на raid-1 на лету вот по этой инструкции https://forum.proxmox.com/threads/howto-proxmox-ve-7-with-software-raid-1.93745/.
На шаге с pvmove вылезла ошибка "Insufficient free space ...", обходя которую пересоздал раздел под будущий корень больше размером. Что и привело в дальнейшем к ошибке grub во время загрузки , при том что lvmid не менялся
Статейка просто бесценная. Благодарю за материал.
Вопрос по "модулям". Откуда и как понять, какие модули есть/надо? Где о них информацию брать?
Столкнулся с подобной проблемой.
Виртуалка под Postgresql была под Hyper-V. Несколько раз расширял том так как кончалось место, в начале увеличил через расширение системного диска, а во второй раз добавив новый диск. После очень долго не перезагружал.
Случилось страшное — вырубили свет на несколько часов и виртуалки пришлось выключать. При восстановлении питания попытались запуститься и получили подобную ошибку.
Отдельных разделов для загрузчика не было, все объединено в единую группу и том.
После многих безуспешных попыток загрузить было принято решение выдернуть данные и запустить их на новом хосте (точка восстановления была старая и попытка воткнуть в неё копию дисков напрямую привела к фиаско из-за совпадения на дисках идентификаторов LVM).
Подключать диски решил на своей машине в VMware Player. С наскоку не получилось, пришлось для начала перевести формат дисков c VHDX на VMDK.
Собрал машину добавил диски и она запустилась, да именно сама без сторонних помощников загрузки. Загрузчик на оригинальных дисков увидел и смог загрузить систему.
Был очень сильно удивлен, решил посмотреть разницу в конфигурации дисков в Hyper-V и VMware. Как оказалось на Hyper-V диски были в конфигурации на разных видах контроллеров (системный на IDE, дополнительный на SCSI), а в VMware оба на SCSI.
Сразу побежал переделывать диски в Hyper-V — на SCSI не загрузилось вообще, а вот при переносе обоих на IDE, тут же произошел запуск системы.
Как оказалось загрузчик GRUB не мог собрать нормально диски с LVM, если они на раздельных контроллерах.
Так и не понял, а с чем была связана ошибка? Похоже именно увеличение корня как-то влияет на эту проблему.
Увеличение корня никак не влияло, повлияла разнородность видов контролеров (IDE и SCSI), к которым были подключены диски из которых формировалась группа LVM. После переноса дисков на один вид контролеров GRUB спокойно смог загрузить систему.
Вот тут неплохая утилита по восстановлению загрузки linux - https://linuxconfig.org/ubuntu-boot-repair
Только что восстановил с ее помощью загрузку виртуалки. Предложенный мной способ не помог, так как boot раздел жил на lvm и я не смог его подцепить через grub rescue. Восстановил в итоге с помощью livecd и указанной в статье утилиты.
https://forum.proxmox.com/threads/howto-proxmox-ve-7-with-software-raid-1.93745/post-607307
~# apt-get install grub-efi-amd64
~# mount /dev/sda2 /efi
~# grub-install --target=x86_64-efi --efi-directory=/efi --no-nvram --force-extra-removable /dev/sda
Если в настройке загрузки BIOS будет стоять не UEFI загрузка, а обычная, то все равно ошибка останется(disk 'lvmid/....' not found.), из grub не будет доступа к lvm разделу и нужной директории /boot. Нужно зайти в BIOS и изменить на тип загрузки UEFI.
Добрый.
Зачем grub располагать на LVM ?
При установке ОС Linux выбираю ручную разбивку:
/boot - 1024Mb ext 2
Остальное - только корневой раздел на LVM с ext4 внутри.
В /boot располагается ядро , к-ое периодически обновляется, занимая место своими обновлениями. Выделив мало места под него можно получить проблемы с невозможностью обновлений ядра, т.к. просто места не хватит.
P.s. Пользую вот такой скрипт. Живет в cron-е - https://github.com/algodelinux/purge-old-kernels. Последняя строка заменена на
apt-get $APT_OPTS remove -y --purge $PURGE для автоудаления старых ядер. Кол-во оставляемых ядер легко варьируется правкой переменной KEEP.
А почему /boot не располагать на lvm? Он его поддерживает уже сто лет в обед. Удобно же, когда единый раздел и не нужно думать о том, что для boot мало места выделил или что-то еще. Бэкап опять же удобно сделать сразу всего в одном месте.
Статейка просто бесценная. Благодарю за материал.
Вопрос по "модулям". Откуда и как понять, какие модули есть/надо? Где о них информацию брать?
А зачем вообще нужен этот grub в эпоху uefi? "Мы напишем свою операционку чтобы грузить операционку".
Сейчас необходимый функционал есть в bios, вполне достаточно какого-нибудь systemd-boot.
P.S. комментарий написан по мотивам статьи https://habr.com/post/314412/
Не знаю зачем, я не задумывался никогда над этим вопросом. Меня устраивает вариант, когда я создаю виртуалку и делаю дефолтную установку ubuntu или centos. Все работает.
Здравствуйте.
Вы пишите: "Она даже разделы диска толком не определила, решив почему-то, что там файловая система msdos, хотя это не она", - но, ведь, строго говоря, нет ФС msdos.
Это в GRUB так именуется FAT?
Или, м.б., msdos - это не тип ФС, а тип таблицы разделов (partition table)?
Может быть, я не разбирался в этом вопросе. Это был раздел с ext2. Мне просто показалось странным увидеть там надпись msdos. Конечно, такой файловой системы нет, и выразился я криво. Когда писал, имел ввиду, что загрузчик там увидел что-то связанное с windows, хотя ничего с ним связанного там никогда не было.
Понял. Спасибо.
Насколько я понимаю, она пишет msdos так как диск размечен в MBR, вот так выглядит help от fdisk:
root@mail:~# fdisk /dev/sda
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): m
Help:
DOS (MBR)
a toggle a bootable flag
b edit nested BSD disklabel
c toggle the dos compatibility flag
Да, всё верно.