Глава 6. dracut
Содержание
Проще говоря, dracut это некий инструментарий, который создаёт ф системах на основе Fedora соответствующую
файловую систему initramfs. Системы на основе Debian и Ubuntu пользуются аналогичным инструментарием, носящим
название update-initramfs
. Когда вы желаете создать, повторно
выработать или персонализировать уде имеющуюся initramfs, тогда вам следует знать как пользоваться этим
инструментарием dracut. Кроме того, вы ознакомитесь с наиболее распространёнными проблемами "Can’t Boot",
относящимися к initramfs.
Всякое ядро обладает своим собственным файлом initramfs, но для вас может оказаться интересным почему же вам
никогда не приходилось применять для создания initramfs при установке некого нового ядра соответствующей команды
dracut
. Вместо этого вы просто отыскиваете надлежащий initramfs в
имеющемся местоположении /boot
. Ну хорошо, когда вы устанавливаете
какое- то новое ядро, соответствующая выполняемая по завершению сценария (post-scripts
)
команда пакета rpm
этого ядра вызывает dracut
и создаёт для вас initramfs. Давайте рассмотрим как это работает в системе на основании Fedora:
# rpm -q --scripts kernel-core-5.3.7-301.fc31.x86_64
postinstall scriptlet (using /bin/sh):
if [ `uname -i` == "x86_64" -o `uname -i` == "i386" ] &&
[ -f /etc/sysconfig/kernel ]; then
/bin/sed -r -i -e 's/^DEFAULTKERNEL=kernel-smp$/DEFAULTKERNEL=kernel/' /etc/sysconfig/kernel || exit $?
fi
preuninstall scriptlet (using /bin/sh):
/bin/kernel-install remove 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz || exit $?
posttrans scriptlet (using /bin/sh):
/bin/kernel-install add 5.3.7-301.fc31.x86_64 /lib/modules/5.3.7-301.fc31.x86_64/vmlinuz || exit $?
Как вы можете видеть, соответствующая команда post-scripts
запускаемого
пакета ядра вызывает надлежащий сценарий kernel-install
. Этот сценарий
kernel-install
выполняет все те сценарии, которые доступны в
/usr/lib/kernel/install.d
.
# vim /bin/kernel-install
94 if ! [[ $MACHINE_ID ]]; then
95 ENTRY_DIR_ABS=$(mktemp -d /tmp/kernel-install.XXXXX) || exit 1
96 trap "rm -rf '$ENTRY_DIR_ABS'" EXIT INT QUIT PIPE
97 elif [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
98 ENTRY_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
99 elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then
100 ENTRY_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
101 elif [[ -d /boot/efi/loader/entries ]] || [[ -d /boot/efi/$MACHINE_ID ]]; then
102 ENTRY_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
103 elif mountpoint -q /efi; then
104 ENTRY_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
105 elif mountpoint -q /boot/efi; then
106 ENTRY_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
107 else
108 ENTRY_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
109 fi
110
111 export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
112
113 ret=0
114
115 readarray -t PLUGINS <<<"$(
116 dropindirs_sort ".install" \
117 "/etc/kernel/install.d" \
118 "/usr/lib/kernel/install.d"
119 )"
Здесь вы можете рассмотреть как наши сценарии выполняются kernel-install
:
# ls /usr/lib/kernel/install.d/ -lh
total 36K
-rwxr-xr-x. 1 root root 744 Oct 10 18:26 00-entry-directory.install
-rwxr-xr-x. 1 root root 1.9K Oct 19 07:46 20-grubby.install
-rwxr-xr-x. 1 root root 6.6K Oct 10 13:05 20-grub.install
-rwxr-xr-x. 1 root root 829 Oct 10 18:26 50-depmod.install
-rwxr-xr-x. 1 root root 1.7K Jul 25 2019 50-dracut.install
-rwxr-xr-x. 1 root root 3.4K Jul 25 2019 51-dracut-rescue.install
-rwxr-xr-x. 1 root root 3.4K Oct 10 18:26 90-loaderentry.install
-rwxr-xr-x. 1 root root 1.1K Oct 10 13:05 99-grub-mkconfig.install
Как вы можете видеть, это выполняет сценарий 50-dracut.install
. Именно
этот конкретный сценарий выполняет соответствующую команду dracut
и
создаёт initramfs для какого- то определённого ядра.
46 for ((i=0; i < "${#BOOT_OPTIONS[@]}"; i++)); do
47 if [[ ${BOOT_OPTIONS[$i]} == root\=PARTUUID\=* ]]; then
48 noimageifnotneeded="yes"
49 break
50 fi
51 done
52 dracut -f ${noimageifnotneeded:+--noimageifnotneeded} "$BOOT_DIR_ABS/$INITRD" "$KERNEL_VERSION"
53 ret=$?
54 ;;
55 remove)
56 rm -f -- "$BOOT_DIR_ABS/$INITRD"
57 ret=$?
58 ;;
59 esac
60 exit $ret
Аналогично имеется надлежащий сценарий 51-dracut-rescue.install
, который
создаст initramfs для соответствующего аварийного ядра.
100 if [[ ! -f "$BOOT_DIR_ABS/$INITRD" ]]; then
101 dracut -f --no-hostonly -a "rescue" "$BOOT_DIR_ABS/$INITRD" "$KERNEL_VERSION"
102 ((ret+=$?))
103 fi
104
105 if [[ "${BOOT_DIR_ABS}" != "/boot" ]]; then
106 {
107 echo "title $PRETTY_NAME - Rescue Image"
108 echo "version $KERNEL_VERSION"
109 echo "machine-id $MACHINE_ID"
110 echo "options ${BOOT_OPTIONS[@]} rd.auto=1"
111 echo "linux $BOOT_DIR/linux"
112 echo "initrd $BOOT_DIR/initrd"
113 } > $LOADER_ENTRY
114 else
115 cp -aT "${KERNEL_IMAGE%/*}/bls.conf" $LOADER_ENTRY
116 sed -i 's/'$KERNEL_VERSION'/0-rescue-'${MACHINE_ID}'/' $LOADER_ENTRY
117 fi
Тем самым, всякое ядро будет обладать своим собственным файлом initramfs.
# ls -lh /boot | grep -e vmlinuz -e initramfs
-rw-------. 1 root root 80M Dec 2 18:32 initramfs-0-rescue-280526b3bc5e4c49ac83c8e5fbdfdb2e.img
-rw-------. 1 root root 28M Dec 23 06:37 initramfs-5.3.16-300.fc31.x86_64.img
-rw-------. 1 root root 30M Dec 2 18:33 initramfs-5.3.7-301.fc31.x86_64.img
-rwxr-xr-x. 1 root root 8.9M Dec 2 18:32 vmlinuz-0-rescue-280526b3bc5e4c49ac83c8e5fbdfdb2e
-rwxr-xr-x. 1 root root 8.9M Dec 13 23:51 vmlinuz-5.3.16-300.fc31.x86_64
-rwxr-xr-x. 1 root root 8.9M Oct 22 01:04 vmlinuz-5.3.7-301.fc31.x86_64
Обратите внимание на размер файла самого ядра (vmlinuz
) и связанного с
ним файла initramfs. Размер файла намного больше размера ядра.
Сначала проверим при помощи данной команды проверим какое ядро было установлено в вашей системе:
# rpm -qa | grep -i kernel-5
kernel-5.3.16-300.fc31.x86_64
kernel-5.3.7-301.fc31.x86_64
Выберите ту версию ядра, для которой вы желаете выработать некий новый образ initramfs и передайте его в dracut.
# dracut /boot/new.img 5.3.7-301.fc31.x86_64 -v
<snip>
dracut: Executing: /usr/bin/dracut /boot/new.img 5.3.7-301.fc31.x86_64 -v
dracut: dracut module 'busybox' will not be installed, because command 'busybox' could not be found!
dracut: dracut module 'stratis' will not be installed, because command 'stratisd-init' could not be found!
dracut: dracut module 'biosdevname' will not be installed, because command 'biosdevname' could not be found!
dracut: dracut module 'busybox' will not be installed, because command 'busybox' could not be found!
dracut: dracut module 'stratis' will not be installed, because command 'stratisd-init' could not be found!
dracut: *** Including module: bash ***
dracut: *** Including module: systemd ***
dracut: *** Including module: systemd-initrd ***
dracut: *** Including module: nss-softokn ***
dracut: *** Including module: i18n ***
dracut: *** Including module: network-manager ***
dracut: *** Including module: network ***
dracut: *** Including module: ifcfg ***
dracut: *** Including module: drm ***
dracut: *** Including module: plymouth ***
.
.
</snip>
В нашем предыдущем коде dracut создаст некую initramfs с названием new.img
в текущем каталоге для соответствующего 64- битного ядра Fedora,
Kernel-5.3.7-301.fc31.x86_64
.
# ls -lh new.img
-rw-------. 1 root root 28M Dec 23 08:16 new.img
Если запрошенная версия ядра не представлена, тогда dracut сделает initramfs для того ядра, через которое
запускалась данная система. Значение передаваемой в dracut версии ядра должно соответствовать значению каталога ядра в
местоположении /lib/modules/
.
# ls /lib/modules/ -l
total 4
drwxr-xr-x. 6 root root 4096 Dec 9 10:18 5.3.7-301.fc31.x86_64
# ls /lib/modules/5.3.7-301.fc31.x86_64/ -l
total 18084
-rw-r--r--. 1 root root 249 Oct 22 01:04 bls.conf
lrwxrwxrwx. 1 root root 38 Oct 22 01:04 build -> /usr/src/kernels/5.3.7-301.fc31.x86_64
-rw-r--r--. 1 root root 213315 Oct 22 01:03 config
drwxr-xr-x. 5 root root 4096 Oct 24 04:44 extra
drwxr-xr-x. 13 root root 4096 Oct 24 04:43 kernel
-rw-r--r--. 1 root root 1127438 Dec 9 10:18 modules.alias
-rw-r--r--. 1 root root 1101059 Dec 9 10:18 modules.alias.bin
-rw-r--r--. 1 root root 1688 Oct 22 01:04 modules.block
-rw-r--r--. 1 root root 8324 Oct 22 01:04 modules.builtin
-rw-r--r--. 1 root root 10669 Dec 9 10:18 modules.builtin.bin
-rw-r--r--. 1 root root 60853 Oct 22 01:04 modules.builtin.modinfo
-rw-r--r--. 1 root root 415475 Dec 9 10:18 modules.dep
-rw-r--r--. 1 root root 574502 Dec 9 10:18 modules.dep.bin
-rw-r--r--. 1 root root 381 Dec 9 10:18 modules.devname
-rw-r--r--. 1 root root 153 Oct 22 01:04 modules.drm
-rw-r--r--. 1 root root 59 Oct 22 01:04 modules.modesetting
-rw-r--r--. 1 root root 2697 Oct 22 01:04 modules.networking
-rw-r--r--. 1 root root 139947 Oct 22 01:04 modules.order
-rw-r--r--. 1 root root 700 Dec 9 10:18 modules.softdep
-rw-r--r--. 1 root root 468520 Dec 9 10:18 modules.symbols
-rw-r--r--. 1 root root 572778 Dec 9 10:18 modules.symbols.bin
lrwxrwxrwx. 1 root root 5 Oct 22 01:04 source -> build
-rw-------. 1 root root 4426726 Oct 22 01:03 System.map
drwxr-xr-x. 2 root root 4096 Oct 22 01:02 updates
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 vdso
-rwxr-xr-x. 1 root root 9323208 Oct 22 01:04 vmlinuz
Как мы знаем, initramfs это некая временная корневая файловая система и её главная цель состоит в предоставлении некой среды, которая поможет смонтировать необходимую корневую файловую систему пользователя. Такая корневая файловая система пользователя может быть локальной в системе или это может быть некое сетевое устройство и для применения такого устройства наше ядро обязано обладать драйверами (модулями) для этого оборудования и, в процессе запуска получать подобные модули из initramfs.
Скажем, допустим соответствующая корневая файловая система пользователя расположена на каком- то локально подключённом жёстком диске и этот HDD это устройство SCSI. Следовательно, initramfs обязана обладать необходимыми драйверами SCSI, добавляемыми в её архив.
# lsinitrd | grep -i scsi | awk '{ print $9 }'
etc/ld.so.conf.d/libiscsi-x86_64.conf
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/firmware/iscsi_ibft.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/iscsi_boot_sysfs.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/libiscsi.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/qla4xxx
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/qla4xxx/qla4xxx.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/scsi_transport_iscsi.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/scsi_transport_srp.ko.xz
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/virtio_scsi.ko.xz
usr/lib/udev/scsi_id
Поверх данного устройства SCSI пользователи могут иметь настроенным некое устройство RAID. Когда и это имеет
место, тогда нашему ядру также требуется иметь драйверы устройства RAID для идентификации и сборки необходимого
устройства RAID. Аналогично, некоторые имеющиеся HDD пользователя могут подключаться через какую- то карту HBA.
В подобных случаях нашему ядру требуются модули наподобии qlaXxxx
.
# lsinitrd | grep -i qla
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/qla4xxx
usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/qla4xxx/qla4xxx.ko.xz
Обратите внимание, что в наше время '/lib'
это символическая ссылка на
'/usr/lib/'
.
В случае некоторых пользователей соответствующий HDD можем поступать через Fiber Channel over Ethernet. Тогда
нашему ядру потребуются модули FCOE. В некой среде с виртуализацией такой HDD может быть каким- то виртуальным диском,
выставляемым гипервизором. В такой ситуации для монтирования подобной корневой файловой системы пользователя
необходим модуль virtIO
. Таким образом, имеющийся перечень оборудования и
соответствующих ему модулей продолжает расти.
Очевидно, что само ядро не способно хранить все такие необходимые файлы модулей (.ko
)
в своём собственном исполняемом файле (vmlinuz
). Следовательно, одно из основных заданий
initramfs состоит в хранении всех таких модулей, которые требуются для монтирования необходимой корневой файловой системы
пользователя. Именно это также одна из причин, по которой размер файла initramfs намного больше по сравнению с
размером файла ядра. Однако помните, что initramfs не выступает в качестве источника таких модулей. Эти модули всегда
будут предоставляться в имеющееся ядро и архивироваться в initramfs через dracut. Само ядро
(vmlinuz
) является источником всех необходимых модулей, однако как вы могли
предугадать, размер подобного ядра будет гигантским если само ядро будет хранить все подобные модули в собственном
исполняемом файле vmlinuz
. Следовательно, помимо некого пакета
kernel
, был введён некий новый пакет с названием
kernel-modules
и именно этот пакет и предоставляет все необходимые модули,
которые представлены в соответствующем местоположении /lib/modules/<kernel-version-arch>
;
dracut вытаскивает лишь те модули (.ko
), которые необходимы для монтирования
соответствующей корневой файловой системы пользователя.
# rpm -qa | grep -i kernel
Kernel-headers-5.3.6-300.fc31.x86_64
kernel-modules-extra-5.3.7-301.fc31.x86_64
kernel-modules-5.3.7-301.fc31.x86_64
kernel-core-5.3.16-300.fc31.x86_64
kernel-core-5.3.7-301.fc31.x86_64
kernel-5.3.16-300.fc31.x86_64
abrt-addon-kerneloops-2.12.2-1.fc31.x86_64
kernel-5.3.7-301.fc31.x86_64
libreport-plugin-kerneloops-2.10.1-2.fc31.x86_64
Kernel-modules-5.3.16-300.fc31.x86_64
# rpm -ql kernel-modules-5.3.7-301.fc31.x86_64 | wc -l
1698
# rpm -ql kernel-modules-5.3.7-301.fc31.x86_64
<snip>
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/atmtcp.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/eni.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/firestream.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/he.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/nicstar.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/solos-pci.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/atm/suni.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/auxdisplay/cfag12864b.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/auxdisplay/cfag12864bfb.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/auxdisplay/charlcd.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/auxdisplay/hd44780.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/auxdisplay/ks0108.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bcma/bcma.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/ath3k.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/bcm203x.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/bfusb.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/bluecard_cs.ko.xz
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/bpa10x.ko.xz
.
.
</snip>
Как вы можете видеть, соответствующий пакет kernel-modules
, который
поставляется с kernel-5.3.7-301
, предоставляет почти 1 698 модулей.
Кроме того, этот пакет kernel-module
будет обладать некой зависимостью от
своего пакета kernel
; таким образом, при каждой установке
kernel
, операционная система Fedora будет доставлять и устанавливать
kernel-modules
.
Теперь мы ознакомимся с модулями dracut.
Чтобы разобраться в том как dracut вытаскивает необходимые модули в initramfs, сначала нам необходимо понять
команду depmod
. depmod
анализирует
все имеющиеся в местоположении /lib/modules/<kernel-version-arch>
модули
ядра и составляет некий список всех этих модулей совместно с их модулями зависимостей. Он оставляет этот перечень
в файле modules.dep
. (Обратите внимание, что в системах на основании Fedora
лучше ссылаться на это местоположение модулей как на
/usr/lib/modules/<kernel_version>/*
,) Вот некий образец:
# vim /lib/modules/5.3.7-301.fc31.x86_64/modules.dep
<snip>
.
.
kernel/arch/x86/kernel/cpu/mce/mce-inject.ko.xz:
kernel/arch/x86/crypto/des3_ede-x86_64.ko.xz: kernel/crypto/des_generic.ko.xz
kernel/arch/x86/crypto/camellia-x86_64.ko.xz:
kernel/arch/x86/crypto/blowfish-x86_64.ko.xz: kernel/crypto/blowfish_common.ko.xz
kernel/arch/x86/crypto/twofish-x86_64.ko.xz: kernel/crypto/twofish_common.ko.xz
.
.
</snip>
В приведённом коде вы можете обнаружить что модуль с названием des3_ede
для надлежащей работы нуждается в модуле des_generic
. В другом примере мы
видите, что модули blowfish
обладают в качестве зависимости модулем
blowfish_comman
. А потому dracut считывает имеющийся файл
modules.dep
и начинает активную доставку необходимых модулей ядра в
создаваемый образ initramfs из местоположения
/lib/modules/5.3.7-301.fc31.x86_64/kernel/
.
# ls /lib/modules/5.3.7-301.fc31.x86_64/kernel/ -l
total 44
drwxr-xr-x. 3 root root 4096 Oct 24 04:43 arch
drwxr-xr-x. 4 root root 4096 Oct 24 04:43 crypto
drwxr-xr-x. 80 root root 4096 Oct 24 04:43 drivers
drwxr-xr-x. 43 root root 4096 Oct 24 04:43 fs
drwxr-xr-x. 4 root root 4096 Oct 24 04:43 kernel
drwxr-xr-x. 8 root root 4096 Oct 24 04:43 lib
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 mm
drwxr-xr-x. 51 root root 4096 Oct 24 04:43 net
drwxr-xr-x. 3 root root 4096 Oct 24 04:43 security
drwxr-xr-x. 13 root root 4096 Oct 24 04:43 sound
drwxr-xr-x. 3 root root 4096 Oct 24 04:43 virt
Наше ядро предоставляет тысячи модулей, но нет нужды добавлять в initramfs все модули. Таким образом, при сборе модулей dracut вытаскивает все конкретные модули.
# find /lib/modules/5.3.7-301.fc31.x86_64/ -name '*.ko.xz' | wc -l
3539
Когда dracut вытягивает все модули, тогда размер initramfs был бы огромным. Кроме того, зачем вытаскивать все модули, когда это не необходимо? Итак, dracut вытаскивает лишь те модули, которые необходимы для монтажа необходимой корневой файловой системы в данной системе.
# lsinitrd | grep -i '.ko.xz' | wc -l
221
Как вы можете видеть, initramfs имеет лишь 221 модуль, в то время как его ядро обладает в себе почти 3 539 модулями.
Если бы мы включили в initramfs 3 539 модулей, это бы превратило initramfs в гигантский, что в конечном счёте
замедлило бы производительность запуска потому как время загрузки м раскрытия архива initramfs было бы высоким.
Кроме того, нам следует понимать, что главная задача initramfs состоит в монтировании основной корневой файловой
системы пользователя. Таким образом, это делает существенным включение лишь только тех модулей, которые необходимы
для монтирования самой корневой файловой системы. Например, в initramfs нет необходимости добавления модулей
Bluetooth, ибо корневая файловая система никогда не приходит на подключаемых через Bluetooth устройствах. Поэтому в
initramfs вы не найдёте связанных с Bluetooth модулей, даже хотя и имеется пара предоставляемых самим ядром
(kernel-modules
) модулей bluetooth
.
# find /lib/modules/5.3.7-301.fc31.x86_64/ -name 'bluetooth'
/lib/modules/5.3.7-301.fc31.x86_64/kernel/net/bluetooth
/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth
# lsinitrd | grep -i blue
<no_output>
По умолчанию dracut добавит в initramfs лишь относящиеся к хосту модули. Он выполняет это инспектируя состояние
своей текущей системы и тех модулей, которые в настоящий модуль применяются данной системой. Для всех ведущих
дистрибутивов Linux подходом по умолчанию является отслеживание специфики хоста. Подобные Fedors и Ubuntu системы
также создают некий общий образ initramfs, имеющий название аварийного образа
initramfs. Такой аварийный initramfs содержит все возможные модули для устройств на которых пользователи
имеют возможность создавать некую корневую файловую систему. Основная идея состоит в том, что такая общая initramfs
должна подходить ко всем имеющимся системам. Следовательно, такая аварийная initramfs всегда будет большей в размере
по сравнению с initramfs специфичными для конкретных хостов. Dracut обладает пакетом некой логики для принятия решения
какие модули необходимы для монтирования своей корневой файловой системы. Именно об этом сообщает страница man, но
помните, что в Linux на основе Fedora по умолчанию устанавливается --hostonly
.
"Если вы желаете создавать более лёгкие initramfs с меньшим размером, вы можете захотеть определять вариант --hostonly или -H. Применяя данный вариант, получаемый в результате образ будет содержать лишь те dracut модули, модули ядра и файловые системы, которые необходимы для запуска этой конкретной машины. Это обладает тем недостатком, что вы можете поместить свой диск на другом контроллере или машине и вы не сможете переключиться на другую корневую файловую систему без повторного создания соответствующего образа initramfs. Применение варианта -hostonly служит лишь для профессионалов и вам придётся хранить осколки. По крайней мере храните копию образа общего назначения (и соответствующие ядра) в качестве запасного варианта для спасения своей системы."
В Главе 5 мы обнаружили, что существует большое число исполняемых файлов, модулей и файлов настройки, которые были выбраны dracut и добавлены в initramfs, но каким образом dracut выбирает файлы из корневой файловой системы пользователя большего размера?
Эти файлы выбираются запуском сценариев из /usr/lib/dracut/modules.d
.
Именно в этом месте хранятся все необходимые сценарии dracut. Dracut запускает эти сценарии при выработке initramfs
как это показано тут:
# ls /usr/lib/dracut/modules.d/ -l
total 288
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 00bash
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 00systemd
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 00warpclock
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 01fips
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 01systemd-initrd
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 02systemd-networkd
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 03modsign
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 03rescue
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 04watchdog
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 05busybox
drwxr-xr-x. 2 root root 4096 Oct 24 04:42 05nss-softokn
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 05rdma
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 10i18n
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 30convertfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 35network-legacy
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 35network-manager
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 40network
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 45ifcfg
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 45url-lib
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 50drm
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 50plymouth
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 80lvmmerge
drwxr-xr-x. 2 root root 4096 Oct 24 04:42 90bcache
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90btrfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90crypt
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90dm
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90dmraid
drwxr-xr-x. 2 root root 4096 Oct 24 04:44 90dmsquash-live
drwxr-xr-x. 2 root root 4096 Oct 24 04:44 90dmsquash-live-ntfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90kernel-modules
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90kernel-modules-extra
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90kernel-network-modules
drwxr-xr-x. 2 root root 4096 Oct 24 04:44 90livenet
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90lvm
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90mdraid
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90multipath
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90qemu
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90qemu-net
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 90stratis
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 91crypt-gpg
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 91crypt-loop
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95cifs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95debug
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95fcoe
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95fcoe-uefi
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95fstab-sys
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95iscsi
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95lunmask
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95nbd
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95nfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95resume
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95rootfs-block
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95ssh-client
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95terminfo
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95udev-rules
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 95virtfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 97biosdevname
drwxr-xr-x. 2 root root 4096 Jan 6 12:42 98dracut-systemd
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 98ecryptfs
drwxr-xr-x. 2 root root 4096 Oct 24 04:44 98ostree
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 98pollcdrom
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 98selinux
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 98syslog
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 98usrmount
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99base
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99earlykdump
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99fs-lib
drwxr-xr-x. 2 root root 4096 Oct 24 04:44 99img-lib
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99kdumpbase
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99shutdown
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99squash
drwxr-xr-x. 2 root root 4096 Oct 24 04:43 99uefi-lib
Тот же самый вывод можно получить воспользовавшись
#dracut --list-modules
.
При каждой попытке создания initramfs dracut запускает файлы сценария module-setup.sh
во всех каталогах /usr/lib/dracut/modules.d/
.
# find /usr/lib/dracut/modules.d/ -name 'module-setup.sh'
/usr/lib/dracut/modules.d/95iscsi/module-setup.sh
/usr/lib/dracut/modules.d/98ecryptfs/module-setup.sh
/usr/lib/dracut/modules.d/30convertfs/module-setup.sh
/usr/lib/dracut/modules.d/90crypt/module-setup.sh
/usr/lib/dracut/modules.d/10i18n/module-setup.sh
/usr/lib/dracut/modules.d/99earlykdump/module-setup.sh
/usr/lib/dracut/modules.d/95nbd/module-setup.sh
.
.
.
/usr/lib/dracut/modules.d/04watchdog/module-setup.sh
/usr/lib/dracut/modules.d/90lvm/module-setup.sh
/usr/lib/dracut/modules.d/35network-legacy/module-setup.sh
/usr/lib/dracut/modules.d/01systemd-initrd/module-setup.sh
/usr/lib/dracut/modules.d/99squash/module-setup.sh
/usr/lib/dracut/modules.d/05busybox/module-setup.sh
/usr/lib/dracut/modules.d/50drm/module-setup.sh
Этот сценарий module-setup.sh
выцепит модули, исполняемые файлы и
файлы настройки, которые специфичны для данного хоста. К примеру, самый первый сценарий
module-setup.sh
, который мы запускаем в каталоге
00bash
, включит в initramfs необходимый исполняемый файл
bash
.
# vim /usr/lib/dracut/modules.d/00bash/module-setup.sh
1 #!/usr/bin/bash
2
3 # called by dracut
4 check() {
5 require_binaries /bin/bash
6 }
7
8 # called by dracut
9 depends() {
10 return 0
11 }
12
13 # called by dracut
14 install() {
15 # If another shell is already installed, do not use bash
16 [[ -x $initdir/bin/sh ]] && return
17
18 # Prefer bash as /bin/sh if it is available.
19 inst /bin/bash && ln -sf bash "${initdir}/bin/sh"
20 }
21
Как вы можете видеть, этот сценарий добавляет в initramfs соответствующий исполняемый файл
/bin/bash
. Давайте рассмотрим другой пример и он относится к
plymouth
.
# vim /usr/lib/dracut/modules.d/50plymouth/module-setup.sh
1 #!/usr/bin/bash
2
3 pkglib_dir() {
4 local _dirs="/usr/lib/plymouth /usr/libexec/plymouth/"
5 if type -P dpkg-architecture &>/dev/null; then
6 _dirs+=" /usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/plymouth"
7 fi
8 for _dir in $_dirs; do
9 if [ -x $_dir/plymouth-populate-initrd ]; then
10 echo $_dir
11 return
12 fi
13 done
14 }
15
16 # called by dracut
17 check() {
18 [[ "$mount_needs" ]] && return 1
19 [ -z $(pkglib_dir) ] && return 1
20
21 require_binaries plymouthd plymouth plymouth-set-default-theme
22 }
23
24 # called by dracut
25 depends() {
26 echo drm
27 }
28
29 # called by dracut
30 install() {
31 PKGLIBDIR=$(pkglib_dir)
32 if grep -q nash ${PKGLIBDIR}/plymouth-populate-initrd \
33 || [ ! -x ${PKGLIBDIR}/plymouth-populate-initrd ]; then
34 . "$moddir"/plymouth-populate-initrd.sh
35 else
36 PLYMOUTH_POPULATE_SOURCE_FUNCTIONS="$dracutfunctions" \
37 ${PKGLIBDIR}/plymouth-populate-initrd -t "$initdir"
38 fi
39
40 inst_hook emergency 50 "$moddir"/plymouth-emergency.sh
41
42 inst_multiple readlink
43
44 if ! dracut_module_included "systemd"; then
45 inst_hook pre-trigger 10 "$moddir"/plymouth-pretrigger.sh
46 inst_hook pre-pivot 90 "$moddir"/plymouth-newroot.sh
47 fi
48 }
Простой проход grep по require_binaries
покажет все те исполняемые
файлы, которые dracut добавит в initramfs общего назначения.
# grep -ir "require_binaries" /usr/lib/dracut/modules.d/
/usr/lib/dracut/modules.d/90mdraid/module-setup.sh: require_binaries mdadm expr || return 1
/usr/lib/dracut/modules.d/80lvmmerge/module-setup.sh: require_binaries lvm dd swapoff || return 1
/usr/lib/dracut/modules.d/95cifs/module-setup.sh: require_binaries mount.cifs || return 1
/usr/lib/dracut/modules.d/91crypt-gpg/module-setup.sh: require_binaries gpg || return 1
/usr/lib/dracut/modules.d/91crypt-gpg/module-setup.sh: require_binaries gpg-agent &&
/usr/lib/dracut/modules.d/91crypt-gpg/module-setup.sh: require_binaries gpg-connect-agent &&
/usr/lib/dracut/modules.d/91crypt-gpg/module-setup.sh: require_binaries /usr/libexec/scdaemon &&
/usr/lib/dracut/modules.d/45url-lib/module-setup.sh: require_binaries curl || return 1
/usr/lib/dracut/modules.d/90stratis/module-setup.sh: require_binaries stratisd-init thin_check thin_repair mkfs.xfs xfs_admin xfs_growfs || return 1
/usr/lib/dracut/modules.d/90multipath/module-setup.sh: require_binaries multipath || return 1
/usr/lib/dracut/modules.d/95iscsi/module-setup.sh: require_binaries iscsi-iname iscsiadm iscsid || return 1
/usr/lib/dracut/modules.d/95ssh-client/module-setup.sh: require_binaries ssh scp || return 1
/usr/lib/dracut/modules.d/35network-manager/module-setup.sh: require_binaries sed grep || return 1
/usr/lib/dracut/modules.d/90dmsquash-live-ntfs/module-setup.sh: require_binaries ntfs-3g || return 1
/usr/lib/dracut/modules.d/91crypt-loop/module-setup.sh: require_binaries losetup || return 1
/usr/lib/dracut/modules.d/05busybox/module-setup.sh: require_binaries busybox || return 1
/usr/lib/dracut/modules.d/99img-lib/module-setup.sh: require_binaries tar gzip dd bash || return 1
/usr/lib/dracut/modules.d/90dm/module-setup.sh: require_binaries dmsetup || return 1
/usr/lib/dracut/modules.d/03modsign/module-setup.sh: require_binaries keyctl || return 1
/usr/lib/dracut/modules.d/97biosdevname/module-setup.sh: require_binaries biosdevname || return 1
/usr/lib/dracut/modules.d/95nfs/module-setup.sh: require_binaries rpc.statd mount.nfs mount.nfs4 umount || return 1
/usr/lib/dracut/modules.d/90dmraid/module-setup.sh: require_binaries dmraid || return 1
/usr/lib/dracut/modules.d/95fcoe/module-setup.sh: require_binaries dcbtool fipvlan lldpad ip readlink fcoemon fcoeadm || return 1
/usr/lib/dracut/modules.d/00warpclock/module-setup.sh: require_binaries /sbin/hwclock || return 1
/usr/lib/dracut/modules.d/35network-legacy/module-setup.sh: require_binaries ip dhclient sed awk grep || return 1
/usr/lib/dracut/modules.d/00bash/module-setup.sh: require_binaries /bin/bash
/usr/lib/dracut/modules.d/95nbd/module-setup.sh: require_binaries nbd-client || return 1
/usr/lib/dracut/modules.d/90btrfs/module-setup.sh: require_binaries btrfs || return 1
/usr/lib/dracut/modules.d/00systemd/module-setup.sh: if require_binaries $systemdutildir/systemd; then
/usr/lib/dracut/modules.d/10i18n/module-setup.sh: require_binaries setfont loadkeys kbd_mode || return 1
/usr/lib/dracut/modules.d/90lvm/module-setup.sh: require_binaries lvm || return 1
/usr/lib/dracut/modules.d/50plymouth/module-setup.sh: require_binaries plymouthd plymouth plymouth-set-default-theme
/usr/lib/dracut/modules.d/95fcoe-uefi/module-setup.sh: require_binaries dcbtool fipvlan lldpad ip readlink || return 1
И снова, dracut не включает все модули из /usr/lib/dracut/modules.d
.
Он включает только специфичные для хоста модули. В своём следующем разделе мы изучим как добавлять или опускать
определённые модули в initramfs.
Dracut также обладает своими собственными модулями. Модули ядра и модули dracut различны. Dracut собирает необходимые
исполняемые файлы, специфичные для хоста, соответствующие ассоциированные библиотеки, требующиеся файлы настройки
и необходимые модули аппаратных устройств и группирует их под названием модулей
dracut. Модули основного ядра составляются из соответствующих файлов .ko
аппаратных устройств. Вы можете обнаружить список модулей dracut либо в
/usr/lib/dracut/modules.d/
, или посредством команды
dracut --list-modules
.
# dracut --list-modules | xargs -n6
bash systemd warpclock fips systemd-initrd systemd-networkd
modsign rescue watchdog busybox nss-softokn rdma
i18n convertfs network-legacy network-manager network ifcfg
url-lib drm plymouth lvmmerge bcache btrfs
crypt dm dmraid dmsquash-live dmsquash-live-ntfs kernel-modules
kernel-modules-extra kernel-network-modules livenet lvm mdraid multipath
qemu qemu-net stratis crypt-gpg crypt-loop cifs
debug fcoe fcoe-uefi fstab-sys iscsi lunmask
nbd nfs resume rootfs-block ssh-client terminfo
udev-rules virtfs biosdevname dracut-systemd ecryptfs ostree
pollcdrom selinux syslog usrmount base earlykdump
fs-lib img-lib kdumpbase shutdown squash uefi-lib
Если вы пожелаете добавить или опустить определённые модули dracut (не модуль соответствующего аппаратного
устройства) из initramfs, тогда в этом жизненно важную роль играет dracut.conf
.
Заметьте, что dracut.conf
это файл настроек dracut, а не initramfs; таким образом,
он не будет доступен внутри initramfs.
# lsinitrd | grep -i 'dracut.conf'
<no output>
Dracut при генерации initramfs применяет в качестве справочного свой файл dracut.conf
.
По умолчанию это будет пустой файл.
# cat /etc/dracut.conf
# PUT YOUR CONFIG IN separate files
# in /etc/dracut.conf.d named "<name>.conf"
# SEE man dracut.conf(5) for options
Существуют различные предоставляемые dracut.conf
варианты, которыми
вы можете пользоваться для добавления или пропуска соответствующих модулей.
Предположим, вы желаете опустить ов initramfs относящиеся к plymouth
файлы (исполняемые, конфигурационные файлы, модули и т.п.); тогда вы либо добавляете в
dracut.conf
некий omit_dracutmodules+=plymouth
,
либо применяете переключатель omit
(o
)
своего исполняемого файла dracut. Вот некий образец:
# lsinitrd | grep -i plymouth | wc -l
118
Имеется почти 118 относящихся к plymouth
файлов, которые представлены
в запускаемом в настоящий момент ядре. Давайте сейчас попробуем опустить относящиеся к
plymouth
файлы.
# dracut -o plymouth /root/new.img
# lsinitrd /root/new.img | grep -i plymouth | wc -l
4
Как вы можете заметить, все относящиеся к plymouth
файлы были исключены из
нашего вновь построенного initramfs. Тем самым, все связанные с plymouth
исполняемые и конфигурационные файлы, библиотеки, а также модули аппаратных устройств (в случае их доступности)
не будут захватываться dracut в initramfs. В точности тот же результат можно достичь добавляя в
dracut.conf
параметр
omit_dracutmodules+=plymouth
.
# cat /etc/dracut.conf | grep -v '#'
omit_dracutmodules+=plymouth
# dracut /root/new.img --force
# lsinitrd /root/new.img | grep -i plymouth
-rw-r--r-- 1 root root 454 Jul 25 2019 usr/lib/systemd/system/systemd-ask-password-plymouth.path
-rw-r--r-- 1 root root 435 Jul 25 2019 usr/lib/systemd/system/systemd-ask-password-plymouth.service
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib/systemd/system/systemd-ask-password-plymouth.service.wants
lrwxrwxrwx 1 root root 33 Jul 25 2019 usr/lib/systemd/system/systemd-ask-password-plymouth.service.wants/systemd-vconsole-setup.service -> ../systemd-vconsole-setup.service
Ниже приводится выдержка из страницы man.
Пропуск Модулей dracut
Порой вы не желаете включать некий модуль dracut по причинам
скорости, размера или функциональности. Для этого вы либо определяете в файле настроек
dracut.conf
или /etc/dracut.conf.d/myconf.conf
,
либо применяете параметр -o
или --omit
в командной строке: # dracut -o "multipath lvm" no-multipath-lvm.img
В точности так же как мы пропускали соответствующий модуль dracut, мы можем добавлять лишь те модули, которые
доступны в /usr/lib/dracut/modules.d
. В dracut.conf
мы можем воспользоваться переключателем dracut --add
или
add_dracutmodules+=
. К примеру, вы можете заметить, что у нас нет NFS
модулей/ файлов/ исполняемого кода в нашем initramfs new.img
, поскольку наша
тестовая система не загружается из NFS и не применяет для себя никаких точек монтирования NFS. Очевидно, что dracut
пропустит модуль nfs
из /usr/lib/dracut/modules.d
.
А потому давайте добавим его в свою initramfs.
#lsinitrd | grep -i nfs
<no_output>
# cat /etc/dracut.conf
# PUT YOUR CONFIG IN separate files
# in /etc/dracut.conf.d named ".conf"
# SEE man dracut.conf(5) for options
#omit_dracutmodules+=plymouth
add_dracutmodules+=nfs
# dracut /root/new.img --force
# lsinitrd /root/new.img | grep -i nfs | wc -l
Мы также можем достичь в точности того же результата воспользовавшись командой dracut с переключателем
--add
.
# lsinitrd /root/new.img | grep -i nfs
# dracut --add nfs /root/new.img --force
# lsinitrd /root/new.img | grep -i nfs
Arguments: --add 'nfs' --force
nfs
-rw-r--r-- 1 root root 15 Jul 25 2019 etc/modprobe.d/nfs.conf
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib64/libnfsidmap
-rwxr-xr-x 1 root root 50416 Jul 25 2019 usr/lib64/libnfsidmap/nsswitch.so
-rwxr-xr-x 1 root root 54584 Jul 25 2019 usr/lib64/libnfsidmap.so.1.0.0
lrwxrwxrwx 1 root root 20 Jul 25 2019 usr/lib64/libnfsidmap.so.1 -> libnfsidmap.so.1.0.0
-rwxr-xr-x 1 root root 42744 Jul 25 2019 usr/lib64/libnfsidmap/sss.so
-rwxr-xr-x 1 root root 46088 Jul 25 2019 usr/lib64/libnfsidmap/static.so
-rwxr-xr-x 1 root root 62600 Jul 25 2019 usr/lib64/libnfsidmap/umich_ldap.so
-rwxr-xr-x 1 root root 849 Oct 8 2018 usr/lib/dracut/hooks/cleanup/99-nfsroot-cleanup.sh
-rwxr-xr-x 1 root root 3337 Oct 8 2018 usr/lib/dracut/hooks/cmdline/90-parse-nfsroot.sh
-rwxr-xr-x 1 root root 874 Oct 8 2018 usr/lib/dracut/hooks/pre-udev/99-nfs-start-rpc.sh
drwxr-xr-x 5 root root 0 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/blocklayout
-rw-r--r-- 1 root root 16488 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/blocklayout/blocklayoutdriver.ko.xz
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs_common
-rw-r--r-- 1 root root 2584 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs_common/grace.ko.xz
-rw-r--r-- 1 root root 3160 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs_common/nfs_acl.ko.xz
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/filelayout
-rw-r--r-- 1 root root 11220 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/filelayout/nfs_layout_nfsv41_files.ko.xz
drwxr-xr-x 2 root root 0 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/flexfilelayout
-rw-r--r-- 1 root root 20872 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/flexfilelayout/nfs_layout_flexfiles.ko.xz
-rw-r--r-- 1 root root 109684 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/nfs.ko.xz
-rw-r--r-- 1 root root 18028 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/nfsv3.ko.xz
-rw-r--r-- 1 root root 182756 Jul 25 2019 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/fs/nfs/nfsv4.ko.xz
-rwxr-xr-x 1 root root 4648 Oct 8 2018 usr/lib/nfs-lib.sh
-rwsr-xr-x 1 root root 187680 Jul 25 2019 usr/sbin/mount.nfs
lrwxrwxrwx 1 root root 9 Jul 25 2019 usr/sbin/mount.nfs4 -> mount.nfs
-rwxr-xr-x 1 root root 719 Oct 8 2018 usr/sbin/nfsroot
drwxr-xr-x 4 root root 0 Jul 25 2019 var/lib/nfs
drwxr-xr-x 2 root root 0 Jul 25 2019 var/lib/nfs/rpc_pipefs
drwxr-xr-x 3 root root 0 Jul 25 2019 var/lib/nfs/statd
drwxr-xr-x 2 root root 0 Jul 25 2019 var/lib/nfs/statd/sm
В точности также, как мы добавляли в свой initramfs дополнительный модуль nfs
,
мы способны добавлять в свой initramfs лишь модуль nfs
при помощи добавления в
dracut.conf
оператора dracutmodules+=
.
Это означает, что получаемый в результате initramfs будет обладать в своём составе только
nfs
. Все прочие модули из /usr/lib/dracut/modules.d/
будут отвергнуты.
# cat /etc/dracut.conf
#omit_dracutmodules+=plymouth
#add_dracutmodules+=nfs
dracutmodules+=nfs
# dracut /root/new.img —force
# lsinitrd /root/new.img
Image: /root/new.img: 20M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x 3 root root 0 Jul 25 2019 .
-rw-r—r-- 1 root root 2 Jul 25 2019 early_cpio
drwxr-xr-x 3 root root 0 Jul 25 2019 kernel
drwxr-xr-x 3 root root 0 Jul 25 2019 kernel/x86
drwxr-xr-x 2 root root 0 Jul 25 2019 kernel/x86/microcode
-rw-r—r-- 1 root root 100352 Jul 25 2019 kernel/x86/microcode/GenuineIntel.bin
========================================================================
Version:
Arguments: --force
dracut modules:
nss-softokn
network-manager
network
kernel-network-modules
nfs
=======================================================================
Как вы можете видеть, был добавлен лишь модуль nfs
вместе со своими
зависимостями, такими как модуль dracut network
. К тому же, обратите
внимание на разницу в значении размера между обеими версиями initramfs.
# ls -lh initramfs-5.3.16-300.fc31.x86_64.img
-rw-------. 1 root root 28M Dec 23 06:37 initramfs-5.3.16-300.fc31.x86_64.img
# ls -lh /root/new.img
-rw-------. 1 root root 20M Dec 24 11:05 /root/new.img
Того же самого можно достичь, воспользовавшись переключателем dracut -m
или --modules
.
# dracut -m nfs /root/new.img --force
Когда вы желаете добавить лишь определённый модуль аппаратного устройства, обратите, пожалуйста, внимание на то,
что модуль аппаратного устройства подразумевает соответствующий файл
*.ko
, предоставляемый надлежащим пакетом
kernel-modules
в
/lib/modules/<kernel-version>/drivers/<module-name>
.
Тогда соответствующие переключатели dracut --add
или
add_dracutmodules+=
не помогут, ибо эти переключатели доьавляют соответствующие
модули dracut, а не файл модуля самого ядра (.ko
).
Итак, чтобы добавить необходимый модуль ядра нам потребуется воспользоваться переулючателем dracut
--add-drivers
или же
drivers+=
, либо add_drivers+=
в
dracut.conf
. Вот некий пример:
# lsinitrd /root/new.img | grep -i ath3k
Этот относящийся к Bluetooth модуль с названием ath3k
не представлен в
нашем initramfs, но он является одним из тех модулей, который предоставляется самим ядром.
#ls -lh /lib/modules/5.3.16-300.fc31.x86_64/kernel/drivers/bluetooth/ath3k.ko.xz
Давайте добавим его как показано здесь:
# dracut --add-drivers ath3k /root/new.img --force
Теперь он был добавлен, как это отображено далее:
# lsinitrd /root/new.img | grep -i ath3k
Arguments: --add-drivers 'ath3k' --force
-rw-r--r-- 1 root root 246804 Jul 25 03:54 usr/lib/firmware/ath3k-1.fw
-rw-r--r-- 1 root root 5652 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/bluetooth/ath3k.ko.xz
Как вы можете заметить, в initramfs был добавлен модуль ath3k.ko
.
Давайте изучим когда добавлять модуль dracut, а когда добавлять модуль ядра. Вот некая ситуация: корневая файловая
система вашего хоста находится на обычном устройстве SCSI. Итак, очевидно, ваш initramfs не обладает внутри себя
никаким модулем ядра multipath.ko
или подобным
multipath.conf
файлом настройки.
-
Внезапно вы принимаете решение перенести свою корневую файловую систему с обычного локального диска в SAN (я бы никогда не посоветовал такого изменения в промышлоенной системе), а эта SAN подключается через устройство со множеством путей.
-
Для получения полной среды этого устройства со множеством путей вам потребуется добавить здесь соответствующий модуль dracut множественного пути с тем, чтобы вся имеющаяся среда множества путей целиком была размещена в initramfs.
-
Через несколько дней вы добавляете какую- то новую сетевую карту в ту же самую систему и производитель этой NIC снабжает её драйверами. Некий драйвер это ничто иное как какой- то файл
.ko
(kernel object). Для добавления этого модуля в вашу initramfs вам придётся выбрать надлежащий вариантkernel module
. Именно он добавит необходимый драйвер лишь для самой сетевой карты, а не всю среду целиком.
Но что если вы желаете добавить в initramfs некий конкретный файл, который не является ни модулем ядра, ни
модулем dracut? Dracut предоставляет соответствующие переменные install_items+=
и --include
для dracut.conf
, посредством
которых мы обладаем возможностью добавления определённых файлов. Такие файлы могут быть чем угодно начиная с
обычного текста, вплоть до исполняемого файла и т.п..
#lsinitrd /root/new.img | grep -i date
<no_output>
Этот исполняемый файл date
по умолчанию не представлен в initramfs. Однако
для добавления какого- то исполняемого файла мы можем воспользоваться переключателем
install_itsems+
.
# cat /etc/dracut.conf
# PUT YOUR CONFIG IN separate files
# in /etc/dracut.conf.d named "<name>.conf"
# SEE man dracut.conf(5) for options
#omit_dracutmodules+=plymouth
#add_dracutmodules+=nfs
#dracutmodules+=nfs
install_items+=date
# dracut /root/new.img --force
# lsinitrd /root/new.img | grep -i date
-rwxr-xr-x 1 root root 122456 Jul 25 02:36 usr/bin/date
Как вы можете видеть, был добавлен исполняемый файл date
, но ещё более
важный момент состоит в том, что он добавил не только этот исполняемый файл; он также добавил и библиотеку, которая
требуется для исполнения этой команды date
. Того же самого можно достичь при
помощи переключателя --install
в самой команде
dracut
. Однако тут имеется некое ограничение; нет возможности добавления
исполняемых файлов, индивидуально изготовляемых самим пользователем. Для этого нам требуется воспользоваться
переключателем dracut --include
. При помощи
--include
вы способны добавлять в initramfs обычные файлы, каталоги или
даже некий исполняемый файл. В последнем случае добавления определённого исполняемого файла, когда вашему
исполняемому файлу требуется некая библиотека сопровождения, тогда вам придётся определить название этой
библиотеки с её абсолютным значением пути.
Проблема: Некая промышленная система Linux перезапускалась после четырёх месяцев на обычное сопровождение и прекратила запускаться. Это сопровождается следующим сообщением об ошибке на экране:
<snip>
.
dracut-initqueue[444]: warning: dracut-initqueue timeout - starting timeout scripts
dracut-initqueue[444]: warning: dracut-initqueue timeout - starting timeout scripts
dracut-initqueue[444]: warning: dracut-initqueue timeout - starting timeout scripts
dracut-initqueue[444]: warning: dracut-initqueue timeout - starting timeout scripts
.
</snip>
Решение: Вот шаги по решению данной проблемы:
-
Данное сообщение об ошибке начинается с оповещения о том, что нет возможности достичь соответствующее устройство подкачки, а далее этот процесс завершается по тайм- ауту.
[TIME] Timed out waiting for device /dev/mapper/fedora_localhost--live-swap
Именно это является критически важной частью сведений, так как сообщает нам что нечто пошло не так в этих системных файловых системах.
-
Соответствующее устройство подкачки базируется на HDD и в нём была создана необходимая файловая система подкачки. Теперь это устройство подкачки утрачено само по себе. Поэтому, либо лежащий в его основе диск сам по себе не доступен, либо разрушена его файловая система подкачки. Осознавая это, мы теперь можем сосредоточиться лишь на вопросе самого хранилища. Важна изоляция данной проблемы самой по себе, ибо проблема "can’t boot" имеет тысячи ситуаций, которые способны вызывать прекращение запуска конкретной системы.
-
Мы выполним загрузку либо при помощи аварийного режима, либо воспользовавшись образом live того же самого дистрибутива с той же версией. Это система система Fedora 31 и, как это отражено на Рисунке 6-1, я воспользуюсь аварийным вариантом из GRUB.
-
После того как мы выполнили запуск в аварийном режиме, мы смонтируем необходимую корневую файловую систему пользователя и выполним
chroot
в неё. Теперь, почему аварийный режим имеет возможность запуска, в то время как обычное ядро не способно запускать ту же самую систему? Это допустимый вопрос и ответ на него рассматривается в Главе 10. -
Так как мы имеем возможность монтирования своей корневой файловой системы с аварийным ядром, но не способны монтировать соответствующую корневую файловую систему с обычным ядром, это означает что нечто не так в его образе initramfs. Может быть пропущен какой- то модуль, который необходим для обраьотки его HDD. Давайте проверим данную теорию.
-
Это система с виртуализацией, что подразумевает, что она обладает неким виртуальным диском. Это можно обнаружить в каталоге
/dev
.#ls /dev/vd* vda vda1 vda2
-
Для обработки таких виртуальных дисков нам требуется обладать представленным в initramfs модулем
virtio_blk
.#lsinitrd /boot/new.img | grep -i virt Arguments: --omit-drivers virtio_blk -rw-r--r-- 1 root root 14132 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/char/virtio_console.ko.xz -rw-r--r-- 1 root root 25028 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/net/virtio_net.ko.xz -rw-r--r-- 1 root root 7780 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/virtio_scsi.ko.xz -rw-r--r-- 1 root root 499 Feb 26 2018 usr/lib/sysctl.d/60-libvirtd.conf
Как вы можете видеть, необходимый нам модуль
virtio_blk
пропущен. -
Поскольку
virtio_blk
отсутствует, очевидно, что наше ядро не способно выявить дискvda
и получить к нему доступ, а именно там наш пользователь имеет свои корневую файловую систему и файловую систему подкачки. -
Для исправления данной проблемы нам требуется добавить в initramfs отсутствующий модуль
virtio_blk
.#dracut --add-drivers=virtio_blk /boot/new.img --force # lsinitrd | grep -i virtio_blk -rw-r--r-- 1 root root 8356 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/block/virtio_blk.ko.xz
-
Мы выполним запуск воспользовавшись своей initramfs
new.img
. Как запускать свою систему вручную из приглашения командной строки GRUB уже обсуждалось в Проблеме 1 "Can’t Boot" (начальный загрузчик). -
После добавления пропущенного модуля
virtio_blk
наша проблема "Can’t Boot" была исправлена. На Рисунке 6-2 вы можете наблюдать успешно запускающуюся систему.
Проблема: Рисунок 6-3 показывает что видно на экране.
Решение: Вот шаги по решению данной проблемы:
-
Теперь в этом просто разобраться и решить.
-
Данное сообщение об ошибке достаточно хорошо само описывает себя; отсутствует файл initramfs сам по себе.
-
Либо отсутствует файл initramfs сам по себе, либо просто файл
/boot/loader/entries/*
содержит в себе ошибочную запись. В данном случае отсутствует сам файл initramfs. -
Поэтому нам необходимо загрузиться в аварийном режиме и смонтировать необходимую корневую файловую систему пользователя.
-
Либо повторно установите надлежащий пакет
rpm
ядра, с тем чтобы его частьpostscripts
повторно выработала отсутствующий initramfs, либо также обновите как следует имеющиеся записи BLS. -
Либо вы можете повторно сгенерировать initramfs при помощи изученной нами команды
dracut
.
Как вы уже видели, GRUB принимает параметры командной строки ядра и передаёт их в само ядро. Конкретное ядро обладает сотнями параметров командной строки и практически невозможно кому бы то ни было охватить абсолютно все параметры. Поэтому давайте сосредоточимся только на тех параметрах, которые требуются для запуска самой операционной системы. Если вам интересны все имеющиеся параметры командной строки ядра, посетите следующую страницу.
Перечень параметров этой страницы относится к ядрам 4 последовательности, но большая часть пояснений параметров
применима и к ядрам 5 последовательности. Наилучший вариант состоит в том чтобы всегда отыскивать документацию в
/usr/share/doc/
.
-
Это один из самых важных параметров командной строки ядра. Окончательной целью запуска является монтирование корневой файловой системы пользователя. Параметр командной строки ядра
root
предоставляет значение имени корневой файловой системы конкретного пользователя, которое намерено монтировать данное ядро. -
От имени своего ядра, запускаемый из initramfs systemd смонтирует заданную корневую файловую систему пользователя.
-
Когда данная корневая файловая система пользователя не доступна или само ядро не способно смонтировать её, тогда это будет рассматриваться как паническая ситуация для данного ядра.
-
Имеющееся ядро запускает из initramfs systemd и он становится самым первым процессом. Он также имеет название
PID-1
и выступает в качестве прародителя всех процессов. -
Однако если вы разработчик и вы желаете запускать свой собственный исполняемый файл вместо systemd, вы можете воспользоваться параметром командной строки ядра
init
. Приведём некий пример:init=/sbin/yogesh
Как вы можете видеть на Рисунке 6-4 , это запустит исполняемы файл
yogesh
вместо systemd.
Однако
yogesh
не доступен в реальной корневой файловой системе; следовательно, как это отображено на Рисунке 6-5, это приводит к отказу в запуске.
-
Наша система выбросила нас в свою аварийную оболочку. За подробностями относительно отладочных оболочек обращайтесь к Главе 8.
-
Основная причина выбрасывания нас в аварийную оболочку и сама причина данной проблемы "can’t boot" упоминается в
/run/initramfs/rdsosreport.txt
. Рисунок 6-6 отображает фрагмент кода этого файлаrdsosreport.txt
.
-
Самый интересный факт, который стоит отметить здесь состоит в том, что наш исполняемый файл
/sbin/yogesh
будет вызываться в тот момент, когда выполняетсяchroot
реальной корневой файловой системы. Мы пока ещё не рассматривалиchroot
; вы можете обнаружить подробное описание в Главе 10.
-
Это сопроводительный параметр для параметра командной строки
root
.ro
это сокращение для файловой системы с "read-only". Такая корневая файловая система пользователя будет смонтирована внутри initramfs в режиме доступа только для чтения когда передан данный параметр командной строки ядраro
. Значениеro
является устанавливаемым по умолчанию для всех основных дистрибутивов Linux.
-
Почти все дистрибутивы Linux показывают свою анимацию в момент запуска чтобы сделать этот процесс запуска более привлекательным, однако данная анимация скрывает все важные сообщения консоли, которые необходимы для анализа этой последовательности запуска. Чтобы прекратить такую анимацию и просмотреть на экране расширенные сообщения консоли удалите установленные параметры
rhgb
иquite
. -
Когда передаются параметры
rhgb
иquite
, как это отображено на Рисунке 6-7, будет показана анимацияplymouth
.
-
Когда
rhgb
иquite
удалены, как вы можете видеть на Рисунке 6-8, пользователю будут выставляться все сообщения консоли.
-
Находясь в экране анимации (
plymouth
) вы также можете нажать Escape и будете иметь возможность наблюдать сообщения консоли, но для этого вы обязаны физически присутствовать перед своей промышленной системой, что маловероятно.
-
Порой, чтобы решить проблему "can’t boot”", вам требуется полностью избавиться от SELinux. В таком случае вы можете передать параметр командной строки ядра
selinux=0
. Это совсем отменит SELinux.
Это несколько параметров командной строки ядра, которые напрямую воздействуют на последовательность запуска. Наряду с такими параметрами командной строки ядра, GRUB способен также принимать и параметры командной строки dracut, которые будут приниматься initramfs, или точнее, systemd initramfs.
С точки зрения неспециалиста вы можете рассматривать начинающиеся с rd.
параметры командной строки в качестве параметров командной строки dracut, который будет распознаваться
initramfs.
-
Согласно странице руководства это позволяет автоматически собирать особые устройства, такие как cryptoLUKS, dmraid, mdraid или lvm. Значением по умолчанию выступает отключение.
-
Рассмотрим сценарий, подобный приведённому ранее, когда в вашей системе не был настроен
mdraid
(программный raid), но теперь вы его недавно реализовали и хотите чтобы это устройство активировалось в момент запуска. Иначе говоря, состояние данного хранилища этой машины изменяется в сам момент создания своего initramfs. Теперь, причём без повторного создания такого нового initramfs, вы желаете активации в момент запуска такой новой конфигурации (LVM или LUKS).
-
Согласно странице руководства удаляет всё скомпилированное в данной конфигурации той системы, в которой был выстроен этот образ initramfs. Это способствует запуску когда изменяется схема любого диска, в особенности с
rd.auto
или иными параметрами, определяемыми этой схемой. -
Допустим, производитель вашей графической карты (например, nVidia), предоставил вам специальные драйверы/ модули, которые представлены в вашей initramfs, но эти модули начали создавать некую проблему. Поскольку данный драйвер будет запускаться на некой ранней стадии запуска, вы желаете избежать применения этого модуля; вместо этого вы хотите воспользоваться неким общим драйвером (
vesa
). При подобной ситуации вы можете воспользоватьсяrd.hostonly=0
. При помощи этого параметра initramfs загрузит свой общий драйвер и избежит применения специфичного для хоста драйвера nVidia.
-
В соответствии со страницей руководства если вы не желаете соблюдать особые параметры монтирования для обнаруженной в реальном каталоге
/etc/fstab
корневой файловой системы, пользуйтесь этим параметром.
-
В соответствии со страницей руководства, это пропускает
fsck
дляrootfs
и/usr
. Если вы монтируете/usr
на доступ только для чтения и инструкцияinit
системы выполняетfsck
пере повторным монтированием, вы можете применять этот параметр во избежание дублирования. -
Большинство администраторов Linux обладают неверным представлением относительно
fsck
и того как она сочетается с параметром командной строки ядраro
. Большинство из нас предполагает что имеющееся ядро сначала монтирует реальную корневую файловую систему в режимеro
и затем выполняет в нейfsck
с тем, чтобыfsck
не разрушал данные этой корневой файловой системы. После того какfsck
завершается успешно, будет произведено перемонтирование этой файловой системы в режиме чтения- записи через обращение к/etc/fstab
. -
Однако такое представление обладает основным недостатком, который заключается в том, что
fsck
не может выполняться в смонтированной файловой системе безотносительно к режимуro
илиrw
.
Следующая корневая файловая система системы Fedora расположена на устройстве sda5
и в настоящий момент монтируется в режиме только чтения, поэтому fsck
завершится неудачно, ибо эта файловая система смонтирована:
# fsck.ext4 /dev/sda5
e2fsck 1.45.3 (14-Jul-2019)
/dev/sda5 is mounted.
e2fsck: Cannot continue, aborting.
Таким образом это доказывает, что основная цель монтирования этой корневой файловой системы пользователя в
режиме ro
состоит не в том чтобы выполнять
fsck
. Тогда зачем передавать своему ядру параметр командной строки
ro
в своё ядро? Давайте обсудим это в последовательности запуска.
-
Установленной ядро распаковывает initramfs и передаёт такие параметры как
root
иro
в systemd, который запускается из initramfs. -
systemd отыщет реальную корневую файловую систему.
-
После того, как необходимая корневая файловая система (диск) выявлена, systemd выполнит в ней
fsck
. -
Если
fsck
успешен, тогда systemd смонтирует эту корневую файловую систему какro
(в соответствии с таким переданным параметром командной строки ядра) внутри самой initramfs. Она будет смонтирована как доступная только для чтения в каталоге/sysroot/code>
initramfs. - Как вы можете увидеть на
Рисунке 6-9,
наше ядро распаковало initramfs и запустило из неё systemd (я удалил параметры
rhgb
иquite
).
Systemd затем сканирует все подключённые устройства хранения на предмет корневой файловой системы и её
обнаружения. Перед монтирование такой корневой файловой системы пользователя, вначале в ней выполнится
fsck
и далее она монтируется внутри initramfs в каталоге
sysroot
. Эта корневая файловая система будет смонтирована в режиме доступа
только на чтение.
-
Основную причину для монтирования её в режиме исключительного чтения понять просто. Допустим, эта система отказывает в запуске, однако она управляется для монтирования своей корневой файловой системы пользователя в
sysroot
и снабжает нас некой оболочкой для исправления данной проблемы "can’t boot". Пользователи могут случайно разрушить или даже удалить эту корневую файловую систему пользователя которая смонтирована вsysroot
. Поэтому для предотвращения подобных происшествий с корневой файловой системой пользователя, предпочтительно монтируется в режиме для исключительного чтения.#switch_root:/# ls -ld /sysroot/ dr-xr-xr-x 19 root 0 4096 Sep 10 2017 /sysroot/
-
То как применять соответствующие отладочные оболочки и как initramfs предоставляет их будет обсуждаться в Главе 8.
-
Рисунок 6-10 показывает systemd продолжает свою последовательность запуска и покидает среду своего initramfs.
-
Как вы можете видеть на Рисунке 6-10, переключаемый корень покидает свою текущую среду initramfs и изменяет свой корень с временной корневой файловой системы initramfs на
/sysroot
, которая имеет смонтированной корневую файловую систему пользователя. (Такой процесс переключения корня будет обсуждаться в Главе 9.) -
Сразу после входа в смонтрованную корневую файловую систему пользователя, systemd этой корневой файловой системы пользователя считывает
/etc/fstab
и предпринимает надлежащие действия в точках монтирования. Например, в данной системе Fedora имеется соответствующая запись корневой файловой системы пользователя помимо записи/boot
(boot в отдельном разделе):#cat /etc/fstab /dev/mapper/fedora_localhost--live-root / ext4 defaults 1 1 UUID=eea3d947-0618-4d8c-b083-87daf15b2679 /boot ext4 defaults 1 2 /dev/mapper/fedora_localhost--live-swap none swap defaults 0 0
-
Как вы можете видеть на Рисунке 6-11, на данном этапе systemd выполнит
fsck
лишь в своём загрузочном устройстве перед её монтированием. Обратите, пожалуйста внимание чтоfsck
не выполняется в соответствующей корневой файловой системе пользователя, так как она уже была осуществлена внутри среды initramfs. Кроме того, корневая файловая система пользователя в настоящий момент смонтирована и мы все знаем что она не придаёт внимания выполнениюfsck
на своём устройстве подкачки.
-
Если бы присутствовали какие- либо иные точки монтирования, такие как
/usr
, пришлось бы выполнятьfsck
и в этом устройстве. -
fsck
зависит от пятого параметра/etc/fstab
. Если он равен 1, тогдаfsck
будет выполняться в момент запуска. Эта настройкаfstab
не применима к корневой файловой системе пользователя, так какfsck
будет принудительно выполняться в корневой файловой системе пользователя внутри initramfs, что происходит перед считыванием этого файла/etc/fstab
. -
rd.skipfsck
применим только к корню и устанавливаемой корневой файловой системой пользователя. Он не применяется ко всем прочим файловым системам, таким как/boot
.
Вот страница руководства по rd.driver.blacklist
:
- rd.driver.blacklist=<drivername>[,<drivername>,...]
не загружать модуль ядра <drivername>. Данный параметр может задаваться множество раз.
rd.driver.blacklist
является одним из наиболее важных параметров командной
строки dracut. Как и предполагает название этого параметра, это будет чёрный список всех определяемых модулей.
Давайте попробуем занести в чёрный список относящиеся к virtio
драйверы, которые достаточно важны для виртуальных гостевых систем.
# lsmod | grep -i virt
virtio_balloon 24576 0
virtio_net 57344 0
virtio_console 40960 2
virtio_blk 20480 3
net_failover 20480 1 virtio_net
Они также доступны и в initramfs.
# lsinitrd | grep -i virtio
-rw-r--r-- 1 root root 8356 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/block/virtio_blk.ko.xz
-rw-r--r-- 1 root root 14132 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/char/virtio_console.ko.xz
-rw-r--r-- 1 root root 25028 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/net/virtio_net.ko.xz
-rw-r--r-- 1 root root 7780 Jul 25 03:54 usr/lib/modules/5.3.7-301.fc31.x86_64/kernel/drivers/scsi/virtio_scsi.ko.xz
Помните, что для занесения в чёрный список соответствующего модуля, как вы это можете видеть на
Рисунке 6-12,
вам требуется убедиться, что все прочие зависимости модуля также занесены в чёрный список; в противном случае
такие модули зависимости вытащили бы и сам занесённый в чёрный список модуль. Например, в данном случае модули
virtio_balloon
, virtio_net
,
virtio_console
, virtio_blk
и
virtio_pci
зависят друг от друга. Это означает, что если мы занесём в
чёрный список только virtio_blk
, прочие имеющиеся модули зависимостей всё же
загрузят и этот модуль virtio_blk
.
Все относящиеся к virtio
драйверы важны. Именно они выступают теми
драйверами, которые выставляются гипервизором в свою гостевую операционную систему виртуальные диски и сетевые
среды. Поскольку мы занесли их в чёрный список, наша гостевая ОС прекратит запускаться. Вы сможете видеть на
Рисунке 6-13
сообщение консоли "can't boot".
Итак, занесение в чёрный список модулей virtio
выполнено успешно, но
при данном подходе имеются две проблемы.
-
rd.driver.blacklist
будет лишь блокировать эти модули для загрузки в initramfs. -
Нам требуется всякий раз вручную предоставлять данный список модулей для
rd.driver.blacklist
.
Когда определённый модуль не находится в initramfs, тогда вы не можете в реальности блокировать его загрузку.
Например, модуль bluetooth
не загружается из initramfs, однако имеющееся
ядро загружает их после выхода из среды initramfs.
# lsmod | grep -i bluetooth
bluetooth 626688 37 btrtl,btintel,btbcm,bnep,btusb,rfcomm
ecdh_generic 16384 1 bluetooth
rfkill 28672 5 bluetooth
# lsinitrd | grep -i bluetooth
<no_output>
Для блокирования загрузки ядром модуля bluetooth
нам потребуется сообщить
команде modprobe
необходимость блокирования загрузки этого модуля.
modprobe
это исполняемый файл, который загружает или удаляет модули от
имени самого ядра.
Сделаем новый файл blacklist.conf
(Вы можете выбрать иное название, но
оно обязано иметь суффикс .conf
) и занесём в чёрный список этот модуль.
#cat /etc/modprobe.d/blacklist.conf
blacklist bluetooth
Однако после перезапуска вы обнаружите что bluetooth
снова загрузится
своим ядром.
#lsmod | grep -i bluetooth
bluetooth 626688 37 btrtl,btintel,btbcm,bnep,btusb,rfcomm
ecdh_generic 16384 1 bluetooth
rfkill 28672 5 bluetooth
Это происходит потому, что данный модуль bluetooth
находится в
зависимостях множества прочих модулей, таких как btrtl
,
btintel
, btbcm
,
bnep
, btusb
,
rfcomm
и rfkill
. Следовательно,
modprobe
загрузил bluetooth
в
качестве зависимости от прочих модулей. В подобной ситуации нам требуется обмануть команду
modprobe
добавляя строку install bluetooth
/bin/true
в соответствующий файл blacklist.conf
, как
это показано здесь:
# cat /etc/modprobe.d/blacklist.conf
install bluetooth /bin/true
После перезагрузки вы обнаружите, что рассматриваемый нами модуль bluetooth
был заблокирован.
# lsmod | grep -i bluetooth
<no_output>
Вы можете применять вместо /bin/true
/bin/false
.
После нашего объяснения rd.driver.blacklist
, параметры командной строки
dracut rd.driver.pre
и rd.driver.post
проще понять и здесь показаны поясняющие себя самостоятельно страницы руководства:
- rd.driver.pre=<drivername>[,<drivername>,...]
принудительно загружает модуль ядра <drivername>. Данный параметр может задаваться множество раз.
- rd.driver.post=<drivername>[,<drivername>,...]
принудительно загружает модуль ядра <drivername>. Данный параметр может задаваться множество раз.
Вот что сообщает страница руководства:
Установите -x для оболочки dracut. Если systemd активен в данной initramfs, весь вывод регистрируется в соответствующем журнале systemd, который вы можете проинспектировать через "journalctl -ab". Когда systemd не активен, тогда всё регистрируемое записывается в dmesg и /run/initramfs/init.log. Если установлена &quit;quiet&quit;, тогда записи также регистрируются в самой консоли.
rd.debug
включит регистрацию отладки systemd, что приведёт к регистрации
гигантского числа сообщений как в сакой консоли, так и в журналах systemd. Такие подробные предоставляемые
rd.debug
сообщения будут полезными при выявлении проблем, относящихся к
"can’t boot".
Вот что сообщает страница руководства:
Выдаёт на печать сведения об используемой памяти в различных точках, устанавливается уровень подробности от 0 до 4. Более высокий уровень означает больше отладочной информации.
0 - без вывода
1 - частичный /proc/meminfo
2 - /proc/meminfo
3 - /proc/meminfo + /proc/slabinfo
4 - /proc/meminfo + /proc/slabinfo + tracekomem
-
Это выдаст на печать в экране все относящиеся к подсистемам сведения о памяти, такие как содержимое файлов
meminfo
иslabinfo
.
Вот что сообщают страницы руководства:
- rd.lvm=0
отключает определение LVM
- rd.lvm.vg=<volume group name>
активирует только определённые группы томов с заданным названием. rd.lvm.vg может определяться множество раз в командной строке ядра.
- rd.lvm.lv=<volume group name>
активирует только определённые логические тома с заданным названием. rd.lvm.lv может определяться множество раз в командной строке ядра.
- rd.lvm.conf=0
удаляет /etc/lvm/lvm.conf, который может иметься в текущем initramfs.
-
Из всех этих параметров вы по крайней мере должны наблюдать передаваемый GRUB параметр
rd.lvm.lv
. Основная цельrd.lvm.lv
состоит в активации задаваемого устройства LVM на неком раннем этапе запуска. По умолчанию основные распространители Linux активируют только устройства LV корня и подкачки (при их настройке). Активирование только самой корневой файловой системы на момент запуска ускоряет всю процедуру запуска. После переключения текущего корня с initramfs на реальную корневую файловую систему, systemd способен активировать остающиеся группы томов в соответствии со списком/etc/fstab
. -
Аналогично dracut предоставляет параметры командной строки, относящиеся к множеству путей и RAID, которые опять- таки сами себя объясняют.
- MD RAID
- rd.md=0
отключает определение MD RAID
- rd.md.imsm=0
отключает определение MD RAID для raid imsm/isw, вместо этого применяйте DM RAID
- rd.md.ddf=0
отключает MD RAID для raid SNIA ddf, вместо этого применяйте DM RAID
- rd.md.conf=0
игнорировать включённый в initramfs mdadm.conf
- rd.md.waitclean=1
дожидаться любой активности для завершения повторной синхронизации, восстановления или трансформации прежде чем продолжить
- rd.md.uuid=<md raid uuid>
активирует только определённые raid с заданным UUID. Данный параметр может определяться множество раз
- DM RAID
- rd.dm=0
отключает определение DM RAID
- rd.dm.uuid=<dm raid uuid>
активирует только определённые raid с заданным UUID. Данный параметр может определяться множество раз
- MULTIPATH
- rd.multipath=0
отключает определение множества путей
-
dracut предоставляет n чисел параметров командной строки для сетевых сред, NFS, CIFS, iSCSI, FCoE и т.п.. Это также означает что существует различные варианты, которыми вы можете помещать свою корневую файловую систему, но практически невозможно охватить абсолютно все параметры командной строки dracut. К тому же я не сторонник запуска системы из таких сложных структур. Я полагаю, что корневая файловая система должна находиться на локальном диске чтобы процедура запуска была простой и в целом потому, что более простую последовательность запуска быстрее исправлять в случае ситуации "can’t boot".
rd.shell
предоставляет нам оболочку в самом конце последовательности
запуска, а с помощью rd.break
мы можем прерывать последовательность своего
запуска. Однако чтобы разобраться с этими параметрами, нам требуется обладать хорошим пониманием systemd.
Следовательно, прежде чем обсуждать rd.break
и специальные точки входа
dracut мы вначале в своей следующей главе рассмотрим systemd. Ниже приводятся все параметры, принимаемые
rd.break
:
Параметр | Назначение |
---|---|
|
Эта специальная точка входа собирает все параметры командной строки ядра. |
|
Эта специальная точка входа запускается перед установленным обработчиком
|
|
В этой специальной точке входа вы можете настроить переменные среды
|
|
Эта специальная точка входа запускается перед монтированием корневой
файловой системы пользователя |
|
Эта специальная точка входа запускается после монтированием корневой
файловой системы пользователя |
|
Эта специальная точка входа запускается в точности перед переключением на реальную корневую файловую систему. |