dracut

来自 Arch Linux 中文维基

dracut 会为内核创建初始映像,用于预载访问根文件系统所需的块设备模块(如 IDE、SCSI 或 RAID)。安装 linux 时,可以在 mkinitcpiodracut 之间进行选择。Fedora、RHEL、Gentoo 和 Debian 等系统都使用 dracut,而Arch 默认使用mkinitcpio

你可以在此查看 dracut 的完整项目文档。

安装[编辑 | 编辑源代码]

安装 dracut,你也可以安装 dracut-gitAUR 使用最新的开发版本。

提示:如果 dracut 测试后功能一切正常,你可以卸载 mkinitcpio

用法[编辑 | 编辑源代码]

dracut 的用法非常简单,而且通常就算在非标准环境下也不需要用户进行配置(如在 LUKS 上配置 LVM)。

使用如下命令为当前运行的内核生成 initramfs:

# dracut --hostonly --no-hostonly-cmdline --add-confdir no-network /boot/initramfs-linux.img

为了永久启用仅主机(hostonly)模式以便无需在命令行中进行指定,你可以在 dracut 的配置中添加:

/etc/dracut.conf.d/hostonly.conf
hostonly="yes"
注意: 在某些情况下,特别是在首次安装系统的时候,上述命令无法使用;这种情况下可以改用:
# dracut --regenerate-all

使用如下命令生成后备 initramfs:

# dracut /boot/initramfs-linux-fallback.img

/boot/initramfs-linux.img 指代输出的镜像文件。如果使用非标准内核,请考虑更改文件名。例如,对于 linux-lts 内核,输出文件应使用 /boot/initramfs-linux-lts.img。不过,只要引导加载程序的配置使用了相同的文件名,就可以随意命名这些文件。

注意: 创建出的文件内嵌所有已安装的微码映像。

额外选项[编辑 | 编辑源代码]

--force 选项会覆写现有映像文件。

--kver 选项用于指定要使用的内核。该选项的输入需要匹配 /usr/lib/modules 目录下文件夹之一的名称。

其它选项可参考 dracut(8)

进阶配置[编辑 | 编辑源代码]

要注意的是,initial ramdisk 阶段有两种执行各种任务的不同方式:

基于 Shell(bash/busybox/dash)的 initial ramdisk:该方式会启动一个初始化脚本,然后扫描 initial ramdisk 的文件系统来查找要执行的 dracut 脚本。
基于 systemd(默认)的 initial ramdisk:systemd 在 initial ramdisk 阶段时就已启动。具体要执行的任务由标准的 systemd 单元文件指定,相关信息可参考 systemd 启动流程

这两种方式的主要区别在于 systemd dracut 模块的存在与否。详细信息请参考 #dracut 模块

dracut 可通过直接传入命令行参数进行配置(参考 dracut(8) § OPTIONS)。如果你希望执行 dracut 命令时始终带上特定参数,可以在 /etc/dracut.conf.d/ 目录下的 .conf 文件中进行指定。例如:

/etc/dracut.conf.d/myflags.conf
hostonly="yes"
compress="lz4"
add_drivers+=" i915 "
omit_dracutmodules+=" systemd network "

更多配置选项可参考 dracut.conf(5)。各个选项的完整说明可参考 dracut(8)。在下文中会对部分常用选项进行说明。

dracut 模块[编辑 | 编辑源代码]

dracut 使用模块化流程构建 initramfs(参考 dracut.modules(7))。dracut 的所有内置模块位于 /lib/dracut/modules.d,可通过 dracut --list-modules 命令列出。更多模块可通过其它软件包提供(如 dracut-sshd-gitAUR)。遗憾的是,dracut 的内置模块缺乏文档说明,尽管它们的名称通常不言自明。

部分模块默认被激活/禁用,可通过 --add/--omit 选项分别激活或禁用,也可以在配置文件中使用 add_dracutmodules+=""omit_dracutmodules+="" 持久化更改:

/etc/dracut.conf.d/myflags.conf
# ...
add_dracutmodules+=" dracut modules to activate "
omit_dracutmodules+=" dracut modules to deactivate "
# ...

以下清单列出了 dracut 模块,对应所需的软件包(dracut 的可选依赖)及模块描述。

大多数 dracut 模块都依赖于其它 dracut 模块。举个例子,蓝牙 dracut 模块就依赖于 dbus dracut 模块。该清单仅列出了 dracut 模块的直接依赖,即指定 dracut 模块的 module-setup.sh 中列出的模块所需软件包。

dracut 模块的详细文档请参考 dracut 上游维基

