microSDに入ったRaspbianのイメージを能う限りコンパクトに取得

作業OS: Ubuntu Server 12.04
取得OS: Raspbian Stretch lite March 2018

大規模な変更を伴うシステム更新や戯れに無謀な試みを実施する場合、事前にRaspbianのバックアップを取っておきたい。しかし乍ら大容量microSDのイメージをddコマンドで吐き出すと時間とストレージがいくらあっても足りない。従って容量いっぱいまで拡げられたルートパーティションを縮める処理が必要である。

$ lsblk -i
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
(snip)
sdf      8:80   1  60.1G  0 disk
|-sdf1   8:81   1  41.8M  0 part
`-sdf2   8:82   1    60G  0 part

作業の大雑把な流れは

  1. ファイルシステムのサイズを縮小
  2. パーティションサイズを縮小

という具合である。また

パーティションサイズ >= ファイルシステムサイズ

という掟も守らねばならない。計算を誤るとKernel PanicでOSが起動しない惧れがあるから心を砕いて取り組む繊細な仕事である。GPartedが利用できる環境であれば此れを用いてシュッとやるのが早くて確かでずっとコンパクトになるからもう絶対GPartedがよかろうとおもう。

図1. GPartedでシュッと縮小

ファイルシステムのサイズを縮小

/dev/sdfとして認識されたmicroSDのパーティション構成を具に確認するとこうである。

$ sudo fdisk -l /dev/sdf
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304   125958143    62929920   83  Linux

ブートパーティションが/dev/sdf1、ルートパーティションが/dev/sdf2のようである。ルートパーティションのサイズをシリンダ数とセクタサイズから求めると概ね60GiBであった。

$ echo 'scale = 3; (125958143 - 98304 + 1) * 512 / 1024 ^ 3' | bc
60.014

あとは/dev/sdf2をresize2fsコマンドでぎゅうと縮める。なおresize2fsの実施に先立ちe2fsckコマンドを実施しておかないと「Please run ‘e2fsck -f /dev/sdf2’ first.」などと言われて終いである。

$ sudo e2fsck -f -y -v -C 0 /dev/sdf2
図2. e2fsckで/dev/sdf2をチェック

作業するにあたっては無闇に縮小できないので、実際に使用されている容量を前もって把握しておく。tune2fsから使用済みのブロック数を割り出し、容量を求めるとだいたい2.01GiBを使用中というふうに観察できる。

$ sudo tune2fs -l /dev/sdf2
(snip)
Block count:              15732480
Free blocks:              15204597
Block size:               4096

$ echo 'scale = 3; (15732480 - 15204597) * 4096 / 1024 ^ 3' | bc
2.013

ぴしゃり2.01GiBに縮めてはOS起動後に空き容量が不足し禄な操作が許されない。も少しゆとりをもたせて2.1GiBに定めた。しかし乍らそのままresize2fsに渡すと「resize2fs: Invalid new size: 2.1G」というエラーとなった。どうもresize2fsは自然数しか受け付けない情勢である。さりとて3GiBでは目標値より一寸隔たりが大きい。そこでMiB単位に改める。2.1GiBは2.1 * 1024 = 2150.4MiBであるから2150Mとすれば概ねよかろうと思う。これで無事縮小処理が始まった。

$ sudo resize2fs -p /dev/sdf2 2150M
図3. resize2fsでファイルサイズを縮小

パーティションサイズを縮小

ルートパーティションのサイズを縮めるにはfdiskを用いる。現在のルートパーティションを一旦削除して新たに作り直す。終了セクタはファイルシステムのサイズが収まるよう2200MiBとした。

$ sudo fdisk /dev/sdf
Command (m for help): p
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304   125958143    62929920   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (2048-125958143, default 2048): 98304
Last sector, +sectors or +size{K,M,G} (98304-125958143, default 125958143): +2200M

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

このあとサイズを指定せずにresize2fsを実行すると、ファイルシステムのサイズをパーティションサイズに一致するよううまい具合に膨らませてくれるようである。

$ sudo resize2fs -p /dev/sdf2
$ sudo fdisk -l /dev/sdf
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304     4603903     2252800   83  Linux

これで漸くルートパーティションのサイズがコンパクトにまとまった。あとはブロックサイズ512byte、4603903+1セクタだけddコマンドで書き出せば終いである。GPartedの仕事にくらぶれば大雑把ではあるけれども1bitをシビアに争う要請ではないから良しとしたいところである。

$ sudo dd if=/dev/sdf of=raspbian.img bs=512 count=4603904

なおresize2fsのマニュアルを読み進めているとKiBやGiBに対して風当たりの強い様が見られて大変興味深い。

Note: when kilobytes is used above, I mean real, power-of-2 kilobytes, (i.e., 1024 bytes), which some politically correct folks insist should be the stupid-sounding “kibibytes”. The same holds true for megabytes, also sometimes known as “mebibytes”, or gigabytes, as the amazingly silly “gibibytes”. Makes you want to gibber, doesn’t it?

Ubuntu Manpage: resize2fs – ext2/ext3/ext4 file system resizer

参考:

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください