![使用 LVM 将 MBR/BIOS RAID 1 根分区迁移到 GPT/UEFI](https://linux22.com/image/1067647/%E4%BD%BF%E7%94%A8%20LVM%20%E5%B0%86%20MBR%2FBIOS%20RAID%201%20%E6%A0%B9%E5%88%86%E5%8C%BA%E8%BF%81%E7%A7%BB%E5%88%B0%20GPT%2FUEFI.png)
我已经思考了一段时间,并搜索了各种帖子,但找不到与我的情况相符的内容。
我目前在 RAID 1 中的几块 SSD 上运行 18.04.3 LTS(以及在一堆 HDD 上带有 LVM 的单独数据 RAID 6)。几年前我设置了这个(当时使用 14.04 LTS),当时我的主板仅支持 MBR/BIOS。
从那时起,我已将主板升级为支持 UEFI 的主板。现在我正准备升级 SSD(更大的 M.2 单元)。
我一直在考虑:除了维持当前设置并更换 SSD 之外,我还在考虑:
- 将设置更改为 GPT/UEFI,以及
- 在 RAID 1 上安装 LVM。
我正在尝试找出实现上述任一或两项操作的最佳方法。我曾考虑过在新的 SSD 上进行全新安装(这种方法很有吸引力,可以摆脱多年来积累的垃圾),但一想到要重新配置所有内容(有很多……),我就不寒而栗。
还有其他方法吗?
关于迁移到 GPT/UEFI,我研究过这样做的可能性就地类似于Boot-Repair
。我考虑的另一个选择是使用我想要的方案对新 SSD 进行分区(简单的 EFI 启动分区和根分区),然后依次将它们引入阵列 - 有点像这。
但是我不完全清楚这两种方法是否可行,例如是否可以Boot-Repair
在不破坏数据的情况下修改实时系统(并且是否会在磁盘启动时插入 EFI 启动分区mdadm
),以及如果我不重新安装操作系统,如何在手动创建的 EFI 启动分区上安装 EFI 引导加载程序?
至于在现有 RAID 1 上安装 LVM 的问题,我正在努力思考如何实现。
一些当前设置(就相关而言 - 我已经删除了多余的信息)以供进一步了解:
$ cat /proc/mdstat
md1 : active raid1 sdg5[2] sdh5[3]
16757632 blocks super 1.2 [2/2] [UU]
md0 : active raid1 sdg1[2] sdh1[3]
100386688 blocks super 1.2 [2/2] [UU]
和:
$ sudo fdisk -l
Disk /dev/sdg: 111.8 GiB, 120034123776 bytes, 234441648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0001cb75
Device Boot Start End Sectors Size Id Type
/dev/sdg1 * 2048 200906751 200904704 95.8G fd Linux RAID autodetect
/dev/sdg2 200908798 234440703 33531906 16G 5 Extended
/dev/sdg5 200908800 234440703 33531904 16G fd Linux RAID autodetect
Disk /dev/sdh: 111.8 GiB, 120034123776 bytes, 234441648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disklabel type: dos
Disk identifier: 0x0001cb75
Device Boot Start End Sectors Size Id Type
/dev/sdh1 * 2048 200906751 200904704 95.8G fd Linux RAID autodetect
/dev/sdh2 200908798 234440703 33531906 16G 5 Extended
/dev/sdh5 200908800 234440703 33531904 16G fd Linux RAID autodetect
/dev/md0
安装在根目录(ext4)上,并被/dev/md1
分配为交换分区。
如果我能够将系统转换为 LVM,我会取消物理交换分区,只创建一个 LVM 交换分区。我认为这也可能有助于迁移过程,因为它会释放当前 SSD 上的一些空间。
有什么想法吗?谢谢。
答案1
好吧,尽管尝试了几次,我还是设法完成了这次迁移。
方法总结
我最终没有采用我最初考虑的任何方法。相反,我的方法包括:
- 在新的 SSD 上创建新的分区方案(EFI 启动分区加上根分区)
- 在 EFI 启动分区上安装 UEFI 引导加载程序
- 在根分区上创建 RAID 1 阵列
- 使用 RAID 1 阵列创建 LVM 物理卷,并使用该卷创建 LVM 卷组
- 在该卷组上创建 LVM 根逻辑卷
- 将根分区的内容从旧 SSD 复制到新 SSD
- 在 RAID 1 阵列上的卷组上创建 LVM 交换逻辑卷
- 整理
我的第一次尝试是手动创建分区并在这些分区上手动安装 UEFI 引导加载程序。经过几次小失误后,最终在新的 SSD 上获得了可启动的系统,但使用了错误的引导加载程序(后备BOOTX64.EFI
而不是 Ubuntugrubx64.efi
或shimx64.efi
引导加载程序)。
我可能可以通过执行下面的第 27 步来解决这个问题,但这是我在第二次尝试时才发现的。但现在请看这个答案的附录。
所以我重新开始了整个过程。
第二次尝试是使用 Ubuntu Live USB 在新的 SSD 之一上执行全新安装(使用我的新分区方案,但没有 RAID 或 LVM)。我认为这将为我提供一个反映 Ubuntu 默认设置(大小、内容)的 EFI 启动分区。
这种方法还使我有机会注意到默认安装包含哪些参数/etc/fstab
,以便我可以在我的新安装上正确地复制这些参数。
Ubuntu Live USB 完成默认安装后,我将 EFI 启动分区复制到另一个 SSD。然后,我删除了已安装的根分区并将其替换为新分区,以擦除已安装的操作系统。然后,我将该分区复制到另一个 SSD 上,并继续执行其余步骤(创建 RAID 阵列等)。
正如您所看到的,这导致系统最初无法启动,但我设法将其挽救回来,grub
现在一切都正常。
请继续阅读详细步骤。我必须承认,在某种程度上,这些步骤是我所做工作的重构,因为在此过程中我做了一些小改动,但从根本上讲,我下面概述的内容准确反映了我所做工作的实质。
参考
在准备和实施我的两次尝试时,我参考了一些教程,特别是:
- 在具有 UEFI BIOS 的机器上安装具有 RAID 1 和 LVM 的 Ubuntu 18.04 桌面
- 如何在 UEFI/GPT 系统上安装具有双启动 RAID 1 分区的 Ubuntu 14.04/16.04 64 位?
- 哪些命令可以在单启动硬件上将 Ubuntu BIOS 安装转换为 EFI/UEFI 而无需启动修复?
- https://serverfault.com/questions/963178/how-do-i-convert-my-linux-disk-from-mbr-to-gpt-with-uefi
- https://www.linux.com/tutorials/how-rescue-non-booting-grub-2-linux/
没有一个完全符合我的用例,并且概述的一些步骤实际上给我带来了问题,但它们确实在各个方面提供了帮助。
所有细节
设置场景:
- 我安装的是 Ubuntu 18.04.3 LTS
- 我的旧安装已打开
/dev/md0
,并打开了交换分区/dev/md1
,均在我的旧 SSD 上 - 我在单独的 HDD 上还有一个 RAID 6 数据阵列 (
/dev/md2
),我想在新安装时保留它们 - 我的新 SSD
/dev/nvme0n1
是/dev/nvme1n1
现在来看看步骤:
步骤1
我实际上并没有执行这第一步,但事后看来,它可能有所帮助。它涉及准备我的旧 Ubuntu 安装(我最终会复制的那个),安装一些在 UEFI 下运行时需要的软件包。因此,当启动到我的旧安装时:
$ sudo apt-get update
$ sudo apt-get install grub-efi-amd64 efibootmgr
第2步
在继续操作之前,我禁用了旧安装上的交换分区,只是为了避免在复制根分区内容时保留任何旧设置。我不确定这是否会是一个实际问题,但想确定一下:
$ sudo swapoff /dev/md1
然后我/etc/fstab
在我最喜欢的文本编辑器中更新以注释掉交换条目,然后:
$ sudo mount -a
步骤3
然后我以 UEFI 模式启动 Ubuntu Live USB(桌面版,而不是服务器版,尽管我安装的是服务器版),并选择“安装 Ubuntu”。您可能需要调整主板固件设置以确保以 UEFI 模式启动。
我想我也可以使用服务器版本来完成这一步,但考虑到我需要桌面版本来完成后面的步骤,我决定保持简单。
我选择了引导式安装,选择使用我的第一个新 SSD(/dev/nvme0n1
)并使用整个驱动器进行安装。我没有设置 RAID 或 LVM。这导致 (a) 一个 EFI 启动分区,以及 (b) 一个根分区,占用了驱动器的其余部分,Ubuntu Desktop 安装在该分区上。
步骤4
完成后,我以 UEFI 模式重新启动进入 Ubuntu Live USB,这次选择“尝试不安装 Ubuntu”。您可以通过打开终端(Ctrl-Alt-T)并运行来测试您是否处于 UEFI 模式:
$ ls /sys/firmware/efi
如果显示多个文件,则表示您处于 UEFI 模式。
步骤5
在终端提示符下,我升级了 Ubuntu Live 并安装了所需的软件包:
$ sudo apt-get update && sudo apt-get dist-upgrade
$ sudo apt-get install -y mdadm
第 6 步
然后,我检查了新安装的分区方案,以便可以正确地将其复制到另一个 SSD 上:
$ sudo parted /dev/nvme0n1
(parted) unit MiB print
Model: Samsung SSD 970 EVO Plus 500GB (nvme)
Disk /dev/nvme0n1: 476940MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1.00MiB 513MiB 512MiB fat32 EFI System Partition boot, esp
2 513MiB 476939MiB 476426MiB ext4
(parted) quit
这表明默认的 EFI 分区大小为 512 MiB,从驱动器开头 1 MiB 开始,采用 FAT32 文件系统。
步骤7
然后,我还检查了默认挂载参数/etc/fstab
(下面的 UUID 被屏蔽为“NUMBER”):
$ sudo mkdir -p /mnt/newroot
$ sudo mount /dev/nvme0n1p2 /mnt/newroot
$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
## / was on /dev/nvme0n1p2 during installation
UUID=NUMBER / ext4 errors=remount-ro 0 1
# /boot/efi was on /dev/nvme0n1p1 during installation
UUID=NUMBER /boot/efi vfat umask=0077 0 1
/swapfile none swap sw 0 0
$ sudo umount /mnt/newroot
我记下了这些参数,以便稍后可以复制它们。
步骤8
然后,我删除了第一个 SSD 上已安装的根分区,以删除桌面安装,并在其位置创建一个新分区(大小相同)。请注意,我没有使用任何文件系统类型创建它,因为 RAID 阵列和 LVM 卷组将覆盖在上面:
$ sudo parted -a optimal /dev/nvme0n1
(parted) rm
Partition number? 2
(parted) mkpart primary 513MiB 100%
(parted) name 2 "Ubuntu Filesystem"
(parted) align-check optimal 2
(parted) set 2 raid on
步骤9
当仍然处于 parted 交互式提示中时,我选择了另一个新的 SSD(/dev/nvme1n1
)来复制分区方案:
(parted) select /dev/nvme1n1
(parted) mklabel gpt
(parted) mkpart primary fat32 1MiB 513MiB
(parted) set 1 esp on
(parted) set 1 boot on
(parted) mkpart primary 513MiB 100%
(parted) name 2 "Ubuntu Filesystem"
(parted) align-check optimal 2
(parted) set 2 raid on
(parted) unit MiB print
Model: Samsung SSD 970 EVO Plus 500GB (nvme)
Disk /dev/nvme1n1: 476940MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1.00MiB 513MiB 512MiB fat32 EFI System Partition boot, esp
2 513MiB 476939MiB 476426MiB ext4 Ubuntu Filesystem raid
(parted) quit
第 10 步
然后我在根分区上创建了一个 RAID 1 阵列,/dev/nvme0n1p2
并且/dev/nvme1n1p2
。我将其命名/dev/md3
为 ,以区别于我的旧系统下已经创建的 RAID 阵列,并避免在迁移过程中发生命名冲突,目的是在新系统启动并运行时稍后重命名它:
$ sudo mdadm --create --bitmap=internal /dev/md3 --level=1 --raid-devices=2 /dev/nvme0n1p2 /dev/nvme1n1p2
我等到 RAID 阵列完成同步后再继续,通过检查:
$ cat /proc/mdstat
步骤11
然后,我在 RAID 1 阵列之外创建了一个 LVM 物理卷,并vgmain
使用该物理卷创建了一个卷组(称为),然后在该卷组上创建了一个 LVM 根逻辑卷(称为lvroot
和 ,大小为 100 GiB):
$ sudo pvcreate /dev/md3
$ sudo vgcreate vgmain /dev/md3
$ sudo lvcreate -L 100G -n lvroot vgmain
步骤12
然后我在根逻辑卷上创建了一个 EXT4 文件系统:
$ sudo mkfs.ext4 -b 4096 -E stride=128,stripe-width=256 /dev/vgmain/lvroot
步骤13
此时,我组装了旧的 RAID 设备,以便我的旧根分区 ( /dev/md0
) 可用于复制数据。显然,要做到这一点,我的旧 SSD 仍然必须连接并通电:
$ sudo mdadm --assemble --scan
步骤14
组装完成后,我安装了旧的根分区:
$ sudo mkdir -p /mnt/oldroot
$ sudo mount /dev/md0 /mnt/oldroot
步骤15
我还挂载了新的根分区(记住挂载点之前已在步骤 7 中创建):
$ sudo mount /dev/vgmain/lvroot /mnt/newroot
步骤16
现在我可以将旧根分区的内容复制到新分区:
$ sudo rsync -axHAX --progress /mnt/oldroot/ /mnt/newroot
步骤17
一旦完成后,就可以卸载旧的根分区并停止旧的 RAID 阵列:
$ sudo umount /mnt/oldroot
$ sudo mdadm --stop /dev/md0
步骤18
现在说点题外话。事后看来,如果我当时执行了第 27 步,我最后遇到的启动问题可能就可以避免。为此,我会执行以下操作:
$ sudo mkdir -p /mnt/newroot/boot/efi
$ sudo mount /dev/nvme0n1p1 /mnt/newroot/boot/efi
$ for d in /dev /dev/pts /sys /proc; do sudo mount -B $d /mnt/newroot$d; done
$ sudo chroot /mnt/newroot
# grub-install
# update-grub
# umount /dev/nvme0n1p1
我不确定这是否能解决后来遇到的问题,但问题已经解决了。但现在请看这个答案的附录。
步骤19
回到我实际做的事情。将旧根分区的内容复制到新根分区(当然,在 RAID 1 阵列中是镜像的)后,我需要将 EFI 启动分区的内容从第一个 SSD 复制到第二个 SSD:
$ sudo dd if=/dev/nvme0n1p1 of=/dev/nvme1n1p1
为了检查这是否成功,我检查了完成后每个上的 UUID 是否相同:
$ sudo blkid
步骤20
为了完整性,我还想将第二个 SSD 放入启动链中,以确保我可以从任一 SSD 顺利启动。此时,新的根分区仍处于挂载状态,但我还需要从 Ubuntu Live USB 挂载其他目录(如果我实施了第 18 步,我就不必在这里挂载这些目录了):
$ for d in /dev /dev/pts /sys /proc; do sudo mount -B $d /mnt/newroot$d; done
$ sudo chroot /mnt/newroot
# efibootmgr -v
## Comment: The above command showed me the file entry for "ubuntu", which in my case was
## \EFI\ubuntu\grubx64.efi (I could have also used \EFI\ubuntu\shimx64.efi).
## I then used that in the next command
# efibootmgr -c -d /dev/nvme1n1 -p 1 -L ubuntu -l '\EFI\ubuntu\grubx64.efi'
显然,对新 SSD 的影响chroot
是,我进入该环境就像启动它一样,因此我在 jail 中运行的命令是在 SSD 上执行的,而不是在 Ubuntu Live USB 上执行的。在 jail 中chroot
,命令以 root 身份运行(如“#”提示符所示),因此sudo
不需要。当然,鉴于 SSD 实际上并未启动,我必须从 Ubuntu Live USB 安装一些关键目录才能获得所需的功能。
(顺便说一句,我必须指出,由于我实际上没有完成第 1 步,当我尝试运行时,efibootmgr
我发现它没有安装,因为我已经复制了我的旧安装,即 MBR/BIOS 安装。所以我必须在此阶段安装它。为此,我发现我还需要/run
从 Ubuntu Live USB 安装,以便我可以访问互联网。我还安装了grub-efi-amd64
。)
步骤21
我还通过检查 返回的详细信息检查了启动顺序是否正确,即/dev/nvme0n1p1
启动链中的第一个是哪个,第二个是哪个。如有必要,可以通过按要求的顺序运行以下命令并使用每个相关磁盘或分区的 4 位代码来修复顺序,例如:/dev/nvme1n1p1
efibootmgr -v
# efibootmgr -o 0000,0001,0002,0005,0004
步骤22
然后,我/etc/fstab
用我最喜欢的文本编辑器进行了更新,以包含根挂载点和/boot/efi
挂载点(从中确定blkid
)的新 UUID。我使用了步骤 7 中的参数,添加noatime
到根挂载点(与我的旧安装一致)。
当然,我保留了旧数据 RAID 6 阵列的挂载点条目,因为它将继续用于新安装,以及固定挂载点/tmp
。
步骤23
新 SSD 上的 mdadm 配置详细信息也需要更新,我通过/dev/md3
以下命令添加新阵列的详细信息,然后/etc/mdadm/mdadm.conf
使用文本编辑器手动编辑以确保删除旧的遗留/dev/md0
条目/dev/md1
:
# mdadm --examine --scan >> /etc/mdadm/mdadm.conf
清理配置文件后,我运行:
# update-initramfs -u
步骤24
此时我基本上已经完成了(或者我是这么认为的)。因此,为了干净利落地完成,我退出chroot
并卸载了所有内容:
# exit
$ for d in /dev /dev/pts /sys /proc; do sudo umount /mnt/newroot$d; done
$ sudo umount /mnt/newroot
步骤25
最后,关键时刻到了——我移除了 Ubuntu Live USB,然后重启了系统,检查主板固件,发现启动顺序中第一个新 SSD 位于最顶部,这样我就可以从 启动了/dev/nvme0n1p1
。如有必要,您可以在启动时通过运行 来检查从哪个驱动器启动efibootmgr -v
。
步骤26
不过,此时,我遇到了启动问题。系统无法启动,并在提示符处停止grub
。为了解决这个问题,我在提示符下执行以下操作:
grub> ls
## Comment: The above command showed me the available partitions and directories, so I knew
## what my root partition was called and could use it in the next command
grub> set root=(lvm/vgmain-lvroot)
grub> linux /vmlinuz root=/dev/mapper/vgmain-lvroot
grub> initrd /initrd.img
grub> boot
步骤27
执行此操作后,我启动了新的 SSD。此时,我运行了以下命令,如果我在第 18 步执行了这些操作,则可能不需要执行这些操作:
$ sudo grub-install
$ sudo update-grub
我发现运行这些命令后, 的大小grubx64.efi
发生/boot/efi/EFI/ubuntu
了变化,因此看起来原始引导加载程序安装存在问题。但现在请看此答案的附录。
步骤28
然后,我重复了步骤 19 和 20 中的相关命令,将更新后的 EFI 启动分区的内容从 复制/dev/nvme0n1p1
到/dev/nvme1n1p1
,并更新启动链。如果您发现还有需要删除的旧条目,请使用:
$ sudo efibootmgr -b 0003 -B # Eg to delete entry Boot0003
步骤29
最后,我重新创建了交换分区,这次作为 LVM 逻辑卷:
$ sudo lvcreate -L 16G -n lvswap vgmain
$ sudo mkswap /dev/vgmain/lvswap
$ sudo swapon /dev/vgmain/lvswap
并/etc/fstab
使用相关UUID和步骤7中确定的参数进行更新:
UUID=NUMBER none swap sw 0 0
就是这样!我现在有一个完全迁移并正常运行的系统。我最终会将我的新 RAID 1 重命名为md0
(仅出于强迫症原因),但那是另一回事了。
附录
第 1 项
在尝试迁移之前,我学习的准备教程说,在开始之前应该在主板固件上禁用安全启动。我没有这么做,因为我发现我的主板(华硕)很难做到这一点(后来我研究了一下,发现可以通过删除安全启动键来实现)。我的启动问题可能是由于安全启动仍然有效而引起的。
第 2 项
您会发现,在 UEFI 模式下启动迁移的系统时,它会在 grub 菜单处暂停 30 秒,然后继续。这显然是为了让用户有时间访问菜单,因为在某些情况下,否则菜单可能无法访问。如果您对启动时间的额外延迟感到烦恼,可以通过将以下内容添加到 来减少这种情况/etc/default/grub
:
GRUB_RECORDFAIL_TIMEOUT=5 # Eg to reduce to five seconds
不要将其减少到零。然后:
$ sudo update-grub