樹莓派映象備份與恢復文章
在做完下屬步驟以後,需要考慮分割槽表,將分割槽表複製到映象裡,否則系統無法啟動,而且還要回利用gparted /dev/loop0以及fdisk -l /dev/loop0等命令,檢視分割槽型別,檔案系統型別,是否需要修改分割槽卷標等操作。
往已經做好的映象新增分割槽表的命令:
sudo dd if=/dev/sdd of=raspberrypi.img bs=1MB seek=0 count=24 conv=notrunc
#2018-05-24更新
#!/bin/bash #sudo apt-get install -y dosfstools parted kpartx rsync df -P | grep /dev/mmcblk0p1 if [ $? -ne 0 ];then echo "mount p1..." sudo mount /dev/mmcblk0p1 /boot fi df=`df -P | grep /dev/mmcblk0p2 | awk '{print $3}'` dr=`df -P | grep /dev/mmcblk0p1 | awk '{print $2}'` df=`echo $df $dr |awk '{print int(($1+$2)*1.2)}'` if [ -f raspberrypi.img ];then rm raspberrypi.img fi sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df sudo parted raspberrypi.img --script -- mklabel msdos start=`sudo fdisk -l /dev/mmcblk0| awk 'NR==9 {print $2}'` start=`echo $start's'` end=`sudo fdisk -l /dev/mmcblk0| awk 'NR==9 {print $3}'` end2=$((${end}+1)) end=`echo $end's'` end2=`echo $end2's'` sudo parted raspberrypi.img --script -- mkpart primary fat32 $start $end sudo parted raspberrypi.img --script -- mkpart primary ext4 $end2 -1 loopdevice=`sudo losetup -f --show raspberrypi.img` sudo kpartx -va $loopdevice | grep "fail" if [ $? -eq 0 ];then echo "part failed" exit 1 fi device=`echo $loopdevice | awk -F '/' '{print $3}'` device="/dev/mapper/${device}" partBoot="${device}p1" partRoot="${device}p2" sudo mkfs.vfat $partBoot sudo mkfs.ext4 $partRoot sudo mount -t vfat $partBoot /media sudo cp -rfp /boot/* /media/ sudo umount /media sudo mount -t ext4 $partRoot /media/ cd /media sudo rsync -aP --exclude="raspberrypi.img" --exclude=/media/* --exclude=/sys/* --exclude=/proc/* --exclude=/tmp/* / ./ cd sudo umount /media sudo kpartx -d $loopdevice sudo losetup -d $loopdevice sudo dd if=/dev/mmcblk0 of=raspberrypi.img bs=1MB seek=0 count=24 conv=notrunc
在Linux下回復的過程是:
sudo dd bs=1M if=raspberrypi.img of=/dev/sdc
sudo sync
最近一直在折騰樹莓派,前幾天裝了10臺裝置,最近又來了15臺開發板子。基本每臺裝置都需要進行如下操作:
1.安裝樹莓派OS,並配置鍵盤、時區、語言編碼格式等;
2.新增組、使用者、配置靜態IP地址;
3.配置應用,並配置2個自啟動的服務;
而這些都是重複性配置,工作量巨大;之前採用了一種方式,直接使用樹莓派官方的USB工具,採用備份還原的方式,clone映象;
但存在問題:SD卡為32GB,每次還原得很長時間,所以想減小映象大小;
參考後文方式,做一個backup.sh檔案,然後安裝相關工具,並增加可執行許可權,並sudo ./backup.sh執行;
安裝所需工具元件:
sudo apt-get install dosfstools sudo apt-get install dump sudo apt-get install parted sudo apt-get install kpartx
內容如下:
#!/bin/sh sudo dd if=/dev/zero of=raspberrypi.img bs=1MB count=4000 sudo parted raspberrypi.img --script -- mklabel msdos sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 2682879s sudo parted raspberrypi.img--script -- mkpart primary ext4 2682880s -1 loopdevice=`sudo losetup -f --show raspberrypi.img` device=`sudo kpartx -va $loopdevice | sed -E 's/.*(loop[0-15])p.*/\1/g' | head -1` device="/dev/ram${device}" partBoot="${device}p1" partRoot="${device}p2" sudo mkfs.vfat $partBoot sudo mkfs.ext4 $partRoot sudo mount -t vfat $partBoot /media sudo cp -rfp /boot/* /media/ sudo umount /media 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
執行之後,等待一段時間,就可以看到相應的映象檔案:
-------------------------
買樹莓派的時候只想到儲存空間大能多存的東西於是買了個16GB的SD卡,可實際用了2G空間不到。最開始備份樹莓派SD卡是用windwos下的Win32DiskImager,這種備份恢復樹莓派的方式最簡單,Windows+讀卡器+Win32DiskImager 就可以對樹莓派的SD做完整的映象備份,可我的樹莓派用的16GB的SD卡,備份還原既浪費空間又浪費時間。
後來發現一種直接用dd備份樹莓派的方法,就是先在樹莓派上mount一個共享目錄(空間大於SD卡的即可),然後用
dd if=/dev/mmcblk0 of=raspberrypi.img bs=1M
備份成raspberrypi.img映象檔案,恢復的方式有兩種:一是用Win32DiskImager在windows系統上直接寫到SD卡中;二是在Linux系統中用(先fdisk -l檢視裝置)
dd if=/path/to/image/raspberrypi.img of=/dev/sdx
這種方式要考慮網路環境,如果你的樹莓派接的無線網絡卡,最好放棄這種方式,太慢!
最後介紹最終極的備份還原樹莓派的方式,利用dump 和 restore。先說明一下這種備份方式的好處:一是可以像Windows的Ghost只dump有效資料,也就是說可以最有效的節省備份空間,樹莓派有多少資料就生成多大的映象檔案;二是可以恢復到比原來SD卡空間的小的SD卡上,我原來用的樹莓派是16GB,現在可以把映象恢復到8GB或者4GB的SD中。下面看詳細步驟(不想看可以直接跳到最後的指令碼)
一、安裝需要的軟體
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總大小為2500MB的映象檔案
sudo dd if=/dev/zero of=raspberrypi.img bs=1MB count=2500
三、分割虛擬磁碟
利用parted將剛才生成的虛擬盤分割成兩個分割槽
- 第一個分割區採用FAT32格式,由sector 8192開始到sector 12879,約62.9MB
- 第二個分割區採用EXT4,由sector 122880開始到結束。
sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 122879s
sudo parted raspberrypi.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 raspberrypi.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
經過以上六步樹莓派中的資料檔案就全部備份到raspberrypi.img中了,你既可以在Windows中用Win32DiskImager將映象恢復到SD卡,也可以在Linux用dd還原到SD卡,而且不要求恢復SD卡的大小跟原來的一樣(不同品牌相同大小的SD卡實際可用空間不一樣的,坑!),這樣就可以很方便的更換SD卡。當用此SD卡啟動樹莓派的時候執行raspi-config ->Expand Filesystem 即可擴充套件未使用的空間。
這裡就是最後的指令碼,包含了以上六步,只需要編輯sudo vi backup.sh複製以下內容,sudo chmod 777 genimg.sh,然後sudo ./backup.sh就可以在當前指令碼目錄中生成樹莓派的SD卡映象了。
#!/bin/sh
sudo dd if=/dev/zero of=raspberrypi.img bs=1MB count=2500
sudo parted raspberrypi.img --script -- mklabel msdos
sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 122879s
sudo parted raspberrypi.img --script -- mkpart primary ext4 122880s -1
loopdevice=`sudo losetup -f --show raspberrypi.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
sudo mount -t vfat $partBoot /media
sudo cp -rfp /boot/* /media/
sudo umount /media
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
摘錄部分要點內容如下(如果作者不允許轉載,請聯絡即刪除):
一、檢視當前系統所佔容量
用Win32DiskImager來製作映象時是將sd卡正卡全部做成映象,是因為無法讀取到linux分割槽的原因,所以我們在製作映象前,先要確定我們當前系統所佔用了多少系統空間,即備份映象的大小。
#檢視當前系統所佔用的空間
df -lh
可以看到,樹莓派是有兩個分割槽,所以boot 【size】+linux【Used】+分割槽損耗【因為格式轉換,所以會損耗5%~10%】=映象實際大小,所以若used使用百分比超過50%那麼就無法在sd中建立此映象。
二、安裝需要的軟體
dosfstools:fat32分割槽格式化工具
dump:dump & restore 備份工具
parted & kpartx:虛擬磁碟工具
sudo apt-get install dosfstools dump parted kpartx
三、生成空白img
根據一里面系統所佔用的空間,生成空白的img。
#df為磁碟佔用空間
sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df
這也是錯誤比較多的地方,有人不理解原文中
count=2500
引數的意義,此引數是用dd命令建立一個大約2.5G的空白映象,若不使用第一步來算出實際映象大小的話,製作出來的映象就會出錯此處注意
dd命令中【1k=1024b;1KB=1000b;1M=1024kb;1MB=1000kb】
四、分割虛擬磁碟
我們已將空白的img建立完畢,現在需要通過parted將磁碟分為boot與root區
通過sudo fdisk -l /dev/mmcblk0
得知
第一個分割槽為boot分割槽,採用FAT32格式,由sector 8192開始到sector 12879
第二個分割區採用EXT4,由sector 122880開始到空白img結尾。
sudo parted raspberrypi.img --script -- mklabel msdos sudo parted raspberrypi.img --script -- mkpart primary fat32 8192s 122879s sudo parted raspberrypi.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 raspberrypi.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"
然後格式化虛擬磁碟分割槽
#boot分割槽用fat32進行格式化
sudo mkfs.vfat $partBoot
sudo mkfs.ext4 $partRoot
六、開始備份
boot分割槽為fat32格式,可以直接利用cp命令直接拷貝
sudo mount -t vfat $partBoot /media sudo cp -rfp /boot/* /media/ sudo umount /media
linux分割槽為ext4格式,需要利用dump & restore備份
#跳過raspberrypi.img不備份 sudo chattr +d raspberrypi.img sudo mount -t ext4 $partRoot /media/ cd /media sudo dump -h 0 -0uaf - / | sudo restore -rf - cd sudo umount /media
這裡原文中也有一點bug,用dump進行磁碟備份時,會將之前建立的空白img一併備份進去,通過chattr跳過raspberrypi.img
七、備份完畢,解除安裝虛擬磁碟
此時,已將所有資料備份至空白img,此時就可以解除安裝虛擬磁碟,將img拷貝出儲存了。
然後利用Win32DiskImager或者df命令即可將該raspberrypi.img恢復至sd卡上。
sudo kpartx -d $loopdevice
sudo losetup -d $loopdevice
這裡是整理後的指令碼,編輯sudo vi backup.sh,複製以下內容,sudo chmod 777 backup.sh,然後sudo ./backup.sh就可以在當前指令碼目錄中生成樹莓派的SD卡映象了。
也可以參考如下shell指令碼:
#!/bin/sh sudo apt-get install -y dosfstools parted kpartx rsync df=`df -P | grep /dev/root | awk '{print $3}'` dr=`df -P | grep /dev/mmcblk0p1 | awk '{print $2}'` df=`echo $df $dr |awk '{print int(($1+$2)*1.2)}'` sudo dd if=/dev/zero of=raspberrypi.img bs=1K count=$df sudo parted raspberrypi.img --script -- mklabel msdos start=`sudo fdisk -l /dev/mmcblk0| awk 'NR==10 {print $2}'` start=`echo $start's'` end=`sudo fdisk -l /dev/mmcblk0| awk 'NR==10 {print $3}'` end2=$[end+1] end=`echo $end's'` end2=`echo $end2's'` sudo parted raspberrypi.img --script -- mkpart primary fat32 $start $end sudo parted raspberrypi.img --script -- mkpart primary ext4 $end2 -1 loopdevice=`sudo losetup -f --show raspberrypi.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 sudo mount -t vfat $partBoot /media sudo cp -rfp /boot/* /media/ sudo umount /media sudo mount -t ext4 $partRoot /media/ cd /media sudo rsync -aP --exclude="raspberrypi.img" --exclude=/media/* --exclude=/sys/* --exclude=/proc/* --exclude=/tmp/* / ./ cd sudo umount /media sudo kpartx -d $loopdevice sudo losetup -d $loopdevice