Heartbleed 更新后无法在 Ubuntu 12.04 上启动 ZFS 根目录

Heartbleed 更新后无法在 Ubuntu 12.04 上启动 ZFS 根目录

我执行了 apt-get update,然后升级以解决 heartbleed 漏洞。升级后我重新启动,但没有检查一切是否正常。现在我运气不太好。它正在启动并说它无法挂载文件系统 '-' 并将我置于 BusyBox shell 中。

好消息是,如果我从 LiveUSB 安装启动,我可以按照说明并执行 rpool 的 zpool 导入。这有效。但是,我尝试了 Ubuntu ZFS FAQ 中的基本操作,但仍然不太顺利。

我应该从 LiveCD 采取哪些步骤才能使系统运行而无需重新安装?

答案1

我使用优秀的 ZFS 操作指南此操作指南现已被替换,并有更新的操作指南推荐被关注

我启动了 Ubuntu 12.04 live usb 并使用了 HOWTO 第 1 步中的所有命令。

步骤 1:准备安装环境

1.1 启动 Ubuntu LiveCD 并在桌面打开终端。

1.2 在终端提示符下输入以下命令:

$ sudo -i
# apt-add-repository --yes ppa:zfs-native/stable
# apt-get update
# apt-get install debootstrap spl-dkms zfs-dkms ubuntu-zfs

1.3 检查ZFS文件系统是否已安装并可用:

# modprobe zfs
# dmesg | grep ZFS:
ZFS: Loaded module v0.6.3-2~trusty, ZFS pool version 5000, ZFS filesystem version 5

第 2 步:磁盘分区

本教程特意推荐 MBR 分区。也可以使用 GPT,但要注意 UEFI 固件错误。

2.1在主存储设备上 运行您最喜欢的磁盘分区程序,如parted或。是本文档中使用的示例设备。cfdisk/dev/disk/by-id/scsi-SATA_disk1

2.2 创建小的 MBR 主分区至少8 兆字节。除非空间紧张,否则 256mb 可能更现实。 /dev/disk/by-id/scsi-SATA_disk1-part1是本文档中使用的示例启动分区。

2.3 在这个第一个小分区上,设置type=BE并启用bootable标志。

2.4 创建大分区至少4 GB。 /dev/disk/by-id/scsi-SATA_disk1-part2是本文档中使用的示例系统分区。

2.5 在这个第二个大分区上,设置type=BF并禁用bootable标志。

分区表看起来应该是这样的:

 # fdisk -l /dev/disk/by-id/scsi-SATA_disk1

 Disk /dev/sda: 10.7 GB, 10737418240 bytes
 255 heads, 63 sectors/track, 1305 cylinders
 Units = cylinders of 16065 * 512 = 8225280 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk identifier: 0x00000000

 Device    Boot      Start         End      Blocks   Id  System
 /dev/sda1    *          1           1        8001   be  Solaris boot
 /dev/sda2               2        1305    10474380   bf  Solaris

记住:下面适当 替换scsi-SATA_disk1-part1和。scsi-SATA_disk1-part2

提示: * 您是在虚拟机中执行此操作吗?是否/dev/disk/by-id缺少了某些内容?请阅读故障排除部分。 * 最近的 GRUB 版本假定该/boot/grub/grubenv文件可由 stage2 模块写入。在 GRUB 获得 ZFS 写入增强功能之前,应将 GRUB 模块安装到 grub 可写入的单独分区中的单独文件系统中。 * 如果/boot/grub在 ZFS 文件系统中,则 GRUB 将无法启动并显示以下消息: 。如果您确实只想要一个文件系统,则删除每个菜单节中error: sparse file not allowed的调用,然后编辑文件以使更改永久生效。 * 或者,如果在 ZFS 文件系统中,您可以使用文件中的文本注释每一行并运行 update-grub。recordfail()grub.cfg/etc/grub.d/10_linux/boot/grubsave_env/etc/grub.d/00_header

步骤 3:磁盘格式化

3.1 将步骤 2.2 创建的小型启动分区格式化为具有 stage1 GRUB 支持的文件系统,如下所示:

 # mke2fs -m 0 -L /boot/grub -j /dev/disk/by-id/scsi-SATA_disk1-part1

3.2 在较大的分区上创建根池:

 # zpool create -o ashift=9 rpool /dev/disk/by-id/scsi-SATA_disk1-part2

