ストレージデバイス(ブロックストレージ)

対象読者

・ストレージデバイスって何?具体的な写真や例で見てみたい
・コンピュータがストレージデバイスにアクセスする仕組みを知りたい
・腰を据えてストレージデバイスの論理フォーマットについて学習したい

キーワード: バス、パーティション、ファイルシステム、マウント

ストレージデバイス って何?

コンピュータがデータを書き込んだり、読み取ったりできるデバイス(機械)です。有名なストレージデバイスは下記の通りです。

・USBメモリ
・CD/DVD
・HDD/SSD
・SDカード

ストレージデバイスはコンピュータからバス(接続部分)を通じてデータを読み書きします。有名なバスは下記の通りです。

・USB(ユニバーサル シリアル バス)
・PCI Express
・SATA (シリアルATA)

バスは形や通信方法などルールが決まっています。以下にバスとストレージデバイスが接続する様子を掲載します。

■USB(バス, 写真左)とUSBメモリ(ストレージデバイス, 写真右)を接続する様子
USB(バス)はノートパソコンでは側面に付いていることが多いです。下記の写真はコンピュータを分解した時の写真です。

■SATA(バス, 写真左)とSSD(ストレージデバイス, 写真右)を接続する様子
SATAやSSDはコンピュータの外から見えることはほとんどないです。コンピュータを分解すると中身は下記の写真のようになっています。

■SATA(バス, 写真左)とDVDドライブ(写真右)を接続する様子
バスと接続するものはストレージでなくても良いです。DVDドライブはDVD(ストレージ)からデータを読み取るデバイスです。読み取ったデータをSATAケーブルを通じてSATA(バス)に送ります。

前述した通り、バスは形や通信方式が決まっているため、異なるバス同士は接続できません。(例:USBバスを持つUSBメモリはSATAに接続端子の形が違うため接続できません。)

コンピュータの世界のストレージデバイス

今までは現実世界にあるストレージデバイスとバスを見てきました。ここからはコンピュータの世界でストレージデバイスがバスを通じてどのように扱われているのか説明します。

コンピュータがストレージデバイスにファイルを保存するための準備として次の4つのSTEPが必要になります。

STEP 1. ストレージデバイスをバスに接続 (先ほど現実世界で接続しました)
STEP 2. ストレージデバイスに対してパーティションを作成
STEP 3. パーティションにファイルシステムを作成
STEP 4. パーティションをマウント

パーティション、ファイルシステム、マウントについては後述します。ちなみにSTEP2~4のことを論理フォーマットと言います。MacやWindowsではSTEP1 を実施するとSTEP 4まで自動でやってくれます。(手動でフォーマットもできます。)USB メモリはUSBに接続した瞬間に自動で使える状態になるし、CDやDVDもドライブに入れた瞬間に自動で使える状態になる。ジョブズやゲイツよ、ありがとう。

以下では手動でSTEP 4まで実施する必要のあるLinuxの場合を例に説明します。

前提知識

ストレージデバイスはセクタと呼ばれる単位でデータを記録する。1セクタ = 512KBとすることが多い。このようにストレージデバイス ではセクタ(ブロック)単位で記録を行うのでブロックストレージと呼ばれます。

STEP 1. ストレージデバイスをバスに接続

先ほど現実世界において下図のようにバスとブロックストレージ (SSD, USBメモリ)を接続しました。

接続されたブロックストレージはコンピュータ上でどのように認識されているのでしょうか?次にコマンド lsblk を使用して接続されているブロックストレージを確認します。

$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 16G 0 disk  ## 1
└─xvda1 202:1 0 16G 0 part / ##3
xvdf 202:80 0 10G 0 disk  ## 2

##1「xvda 202:0 0 16G 0 disk」
ブロックストレージ名: xvda, 容量: 16Gのブロックストレージが接続されていることを表します。ここではSSDのことです。

ちなみにブロックストレージ名はOSが勝手にxvdaなど名前をつけています。

