我执行了 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/grub
save_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.6
mountpoint
在根文件系统上设置属性:# zfs set mountpoint=/ rpool/ROOT/ubuntu-1
3.7 设置
bootfs
根池的属性。# zpool set bootfs=rpool/ROOT/ubuntu-1 rpool
引导加载程序使用这两个属性来查找和启动操作系统。这些属性名称是不是随意的。
暗示: 在内核命令行上放置
rpool=MyPool
或bootfs=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 桌面安装程序可能会向文件中添加
dev
、proc
、sys
或tmp
行/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。我怀疑这只是“大”池无法正确导入和挂载的问题。