树莓派udev不能自动挂载_树莓派学习笔记3-系统备份

23c86965c32330b9de392a8a95c4832a.png

上回说到,U盘挂载和系统备份,在网上教程的加持下我浪费了两天的时间。前几天在知友 @ningxuezhi 宁同学的帮助下终于找到了靠谱的方法,现整理如下。

问题检测

上文中提到的宁同学与我遇到了相同的问题,使用之前的脚本备份系统,将所得镜像文件写入新的SD卡却不能运行。宁同学使用树莓派的板载串口输出调试数据,查看系统打印的提示信息,希望借此来找出问题所在。

2742a44aba57b997858dada7b029ffc8.png
宁同学正常启动的树莓派-@ningxuezhi

上图是宁同学手上一块正常启动的树莓派的打印信息,下一步使用这个树莓派测试备份脚本,将脚本写入新卡进行启动测试。

50a33bc40a771fd672147d5d46f2daab.png
正常启动与异常的对比-@ningxuezhi

上图左为正常启动的树莓派,右侧为对比。可以看出异常的树莓派压根没有去启动root分区的挂载,这里猜测是root分区在拷贝的时候不完整导致异常。

解决方案

这个结果是复合预期的,因为之前使用的dump/restore就是在root分区出现问题。回忆起上次看得“终极解决方案”中提到了root分区的问题,于是找到作者的GitHub,看到了他的一个古老脚本,仔细阅读后形成了改了改,如下。

#!/bin/bash

#install tools
sudo apt-get -y install rsync dosfstools parted kpartx exfat-fuse

# create log file
curent_path=`pwd`/log
mkdir -p $curent_path
log_file=${curent_path}/backup_log-`date +%Y%m%d-%H%M%S`.log
touch $log_file

echo_log(){
	echo [`date +%Y/%m/%d-%H:%M:%S`]: $* >> $log_file
}

echo_log "Create log at" $log_file

#mount USB device
usbmount=/mnt/backup_flash
mkdir -p $usbmount
if [ -z $1 ]; then
	echo "no argument, assume the mount device is /dev/sda1 ? Y/N"
	read key
	if [ "$key" = "y" -o "$key" = "Y" ]; then
		# sudo mount -o uid=1000 /dev/sda1 $usbmount
		sudo mount /dev/sda1 $usbmount
		echo_log "Mounted /dev/sda1 at" $usbmount "."
	else
		echo "$0 [backup dest device name], e.g. $0 /dev/sda1"
		exit 0
	fi
else
	# sudo mount -o uid=1000 $1 $usbmount
	sudo mount $1 $usbmount
	echo_log "Mounted" $1 "at" $usbmount "."
fi
if [ -z "`grep $usbmount /etc/mtab`" ]; then
	echo "mount fail, exit now"
	echo_log "Mount fail."
	exit 0
fi 

img=$usbmount/rpi-`date +%Y%m%d-%H%M`.img
#img=$usbmount/rpi.img


echo ===================== part 1, create a new blank img ===============================
# New img file
#sudo rm $img
bootsz=`df -P | grep /boot | awk '{print $2}'`
echo_log "boot section size: " $bootsz "Byte(s)"
rootsz=`df -P | grep /dev/root | awk '{print $3}'`
echo_log "root section size: " $rootsz "Byte(s)"
totalsz=`echo $bootsz $rootsz | awk '{print int(($1+$2)*1.3)}'`
echo_log "total size: " $totalsz "Byte(s)"
sudo dd if=/dev/zero of=$img bs=1K count=$totalsz
echo_log "Create image file at" $img

# format virtual disk
bootstart=`sudo fdisk -l /dev/mmcblk0 | grep mmcblk0p1 | awk '{print $2}'`
bootend=`sudo fdisk -l /dev/mmcblk0 | grep mmcblk0p1 | awk '{print $3}'`
rootstart=`sudo fdisk -l /dev/mmcblk0 | grep mmcblk0p2 | awk '{print $2}'`
echo "boot: $bootstart >>> $bootend, root: $rootstart >>> end"
echo_log "boot: $bootstart >>> $bootend, root: $rootstart >>> end"
#rootend=`sudo fdisk -l /dev/mmcblk0 | grep mmcblk0p2 | awk '{print $3}'`
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 -1s
echo_log "Image file parted done."
loopdevice=`sudo losetup -f --show $img`
device=/dev/mapper/`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1`
sleep 15
echo_log `sudo mkfs.vfat ${device}p1 -n BOOT`
echo_log `sudo mkfs.ext4 ${device}p2`


