1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Raspberry Piの起動SSDをddでバックアップする

Last updated at Posted at 2021-09-29

1. はじめに

色々と試行錯誤する中で起動メディアを作り直す作業を10回以上行いましたが、今後もまだまだ同じことを繰り返しそうなので、せめて毎回行う定型的な作業が終わった状態の起動メディアをバックアップすることにします。

1.1. 改訂履歴

2021/09/30 ファイルシステムを縮小する際に-Mオプションを使用し、自動的に最小サイズになるようにしました

2. 用意した物

  • Raspberry Piとは別のLinux環境 (CentOS 7.9)

USB 3.xが利用できる実機なりVMなりがあれば作業が早そう。

3. 作業の流れ

すべてLinux環境での作業

  1. 大きなパーティションを縮小する
  2. ddで読み取り、圧縮し、ファイルに書き出す

4. 大きなパーティションを縮小する

4.1. 装置名を確認する

USBハードディスクケースに入ったSSDを別のLinuxにつなぐ前に、現状を見ておきます。

# ls -al /dev/sd*
brw-rw---- 1 root disk 8,  0  9月 29 21:02 /dev/sda
brw-rw---- 1 root disk 8,  1  9月 29 21:02 /dev/sda1
brw-rw---- 1 root disk 8,  2  9月 29 21:02 /dev/sda2
brw-rw---- 1 root disk 8,  3  9月 29 21:02 /dev/sda3
brw-rw---- 1 root disk 8, 16  9月 29 21:02 /dev/sdb
brw-rw---- 1 root disk 8, 17  9月 29 21:02 /dev/sdb1

このシステムには/dev/sda/dev/sdbが接続されています。
USBハードディスクケースに入ったSSDをつなぎます。

# ls -al /dev/sd*
brw-rw---- 1 root disk 8,  0  9月 29 21:02 /dev/sda
brw-rw---- 1 root disk 8,  1  9月 29 21:02 /dev/sda1
brw-rw---- 1 root disk 8,  2  9月 29 21:02 /dev/sda2
brw-rw---- 1 root disk 8,  3  9月 29 21:02 /dev/sda3
brw-rw---- 1 root disk 8, 16  9月 29 21:02 /dev/sdb
brw-rw---- 1 root disk 8, 17  9月 29 21:02 /dev/sdb1
brw-rw---- 1 root disk 8, 32  9月 29 21:03 /dev/sdc
brw-rw---- 1 root disk 8, 33  9月 29 21:03 /dev/sdc1
brw-rw---- 1 root disk 8, 34  9月 29 21:03 /dev/sdc2

/dev/sdcが増えたので、これが今接続したSSDなのでしょう。
とすれば、/dev/sdc1はbootパーティション、/dev/sdc2がルートパーティションです。

4.2. ルートパーティションをチェックする

# e2fsck -f /dev/sdc2
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: 39288/29263600 files (0.2% non-contiguous), 2230322/122030086 blocks

問題ないようです。

4.3. ルートパーティションのファイルシステムを縮小する

resize2fs -Mとすることで、最小サイズになります。
古いresize2fsでは機能しないかもしれません。
man resize2fsで確認してみてください。

# resize2fs -M /dev/sdc2
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdc2 to 647400 (4k) blocks.
The filesystem on /dev/sdc2 is now 647400 blocks long.

647400 (4k) blocks.ということは、4k=4096byteなので、セクタ(512byte)に直すと647400 * 4096 / 512 = 5179200です。
5179200という数字は、後で使います。

4.4. ルートパーティションを縮小する

# fdisk /dev/sdc

The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

コマンド (m でヘルプ): 

pを入力し、現状のパーティションを表示します。

コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480   976773167   488120344   83  Linux

コマンド (m でヘルプ): 

現状のルートパーティション/dev/sdc2は、始点が532480、終点が488120344です。
これを一度削除します。削除すると言ってもデータが消えるわけではありません。
削除するのはパーティションの「開始位置」「終了位置」の記録です。
dを入力します。

コマンド (m でヘルプ): d

次にパーティション番号を入力します

パーティション番号 (1,2, default 2): 2
Partition 2 is deleted

コマンド (m でヘルプ): 

削除されました。
次に新しいパーティションの位置を定義します。
nを入力します。

コマンド (m でヘルプ): n

次にパーティションのタイプを指定します。
プライマリパーティションを作成しますので、pを入力します。

Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p

次にパーティション番号を指定します。
2を入力します。

パーティション番号 (2-4, default 2): 2

次にパーティションの始点を指定します。
ここで入力するのは、以前の手順で表示したパーティション情報の数値です。

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480   976773167   488120344   83  Linux

以前あった/dev/sdcと始点は同じですので、この例では532480を入力します。
環境により異なる可能性がありますので、注意してください。

最初 sector (2048-976773167, 初期値 2048): 532480

次にパーティションの終点を指定します。
ここで入力するのは、以前の手順で縮小した始点のセクタ数 + ファイルシステム上のセクタ数です。
今回は532480 + 5179200 = 5711680となります。

しかし今回のように、始点セクタ数が偶数でファイルシステム上のセクタ数も偶数の場合、実際に確保されるセクタ数は奇数となり、pコマンドでパーティションを表示させた際に+が表示されます。

コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480     5711680     2589600+  83  Linux

コマンド (m でヘルプ): 

この場合、入力する値には1を加えてください。
今回の場合、5711681を入力します。

Last sector, +sectors or +size{K,M,G} (532480-976773167, 初期値 976773167): 5711681
Partition 2 of type Linux and of size 2.5 GiB is set

コマンド (m でヘルプ): 

始点と終点がそれぞれ指定されました。
ここまでの作業結果を確認します。
pを入力し、パーティション情報を表示します。

コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480     5711681     2589601   83  Linux

コマンド (m でヘルプ): 

/dev/sdc2の終点が976773167から5711681になりました。
ここまでの結果をディスクに書き込み、反映させます。

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
# 

無事おわりました。

5. ddで読み取り、圧縮しながら書き出す

今回使うddコマンドの書式はこうです。

dd if=入力デバイス bs=ブロックサイズ count=読み取り回数

そしてpvで進捗を出力しつつgzipで圧縮しながら出力します。
pvがなければaptdnfでインストールしましょう。

dd if=入力デバイス bs=ブロックサイズ count=読み取り回数 | pv | gzip > ./バックアップ先ファイル名.gz

gzipの替わりにpigzを使うと早いそうです。
なければインストールしましょう。

https://qiita.com/taiyodayo/items/7c60c9b3bc00b13baf43

dd if=入力デバイス bs=ブロックサイズ count=読み取り回数 | pv | pigz > ./バックアップ先ファイル名.gz

入力デバイスはパーティションではなく装置全体を示す/dev/sdcです。
ブロックサイズはある程度大きい方が早いのですが、読み取り回数にも関係します。
間違えたくないので、先ほどのパーティションの数値を流用できるようなブロックサイズにします。

  • 終点5711681(Units = sectors of 1 * 512 = 512 bytes)までを読み取ればいい
  • bs=512とすると5711681回読み取らなければならないので時間がかかりそう
  • I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイトと書いてあるので、そもそもbs=512は小さすぎる
  • bsを10000倍の大きさにしてbs=5120000とすれば、読み取り回数は5711681 / 10000 = 571.1681(回)となる
  • 切り上げて572なので、終点の5711681をコピペして5文字消して1足した数字を書く

書いていてとても意味のないことを頑張っている気がしてきましたが、将来見返した時にはきれいに忘れていそうなので。
最終的にこうなります。

dd if=/dev/sdc bs=5120000 count=572 | pv | pigz > ./raspi_$(date "+%Y%m%d")-$(date "+%H%M").gz

結果はこうでした。

# dd if=/dev/sdc bs=5120000 count=572 | pv | pigz > ./raspi_$(date "+%Y%m%d")-$(date "+%H%M").gz
572+0 レコード入力
572+0 レコード出力
2928640000 バイト (2.9 GB) コピーされました、 56.8524 秒、 51.5 MB/秒

bsを1桁減らし、countを1桁増やして試してみましたが、時間はほとんど変わりませんでした。

# dd if=/dev/sdc bs=512000 count=5720 | pv | pigz > ./raspi_$(date "+%Y%m%d")-$(date "+%H%M").gz
5720+0 レコード入力
5720+0 レコード出力
2928640000 バイト (2.9 GB) コピーされました、 57.2286 秒、 51.2 MB/秒

3割程度に圧縮されています。

-rw-r--r--   1 root root   939996203  9月 30 01:39 raspi_20210930-0138.gz

6. バックアップのために小さくした諸々を戻しておく

# fdisk /dev/sdc

The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480     5711681     2589601   83  Linux

コマンド (m でヘルプ): d
パーティション番号 (1,2, default 2): 2
Partition 2 is deleted

コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)

コマンド (m でヘルプ): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
パーティション番号 (2-4, default 2): 2
最初 sector (2048-976773167, 初期値 2048): 532480
Last sector, +sectors or +size{K,M,G} (532480-976773167, 初期値 976773167): 
初期値 976773167 を使います
Partition 2 of type Linux and of size 465.5 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sdc: 500.1 GB, 500107862016 bytes, 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
Disk label type: dos
ディスク識別子: 0xb6da2e9c

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdc1            8192      532479      262144    c  W95 FAT32 (LBA)
/dev/sdc2          532480   976773167   488120344   83  Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。

# resize2fs /dev/sdc2
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdc2 to 122030086 (4k) blocks.
The filesystem on /dev/sdc2 is now 122030086 blocks long.

Raspberry Piに取り付け、確認。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        459G  1.5G  439G    1% /
devtmpfs         326M     0  326M    0% /dev
tmpfs            455M     0  455M    0% /dev/shm
tmpfs            182M  684K  182M    1% /run
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
/dev/sda1        253M   30M  223M   12% /boot
tmpfs             91M     0   91M    0% /run/user/1000

/dev/root、サイズ459Gを確認。

今日はここまで。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?