ファイルの上にファイルシステムを作る
目標
ふつうのファイルの上に本物のext4ファイルシステムを作り、スーパーブロックを読んで調整し、中身をのぞきます。最後に、そのファイルシステムをマウントするfstabの行を、UUIDで作成します。
なぜ重要なのか
mkfsは、対象がブロックデバイスなのかふつうのファイルなのかを区別しません。決まった構造を書き込むだけです。この性質のおかげで、特権がなくてもファイルシステムの内部を学べ、実務でもイメージファイルを作って検査することがよくあります。特に、inodeの数はフォーマット時点で固定され、あとから増やせないという事実と、既定の5%という予約ブロックが大容量ディスクでどれほどの無駄なのかは、数字で見て初めて実感できます。
この環境にはmountの権限がないため、実際には取り付けません。その代わり、fstabを正確に書くことを採点します。現場でも、事故はmountコマンドではなく、fstabの1行で起きます。
ステップ
/root/diskディレクトリを作成し、/root/disk/lab.imgを256MiBのスパースファイルとして作成してください。そして、論理サイズと実際の占有サイズを1行ずつ/root/disk/sparse.txtに書いてください(単位はバイトで、論理サイズが先です)。- そのファイルを、ラベル
LABHUBでext4にフォーマットしてください。 - ファイルシステムのUUIDだけを1行で
/root/disk/uuid.txtに書いてください。 - スーパーブロックからブロックサイズ / inode数 / 予約ブロック数の3つの値を取り出し、
/root/disk/super.txtに次の形式で書いてください。BLOCK_SIZE=<값>/INODE_COUNT=<값>/RESERVED_BLOCKS=<값>(プレースホルダーは値です) - 予約ブロックの割合を1パーセントに下げ、変更後の予約ブロック数を
/root/disk/reserved-after.txtに数字1行で書いてください。ステップ4の値より小さい必要があります。 debugfsでイメージのルートにdataディレクトリを作成し、ルートの一覧を/root/disk/rootls.txtに保存してください。一覧にlost+foundとdataの両方がある必要があります。/root/disk/fstab.lineに、このファイルシステムを/mnt/labdataにマウントするfstabの行を1行で書いてください。デバイスはUUID=表記、タイプはext4、オプションにはdefaults、noatime、nofailがすべて含まれ、dumpは0、passは2である必要があります。/root/disk/report.txtを次の5行で作成してください。LABEL=LABHUB/UUID=<3번 값>/BLOCK_SIZE=<4번 값>/INODE_COUNT=<4번 값>/MOUNTPOINT=/mnt/labdata(プレースホルダーは順に、ステップ3の値、ステップ4の値、ステップ4の値です)
参考
truncate -s 256M <파일>、mkfs.ext4 -F -L LABHUB <파일>、blkid <파일>、dumpe2fs -h <파일>、tune2fs -m 1 <파일>の順です(プレースホルダーはファイル名です)。- 実際の占有サイズは
du -B1 <파일>で、論理サイズはdu -B1 --apparent-size <파일>またはstat -c %sで求めます(プレースホルダーはファイル名です)。 debugfs -w -R 'mkdir /data' <파일>で書き込み作業を、debugfs -R 'ls -l /' <파일>で参照を行います(プレースホルダーはファイル名です)。- よくある間違い1:
mkfs.ext4が「not a block special device」と確認を求めてきたとき、-Fなしでは先に進めない場合です。 - よくある間違い2: ステップ7で、UUIDの値に引用符を付けてしまう場合です。fstabでは引用符を使いません。
スパースイメージファイルを作る
/root/diskディレクトリを作成し、/root/disk/lab.imgを256MiBのスパースファイルとして作成してください。そして、論理サイズと実際の占有サイズを1行ずつ/root/disk/sparse.txtに書いてください(単位はバイトで、論理サイズが先です)。
truncateは、実際のブロックを割り当てず、サイズだけを指定します。duの2種類のサイズを比べてみてください。
ext4にフォーマットする
そのファイルを、ラベルLABHUBでext4にフォーマットしてください。
ブロックデバイスではないという警告が出たら、強制オプションが必要です。ラベルを指定するオプションも一緒に使ってください。
UUIDの取り出し
ファイルシステムのUUIDだけを1行で/root/disk/uuid.txtに書いてください。
blkidはファイルにも動作します。出力からUUIDの値だけを取り出すには、フォーマット指定オプションや文字列処理を使ってください。
スーパーブロックを読む
スーパーブロックからブロックサイズ / inode数 / 予約ブロック数の3つの値を取り出し、/root/disk/super.txtに次の形式で書いてください。
BLOCK_SIZE=<값> / INODE_COUNT=<값> / RESERVED_BLOCKS=<값>(プレースホルダーは値です)
dumpe2fsの-hは、スーパーブロックの情報だけを出力します。3つの項目の値がそれぞれ何を意味するのかを、考えてみてください。
予約ブロックの割合の変更
予約ブロックの割合を1パーセントに下げ、変更後の予約ブロック数を/root/disk/reserved-after.txtに数字1行で書いてください。ステップ4の値より小さい必要があります。
tune2fsの-mは、パーセントで指定します。変更後にdumpe2fsで再確認してください。
イメージの中をのぞく
debugfsでイメージのルートにdataディレクトリを作成し、ルートの一覧を/root/disk/rootls.txtに保存してください。一覧にlost+foundとdataの両方がある必要があります。
debugfsは、-Rでコマンドを1つ実行します。書き込み作業には、別のオプションが必要です。
fstabの行の作成
/root/disk/fstab.lineに、このファイルシステムを/mnt/labdataにマウントするfstabの行を1行で書いてください。デバイスはUUID=表記、タイプはext4、オプションにはdefaults、noatime、nofailがすべて含まれ、dumpは0、passは2である必要があります。
6つのフィールドを空白で区切ります。デバイスはUUID=表記で、オプションには3つが入る必要があります。
イメージの要約レポート
/root/disk/report.txtを次の5行で作成してください。
LABEL=LABHUB / UUID=<3번 값> / BLOCK_SIZE=<4번 값> / INODE_COUNT=<4번 값> / MOUNTPOINT=/mnt/labdata(プレースホルダーは順に、ステップ3の値、ステップ4の値、ステップ4の値です)
前のステップで取り出した値を、キー=値としてまとめれば十分です。数字は単位なしで書いてください。