上一次我们说到系统配置的一些工作,在那些工作完成之后我突然想到之前从来没有做过的一个工作:系统备份。这一次我们就研究一下系统备份是怎么做的。

系统备份其实很简单,你总是可以把树莓派上的SD卡拔下来,在电脑上用Win32DiskImager来备份,但是这样备份出来的文件会和SD卡容量一样大,这种备份方法不可持续。那么参考网上的使用linux下的dd指令来完成这个工作。

我看了一下,在使用linux电脑备份的时候是把树莓派的卡插到电脑上,然后用dd把SD卡内容拷贝到本地。我手上只有树莓派作为linux电脑,那就先用我的4B测试一下,看看效果。

树莓派4B

害怕树莓派上空间不够,先挂个U盘备份到U盘里试试。一只没弄明白U盘是怎么挂载的,借此机会研究一下。

挂载U盘

U盘直接插上是读不了内容的,所以必须要使用mount指令进行挂载。虽然mount天然支持FAT文件系统,然而FAT有个文件尺寸上限,不是很好。因此考虑使用exFAT文件系统。安装新的工具包来使mount支持exFAT。

sudo apt install exfat-fuse

好下一步将我的U盘格式化为exFAT格式,在里面放一个文件以备后续测试。

把U盘插到树莓派上。

忘了U盘是不是支持USB3.0

使用上一次学的指令查看USB设备。

奇怪,U盘是16GB的,为什么这里显示是64GB?问题不大,下一步查看一下/dev下的设备。这里目录下的sd表示存储设备,sda表示第一个存储设备,sdb表示第二个,以此类推。sda1就表示这个设备的第一个分区,sda2表示第二个分区,以此类推。

可以看到已经连接上了,我的U盘没有分区所以只有一个sda1。

下面创建挂载点,一般在/mnt或者/media目录下创建挂载点。 我现在没有挂载东西所以这俩目录底下都是空的。这里我就在mnt下挂载了。注意指令里面的uid和gid是权限设置,后面是你的用户名。

sudo mkdir /mnt/backup_flash
sudo mount -o uid=pi,gid=pi /dev/sda1 /mnt/backup_flash

挂载成功了,下面看一下我放在U盘里的文件都有啥。

我在电脑上整文件的时候没有搞换行,导致这么一个效果,整体来看没啥问题。

尝试修改这个文件,然后取消挂载,再到电脑上看看。

成功。


习得新指令:mountumount

功能:挂载和卸载移动存储设备


系统备份1

我现在想备份的系统正在树莓派上跑着,没法搞,现在先用另一个有系统的sd卡测试一下备份功能。

闪迪打钱(雾)

还是查看一下设备

注意到Device 006和/dev下的sdb系列。在烧录系统得时候sd卡被分成了两个分区,所以这里有sdb1和sdb2。

可以使用df -h指令来查看挂载情况。

这里由于sdb没有挂载,所以这里没有显示。使用上面的指令进行挂载。

注意这里的区别。烧录到sd卡后较大的分区是ext4文件系统,挂载的时候要强调这个。另外由于系统烧录后所属权限是root,所以这里的uid和gid设置要去掉,否则挂载会不成功。

挂载成功,下一步进行备份测试。

sudo dd if=/dev/sdb of=/mnt/backup_flash/RPi_backup_64GB_test.img bs=4M

使用dd指令进行拷贝,拷贝到U盘下的RPi_backup_64GB_test.img下。注意:这里的if表示输入文件(input file),of表示输出文件(output file),bs表示分包大小(bag size?)。如果想查看进度可以新建一个终端并输入如下执行查看进度。

sudo pkill -USR1 -n -x dd

到这一步可能按道理就应该完成了,但实际上并不是这样。经过漫长的等待(半个小时),终于拷贝完成的时候,系统提示空间不足,备份失败。

这和我想象的不太一样啊,又查阅了更多的资料后发现直接对SD卡使用dd指令的结果和在windows上用Win32DiskImager的结果是一样的:镜像文件和SD卡一样大。

此路不通,换道。


习得新指令:dd

功能:文件拷贝和创建


系统备份2

试错之后发现了新的方法,这个方法需要更多的工具,也更复杂,但网上有人写好了脚本我可以直接使用。与直接使用dd拷贝SD卡不同,这里我们要先使用dd创建一个合适尺寸的镜像文件,然后将这个镜像文件划分为两个分区, root区为FAT32文件系统,Linux区为ext4文件系统。分区完成后需要把这个镜像文件作为虚拟磁盘挂载,挂载完成以后就可以进行格式化。此后就可以进行备份了。

