在系统引导期间查找 rootfs(2)四个技巧-2
- UID
- 1066743
|
在系统引导期间查找 rootfs(2)四个技巧-2
3. 编辑 initrd 映像以更改存储适配器顺序initrd 映像实际上是一个 RAM 磁盘,其中包含带有基本配置文件、二进制文件、库和驱动程序的小型文件系统。在这个小型文件系统中,有一个将在引导期间装入到内存中的根文件系统,还有一个用于装入系统设备驱动程序的初始化脚本;它将在加载完所有设备驱动程序后重新加载实际的根文件系统磁盘。当系统尝试将 initrd 根文件系统切换到拥有此配置中的设备名称的实际根文件系统磁盘时,经常会出现 cannot mount rootfs 错误。您需要更改 initrd 映像的驱动程序载入脚本中的设备驱动程序载入顺序,让您的根文件系统磁盘在系统尝试重新加载实际的根文件系统之前 显示正确的设备名称。为此:
- 使用 Linux 恢复 CD 将系统引导到恢复模式下,因为您无法访问根文件系统。
- 将根文件系统加载到诸如 sysroot 之类的临时目录中(某些 Linux 恢复 CD 将自动为您执行此操作)。例如,在将系统引导到恢复模式下并且根文件系统使用的是第 3 分区时,根文件系统磁盘将被识别为 /dev/sdc。
1
| [root@linuxhost ~]#mount /dev/sdc3 sysroot
|
- 将恢复系统根目录切换为 sysroot,以便您可以访问问题服务器系统的根文件系统。
1
| [root@linuxhost ~]#chroot sysroot
|
- 提取 initrd 映像。
- 对于 Red Hat Enterprise Linux 第 3 版之前的版本和 SUSE Linux Enterprise Server 第 9 版之前的版本:
1
2
3
4
| [root@linuxhost ~]#cp /boot/initrd-x.x.x-x.ELsmp.img ./initrd.gz
[root@linuxhost ~]#mkdir temp
[root@linuxhost ~]#gunzip ./initrd.gz
[root@linuxhost ~]#mount -o loop -t ext2 initrd temp
|
这段代码将把 initrd 映像提取到 initrd 文件中;然后将使用 ext2 文件系统类型加载这个文件,以加载 temp。在此之后,您将看到所有文件被封装到 initrd 映像中。 - 对于 Red Hat Enterprise Linux 第 4 版和更高版本或者 SUSE Linux Enterprise Server 第 10 版和更高版本:
1
2
3
4
| [root@linuxhost ~]#cp /boot/initrd-*.img ./initrd.gz
[root@linuxhost ~]#mkdir temp
[root@linuxhost ~]#cd temp
[root@linuxhost ~]#gzip -dc ../initrd.gz | cpio -id
|
在这些最新的 Linux 发行版中,initrd 映像也是用 cpio 压缩的。这些命令将提取 temp 目录下包含目录结构的整个文件系统。您现在应当可以在 temp 目录的 initrd 映像中找到所有文件。
- 现在,您将在 temp 目录下找到适用于 Red Hat Enterprise Linux 和 SUSE Linux Enterprise Server 第 10 版的 init 文件,或者适用于 SUSE Linux Enterprise Server 第 9 版之前的版本的 linuxrc 文件。此文件是包含将设备驱动程序载入到系统内存中的所有命令的简单 Linux shell 脚本。您可以通过文本编辑器或者其他编辑器来编辑它。
- 编辑 init 或 linuxrc 文件,以使根文件系统磁盘适配器出现在同一个类别中的所有其他存储适配器的前面。在大多数情况下,根文件系统磁盘将是带有 sd 前缀的 SCSI 设备;您需要把诸如 FC 或 SAS HBA 驱动程序之类的所有其他存储适配器放到根文件系统磁盘所依赖的驱动程序之后。
- 例如,如果根文件系统的物理磁盘与 SAS 适配器连接在一起,则 init 文件可以有如下所示的字段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| .......
echo "Loading mptbase.ko module"
insmod /lib/mptbase.ko
echo "Loading mptscsi.ko module"
insmod /lib/mptscsi.ko
echo "Loading mptspi.ko module"
insmod /lib/mptspi.ko
echo "Loading mptsas.ko module"
insmod /lib/mptsas.ko
echo "Loading mptscsih.ko module"
insmod /lib/mptscsih.ko
echo "Loading qla2xxx.ko module"
insmod /lib/qla2xxx.ko
.......
|
在本例中,将所有其他 SCSI 适配器驱动程序(如 Qlogic HBA 驱动程序 qla2xxx.ko)放在 SAS 适配器驱动程序 mptsas.ko 之后。 - 如果使用的是 SUSE Linux Enterprise Server 第 10 版,它将类似以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| modprobe scsi_mod $params
modprobe sd_mod $params
params=
for p in $(cat /proc/cmdline) ; do
case $p in
aacraid.*)
params="$params ${p#aacraid.}"
;;
esac
done
echo "Loading aacraid"
modprobe aacraid $params
modprobe scsi_transport_fc $params
modprobe firmware_class $params
params=
for p in $(cat /proc/cmdline) ; do
case $p in
qla2xxx.*)
params="$params ${p#qla2xxx.}"
;;
esac
done
echo "Loading qla2xxx"
modprobe qla2xxx $params
|
- 检验您的版本是否正确,这样才不会遗漏任何所需的驱动程序(例如,SAS 需要同时装入 mptbase.ko、mptscsi.ko、mptspi.ko、mptsas.ko 和 mptscsih.ko,这样您不能先装入 qla2xxx.ko,再装入 mptscsih.ko)。此外,您可能还需要检查错误的输入。
- 此时,您需要将 initrd 文件系统重新压缩到一个映像中,并替换 /boot 目录下的原有映像。
- 对于 Red Hat Enterprise Linux 第 3 版之前的版本和 SUSE Linux Enterprise Server 第 9 版之前的版本:
1
2
3
| [root@linuxhost ~]#umount temp
[root@linuxhost ~]#gzip initrd
[root@linuxhost ~]#cp initrd.gz /boot/initrd-2.x.x-x.img
|
- 对于 Red Hat Enterprise Linux 第 4 版和更高版本或者 SUSE Linux Enterprise Server 第 10 版和更高版本:
1
2
3
| [root@linuxhost ~]#find ./ | cpio -H newc -o > ../initrd
[root@linuxhost ~]#gzip initrd
[root@linuxhost ~]#cp initrd.gz /boot/initrd-2.6.x-x.img
|
- 祝贺您!您已经修正了问题。现在重新启动并检查结果。
4. 使用标签、UUID 或友好的名称UUIDUUID 表示全局惟一标识符(Universally Unique Identifier)。它是软件构造中使用的标识符标准,开放软件基金会(Open Software Foundation)将其标准化为分布式计算环境(Distributed Computing Environment,DCE)的一部分。UUID 的目的是支持分布式系统,以惟一地标识信息而无需进行重大的协调;标有 UUID 的信息可以并入单个数据库中,而无需解决名称冲突。此标准的重要应用包括 Linux ext2/ext3 文件系统、LUKS 加密分区、GNOME、KDE、Mac OS X 和 Microsoft® Globally Unique Identifiers。
某些 Linux 文件系统类型(如 ext2、ext3、reiserfs、swap 和 XFS)支持装入带有标签的文件系统而不是带有设备名称的文件系统,如果您的 Linux 系统支持,则可以转而使用 UUID。此外,如果您的设备驱动程序支持,则可以使用友好的名称。
这些方法需要 Linux 系统支持这些功能(如 Red Hat Enterprise Linux V4 和更高版本或者 SUSE Linux Enterprise Server V9 和更高版本)。由于标签、UUID 和友好的名称将永远与专用设备绑定在一起,因此不管拥有什么设备 ID 或者使用什么设备名称,系统总是能够找到根文件系统磁盘。
使用标签
- 在创建诸如 root、swap 之类的文件系统或其他文件系统时,创建一个标签。
1
2
3
4
| [root@linuxhost ~]#mkfs.ext3 -L ROOT /dev/sda1
[root@linuxhost ~]#mkfs.reiserfs -l OSROOT /dev/sdb2
[root@linuxhost ~]#mkfs.xfs -L XFSROOT /dev/sde3
[root@linuxhost ~]#mkswap -L SWAP0 /dev/sdb5
|
- 在创建文件系统后给它添加一个标签。
1
2
3
| [root@linuxhost ~]#e2label /dev/sda1 PRIMARY_ROOT
[root@linuxhost ~]#reiserfstune -l OSROOT /dev/sdb2
[root@linuxhost ~]#xfs_admin -L DATA1 /dev/sdf4
|
- 在系统中使用标签。
- 编辑 Linux 系统的 /etc/fstab,这样系统将使用标签而非设备名称来装入文件系统。下面是 /etc/fstab 内容的简单示例:
1
2
3
4
| LABEL=ROOT / ext3 defaults 1 1
LABEL=BOOT /boot ext3 defaults 1 2
LABEL=SWAP swap swap defaults 0 0
LABEL=HOME /home ext3 nosuid,auto 1 2
|
- 编辑 Linux 引导加载程序的 grub.conf。
1
2
3
4
| title Linux
root (hd0,0)
kernel (hd0,0)/vmlinuz ro root=LABEL=ROOT rhgb quiet
initrd (hd0,0)/initrd-2.x.x-xx.img
|
使用 UUID
- 获得根设备的 UUID。让我们假定以下示例中的根文件系统位于 /dev/sda 磁盘设备中:
1
| [root@linuxhost ~]#scsi_id -g -s -u /block/sda
|
- 使用以下命令检查带有从第 1 步中得到的设备 UUID 的根文件系统设备的 ID。
1
| [root@linuxhost ~]#ls /dev/disk/by-id/<your device UUID>
|
- 在本例中,通过编辑 /etc/fstab 以在系统中使用 UUID:
1
| /dev/disk/by-id/scsi-<your uuid>-part2 / ext3 defaults 1 1
|
使用友好的设备名称
如果将设备映射程序多路径(DMMP)工具用于多路径存储,则可以将友好的名称用于根文件系统以避免设备在重新启动后被 DMMP 重新编号。
- 获得根设备的 UUID。让我们假定根文件系统位于 /dev/sda 磁盘设备中。
1
| [root@linuxhost ~]#scsi_id -g -s -u /block/sda
|
- 编辑 /etc/multipath.conf 以添加根文件系统设备的友好名称,如下所示:
1
2
3
4
5
6
| multipaths {
multipath {
wwid <your disk UUID get from above command>
alias OSROOT
}
}
|
- 然后,在重新引导系统或重新载入 DMMP 后,根文件系统设备将拥有诸如 /dev/mapper/OSROOT 之类的设备名称(如果根文件系统使用的是此磁盘的分区 3,则将拥有 /dev/mapper/OSROOT-part3 或 /dev/mapper/OSROOTp3 设备名称)。
- 编辑 /etc/fstab 以将此友好名称用于此根文件系统设备,如下所示:
1
| /dev/mapper/OSROOT-part3 / ext3 defaults 1 1
|
- 编辑 /etc/grub.conf 以在系统启动时使用此名称。
1
2
3
4
| title Linux
root (hd0,0)
kernel (hd0,0)/vmlinuz ro root=/dev/mapper/OSROOT-part3 rhgb quiet
initrd (hd0,0)/initrd-2.x.x-xx.img
|
- 此时,您已经完成了全部工作。您可以重新启动并查看它是否工作。
|
|
|
|
|
|