Linux 講座 / ファイルシステムのマウントとストレージ管理

マウントとは、ファイルシステムをLinuxのディレクトリパスに接続してアクセス可能にする作業です。接続前には対象とマウントポイントを確認し、接続後にはfindmntで実際のソース・パス・オプションを検証し、保存容量不足は容量とiノードに分けて確認します。

フォーマットする対象を判断する前に、ディスク・パーティション・ファイルシステムの区別を確認してください。以下の実習では、運用ディスクの代わりに新しい一時イメージファイルのみを使用します。

システム設定実習の基準は Ubuntu 26.04 LTS と Rocky Linux 9 系の一般インストール VM です。コンテナ・WSL・別のリリースでは、サービスやパッケージの構成が異なる場合があります。仮想マシン実習環境の作成で、コンソールの復旧とバージョン確認を最初に準備してください。

マウントポイントにあったファイルはどうなるか

空でないディレクトリに別のファイルシステムをマウントすると、元のファイルが削除されるのではなく、マウントが維持されている間は隠されます。マウントを解除すると再び見えるようになります。空の実習用ディレクトリを使用すれば、何が元のファイルで何が接続された記憶領域のファイルか混同しません。パスの実際の保存場所を確認する場合は、そのパスを指定してfindmnt -Tを使用してください。

findmnt -T "$HOME"
df -hT "$HOME"
df -i "$HOME"

上記のコマンドは、ホームパスのマウント情報、読みやすい容量、iノード使用量をそれぞれ表示します。iノードはファイルシステムがファイルオブジェクトを管理する際に使用するメタデータの単位であり、多くの小さなファイルがあるとバイトに余裕があっても不足することがあります。ファイルシステムの種類によって表示方法や制約が異なります。

新しいイメージでマウント・記録・解除を実習する

管理権限のある実習用仮想マシンで実行します。ext4ツールが必要で、コンテナではmount権限がないため失敗することがあります。以下は前回の講義のパスに依存しない独立した例です。イメージファイルのみを初期化し、実際のディスクは指定しません。

以下の全コードをLF改行でmount-lab.shに保存した後、bash mount-lab.shで実行します。Bashとutil-linux・e2fsprogsツール、sudo権限が必要です。Ubuntuではsudo apt install util-linux e2fsprogs、Rockyではsudo dnf install util-linux e2fsprogsでツールを準備できます。ループデバイスを直接割り当て、正確なマウントポイントのソースがそのデバイスと一致する場合にのみファイルを書き込みます。いずれかの準備段階が失敗した場合は書き込み段階に進みません。

#!/usr/bin/env bash
set -u
set -o pipefail
for tool in mktemp truncate mkfs.ext4 losetup mount umount findmnt sudo tee; do
  command -v "$tool" >/dev/null || { printf 'Missing tool: %s\n' "$tool" >&2; exit 1; }
