暫定 - 技術メモなど

今のところはRaspberry Piを使ったIoTが話題の中心です

rpi-cloneバックアップイメージ書き出し不具合の対処について

普段、Raspberry Piのバックアップを取るときにはrpi-cloneを使っています。

github.com

このツールはとても便利で、接続しているUSBメモリに対話式でバックアップを取ってくれます。ぼくの場合は、ブートに使っているmicroSDと同じ16GBのmicroSDをUSBのアダプタに入れて、バックアップ先にしています。Raspberry Piに何か問題が起きた場合、バックアップ先になっているmicroSDと差し替えればそのままブートできるので、システム変更前のロールバック準備として重宝しています。

rpi-clone自体は何の問題もなく動いているのですが、バックアップ先のmicroSDをイメージとしてMacに残す際に問題が発生しました。
ddコマンドでイメージを取っているのですが、15GBあるはずのデータが300MBで保存されるようになってしまったのです。当然のことながら、そのイメージをmicroSDに書き戻してもブートしません。
原因を調べたのですが、このような症例は見つからず、困り果てていたのですが
(現に、作業前に取得したバックアップより一つ前に戻したかったのに、バックアップファイルが有効ではない、ということがありました)
Raspberry Piでイメージにして、それをMacに移せばいいではないか、と思い至りました。
方法としては下記の流れになります。

  1. rpi-cloneでmicroSDにバックアップ
  2. イメージ書き出し先のUSBメモリの準備
  3. バックアップのイメージをUSBメモリに書き出す
  4. Macにバックアップ

試してみたところこれで解決しましたので、メモとして残しておきたい思います。

1.rpi-cloneでmicroSDにバックアップ

うちの環境では下記のコマンドでバックアップを取得しています。

$ sudo rpi-clone sda -f

この後、いくつか質問が出ますが、yesで答えればバックアップが取られます。
ちなみにrpi-cloneはGitHubの公式に従って /usr/local/sbin に置いています。

2.イメージ書き出し先のUSBメモリの準備

rpi-cloneで取得したバックアップのイメージを書き出すUSBメモリRaspberry Piに接続し、ext4でフォーマットします。
まずは確認します。

$ sudo fdisk -l | grep /dev/sd

Disk /dev/sda: 14.4 GiB, 15502147584 bytes, 30277632 sectors
/dev/sda1         8192   137215   129024   63M  c W95 FAT32 (LBA)
/dev/sda2       137216 30277631 30140416 14.4G 83 Linux
Disk /dev/sdb: 14.6 GiB, 15648948224 bytes, 30564352 sectors

サイズと表示内容からイメージを書き出す先のUSBメモリは /dev/sdb であることがわかりました。(/dev/sda はrpi-cloneのバックアップ先)
イメージ書きだし先となるUSBメモリをフォーマットします。

$ sudo mkfs.ext4 /dev/sdb
mke2fs 1.43.4 (31-Jan-2017)
Found a dos partition table in /dev/sdb
Proceed anyway? (y,N) y
Creating filesystem with 3820544 4k blocks and 956592 inodes
Filesystem UUID: cce35784-eff5-47d2-b2a5-214cb6783bdd
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information:
done

このUSBメモリを /mnt/sdb にマウントします。

$ sudo mount /dev/sdb /mnt/sdb/
3.バックアップのイメージをUSBメモリに書き出す

rpi-cloneでバックアップした /dev/sda をマウントした /mnt/sdb に書き出します。
が、rootにならないと /mnt/sdb/ に権限がないと言われてしまうので、rootになってから実行します。

$ sudo su -
# dd bs=4M if=/dev/sda | gzip -c > /mnt/sdb/20180617-raspberrypi01.gz

書き出しが終わったらUSBメモリをアンマウントしてMacに挿しましょう。

4.Macにバックアップ

Macではext4でフォーマットしたUSBメモリが読めない為、ext4fuseをインストールしておきます。

$ brew cask install osxfuse
$ brew install ext4fuse

その後、こちらのアドバイスに従って operator グループに自分のユーザーを追加します。
architect-wat.hatenablog.jp

$ sudo dscl . append /Groups/operator GroupMembership <username>

次に diskutil list 等でUSBメモリのデバイスの番号を調べ、 ext4fuse を使ってUSBメモリを ~/mnt/ にマウントします。
(下記は /dev/disk3 の例。operator グループに入れていなくても root になれば実行できます。)

$ mkdir ~/mnt
$ ext4fuse /dev/disk3 ~/mnt/

~/mnt にUSBメモリがマウントされるので、GUIでコピペか、cpコマンドでローカルにコピーしましょう。
GUIの場合はマウントしたフォルダが表示されないので、Finderで[移動]-[フォルダへ移動]で ~/mnt 等を入力して直接開きます)
また、ext4fuseでマウントしたフォルダからアンマウントする場合は、普通に sudo umount ~/mnt/ 等でアンマウント可能です。

#2018年12月10日追記
この圧縮したイメージをmicroSDに書き戻すには、まずmicroSDをFATでフォーマットします。

$ sudo diskutil eraseDisk FAT32 USB MBRFormat /dev/disk3

上記の「USB」のところはアルファベット大文字で名前をつけましょう。
また、上記では /dev/disk3 となっていますが、diskutil list でmicroSDのパスを確認しましょう。
フォーマットが終わったら下記コマンドでイメージをmicroSDに書き戻します。

$ sudo diskutil umount /Volumes/USB
$ sudo dd bs=1m if=./20180617-raspberrypi01.img of=/dev/rdisk3

これまた、if= の箇所はイメージのパスに書き換えましょう。
以上です。
ーーー
なぜこのような追記をしたのか。賢明なあなたにはお分かりの通り、対応の必要があったからである。
一つ前のバックアップではなぜか homebridge 環境が元に戻らない事象が発生したので、圧縮したイメージから復旧することになった。
バックアップがいかに大事か、しかも小まめにバックアップしておくことがいかに大事か身を以て知ったという話。