在CentOS/RHEL 7和8中更新和重建initrd镜像的2种方法
如何解压缩或者解压缩initrd或者initramfs引导镜像文件?
如何修改initrd或者initramfs的内容?
如何查看initrd或者initramfs?
如何在RHEL Linux中自定义initrd。
如何在RHEL 8 Linux中重建initrd镜像。
如何在RHEL 7 Linux中更新initrd。
如何使用XV压缩数据更新initrd。
如何使用LZMA压缩数据重建initrd镜像。
如何在Red Hat Enterprise Linux中重建初始ramdisk镜像。
如何在Red Hat Enterprise Linux中重建初始ram磁盘镜像。
如何重制或者重新创建initrd或者initramfs。
什么是initrd?
初始RAM磁盘(initrd)是在实际根文件系统可用之前已安装的初始根文件系统。
initrd绑定到内核,并作为内核引导过程的一部分进行加载。
然后,内核将此initrd挂载为两阶段引导过程的一部分,以加载模块以使实际文件系统可用并获得真实的根文件系统。initrd文件包含用于实现此目的的最少目录和可执行文件集,例如用于将内核模块安装到内核中的" insmod"工具。
换句话说,它包含必要的可执行文件和系统文件,以支持Linux系统的第二阶段引导。initrd镜像位于/boot目录下,并由内核软件包拥有。
系统上正在运行的内核的版本将用于识别引导过程中使用的当前initrd镜像。
提示:
RHEL 7提供了两个initrd镜像。
一个是在内核安装到根文件系统上之后创建的,即在/boot/initramfs-$(uname -r).img
中可用,而另一个在在系统启动的初始阶段加载的RHEL ISO DVD。
在本文中,我们研究了RHEL ISO DVD中提供的更新和重建initrd的步骤,以了解从系统中提取和重建initramfs的步骤,我们可以按照本文进行操作。
为什么要更新initrd?
Initrd包含许多用于第三方供应商的驱动程序,以及许多有助于操作系统检测底层硬件的模块和可执行文件。
在新硬件上,initrd可能无法检测到底层硬件部件,例如网卡,存储适配器等。
在这种情况下,我们可以修改" initrd"镜像。
尽管不建议将第三方供应商的驱动程序模块添加到initrd
中,但我还是建议创建一个自定义DUD(驱动程序更新磁盘),因为它也执行相同的任务,并且比更新和重建initrd
更好。
说明:
不建议在生产环境中修改" initrd",如果我们具有有效的订阅,则应与支持团队联系以处理需要修改" initrd"的任何问题。
除了修改initrd
镜像外,我们还可以选择创建一个updates.img
文件,该文件在BOOT UP的稍后阶段被调用。
但是,如果问题与底层硬件的检测失败有关,那么" updates.img"将无济于事。
选择哪一个initrd.img还是updates.img?
anaconda可以在运行时合并更新,以修复安装程序中的所有错误或者问题。
这些更新通常作为磁盘镜像文件分发(在本文中称为updates.img)。
因此,我们有两个选项可以通过自定义更改来更改启动过程,一个选项使用initrd,另一个选项使用updates.img
。
这个问题的答案取决于要求。
在启动过程的后期会调用updates.img
,因此,如果我们希望包括重要的模块来检测硬件,则应该更新并重建initrd,而如果需要为RHEL OS添加一些错误修复,则继续updates.img
检查initrd内容
在更新initrd之前,最好验证一下initrd镜像的现有内容。
其中我正在从RHEL 8 ISO镜像检查initrd的内容。
[root@rhel-8 ~]# lsinitrd /mnt/images/pxeboot/initrd.img | less Image: /mnt/images/pxeboot/initrd.img: 58M ======================================================================== Version: dracut-049-10.git20190115.el8 Arguments: --nomdadmconf --nolvmconf --xz --install '/.buildstamp' --no-early-microcode --add 'fips' --add 'anaconda pollcdrom qemu qemu-net prefixdevname-tools' --force dracut modules: bash systemd fips systemd-initrd modsign nss-softokn i18n convertfs network-legacy network ifcfg url-lib drm plymouth <Output trimmed> drwxr-xr-x 2 root root 0 Jan 15 2019 var/lib/nfs/rpc_pipefs drwxrwxr-x 3 root root 0 Jan 15 2019 var/lib/nfs/statd drwxr-xr-x 2 root root 0 Jan 15 2019 var/lib/nfs/statd/sm drwxrwx--- 2 root root 0 Jan 15 2019 var/lib/rpcbind lrwxrwxrwx 1 root root 11 Jan 15 2019 var/lock -> ../run/lock lrwxrwxrwx 1 root root 6 Jan 15 2019 var/run -> ../run drwxr-xr-x 2 root root 0 Jan 15 2019 var/tmp ========================================================================
在此列表中,我们可以其中查找initrd图像文件的内容。
方法1:提取initrd图像
根据initrd文件压缩类型,提取和重建initrd的命令将有所不同。
对于RHEL 7和8中的情况,我们在initrd文件中具有XZ压缩数据,如下所示:
[root@rhel-8 ~]# file /mnt/images/pxeboot/initrd.img /mnt/images/pxeboot/initrd.img: XZ compressed data [root@rhel-8 ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.0 (Ootpa)
[root@rhel-7 ~]# file /mnt/images/pxeboot/initrd.img /mnt/images/pxeboot/initrd.img: XZ compressed data [root@rhel-7 ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.6 (Maipo)
因此,我们可以使用相同的方法为RHEL 7和8 Linux提取并重建initrd。
重要的提示:
提取initrd之前,请确保已备份initrd文件,或者可以在不触摸原始文件的情况下提取到其他位置。
我们将创建一个临时目录,其中提取和更新initrd
[root@rhel-8 custom_initrd]# mkdir /tmp/custom_initrd
要提取initrd,请使用以下命令:
[root@rhel-8 custom_initrd]# xz -dc < /mnt/images/pxeboot/initrd.img | cpio -idmv
这将提取当前目录中initrd的所有内容
[root@rhel-8 custom_initrd]# ls -l total 44 lrwxrwxrwx. 1 root root 7 Sep 13 19:44 bin -> usr/bin drwxr-xr-x. 2 root root 4096 Sep 13 19:44 dev drwxr-xr-x. 14 root root 4096 Sep 13 19:44 etc lrwxrwxrwx. 1 root root 23 Sep 13 19:44 init -> usr/lib/systemd/systemd lrwxrwxrwx. 1 root root 7 Sep 13 19:44 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Sep 13 19:44 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 4096 Jan 15 2019 proc drwxr-xr-x. 2 root root 4096 Jan 15 2019 root drwxr-xr-x. 2 root root 4096 Jan 15 2019 run lrwxrwxrwx. 1 root root 8 Sep 13 19:44 sbin -> usr/sbin -rwxr-xr-x. 1 root root 3126 Oct 8 2016 shutdown drwxr-xr-x. 2 root root 4096 Jan 15 2019 sys drwxr-xr-x. 2 root root 4096 Jan 15 2019 sysroot drwxrwxr-x. 2 root root 4096 Jan 15 2019 tmp drwxrwxr-x. 9 root root 4096 Sep 13 19:44 usr drwxr-xr-x. 4 root root 4096 Sep 13 19:44 var
方法2:提取initrd图像
另外,我们也可以使用以下步骤列表提取initrd。
首先将initrd文件从RHEL 7/8 ISO DVD复制到临时目录
[root@rhel-8 custom_initrd]# cp /mnt/isolinux/initrd.img /tmp/custom_initrd/
验证文件
[root@rhel-8 custom_initrd]# ls -lh total 58M -r--r--r--. 1 root root 58M Sep 13 22:03 initrd.img
现在解压缩文件
[root@rhel-8 custom_initrd]# unxz -S .img initrd.img
这样,initrd.img将提取并创建一个initrd文件
[root@rhel-8 custom_initrd]# ls -lh total 171M -r--r--r--. 1 root root 185M Sep 13 22:03 initrd
将initrd的内容提取到当前目录中
[root@rhel-8 custom_initrd]# cat initrd | cpio -idm cpio: .buildstamp not created: newer or same age version exists 378442 blocks
验证initrd的内容
[root@rhel-8 custom_initrd]# ls -lh total 171M lrwxrwxrwx. 1 root root 7 Sep 13 22:07 bin -> usr/bin drwxr-xr-x. 2 root root 4.0K Sep 13 22:07 dev drwxr-xr-x. 14 root root 4.0K Sep 13 22:07 etc lrwxrwxrwx. 1 root root 23 Sep 13 22:07 init -> usr/lib/systemd/systemd -r--r--r--. 1 root root 185M Sep 13 22:03 initrd lrwxrwxrwx. 1 root root 7 Sep 13 22:07 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Sep 13 22:07 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 4.0K Jan 15 2019 proc drwxr-xr-x. 2 root root 4.0K Jan 15 2019 root drwxr-xr-x. 2 root root 4.0K Jan 15 2019 run lrwxrwxrwx. 1 root root 8 Sep 13 22:07 sbin -> usr/sbin -rwxr-xr-x. 1 root root 3.1K Oct 8 2016 shutdown drwxr-xr-x. 2 root root 4.0K Jan 15 2019 sys drwxr-xr-x. 2 root root 4.0K Jan 15 2019 sysroot drwxrwxr-x. 2 root root 4.0K Jan 15 2019 tmp drwxrwxr-x. 9 root root 4.0K Sep 13 22:07 usr drwxr-xr-x. 4 root root 4.0K Sep 13 22:07 var
更新initrd镜像
现在,由于我们已经成功提取了initrd,因此我们可以继续进行修改。
例如,我们可以从供应商处添加新的驱动程序模块,以支持某些新硬件或者任何其他自定义更改。
重要的提示:
不要更改initrd镜像的目录结构
为了本文的方便,我希望将一个udev规则文件添加到initrd中,以检测和映射具有预定义PCI ID的NIC卡。
# cat 20-persistent-net.rules SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:01:00.0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0" SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:01:00.1", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1" SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:03:00.0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2" SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:03:00.1", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3" SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:04:00.0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth4" SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", BUS=="pci", ID=="0000:04:00.1", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth5"
我们将其添加到initrd中的/usr/lib/udev/rules.d下。
[root@rhel-8 rules.d]# ls -l total 124 -r--r--r--. 1 root root 7266 Jan 15 2019 10-dm.rules -r--r--r--. 1 root root 2454 Jan 15 2019 11-dm-lvm.rules -rw-r--r--. 1 root root 4538 Jan 15 2019 11-dm-mpath.rules -r--r--r--. 1 root root 1794 Jan 15 2019 13-dm-disk.rules -rw-r--r--. 1 root root 876 Sep 13 20:13 20-persistent-net.rules -rw-r--r--. 1 root root 1622 Jan 15 2019 40-redhat.rules -rw-r--r--. 1 root root 3679 Jan 15 2019 50-udev-default.rules
方法1:重建initrd镜像
如果我们使用方法1提取initrd,然后按照以下步骤重建initrd镜像,请导航到提取了initrd镜像的临时目录。
[root@rhel-8 rules.d]# cd /tmp/custom_initrd/ [root@rhel-8 custom_initrd]#
执行以下命令以xz作为压缩格式重建initrd镜像
[root@rhel-8 custom_initrd]# find . 2>/dev/null | cpio -c -o | xz -9 --format=xz > /tmp/new.img 378439 blocks
检查新initrd文件的压缩类型
[root@rhel-8 custom_initrd]# ls -l /tmp/new.img -rw-r--r--. 1 root root 53615972 Sep 13 20:24 /tmp/new.img [root@rhel-8 custom_initrd]# file /tmp/new.img /tmp/new.img: XZ compressed data
方法2:重建initrd镜像
如果我们使用方法2执行解压缩initrd,然后按照以下步骤重建initrd镜像,请导航到提取initrd镜像的临时目录。
删除已解压缩的initrd文件在同一目录中。
[root@rhel-8 custom_initrd]# rm -f initrd
接下来使用以下命令重建initrd镜像:
[root@rhel-8 custom_initrd]# find . | cpio -oc > ../initrd; cd ..; xz -S .img initrd 378442 blocks
验证新的initrd镜像
[root@rhel-8 tmp]# ls -lh initrd.img -rw-r--r--. 1 root root 53M Sep 13 22:15 initrd.img
验证initrd镜像
现在,既然我们成功地重建了initrd镜像,那么让我们验证新initrd的内容,并确保新的规则文件存在于该initrd镜像中
[root@rhel-8 custom_initrd]# lsinitrd /tmp/new.img | grep 20-persistent-net.rules -rw-r--r-- 1 root root 876 Sep 13 20:13 usr/lib/udev/rules.d/20-persistent-net.rules
如我们所见,我们的文件现在是initrd文件的一部分。
因此,现在我们可以使用此initrd文件启动系统。
同样,我们可以验证使用方法2创建的initrd的内容。