echo ===================== part 2, fill the data to img =========================
# mount partitions
virmount=/media/vir_mount
#sudo mkdir -p $virmount
mountb=${virmount}/backup_boot
mountr=${virmount}/backup_root
sudo mkdir -p $mountb $mountr
echo_log "Make directories: " $mountb $mountr
# backup /boot
echo_log "Mount" ${device}p1 "at" $mountb
sudo mount -t vfat ${device}p1 $mountb >> $log_file
echo_log "mount done"
sudo cp -rfp /boot/* $mountb
sync
echo "...Boot partition done"
echo_log "Boot partition done"
# backup /root
echo_log "Mount" ${device}p2 "at" $mountr
sudo mount -t ext4 ${device}p2 $mountr >> $log_file
echo_log "mount done"
if [ -f /etc/dphys-swapfile ]; then
        SWAPFILE=`cat /etc/dphys-swapfile | grep ^CONF_SWAPFILE | cut -f 2 -d=`
	if [ "$SWAPFILE" = "" ]; then
		SWAPFILE=/var/swap
	fi
	EXCLUDE_SWAPFILE="--exclude=$SWAPFILE"
fi
sudo rsync --force -rltWDEgop --delete --stats --progress 
	$EXCLUDE_SWAPFILE 
	--exclude='.gvfs' 
	--exclude='/dev' 
	--exclude='/media' 
	--exclude='/mnt' 
	--exclude='/proc' 
	--exclude='/run' 
	--exclude='/sys' 
	--exclude='/tmp' 
	--exclude='lost+found' 
	--exclude='$usbmount' 
	--exclude='$virmount' 
	--exclude='$log_file' 
	// $mountr >> $log_file
# special dirs 
for i in dev media mnt proc run sys boot; do
	if [ ! -d $mountr/$i ]; then
		sudo mkdir $mountr/$i
	fi
done
if [ ! -d $mountr/tmp ]; then
	sudo mkdir $mountr/tmp
	sudo chmod a+w $mountr/tmp
fi
sudo rm -f $mountr/etc/udev/rules.d/70-persistent-net.rules

sync
echo ${mountr}/home/pi
ls -lia $mountr/home/pi/
echo "...Root partition done"
# if using the dump/restore 
# tmp=$usbmount/root.ext4
# sudo chattr +d $img $mountb $mountr $tmp
# sudo mount -t ext4 ${device}p2 $mountr
# cd $mountr
# sudo dump -0uaf - / | sudo restore -rf -
# cd


# replace PARTUUID
opartuuidb=`blkid -o export /dev/mmcblk0p1 | grep PARTUUID`
opartuuidr=`blkid -o export /dev/mmcblk0p2 | grep PARTUUID`
npartuuidb=`blkid -o export ${device}p1 | grep PARTUUID`
npartuuidr=`blkid -o export ${device}p2 | grep PARTUUID`
sudo sed -i "s/$opartuuidr/$npartuuidr/g" $mountb/cmdline.txt
sudo sed -i "s/$opartuuidb/$npartuuidb/g" $mountr/etc/fstab
sudo sed -i "s/$opartuuidr/$npartuuidr/g" $mountr/etc/fstab

sudo umount $mountb
sudo umount $mountr

# umount loop device
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
sudo umount $usbmount
sudo rm -rf $mountb $mountr
echo "==== All done. You can un-plug the backup device"
echo_log "done"

这个脚本的具体内容不细说了,大致上和我上一篇文章的内容一致。这里只说一下流程。

  1. 安装依赖工具
  2. 挂载移动设备并创建空的镜像文件
  3. 空镜像文件分区与格式化
  4. 格式化后镜像文件挂载为虚拟磁盘
  5. boot分区备份
  6. root分区备份
  7. 卸载虚拟磁盘
  8. 卸载移动设备

在USB3.0的加持下,树莓派4B备份只需要不到半小时就能完成,尺寸也很合理。

fa3a3bdf3939018fe08058b24f90412f.png

需要强调几点:

  • 运行脚本时必须先切换到超级管理员
sudo su
chmod +x backup.sh
./backup.sh /dev/sda1
  • 备份完成后重新烧录的系统要手动扩展文件系统
sudo raspi-config

总结

至此,困扰我一周的备份问题已经解决,以后玩耍的时候可以胡乱搞了。文中提到的串口调试信息我还没用研究通透,可能下一篇文章会写。另外我的这个系列文章写的脚本和一些拍摄的图片会同步更新到GitHub上,欢迎star。

我的GitHub

yuxiaoyuan0406/RaspberryPi-Note​github.com
242e87afec875898cae6a03699b43121.png

参考文献

rpi-backup:

conanwhf/RaspberryPi-script​github.com
d3e3b5484d974e00922e6614955c1b5d.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值