备份 - 第二部分

难度:中等

在第一部分中,我演示了如何将你的树莓派中的SD卡备份。在第二部分中,我将演示如何检查备份是否有效,以及将备份镜像作为一个磁盘时的一些“趣事”。你将了解到如何在备份镜像当中修改文件。当你随后将镜像写入一张SD卡时,你所有做的改动将会呈现出来。

再次说明,这些在一台Linux电脑上来做很容易,但是,对于Windows用户来说却完全不是这么回事。如果Windows用户想跟着继续,可以考虑用Linux Live CD 或者在VirtualBox(或类似的)中使用Linux。

检查备份文件

备份通常很简单,但是你如何知道备份是否有效呢?要是当你树莓派的SD卡坏了而此时你发现你无法恢复备份时,那可是一点也不好玩的。你得再次从头开始创建一个新的默认分发版本、重新安装并设置所有的软件。当然,你自己的所有文件都无法恢复了。所以说,你应该时常检查你的备份是否有效。

检查备份的最简单的方法就是写镜像到一个多余的SD卡中,然后将其插入树莓派并重启。同时这也是最快捷的方法,我们在第一部分中已经描述了其中的一些细节了。

本文介绍了一个方法,你可以用一个备份镜像伪装成是一个真实的设备,比如是SD卡,并对应的使用它就像是用真实的SD卡一样。

请注意,以下所有步骤都是在你的备份镜像没有被压缩,在一个本地硬盘的情况下。如果你压缩了镜像,你得将其解压才能进行接下来的操作。

第一步,一如既往的,root权限决定了从哪个分区开始。因为我们有一个SD卡的镜像拷贝,我们可以看看这个文件本身及其中的分区表。如果你想要作为Pi的用户运行下面的命令,请在每个命令前加入sudo。否则,为简单起见,输入:

  1. $ sudo sh

该命令将会为你打开一个root 终端,这样就没有必要在命令前都加上sudo了。

首先列出备份镜像查看分区的起始处及以扇区为单位的文件大小。Fdisk的报告以扇区为单位的大小,但方便的是它将扇区大小显示在了顶上。

列出分区详细信息的命令是:

  1. $ fdisk Rpi_8gb_backup.img
  2. Welcome to fdisk (util-linux 2.21.2).
  3. Command (m for help): p
  4. Disk Rpi_8gb_backup.img: 7948 MB, 7948206080 bytes
  5. 255 heads, 63 sectors/track, 966 cylinders, total 15523840 sectors
  6. Units = sectors of 1 * 512 = 512 bytes
  7. Sector size (logical/physical): 512 bytes / 512 bytes
  8. I/O size (minimunm/optimal): 512 bytes / 512 bytes
  9. Disk identifier: 0x00dbfc6
  10. Device Boot Start End Blocks Id System
  11. /BU/Rpi_8gb_backup.img1 8192 122879 57344 c W95 FAT32 (LBA)
  12. /BU/Rpi_8gb_backup.img2 122880 15523839 7700480 83 Linux

该命令的输出将会显示在接下来一页的顶部。

当工具加载完毕后,我们用命令’p’来打印当前的分区表。该命令可显示当前分区表的细节,如分区的位置及大小。

我们可从“Units”或“Sector Size”行得知,每个扇区是512个字节。同时我们可知,两个分区分别自扇区8,192和扇区122,880开始。将这两个起始扇区号乘以512可得起始字节号。分别可得是 4,194,304字节 及 62,914,560字节,不过起始我们并不需要后一组数据,Linux会帮我们计算出来。

在你的树莓派上,通常首个分区会挂载在 /boot 目录下,第二个分区的挂载点则是根目录(/)。

检查其挂载信息,在不用Pi的情况下,我们需要创建一对挂载点,如下:

  1. $ mkdir /mnt/root /mnt/boot
  2. $ chmod a=rwx /mnt/root /mnt/boot

以上两条命令仅需执行一次,既是我们首次尝试这个练习时。接下来,及在下面的任何将做这件事时,以下两条命令必须每条一行,以将备份中的两个分区像虚拟磁盘一样挂载:

  1. $ mount -t vfat -o loop,offset=$((8192 * 512)) /BU/Rpi_8gb_backup.img /mnt/boot
  2. $ mount -t ext4 -o loop,offset=$((122880 * 512)) /BU/Rpi_8gb_backup.img /mnt/root

以上里面创建了两个挂载点(目录),将镜像文件中的第一个分区以vfat为文件系统挂载至 /mnt/boot,再将第二个分区以ext4为文件系统挂载至 /mnt/root。

