From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Resent-From: Michael Shigorin Resent-Date: Tue, 23 Apr 2019 16:00:07 +0300 Resent-Message-ID: <20190423130007.GJ18867@imap.altlinux.org> Resent-To: make-initrd@lists.altlinux.org Envelope-to: ar@cs.msu.ru Delivery-date: Mon, 22 Apr 2019 03:05:04 +0300 Date: Mon, 22 Apr 2019 02:04:50 +0200 From: Alexey Gladkov To: "Michael A. Kangin" Message-ID: <20190422000450.GY21174@Legion-PC.fortress> References: <41fbf1a2-40dc-84a0-4465-cb6f0b28569b@complife.ru> <3fd9233e-74e2-4c89-327b-f9309d030087@gmail.com> <489be984-aa29-53cf-c0a8-e4da309efc8a@complife.ru> <5b6ad98a-29bc-1c16-27df-d0a82b3e3adc@gmail.com> <28dad1c6-a80c-7b5d-a6b8-2c6a8f404842@complife.ru> <20190419210447.GV21174@Legion-PC.fortress> <7f74a951-a415-1581-4df0-909d5ba75020@complife.ru> <20190421134343.GW21174@Legion-PC.fortress> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-SA-Exim-Connect-IP: 194.107.17.36 X-SA-Exim-Mail-From: legion@altlinux.ru X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.cs.msu.ru X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 X-SA-Exim-Version: 4.2 X-SA-Exim-Scanned: Yes (on mail.cs.msu.ru) Cc: Leonid Krivoshein , =?utf-8?B?0JDQvdGC0L7QvSDQnNC40LTRjtC60L7Qsg==?= Subject: Re: [make-initrd] [devel] syslinux X-BeenThere: make-initrd@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Apr 2019 13:00:08 -0000 Archived-At: List-Archive: On Sun, Apr 21, 2019 at 05:44:14PM +0200, Michael A. Kangin wrote: > On 04/21/2019 03:43 PM, Alexey Gladkov wrote: > > >> А есть еще какой-то "payload" для тестирования сетевой загрузки? > > > > Не очень понял вопроса. > > Какая-нибудь фича, которая бы пользовалась сетью для обретения корневой > FS. Ну, чтобы система полностью могла загрузиться. > > nfsroot не работает, CLB на новую версию не спортировано, netboot > (который выкачивал tgz и распаковывал в tmpfs) тоже не спортирован. > А больше мне ничего на ум не приходит. Никакие другие мне тоже не известны. Но раз вы подняли эту проблему, то, возможно, мы сейчас сделаем такую фичу и починим nfsroot. > > Попробую сделать это в ближайшее время. Буду признателен, если > > заинтересованные в таком варианте протестируют перед релизом. > > Разумеется. > Думаю, было бы неплохо так же рассматривать NFS как транспорт для других > фич, по давним замерам производительности смонтировать squashfs по NFS Интересная мысль. Она хорошо согласуется с необходимостью монтирования cd-диска, который тоже является промежуточной стадией. По сути нет разницы между разными промежуточными стадиями. Правда пока этот механизм я не придумал. > может оказаться заметно быстрее, чем чистый корень: > > https://lists.altlinux.org/pipermail/ltsp-server/2012-August/002532.html Интересно. > >> Еще большой вопрос - как написать фичу? Есть какая-то образцовая > >> работающая фича? Или документация, с бест-практиками, примерами... > > > > Каждая фича приносит какой-то новый функционал. У меня нет документации > > для этого. Бест-практики появляются, когда достаточное количество людей > > занимаются их написанием. В моём случае это не так. > > Боюсь, тут может быть некоторый замкнутый круг. Конечно есть. > Чтобы появилось хоть некоторое количество таких людей, у них должно быть > понимание, как это делать. Или хотя бы с чего начать. Дело в том, что для самого себя писать документацию сложно. А заставить себя в такой ситуации ещё сложнее. Также вы же понимаете что когда один разрабатываешь что-то, то многие вещи кажутся самоочевидными. Я надеюсь, что благодаря вам и Леониду, вашим вопросам я смогу заполнить пробелы. > В старой версии M-I я попытался взять за основу упомянутый netboot и > написать свою фичу по его мотивам. Результат, конечно, так себе, и далёк > от любых бест-практик, но оно хотя бы заработало. И было некое > понимание, что скрипт в post/udev/ выполнится после работы udev'а, и в > рамках этого скрипта можно реализовать всю необходимую логику. Сейчас добавление дополнительной функциональности стало ещё проще. Весь рантайм выглядит как обычная система с сервисами. Встроиться можно куда угодно. > Сейчас, с новой версией M-I, нет ни понимания, ни документации, ни > работающего референсного примера. Для каждой фичи встраиваться нужно в разные места. Если вы хотите обработать новый тип загрузки (тот же nfs), то нужно встраиваться нужно в одно место. Если же вам нужно загрузить консольный шрифт и раскладку, то в другое. Всё это сильно зависит. > Я смутно догадываюсь, что сейчас фичу нужно оформлять какими-то > udev-коллбеками, фильтрами и хуками, но абсолютно не представляю, с чего > начать. udev-коллбэки это лишь часть эвентов. Они позволяют реагировать на загрузку модулей. Сейчас через тот же механизм можно реагировать на этапы конфигурации сети. > Поэтому буду рад любым советам и намёкам (варианты for dummies, in a > nutshell вообще бесценны для снижения порога вхождения и сглаживания > лёрнинг курвы :) Ок )) Я постараюсь описать некоторые моменты. > >> Я думал попробовать взять за основу nfsroot, но, похоже, он вообще не > >> "запускается". По крайней мере ни одного упоминания в /var/log нет, в > >> dmesg только о загруженном модуле nfs. > > > > Безотносительно работает nfsmount или нет эта фича хорошо показывает как > > добавляются новые варианты загрузки. > > Меня только смущает, что эта фича даже не пробует начать работать в boot > runtime, по крайней мере, я не никакого признака не заметил - в логах > пусто, в /.initrd/ ничего не грепается и не ищется. Ни md_run, ни nfsroot ничего не пишут в процессе работы. Это неприятно. Поэтому я двигаюсь в сторону отказа от них. > rules.mk, config.mk - тут в принципе понятно. Но я наткнулся на странный > результат с модулем nfs. В первый раз, когда я делал образ initrd с этой > фичей, в него попал модуль nfs, согласно > NFS_PRELOAD = af_packet nfs > ... > MODULES_PRELOAD += $(NFS_PRELOAD) > > Однако, после нескольких попыток разобраться, почему она не работает, и nfsroot работало. Возможно, какого-то модуля ядра не хватает. > в частности после попытки применения рецепта с вики DISABLE_GUESS = root > (https://www.altlinux.org/Make-initrd#nfsroot) Просто для справки, я стараюсь вынести документацию с этой вики на github. > этот модуль попадать в образ initrd перестал, даже с явным указанием > MODULES_ADD += nfs в /etc/initrd.mk. Пожалуйста сделайте пример конфига, где это можно воспроизвести. Это очень странно. > Получается, сборка образа initrd не совсем воспроизводима, и от раза к > разу может давать разные результаты? Сборка образа отталкивается от того как был сконфигурён корень. Тут всё довольно просто. > Может, есть где сказать нечто вроде "make clean"? Я впервые сталкиваюсь > с таким поведением, и даже не знаю, куда посмотреть. Одна попытка сборки с другой никак не связана и не пересекается. > /etc/initrd/cmdline.d/nfsroot - тут, как я полагаю, нужно > зарегистрировать все-все boot parameters, которыми фича собирается > пользоваться. Верно. Выяснилось, что некоторые пользователи жалуются на ошибки, когда указывают rootdelay=five. Из этого вылилась система валидации параметров cmdline. > Чем отличается register_parameter от register_array (и, судя по > исходникам, есть еще register_alias), в каких случаях пользоваться той > или иной функцией, какой синтаксис для _array - указывать несколько раз > один и тот же параметр, или внутри одного параметра что-то перечислить > через запятую? Разглядывание лаконичного кода этих функций в исходниках > просветления, увы, не принесло... Вот как это как раз пример того, что мне казалось очевидным, а оказывается, что это не так. Семантика у этих функций такая: register_parameter [] Функция регистрирует параметр и типом . Также можно указать значение по умолчанию. register_array Позволяет создать "массив" с определённым типом. По правилам /proc/cmdline параметр с тем же именем, находящийся правее переписывает предыдущие. В некоторых случаях хочется иметь возможность получить их все как массив значений. Пример такого параметра IP. Каждое последующее его указание не отменяет предыдущий, а конфигурирует другой интерфейс. register_alias [ ...] Эта функция создана для указания более одного имени для одно и того же параметра. Это полезно если возникает необходимость переименовать параметр или сделать слой совместимости, например, с dracut по некоторым параметрам. type может быть string, number, bool. varname это не оригинальное имя, которое может быть указано в /proc/cmdline, а имя после обработки. Дело в том, что в /proc/cmdline параметры совсем не shell-like. Они могут содержать дефисы или точки. Поэтому make-initrd приводит имена параметров к uppercase и заменяет дефисы и точки на подчёркивания. В такой форме они и регистрируются. > Как дальше пользоваться этими параметрами? делать в каждом скрипте > инклюд . /.initrd/initenv, и ссылаться на переменную параметра, как уже > существующую? Сервис data/etc/rc.d/init.d/cmdline отвечает за разбор cmdline параметров. Он же создаёт /.initrd/initenv. Это необходимо в том числе и из-за того, что некоторые параметры используются более чем в одном месте и имеют значения по умолчанию. Производить анализ cmdline каждый раз, где нужен параметр очень неудобно по понятным причинам. Поэтому анализ производится лишь один раз и результат записывается в /.initrd/initenv, который импортируют все остальные скрипты. > В cmdline писать параметр маленькими буковками, а > переменную ожидать, что она существует с именем заглавными буквами? Параметры вы можете писать какими угодно буквами. Вы можете использовать дефис вместо подчёркивания, а в коде всегда работать с параметром названный заглавными и с подчёркиванием. > /etc/udev/rules.d/99-nfsroot.rules - так, тут какое-то правило udev. > SUBSYSTEM=="net", ACTION=="online", RUN+="/lib/uevent/filters/nfsroot" > т.е. когда сеть будет в онлайне, начнёт действовать фильтр событий > /lib/uevent/filters/nfsroot, если я правильно трактую. Да. Вы всё правильно поняли. > Наверное, для всех сетевых фич это будет более-менее однотипно. > "Пользовательским фичам" рекомендуется использовать номер 99-? Пока полиси на эту тему у меня нет. У вас есть идеи ? > /lib/uevent/filters/nfsroot - этот файл уже значительно менее понятен. > [ -n "$NFSROOT" ] || [ "$ROOT" != '/dev/nfs' ] || > NFSROOT='auto' > > [ -n "$NFSROOT" ] || > exit 0 > > exit 0 нужно использовать, когда мы недовольны качеством предоставленных > параметров, еще чем-нибудь, и не хотим оказывать услугу? Как вы уже правильно заметили этот скрипт выполняется udev'ом. Не нужно завершаться с ненулевым кодом возврата, если не было ошибки. Если написать: [ -n "$NFSROOT" ] || exit то exit без аргумента будет использовать код возврата от предыдущей операции, а это 1 так как переменная NFSROOT пуста. > event="$(make_event)" > showenv -q > "$event" > release_event nfsroot "$event" > > Эти заклинания использовать, как_есть? Заклинания не нужно выполнять никогда. Лучше знать, что происходит. Я попробую коротко рассказать что это и почему оно так. udev не может выполнять долгие задания. В udev(1) для RUN написано: This can only be used for very short-running foreground tasks. Running an event process for a long period of time may block all further events for this or a dependent device. И так было с самого начала. Поэтому обработка событий разделена на две части и скрипты (filters) из udev ничего сами не делают. Они лишь подготавливают условия для реальных обработчиков (handlers). Фильтры выполняются udev'ом параллельно и формируют очередь, которая разбирается демоном ueventd (User EVENT Daemon). ueventd делает это последовательно так как порядок выполнения handlers важен. Теперь зная это возвращаемся к этим трём строчкам. Эти функции описаны в data/bin/uevent-sh-functions. Функция make_event создаёт временный файл для эвента и печатает его имя. Далее showenv печатает в этот файл текущие переменные окружения. Это делается из-за того, что udev передаёт параметры устройства через окружение. Таким образом handler получит то же самое окружение, что и filter. Ну и наконец сформированный эвент передаётся на обработку ueventd функцией release_event. > Я посмотрел доступные файлы в /lib/uevent/filters, но никакой системы > использования понять не сумел, все они достаточно разношерстные. Они подготавливают окружение для разных handler'ов, да, они все разные. > /lib/uevent/handlers/040-nfsroot - это уже похоже на скрипт, в котором > делается реальная работа. Это handler. > Всю логику необходимо помещать внутрь функции handler() как я понимаю. Да. Но нужно помнить, что пока этот скрипт не завершит работу следующий не будет запущен. > for e in "$eventdir"/nfsroot.*; do > [ -f "$e" ] || break > ( . "$e"; handler; ) || > rc=1 > done_event "$e" > done > Эти заклинания будут неизменны? Эти "заклинания" будут зависеть от логики обработчика. > Во всех просмотренных хандлерах ссылка на эвенты выглядит как > "$eventdir"/nfsroot.*, "$eventdir/network.$ev_type", > "$eventdir"/mountdev.*, etc. > Однако, внутри этой директории /.initrd/uevent-events находятся файлы вида: > done.network.addr.update.29.84.XXXNRubtr > done.network.addr.update.29.85.XXXHB5F1u > done.network.config.update.13.56.XXXPsND17 > done.network.config.update.13.59.XXXJrrdH9 > done.network.hostname.update.29.84.XXXwup0dr > > т.е. они не подпадают под ожидаемые маски. Это нормально? Это выполненные задания (см. uevent-sh-functions). Так как initrd удаляется быстро, то нет смысла их удалять. Но для отладки они очень важны. > В некоторых фичах оформляется еще служба init.d, однако, в nfsroot > например такой службы нет. В каких случаях делать, в каких не надо? Всё также как и в обычной системе. Если вам нужна отдельная служба, то нужно делать сервис, если нет, то не нужно. > Если есть init.d/service, как можно в рантайме сделать на него ссылки в > rcN.d (есть ли местный аналог chkconfig)? В initrd используется lsb заголовки для сервисов. Сервисы могут предоставлять как реальное имя так и виртуальное имя. Это очень старый механизм и о нём я много рассказывать не буду. Подробнее здесь [1][2]. Ссылки создаются в процессе создания обарза утилитой sort-lsb. > Если в рантайме нужно делать какие-то мелкие действия, обязательно ли > оформлять для этого init.d/сервис, или есть какой-то аналог rc.local? Не понял вопроса. > Работают ли еще старые механизмы pre/ post/ скриптов? Нет. Раньше были стадии перед которыми можно было вклиниться, но с v2 функционально их не стало и даже для обратной совместимости неоткуда их вызвать. Я очень долго просил откликнуться тех у кого есть фичи, чтобы помочь в адаптации. Всем кто откликнулся я помог. > Замечания, появляющиеся в ходе тестирования сети, предпочтительней > оформлять багами или для начала лучше писать сюда (для обсуждения и > понимания, баг это или фича)? На релиз в сизифе баги стоит вешать в багзиллу. До релиза пишите в личку или на github. [1] https://github.com/legionus/make-initrd/blob/master/docs/InitramfsServices.md [2] https://github.com/legionus/make-initrd/blob/master/docs/BootRuntime.md P.S. Уф. У вас длинное письмо. Я постарался ответить на всё. Извините, если получилось слишком много. P.P.S. Если вы найдёте время помочь мне с документацией того, что мы тут обсуждаем, то вы мне очень поможете сделать всё понятнее. -- Rgrds, legion