Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56e266c439 | ||
|
|
d7012437df | ||
|
|
c24887c795 |
181
s4a.tex
181
s4a.tex
@@ -1388,6 +1388,187 @@ systemd уже подготовлен для работы внутри таки
|
|||||||
|
|
||||||
И все это уже сейчас доступно в Fedora~15.
|
И все это уже сейчас доступно в Fedora~15.
|
||||||
|
|
||||||
|
\section{Поиск виновных}
|
||||||
|
|
||||||
|
Fedora~15\footnote{Величайший в истории релиз свободной ОС}
|
||||||
|
является первым релизом Fedora, использующим systemd в качестве системы
|
||||||
|
инициализации по умолчанию. Основной нашей целью при работе над выпуском F15
|
||||||
|
является обеспечение полной взаимной интеграции и корректной работы всех
|
||||||
|
компонентов. При подготовке следующего релиза, F16, мы сконцентрируемся на
|
||||||
|
дальнейшей полировке и ускорении системы. Для этого мы подготовили ряд
|
||||||
|
инструментов (доступных уже в F15), которые должны помочь нам в поиске проблем,
|
||||||
|
связанных с процессом загрузки. В этой статье я попытаюсь рассказать о том, как
|
||||||
|
найти виновников медленной загрузки вашей системы, и о том, что с ними делать
|
||||||
|
дальше.
|
||||||
|
|
||||||
|
Первый инструмент, который мы можем вам предложить, очень прост: по завершении
|
||||||
|
загрузки, systemd регистрирует в системном журнале информацию о суммарном
|
||||||
|
времени загрузки:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemd[1]: Startup finished in 2s 65ms 924us (kernel) + 2s 828ms 195us (initrd)
|
||||||
|
+ 11s 900ms 471us (userspace) = 16s 794ms 590us.
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Эта запись означает следующее: на инициализацию ядра (до момента запуска initrd,
|
||||||
|
т.е. dracut) ушло 2 секунды. Далее, чуть менее трех секунд работал initrd. И
|
||||||
|
наконец, почти 12 секунд было потрачено systemd на запуск программ из
|
||||||
|
пространства пользователя. Итоговое время, начиная с того момента, как загрузчик
|
||||||
|
передал управление коду ядра, до того момента, как systemd завершил все
|
||||||
|
операции, связанные с загрузкой системы, составило почти 17 секунд. Казалось
|
||||||
|
бы, смысл этого числа вполне очевиден\ldots{} Однако не~стоит делать поспешных
|
||||||
|
выводов. Прежде всего, сюда не~входит время, затраченное на
|
||||||
|
инициализацию вашего сеанса в GNOME, так как эта задача уже выходит за рамки
|
||||||
|
задач процесса init. Кроме того, в этом показателе учитывается только время
|
||||||
|
работы systemd, хотя часто бывает так, что некоторые демоны продолжают
|
||||||
|
\emph{свою} работу по инициализации уже после того, как секундомер остановлен.
|
||||||
|
Проще говоря: приведенные числа позволяют лишь оценить общую скорость
|
||||||
|
загрузки, однако они не~являются точной характеристикой длительности процесса.
|
||||||
|
|
||||||
|
Кроме того, эта информация носит поверхностный характер: она не~сообщает, какие
|
||||||
|
именно системные компоненты заставляют systemd ждать так долго. Чтобы исправить
|
||||||
|
это упущение, мы ввели команду +systemd-analyze blame+:
|
||||||
|
\begin{Verbatim}
|
||||||
|
$ systemd-analyze blame
|
||||||
|
6207ms udev-settle.service
|
||||||
|
5228ms cryptsetup@luks\x2d9899b85d\x2df790\x2d4d2a\x2da650\x2d8b7d2fb92cc3.service
|
||||||
|
735ms NetworkManager.service
|
||||||
|
642ms avahi-daemon.service
|
||||||
|
600ms abrtd.service
|
||||||
|
517ms rtkit-daemon.service
|
||||||
|
478ms fedora-storage-init.service
|
||||||
|
396ms dbus.service
|
||||||
|
390ms rpcidmapd.service
|
||||||
|
346ms systemd-tmpfiles-setup.service
|
||||||
|
322ms fedora-sysinit-unhack.service
|
||||||
|
316ms cups.service
|
||||||
|
310ms console-kit-log-system-start.service
|
||||||
|
309ms libvirtd.service
|
||||||
|
303ms rpcbind.service
|
||||||
|
298ms ksmtuned.service
|
||||||
|
288ms lvm2-monitor.service
|
||||||
|
281ms rpcgssd.service
|
||||||
|
277ms sshd.service
|
||||||
|
276ms livesys.service
|
||||||
|
267ms iscsid.service
|
||||||
|
236ms mdmonitor.service
|
||||||
|
234ms nfslock.service
|
||||||
|
223ms ksm.service
|
||||||
|
218ms mcelog.service
|
||||||
|
...
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Она выводит список юнитов systemd, активированных при загрузке, с указанием
|
||||||
|
времени инициализации для каждого из них. Список отсортирован по убыванию этого
|
||||||
|
времени, поэтому наибольший интерес для нас представляют первые строчки. В нашем
|
||||||
|
случае это +udev-settle.service+ и
|
||||||
|
+cryptsetup@luks\x2d9899b85d\x2df790\x2d4d2a\x2da650\x2d8b7d2fb92cc3.service+,
|
||||||
|
инициализация которых занимает более одной секунды. Стоит отметить, что к
|
||||||
|
анализу вывода команды +systemd-analyze blame+ тоже следует подходить с
|
||||||
|
осторожностью: она не~поясняет, \emph{почему} тот или иной юнит тратит
|
||||||
|
столько-то времени, она лишь констатирует факт, что время было затрачено. Кроме
|
||||||
|
того, не~стоит забывать, что юниты могут запускаться параллельно. В частности,
|
||||||
|
если две службы были запущены одновременно, то время их инициализации будет
|
||||||
|
значительно меньше, чем сумма времен инициализации каждой из них.
|
||||||
|
|
||||||
|
Рассмотрим повнимательнее первого осквернителя нашей загрузки: службу
|
||||||
|
+udev-settle.service+. Почему ей требуется так много времени для запуска, и что
|
||||||
|
мы можем с этим сделать? Эта служба выполняет очень простую задачу: она ожидает,
|
||||||
|
пока udev завершит опрос устройств, после чего завершается. Опрос же устройств
|
||||||
|
может занимать довольно много времени. Например, в нашем случае опрос устройств
|
||||||
|
занимает более 6~секунд из-за встроенного в компьютер 3G-модема, в котором
|
||||||
|
отсутствует SIM-карта. Этот модем очень долго отвечает на запросы udev. Опрос
|
||||||
|
устройств является частью схемы, обеспечивающей работу ModemManager'а и
|
||||||
|
позволяющей NetworkManager'у упростить для вас настройку 3G. Казалось бы,
|
||||||
|
очевидно, что виновником задержки является именно ModemManager, так как опрос
|
||||||
|
устройств для него занимает слишком много времени. Но такое обвинение будет
|
||||||
|
заведомо ошибочным. Дело в том, что опрос устройств очень часто оказывается довольно
|
||||||
|
длительной процедурой. Медленный опрос 3G-устройств для ModemManager является
|
||||||
|
частным случаем, отражающим это общее правило. Хорошая система опроса устройств
|
||||||
|
обязательно должна учитывать тот факт, что операция опроса любого из устройств
|
||||||
|
может затянуться надолго. Истинной причиной наших проблем является необходимость
|
||||||
|
ожидать завершения опроса устройств, т.е., наличие службы
|
||||||
|
+udev-settle.service+ как обязательной части нашего процесса загрузки.
|
||||||
|
|
||||||
|
Но почему эта служба вообще присутствует в нашем процессе загрузки? На самом
|
||||||
|
деле, мы можем прекрасно обойтись и без нее. Она нужна лишь как часть
|
||||||
|
используемой в Fedora схемы инициализации устройств хранения, а именно,
|
||||||
|
набора скриптов, выполняющих настройку LVM, RAID и multipath-устройств. На
|
||||||
|
сегодняшний день, реализация этих систем не~поддерживает собственного механизма
|
||||||
|
поиска и опроса устройств, и поэтому их запуск должен производиться только после
|
||||||
|
того, как эта работа уже проделана~--- тогда они могут просто последовательно
|
||||||
|
перебирать все диски. Однако, такой подход противоречит одному из
|
||||||
|
фундаментальных требований к современным компьютерам:
|
||||||
|
возможности подключать и отключать оборудование в любой момент, как при
|
||||||
|
выключенном компьютере, так и при включенном. Для некоторых
|
||||||
|
технологий невозможно точно определить момент завершения формирования списка устройств
|
||||||
|
(например, это характерно для USB и iSCSI), и поэтому процесс опроса
|
||||||
|
таких устройств обязательно должен включать некоторую фиксированную задержку,
|
||||||
|
гарантирующую, что все подключенные устройства успеют отозваться. С точки зрения
|
||||||
|
скорости загрузки это, безусловно, негативный эффект: соответствующие скрипты
|
||||||
|
заставляют нас ожидать завершения опроса устройств, хотя большинство этих
|
||||||
|
устройств не~являются необходимыми на данной стадии загрузки. В частности, в
|
||||||
|
рассматриваемой нами системе LVM, RAID и multipath вообще
|
||||||
|
не~используются!\footnote{Наиболее правильным решением в данном случае будет
|
||||||
|
ожидание событий подключения устройств (реализованное через libudev или
|
||||||
|
аналогичную технологию) с соответствующей обработкой каждого такого события~---
|
||||||
|
подобный подход позволит нам продолжить загрузку, как только будут готовы все
|
||||||
|
устройства, необходимые для ее продолжения. Для того, чтобы загрузка была
|
||||||
|
быстрой, мы должны ожидать завершения инициализации только тех устройств, которые
|
||||||
|
\emph{действительно} необходимы для ее продолжения на данной стадии. Ожидать
|
||||||
|
остальные устройства в данном случае смысла нет. Кроме того, стоит отметить, что
|
||||||
|
в числе программ, не~приспособленных для работы с динамически меняющимся
|
||||||
|
оборудованием и построенных в предположении о неизменности списка устройств,
|
||||||
|
кроме служб хранения, есть и другие подсистемы. Например, в нашем случае работа
|
||||||
|
initrd занимает так много времени главным образом из-за того, что для запуска
|
||||||
|
Plymouth необходимо дождаться завершения инициализации всех устройств
|
||||||
|
видеовывода. По неизвестной причине (во всяком случае, неизвестной для меня)
|
||||||
|
подгрузка модулей для моих видеокарт Intel занимает довольно продолжительное
|
||||||
|
время, что приводит к беспричинной задержке процесса загрузки. (Нет, я протестую
|
||||||
|
не~против опроса устройств, но против необходимости ожидать его завершения, чтобы
|
||||||
|
продолжить загрузку.)}
|
||||||
|
|
||||||
|
С учетом вышесказанного, мы можем спокойно исключить +udev-settle.service+ из
|
||||||
|
нашего процесса загрузки, так как мы не~используем ни~LVM, ни~RAID,
|
||||||
|
ни~multipath. Замаскируем эти службы, чтобы увеличить скорость загрузки:
|
||||||
|
\begin{Verbatim}
|
||||||
|
# ln -s /dev/null /etc/systemd/system/udev-settle.service
|
||||||
|
# ln -s /dev/null /etc/systemd/system/fedora-wait-storage.service
|
||||||
|
# ln -s /dev/null /etc/systemd/system/fedora-storage-init.service
|
||||||
|
# systemctl daemon-reload
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
После перезагрузки мы видим, что загрузка стала на одну секунду быстрее. Но
|
||||||
|
почему выигрыш оказался таким маленьким? Из-за второго осквернителя нашей
|
||||||
|
загрузки~--- cryptsetup. На рассматриваемой нами системе зашифрован раздел
|
||||||
|
+/home+. Специально для тестирования я записал пароль в файл, чтобы исключить
|
||||||
|
влияние скорости ручного набора пароля. К сожалению, для подключения
|
||||||
|
шифрованного раздела cryptsetup требует более пяти секунд. Будем ленивы, и
|
||||||
|
вместо того, чтобы исправлять ошибку в cryptsetup\footnote{На самом деле, я
|
||||||
|
действительно пытался исправить эту ошибку. Задержки в cryptsetup, по
|
||||||
|
моим наблюдениям, обусловлены, главным образом, слишком большим значением по
|
||||||
|
умолчанию для опции +--iter-time+. Я попытался доказать сопровождающим пакета
|
||||||
|
cryptsetup, что снижение этого времени с 1 секунды до 100~миллисекунд
|
||||||
|
не~приведет к трагическим последствиям для безопасности, однако они мне
|
||||||
|
не~поверили.}, попробуем найти обходной путь\footnote{Вообще-то я предпочитаю
|
||||||
|
решать проблемы, а не~искать пути для их обхода, однако в данном конкретном
|
||||||
|
случае возникает отличная возможность продемонстрировать одну интересную
|
||||||
|
возможность systemd\ldots{}}. Во время загрузки systemd должен дождаться, пока
|
||||||
|
все файловые системы, перечисленные в +/etc/fstab+ (кроме помеченных как
|
||||||
|
+noauto+) будут обнаружены, проверены и смонтированы. Только после этого systemd
|
||||||
|
может продолжить загрузку и приступить к запуску служб. Но первое обращение
|
||||||
|
к +/home+ (в отличие, например, от +/var+), происходит на поздней стадии
|
||||||
|
процесса загрузки (когда пользователь входит в систему). Следовательно, нам
|
||||||
|
нужно сделать так, чтобы этот каталога автоматически монтировался при загрузке,
|
||||||
|
но процесс загрузки не~ожидал завершения работы +cryptsetup+, +fsck+ и +mount+
|
||||||
|
для этого раздела. Как же сделать точку монтирования доступной, не~ожидая, пока
|
||||||
|
завершится процесс монтирования? Это можно сделать, воспользовавшись магической
|
||||||
|
силой systemd~--- просто добавим опцию монтирования +comment=systemd.automount+
|
||||||
|
в +/etc/fstab+. После этого, systemd будет создавать в +/home+ точку
|
||||||
|
автоматического монтирования, и при первом же обращении к этому каталогу
|
||||||
|
systemd выполнит подготовку устройства, проверку и монтирование файловой
|
||||||
|
системы.
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|
||||||
vim:ft=tex:tw=80:spell:spelllang=ru
|
vim:ft=tex:tw=80:spell:spelllang=ru
|
||||||
|
|||||||
Reference in New Issue
Block a user