前面的两条用来创建挂载点设定其权限的命令,仅需运行一次,即你首次做本练习时。

你现在可以通过打开一个文件管理器来查看文件,找到目录 /mnt/boot 和 /mnt/root,你应该能看到一如在你的树莓派上看到的很多文件。

终于你现在可以确认你的镜像文件可以用来恢复到一张SD卡上,至少它是可以被挂载的。那么以后你就可以用它来恢复一张损坏的卡了。不过,像这样在Linux笔记本上将卡的镜像文件挂载为虚拟磁盘,你就可以一如在真实的磁盘上一样,编辑文件、创建文件、删除你不需要的文件,等等。

编辑文件

例如,你要将该备份镜像恢复至另一张SD卡,但卡一般是放在连接VGA的电视机上的Pi里,而不是连接的HDMI,你可以在镜像内还未写入新SD卡前在 /boot 分区中编辑config.txt文件。

镜像的首个分区平常是挂载在/boot上,现在已经在你的笔记本中挂载为/mnt/boot,那么你现在所需要做的就是用你喜爱的编辑器来编辑/mnt/boot/config.txt,将 hdmi_group 和 hdmi_mode 值设置为1,将文件保存。

当你今后将该备份镜像写进一张新卡时,它就已经准备好了在用VGA连接电视的Pi上运行了。

为什么要这么做呢?你可能会有好些 Pi 运行着同样的设置,一个是在主机房里连接HDMI电视或是监控器,一个是在孩子卧室里连接这VGA电视或监控器。该方法就省得你将一个设备上的备份,再写进另一个设备,结果连接到了“错误的”的显示器上启动,然后修改配置在正确的显示器上启动。

显然,如果你将两个设备都配置成连接你的网络时使用静态IP地址,那你就得编辑 /etv/networkinterfaces 以适应SD卡重新刷了镜像的设备,否则你最后会让两台设备跑同样的IP地址,而这只会导致错误发生。

恢复单个文件

当你在 Pi 上删除了一个文件,当然是意外删除的,但你知道你有一个备份,那将磁盘镜像挂载为设备的方便总是有效的。如果 Pi 是在网络上,你可以简单的如前挂载备份镜像,找到文件并确定就是你想要的那个,然后用 scp 或 sftp 将文件拷至 Pi 中,正如下面演示的那样:

  1. $ mount -t ext4 -o loop,offset=$((122880 * 512)) /BU/Rpi_8gb_backup.img /mnt/root
  2. $ cd /mnt/root/home/pi
  3. $ scp Lost_file.txt pi@raspberrypi:

你将会得到提示要求输入 Pi 的密码,然后就会将文件拷贝到 Pi 用户在树莓派上的Home文件夹中去。

你现在已经知道如何将备份文件挂载至备份电脑中以查看其是否正常工作,此外,也知道了如何抽出单个(或多个)文件以用作单独的恢复。我们还能做些什么呢?

这一如第一次用SD卡时格式化卡般简单。如果你的SD卡比镜像文件大或者相同大小,你便能将一个备份文件恢复到SD卡中。如前,以下命令得以root身份执行:

  1. $ dd if=Rpi_8gb_backup.img of=/dev/mmcblk0 bs=2M

该命令应该写为一行。

这会花点时间,不过最后是会恢复的。你要做的就是等待复制完成,然后将恢复好的SD卡插进插槽启动 Pi。恢复压缩或分割备份镜像的详细操作请看第一部分。

恢复至大一点的存储卡

如果我们恰好在升级设备,我们同样也能用较小的备份文件来初始化较大的SD卡。我之前将一个4Gb的备份恢复到一张8Gb的卡上时就要这么做。恢复完成后,在8Gb的SD卡上便有了4Gb的镜像。为了利用起丢失的4Gb空间,所需要做的就是将恢复过的8Gb卡安好启动Pi,像平常一样以Pi用户登录。

一旦登录,我运行了 sudo reaspi-config 命令,选择了选项“Expand root partition to fill SD(展开root分区以填充SD卡)”,系统顺利地展开了4Gb分区以填充卡上剩余的空闲空间。事实上重新分配大小的操作是你下次重启Pi时的一部分—它并没有立即执行。

你可以通过 df 命令看到它的结果,而且并不需要root权限去执行!

  1. $ df -h /
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/root 7.3G 1.6G 5.4G 23% /

以上输出显示了我的根文件系统挂载在 / 上,容量为7.3Gb,所以我知道它不可能跟我从4Gb备份镜像中恢复的一样大小。