工具准备

这个方法里面需要三个工具:

  • dosfstools:fat32分区格式化工具
  • dump:dump& restore 备份工具
  • parted & kpartx:虚拟磁盘工具

使用如下指令安装。

sudo apt install dosfstools dump parted kpartx

创建镜像

根据系统尺寸决定使用的空间大小。

使用指令df -P的时候,显示的数据是以1K(1024字节)为单位,注意到sdb1和sdb2分别使用的空间,下面要进行img空间分配。

应该注意到,boot分区其实是很小的,不过几十兆,分配的时候不应该用boot分区已经使用的空间,而是boot分区整个的大小,也就是表中第二列。root分区就不一样了,里面存放的是系统各项文件,这个分区在空间划分的时候应该照顾已经使用的空间,所以要注意的是表中第三列

使用下列指令获取上面的参数。

bootsz=`df -P | grep /dev/sdb1 | awk '{print $2}'`# 注意到最后的那个$2
rootsz=`df -P | grep /dev/sdb2 | awk '{print $3}'`# 注意到最后的那个$3

然后利用下面指令计算镜像文件尺寸。

totalsz=`echo $rootsz $bootsz | awk '{print int(($1+$2)*1.3)}'`

注意到上面的参数1.3,这个参数是网上一个同学经过测试测出来的。使用原始大小的1.3倍是极好的,兼顾尺寸和完备程度。

利用下面的指令申请镜像空间。

img=/mnt/backup_flash/PRi_64GB_test.img
sudo dd if=/dev/zero of=$img bs=1k count=$totalsz

申请空间这一步会花不少时间,像我这个9GB多大概一小时吧。

至此,空间分配完成,下面开始分区。

空间分区

使用fdisk指令查看分区情况。

sudo fdisk -l /dev/sdb

在镜像文件分区的时候是根据扇区编号来确定的。和分配空间类似,sdb1分区应该完整划分,剩下的都是sdb2分区。

使用以下指令获得分区始末位置。

bootstart=`sudo fdisk -l /dev/sdb | grep sdb1 | awk '{print $2}'`
bootend=`sudo fdisk -l /dev/sdb | grep sdb1 | awk '{print $3}'`
rootstart=`sudo fdisk -l /dev/sdb | grep sdb2 | awk '{print $2}'`

奇怪,为什么分区始末是不连续的?暂时不管,使用下面的指令查看数据。

echo "boot: $bootstart -> $bootend, root: $rootstart -> end"

使用下面的指令进行分区。

sudo parted $img --script -- mklabel msdos
sudo parted $img --script -- mkpart primary fat32 ${bootstart}s ${bootend}s
sudo parted $img --script -- mkpart primary ext4 ${rootstart}s -1

注意,这里第三个指令最后一个参数是负一,不是英文字母l,表示的含义是到最后一个,千万不要搞错了。

分区完毕之后进行格式化操作。

