计算机‎ > ‎软件‎ > ‎Linux‎ > ‎

树莓派 SD 卡备份与还原

发布者:guo rue,发布时间:2016年1月30日 上午8:10   [ 更新时间:2016年2月5日 上午12:57 ]
由于我之前是用 dd 命令烧写系统进 SD 卡的。那备份系统自然想到的是 dd 回来,这当然可以
dd if=/dev/mmcblk0 of=pi.img bs=1M
可是这是何等的握艹,我的 SD 是 32GB 的,系统只用了不到 6GB,而这样备份出来的 img 就有 30 多 GB。

那,读卡器 + Windows + Win32DiskImager 做的镜像备份也是这个套路。我也不考虑了。

终于发现了一种备份方式。
一 是可以像 Windows 的 Ghost 只 dump 有效数据,也就是说可以最有效的节省备份空间,树莓派有多少数据就生成多大的镜像文件;
二 是可以恢复到比原来 SD 卡空间的小的 SD 卡上,我原来用的树莓派是 32GB SD 卡,现在可以把镜像恢复到 16GB 或者 8GB 的 SD 卡中。
三 SD 卡还可以是不同品牌。这样就可以很方便的更换SD卡。当用这个 img 烧进新 SD 卡之后,启动树莓派之后执行 raspi-config ->Expand Filesystem 即可扩展未使用的空间。

零、硬件准备 A 和 B 方案选一种
A 一个 USB 盘
B 一个同局域网内的服务器 IP 192.168.2.31

由于没有 U 盘,我准备直接将生成的 img 透过网络直接上传到服务器,也就是 装 B 的方式。

搭建 NFS 服务
服务器端安装
sudo aptitude install nfs-common nfs-kernel-server portmap
服务的启动停止与重启
sudo /etc/init.d/nfs-kernel-server start
# /etc/init.d/nfs-kernel-server stop
# /etc/init.d/nfs-kernel-server restart

创建共享目录
mkdir /home/nfs
sudo chmod a+rwx /home/nfs

创建或修改配置文件
sudo nano /etc/exports
这个文件的内容非常简单,每一行由抛出路径,客户名列表以及每个客户名后紧跟的访问选项构成:
[共享的目录] [主机名或IP(参数,参数)]
/home/nfs *(rw,sync,insecure,no_root_squash,no_subtree_check)
这里包括三个部分:
/home/nfs 是共享目录
*是允许访问这个目录的IP地址
(rw,sync):这个是设置访问的属性,例如rw表示读写,sync表示同时写到内存和磁盘,更多内容,还可以参见nfs的设置。

这里设置好了之后需要重启 nfs 来让这个 work 命令是
/etc/init.d/nfs-kernel-server restart

然后看到
Shutting down NFS mountd: [  OK  ]
Shutting down NFS daemon: [  OK  ]
Shutting down NFS services:  [  OK  ]
Starting NFS services:    [  OK  ]
Starting NFS daemon:      [  OK  ]
Starting NFS mountd:      [  OK  ]
表示OK了。

登陆树莓派,安装客户端
sudo aptitude install nfs-common portmap
查看NFS的资源共享情况
showmount -e 192.168.2.31
使用 mount 命令即可挂栽
sudo mount -t nfs 192.168.2.31:/home/nfs /mnt
cd /mnt

一、安装需要的软件
dosfstools:fat32分区格式化工具
dump:dump & restore 备份工具
parted & kpartx:虚拟磁盘工具

执行软件安装
sudo apt-get install dosfstools
sudo apt-get install dump
sudo apt-get install parted
sudo apt-get install  kpartx

二、生成新的img文件
df -h
查看下树莓派实际使用空间然后在决定生成文件大小,下面命令生成块大小为 1MB 总大小为 6000MB 的镜像文件
sudo dd if=/dev/zero of=pi.img bs=1MB count=6000
这个可能会花费一些时间,取决于各种硬件的速度。我用了大约 500 秒。

三、分割虚拟磁盘
利用 parted 将刚才生成的虚拟盘分割成两个分区
第一个分割区采用 FAT32 格式,由 sector 8192 开始到 sector 122879,约 62.9MB
第二个分割区采用 EXT4 ,由sector 122880 开始到结束。

sudo parted pi.img --script -- mklabel msdos
sudo parted pi.img --script -- mkpart primary fat32 8192s 122879s
sudo parted pi.img --script -- mkpart primary ext4 122880s -1

四、挂载虚拟磁盘并格式化
loopdevice:执行 losetup 连接 img 文件的 loop device
device:执行完 kpartx 后,虚拟磁盘代号。
partBoot:由 device 加上 p1 组合而成的 FAT32 虚拟磁盘分区。
partRoot:由 device 加上 p2 组合而成的 EXT4 虚拟磁盘分区。

首先建立虚拟磁盘并分区
loopdevice=`sudo losetup -f --show pi.img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/\1/g' | head -1`
device="/dev/mapper/${device}"
partBoot="${device}p1"
partRoot="${device}p2"

格式化虚拟磁盘分区
sudo mkfs.vfat $partBoot
sudo mkfs.ext4 $partRoot

五、开始备份
fat32 虚拟磁盘分区建立好后直接用 cp 命令备份文件
sudo mount -t vfat $partBoot /media
sudo cp -rfp /boot/* /media/
sudo umount /media

ext4 linux 虚拟磁盘分区用 dump & restore 备份
sudo mount -t ext4 $partRoot /media/
cd /media
sudo dump -0uaf - / |  sudo restore -rf -
cd
sudo umount /media

六、卸载虚拟磁盘
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
sudo umount /mnt

经过以上六步树莓派中的数据文件就全部备份到 pi.img 中了

参考
http://general.blog.51cto.com/927298/354523
http://docs.oracle.com/cd/E19253-01/819-7062/6n91k1frj/index.html
http://blog.csdn.net/kevinhg/article/details/5967432
http://gsyan888.blogspot.com/2013/06/raspberry-pi-dump-restore.html
http://cn.docs.kali.org/development-cn/%E5%AE%9A%E5%88%B6raspberry-pi%E9%95%9C%E5%83%8F
http://cn.docs.kali.org/general-use/%E5%AE%89%E8%A3%85kali-linux-arm%E7%89%88%E6%9C%AC%E5%88%B0raspberry-pi
http://cn.docs.kali.org/development-cn/%E5%87%86%E5%A4%87kali-linux-arm-chroot
http://cn.docs.kali.org/development-cn/arm%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91