【Linux カーネル: OS 基礎入門4】ストレージ管理・ファイル

スポンサーリンク
Linux

本記事は全5回に渡る Linux カーネルの解説のうち第4回「ストレージ管理・ファイル」に関する記事です。

その他の Linux カーネルの解説については以下の記事をご覧ください。

初めに:ストレージのデータにアクセスする方法

Linux カーネルはストレージのデータへアクセスする際に、「ファイル」を利用します。

ストレージにファイルを作成するためには、以下の手順を実施します。

  1. ストレージにパーティションを作成 (fdisk コマンド)
  2. パーティションファイルシステムを作成(mkfs コマンド)
  3. ファイルシステムマウント(mount コマンド)
  4. ファイルシステムファイルを作成

以降では、「ファイルパーティションファイルシステムマウント」についてそれぞれ解説します。

ファイルとは

ファイルとは、データを1つにまとめて名前と関連情報を付与したものです。
デバイス(ストレージ・マウスなど)や他のプロセスとデータをやりとりするために利用します。

プロセスについて詳細を知りたい方は、以下の記事をご覧ください。

ファイルという概念が必要な理由

ファイルという概念があることにより、ファイル名を指定することでストレージに保存されたデータにアクセス可能となります。

ファイルの種類

Linux では通常のファイルとは別に、ディレクトリやデバイス(マウス・ストレージ・モニタ等)を含む様々なものをファイルとして扱います。

ファイルの種類は ls -l コマンドの各行の最初の1文字目のシンボルで確認できます。

ls -l
total 80
-rw-r--r--   1 hoge  staff   149  3 20 13:27 Test.java
drwxr-xr-x   5 teruohas  staff   160  1 15 23:17 test

ファイルには以下の種類があります。

シンボルファイルの種類説明用途
-レギュラーファイル単にデータを読み書き可能な普通のファイルいわゆるファイル
dディレクトリファイルのリストを持つファイルディレクトリを表現
lシンボリックリンクこのファイルへの読み書きは参照先のファイルに反映別名ファイル、ショートカット
cキャラクタデバイスこのファイルへの読み書きは、対応するデバイスと1バイト単位でデータをやりとり(つまりストリーム処理)マウスやキーボードの入力を読み込む
bブロックデバイスこのファイルへの読み書きは、対応するデバイスとブロック単位でデータをやりとり(つまりバッファにバイトを貯める)SSD への読み書き
p名前付きパイプ
(FIFOスペシャル)
このファイルへ書き込まれたデータは同じ OS の他のプロセスで読み出すことが可能プロセス間通信
sソケットこのファイルは別の OS のプロセスから読み書き可能別のOSのプロセスと通信

なお、ストレージ(デバイス)を接続した際に対応するデバイスファイルが自動的に作成されるのは udev という機能によるものです。udev の詳細は以下の記事をご覧ください

ストレージのデータへのアクセスはブロックデバイスファイルを経由してアクセスします。

パーティションとは

パーティションとは、ストレージを分割した領域のことです。

/dev/sdaを「未割り当て」・「/dev/sda1」・「未割り当て」・「/dev/sda2」・「/dev/sda3」の5つのパーティションに分ける例

ストレージのパーティションを分割する利点は以下の2つです。

  • 障害の局所化(別のパーティションに影響を与えない)
    • 例:OS の再インストールする場合に、アプリケーションのパーティションに影響を与えない
  • 空き容量不足の局所化(パーティションごとに別々に空き容量を確保)
    • 例:ログファイルが肥大化しても、OSの領域は確保する

パーティションテーブルの構造

パーティションの構造は次のパーティションの形式によって変化します。

  • MBR(Master Boot Record)パーティションテーブル形式
  • GPT(GUID Partition Table)形式
MBR パーティションテーブルGPT
対応するストレージ容量2TiB8ZiB
プライマリーパーティションの数4128
拡張パーティションありなし
故障耐性なしあり
不正書き込み防止(チェックサム)なしあり
ストレージアクセス方式CHSCHS,LBA
ブートセクタMBRGPTヘッダー
ブートセクタ呼び出し元ファームウェアBIOSUEFI

