因为之前没有使用过这种方式来对系统克隆,所以就开始了这方面的尝试,在尝试的过程中 遇到了不少问题,最终通过分析也都解决了。有待继续尝试的地方很多,也会把没有尝试的方法写出来。

为了做这个实验, 买了两个硬盘盒,以及两块固态硬盘。

这里使用的是vmware workstation ,开启了一台centos7 的虚拟机,进入虚拟机使用 lsblk 命名可以看到 当前系统只有一块磁盘 名为 /dev/sda  , 在这块磁盘上 有 两个分区, 分别是 /dev/sda1  挂载点为 /boot   大小为1G , 文件系统为 XFS ;另一块分区为为 /dev/sda2 ,挂载点为 / ,大小为 39G,逻辑卷 。 要想 虚拟机识别外部的硬件设备,必须给当前虚拟机开启usb 接口,插上 移动硬盘 到usb 接口,vmware 会提示 把当前移动硬盘加载到 哪个系统,选择 当前虚拟机,而不是 宿主机。

使用 lsblk  ,可以发现 自己的移动硬盘名为/dev/sdb 。

1,使用 dd    将 /dev/sda    上的数据全部拷贝到  /dev/sdb  # 一次读取1G 的数据并写入 目标磁盘,并显示详细过程。

dd if=/dev/sda of=/dev/sdb bs=1G status=progress  

2,到此, 拷贝结束后 , 就可以关机,然后尝试使用本地物理机 启动克隆的系统了。但是,虽然可以引导,并且可以选择启动的系统,救援模式,但是怎么都不能正常的启动。尝试了很多方法,虽然到目前为止,得到的结果也并不十分准确,但是可以肯定的是与驱动有关系(我也是卡了很久才确定的, 试了很多方法, 可能理论知识不够牢固)这里主要介绍我的尝试方法,先不讲具体如何解决系统启动的问题。

因为我是将当前活动的系统盘 , 拷贝到 目标磁盘的,网上的资料建议我卸载掉源磁盘。如果不卸载源磁盘,克隆当前活动的系统盘到目标磁盘,可以 在dd 命令后面添加 iflag=direct (说是可以绕过系统缓存,直接读取磁盘数据,但是拷贝时间会很久)

dd  if=/dev/sda of=/dev/sdb iflag=direct bs=1G  status=progress

但是最终的结果还是不能在宿主机上启动。

包括卸载源磁盘,克隆卸载的元磁盘到目标磁盘 还是不能正常从宿主机启动目标磁盘。

这里也尝试了对比目标磁盘 ,各个位置的数据。使用的是dd 命令 ,和hexdump 命令,都可以完成数据对比。实践到这里感觉可以写一个对比块设备的工具脚本出来了。这里分别以 /dev/sda  和 /dev/sdb  来说明。

对比两块磁盘 前2047 字节的数据是否一致。(dd 是读取磁盘的二进制, hexdump  是读取磁盘的16进制以及ascII 码)

dd if=/dev/sda of=/tmp/a.txt bs=1 count=2047 
dd if=/dev/sdb of=/tmp/b.txt bs=1 count=2047
cd /tmp
ls *.txt | xargs md5sum 

#使用 hexdump 来对比

hexdump -n 2047  /dev/sda   >> /tmp/ahex.txt
hexdump -n 2047  /dev/sdb   >> /tmp/bhex.txt

ls *.txt | xargs md5sum 

读取 a 磁盘的 sda1 分区的第一个字节,对比 sdb1 

dd  if=/dev/sda1 of=/tmp/a1.txt bs=1 count=1 
dd  if=/dev/sdb1 of=/tmp/b1.txt bs=1  count=1

从磁盘a 的 512 字节开始,读取 512 字节 ,写入到 b 磁盘的 513 字节 位置 

dd  if=/dev/sda of=/dev/sdb  bs=1 count=512 skip=512 seek=512 

dd if=/dev/sda of=/tmp/a512.txt bs=1 count=512  skip=512
dd if=/dev/sdb of=/tmp/b512.txt bs=1 count=512  skip=512

cd /tmp
ls *.txt | xargs md5sum 

现在开始介绍,如何解决那个问题,因为我是将虚拟机里的系统盘拷贝物理磁盘, 并期望 物理磁盘能够从宿主机启动,并加载根文件系统。根文件系统是存在于具体硬件设备, 也就是我的固态硬盘,系统在加载时,需要相应的驱动程序才能读取硬件设备,并加载根文件系统。具体的原理是很复杂的,之前也有了解过,但是容易忘记, 也许那才是最重要的知识。所以我这边的解决方案是,使用u 盘直接在 宿主机上 把对应的系统 装在我的另一块固态硬盘,并尝试从固态硬盘启动。最后成功启动。最后开启宿主机, 在对应虚拟机里加载已经成功启动的硬盘,以及挂载从虚拟机克隆的固态硬盘,现在是要 从克隆的系统盘启动宿主机。对比两块磁盘的,块文件位置的数据,比如 0-2047 字节, 以及2048字节的数据。经过对比 0-2047 字节的数据两块磁盘的数据一样, 所以问题就不在 0-2047 字节上,2048字节的数据不一致,那就是 异常点。克隆的系统盘有两个分区,分别是 sdb1 sdb2  sdb1 挂载的是 /boot  ,负责加载根文件系统,也就是加载 sdb2 上的分区。sdb2 才是系统上存放数据的位置,当然我之前也有想过把 对应的 initramfs  拷贝到 sdb1 上的boot 分区。但是涉及到挂载从文件系统拷贝, 这里没有尝试, 使用的是简单的 块设备 复制 。

dd if=/dev/sdc1 of=/dev/sdb1 bs=1G 

到此 根分区 就是 /boot 分区就拷贝结束了。目前已经可以成功启动,并且,可以看到宿主机 里的磁盘分区,所以到这里了, 我们也可以使用dd 来对 宿主机的内置的磁盘 ,克隆对应的分区, 比如c 盘, 我这边还没尝试,应该可以。

到此 , 以上的尝试 就结束了。现在总结一下, 其他有待尝试的想法。

1, 从文件系统拷贝,克隆系统。结果应该可以预料,也将无法启动。

2,使用dd  将元磁盘 写入一个镜像文件 ,然后将这个镜像文件写入要克隆的磁盘,未尝试,也是不能直接启动的。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