始终对 ZFS 使用长别名 /dev/disk/by-id/*。直接使用 /dev/sd* 设备节点可能会导致偶尔的导入失败,尤其是在具有多个存储池的系统上。

警告:目前在 PPA 中为 Precise 发布的 grub2-1.99 包无法可靠地处理 4k 块大小ashift=12

提示: *# ls -la /dev/disk/by-id将列出别名。 * 根池可以是镜像。例如zpool create -o ashift=9 rpool mirror /dev/disk/by-id/scsi-SATA_disk1-part2 /dev/disk/by-id/scsi-SATA_disk2-part2。请记住,版本和 ashift 对于 GRUB 必须读取的任何池都很重要,并且这些内容在创建池后很难更改。 * 如果您使用如上所述的具有单独启动分区的镜像,请不要忘记编辑 grub.cfg 文件在第二个硬盘分区上这样“root=”分区也指第二个 HD 上的那个分区;否则,如果您丢失了第一个磁盘,您将无法从第二个磁盘启动,因为内核将继续尝试从第一个磁盘挂载根分区。 * 池名称是任意的。在可以自动安装到 ZFS 的系统上,根池默认命名为“rpool”。请注意,如果您选择一个唯一的名称而不是“rpool”,系统恢复会更容易。除了“rpool”或“tank”之外的任何名称(如主机名)都是不错的选择。 * 如果您想创建镜像但现在只有一个磁盘可用,您可以使用稀疏文件作为第二个成员来创建镜像,然后立即将其脱机,以便镜像处于降级模式。稍后您可以将另一个驱动器添加到线轴,ZFS 将自动同步它们。稀疏文件不会占用超过几 KB 的空间,因此它可以比您正在运行的系统更大。只需确保在写入池之前将稀疏文件脱机。

3.2.1 创建一个至少与硬盘上较大分区一样大的稀疏文件:

 # truncate -s 11g /tmp/sparsefile

3.2.2 不要使用第 3.2 节中的命令,而是使用以下命令来创建镜像:

 # zpool create -o ashift=9 rpool mirror /dev/disk/by-id/scsi-SATA_disk1-part2 /tmp/sparsefile

3.2.3 将稀疏文件离线。如果需要,您可以在此之后将其删除。

 # zpool offline rpool /tmp/sparsefile

3.2.4 验证池已创建并且现在已降级。

 # zpool list
 NAME       SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
 rpool     10.5G   188K  10.5G     0%  1.00x  DEGRADED  -

3.3 在根池中创建“ROOT”文件系统:

 # zfs create rpool/ROOT

3.4 为 Ubuntu 系统创建后代文件系统:

 # zfs create rpool/ROOT/ubuntu-1

pkg image-update在 Solaris 系统上,通过或克隆根文件系统并增加后缀以进行重大系统更改beadm。APT 也有类似的功能,但目前尚未实现。

3.5 卸载所有 ZFS 文件系统。

 # zfs umount -a

3.6mountpoint在根文件系统上设置属性:

 # zfs set mountpoint=/ rpool/ROOT/ubuntu-1

3.7 设置bootfs根池的属性。

 # zpool set bootfs=rpool/ROOT/ubuntu-1 rpool

引导加载程序使用这两个属性来查找和启动操作系统。这些属性名称是不是随意的。

暗示: 在内核命令行上放置rpool=MyPoolbootfs=MyPool/ROOT/system-1将覆盖 ZFS 属性。

3.9 导出池:

 # zpool export rpool

不要跳过此步骤。如果此命令失败或此时重新启动,系统将处于不一致状态。

(为了完整性,我已包括步骤 2 和步骤 3,但我跳过了它们,因为所有内容均已分区和格式化。)

然后我运行zpool list以验证没有加载任何池。(没有)然后我只执行了步骤 4.1

zpool import -d /dev/disk/by-id -R /mnt rpool

完整的步骤 4 如下

步骤4:系统安装

记住:用“rpool”替换步骤 3.2 中选择的名称。

4.1 导入池:

 # zpool import -d /dev/disk/by-id -R /mnt rpool

如果此操作失败并显示“无法导入‘rpool’:没有可用的池”,您可以尝试导入不带设备名称的池,例如:

     # zpool import -R /mnt rpool

4.2 挂载在步骤 3.1 中创建的 GRUB 的小型启动文件系统:

 # mkdir -p /mnt/boot/grub
 # mount /dev/disk/by-id/scsi-SATA_disk1-part1 /mnt/boot/grub

4.4 安装最小系统:

 # debootstrap trusty /mnt

debootstrap命令使新系统处于未配置状态。在步骤 5 中,我们将仅执行使新系统可运行所需的最少配置。

然后我检查了一下ls -al /mnt以确保它看起来没问题。

然后我跳到步骤 5.4。是时候chroot进入导入的 rpool 了。

# mount --bind /dev  /mnt/dev
# mount --bind /proc /mnt/proc
# mount --bind /sys  /mnt/sys
# chroot /mnt /bin/bash --login

目前,我们已处于修复系统的适当状态。

完整的第 5 步是

步骤5:系统配置

5.1 将这些文件从LiveCD环境复制到新系统:

 # cp /etc/hostname /mnt/etc/
 # cp /etc/hosts /mnt/etc/

5.2 该/mnt/etc/fstab文件除了注释外应为空。将以下行添加到文件/mnt/etc/fstab

 /dev/disk/by-id/scsi-SATA_disk1-part1  /boot/grub  auto  defaults  0  1

常规 Ubuntu 桌面安装程序可能会向文件中添加devprocsystmp/etc/fstab,但此类条目在具有 文件的系统上是多余的/lib/init/fstab。如果您需要它们,请立即添加。

5.3 编辑/mnt/etc/network/interfaces文件,使其包含如下内容:

 # interfaces(5) file used by ifup(8) and ifdown(8)
 auto lo
 iface lo inet loopback

 auto eth0
 iface eth0 inet dhcp

如果新系统不是 LAN 上的 DHCP 客户端,请自定义此文件。

5.4 使 LiveCD 环境中的虚拟文件系统对新系统可见并chroot进入其中:

 # mount --bind /dev  /mnt/dev
 # mount --bind /proc /mnt/proc
 # mount --bind /sys  /mnt/sys
 # chroot /mnt /bin/bash --login

5.5 在 chroot 环境中安装 PPA 支持,如下所示:

 # locale-gen en_US.UTF-8
 # apt-get update
 # apt-get install ubuntu-minimal software-properties-common

即使您更喜欢非英语系统语言,也请始终确保 en_US.UTF-8 可用。使用 PPA 中打包的 ZoL 需要 ubuntu-minimal 包。

5.6 在新系统的 chroot 环境中安装 ZFS:

 # apt-add-repository --yes ppa:zfs-native/stable
 # apt-add-repository --yes ppa:zfs-native/grub
 # apt-get update
 # apt-get install --no-install-recommends linux-image-generic linux-headers-generic
 # apt-get install ubuntu-zfs
 # apt-get install grub2-common grub-pc
 # apt-get install zfs-initramfs
 # apt-get dist-upgrade

警告:这是您第二次必须等待 SPL 和 ZFS 模块编译。 不要尝试通过将任何内容从主机环境复制到 chroot 环境来跳过此步骤。

笔记:这应该会安装一个内核包及其头文件、一个修补过的 mountall 和 dkms 包。如果您在任何方面偏离了这些说明,请仔细检查您是否从 PPA 获取了这些包。

/dev/disk/by-id/scsi-SATA_disk1如果提示安装 MBR 加载程序,请选择安装。

忽略由 chroot 环境引起的警告,例如:

  • Can not write log, openpty() failed (/dev/pts not mounted?)
  • df: Warning: cannot read table of mounted file systems
  • mtab is not present at /etc/mtab.

    5.7 在新系统上设置root密码:

    # 密码 root

    暗示:如果您想要 ubuntu-desktop 包,请在第一次重启后安装它。如果您现在安装它,那么它将启动几个进程,必须在卸载之前手动停止这些进程。

步骤6:GRUB 安装

记住:所有步骤 6 都依赖于步骤 5.4,并且必须在 chroot 环境中进行。

6.1 验证 ZFS 根文件系统是否被 GRUB 识别:

 # grub-probe /
 zfs

并且已安装 GRUB 的 ZFS 模块:

 # ls /boot/grub/zfs*
 /boot/grub/zfs.mod  /boot/grub/zfsinfo.mod

请注意,在 Ubuntu 13 之后,这些现在位于 /boot/grub/i386/pc/zfs*

 # ls /boot/grub/i386-pc/zfs*
 /boot/grub/i386-pc/zfs.mod  /boot/grub/i386-pc/zfsinfo.mod

否则,请查看下面有关 GRUB 的故障排除说明。

6.2刷新initrd文件:

 # update-initramfs -c -k all
 update-initramfs: Generating /boot/initrd.img-3.2.0-40-generic

6.3更新启动配置文件:

 # update-grub
 Generating grub.cfg ...
 Found linux image: /boot/vmlinuz-3.2.0-40-generic
 Found initrd image: /boot/initrd.img-3.2.0-40-generic
 done

验证boot=zfs启动配置文件中是否出现:

 # grep boot=zfs /boot/grub/grub.cfg
 linux /ROOT/ubuntu-1/@/boot/vmlinuz-3.2.0-40-generic root=/dev/sda2 ro boot=zfs $bootfs quiet splash $vt_handoff
 linux /ROOT/ubuntu-1/@/boot/vmlinuz-3.2.0-40-generic root=/dev/sda2 ro single nomodeset boot=zfs $bootfs

6.4 将引导加载程序安装到 MBR,如下所示:

 # grub-install $(readlink -f /dev/disk/by-id/scsi-SATA_disk1)
 Installation finished. No error reported.

直到您收到确切的结果消息之前,请勿重新启动计算机。请注意,您正在将加载程序安装到整个磁盘,而不是分区。

笔记:需要 readlink,因为最近的 GRUB 版本不会取消引用符号链接。

步骤 7:清理并首次重启

7.1 退出chroot环境回到LiveCD环境:

 # exit

7.2 在 LiveCD 环境中运行这些命令来卸载所有文件系统:

 # umount /mnt/boot/grub
 # umount /mnt/dev
 # umount /mnt/proc
 # umount /mnt/sys
 # zfs umount -a
 # zpool export rpool

zpool export命令必须成功执行,不能强制执行,否则新系统将无法启动。

7.3 完成了!

 # reboot

在第 6 步之前,我尝试执行上述所有步骤,无需修改。正如预期的那样,系统仍然无法工作。(这里的想法是,这是一个简单的 zpool.cache 问题。)

在另一次尝试中,我重新执行了 apt-get update 和 upgrade。我突然灵光一闪,于是做了:

# apt-get dist-upgrade

当我修补 heartbleed 时,我只是做了一个apt-get upgrade。dist-upgrade 甚至会安装通常被阻止的软件包(如内核)。这个小错误可能是导致这一切的原因。无论如何,在 dist-upgrade 成功后,我一些成功。系统将启动并进入网络启动状态,我可以尝试 ssh 登录。但是,我无法进入我的帐户。

此时,我的理论是“大”池没有被导入和挂载。该池有我的主目录。挂载时出现任何问题都会阻止我登录。

我认为我可能有足够的系统可以解决这个问题。我尝试通过“grub”菜单启动恢复内核。当我选择恢复内核时,我从未得到正确的 grub 恢复菜单或 shell。系统将启动并加载内核 + 模块,但随后它会挂起。然后我重新启动并编辑 grub 启动命令。我添加了一个“1”以进入单用户模式。结果相同,没有 shell。我再次在启动时编辑 grub 命令。我更改了ro->rw并添加了init=/bin/bash。然后我启动并进入 shell。我不记得此时是否导入/安装了“rpool”。要么是 rpool 已安装,要么是我安装了它。然后我注意到我的大池没有安装,但我不确定它是否会在这个阶段安装。

然后我导入了我的大池。在我的“大”池上,我还有一个 zfs 挂载点/var/cache。由于挂载点不为空,它抱怨。然后我清除了旧的/var/cache并重新挂载。一切正常,看起来不错。然而,像个傻瓜一样,我按下 CTRL-D 退出 shell,内核立即崩溃了……(正如预期的那样)。哎呀!我现在以为系统没有正确同步到磁盘,我必须从上次启动开始重做一切。

我重启了系统,没有编辑启动参数,系统看起来运行正常。我尝试再次 ssh 登录……成功了!哇!我想同步的信息足以让系统恢复。

我重新启动以验证系统是否会再次启动。我还验证了 apt-get update 是否完全更新。我还验证了 OpenSSL 是否已打补丁。所有这一切都很好。在最后一次重新启动检查后,我按照常规 zfs 备份到另一个系统。

那么,为什么它会起作用呢?dist-upgrade 肯定存在一个自身造成的问题。为什么“大”池无法挂载?不确定。我没有重做 RAM 磁盘中的 zpool.cache。我怀疑这只是“大”池无法正确导入和挂载的问题。

相关内容