SLES 15 и невозможность загрузки ядра Xen

Пришлось столкнуться с забавной ошибкой, по которой сходу не удалось найти никакой информации в интернете.

Проблема по первичным признакам такая. Грузится SUSE Linux Enterprise Server 15, доходит до меню загрузки GRUB. Далее, если выбрать обычное ядро, всё нормально, а если выбрать ядро для гипервизора Xen, то экран моргает и мы опять возвращаемся в меню. Запустить Xen невозможно никак.

Долгие упражнения с настройками GRUB и параметрами загрузки ядра ничего не дали (а надо отметить, что инициализация сервера при загрузке — это неспешный процесс, поэтому дело затягивается надолго). Наконец, возникла ведущая к победе мысль — заснять процесс загрузки на смартфон в ускоренном режиме!

После нескольких попыток удалось получить вот такой кадр:

Это изображение держится на экране в самом удачном случае доли секунды.

Дальше уже делом техники было найти описание проблемы на форуме поддержки Lenovo, которое заключается в следующем.

  1. Загрузчик EFI ядра Xen написан весьма вольно, и грузит ядро одной физической командой чтения.

  2. До версии SLES 15 SP2 размер ядра составлял чуть менее 16 мегабайт, начиная с SP3 — увеличился до чуть более 16 мегабайт.

  3. У ряда контроллеров и дисков размер буфера чтения ограничен как раз величиной 16 мегабайт.

  4. Как следствие, загрузка Xen в режиме EFI с недостаточно продвинутого контроллера или диска приводит к ошибке чтения и мгновенному возврату обратно в меню.

Для того, чтобы справиться с проблемой, предлагается воспользоваться одним из следующих решений:

a) Дождаться, пока Xen community исправит ошибку, интегрировав предложения Lenovo/IBM в свой код (пока с версии 15SP3 ничего не произошло, сейчас на дворе 15SP5).

б) Скачать исходники ядра Xen и перекомпилировать с патчем, предложенным на упомянутой выше странице поддержки, где файл читается порциями по 1 мегабайту. Делать так каждый раз после обновления загрузчика (не проверял, но должно работать).

в) Выполнять загрузку сервера не в режиме EFI, а в режиме Legacy (это работает).

Очень поучительная история.

Бонус:

Ещё одной причиной незагрузки ядра Xen, менее замороченной, начиная с давних времён версии SLES 12 является русский язык. Если зайти на даже полностью англоязычный сервер удалённо через ssh -X yast2 с машины, на которой активна русская локаль, то интерфейс yast и его элементов настройки будет русским. При этом в меню загрузки пункт будет называться “Ядро SLES с гипервизором Xen”, и такой же раздел файла настроек GRUB будет искаться скриптом. А учитывая, что раздел на самом деле называется “SLES kernel with Xen hypervisor”, ясно, что ничего хорошего скрипт не найдёт. Но это простая в диагностике ошибка.

@vadimr
28.02.2023 15:40 UTC
Первоисточник

Комментарии

@casuss
28.02.2023 14:24 UTC
0

На скрине вроде бы ошибка на initrd вылезает - м.б. дело в его размере?

@vadimr
28.02.2023 15:10 UTC
0

Да, именно в его. Под ядром не конкретно файл kernel в данном случае имеется в виду.

@Johan_Palych
28.02.2023 17:46 UTC
+1

Не хочу быть нудным, но:

sudo journalctl --list-boots
sudo journalctl -p 3..1 -xe --since "Tue 2023-02-28 19:51:46"

@vadimr
28.02.2023 18:02 UTC
+2

Кто писать-то это будет в журнал, когда загрузка ядра даже не начинается? Мы говорим о коде EFI.

@johnfound
28.02.2023 17:48 UTC
0
и грузит ядро одной физической командой чтения.

размер буфера чтения ограничен как раз величиной 16 мегабайт.

где файл читается порциями по 1 мегабайту

приводит к ошибке чтения и мгновенному возврату обратно в меню.

Если это про операцию read с диска, то эти цитаты демонстрируют непонимание как все работает на самом деле.


Операция read совершенно не обязана читать столько, сколько запросил вызывающий. Она читает сколько возможно и возвращает количество прочитанных байт. И это никак ошибкой не является. Программист должен проверить прочиталось ли нужное количество или нет и если нет, должен вызвать функцию снова для разницы. Все.


Читать именно порциями по 1МБ не исправляет ситуацию ну никак, потому что 1МБ тоже может не прочитаться полностью. По крайней мере гарантии никакой нет. То есть заменили один баг на другой.

@vadimr
28.02.2023 17:54 UTC
0

Вы говорите о реализации функции read в libc, в то время как речь идёт о функции Read (с большой буквы даже) в EFI API. Она возвращает только код возврата, судя по коду Lenovo.

На этом этапе ещё нет ядра операционной системы и всех этих приятностей.

28.02.2023 18:24 UTC
0

А где можно об этом прочитать? По крайней мере, если функция возвращает только код ошибки (кстати, read тоже возвращает код ошибки, отрицательными числами (я говорю скорее всего о sys_read (но это не суть))).


Но даже если и так, то тогда та же функция должна иметь ограничение на входных параметрах, чтобы не задавали размер больше чем она может читать физически. И тогда обязанность выбирать правильный размер тоже на того кто вызывает функцию. Правда, тогда чтением порциями в 1МБ багом не является.

28.02.2023 18:39 UTC
0

А где можно об этом прочитать?

Я так понимаю, в описании EFI.

Но даже если и так, то тогда та же функция должна иметь ограничение на входных параметрах, чтобы не задавали размер больше чем она может читать физически

Функции всё равно, чтение осуществляет контроллер диска. Это по сути просто прототип функции, содержащий ссылку на реализацию в прошивке контроллера (как водится, через несколько уровней абстракции, но без изменения содержания). Lenovo пишет, что всё зависит именно от HBA, но я думаю, что диск тоже играет роль.

Как только дело доходит до функций работы с железом напрямую, в современных системах, честно говоря, просто глюк на глюке. Драйвер контроллеров SAS MegaRAID, входящий во все дистрибутивы Linux, например, просто виснет, когда размер читаемого блока не кратен 512 байтам (а это так для работы с ленточными накопителями через /dev/stN). Я смотрел этот код, там просто кошмар.