LINUX.ORG.RU

Чиним тормоза и зависоны GRUB

 ,


0

1

По результатам вчерашнего изучения ситуации с зависанием os-prober-а, о чем писал в теме Немейнстримные RPM-based дистрибутивы: зачем и почему (комментарий)

По итогу причиной оказалась запредельная крутизна O()-метрики алгоритма из-за некачественного кода.

Проблем оказалось две. Первая затрагивает логику работы утилиты grub-mount. А вторая общую логику работы файловой подсистемы GRUB. Вот они:

  1. https://github.com/wandrien/grub/issues/1

  2. https://github.com/wandrien/grub/issues/2

Вот ветка с фиксом для 1-й проблемы: https://github.com/wandrien/grub/commits/grub-mount-fixes

2-й еще не занимался.

Я пока не стал писать в апстрим. Загрузил код на гитхаб и там же разместил тексты багрепортов. Как сформирую цельный пачсет, тогда напишу в апстрим на Саванну.

Желающие помочь с кодом/пул-реквестами/тестированием/исправлением моего английского/умными идеями - are welcome.

Да, по второму багу. Знаете, что GRUB делает на каждом вызове функции grub_file_open()? Каждый раз заново детектирует файловую систему на разделе.

Я пока не знаю, разумного объяснения, почему так сделано. Ну то есть… если это сделано специально?

Пока что считаю, что это просто было сделано по принципу «работает и ладно», и поэтому исправить проблему труда не составит. Дальше посмотрим…

Ответ на: комментарий от chenbr0

Я затрудняюсь с пониманием вопроса. Данная проблема проявляется в нативном grub и в утилите grub-mount при чтении каталогов с большим количеством файлов. При чем тут freebsd.

wandrien ★★
() автор топика

Тоже помню какие-то тормоза в grub-е, но поскольку он нужен раз в месяц то даже не думал разбираться. Но твою инициативу одобряю, подобные гадости надо искоренять.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

По итогу причиной оказалась запредельная крутизна O()-метрики алгоритма из-за некачественного кода.

Из вашего описания видно, что «метрика вызовов функции» становится O(N*2), что упрощается до O(N), здесь нет O(N^2), более того, всё это кешируется ещё при первом обращении. Вероятно проблема в чём-то другом, например, логических или физических повреждениях диска.

raspopov
()
Ответ на: комментарий от raspopov

здесь нет O(N^2)

int i, j, size = 1000;
for (i = 0; i < size; i++)
{
  for (j = 0; j <= i; j++)
  {
     printf("%d, %d\n", i, j);
  }
}

Какова сложность алгоритма относительно size?

всё это кешируется ещё при первом обращении

Нет.

Вероятно проблема в чём-то другом, например, логических или физических повреждениях диска.

Нет.

wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)

Мне интересно. Почему GRUB до сих пор популярен на UEFI системах? Мне кажется, что лучше либо EFISTUB, если без дуалбутов. А если с дуалбутами, то rEFInd. Нет убогой генерации конфига, обнаруживает загрузчики прямо на месте. Нескучные обои тоже есть. Статические конфиги тоже поддерживаются. И зачем везде пихают grub?

Werenter ★★★
()
Последнее исправление: Werenter (всего исправлений: 1)
Ответ на: комментарий от wandrien

И то, не совсем. GRUB не может, будучи загруженным в EFI режиме, запускать ОС в режиме BIOS. А если нет полной переносимости, то мне кажется надо делать так: делать в зависимости от режима, в котором запустили установщик, выбор загрузчика. Если BIOS - то граб, и выбирать нечего. А если UEFI - то на выбор grub, rEFInd и EFISTUB. Естественно привести краткие описания каждого из вариантов. По умолчанию можно оставить таки граб.

Werenter ★★★
()
Ответ на: комментарий от raspopov

Тогда с примером реального кода, пожалуйста, а то я даже grub_file_open() не нашёл в исходниках grub.

Реальный код есть по ссылке. Я потратил вечер, чтобы локализовать проблему и разобраться в коде, и еще половину рабочего дня, чтобы работать с кодом. Потрудитесь и вы.

Вы grep по исходникам запустить не посчитали нужным, но выше уверенно заявляли «всё это кешируется ещё при первом обращении».

wandrien ★★
() автор топика
Ответ на: комментарий от Werenter

Всё не так

GRUB не может, будучи загруженным в EFI режиме, запускать ОС в режиме BIOS.

т.е. «прошивка» работает как и планировалось.

Или имеется ввиду нечто другое?

Для установленного линукса можно менять режим загрузки

  • установить требуемый загрузчик
  • переключить режим в Биос

Кстати… Ядро EFIstub в legacy же в принципе не умеет?

master_0K
()
Ответ на: комментарий от master_0K

Речь шла о том, чтобы загрузчик не переустанавливать, а делать так: имеем загрузчик, запускаемый в UEFI режиме, но умеющий и BIOS загрузку(читать загрузочный сектор). Это было бы полезно на некоторых говноноутах, где нет legacy режима, но хочется использовать например Windows XP. То есть имеем UEFI загрузчик, в котором реализована BIOS загрузка, прямо в загрузчике.

Werenter ★★★
()
Ответ на: комментарий от wandrien

Вы grep по исходникам запустить не посчитали нужным

GitHub не переиндексировал исходники на момент моей первой проверки репы (я даже не знал что так бывает, если честно), а вот сейчас уже вижу результаты поиска…

raspopov
()
Ответ на: комментарий от Werenter

Так оно не работает. Состояние компьютера при загрузке в legacy и в UEFI сильно разное.

У винды это жестко задано (режим загрузки и т.п.). Хочешь менять: переустанавливай. В линукс всё иначе: нужно установить и сконфигурировать загрузчик. И этого обычно хватает.

Это было бы полезно на некоторых говноноутах, где нет legacy режима, но хочется использовать например Windows XP

«Натягиваешь» ВМ, которая имитирует «старый-добрый биос» и в ней сразу запускаешь «динозавра» вроде Windows XP

master_0K
()