FreeBSD-5.3 SMP and qemu
TL; DR:
Рецепт FreeBSD-5.3 с поддержкой многопроцессорности на KVM (запоздал на 10 лет, но вдруг кому еще надо):
- Установить FreeBSD-5.3 и загрузить ядро в Safe mode (иначе будет вешаться)
- Собрать SMP (options SMP) ядро с отключенным MIXED_MODE (options NO_MIXED_MODE)
А теперь история сего элегантного решения :]
Давным-давно (году, эдак, в 2005-м :]) у нас появился потенциальный клиент. Ему нужен был наш продукт (написан на С++/pthreads) для FreeBSD-5.
Для этого быстро взяли железную машину и с матерщиной установили туда фрю. В 2006-2007 году я устроился на должность программиста, поддерживающего нашу прогу на зоопарке всяких linux/BSD.
FreeBSD-5 оказалась самой глючной системой из всех мне попадавшихся, но это тема отдельного застольного разговора :]
Гораздо позже (в 2009 году) можности тачек подросли и я решил перенести это хрупкое чудо на виртуальную машину (тогда остановился на Xen в качестве гипервизора).
Всё началось с того, что FreeBSD-5.3 ненавидит ACPI в любом его проявлении. При попытке загрузки ядро висло не доходя до старта /sbin/init. Не работали первых 2 пункта меню загрузки системы: default и without ACPI.
Но 3-й пункт меню (Safe mode) работал! Немного покопавшись конфигах загрузчика я нашел заветвый кусок кода:
= if
dup bootsafekey @ " arch-i386" environment? if
s" acpi_load" unsetenv
s" 1" s" hint.acpi.0.disabled" setenv
s" 1" s" loader.acpi_disabled_by_user" setenv
s" 1" s" hint.apic.0.disabled" setenv
s
then" 0" s" hw.ata.ata_dma" setenv
s" 0" s" hw.ata.atapi_dma" setenv
s" 0" s" hw.ata.wc" setenv
s" 0" s" hw.eisa_slots" setenv
s0 boot
then
Из этого мне оказалась нужна единственная строка:
" 1" s" hint.acpi.0.disabled" setenv s
Что в переводе на /boot/loader.conf:
.apic.0.disabled="1" hint
Этот костыль полностью отключает ACPI и позволяет кое-как грузить тачку и собирать там продукты. Позже я устал от ядра Xen.
Это был упатченный linux-2.6.18, в котором было сломано почти всё, что я тогда пытался использовать:
- сломан hotplug сетевух на тогда новом udev
- сломан bridge (при выключении xen-ядра машина падала в kernel panic из-за драйверов, которые не сбрасывали счётчик использования драйвера bridge при деинициализации). Технически, это скорее всего ошибка драйвера хост сетевухи (forcedeth), но меня как как “просто юзера” это не волновало.
- иногда xen домены залипали так, что приходилось перезагружать гипервизора.
Немного поюзав KVM на своей машине решил перевести и сервер виртуальных машин. Гостевых ОСей было 5:
- RedHat-5.2
- CentOS
- FreeBSD-4
- FreeBSD-5
- FreeBSD-7
Не завелась единственная система. Угадайте какая?
Правильно - FreeBSD-5 :] Но на этот раз в ядре linux. Немного порывшись в интернетах нашел решение, которое уже попало в git дерево проекта kvm. Оно исправляло эмуляцию какой-то 16-битной ring0 инструкции работы с сегментами. Обновившись до ядра из этой ветки я ненадолго успокоился.
Прошло несколько лет и мы обновили сервер сборки с двухголового AMD64-X2 до 8-голового Core i7. Горе в том, что при отключенном APIC система в принципе не видит больше одного процессора.
В результате на FreeBSD-5 продукты собирались в 2 раза медленнее, чем на на всех остальных виртуальных машинах вместе взятых.
По умолчанию ядро FreeBSD-5 вообще не поддерживает SMP системы, так как SMP-ядро работает чуть медленнее UP ядра на UP системе.
Я стал ёрзать и отважился впервые пересобрать ядро FreeBSD. У ребят прекрасный handbook, с помощью которого я сравнительно быстро нашел проблему в ACPI и собрал таки работающее ядро.
Результирующий конфиг:
# cd /usr/src
# cat sys/i386/conf/MYKERNEL
include GENERIC
options SMP
options NO_MIXED_MODE
# make buildkernel KERNCONF=MYKERNEL
# make installkernel KERNCONF=MYKERNEL
# /sbin/reboot
Время сборки продукта сократилось с 5 минут до 36 секунд:
bash-2.05b$ time gmake target=freebsd5 -j9
...
real 0m36.046s
user 4m13.069s
sys 0m24.774s
bash-2.05b$ uname -r
5.3-RELEASE
Такие дела :]