##2 「xvdf 202:80 0 10G 0 disk」
ブロックストレージ名: xvdf, 容量: 10Gのブロックストレージが接続されていることを表します。ここではUSBメモリのことです。

Linuxではデバイス(ストレージデバイスに限らず)は全てファイルとして管理されます。全てのデバイスは/devディレクトリにファイルとして格納されています。USBメモリ xvdf であれば/dev/xbdfファイルです。

##3「└─xvda1 202:1 0 16G 0 part /」

ブロックストレージ xvdaをパーティションで切ったものです。パーティションについてはSTEP2で解説します。

STEP 2. ストレージデバイスに対してパーティションを作成

そもそもパーティションとは

ストレージデバイス(ブロックデバイス)の保存領域を分割する区切りことです。これによって1つのストレージデバイスで、コンピュータには複数のストレージデバイスが接続されているように見えます。

パーティションの使い道の例

1つ目のパーティション: OS
2つ目のパーティション: アプリケーション
3つ目のパーティション: ログ

パーティションを分けることでログが肥大化してもOSやアプリケーションの保存領域に書き込むことはありません。ログのパーティションを全部削除してもOSやアプリケーションのデータが吹き飛ぶことはありません。

まずはパーティションが無い10GBのUSBメモリ (上述した ##2 「xvdf 202:80 0 10G 0 disk)を見ていきましょう。

このUSBメモリ(ブロックストレージ)のパーティションで区切ってみます。(" ## " は私のコメントです)

$ sudo fdisk /dev/xvdf
##/dev/xvdf(USBメモリ) のパーティションを操作

コマンド (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
##4GiB = 4 * 2^30 バイト = 4294967296バイト
4294967296vバイト / 512 セクタ = 8388608 セクタ

図示すると下記の感じ

OSから認識しているブロックストレージがどのように変化したのか見てみましょう。

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

$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 16G 0 disk
└─xvda1 202:1 0 16G 0 part /
xvdf 202:80 0 10G 0 disk
└─xvdf1 202:81 0 4G 0 part
##USBメモリ(xvdf) 10Gのうち 4Gのパーティションが区切られていることがわかる。

STEP 3. パーティションにファイルシステムを作成

ファイルシステムとはブロックストレージをファイル形式でアクセスするようにしたものです。本来ブロックストレージとはセクタと保存領域を指定してデータを保存します。例えば512000KB(1000セクタ)の動画を保存する時には2048セクタから3047セクタ目までの1000セクタに保存してくれという命令を出します。

動画を再生する時には2048セクタ目から3047セクタ目を読み取ってくれと命令するのです。全てのデータについて何セクタ目からどのぐらいの容量が保存されているのか覚えておかなければいけません。データが増えると覚えてられませんよね?このままでは使いにくすぎますよね?そこでファイルシステムの登場です。

データにアクセスする際に必要なデータや人間にわかりやすいデータをひとまとまりにしてファイルという単位で管理します。ファイルには下記のような情報が含まれます。

- データの先頭セクタ (アクセスに必要)
- データのサイズ (アクセスに必要)
- ファイル名 (どんなデータかわかるように名前をつけられる)
- 保存ディレクトリ (保存場所に名前をつけられる)

本来ディレクトリやファイル名などはデータにアクセスする上で必要ありません。しかし人間がデータを管理する上で名前が無いと不便なので付加情報としてファイルにまとめられています。

ということで人間がアクセスしやすいようにファイルシステムを作成します。ファイルシステムには様々な種類があります。興味がある方は調べてみてください。今回はxfsというファイルシステムを使用します。

$ sudo file -s /dev/xvdf1
/dev/xvdf1: data
##ファイルシステムを確認するコマンドです。 /dev/xvdf1 は先ほどパーティションを設定したUSBメモリの4GiBの領域です。dataはファイルシステムが設定されていない状態です。

$ sudo mkfs -t xfs /dev/xvdf1
##好きなファイルシステムを設定します。 今回は xfsを /dev/xvdf1に設定します。

$ sudo file -s /dev/xvdf1
/dev/xvdf1: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)
##正しくファイルシステムが設定できているのか確認します。
ファイルシステム XFSが登録されていることがわかります。

STEP 4. パーティションをマウント

STEP3でブロックストレージにファイルシステムを登録しましたが、OSはブロックストレージがどのディレクトリに紐づいているのかわかりません。そのため、OSにディレクトリとブロックストレージの関係を教えてやる必要があります。これがマウントです。

USBの1つ目のパーティションをディレクトリ /USB1_Partition1にマウントします。

$ df -T
ファイルシス タイプ 1K-ブロック 使用 使用可 使用% マウント位置
(中略)
/dev/xvda1 xfs 16764908 3611384 13153524 22% /
##マウントされているファイルシステムを確認します。
xvda1(SSD)がファイルシステムxfsを使用して、すでに ディレクトリ "/"にマウントされていることがわかります。xvdf1(USBメモリ)は表示されていないため、マウントされていないことがわかります。

$ sudo mkdir /USB1_Partition1
##ディレクトリ(USB1_Partition1) を作成します。

$ sudo mount /dev/xvdf1 /USB1_Partition1
## ブロックストレージ /dev/xvdf1 をディレクトリ /USB1_Partition1にマウントします。

$ df -T
ファイルシス タイプ 1K-ブロック 使用 使用可 使用% マウント位置
(中略)
/dev/xvda1 xfs 16764908 3611384 13153524 22% /
/dev/xvdf1 xfs 4184064 37216 4146848 1% /USB1_Partition1
##/dev/xvdf1(USBメモリ)が ディレクトリ /USB1_Partition1にマウントされました。

なお、/USB1_Partition1 ディレクトリの配下にさらにディレクトリを作った場合は、ファイルシステムが全てUSBメモリにデータを保存するようにします。

ここまでくればUSBにファイルを自由に読み書きできるようになります。

補足

コンピュータは起動する度にバスに接続されたデバイスを読み取ります。つまり、再起動する度にマウントしないといけません。これでは非効率すぎるので、/etc/fstab を使用することで起動した際に自動でマウントしてくれます。

$ sudo blkid
/dev/xvda1: LABEL="/" UUID="12345678-9abc-defg-hijk-lmnopqrstuvw" TYPE="xfs" PARTLABEL="Linux" PARTUUID="****"
/dev/xvdf1: UUID="usb45678-9abc-defg-hijk-lmnopqrstuvw" TYPE="xfs" PARTUUID="*****"
##ブロックストレージ固有のID(UUID)を調べます。/dev/xvdf1(USBメモリ)のUUIDはusb45678-9abc-defg-hijk-lmnopqrstuvw であることがわかります。

$ sudo vi /etc/fstab
UUID=12345678-9abc-defg-hijk-lmnopqrstuvw / xfs defaults,noatime 1 1
##/etc/fstabファイルを編集します。
UUIDからすでに/dev/xvda1(SSD)が登録されていることがわかります。これはOSを読み込むためです。

##こちらにUSBのUUIDを追加します。
UUID=usb45678-9abc-defg-hijk-lmnopqrstuvw /USB1_Partition1 xfs defaults 0 2
前から順にデバイスの指定、マウントするディレクトリ、ファイルシステム、オプション、バックアップ(0=しない)、起動時の優先度(OSを1とする)

これで再起動しても自動でマウントされます。お疲れ様でした。

まとめ

・ストレージデバイスはバスに接続することで認識される。
・ストレージデバイス(ブロックストレージ)はパーティションで区切ることで複数のデバイスのように扱える。
・ストレージデバイス(ブロックストレージ)はファイルシステムを使うことで、人間の扱いやすいファイル単位でデータを管理できる。
・ストレージデバイス(ブロックストレージ)はマウントすることでディレクトリとブロックストレージのファイルシステムを紐づける。



この記事が気に入ったらサポートをしてみませんか?