【趣旨】
RaspberryPi, OrangePi, BanaPi などで、複数台を構築する際に利用。
〇 利点
- HDD保管領域の容量節約
- イメージをSDカードへ展開する時間の短縮
〇 欠点
- 面倒くさい
- HDD保管領域や作業時間が十分にに取れる場合は、
マスターとなるSDカードを空のSDカードへディスクコピーしたほうが簡単
※ 滅多に行わないので備忘として残す
【作業環境】
手頃なLinuxOS端末 -- 母艦OSと呼称。
※ SDカードで使用されているファイルシステムは、サポート可能である事。
※ FAT, ext4など
【情報収集】
- SDカードのOSはArmbian
- SDカードの総容量は32GB
- Loaderはu-bootが使用されている。
母艦OSにSDカード(USB変換アダプタなどで)を認識。認識デバイス /dev/sdiと仮定。
# fdisk -l /dev/sdi
ディスク /dev/sdi: 29.2 GiB, 31331450880 バイト, 61194240 セクタ
単位: セクタ (1 * 512 = 512 バイト) ・・・①
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0xb765619f
デバイス 起動 開始位置 終了位置 セクタ サイズ Id タイプ
/dev/sdi1 8192 1056767 1048576 512M ea Rufus alignment ・・・②
/dev/sdi2 1056768 60555263 59498496 28.4G 83 Linux
# lsblk -f /dev/sdi
NAME FSTYPE LABEL UUID MOUNTPOINT
sdi
|-sdi1 vfat armbi_boot A63B-8E78
|-sdi2 ext4 armbi_root 1364b180-84ba-4ee5-b238-8aff727daf80
# mkdir /mnt/{sdi1,sdi2}
# mount /dev/sdi1 /mnt/sdi1
# mount /dev/sdi2 /mnt/sdi2
# df -h /mnt/sdi1 /mnt/sdi2
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/sdi1 511M 70M 442M 14% /mnt/sdi1 ・・・③
/dev/sdi2 28G 1.8G 26G 7% /mnt/ddi2 ・・・④
# umount /mnt/sdi1
# umount /mnt/sdi2
# rmdir /mnt/sdi1 /mnt/sdi2
【バックアップ】
母艦OSの作業場所は、
・バックアップ /home/user01/backup
(1) MBR領域の取得
第1パーティションの開始セクターは8192。(【情報収集】 ②)
0~8191 までが、Loaderが起動されるまでの情報が保存されている。
- fdiskの結果(【情報収集】 ①) から、1セクタは512Byte よって、bs=512
- セクターの0-8191まで取得したいので、count=8192
# dd if=/dev/sdi of=/home/user01/backup/dd-mbr-8192.img bs=512 count=8192
(2) 第1パーティションの取得
vfat領域の為、tarで取得
# mkdir /mnt/SDCARD
# mount /dev/sdi1 /mnt/SDCARD
# cd /mnt/SDCARD
# tar zcf /home/user01/backup/sdi1.tar.gz ./
# cd /
# umount /mnt/SDCARD
# rndir /mnt/SDCARD
(2) 第2パーティションの取得
ext4領域の為、dumpコマンドで取得。(この辺りは好みで)
# /sbin/dump -0u -z9 -b 20 -f /home/user01/backup/sdi2.dump /dev/sdi2 && sync
【イメージ作成】
母艦OSの作業場所は、
・作成場所 /home/user01/work
(1) ディスク容量の確保
今回2つのパーティションを作成するが、作成後に拡張出来るのは第2パーティション以降の空き容量を第2パーティションとする事が出来る。
よって第1パーティションは後で拡張出来な事を考慮する。(【情報収集】 ③ , ④ )
- 第1パーティションは、そんまま512MB
- 第2パーティションは、2GB
計、2.5GBの領域を準備する。
# dd if=/dev/zero of=/home/user01/work/master.img bs=1M count=2500 && sync
→ fallocate コマンドでも良いが、最終的にxzで圧縮するので/dev/zero のほうが圧縮率が良さそう?
2500+0 レコード入力
2500+0 レコード出力
2621440000 bytes (2.6 GB, 2.4 GiB) copied, 1.4998 s, 1.7 GB/s
# losetup -f /home/user01/work/master.img
# losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 0 /home/user01/work/master.img 0 512
(2) MBR領域の展開
バックアップしたMBRのイメージ dd-mbr-8192.img を展開する。
# dd if=/home/user01/backup/dd-mbr-8192.img of=/dev/loop0
8192+0 レコード入力
8192+0 レコード出力
4194304 bytes (4.2 MB, 4.0 MiB) copied, 0.086115 s, 48.7 MB/s
(3) fdiskで領域の修正
# fdisk -l /dev/loop0
ディスク /dev/loop0: 2.5 GiB, 2621440000 バイト, 5120000 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0xb765619f
デバイス 起動 開始位置 終了位置 セクタ サイズ Id タイプ
/dev/loop0p1 8192 1056767 1048576 512M ea Rufus alignment
/dev/loop0p2 1056768 60555263 59498496 28.4G 83 Linux
/dev/loop0 の総容量は2.5GBに対して、強制的に32GBのSDカードのMBR領域を上書きしたので、
第2パーティション /dev/loop0p2 の終了位置 60555263が、最大5120000 セクタを超えている。
第2パーティションを削除/新規作成して正しい状態に戻す。
# fdisk /dev/loop0
p (確認)
d -> 2 (第2パーティション削除)
n -> p -> 2 -> 1056768(開始位置) -> 5119999(終了位置) ※値は既定値最大
p (確認)
w (書込み)
パーティション情報の再読み込みに失敗しました。: Invalid argument
カーネルは古い情報を使用しています。新しい情報を利用するには、システムを再起動するか、もしくは partprobe(8) または kpartx(8) を実行してください。
(4) 第1/第2パーティションのファイルシステム作成
使用している母艦OSでは、/dev/loop0p1, /dev/loop0p2 が作成出来ずに、partprobe or kpartx で認識させる事になる。
# kpartx -a /dev/loop0
# ls -l /dev/mapper/loop0p*
lrwxrwxrwx 1 root root 7 11月 24 07:43 /dev/mapper/loop0p1 -> ../dm-0
lrwxrwxrwx 1 root root 7 11月 24 07:43 /dev/mapper/loop0p2 -> ../dm-1
パーティションラベルとUUIDを指定して、ファイルシステムを作成
# mkfs.vfat -n armbi_boot -i A63B8E78 /dev/mapper/loop0p1
# mkfs.ext4 -L armbi_root -U 1364b180-84ba-4ee5-b238-8aff727daf80 /dev/mapper/loop0p2
パーティションラベルとUUIDが指定した通りとなっているか確認
# lsblk -i -f /dev/loop0
NAME FSTYPE LABEL UUID MOUNTPOINT
loop0
|-loop0p1 vfat armbi_boot A63B-8E78
`-loop0p2 ext4 armbi_root 1364b180-84ba-4ee5-b238-8aff727daf80
(5) 第1/第2パーティションのデータリストア
# mkdir /mnt/{sdi1,sdi2}
# mount /dev/sdi1 /mnt/sdi1
# mount /dev/sdi2 /mnt/sdi2
# cd /mnt/sdi1
# tar zxfv /home/user01/backup/sdi1.tar.gz
# cd /mnt/sdi2
# restore -r -f /home/user01/backup/sdi2.dump && sync
# rm restoresymtable
# cd /
# umount /mnt/sdi1
# umount /mnt/sdi2
# rmdir /mnt/sdi1 /mnt/sdi2
(6) loop0デバイスの解除
# kpartx -d /dev/loop0
# ls -l /dev/mapper/
合計 0
crw------- 1 root root 10, 236 11月 24 07:43 control
# losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 0 /home/user01/work/master.img 0 512
# losetup -d /dev/loop0
# losetup -l
(loop0デバイスが未割当状態を確認)
# ls -lh /home/user01/work
-rw-r--r-- 1 root root 2.5G 11月 24 08:17 master.img
(7) 中間ファイル削除
# rm -fr /home/user01/backup
# xz /home/user01/work/master.img
# ls -lh /home/user01/work
-rw-r--r-- 1 root root 535M 11月 24 08:17 master.img.xz
以上で完成である。
SDカードのディスクイメージ 32GBが、圧縮させると535MBとなるので保管や配布等には向いている。