MBR(Master Boot Record)とは

MBR とは OS をブートするローダーと各パーティションの開始位置が記録されたレコードです。

MBR の構造は以下のとおりです。

GPT ヘッダーとは

GPT とは MBR の置き換えを目的としたレコードです。パーティションを設定可能なストレージの容量が MBR では 2TiB ですが、 GTP では 8ZiB まで増加しています。

GPT の構造は以下のとおりです。

MBR(Master Boot Record)形式とは

MBR パーティションテーブル形式は MBR を利用した古いタイプの形式で、2TiB までのストレージしか管理できない特徴を持ちます。

MBR 形式のパーティションテーブルの構造は以下のとおりです。

GPT(GUID Partition Table)形式とは

GPT 形式は GPTヘッダーを利用した新しいタイプの形式で、8ZiB までのストレージを管理できる特徴を持ちます。

GPT 形式のパーティションテーブルの構造は以下のとおりです。MBR が存在することからわかるように、MBR 形式と互換性があります。

パーティションの作成方法 fdisk

ストレージにパーティションを作成するには、fdisk コマンドを利用します。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk 
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk 
# ブロックデバイスファイル(ファイルとして表現されたストレージ)の一覧を表示
# xvdf ストレージのパーティションを分けることにします。

$ ls /dev/xvd*
/dev/xvda  /dev/xvda1  /dev/xvdf  /dev/xvdf1
# デバイスファイルは "/dev/" 配下に存在します。

$ sudo fdisk /dev/xvdf
#/dev/xvdf ブロックデバイスファイル(ファイルとして表現されたストレージ)のパーティションを操作

コマンド (m でヘルプ): n
# n はnew パーティションを作成という意味です。

パーティションタイプ
p 基本パーティション (0 プライマリ, 0 拡張, 4 空き)
e 拡張領域 (論理パーティションが入ります)
選択 (既定値 p): p
#基本(プライマリー)パーティションと拡張領域があります。基本パーティション選択
#基本パーティションはOSを起動できるパーティションで4つまで作成できます。論理パーティションは5つ目以降のパーティションを作成する際に基本パーティションの番号(1-4)のどれか1つを拡張パーティションとして定義し、その中に論理パーティションを作成します。

パーティション番号 (1-4, 既定値 1): 1
#4つまで作れます。今回は1つ目なので 1

最初のセクタ (2048-20971519, 既定値 2048): 2048
#管理情報に2048セクタ使用されているので、それ以降を指定します。

最終セクタ, +セクタ番号 または +サイズ{K,M,G,T,P}(2048-20971519, 既定値 20971519):+4G
#4G分の領域を確保します。

実行結果は以下のとおりです。

コマンド (m でヘルプ): p
# pはパーティションの情報を確認します。

(中略)
デバイス   起動 開始位置 最後から  セクタ サイズ Id タイプ
/dev/xvdf1          2048  8390655 8388608     4G 83 Linux

コマンド (m でヘルプ): w
#fdiskコマンドを終了します。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk 
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk 
└─xvdf1 202:81   0   4G  0 part 
#xvdf ブロックデバイスファイル(ストレージ)10Gのうち 4Gのパーティションに区切られていることがわかる。

ファイルシステムとは

ファイルシステムとは、ファイルをアクセス・管理するためのカーネルの機能です。
1つのストレージでも、パーティションごとに異なるファイルシステムが作成可能です。

カーネルについて詳細を知りたい方は、以下の記事をご覧ください。

ファイルシステムの一覧

Linux で主に利用するファイルシステムは、RHEL の公式ドキュメントに記載されています。ファイルにアクセスするという基本機能は同じですが、特定のファイルシステムにしか無い機能も存在します。

ファイルシステムの管理 Red Hat Enterprise Linux 8 | Red Hat Customer Portal
本書は、Red Hat Enterprise Linux 8 でファイルシステムを効果的に管理する方法を説明します。

ファイルシステムの構造

ファイルシステムはパーティションごとに設定可能であり、以下のような4つのブロックから構成されます。