dracut 模块 所需软件包 描述
bluetooth bluez 蓝牙(键盘)
btrfs btrfs-progs 在块设备上查找 Btrfs
busybox busybox 允许使用 BusyBox(后果自负)
crypt cryptsetup 加密 Dm-crypt 文件系统支持
dash dash 允许使用 Dash(后果自负)
dmraid dmraidmultipath-tools dmraid dracut 模块支持
multipath multipath-tools Multipath dracut 模块支持
dmsquash-live-ntfs fuse3, ntfs-3g Live on NTFS
lvm lvm2 LVM 支持
mdraid mdadm MD 设备支持,也被称作软件 RAID 设备
memstrack memstrackAUR memstrack 支持
nvdimm ndctl NVDIMM 支持
plymouth plymouth Plymouth 启动界面
rescue 提供用于急救模式的多种工具(例如 ping,ssh,vi,fsck.*)
resume 允许 initramfs 从低功耗模式恢复
rngd Starts random generator service on early boot
syslog rsyslogAUR 启用 Rsyslog 日志记录
squash squashfs-tools squashed initramfs 构建支持
tpm2-tss tpm2-tools Trusted Platform Module
base 带有所需工具的基础模块
bash bash 在有更多可用解释器的情况下,Bash 是首选的解释器
biosdevname biosdevnameAUR 启用 BIOS 网络设备重命名
caps Supports dropping capabilities before init
convertfs Merges / into /usr on next boot
crypt-gpg gnupg 为加密操作操作和智能卡提供支持(可能需要 GPG 密钥)
crypt-loop 添加加密回环设备支持(对称密钥)
dbus 用于 dbus-broker 或 dbus-daemon 的虚拟包
dbus-broker dbus-broker dbus-broker 作为 dbus 服务提供者
dbus-daemon dbus dbus 作为 dbus 服务提供者
debug 启用调试功能
dm 添加 device-mapper 支持
dmsquash-live-autooverlay 在根文件系统父块设备的可用空间中创建一个供 overlayfs 使用的分区
dracut-systemd 基础 systemd dracut 模块
drm 包含提供 DRM 支持的内核模块
ecryptfs 添加 ecryptfs 文件系统支持
fido2 允许使用 FIDO2 安全令牌解锁加密文件系统
fips 强制执行 FIPS 安全标准规定
fs-lib 文件系统工具库(包括 fsck.* 和 mount)
fstab-sys 在挂载根文件系统前挂载任意分区
i18n 包括键盘布局,终端字体等
img-lib 提供用于解压映像的多种工具
integrity 添加扩展验证模块支持
kernel-modules Kernel modules for root filesystems and other boot-time devices
kernel-modules-extra Extra out-of-tree kernel modules
lunmask Masks LUN devices to select only ones which required to boot
lvmmerge Merges lvm snapshots
lvmthinpool-monitor Monitor LVM thinpool service
masterkey Masterkey that can be used to decrypt other keys and keyutils
modsign Adds signing kernel modules support
overlayfs Kernel module for overlayfs
pcsc Adds support for PCSC Smart cards
pkcs11 Includes PKCS#11 libraries
pollcdrom Enables CD-ROM polling
qemu Includes kernel modules for QEMU environment
rescue utilities for rescue mode (such as ping, ssh, vi, fsck.*)
rootfs-block Arranges for the block device containing the rootfs to be mounted
securityfs Arranges for the securityfs to be mounted early
selinux Arranges for the selinux policy to be loaded
shutdown Sets up hooks to run on shutdown
systemd Adds systemd as early init initialization system
terminfo Includes a terminfo file
udev-rules Includes udev and some basic rules
uefi-lib Library to include UEFI tools
usrmount Mounts /usr
virtfs Adds virtual filesystems (9p) support
virtiofs Adds virtiofs filesystems support
warpclock Sets kernel's timezone and reset the system time if adjtime is set to LOCAL
watchdog Includes watchdog devices management; works only if systemd not in use
watchdog-modules Includes watchdog kernel modules to be loaded early in booting

以下为在早期启动阶段就需要使用 IP 地址的 dracut 模块:

dracut 网络模块 所需软件包 描述
cifs cifs-utils Samba 支持
nbd nbd 网络块设备支持
network-manager networkmanager NetworkManager 支持
nfs nfs-utils NFS 支持 - NFSv3 和 NFSv4
nvmf nvme-clijq NVMe over Fibre Channel and NVMe-over Fabrics support
iscsi open-iscsi ISCSI 支持
ssh-client openssh 安装 ssh 和 scp 及配置文件和指定密钥
network-legacy dhclient, iproute2, iputils 传统网络配置支持
connman connman ConnMan 网络管理支持
kernel-network-modules 添加并加载网络设备所需的内核模块
livenet 为 SquashFS 映像拉取实时更新
network Virtual module for network service providers
url-lib 包含 curl 和 SSL 证书
qemu-net 包含 QEMU 环境网络内核模块
systemd-network-management Adds network management for systemd. Includes systemd-networkd, systemd-resolved and some othr networking related dracut modules
systemd-networkd Systemd-networkd
net-lib Networking library with ip

