年末なのでRaspberry Piも手入れをしましょう 〜 UpdateとBackup 〜

＿・）今年ももうおしまいですね〜

[Raspberry Pi Advent Calendar 2016](http://www.adventar.org/calendars/1341)の18日目分の投稿です。
何を書こうかなと色々迷ったんですが、無難なところに落ち着きました。

# 年末ですよ
2016年も残すところ半月弱となって参りました。

私自身振り返ると、この一年でまた結構RasPi本体の所有数が増えて
地デジ録画サーバだの、RasPiタンク工作だのが結構増えちゃったりしました。

さて、そんなRaspberry Pi工作群なのですが、やはり定期的にアップデートやバックアップなどのメンテナンスはしてあげましょう。愛です、愛。

年末の大掃除のついでに、自宅サーバとなっているRaspberry Piのお掃除もしつつ（ホコリとりましょう）、中身もケアしてみましょう。

今回は、Raspbianを利用している方向けにアップデートやバックアップに便利なコマンドなどを紹介します。他のディストリビューションは一部使えないと思いますので、悪しからず・・・。

## rpi-update

最近は、Raspbianにも最初っから入ってたりするので結構有名な[rpi-update](https://github.com/Hexxeh/rpi-update)。
Raspberry PiのファームウェアやRaspbianのカーネルをアップデートしてくれる便利なやつです。

よほど古いバージョンではなければRaspbianにインストールされているので、実行も簡単です。
ただ、カーネルバージョンを上げたせいで他のソフトウェアの動作に影響が出ることも考えられますので、実行の際には注意してください。
心配な場合は、後ほど紹介するバックアップを先に行った方がいいかも知れません。

実行には管理者権限が必要ですので、sudoを付けて実行します。

```shell-session
pi@raspberrypi:~ $ sudo rpi-update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** Performing self-update
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12022  100 12022    0     0   2061      0  0:00:05  0:00:05 --:--:--  2787
 *** Relaunching after update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** We're running for the first time
 *** Backing up files (this will take a few minutes)
 *** Backing up firmware
 *** Backing up modules 4.4.21-v7+
This update bumps to rpi-4.4.y linux tree
Be aware there could be compatibility issues with some drivers
Discussion here:
https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=144087
##############################################################
 *** Downloading specific firmware revision (this will take a few minutes)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   168    0   168    0     0     26      0 --:--:--  0:00:06 --:--:--    43
100 51.8M  100 51.8M    0     0  1008k      0  0:00:52  0:00:52 --:--:-- 1782k
 *** Updating firmware
 *** Updating kernel modules
 *** depmod 4.4.38+
 *** depmod 4.4.38-v7+
 *** Updating VideoCore libraries
 *** Using HardFP libraries
 *** Updating SDK
 *** Running ldconfig
 *** Storing current firmware revision
 *** Deleting downloaded files
 *** Syncing changes to disk
 *** If no errors appeared, your firmware was successfully updated to af9cb14d5053f89857225bd18d1df59a089c171e
 *** A reboot is needed to activate the new firmware

pi@raspberrypi:~ $ 
```

アップデート後は画面の表示に従って再起動しときましょう。

```shell-session
pi@raspberrypi:~ $ sudo shutdown -r now
```

## apt

aptのパッケージ群も定期的にアップデートされてます。自動更新とかさせてない場合は、定期的にアップデートしておきましょう。この辺は特にRaspberry Piだからって話ではなくて、普通のLinuxの管理と同じですね。

Raspbianは名前の通り、Debian系ディストリビューションなのでaptコマンドでパッケージの更新が可能です。

まずはupdateサブコマンドでパッケージリストを更新します。

```shell-session
pi@raspberrypi:~ $ sudo apt update
Get:1 http://mirrordirector.raspbian.org jessie InRelease [14.9 kB]
Get:2 http://mirrordirector.raspbian.org jessie/main armhf Packages [8982 kB]
Get:3 http://mirrordirector.raspbian.org jessie/contrib armhf Packages [37.5 kB]
Get:4 http://mirrordirector.raspbian.org jessie/non-free armhf Packages [70.3 kB]
Get:5 http://mirrordirector.raspbian.org jessie/rpi armhf Packages [1356 B]
Get:6 http://archive.raspberrypi.org jessie InRelease [13.2 kB]
Get:7 http://archive.raspberrypi.org jessie/main armhf Packages [130 kB]
Get:8 http://archive.raspberrypi.org jessie/ui armhf Packages [53.6 kB]
Ign http://mirrordirector.raspbian.org jessie/contrib Translation-en
Ign http://mirrordirector.raspbian.org jessie/main Translation-en
Ign http://mirrordirector.raspbian.org jessie/non-free Translation-en
Ign http://mirrordirector.raspbian.org jessie/rpi Translation-en
Ign http://archive.raspberrypi.org jessie/main Translation-en
Ign http://archive.raspberrypi.org jessie/ui Translation-en
Fetched 9303 kB in 27s (342 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
127 packages can be upgraded. Run 'apt list --upgradable' to see them.
```

次に、パッケージをupgradeサブコマンドでアップデートします。
パッケージによっては途中で対話式のメニュー等が出てきたりしますので、時々画面を確認しましょう。

```shell-session
pi@raspberrypi:~ $ sudo apt upgrade -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... The following packages were automatically installed and are no longer required:
  libboost-filesystem1.55.0 libboost-program-options1.55.0 libboost-regex1.55.0 libcwiid1 libjs-prettify libllvm3.7
  libqscintilla2-11 libqscintilla2-l10n libqt4-network libqt4-xmlpatterns libqtwebkit4 libruby1.9.1 libruby1.9.1-dbg
  libtcl8.5 libtcltk-ruby1.9.1 libtk8.5 ri1.9.1 ruby1.9.1 ruby1.9.1-dev ruby1.9.1-examples ruby1.9.1-full ruby1.9.3
  supercollider supercollider-common supercollider-ide supercollider-language supercollider-supernova tcl8.5 tk8.5
Use 'apt-get autoremove' to remove them.
Done
The following NEW packages will be installed:
  libllvm3.9 libqt5concurrent5 libqt5core5a libqt5dbus5 libqt5gui5 libqt5network5 libqt5opengl5 libqt5printsupport5
  libqt5svg5 libqt5widgets5 libwayland-egl1-mesa libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0
  libxcb-render-util0 libxcb-xkb1 libxkbcommon-x11-0 qttranslations5-l10n whois
The following packages will be upgraded:
  apt apt-utils bind9-host bluej chromium-browser curl fonts-opensymbol gdb gdbserver greenfoot
  gstreamer1.0-plugins-bad gstreamer1.0-plugins-good libapt-inst1.5 libapt-pkg4.12 libarchive13 libavcodec56
  libavformat56 libavresample2 libavutil54 libbind9-90 libc-ares2 libcurl3 libcurl3-gnutls libdns-export100 libdns100
  libdrm-amdgpu1 libdrm-freedreno1 libdrm-nouveau2 libdrm-radeon1 libdrm2 libegl1-mesa libgbm1 libgd3 libgl1-mesa-dri
  libgl1-mesa-glx libglapi-mesa libgles1-mesa libgles2-mesa libgme0 libgstreamer-plugins-bad1.0-0 libicu52
  libirs-export91 libisc-export95 libisc95 libisccc90 libisccfg-export90 libisccfg90 liblightdm-gobject-1-0
  liblwres90 libnspr4 libnss3 libobrender29 libobt2 libraspberrypi-bin libraspberrypi-dev libraspberrypi-doc
  libraspberrypi0 libreoffice libreoffice-avmedia-backend-gstreamer libreoffice-base libreoffice-base-core
  libreoffice-base-drivers libreoffice-calc libreoffice-common libreoffice-core libreoffice-draw libreoffice-gtk
  libreoffice-impress libreoffice-java-common libreoffice-math libreoffice-report-builder-bin libreoffice-sdbc-hsqldb
  libreoffice-style-galaxy libreoffice-writer libssl1.0.0 libswscale3 libva1 libwayland-client0 libwayland-cursor0
  libwayland-server0 libxfont1 libxslt1.1 lightdm lxpanel lxpanel-data nodered nuscratch omxplayer openbox openssl
  pcmanfm pi-greeter pi-package pi-package-data pi-package-session pipanel pishutdown pix-icons pix-plym-splash
  pixel-wallpaper python-pil python-rpi.gpio python3-pil python3-rpi.gpio python3-uno raspberrypi-bootloader
  raspberrypi-kernel raspberrypi-net-mods raspberrypi-sys-mods raspberrypi-ui-mods raspi-config rc-gui
  realvnc-vnc-server rpi-chromium-mods sonic-pi uno-libs3 ure va-driver-all vim-common vim-tiny xserver-common
  xserver-xorg xserver-xorg-core xserver-xorg-input-evdev xserver-xorg-input-synaptics xserver-xorg-video-fbdev
  xserver-xorg-video-fbturbo
127 upgraded, 20 newly installed, 0 to remove and 0 not upgraded.
Need to get 382 MB of archives.
After this operation, 147 MB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian/ jessie/main libraspberrypi-bin armhf 1.20161125-1 [329 kB]
Get:2 http://archive.raspberrypi.org/debian/ jessie/main libraspberrypi-dev armhf 1.20161125-1 [396 kB]
Get:3 http://archive.raspberrypi.org/debian/ jessie/main libraspberrypi-doc armhf 1.20161125-1 [31.4 MB]
　（以下略）
```

upgradeの実行中に画面に表示されている通り、不要なパッケージを削除するために```apt-get autoremove```を実行します。autoremoveサブコマンドはaptコマンドには用意されていないので、ここではapt-getコマンドを使います。

```shell-session
pi@raspberrypi:~ $ sudo apt-get -y autoremove
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  libboost-filesystem1.55.0 libboost-program-options1.55.0 libboost-regex1.55.0 libcwiid1 libjs-prettify libllvm3.7
  libqscintilla2-11 libqscintilla2-l10n libqt4-network libqt4-xmlpatterns libqtwebkit4 libruby1.9.1 libruby1.9.1-dbg
  libtcl8.5 libtcltk-ruby1.9.1 libtk8.5 ri1.9.1 ruby1.9.1 ruby1.9.1-dev ruby1.9.1-examples ruby1.9.1-full ruby1.9.3
  supercollider supercollider-common supercollider-ide supercollider-language supercollider-supernova tcl8.5 tk8.5
0 upgraded, 0 newly installed, 29 to remove and 0 not upgraded.
After this operation, 130 MB disk space will be freed.
(Reading database ... 131057 files and directories currently installed.)
Removing supercollider-supernova (1:3.6.6~repack-2-1) ...
Removing supercollider (1:3.6.6~repack-2-1) ...
Removing supercollider-ide (1:3.6.6~repack-2-1) ...
　（以下略）
```

ここでも一度、Raspberry Piを再起動しときましょう。

```shell-session
pi@raspberrypi:~ $ sudo shutdown -r now
```

## rpi-clone

Raspbeey Piをいじくって遊んでる人が一度は呟いたことある心の台詞・・・

**なんでSDカードすぐ死んでしまうん？**


特に電源がシビアなRaspbeey Pi 3の場合、電源アダプタが微妙だとわりとすぐSDカードが死んでしまいます。電源アダプタ気にしていても死にます。SDカードは体弱い子なんです。ここ1週間で2枚逝ったぜ。

せっかくあれこれ設定したりコード書いたりしたSDカードが死んでしまうのもダメージでかいのですが、MakerFaireやOSCなんかのイベント展示で、SDカードが逝ってしまったときの悲しさといったら・・・。転ばぬ先の杖として、是非普段からバックアップを取っておく習慣を持ちましょう。

検索してみるとRaspberry Piのバックアップは色々な方が気にしている様子ですね。多いのがddコマンド（またはddツール）を使うやり方。

[公式ドキュメントのバックアップ](https://www.raspberrypi.org/documentation/linux/filesystem/backup.md)のところにも書いてあるので正攻法ではあるのですが、Raspberry PiからSDカードを取り外して別のマシンでddを使う方法は正直めんどくさいです。少なくとも毎日やるには向いていませんね。

最近のRaspbianですと、GUIであれば[UedaTakeyuki](http://qiita.com/UedaTakeyuki)さんの[こちらの記事（”BackupPi: Raspberry Pi のバックアップとリストアを Raspbery Pi 自身で行う方法”）](http://qiita.com/UedaTakeyuki/items/4a78c38b3070e8ef57e5)でも紹介されている[SD card copier](https://www.raspberrypi.org/blog/another-update-raspbian/)が利用できます。

SD card copierを利用することで、Raspberry PiのUSBポートに接続したSDカードリーダー経由で別のSDカードにバックアップを簡単に取ることが可能です。いちいちRaspberry PiをシャットダウンしたりSDカードを取り出したりしないで済むのは非常にありがたいですね。

しかし、GUIを使わない人にはせっかくのツールも意味がありません。Xだけ飛ばす？いや逆にめんどくさいわ。

普段Raspberry PiにSSHでログインして操作している私みたいな人でも使い易いバックアップツールはないかなーって探したところ、川内 康雄さんの[こんなブログ記事（Raspberry PiでIoTなシステム開発：SDカードのバックアップはrpi-cloneでやろう）](http://www.homu.net/raspberry-piでiotなシステム開発：sdカードのバックアップはrpi/)が見つかりました。

この記事内で紹介されている[rpi-clone](https://github.com/billw2/rpi-clone)を利用すれば、SD card copierと同様のことがコマンドラインで実現できます。

注意点はGitHubのプロジェクトにあるREADME.mdをにも書いてある"rpi-clone does not work with NOOBS."って部分で、要はNOOBS環境のSDカードは対応していません。NOOBS愛好家の皆さんは今回は諦めてください。すみません。先のSD card copierはNOOBS対応です。

rpi-cloneはGitHubで公開されてますのでバックアップ取得元のRaspbianに```git clone```でコピーします。

```shell-session
pi@raspberrypi:~ $ git clone https://github.com/billw2/rpi-clone.git
Cloning into 'rpi-clone'...
remote: Counting objects: 58, done.
remote: Total 58 (delta 0), reused 0 (delta 0), pack-reused 58
Unpacking objects: 100% (58/58), done.
Checking connectivity... done.
pi@raspberrypi:~ $ cd rpi-clone
pi@raspberrypi:~/rpi-clone $ sudo cp rpi-clone /usr/local/sbin
```

rpi-cloneの使い方はこんな感じです。ちなみに、rpi-cloneの実行には管理者権限が必要ですので、sudoを付けて実行します。

```shell-session
pi@raspberrypi:~ $ sudo rpi-clone

usage: rpi-clone sdN {-f|--force-initialize} {-v|--verbose} {-x}
    Example:  rpi-clone sda
    -v - list all files as they are copied.
    -f - force initialize the destination partitions
    -x - use set -x for very verbose bash shell script debugging

    Clone (rsync) a running Raspberry Pi file system to a destination
    SD card 'sdN' plugged into a Pi USB port (via a USB card reader).
    rpi-clone can clone the running system to a new SD card or can
    incrementally rsync to existing backup Raspberry Pi SD cards.

    If the destination SD card has an existing fat16 partition 1 and a
    ext4 partition 2, rpi-clone assumes (unless using the -f option)
    that the SD card is an existing backup with the partitions
    properly sized and set up for a Raspberry Pi.  All that is needed
    is to mount the partitions and rsync them to the running system.

    If these partitions are not found (or -f), then rpi-clone will ask
    if it is OK to initialize the destination SD card partitions.
    This is done by a partial 'dd' from the running booted device
    /dev/mmcblk0 to the destination SD card /dev/sdN followed by a
    fdisk resize and mkfs.ext4 of /dev/sdN partition 2.
    This creates a completed fat16 partition 1 containing all boot
    files and an empty but properly sized partition 2 rootfs.
    The SD card  partitions are then mounted and rsynced to the
    running system.

    The SD card destination partitions will be mounted on /mnt/clone.
    A log will be written to /var/log/rpi-clone.log.
    It's better to avoid running other disk writing programs
    when running rpi-clone.

    Version 1.5
```

バックアップを行う為に、まずは空のSDカードをSDカードリーダに挿入してRaspberry PiのUSBポートに接続します。

その後、```lsblk```コマンドで認識されたSDカードのデバイス名を確認します。

```shell-session
pi@raspberrypi:~ $ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sdb           8:16   1 29.6G  0 disk
└─sdb1        8:17   1 29.6G  0 part
mmcblk0     179:0    0 29.6G  0 disk
├─mmcblk0p1 179:1    0   63M  0 part /boot
└─mmcblk0p2 179:2    0 29.5G  0 part /
```

今回はバックアップ先SDカードのデバイス名がsdbであることが分かりました。
では早速バックアップを取ってみましょう。

```shell-session
pi@raspberrypi:~ $ sudo rpi-clone sdb

The destination disk sdb partition table does not
match the booted disk /dev/mmcblk0 partition table so a
destination disk initialize is required.
The existing destination disk 'sdb' partitions are:
Disk /dev/sdb: 31725MB
Partition Table: msdos

Number  Start   End      Size     Type     File system  Flags
 1      0.00MB  31725MB  31725MB  primary  fat32

*** All data on destination disk sdb will be overwritten! ***

Do you want to initialize the destination disk /dev/sdb? (yes/no): yes
```

初回バックアップの場合は、バックアップ先SDカードにパーティションを作成して良いかの確認ができますので、問題がなければ```yes```と回答して処理を進めます。

```shell-session
Imaging the partition structure, copying 78 megabytes...
78+0 records in
78+0 records out
81788928 bytes (82 MB) copied, 12.4279 s, 6.6 MB/s
Running fsck on /dev/sdb1...
Sizing partition 2 (root partition) to use all SD card space...
Re-reading the partition table failed.: Device or resource busy
mke2fs 1.42.12 (29-Aug-2014)
/dev/sdb2 contains a ext4 file system
	last mounted on / on Sun Dec 18 08:23:52 2016
Creating filesystem with 7725824 4k blocks and 1933312 inodes
Filesystem UUID: 46388a45-32f2-4c02-af8d-41b93ccb51cc
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000

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


/dev/sdb is initialized and resized.  Its partitions are:
Disk /dev/sdb: 31725MB
Partition Table: msdos

Number  Start   End      Size     Type     File system  Flags
 1      4.19MB  70.3MB   66.1MB   primary  fat16        lba
 2      70.3MB  31725MB  31654MB  primary  ext4


Your booted /dev/mmcblk0p2 rootfs existing label:
You may enter a label for the destination rootfs /dev/sdb2:
```

rootfsとなるパーティションのラベル名を聞かれますが、必要が無ければ無回答で構いません。```enter```を入力して先に進めます。

```shell-session
======== Clone Summary ========
Clone mode               :  rsync all files to sdb root file system
Clone destination disk   :  sdb
Clone destination rootfs :  /dev/sdb2 (no label) on /mnt/clone
Clone destination bootfs :  /dev/sdb1 on /mnt/clone/boot
Verbose mode             :  off
===============================
Final check, is it Ok to proceed with the clone (yes/no)?: yes
```

バックアップ（クローン）を実施しても良いか確認が表示されますので、実施してよければ```yes```と回答し、処理を実行します。ちなみに、バックアップには少し時間がかかります。

```shell-session
=> Mounting /dev/sdb2 (no label) on /mnt/clone
=> Mounting /dev/sdb1 on /mnt/clone/boot
===============================
Starting the filesystem rsync to sdb
(This may take several minutes)...
*** Done with clone to /dev/sdb ***
    Started: 09:15:33    Finished: 09:24:26
```

Raspberry Pi 3に32GBのmicroSDカードを利用しているんですが、だいたい10分弱かかりました。

出力結果から分かると思うのですが、やっていることはマウントしたSDカードにrsyncさせています。sdb1（/boot）とsdb2(/)をそれぞれ/mnt/clone/bootと/mnt/cloneに自動マウントしています。必要な場合は、/mnt/clone以下のファイルを編集することで、バックアップ用途だけではなく名前の通りクローニング用途にも便利に使えるわけですね。

```shell-session
Hit Enter when ready to unmount the /dev/sdb partitions...
unmounting /mnt/clone/boot
unmounting /mnt/clone
===============================
```

/dev/sdbをアンマウントしても良いかを確認されますので、問題がなければ```enter```を入力しアンマウントしてバックアップ完了です。

バックアップ後、もう一度```rpi-clone```を実行してみました。2回目はパーティションが不要かつrsyncで差分コピーなので実行時間が短くて済みます。

```shell-session
pi@raspberrypi:~ $ sudo rpi-clone sdb

======== Clone Summary ========
Clone mode               :  rsync modified files to existing sdb file systems
Clone destination disk   :  sdb
Clone destination rootfs :  /dev/sdb2 (no label) on /mnt/clone
Clone destination bootfs :  /dev/sdb1 on /mnt/clone/boot
Verbose mode             :  off
===============================
Final check, is it Ok to proceed with the clone (yes/no)?: yes
=> Mounting /dev/sdb2 (no label) on /mnt/clone
=> Mounting /dev/sdb1 on /mnt/clone/boot
===============================
Starting the filesystem rsync to sdb
(This may take several minutes)...
*** Done with clone to /dev/sdb ***
    Started: 09:30:36    Finished: 09:31:05

Hit Enter when ready to unmount the /dev/sdb partitions...
unmounting /mnt/clone/boot
unmounting /mnt/clone
===============================
```

# まとめ

アップデートやバックアップは自宅サーバの場合ついつい疎かにしてしまうことがあります（私の話）が、年末くらいは可愛がってあげて仲良く新年を迎えましょう。

・・・さてこの記事書く間に壊れたSDカードの代わりをを発注するかな・・・。