ブロック説明
ブートブロックOSをブートするためのファイルが格納
スーパーブロックファイルシステムのメタデータ(種類・サイズ・inodeの数等)を格納
i-node テーブルファイルのメタデータ(ファイルタイプ・サイズ等)の一覧を格納
データブロックファイルのデータを格納

スーパーブロックの確認

スーパーブロックはファイルシステムのメタデータのことです。

利用中のファイルシステムのスーパーブロックは、dump2fs コマンドにオプション -h を付与することで確認可能です。

sudo dumpe2fs -h /dev/xvdf1
Filesystem UUID: ????????-????-????-*** ##ファイルシステムのUUID
Filesystem magic number:  0xEF53
Inode count:              524288 ##inodeの数
Block count:              2096635 ##ブロックの数
Block size:               4096 ##ブロックのサイズ(Byte)
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      1023
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Sat Oct  5 09:13:12 2019 ##ファイルシステム作成日
Last mount time:          Sat Oct  5 09:14:29 2019 ##マウントした日
Last write time:          Sat Oct  5 09:14:29 2019 ##最終書き込みを行った日
Inode size:	          256
(中略)

i-node の確認

i-node はファイルのメタデータのことです。POSIX 標準で規定されているメタデータの一覧は以下のとおりです。

  • ファイルサイズ
  • ファイルタイプ
  • inode 番号(ファイルシステム内でユニークな ID 。ファイルを識別)
  • 当該 inode を指すハードリンクの数
  • デバイス ID(ファイルを格納しているデバイスを識別)
  • ファイルパーミッション
  • ファイル所有者のユーザー ID
  • ファイルのグループ ID
  • 最終 inode 更新時(ctime)、最終ファイル更新時(mtime)、最終参照時(atime) を示すタイムスタンプ群

なお、ファイルの i-node は stat <ファイル名>コマンドで確認可能です。

