Raspberry Pi の USB ブート環境を作っておくと、backup と restore が捗った話


#はじめに
[以前、ちょっと書いたように](http://qiita.com/UedaTakeyuki/items/4f97240b5fd7fc8a4d0b)、Raspberry Pi の SD カードは以下の二つの領域から構成されます (NOOBS はもう少しややこしい構成になるようですが、すみませんが使った事がなく詳細をよく知りません)

- FAT の領域： boot loader が入っている
- ext4 の領域： Linux 起動時にルートファイルシステムとしてマウントされる領域

Raspberry Pi のブートシーケンスが BCM2835組み込みの初期化シーケンスをそのまま利用し、 **SD カードから FAT の領域をマウントして boot loader を起動する** という仕組みになっているので前者のFAT の領域は起動時には必ず SD 上になければいけないのですが、後者の ext4 の領域は USB メモリでも HDD でもどこにでも動かせます。
そこで、この ext4 の領域を USB メモリに移動し、Raspbian を USB から起動する SD カードを作ります

# なにが嬉しいのか
このような環境を作っておくと、Raspberry Pi のバックアップとリストアが楽になります

通常、Raspberry Pi のバックアップとリストアは SD カードの（ファイルのコピーではなく）バイトイメージを dd コマンドで吸い出す/書き込むということを **PC等** で行います。この時、 **SDカードと間違えて PC の HDD にリストアしたりしてしまうと PC の HDD が悲惨なことになる** のでかなり神経を使います

本当は  **Raspberry Pi に閉じた環境で**バックアップ/リストアを行いたい、できればスクリプトにしておいて自動的にバックアプサーバに自動アップロード、自動ダウンロードとかまでしてくれるようにしておくと大分楽になるのですが、現状はそれができません。 **Raspbian の実行中はルートファイルシステムを unmount できない** ので、SD カードに対する dd による直接操作ができません

そこで、ルートファイルシステムを SD ではなく USB に移動しておくと **Raspberry Pi から SD カードへの dd による操作が可能** になり、PC等なしで、 **Raspberry Pi だけでバックアップ/リストア**が可能になります



#用意するもの
普段使っている SD カードとは別に、以下を用意します

- マイクロSDカード：
boot 用の FAT 領域だけの SD カードをつくります。記憶容量の小さい数百円のカードでいいです
- USB メモリ：普段使っている SD カードを圧縮したサイズ + 2GByte ぐらいの容量でいいので、やはり数百円の記憶容量の小さいので十分です

#USB ブート環境の作り方
## 1. ブート用のUSBメモリを作る
手順は参考にさせていただいた[参考URL1.](http://marshland.hatenablog.com/entry/2014/09/21/143716)のとおりです

- USB メモリを刺して、普段使っている SD で普通に Raspberry Pi を起動

- ```sudo fdisk -l``` で USB メモリ（普通、/dev/sda1）と、Linux のルートファイルシステムが(NOOBS を使わずに Raspbian を dd で焼いたのであれば通常は /dev/mmcblk0p2)

- Linux のルートファイルシステムのバイトイメージを USB メモリにコピー：

 ```sudo dd if=/dev/mmcblk0p2 of=/dev/sda1 bs=32M conv=noerror,sync```

- エラーチェック、修復、領域の拡張

```
sudo e2fsck -f /dev/sda1
sudo e2fsck -f /dev/sda1
sudo resize2fs /dev/sda1
```

##2. ブート用のSDカードの作成

- 普段使っている、Raspbian の入っている SD カードを PC に刺し、/boot 領域の中身をどこかにコピーしておく

- USB 起動用 SD カードにする SD を PC に刺し、先ほどコピーておいたファイルを全てこちらにコピーする

- cmdline.txt の編集
root をSD（例えば、mmcblk0p2）からUSB（例えば、 sda1）に変更する

```bash:編集前
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
```

```bash:編集後
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline rootwait
```

# （復習）Raspberry Pi の SD カードの通常のバックアップ、リストア手順 ___間違えると Mac の HD が死ぬので十分にご注意を___

- SD カードを Mac に刺す。SDカードリーダ/ライタが多分別途必要になる

- ```diskutil list``` で SDカードが何番の /dev/disk にマウントされているか確認（間違えると大変。毎回同じ番号になるわけではなく、先に外部 HDD などが刺さっていると番号は変わるので注意）
以下では、例として /dev/disk1 だったとします。 **これが違うと大変なことになるので、必ずご自身の環境のご確認を**

- バックアップ（ディスク番号のご確認を）

```sudo dd if=/dev/rdisk1 bs=1m | gzip > ~/Desktop/pi.gz```


- リストア（ディスク番号のご確認を！間違ってると Mac の HDD が壊れます）

```
sudo diskutil unmountDisk
gzip -dc ~/Desktop/pi.gz | sudo dd of=/dev/rdisk1 bs=1m
```

# （新）USB ブート環境を使ったバックアップ/リストア手順
- USB ブート環境（上で作った USB ブート用 SD と USB メモリ）で Raspberry Pi を起動
- 起動後、バックアップ/リストア対象の SDと交換 
- バックアップ
```udo dd if=/dev/mmcblk0 bs=1048576 | gzip > pi.gz```
- リストア
```gzip -dc pi.gz | sudo dd of=/dev/mmcblk0 bs=1048576```

# (参考) gparted
USB ブート環境で、以下のように [gparted](http://gparted.org/index.php) をインストールしておくと Raspberry Pi で SD カードの領域の変更（小さくしたり、大きくしたり）ができて便利です

``` sudo apt-get install gparted```

![スクリーンショット 2015-05-07 18.31.13.png](https://qiita-image-store.s3.amazonaws.com/0/46544/954d4e33-2977-a88c-920d-25a62e74e0d4.png "スクリーンショット 2015-05-07 18.31.13.png")

# 雑談
唐突ですが、ソフトウエア工学の上流行程の各種手法や、メトリクスによる各種の(effort だったり error pronness だったり traceability link recovery だったり...) predictive な手法等は、その external validity の狭さというか、ようするにソフトウエアプロジェクトが本質的に持つ、他の工学領域で例をみないような徹底的な多様性が原因で、それらの手法が主張する「有用性」はどのようなプロジェクトでも普遍的に発揮されるわけではなく、苦労して導入した手法が現場で期待した成果をあげない例があちこちで見られます

そんな頼りないソフトウェア工学の知見に対して、私達コーダーがアプリオリに知っている以下の***ソフトウェア動作の法則***（？）はどんなソフトプロジェクトでも必ず成立する普遍的な性質だと思います。というか未だ反例が見つけられず

環境に変化がない場合：
- 第一法則：期待動作をしているソフトウエアは変更しない限り期待動作を続ける
- 第二法則：変更を加えたソフトウェアは期待動作を続けるとは限らない

なんか運動の法則みたいですが、ここから重要な原理が導かれます
第二法則より環境に変化がない場合、動いていたソフトウェアが動かなくなった時は変更が原因なので、第一法則より動いていた時のバックアップを戻すとまた正常に動く、という **バックアップの重要性の原理**が導出されたわけです！

しょうもない話でどうもすみません、ちょっと風邪引いて熱があるみたいです ^^;;; 
というか、私は Raspberry Pi をいろいろいじっていると、よく動かなくなってしまいます。 **こまめにバックアップをとっておくと本当に助かります**


#参考URL

- 1.[Raspberry Piの起動ディスクをポータブルHDDにした](http://marshland.hatenablog.com/entry/2014/09/21/143716)

- 2.[GParted: GNOME Partition Editor](http://gparted.org/index.php)