urMQTT на настоящем ARM64 VPS: без экрана, без аппаратного генератора случайных чисел и с рукопожатием, которое было слишком медленным
Что произошло после текста о v0.3.0: первый запуск на настоящем сервере aarch64 с KVM (установка на его диск, отключение питания, цифры диска), Диагностический вход, который сообщает результат по сети, потому что консоль не видна, что он выяснил о генераторе случайных чисел, ассемблер P-256 для ARM64, благодаря которому полные рукопожатия стали примерно в 1,5 раза чаще, и ошибки, которые мы допустили по дороге.

Предыдущий текст, urMQTT v0.3.0, закончился четырьмя пунктами в разделе «Что дальше»: решение по публичному демо-брокеру (D1), фаззинг парсеров PCI и virtio и тест для заблокированных таблиц страниц, диалог для ключа на странице сборщика и bare metal. Ни один из четырех в этом раунде не сделан, и мы говорим об этом сразу. Вместо этого мы сделали то, чего все время не хватало: запустили urMQTT на настоящем сервере ARM64 под KVM, и почти все, о чем пойдет речь ниже, получено на этой единственной машине. Первый пункт старого списка, CI, приведен в порядок (прежний текст и примечания к релизу, где написано, что он красный, исправлены).
Предупреждение заранее прежнее: проект находится на стадии пре-альфа, цифры измеряют код, тесты и определенные эксперименты на одной машине, а не зрелость в продакшене. Если цифра не измерялась на целевой машине, мы так и пишем.
Как это выглядело во времени
С прошлого текста (3 ноября, 02:43) до сегодняшнего дня (4 ноября, 03:18) в main 29 новых коммитов, всего 244. Как и раньше, проект строится с Claude Code (коммиты несут Co-Authored-By: Claude). Цифры вычислены методом двух прошлых текстов (все файлы .rs вне vendor/ и fuzz/, функции #[test], заголовки ## ADR- в docs/DECISIONS.md); на старом коммите метод дает те же цифры, что и тогда.
| Момент | Коммит | Время | Строк Rust | Тестов | ADR | Коммитов |
|---|---|---|---|---|---|---|
| прошлый текст | f1a7fbc | 3.11. 02:43 | 115 148 | 962 | 133 | 215 |
| сегодня | efddf6e | 4.11. 03:18 | 117 084 | 978 | 134 | 244 |
Рост: +1 936 строк, +16 тестов, +1 ADR. Нового кода снова немного; сам ассемблер P-256 (1 509 строк) вендорный и в число строк не входит.
Вторая настоящая машина
До сих пор у проекта был один настоящий сервер: Contabo VPS с AMD EPYC (x86_64, KVM), на котором мы сравнивали производительность с Mosquitto. ARM64 запускался только в QEMU, с аппаратным ускорением на Mac и без него в CI. Новая машина это VPS 500 ARM G12.5 от netcup: ядро Neoverse N1 примерно на 3 GHz, 2 vCPU, 3,9 GiB ОЗУ, диск virtio на 64 GiB, QEMU/KVM с прошивкой UEFI, сетевая карта virtio. Всем управляли через REST API провайдера с помощью клиента командной строки: загружаем ISO, подключаем его как виртуальный CD, переключаем загрузочное устройство, перезапускаем питание.
Что мы на ней сделали, по порядку:
- Сначала снимок исходной системы. Онлайн-снимок при UEFI невозможен, поэтому сервер выключили и сделали офлайн-снимок.
- Установка. Установщик ISO записал образ на диск (включая 30-секундный обратный отсчет, всего около 40 секунд) и сам выключил машину, как и задумано.
- Загрузка с установленного диска заняла около 35 секунд до TLS-рукопожатия.
- Retained-сообщение пережило жесткое отключение питания. Мы опубликовали его, отключили питание через API, загрузились снова и прочитали его обратно.
- Установленный диск, измеренный Диагностическим входом (только чтение; тест записи пропущен, потому что в установленной раскладке нет нераспределенного места, это задумано): последовательное чтение 332 MiB/s, случайное чтение по 4 KiB 22 147 в секунду, p50 10,4 мкс, p90 28,3 мкс, p99 671 мкс, максимум 9,9 мс (2 000 чтений).
Пять пунктов это не набор тестов: это одна машина, по одному запуску каждого пункта, а путь установки на настоящем диске был выполнен один раз. Показывает это другое: собственный драйвер virtio-blk в ядре, установщик и загрузка работают на настоящем облачном госте, а не только в лабораторном эмуляторе.
Экрана нет, поэтому диагностика идет по сети
Диагностический вход из v0.3.0 рисует свои цифры на фреймбуфере. На этом сервере консоль провайдера пишет «Display output is not active»: у виртуальной машины графическая карта virtio, для которой у нас нет драйвера, а последовательный порт не открыт. Цифры существовали, и прочитать их никто не мог.
Решение это слово загрузки diag-serve: машина выполняет те же измерения, затем загружается как обычный работающий брокер и публикует отчет одним документом JSON в retained-сообщении $SYS/diag/report, которое может читать только сертификат оператора. Небольшая утилита urmqtt-diag-png рисует панель по этому JSON тем же кодом, который ядро использует на экране (та же раскладка и тот же шрифт 8x8), поэтому картинка это тот экран, который показала бы машина:

По дороге на экран добавились две вещи, которых нам не хватало: тактовая частота CPU (счетчик циклов PMU относительно базы времени: здесь от 2,95 до 2,98 GHz; там, где читается только таймер с фиксированной частотой, написано «не измеряется», а не частота таймера, выданная за частоту процессора) и панель генератора случайных чисел.
Из чего состоит генератор случайных чисел
Панель показывает, откуда генератор был инициализирован, и проверяет свежие байты из каждого аппаратного источника. На этой машине она говорит:
- virtio-rng: устройства нет.
RNDR(собственная инструкция процессора): на этом процессоре недоступна. - Генератор случайных чисел EFI загрузчика: 8 значений из 8 ненулевые.
- Резервный источник на основе джиттера времени CPU (ADR-038): 1 024 выборки по 64 шага через счетчик циклов PMU, оценка 3 бита на выборку, засчитано 768 бит (четверть оценки, так задумано), проверки здоровья пройдены.
- Выход генератора, проверка на вменяемость по 4 096 байтам: 49,6 % единиц, самая длинная серия 16 бит. Это проверка того, что ничто не застряло и нет смещения, а не статистическая сертификация.
Итак, генератор на этом сервере опирается на резервный источник джиттера и на то, что передала прошивка. Именно это описывает ADR-038, и это самая слабая инициализация, которую ядро принимает. Мы не называем ее сломанной: засчитанные биты выше порога, который требует ядро (256), а оценка консервативна. Но мы также не можем доказать, что она так же хороша, как аппаратный источник. Должен ли продакшен-образ отказываться загружаться без аппаратного источника, если оператор не согласился иначе, это открытый вопрос к владельцу (он есть в дорожной карте, ниже). На практике это вопрос и к провайдеру: аппаратное устройство случайных чисел для виртуальной машины сняло бы его.
Рукопожатие, которое было слишком медленным
Диагностический вход показал еще и цену полного взаимного TLS-рукопожатия на сервере: 1,08 мс. Почти все это арифметика с открытым ключом: две проверки ECDSA P-256 (сертификат клиента и доказательство клиента), около 508 мкс каждая, X25519 176 мкс, одна подпись ECDSA 141 мкс. На x86_64 мы решили это раньше (ADR-130, ассемблер OpenSSL/Intel: P-256 в три-четыре раза быстрее); на ARM64 все еще работал переносимый код RustCrypto.
То же мы сделали для ARM64 (ADR-255). Ассемблер это nistz256 для ARMv8 из OpenSSL (Apache-2.0), взятый из ring 0.17.14 и вендоренный с записью происхождения и каждого механического изменения. Что было важно в деталях:
- Только целочисленный. Ассемблер не использует регистры NEON. Две функции выбора из таблицы, которые в оригинале используют NEON, мы убрали и написали вместо них сканирование с масками за постоянное время на Rust (они стоят не больше 1,4 мкс из 12 мкс подписи).
- Защита ветвлений. Ядро компилируется с BTI и аутентификацией указателей. У каждой из 8 экспортируемых точек входа есть посадочная площадка, это проверено в дизассемблере ядра, а шесть, которые сохраняют регистр связи, подписывают его.
- Тесты, потому что это криптография в доверенной основе. Весь набор x86_64 теперь запускается и на aarch64 Linux: арифметика поля и скаляра против школьной эталонной реализации, вся таблица генератора (2 368 записей) против RustCrypto, подписи бит в бит равны подписям RustCrypto, вердикты проверки, ECDH с входами вне кривой и нулевыми, и тесты с известным ответом, которые выполняются при каждой загрузке через продакшен-пути. На четырехъядерной виртуальной машине под штормом прерываний прошло 59 526 раундов с известным ответом, 0 расхождений.
- Тест времени с контролем и сигнал, который оказался нашим собственным тестом. Намеренно протекающее умножение получает |t| от 482 до 1755, значит, тест видит утечку такого масштаба. На ядре Apple в контейнере ECDH получил от 0,2 до 2,1, подпись от 0,5 до 1,9, генерация ключа от 0,8 до 5,5. На серверном ядре arm64 раннера CI подпись ECDSA показала |t| = 8,6, 9,1 и 8,3 в трех попытках, выше нашей границы 7, тогда как ECDH (3,9) и генерация ключа (1,9) на той же машине прошли. Результат, который повторяется, не шум, поэтому мы записали его как открытую находку (A255-W1) и на несколько часов подняли границу для этого одного случая до 12, чтобы сборка могла пройти. Потом мы нашли причину, и ею оказалась тестовая обвязка: случай подписывал одно и то же фиксированное сообщение, поэтому разреженный ключ каждый раз давал одну и ту же подпись, а случайные ключи каждый раз разную, а DER-кодирование повторяющейся подписи быстрее (|t| от 49 до 57 только для кодирования). При случайном сообщении на каждое измерение в обоих классах случай получает на раннере (виртуальной машине Neoverse N2) 1,4 и 1,8, одна лишь генерация nonce 2,7 и 1,1, а граница снова равна 7. Одно остается открытым (A255-W2): флаг процессора, который делает время умножителя не зависящим от данных на ядрах Arm (DIT), не устанавливается нигде, ни ядром, ни вокруг вызовов на стороне хоста. Ни одно измерение не показывает разницы, но виртуальная машина раннера не предоставляет эту функцию, поэтому тест тоже не мог её показать.
Что это дало
Сначала микробенчмарк на машине, где мы разрабатывали, на Apple M4 Pro (не целевой процессор, поэтому отношения на сервере могут отличаться), тот же код, который вызывает рукопожатие, до и после:
| Операция | до (мкс) | после (мкс) | отношение |
|---|---|---|---|
| генерация ключа | 30,8 | 7,0 | 4,4x |
| ECDH P-256 | 135,2 | 25,0 | 5,4x |
| подпись ECDSA | 34,7 | 11,6 | 3,0x |
| проверка ECDSA (неизвестный ключ) | 147,4 | 29,1 | 5,1x |
| проверка CA (зарегистрированный издатель) | 54,2 | 9,6 | 5,6x |
| X25519 (код не менялся) | 20,4 | 20,1 | 1,0x |
| оценка рукопожатия (сумма предыдущего) | 292 | 104 | 2,8x |
Затем настоящая проверка: тот же генератор нагрузки, тот же метод, что и в тексте о производительности (полное рукопожатие TLS 1.3 с сертификатом клиента, без возобновления, MQTT CONNECT, сервер закрывает первым), запущен с машины в 9 мс от сервера, против того же VPS netcup, до и после изменения. В образе для бенчмарка ограничения рукопожатия ослаблены, как в сравнении на x86_64; три повторения, цифра это медиана.
| Потоков | до (соед./с) | после (соед./с) | отношение | ошибок |
|---|---|---|---|---|
| 32 | 848 (408-855) | 1 317 (957-1 317) | 1,55x | 0 |
| 64 | 827 (815-839) | 1 398 (1 352-1 416) | 1,69x | 0 |
| 128 | 778 (714-788) | 1 316 (1 313-1 383) | 1,69x | 0 |
| Часть TLS в соединении, p50, 32 потока | 18,5 мс | 13 мс |
Число полных рукопожатий в секунду выросло примерно в 1,55-1,7 раза, а не втрое, как дала бы одна арифметика. Причина проста и о ней стоит сказать: мы ускорили P-256, а X25519 (176 мкс), стек TCP/IP, слой записей и MQTT остались прежними, поэтому остающаяся доля становится важнее (закон Амдала). Следующий кандидат это X25519.
Для ориентира рядом с сервером x86_64 из прежнего текста. Это не сопоставимо как гонка: разные процессоры, разное число ядер (4 против 2), разное расстояние до генератора (15 мс против 9 мс), и в обоих случаях общий хост с нагрузкой, который во время запусков отбирал у себя от 5 до 60 % CPU. Сопоставим столбец с собственной ценой CPU сервера на одно рукопожатие:
| Contabo, x86_64 EPYC (asm) | netcup, ARM64 N1 до | netcup, ARM64 N1 после | |
|---|---|---|---|
| CPU сервера на рукопожатие | 0,26 мс (консоль брокера) | 1,08 мс (Диагностика) | 0,55 мс (Диагностика, один запуск, см. ниже) |
| рукопожатий/с, 32 потока | 169 (бенч) | 848 | 1 317 |
| рукопожатий/с, 64 потока | 278 (бенч) | 827 | 1 398 |
| рукопожатий/с, 128 потоков | 413 (бенч) | 778 | 1 316 |
В тот же день Диагностический вход снова запустили на этой машине, с ассемблером (в сборке, которая содержит и графический драйвер, описанный в обновлении в конце): стоимость CPU сервера на одно взаимное TLS-рукопожатие составила 553 мкс против 1,08 мс раньше, в 1,95 раза меньше. Проверка ECDSA заняла 192 мкс (раньше 508 мкс), подпись 78 мкс (141 мкс), а X25519 209 мкс (176 мкс; этот код не менялся, а тактовая частота CPU в этом запуске была 2,58 ГГц против 2,95-2,98 ГГц в прежних, поэтому отдельные цифры на этой общей машине меняются на десятки процентов). Это один запуск, на общем хосте. То, что частота рукопожатий выросла в 1,55-1,7 раза, а собственная стоимость сервера на рукопожатие упала в 1,95 раза, согласуется: остаток соединения это стек, генератор и сеть. Разброс между запусками виден в необработанных файлах: в каждой тройке есть один выброс (408 до и 957 после при 32 потоках), когда нагрузочный хост терял большую часть CPU в пользу других виртуальных машин. При 128 потоках на пределе на обеих машинах генератор, а не сервер.
Остальной набор на этой машине
Тот же набор, что и для сервера x86_64 (пропускная способность, задержка, fan-out, простаивающие соединения), полностью прошел на новой сборке. Строки «до» для них нет: запуск остановили, чтобы собрать ассемблер, поэтому это состояние после изменения, а ассемблер этих путей не затрагивает, кроме рукопожатий, которые открывают соединения. Один факт объясняет большую часть дальнейшего: у этой виртуальной машины два vCPU. Ядро 0 обслуживает сетевую карту, диспетчеризацию и всю работу MQTT и TLS, ядро 1 это ядро базы данных, и оно было занято на 2-3 % все время. У сервера x86_64 было четыре vCPU и два рабочих ядра. Поэтому все ниже это производительность брокера на одном ядре.
| Простаивающие соединения | 5 000 | 10 000 | 20 000 |
|---|---|---|---|
| подключено | 5 000 из 5 000 за 4,3 с | 10 000 за 9,3 с | 20 000 за 21,2 с |
| рост кучи ядра на соединение | 0,34 KB | 0,41 KB | 0,43 KB |
| ошибок | 0 | 0 | 0 |
(0,50-0,66 KB на соединение на сервере x86_64 на коммите H7. Цифра кучи это $SYS/broker/memory/used минус его значение до первого соединения.)
| Задержка при умеренной скорости (8 пар x 100 сообщений/с, 64 B) | p50 | p99 |
|---|---|---|
| QoS 0 | 4,0 мс | 6,9 мс |
| QoS 1 | 4,1 мс | 7,0 мс |
| Fan-out (1 издатель, 64 B) | доставлено в секунду | p50 | p99 |
|---|---|---|---|
| 100 подписчиков, QoS 0, 50 сообщ./с | 5 000 (все) | 5,9 мс | 8,6 мс |
| 100 подписчиков, QoS 1, 50 сообщ./с | 5 000 (все) | 6,3 мс | 10,0 мс |
| 1 000 подписчиков, QoS 0, 10 сообщ./с | 8 805 из 10 000 | 207 мс | 5,4 с |
| Поток, 16 пар, издатели так быстро, как принимает брокер | опубликовано/с | доставлено/с | p50 / p99 | потеряно соединений |
|---|---|---|---|---|
| QoS 0, 64 B | 231 317 | 85 140 | 1,36 с / 2,8 с | 0 |
| QoS 0, 1 KiB | 62 110 | 25 506 | 336 мс / 873 мс | 0 |
| QoS 1, 64 B | 107 349 | 55 965 | 21 мс / 29 мс | 0 |
| QoS 1, 1 KiB | 51 369 | 25 054 | 47 мс / 60 мс | 0 |
| QoS 1, 64 B, 64 пары | 130 462 | 69 411 | 69 мс / 87 мс | 0 |
Как это читать. Задержка при умеренной скорости это вклад брокера плюс один путь до генератора: генератор находится ближе к этому серверу, чем в сравнении на x86_64, поэтому два столбца задержки несопоставимы. Поток QoS 0 показывает обычную картину перегруженного одного ядра: брокер принимает 231 000 сообщений в секунду и доставляет 85 000 (остальное отбрасывают правила противодавления, для того они и нужны) с задержками в секундах, и ни одно соединение не потеряно; на сервере x86_64 поток такого же рода стоил нескольких соединений за запуск из-за сторожевого таймера на 20 мс (с тех пор ADR-221 изменил способ подсчета этого бюджета). Строка с 1 000 подписчиков того же характера, что и раньше, хвосты в секундах, отчасти от самого генератора. Цифры на коммите H7 на сервере x86_64 есть в прежнем тексте; в одну таблицу с этими мы их не ставим, потому что код между двумя измерениями изменился в пути данных (с ADR-221 по ADR-224), а машины различаются во всем.
Ошибки, которые мы нашли сами
- Картинка говорила «диски не найдены», а диск был в отчете. Первая версия
urmqtt-diag-pngвообще не читала полеdisks. Владелец проекта посмотрел на изображение, сказал, что оно выглядит неправильно, и был прав. Исправлено, и теперь тест читает диск обратно из JSON. - Мы слишком рано объявили установщик завершенным. Состояние сервера дважды переходило в «выключен»: один раз в конце перезапуска питания и один раз, когда установщик закончил. Наш скрипт принял первое за второе, отсоединил ISO и загрузил старую систему, которая сообщила старый номер версии и заставила нас искать в установщике ошибку, которой там не было. Теперь скрипт сначала ждет свежей загрузки.
- История прогресса была потеряна. Анализ для дорожной карты показал, что коммит для этапа S6 заменил
docs/PROGRESS.md(1 763 строки, этапы с M0 по S5) собственной записью в 26 строк. Это оставалось незамеченным несколько дней, хотя README называет этот файл «источником истины». Файл восстановлен из истории. - CI упал после ассемблера в двух местах. В трех дымовых тестах был записан размер загрузочного образа («10 MiB»), который с более крупным ядром вырос до 11 MiB; теперь они не предполагают размер. Второй сбой был в описанном выше тесте времени: в первый раз он выглядел как шум на общем раннере, поэтому мы сделали так, чтобы тест повторялся три раза; он упал во всех трех попытках, так мы и узнали, что это сигнал, а сигналом оказался наш собственный тест (он каждый раз подписывал одно и то же сообщение). Мы подняли эту одну границу на несколько часов, сказали об этом открыто и снова понизили её, когда причину исправили.
- Документация насчитывает три слова загрузки, а в коде их четыре (
diag-serve), и таблица этапов в README все еще показывает работу прошлой недели как запланированную. Оба пункта есть в дорожной карте как подлежащие исправлению.
Дорожная карта, с вопросами
Впервые появилась дорожная карта: около 40 пунктов в трех фазах (v0.4 укрепление и эксплуатация; протокол и сеть; масштабирование, больше облаков и bare metal), у каждого основание из документа, трудозатраты, риск и способ проверки, 16 вопросов, на которые может ответить только владелец, и список того, что вне рамок. Несколько вещей она говорит прямо: поддерживается только MQTT 3.1.1, публикация QoS 2 закрывает соединение, нет IPv6 (провайдер выдает /64), нет WebSocket и нет исходящего соединения от брокера, а драйверов для сетевых устройств и устройств хранения больших облаков нет.
Что еще не доказано
- Стоимость CPU на рукопожатие с ассемблером на ядре Neoverse измерена только один раз (553 мкс против 1,08 мс раньше, на более низкой частоте, на общем хосте); 1,55-1,7 раза получено по частоте полного рукопожатия, а 3-5 раз по ядру Apple. Сторона x86_64 этого рефакторинга (код, вынесенный в отдельный файл) проверена по типам и собрана, но её модульные тесты не запускались, и ядро x86_64 после неё не загружалось: наборы x86_64 не входят в CI, их запускают вручную на Contabo VPS, и для этого изменения это ещё не сделано.
- Постоянное время: для генерации ключа P-256, ECDH и подписи (ключ и nonce) статистический тест не нашел зависимости от разреженного секрета. Он выполнялся на ядре Apple и на раннере CI (виртуальной машине Neoverse N2), не на ядре Neoverse N1 у netcup, и ни разу с установленным флагом DIT на серверном ядре (A255-W2, открыто: ядро его не устанавливает). Для X25519 и Ed25519 он не выполнялся. Тест чёрного ящика ограничивает лишь то, что способен различить при своём размере выборки.
- Один сервер, один провайдер, одна установка. Несколько результатов (установка, отключение питания) это один запуск. Кроме рукопожатий, у строк производительности нет «до», а машина с двумя vCPU дает брокеру одно ядро данных.
- Генератор случайных чисел на этом сервере инициализирован джиттером и прошивкой, как описано выше.
- Ключ подписи по-прежнему пробный, образы релиза это development-сборки, а переводы этого текста написал AI, и носители языка их не проверяли.
- Независимого аудита, bare metal и IOMMU нет.
Что дальше
- X25519 на ассемблере для ARM64 (это 176 мкс оставшегося рукопожатия) и повторение измерения на рукопожатие на ядре Neoverse больше одного раза.
- Решение о значении по умолчанию для генератора случайных чисел: отказываться загружаться без аппаратного источника, если оператор не скажет иначе, или оставить резервный источник джиттера и сказать об этом громко.
- Старый список: решение по D1, фаззинг парсеров PCI и virtio, диалог для ключа на странице сборщика.
- Из дорожной карты, для следующего релиза: настоящий ключ подписи и продакшен-PKI, MQTT 5.0 и QoS 2.
Код находится на github.com/zeljan-alduk/urMQTT; docs/PROGRESS.md по-прежнему источник истины о том, что работает, docs/PERFORMANCE.md о том, что измерено (в разделе 10 цифры ассемблера), а docs/AUDIT.md о том, что не доказано. Пре-альфа, как и раньше; сообщения об ошибках и о проблемах безопасности по инструкции в SECURITY.md приветствуются.
Обновление, 4 ноября, позже в тот же день. Четыре вещи из часов после публикации этого текста.
- Недостающая цифра. Диагностический вход снова запустили на сервере netcup с ассемблером, и он дал число, которого не хватает в первой таблице: 553 мкс CPU сервера на взаимное TLS-рукопожатие против 1,08 мс раньше (подробности под этой таблицей).
- Сигнал у подписи был нашим тестом. Причина описанного выше сигнала времени найдена и исправлена в тестовой обвязке (она каждый раз подписывала одно и то же сообщение); граница снова равна 7. Открытым остаётся то, что флаг DIT не устанавливается нигде (A255-W2).
-
Проблема с экраном решена, и она в
main. Мы написали драйвер графической карты virtio (только 2D, ADR-256), включаемый ключом конфигурации, который вшит в образ (console.virtio_gpu, по умолчаниюoff, аautoиonтребуют формат конфигурации 5). Сonвкладка «Экран» у провайдера показывает панель Диагностики вживую на сервере netcup, ту же картинку, что выше, включая последний экран с «press any key». Его фаззинг-цель нашла настоящую ошибку в первой версии: ответ с информацией о дисплее, на четыре байта короче, чем в спецификации, принимался как допустимый (A256-W1); настоящее устройство всегда присылает ответ целиком, так что сервер это не затрагивало, а парсер теперь отклоняет короткий. Что мы не проверяли: что тёмный дисплей действительно возник из-за сброса карты прошивкой при передаче управления ядру (вероятно, не подтверждено), взаимодействие с Secure Boot и x86_64 на настоящей машине (он запускался только под эмуляцией). Известное ограничение (A256-W2): значениеautoне отличает живой эмулированный фреймбуфер рядом с картой virtio от мёртвого, поэтому в этой одной конфигурации оно выбирает карту virtio. Драйвер добавляет в ядро парсер ответов гипервизора, поэтому он выключен, если конфигурация его не запрашивает. -
Релиз. Всё это есть в v0.4.0, опубликованном в тот же вечер как предварительный релиз (релиз на GitHub). Страница сборщика на этом сайте предлагает его первым; ему нужен формат конфигурации 6, а старые шаблоны (от v0.2.0 до v0.3.0) отвергают новые ключи сообщением с просьбой использовать более новый релиз. Ограничения v0.3.0 остаются: ключ подписи по-прежнему пробный, а образы это development-сборки с пробными сертификатами. CI на коммите релиза стал зелёным только после повторного запуска одной задачи (клиентский тест внутри дымового сценария один раз превысил время ожидания, а со второго раза прошёл). Что мы проверили на опубликованных файлах: подпись minisign, контрольные суммы, аттестации сборки ядра и SBOM, а также шаблон с новыми ключами (v0.4.0 их принимает, v0.3.0 отвергает). Драйвер новых устройств virtio (консоль, balloon, ввод, vsock) входит в релиз, но по умолчанию выключен и не запускался на настоящем сервере.
Комментарии
Правила комментирования