stat test.txt
  File: `test.txt'
  Size: 4         	Blocks: 8          IO Block: 4096   通常ファイル
Device: 10302h/66306d	Inode: 12960620    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/ec2-user)   Gid: ( 1000/ec2-user)
Access: 2021-04-12 13:04:55.867584473 +0000
Modify: 2021-04-12 13:04:55.867584473 +0000
Change: 2021-04-12 13:04:55.867584473 +0000
 Birth: -

ファイルシステムの主な機能

ファイルシステムの主な機能は以下の3つです。

以降では、ファイルシステムの上記3つの機能について説明します。

ファイルアクセスメカニズム

ファイルアクセスメカニズムはファイルを利用してデータにアクセスする方法のことです。

ファイルアクセスメカニズムには以下の3つが存在します。

  • シーケンシャルアクセス
  • ランダムアクセス(ダイレクトアクセス)
  • インデックスシーケンシャルアクセス

なお、ファイルアクセスメカニズムで利用する情報は i-node から取得します。

シーケンシャルアクセス

シーケンシャルアクセスとは、指定したアドレスから連続でブロックにアクセスする方法です。

https://www.geeksforgeeks.org/file-allocation-methods/

例えば、mai というファイルは 19 番ブロックから 6 ブロック(19, 20, 21, 22, 23, 24)にアクセスすれば良いことがわかります。

  • ○: ストレージのアクセス速度が速い(1度ブロックを探すと順番に読み込むだけ)
  • ✗: ストレージでフラグメンテーションが発生します。

ランダムアクセス(ダイレクトアクセス)

ランダムアクセスとは、指定したアドレスのブロックに直接アクセスする方法です。
各ブロックには次に読み込むブロックの情報があり、ブロックが隣接している必要がありません。

https://www.geeksforgeeks.org/file-allocation-methods/

jeep というファイルは 9番ブロックから読み込みを開始し、9番ブロックには次に16番ブロックを読み込むように書かれていて・・・・最後に25番ブロックを読み込むまでこれを続けます。

  • ○: ストレージのフラグメンテーションの影響を受けない
  • ✗: 読み込み速度が遅い(アクセスするブロックのアドレスを毎回探す必要がある)

インデックスシーケンシャルアクセス

インデックスシーケンシャルアクセスとは、Index ブロックと呼ばれるブロックを利用する方法です。
Index ブロックには、ファイルを構成する全てのブロックのアドレスを順番に格納しています。

jeep というファイルの index ブロックは 19 番です。

index ブロックには次に読み込むべきブロック(1, 9, 10, 16, 25)が記載されています。

  • ○: ストレージのフラグメンテーションの影響を受けない
  • ○: ランダムアクセスより速い
  • ✗: index ブロック用に無駄にスペースを食う

ジャーナリング

ジャーナリングとは、ファイルの更新中に電源断等が発生しても、元のファイルに復元可能な仕組みです。

ジャーナリングが無い時

データブロックを更新した後に電源断が発生すると、データブロックやメタデータ(スーパーブロックi-node テーブル)で不整合が発生する可能性があります。

mv コマンドで /hoge/bar ファイルを /bar に移動させる例を見てみます。

「②/bar のリンクを追加」の状態で電源断が発生すると、inode にある /hoge/bar のハードリンクが削除されないまま処理が終了してしまいます。

ジャーナリングがある時

ジャーナリングを利用すると以下の手順でファイルを更新します。

  1. メインメモリ上のメタデータを更新
  2. メタデータの更新をストレージ上のジャーナルログに書き出す
  3. 実際にファイル(データブロック・スーパーブロックi-node)を更新
  4. ジャーナルログを破棄
1. メインメモリ上のメタデータを更新(ストレージのデータに変化なし)
2. メタデータの更新をストレージ上のジャーナルログに書き出す
3. 実際にファイル(データブロック・スーパーブロックi-node)を更新
3. 実際にファイル(データブロック・スーパーブロックi-node)を更新
4. ジャーナルログを破棄

以上の手順で1〜4のどの段階で電源断が発生してもファイルを元の状態に復元することが可能です。

  1. メインメモリ上のメタデータを更新
  2. メタデータの更新をストレージ上のジャーナルログに書き出す
  3. 実際にファイル(データブロック・スーパーブロックi-node)を更新
  4. ジャーナルログを破棄

1. 「メインメモリ上のメタデータを更新」で電源断

メインメモリのデータが消えるだけです。

ストレージのデータに影響は無いため、最初からもう1度やり直します。

2. 「メタデータの更新をストレージ上のジャーナルログに書き出す」で電源断

ジャーナルログの書き込み完了記録フラグが立ってない場合は、ジャーナルログを廃棄して最初からやり直します。

ストレージの実際のファイル(データブロック・スーパーブロックi-node)は更新していないので問題ありません。

3. 「実際にファイル(データブロック・スーパーブロックi-node)を更新」で電源断

ジャーナルログにある処理がコミットされていない場合は、ジャーナルログを用いてをロールバックします。これにより、ファイルが復元されます。

その後、ジャーナルログを最初から実行します。

4. 「ジャーナルログを破棄」で電源断

ジャーナルログにある処理がコミットされている場合はジャーナルログの廃棄を再開します。

スナップショット

スナップショットは任意の時点でのデータを保存することです。
スナップショットは取得時点ではデータブロックへのポインタを取得するだけなので、バックアップと比較して非常に短い時間で済みます。

スナップショットの種類には以下の2つが存在します。

  • Copy on Write (CoW)
  • Redirect on Write (RoW)

Copy on Write (CoW) スナップショット

Copy on Write スナップショットでは、コピー時にデータブロックのポインタを取得するだけでデータブロックはコピーしません。
データブロックを更新する際に、元のデータを「スナップショット予約済みスペース」にコピーする方法です。

After Modifications は元のデータブロックから B を削除して、D を変更する場合
https://technoscooop.wordpress.com/tag/copy-on-write/

スナップショット予約済みスペースには、元の B と D のデータブロックが保存されます。

ちなみに Windows では VSS(ボリュームシャドウコピー)と呼ばれてます。

ボリューム シャドウ コピー サービス (VSS) について

Redirect on Write (RoW) スナップショット

Redirect on Write スナップショットでも、コピー時にデータブロックのポインタを取得するだけでデータブロックはコピーしません。
データブロックを更新する際に、更新後のブロックを「スナップショット予約済みスペース」に書き込み、オリジナルのポインタをリダイレクトします。(元のデータは更新しません。)

After Modifications は元のデータブロックから B を削除して、D を変更する場合
https://technoscooop.wordpress.com/tag/copy-on-write/

スナップショット予約済みスペースには、更新分の「B(削除), D+, E, F」が記録されます。

バックアップとスナップショットの違い

  • バックアップはデータブロックをコピーします
  • スナップショットはデータブロックのポインタを取得するだけです。その後データブロックが更新される度に、差分・増分のデータブロックを別途保存します。

そのため、バックアップとスナップショットの以下のような違いがあります。

  • スナップショットのほうが取得が速い
  • スナップショットのほうが容量が少ない
  • バックアップはオリジナルのデータが消えても問題ない
    • スナップショットは初回時に全体をバックアップする必要がある

ファイルシステムの作成方法 mkfs

ファイルシステムは mkfs.<ファイルシステム名>で作成できます。上述したファイルシステムの一覧を確認した上で任意のファイルシステムを作成します。今回は ext4 ファイルシステムを例に説明します。

sudo file -s /dev/xvdf1
/dev/xvdf1: data

"data" はファイルシステムが無いことを表します。

次に /dev/xvdf1 パーティションに ext4 ファイルシステムを作成します。

sudo mkfs.ext4 /dev/xvdf1
mke2fs 1.42.9 (28-Dec-2013)
(中略)                         
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

/dev/xvdf1 パーティションに ext4 ファイルシステムが作成できていることを確認します。

sudo file -s /dev/xvdf1
/dev/xvdf1: Linux rev 1.0 ext4 filesystem data

ファイルシステムのマウントとは

マウントとは、ファイルシステムを設定したパーティションとマウントポイント(ディレクトリ)を関連付けることです。

ファイルシステムを設定したデバイスファイルはマウントすることでディレクトリとして利用できます。

マウント方法 mount

df -T|grep -e xvdf1 -e ファイル
ファイルシス   タイプ   1K-ブロック    使用  使用可 使用% マウント位置

/dev/xvdf1 がマウントされていないことがわかったので、マウントポイント(/test ディレクトリ)にマウントする。

sudo mkdir /test
sudo mount /dev/xvdf1 /test
df -T|grep -e xvdf1 -e ファイル
ファイルシス   タイプ   1K-ブロック    使用  使用可 使用% マウント位置
/dev/xvdf1     ext4         3997376   16376 3754904    1% /test

マウント方法 /etc/fstab

ファイルシステムの種類によりますが mount コマンドだけでは、再起動するとマウントの設定が消えます。

そこで、再起動後もマウントの設定を反映させるためには、/etc/fstab ファイルを利用します。

/dev/xvdf1(UUID=1234abcd-1234-as12-234s-123456789abc)パーティションを /test マウントポイントにマウントする設定は以下のとおりです。

sudo blkid /dev/xvdf1
/dev/xvdf1: UUID="1234abcd-1234-as12-234s-123456789abc" TYPE="ext4" PARTUUID="1234abcd-11"
sudo vim /etc/fstab
UUID=1234abcd-1234-as12-234s-123456789abc       /test   ext4    defaults        1       1

/etc/fstab の各フィールドの意味は以下のとおりです。

フィールド説明
第1フィールドデバイス名(UUID もしくはデバイスファイルパス)
第2フィールドマウントポイント
第3フィールドファイルシステムの種類
第4フィールドオプション。defaults はブート時にマウント
第5フィールド1でダンププログラムがファイルシステムをバックアップする
第6フィールド2でOS起動後にfsckチェックを行う
0 - do not check
1 - check immediately during boot
2 - check after boot

最後に

Linux カーネル「ストレージ管理・ファイル」に関する説明は以上となります。

その他の Linux カーネルの機能について知りたい場合は以下の記事をどうぞ。

参考書籍

以下の書籍を参考にしました。

参考サイト

OS Exams Questions with Answers - Tutorialspoint
OS Exams Questions with Answers - These selected questions and answers are prepared from Operating Systems Exam point of view and will also help in quick revisi...
0
Linux
スポンサーリンク
シェアする
ほげてくをフォローする
ほげほげテクノロジー

コメント