前言

欢迎阅读鲸落重建计划的第一篇文章!这篇教程将教你如何使用rsync之类的工具将你的Linux系统从一块硬盘迁移到另一块硬盘上

起因在我的鲸落重建计划的序章里:

在维修我初中时代的笔记本后,我成功拿到了这块笔记本的硬盘。这块硬盘被当时的我安装Windows和Ubuntu20.04LTS双系统,虽然可以正常启动,但是希捷笔记本酷鱼1T叠瓦盘这几个因素叠起来,想必在这个笔记本硬盘上并不会有太好的体验鬼知道我初中是怎么用下去的,为了将初中搭建的Wordpress和写的博客恢复出来,我决定将里面的系统从那块笔记本迁移出来

Windows的迁移几乎没有难度,你只需要打开DiskGenius硬碟鬼才选择工具——>系统迁移,然后选择源硬盘和目标硬盘的分区,迁移完毕后创建一个ESP分区后使用Dism++重建引导就可以了。可是到了Ubuntu这里犯了难,我们要怎么把ext4/btrfs/zfs文件系统里的文件拷贝到新硬盘上,怎么保证拷贝过去的文件权限正确,拷贝过去后怎么重建GRUB引导?在试错了无数次后,我成功将Ubuntu迁移到了新固态上,接下来,让我们开始吧!

迁移系统分区

不要脸但方便快捷的迁移方法

如果你的原系统正好是安装在EXT4文件系统上的,那恭喜,你只需要一台可以正常启动的Windows电脑和DiskGenius就可以完成迁移分区这个操作!

很不幸,如果你没有安装Windows系统或者你的文件系统不是EXT4而是Btrfs、ZFS之类的或者你就是想要在Linux下用命令行迁移显得装B中二有文化,那么你还是前往下一个小节查看怎么在Linux或Live环境下进行系统迁移吧

首先下载DiskGenius(硬碟鬼才)(没完了是吧!),在DiskGenius官网上就可以下载到,只需要免费版,这个工具也包含在图吧工具箱中

tbtools.webp

如图,这是我的两块磁盘,HD3是原磁盘,HD4是迁移目标磁盘,这块盘上我已经对原来的Windows做好了迁移

首先选中上方的灰色区域(空分区),点击上方的新建分区

choosevoid.png

弹出的窗口勾上创建ESP分区

allowesp.png

将文件系统类型改为EXT4,大小只需要比你现有分区占用的文件大小大就行,不需要比原来的分区大

setparation.png

单击确定保存,然后点击左上角工具栏的保存更改

savechanges.png

完成后,右键新建的ESP分区,选择格式化当前分区,将文件系统格式化为FAT32,完成后再次单击右键这个ESP分区,选择更改分区参数

rightclickesp.webp

确认这个分区的参数为EFI system partition,如果不是,将这个分区改为这个类型

changetoespifnot.webp

接下来,点按左边回到你的原始磁盘上,点击选中你原磁盘的EXT4分区(点击磁盘分区条中的粉色分区)

2disk.webp

点击上方菜单栏的工具——>克隆分区

copyparation.webp

在弹出的窗口选择目标分区目标迁移磁盘刚刚新建的EXT4分区

choosetonew.webp

点击开始即可开始迁移原来的系统分区,完成后你会发现所有文件类型和权限被正确保留,请前往“重建引导“部分的“使用boot-repair”章节来查看如何处理引导

finishcopy.webp

在Live环境下进行迁移

首先我们需要介绍一个概念——伪文件系统(pseudo filesystem)

在 Linux 里,一切都是文件 ——键盘、硬盘、内存、进程……都可以被当作文件访问。但是这些东西中,很多并不真的存储在磁盘上,而是由内核动态生成、实时反映系统状态的。

这些“看起来像文件,但其实不是磁盘文件”的内容,就存在于所谓的 伪文件系统(pseudo filesystem) 里。它们都不是磁盘上的目录,而是由内核实时生成并挂载的。下表是一些常见的伪文件系统

挂载点

名称

作用

/proc

procfs

提供系统和进程信息,比如 /proc/cpuinfo, /proc/meminfo

/sys

sysfs

提供内核设备、驱动、模块的信息

/dev

devtmpfs