done
sudo -v || exit 1
lab=$(mktemp -d "$HOME/linux-mount-lab.XXXXXX") || exit 1
img=$lab/disk.img
mnt=$lab/mnt
loop=''
cleanup() {
  result=$?
  trap - EXIT
  if [[ -n "$loop" ]]; then
    source=$(findmnt -rn --mountpoint "$mnt" -o SOURCE)
    lookup=$?
    if (( lookup == 0 )) && [[ "$source" == "$loop" ]]; then
      sudo umount -- "$mnt" || result=1
    elif (( lookup != 1 )); then
      printf 'Inspect mount before cleanup: %s\n' "$mnt" >&2
      result=1
    fi
    if findmnt -rn --source "$loop" >/dev/null; then
      printf 'Still mounted; keeping loop device: %s\n' "$loop" >&2
      result=1
    else
      lookup=$?
      if (( lookup == 1 )); then
        sudo losetup --detach "$loop" || result=1
      else
        printf 'Cannot verify loop usage; keeping: %s\n' "$loop" >&2
        result=1
      fi
    fi
  fi
  printf 'Lab retained for inspection: %s\n' "$lab"
  exit "$result"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
truncate -s 128M "$img" || exit 1
mkfs.ext4 -F "$img" || exit 1
mkdir "$mnt" || exit 1
loop=$(sudo losetup --find --show "$img") || exit 1
[[ "$loop" == /dev/loop* ]] || { printf 'Unexpected loop device\n' >&2; exit 1; }
sudo mount -t ext4 -o nodev,nosuid "$loop" "$mnt" || exit 1
source=$(findmnt -rn --mountpoint "$mnt" -o SOURCE) || exit 1
[[ "$source" == "$loop" ]] || { printf 'Mount source mismatch; no write\n' >&2; exit 1; }
printf 'mounted storage\n' | sudo tee "$mnt/note.txt" >/dev/null || exit 1
cat "$mnt/note.txt" || exit 1
sudo umount -- "$mnt" || exit 1
if findmnt -rn --mountpoint "$mnt"; then
  printf 'Mount still present\n' >&2
  exit 1
else
  lookup=$?
  (( lookup == 1 )) || exit 1
fi
printf 'Unmount verified\n'

成功するとmounted storageとUnmount verifiedが表示されます。終了処理では確認済みの自分のマウントだけを解除し、そのループデバイスを使用するマウントがない場合にのみデバイスを切り離します。解除に失敗したり参照エラーがある場合はデバイスを維持し、エラーで終了します。一時フォルダとイメージファイルは自動で削除せず、最後にパスを出力します。再実行時には新しいフォルダを作成します。

この例は、他の管理者と同時にマウントを変更しない個人練習用VMを想定しています。ソース確認と書き込みの間の競合条件まで取り除く運用用のストレージ管理ツールではありません。失敗後は出力されたパスをfindmnt --mountpoint、デバイスをsudo losetup --listで確認し、マウントが残っている場合はファイルを削除しないでください。

busyエラーの場合は使用中の作業から探す

マウント内に現在のディレクトリを置いているシェル、開かれているファイル、実行中のサービスがあると、解除は失敗する可能性があります。まずターミナルでマウント外に移動し、そのファイルを使用しているプログラムを正常終了させます。インストールされている場合はfuser -vm マウントパスまたはlsofで利用者を調査できます。理由も分からずにプロセスを強制終了したり、遅延解除を使用することを基本解決策としないでください。

自動マウントはUUIDと検証手順を併用する

/etc/fstabはファイルシステムのソース・マウントパス・フォーマット・オプション・dump用のフラグ・fsckの検査順を記録します。デバイス名は起動ごとに変わる可能性があるため、サポートされている環境ではUUIDのように安定した識別子を使用します。次の行はext4補助ディスクの記述形式の例であり、実際のUUIDと事前に用意したディレクトリに置き換える必要があります。このイメージ実習ファイルをそのままfstabに登録しないでください。

UUID=REPLACE_WITH_ACTUAL_UUID /srv/data ext4 defaults,nodev,nosuid 0 2

修正前のファイルをバックアップし、sudo findmnt --verify --verboseで構文・アクセス可能な対象を確認します。systemd環境ではfstab変更後にsudo systemctl daemon-reloadで生成ユニットを更新し、必要なマウントのみ意図的にテストします。検証コマンドは次回起動のすべての状況を保証するものではないため、コンソール回復経路を維持してください。

nofailは補助デバイスがない場合に起動を続けるオプションですが、サービスが空のマウントディレクトリにデータを書き込んでしまう問題は解決しません。必須の保存領域であれば、マウントへの依存関係とアプリケーションの起動条件を設計してください。読み取り専用、nodev・nosuid・noexecオプションも目的やプログラムの要求に合わせて選択し、万能のセキュリティ設定として扱わないでください。

dfとduが異なる理由と空き容量整理の順序

df -hT
df -i
du -xhd1 "$HOME" 2>/dev/null | sort -h

dfはファイルシステム全体の割り当て状況を報告し、duは走査できたファイルのディスク使用量を合算します。削除されたがプロセスが開いているファイル、権限のために読み取れないパス、予約スペース・メタデータが差を生むことがあります。du -xは別のファイルシステムへの走査を制限し、大きなツリーでは問い合わせ自体がI/Oを発生させます。権限エラーを隠している場合、合計は不完全になる可能性があります。

大きなファイルを見つけたからといってすぐに削除せず、所有サービスと保存ポリシーを確認してください。ログはログローテーションポリシーで、キャッシュは該当プログラムの整理方法で管理します。実習イメージの整理は、マウント解除を確認してからのみ実行し、fstabを変更した場合はまず元の項目を復元して検証します。

公式ドキュメント