TPM2[编辑 | 编辑源代码]

要使用 systemd 通过 systemd-cryptenroll 调用 TPM2 解锁 luks2 加密卷的功能,需要安装 tpm2-tools 并启用 tpm2-tss dracut 模块。

早期内核模块加载[编辑 | 编辑源代码]

可以通过 --force_drivers 命令行选项或 force_drivers+="" 配置项启用 dracut 早期加载功能(在 initramfs 阶段通过 modprobe 加载)。例如:

/etc/dracut.conf.d/myflags.conf
# ...
force_drivers+=" nvidia nvidia_modeset nvidia_uvm nvidia_drm "
# ...

内核命令行参数[编辑 | 编辑源代码]

内核命令行选项可放置在 /etc/dracut.conf.d/.conf 文件内,并通过 kernel_cmdline= 选项进行配置。Dracut 会自动读取配置,然后创建并写入到 initramfs /etc/cmdline.d/ 目录下的 01-default.conf 文件中。举个例子,你的内核命令行选项文件内容可能如下:

/etc/dracut.conf.d/cmdline.conf
kernel_cmdline="rd.luks.uuid=luks-f6c738f3-ee64-4633-b6b0-eceddb1bb010 rd.lvm.lv=arch/root rd.lvm.lv=arch/swap  root=/dev/arch/root rootfstype=ext4 rootflags=rw,relatime"

其它说明[编辑 | 编辑源代码]

不需要为 dracut 指定根块设备。参考 dracut.cmdline(7)

内核使用的根设备从来都是在启动配置文件的内核命令行选项中指定的。

不过,提前设置一些参数可能会很有用,而且还可以启用一些其它功能,如提示输入额外命令行参数。所有选项请参见 dracut.cmdline(7)。下面是一些配置选项示例:

  • 从交换分区恢复:resume=UUID=80895b78-7312-45bc-afe5-58eb4b579422
  • 提示输入额外内核命令行参数:{ic|1=rd.cmdline=ask}}
  • 在设定了 quiet 的前提下输出更多信息:rd.info

统一内核映像[编辑 | 编辑源代码]

dracut 可以通过 --uefi 命令行参数或 uefi="yes" 配置项生成统一内核映像

小提示[编辑 | 编辑源代码]

查看生成映像的信息[编辑 | 编辑源代码]

你可以查看生成的映像的信息,并输出到单页上:

# lsinitrd /path/to/initramfs_or_uefi_image | less

该命令会列出生成映像时传入到 dracut 的参数、包含的 dracut 模块以及包含的所有文件。

修改压缩软件[编辑 | 编辑源代码]

要减少压缩生成映像所消耗的时间,可以更换使用的压缩软件。

警告: 请确保你的内核编译了所选软件对应的解压支持,否则系统将无法启动。你还需要安装所选压缩程序的软件包。

只需添加下列任意一行(不能多选)到 dracut 配置文件中:

compress="cat"
compress="gzip"
compress="bzip2"
compress="lzma"
compress="xz"
compress="lzo"
compress="lz4"
compress="zstd"

默认使用的是 gzip。选择 compress="cat" 将不会压缩 initramfs。

你也可以使用非官方支持的压缩软件:

compress="program"

性能考虑[编辑 | 编辑源代码]

有些方法可以优化启动和生成 initramfs 的性能:

  • 理解并配置最快的压缩方式。如果内核模块已经被压缩过,可能在生成 initramfs 时就不需要再次进行压缩。
  • 理解在 initramfs 中添加 systemd 可能造成的影响。如果它会降低性能,就将其移除;如果会提升性能,就纳入进来。
  • 在使用写时复制文件系统时,考虑使用 dracut-cpio。具体适用性请参考 --enhanced-cpio 选项。
  • 减少 initramfs 中嵌入的内核模块和 dracut 模块的数量。例如:如果安装了 nfs-utils,但不依赖其进行启动,就需要显式移除 nfs dracut 模块,否则在默认配置下生成的 initramfs 会启用网络启动 - 详细信息请参考 https://github.com/dracut-ng/dracut-ng/pull/297
  • 考虑使用 busybox 取代 bash。
  • 考虑使用 hostonly。

升级内核时生成新 initramfs[编辑 | 编辑源代码]

可以在升级内核时自动生成新的 initramfs 映像。以下指南适用于默认 linux 内核,但为其它内核添加钩子也很容易。

