Оптимизация initramfs в Debian

()

Debian Linux это один из самых популярных современных дистрибутивов, являющийся кроме того "родителем" целого ряда других дистрибутивов, в частности Ubuntu, Linux Mint и проч. Популярность Debian завоевал благодаря своей дружественности к пользователю.

Однако у этой дружественности есть и ряд минусов: попытка "угодить всем" привела к тому, что далеко не все элементы системы с конфигурацией по умолчанию работают оптимально. Например образ initramfs занимает на диске почти десять мегабайт и содержит в себе практически все доступные модули, что конечно же в условиях конкретной задачи является излишним.

Далее будет предпринята попытка максимально подробно разобрать способ генерации initramfs в Debian и показать как можно его оптимизировать.

Итак, что же такое initramfs? Согласно википедии это "временная файловая система, использующаяся ядром при начальной загрузке". Проще говоря загрузчик загружает в память ядро и образ initramfs, и начальная загрузка системы происходит из этого образа. Соответственно чем меньше лишнего в этом образе - тем быстрее будет загружаться система и тем меньше она будет требовать памяти на начальном этапе.

Прежде чем продолжить нужно сделать два уточнения. Первое: все описанные здесь инструкции справедливы не только для Debian, но и для большинства его "потомков". Второе: да, конечно, если пересобрать ядро руками то можно вообще отказаться от initramfs, но не все и не всегда хотят при каждом обновлении заново пересобирать ядро. Поэтому лучше просто оптимизировать initramfs штатными средствами дистрибутива.

Образ initramfs создаётся утилитой update-initramfs. Пронаблюдать как создаётся образ для текущего ядра с настройками по умолчанию можно запустив создание этого образа командой:

update-initramfs -v -c -k `uname -r`

Можно заметить что сначала добавляются модули, потом минимально-необходимые базовые утилиты и потом выполняются "хуки" (hooks) - модули для update-initramfs, которые добавляют в образ различные дополнительные функции. Например хук dmsetup добавляют поддержку функционала Device Mapper, а хук fuse_utils - поддержку файловых систем, доступных через fuse.

Следует отметить что если в образе initramfs отсутствует какой-то модуль то он будет загружен позже, уже с жёсткого диска (главное чтобы набор модулей в образе позволял ядру добраться до этого жёсткого диска).

Основные настройки update-initramfs расположены в директории /etc/initramfs-tools. Начнём со списка загружаемых модулей. Чтобы загружать только нужные изменим значение параметра MODULES в файле initramfs.conf:

#MODULES=most
MODULES=list

Дальше нам нужно создать список необходимых модулей. Самое просто решение тут - просто взять список уже загруженых модулей и использовать его. Список модулей храниться в файле modules. Создадим его, получив список загруженных модулей через lsmod:

lsmod | tail -n +2 | sort | awk '{print $1;}' > /etc/initramfs-tools/modules

Затем пересоздадим образ initramfs, предварительно удалив старый:

update-initramfs -v -d -k `uname -r` && update-initramfs -v -c -k `uname -r`

Желающие могут сравнить размеры файлов /boot/initrd.img-* до и после этой команды и, так сказать, "почувствовать разницу".

С модулями вобщем-то разобрались. Переходим к хукам. Системные хуки хранятся в директории /usr/share/initramfs-tools/hooks, пользователь (вернее администратор системы) может определять свои хуки в директории /etc/initramfs-tools/hooks (по умолчанию в ней пусто).

Чтобы понять какой хук за что отвечает проще всего выяснить какому пакету он принадлежит и читать документацию на этот пакет. Получить список пакетов-владельцев хуков можно командой:

find /usr/share/initramfs-tools/hooks/ -type f -exec dpkg -S '{}' \;

К сожалению при генерации образа initramfs нельзя указать список хуков, которые надо пропустить. Поэтому единственным способом убрать лишнее из initramfs является удаление пакета, содержащего не нужный хук. Ну или удаление файла хука (однако следует помнить что в этом случае при обновлении системы он будет создан заново).

Хуки принадлежащие initramfs-tools и udev лучше не трогать. С остальными нужно разбираться по ситуации. Например если речь о сервере то вряд ли там используются какие либо файловые системы, монтируемые через fuse, а значит хуки fuse_utils И ntfs_3g явно лишние. Освободить initramfs от них можно следующим образом:

apt-get purge fuse-utils ntfs-3g && apt-get autoremove --purge && update-initramfs -v -c -k `uname -r`