存放设备节点(如 /dev/sda, /dev/null

/run

tmpfs

保存运行时状态,比如 PID、锁文件

/tmp

tmpfs(部分情况)

临时文件,存在内存中

在迁移过程中直接复制 /proc/sys/dev 这些内容,你会复制一堆内核虚拟数据和设备节点,这没有任何意义;

所以在Linux环境下,我们在迁移时需要排除这些文件类型。

首先进入Live环境,Live环境可以在下载一个Ubuntu安装镜像引导启动后选择Try Ubuntu进入

在进入系统后,打开终端,输入lsblk -f,检查现在的磁盘信息

╭─[fridayssheep@allinone:~]—{^o^}—(19:17:39)—(16ms)
╰─$> lsblk -f
NAME        FSTYPE FSVER LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda                                                                                 
├─sda1      ntfs                709AFC95C5957D6A                                    
├─sda2      ntfs         新加卷 A32119487D55344B                                    
├─sda3      vfat   FAT32        F71A-36DA                                           
├─sda4      ext4   1.0          69bfdfd4-2944-45eb-9c33-4315b0057e1c                
├─sda5      vfat   FAT32        18C6-1598                                           
└─sda6      vfat   FAT32        EC29-9252                                           
sdb                                                                                 
├─sdb1      vfat   FAT32        1201-3968                                           
├─sdb2                                                                              
├─sdb3      ntfs                7AB4063EB405FD7F                                    
├─sdb4      ntfs                58B63B2AB63B0850                                    
├─sdb5      ntfs         新加卷 F6387B4E387B0D3D                                    
└─sdb6      ext4   1.0          69bfdfd4-2944-45eb-9c33-4315b0057e1c                
nvme0n1                                                                             
├─nvme0n1p1 vfat   FAT32        22F6-296A                               280M     2% /boot/efi
└─nvme0n1p2 btrfs               df786aca-5ee2-4ca7-9107-a0d1cccc419c  189.7G    19% /home
                                                                              /

可以看到,这里的/dev/sdb是我的原始磁盘,/dev/sda是我们的目标迁移磁盘

之后在终端中使用sudo -i获取root权限,使用cfdisk /dev/sda命令操作我们的目标迁移磁盘

删除不需要的分区或使用Resize调整原有分区的大小,将高亮部分移到Free Space部分,使用左右方向键选择下方的New,按下回车键进入

choosefreespace.png

创建一个500MB左右的分区,输入500MB按下回车即可

createesp.png

将光标移到type,回车进入

changetype.png

将类型改为EFI System

changeesp.png

将剩下的Free Space按需分配大小创建为Linux Filesystem

完成后将更改写入磁盘

writetodisk.png

将光标移动到Quit,退出cfdisk

使用mkfs.fat -F32 处理新建的ESP分区

mkfs.fat -F32 /dev/sda3

根据你之前操作系统的实际文件系统,使用mkfs来将分区处理为对应的文件系统

Ext4文件系统

mkfs.ext4 /dev/sda4

使用lsblk -f再次查看现在的分区表,确定你的原系统和新系统的分区

/mnt下分别创建old和new文件夹,分别挂载你的旧系统分区和新目标迁移分区

mkdir /mnt/new /mnt/old
mount /dev/sda4 /mnt/new
mount /dev/sdb6 /mnt/old

使用rsync迁移所有的文件

  • -aAXH 保留权限、ACL、xattr、硬链接

  • --info=progress2 显示剩余时间,进度

  • -x 避免复制/dev /run等的动态系统目录

rsync -aAXv --info=progress2 -x /mnt/old/ /mnt/new/

大约用了7分钟迁移完毕,天哪,我看到了万恶的snap

rsync.webp

你可以使用dry-run对文件再次检查一遍

rsync -avn /mnt/old/ /mnt/new/

Btrfs文件系统

处理新创建的分区

mkfs.btrfs /dev/sda4

挂载分区

mkdir /mnt/new /mnt/old
mount /dev/sda4 /mnt/new
mount /dev/sdb6 /mnt/old

对于Btrfs文件系统,我们还需要处理子卷,进入旧系统的分区,查看之前的子卷

root@allinone:~ # cd /mnt/old
root@allinone:/mnt/old # btrfs subvol list -p /mnt/old
ID 272 gen 38391 parent 5 top level 5 path @home
ID 273 gen 38391 parent 5 top level 5 path @

由于非只读子卷不能直接btrfs send/receive,因此需要创建新的只读镜像用于传输。

mkdir /mnt/old/@snapshots/mv
btrfs subvolume snapshot -r /mnt/old/@ /mnt/old/@snapshots/mv/@_ro
btrfs subvolume snapshot -r /mnt/old/@home /mnt/old/@snapshots/mv/@home_ro

传输只读镜像

btrfs send /mnt/old/@snapshots/mv/@_ro | sudo btrfs receive /mnt/new/
btrfs send /mnt/old/@snapshots/mv/@home_ro | sudo btrfs receive /mnt/new/

将只读镜像处理为可读写子卷

btrfs subvolume snapshot /mnt/new/@_ro /mnt/newroot/@
btrfs subvolume snapshot /mnt/new/@home_ro /mnt/newroot/@home

删除只读镜像

btrfs subvolume delete /mnt/new/@_ro
btrfs subvolume delete /mnt/new/@home_ro

重新挂载新的分区

umount -R /mnt/new/
mount -o subvol=@ /dev/sda4 /mnt/new
mount -o subvol=@home /dev/sda4 /mnt/new/home

检查新分区情况

root@allinone:/mnt/old # cd /mnt/new
root@allinone:/mnt/new # btrfs subvol list -p /mnt/new
ID 272 gen 38391 parent 5 top level 5 path @home
ID 273 gen 38391 parent 5 top level 5 path @

重建引导

正常操作

迁移完成后,你需要编辑fstab来让系统识别新的硬盘

使用lsblk -f来查看磁盘的UUID

lsblk -f

将所有分区的UUID改成新硬盘的

vim /mnt/new/etc/fstab

按下i进入编辑模式,修改完毕后按下Esc,输入:wq保存退出

挂载ESP分区

mount /dev/sda3 /mnt/new/boot/efi

挂载伪文件系统

for dir in dev proc sys run; do
  sudo mount --bind /$dir /mnt/new/$dir
done

chroot进入迁移的系统

chroot /mnt/new /bin/bash

重新安装grub

grub-install /dev/sda3
update-grub
exit

取消挂载所有文件系统

umount -R /mnt/new
umount -R /mnt/old

重启系统,在BIOS里面调整启动顺序或者使用efibootmgr

root@allinone:/boot/efi# efibootmgr
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0008,0002
Boot0000* debian        HD(1,GPT,3c66c91a-5dc9-4158-9e01-eb4cfe64b21b,0x800,0x8e800)/\EFI\debian\shimx64.efi
Boot0002* UEFI: PXE IPv4 Realtek PCIe GBE Family Controller     PciRoot(0x0)/Pci(0x1c,0x2)/Pci(0x0,0x0)/MAC(220112a10c3f,0)/IPv4(0.0.0.0,0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)0000424f
Boot0008* ubuntu        HD(1,GPT,3c66c91a-5dc9-4158-9e01-eb4cfe64b21b,0x800,0x8e800)/\EFI\UBUNTU\GRUBX64.EFI0000424f

使用efibootmgr -o来配置启动顺序

root@allinone:/boot/efi# efibootmgr -o 0000,0002
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0002
Boot0000* debian        HD(1,GPT,3c66c91a-5dc9-4158-9e01-eb4cfe64b21b,0x800,0x8e800)/\EFI\debian\shimx64.efi
Boot0002* UEFI: PXE IPv4 Realtek PCIe GBE Family Controller     PciRoot(0x0)/Pci(0x1c,0x2)/Pci(0x0,0x0)/MAC(220112a10c3f,0)/IPv4(0.0.0.0,0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)0000424f

使用boot-repair

筑波筑波,使用命令行还是有点太吃操作了,有没有什么快捷一点的办法?

有的兄弟,有的

前往项目地址下载boot-repair镜像

getbootrepair.webp

下载完成后,使用Rufus或者Balena Etcher来写入镜像。什么?你说你没有多的U盘啦?偷偷告诉你,你可以创建一个空的fat32分区,然后直接将这个镜像使用7zip之类的软件解压到这个分区的空目录下也可以正常启动

进入系统后,boot-repair这个应用程序会自动启动,先给他叉掉不管他

使用Ctrl+Alt+t打开终端,输入sudo -i切换到root用户

使用lsblk -f再次查看现在的分区表和UUID,确定你的新系统的分区UUID

将你的目标迁移磁盘分区挂载到/mnt

mount /dev/sdxX /mnt

修改磁盘的fstab文件,将所有分区的UUID改成新硬盘的

nano /mnt/etc/fstab

你问我为什么不用vim?因为这玩意是基于Linux mint镜像制作的,而Linux mint里面不包含vim这个软件包,连vi都没有

修改完毕后按下Ctrl+X退出,输入yes保存,再按下Enter退出nano

在开始菜单找到boot repair重新打开它

launchbootrepair.webp

点击下面的Advance options ,转到GRUB location选项卡

changesetting.webp

修改这里的选项为正确的系统和ESP分区,然后点击Apply即可开始重建引导

重建完毕后,重新启动系统即可

进入新系统

此时不出意外的话,你应该进入了新系统,恭喜你,让新舟载着你的梦想继续前行吧!