loopdevice=`sudo losetup -f --show $img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
device="/dev/mapper/${device}"
sudo mkfs.vfat ${device}p1 -n boot
sudo mkfs.ext4 ${device}p2

挂载并备份

使用下面的指令挂载虚拟磁盘的boot分区。

sudo mkdir -p /mnt/vir_img/boot
sudo mount -t vfat ${device}p1 /mnt/vir_img/boot

注意,boot区是FAT32格式,可以直接用cp指令进行拷贝。使用下面指令即可。

sudo cp -rfp /mnt/rpi_sd/boot/* /mnt/vir_img/boot/

从要备份的SD卡,拷贝到目标文件挂载的目录。

然后挂载root分区。

sudo mkdir -p /mnt/vir_img/root
sudo mount -t ext4 ${device}p2 /mnt/vir_img/root

注意,root分区是exf4格式,需要使用dump & restore进行备份。

cd /mnt/vir_img/root
sudo chattr +d $img
sudo dump -0uaf - /mnt/rpi_sd/root/ | sudo restore -rf -
cd
sudo sync

经过漫长的拷贝过程,完成之后就可以卸载虚拟磁盘了。

sudo umount /mnt/vir_img/*
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
sudo umount /mnt/backup_flash

好的,现在把得到的镜像拷贝到电脑上,烧到一个新的SD卡里用旧的树莓派测试一下。

emmmmm卡住不动了,备份失败

把上面的参数1.3改一下,改成1.5,新写一个自动化脚本测试一下。

#!/bin/bash# 时间
now=`date +%Y-%m-%d-%H%M%S`
exho "time:%t $now"# 备份文件写入位置
target_file_dir=/home/pi/Documents/backup_test
sudo mkdir -p $target_file_dir
img=${target_file_dir}/backup-${now}.img
echo "target file" $img# 虚拟磁盘挂载位置
vir_dir=/mnt/vir_img# 目标文件文件系统和目录
bootfs=/dev/sdb1
rootfs=/dev/sdb2
bootdir=`df -P | grep ${bootfs} | awk '{print $6}'`
rootdir=`df -P | grep ${rootfs} | awk '{print $6}'`
echo $bootfs "mounted on" $bootdir
echo $rootfs "mounted on" $rootdir# 计算目标空间尺寸
bootsz=`df -P | grep $bootfs | awk '{print $2}'`
rootsz=`df -P | grep $rootfs | awk '{print $3}'`
totalsz=`echo $rootsz $bootsz | awk '{print int(($1+$2)*1.5)}'`
echo "total size" ${totalsz}KB# 获取分区始末位置
bootstart=`sudo fdisk -l | grep $bootfs | awk '{print $2}'`
bootend=`sudo fdisk -l | grep $bootfs | awk '{print $3}'`
rootstart=`sudo fdisk -l | grep $rootfs | awk '{print $2}'`
echo "boot: $bootstart -> $bootend, root: $rootstart -> end"# 申请镜像空间
sudo dd if=/dev/zero of=$img bs=1k count=$totalsz# 目标镜像分区
sudo parted $img --script -- mklabel msdos
sudo parted $img --script -- mkpart primary fat32 ${bootstart}s ${bootend}s
sudo parted $img --script -- mkpart primary ext4 ${rootstart}s -1# 创建虚拟磁盘
loopdevice=`sudo losetup -f --show $img`
device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
sleep 5     # 暂停来避开bug
device="/dev/mapper/${device}"# 格式化
sudo mkfs.vfat ${device}p1 -n BOOT
sudo mkfs.ext4 ${device}p2# 挂载虚拟磁盘
vir_boot=${vir_dir}/boot
vir_root=${vir_dir}/root
sudo mkdir -p $vir_boot $vir_root
sudo mount -t vfat ${device}p1 $vir_boot
sudo mount -t ext4 ${device}p2 $vir_root# 备份boot分区
sudo cp -rfp ${bootdir}/* ${vir_boot}/# 备份root分区
cd $vir_root
sudo chattr +d $img
sudo dump -0uaf - $rootdir | sudo restore -rf -
cd
sudo sync# 卸载虚拟磁盘
sudo umount ${vir_dir}/*
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice

保存,执行,还是不行。

咋回事呢?我一步步按照教程来的啊,怎么就不好使呢?

莫非是备份目标的问题?教程里是把正在运行的树莓派固件备份,我这里是把一个挂载的卡备份,会不会不一样呢?会不会是刚才不连续的问题造成的呢?

修改脚本,重新测试,依旧失败,出现了教程里面一个broken pipe的问题。

时间有点晚了,暂时到这里,系统备份失败,下次再继续研究。

总结

虽然系统备份是失败的,但是我挂载U盘的指令由于反复使用已经烂熟于心,另外dffdisk指令也是经常使用,也熟练了不少。

参考文献

树莓派挂载U盘或移动硬盘:http://shumeipai.nxez.com/2013/09/08/raspberry-pi-to-mount-the-removable-hard-disk.html

linux下mount指令详解:https://blog.csdn.net/daydayup654/article/details/78788310

linux下uid和gid详解:https://blog.csdn.net/36/article/details/86573899

dd指令系统备份:https://blog.csdn.net/just_s0so/article/details/88825716

系统备份:https://www.cnblogs.com/javazhu/articles/9234097.html

系统备份(蜜汁1.3):http://www.360doc.com/content/17/0805/03/40492717_676751545.shtml

u盘安装linux 提示no such device_树莓派学习笔记2-U盘挂载和系统备份相关推荐

  1. u盘安装linux 提示no such device_IGH EtherCAT 开源主站安装及测试

    1.Linux系统: 采用的系统版本: Ubun 14.04.1 64位: 内核版本: 3.13.0-12-generic 具体型号: 2.去IGH官网下载1.5.2版本. 3.编译源码 (1)解压下 ...

  2. u盘安装linux 提示no such device_Linux 网络基础设计

    误删网卡配置文件解决思路 本回复案例仅在Centos 7如试验成功其它系统无从考究,仅供参考 请在root用户模式下配置 获得设备名称DEVICE 常见使用ifconfig,如果尚未安装请先安装 如果 ...

  3. PXE实现无人值守无盘安装Linux

    什么是PXE: PXE(preboot execute environment)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持工作站通过网络从远端服务器下载映像,并 ...

  4. Win7下使用U盘安装linux Ubuntu16.04双系统图文教程

    Win7下使用U盘安装linux Ubuntu16.04双系统图文教程 Ubuntu(友帮拓.优般图.乌班图)是一个以桌面应用为主的开源GNU/Linux操作系统,Ubuntu 是基于DebianGN ...

  5. 用u盘安装linux系统

    用U盘安装linux系统步骤: 1.用WinPE(老毛桃)讲U盘做成启动盘: 2.用UltraISO将linux的boot提取到U盘下,选择Bootable下的write disk p_w_picpa ...

  6. win10安装linux系统视频播放器,u盘安装linux视频mac制作win10安装u盘

    5. 用柔软的湿布清除打印机内部灰尘.污迹.墨水渍和碎纸屑,防止损坏.其次,用万用表检查外部电压是否符合要求,雨林木风win8系统,电压过高或过低都可能引起主机电源发生过压或欠压电路的自动停机保护 飞 ...

  7. h3c.服务器 装系统,h3c服务器u盘安装linux系统安装

    h3c服务器u盘安装linux系统安装 内容精选 换一换 简要介绍Anaconda是Python的包管理器和环境管理器.它附带了conda.Python和 7500 多个科学包及其依赖项.编写语言:C ...

  8. u盘软件怎么安装linux,教你怎么使用u盘安装Linux平台

    小伙伴你们明白如何使用u盘来安装Linux平台吗?可能大多数的人都好还不太清楚,不知道的也没关系哟,小编这就来将u盘安装Linux平台的操作方法来带来他们. 小伙伴之所以知道借助u盘进行调试Linux ...

  9. 安装win7后怎么装linux系统,小编教你如何使用u盘安装Linux系统

    第二步:u盘安装Linux 1,U盘插到要安装Linux的电脑上后,启动电脑,在启动时,一直按F2键,就能进入到主板的BIOS控制界面,按左右键移动到boot选项.然后按上下键到removeable ...

最新文章

  1. 接受java的返回值_java怎样接受 到return的值的?
  2. mac你没有权限打开应用程序_苹果mac卡顿怎么解决呢?轻松几招让你Mac流畅如新
  3. html jq 控制显示密码,js、jquery分别实现点击密码输入框密码显示和隐藏
  4. 使用@RequestParam注解和泛型遇到的问题
  5. OCR-CTPN 文字检测
  6. 触动精灵 - 获取颜色相似度
  7. 新浪微博开发者创新基金开始接受申请
  8. Gavin老师Transformer直播课感悟 - BERT多任务Fine-tuning案例实战
  9. Axure 如何在页面加载时,设置文本框的内容为当前日期
  10. CSS在线字体库,外部字体的引用方法@font-face
  11. hpuoj 1725: 感恩节KK专场——特殊的比赛日期 (素数判断)
  12. SIFT,SURF,ORB,FAST,BRISK 特征提取算法比较
  13. -XX:+PrintGCTimeStamps 打印CG发生的时间戳
  14. flush()的使用
  15. react学习笔记一:入门级小白到脚手架(create-react-app)开发项目
  16. android java 线程通信_Android 线程间通信
  17. 软件测试大环境求职难,跳槽难?我在大军中异军突起
  18. linux zip/unzip命令详解
  19. 写作分享|向SCI期刊投稿时使用什么邮箱比较好?
  20. BUU-2019极客大挑战全集

热门文章

  1. 大剑无锋之Hbase的优化【面试推荐】
  2. 一些 Linux 系统故障修复和修复技巧
  3. leetcode 341. Flatten Nested List Iterator | 341. 扁平化嵌套列表迭代器(Java)
  4. 数据结构:超好用的数据结构与算法可视化工具(USFCA旧金山大学)
  5. JVM从入门到精通(十):垃圾回收算法串讲:CMS,G1,三色标记算法
  6. Python基础之:函数
  7. JVM详解之:汇编角度理解本地变量的生命周期
  8. 分布式文件系统HDFS解析
  9. HashMap中hash函数怎么是实现的?
  10. 远程图片保存到服务器 php,保存远程图片到本地服务器几种方法[php,asp]网