一、前言

家里的NAS是用之前的旧笔记本改装来的,系统用的是openSUSE。装系统的时候脑子有点抽,把根文件系统放在了raid0上面,其中一块raid0的盘还是用usb3.0的接口。不知道什么原因raid0有点不稳定,运行几天或者几周之后就会随机发生掉盘的现象(可能是因为usb的缘故吧)。正好本子里面还有一个m.2的sata接口,索性买了一块64G的固态作为系统盘,把根分区迁移至固态得了。

二、准备工作

  • 一块新硬盘
  • 一个LiveCD(一切顺利的情况下不会用到它,防止迁移后无法正常启动的系统修复)

三、系统迁移

1.插入新硬盘,开机进入原系统的rescue(恢复)模式

要做根文件系统的复制,必须要在恢复模式下进行。而且之前的根文件系统是在raid0上面,用liveCD的话还得重新构建raid信息,所以选择进入原系统的恢复模式(在grub的引导菜单中选择恢复模式就行了)。

2.新硬盘分区

# 分区前硬盘信息
## 新硬盘
@rescue:/> fdisk /dev/sdb -l
Disk /dev/sdb: 59.6 GiB, 64023257088 bytes, 125045424 sectors
Disk model: KINGBANK KM100
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: 
Disk identifier: 4C1B4020-EC25-5341-9146-BECB2130840B
 
Device      Start      End  Sectors  Size Type
 
## 既存raid0
@rescue:/> fdisk /dev/md0 -l
Disk /dev/md0: 1.8 TiB, 1999777038336 bytes, 3905814528 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 1048576 bytes / 2097152 bytes
Disklabel type: gpt
Disk identifier: 1C4041DA-1993-4CB5-A393-DA075D2BCA38
 
Device        Start        End    Sectors  Size Type
/dev/md0p1 2048 42559487 4132,640 20G Linux filesystem
/dev/md0p2 41947136 3905290206 3863343071  1.8T Linux filesystem
 
# 使用fdisk /dev/sdb进行分区、格式化,过程跳过,根据提示输入命令即可
## 分区后硬盘信息
@rescue:/> fdisk /dev/sdb -l
Disk /dev/sdb: 59.6 GiB, 64023257088 bytes, 125045424 sectors
Disk model: KINGBANK KM100
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: gpt
Disk identifier: 4C1B4020-EC25-5341-9146-BECB2130840B
 
Device      Start      End  Sectors  Size Type
/dev/sdb1    2048   616447   614400  300M EFI System
/dev/sdb2  616448 42559487 41943040   20G Linux filesystem
 
# 备注:对于原来的分区,建议在分区拷贝之后将UUID覆盖掉,避免影响后续的启动。不过后续的启动你也可以选择拔掉旧硬盘。

3.根文件系统迁移

建议使用dd命令进行磁盘分区的拷贝,因为可以保留原分区的UUID,这样可以把系统引导修复所需要修改的地方降低到最少。

# 拷贝原/boot/efi分区
@rescue:/> dd if=/dev/sda1 of=/dev/sdb1
# 拷贝原根分区
@rescue:/> dd if=/dev/md0p1 of=/dev/sda2

4.修复引导

# 挂载新的文件系统,并将新的grub引导安装至新硬盘
@rescue:/> mkdir /chroot
## 备注:准备chroot的挂载点的时候最好不要使用/mnt /tmp等系统的临时文件目录,本人在修改时出现了grub引导安装失败的情况,更换挂载点后才成功。
@rescue:/> mount /dev/sdb2 /chroot
@rescue:/> mount /dev/sdb1 /chroot/boot/efi
@rescue:/> mount -t proc proc /chroot/proc
@rescue:/> mount --rbind /sys /chroot/sys
@rescue:/> mount --rbind /dev /chroot/dev
# 切换chroot目录
@rescue:/> chroot /chroot
# 检查efi启动项
/:> efibootmgr
BootCurrent: 0000
Timeout: 2 seconds
BootOrder: 0000,2001
Boot0000* opensuse
Boot2001* EFI USB Device
# 新硬盘安装grub引导
/:> grub2-mkconfig -o /boot/grub2/grub2.cfg
/:> grub2-install /dev/sdb
···
# 验证efi启动项安装成功
/:> efibootmgr
BootCurrent: 0000
Timeout: 2 seconds
BootOrder: 0000,0001,2001
Boot0000* opensuse
Boot0001* opensuse
Boot2001* EFI USB Device
 
# 备注:关于引导修复最关键的地方也在这里,本人用的openSUSE使用的是grub2-install命令,其它发行版根据实际情况决定,如Ubuntu则应该是update-grub。同时,更新grub后请一定确认efi启动项添加成功。

5.重启,验证新硬盘能否正常引导

重启的时候如果旧文件系统的UUID没有覆盖掉的话最好拔掉旧硬盘,避免启动之后根文件系统依旧挂在到旧硬盘。其实没有覆盖掉的话也不会影响启动,只是如果挂载到了旧硬盘你就无法释放原来旧硬盘的分区了。

如果出现grub无法引导的情况,请用liveCD进行救急,进入恢复模式重复第四步。本人就出现过N次grub引导安装失败的情况。重启前确认了efi的启动项已经添加成功但是就是没法引导,liveCD进入后查看efi启动项,不过添加的东西不翼而飞。最后更换了chroot的挂载点才成功(之前图简单直接将chroot的挂载点放在了/mnt下面)。