提示:
  • dracut-ukifyAUR 软件包是使用 systemd-ukify 生成统一内核映像的现代方法。与以下方法不同,你可以对整个内核映像签名包括 initramfs。需要在 dracut 配置中使用 uefi_secureboot_certuefi_secureboot_key 选项(dracut.conf(5))。
  • dracut-hookAUR 软件包提供了类似下面的钩子和脚本。另外,如果你希望 initramfs 映像也是 EFI 可执行文件(即 esp/EFI/Linux/linux-kernel-machine_id-build_id.efi),也可以使用 dracut-uefi-hookAURdracut-hook-uefiAUR。在该目录下的 EFI 二进制文件会被 systemd-boot 自动检测到,因此不需要在 /boot/loader/loader.conf 中额外创建条目。

鉴于获取内核版本的复杂性,单靠 pacman 钩子无法达成目标。你需要在系统的任意位置下创建一个脚本,在该示例中位于 /usr/local/bin/

由于内核软件包已不再将文件写入 /boot/ 中,该脚本同时会将新的 vmlinuz 内核文件复制到 /boot/ 目录下。[1]

/usr/local/bin/dracut-install.sh
#!/usr/bin/env bash

args=('--force' '--no-hostonly-cmdline')

while read -r line; do
	if [[ "$line" == 'usr/lib/modules/'+([^/])'/pkgbase' ]]; then
		read -r pkgbase < "/${line}"
		kver="${line#'usr/lib/modules/'}"
		kver="${kver%'/pkgbase'}"

		install -Dm0644 "/${line%'/pkgbase'}/vmlinuz" "/boot/vmlinuz-${pkgbase}"
		dracut "${args[@]}" --hostonly "/boot/initramfs-${pkgbase}.img" --kver "$kver"
		dracut "${args[@]}" --add-confdir rescue  "/boot/initramfs-${pkgbase}-fallback.img" --kver "$kver"
	fi
done
/usr/local/bin/dracut-remove.sh
#!/usr/bin/env bash

while read -r line; do
	if [[ "$line" == 'usr/lib/modules/'+([^/])'/pkgbase' ]]; then
		read -r pkgbase < "/${line}"
		rm -f "/boot/vmlinuz-${pkgbase}" "/boot/initramfs-${pkgbase}.img" "/boot/initramfs-${pkgbase}-fallback.img"
	fi
done

接下来需要将该脚本设为可执行。如果你需要添加或移除选项,需要在 dracut 配置文件进行修改

下一步是创建 pacman 钩子

/etc/pacman.d/hooks/90-dracut-install.hook
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Target = usr/lib/modules/*/pkgbase

[Action]
Description = Updating linux initcpios (with dracut!)...
When = PostTransaction
Exec = /usr/local/bin/dracut-install.sh
Depends = dracut
NeedsTargets
/etc/pacman.d/hooks/60-dracut-remove.hook
[Trigger]
Type = Path
Operation = Remove
Target = usr/lib/modules/*/pkgbase

[Action]
Description = Removing linux initcpios...
When = PreTransaction
Exec = /usr/local/bin/dracut-remove.sh
NeedsTargets

你同时需要通过卸载 mkinitcpio 或使用以下命令来阻止 mkinitcpio 创建和移除 initramfs 映像:

# ln -sf /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
# ln -sf /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook

蓝牙键盘支持[编辑 | 编辑源代码]

如果检测到了蓝牙键盘,dracut 会自动启用蓝牙模块。但该功能需要 dracut 处于 hostonly 模式,默认情况下似乎并非如此。

排障[编辑 | 编辑源代码]

休眠[编辑 | 编辑源代码]

如果从休眠中恢复无效,你可能需要配置 dracut 以包含 resume 模块。添加一个配置文件

/etc/dracut.conf.d/resume-from-hibernate.conf
add_dracutmodules+=" resume "

如果适用于你的系统,你可能也需要看下从加密交换分区恢复指南以及 dracut 特定指南

LVM / 软 RAID / LUKS[编辑 | 编辑源代码]

如果内核无法自动发现并挂载 LVM / 软 RAID / LUKS 块设备,你可以加上以下内核命令行选项重新生成 initramfs:

rd.auto rd.lvm=1 rd.dm=1 rd.md=1 rd.luks=1

A stop job is running for "brltty"[编辑 | 编辑源代码]

If you have issues booting or very long shutdown processes while the system waits for brltty, add the following to the dracut configuration line:

omit_dracutmodules+=" brltty "

Alternatively, uninstall brltty if it is not needed.

No usable keyslot is available[编辑 | 编辑源代码]

Cannot use whirlpool hash for keyslot encryption. 
Keyslot open failed. 
No usable keyslot is available.

A failure to boot with a message similar to the above typically will only require the user to include the crypt module via add_dracutmodules.

参考[编辑 | 编辑源代码]