Если речь идёт о рабочей станции то чаще всего поддержка Drive Mapper бывает ненужна. Как уже говорилось выше - за неё отвечает хук dmsetup, являющийся частью одноимённого пакета. В этом случае убрать его можно командой:

apt-get purge dmsetup && apt-get autoremove --purge && update-initramfs -v -c -k `uname -r`

Отдельного внимания заслуживает вопрос явной пересборки образа после внесения каких либо изменений в его конфигурацию, ведь после установки/удаления пакетов, меняющих эту конфигурацию dpkg сам вызывает update-initramfs для обновления образа. Дело в том, что dpkg запускает update-initramfs командой:

update-initramfs -u -k all

Здесь опция "-k" указывает на ядро ("all" - означает все ядра, имеющиеся в системе), а "-u" - указывает а необходимость обновить (но не пересоздать с нуля!) образ initramfs.

При обновлении образа может остаться какой-то не нужный мусор, поэтому лучше всё-таки собирать образ с нуля, что и делается командой:

update-initramfs -c -k all

То есть вместо "-u" указывается ключ "-c", указывающий на необходимость пересоздания образа с нуля. Для наглядности так же можно указывать ключ "-v" - в этом случае по ходу создания образа будет показана информация обо всех предпринимаемых действиях.

В конечном итоге если вдумчиво подойти к описанному выше - можно уменьшить размер сжатого образа в два-четыре раза, что позволит ускорить загрузку на несколько десятков секунд.

Приятной работы!

Ключевые слова: оптимизация, initramfs, debian.

Комментарии:

Kirill Zabarniuk 2008-11-17 14:12:31 (#)

Раз уж решили минимизировать число модулей в initrd, то после указания
MODULES=list

список модулей лучше получить, загрузившись с параметром ядру init=/bin/sh. Тогда увидите действительно минимально необходимое для загрузки кол-во модулей. Плюс потом можно еще прошерстить выхлоп lsmod вручную.
upd. А, тут написано "самое простое решение..." - тогда да, это решение самое простое.

MooSE 2008-11-17 15:56:56 (#)

В любом случае список, получаемый по lsmod, много меньше того, что пихается по умолчанию...

Олег777 2008-12-04 14:04:09 (#)

Хочется добавить, что указанный метод подхватывает модули с параметрами. Что может привести к некоторым недоразумениям при обновлении ядра.

MooSE 2008-12-05 14:15:27 (#)

при обновлении ядра можно пройти всю цепочку заново. хотя у меня пока проблем не было.

Alexander Sashnov 2009-01-15 07:22:56 (#)

yaird разве не та утилита, которая генерирует initrd только с нужными для этой машины модулями?

MooSE 2009-01-16 15:24:14 (#)

Попробовал я его. В итоге получил следующее:

first ~ # yaird --output=/root/test
yaird error: bad device link in /sys/block/sda (fatal)


Так и не понял откуда такое счастье и забил...

Windows 2009-09-23 13:04:41 (#)

Вопрос!

А размер самого загруженного ядра уменьшается, если уменьшить образ initramfs?

Спрашиваю, потому как, если памяти на серваке много, то стоит ли возиться с initramfs, если он только уменьшает время загрузки?

Заранее спасибо.

MooSE 2009-09-23 18:00:28 (#)

Цитата:


А размер самого загруженного ядра уменьшается, если уменьшить образ initramfs?


Нет конечно. :)

На серверах может и не стоит возиться, а вот на слабых машинах - полезною

Anonymous 2009-10-07 21:36:21 (#)

just 4 fun:
pathos-laptop:/boot# du -sh *
96K config-2.6.26-2-686
284K grub
5.0M initrd.img-2.6.26-2-686 - стало
3.9M initrd.img-2.6.26-2-686. - было
2.8M initrd.img-2.6.26-2-686.bak
108K memtest86.bin
912K System.map-2.6.26-2-686
1.5M vmlinuz-2.6.26-2-686
pathos-laptop:/boot#

Anonymous 2013-08-10 20:41:44 (#)

Спасибо вам, немного использовал ваши материалы, могу сказать что для обновления initrd достаточно просто
update-initramfs -u
выполнить.

У меня тут неттоп слабенький в качестве мини-сервера, вот я и занялся облегчением системы, еще можно скрипты переписать в инитрд и сам файл init модифицировать так, чтобы он не определял оборудования и не делал лишние проверки, а просто делал несколько строчек modprobe и mount, но это уже для особых извращенцев типа меня)))
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE