1. はじめに
色々と試行錯誤する中で起動メディアを作り直す作業を10回以上行いましたが、今後もまだまだ同じことを繰り返しそうなので、せめて毎回行う定型的な作業が終わった状態の起動メディアをバックアップすることにします。
1.1. 改訂履歴
2021/09/30 ファイルシステムを縮小する際に-M
オプションを使用し、自動的に最小サイズになるようにしました
2. 用意した物
- Raspberry Piとは別のLinux環境 (CentOS 7.9)
USB 3.xが利用できる実機なりVMなりがあれば作業が早そう。
3. 作業の流れ
すべてLinux環境での作業
- 大きなパーティションを縮小する
- 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
がなければapt
やdnf
でインストールしましょう。
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
を確認。
今日はここまで。