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

Проблема по первичным признакам такая. Грузится 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”, ясно, что ничего хорошего скрипт не найдёт. Но это простая в диагностике ошибка.

Комментарии (8)


  1. casuss
    00.00.0000 00:00

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


    1. vadimr Автор
      00.00.0000 00:00

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


  1. Johan_Palych
    00.00.0000 00:00
    +1

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

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


    1. vadimr Автор
      00.00.0000 00:00
      +2

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


  1. johnfound
    00.00.0000 00:00

    и грузит ядро одной физической командой чтения.

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

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

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

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


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


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


    1. vadimr Автор
      00.00.0000 00:00

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

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


      1. johnfound
        00.00.0000 00:00

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


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


        1. vadimr Автор
          00.00.0000 00:00

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

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

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

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

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