はじめに
Everything is a file
UNIX 哲学には「すべてはファイルである」という設計思想がある。
ディレクトリやデバイスファイルなどは全て『ファイル』として扱われる。
例えばパーティションに対する操作は、パーティションを表現する デバイスファイル に対して行う。
ファイルシステムを理解する上で重要なポイントは以下の 5 つ。
-
物理ディスクは、論理的に複数に分割して、それぞれを独立させて使うことができる
- 分割された領域は「パーティション」と呼ばれる
-
パーティションデバイスファイルとして表現される
- パーティションに対する操作は「デバイスファイル」に対して行う
-
ファイルシステムは、パーティションに対して構築される
- パーティションを作成せずに、デバイスに直接構築することも可能(小容量の USB など)
-
パーティションに構築されたファイルシステムは、既存のディレクトリでマウントすることで、操作可能になる
- このディレクトリは「マウントポイント」と呼ばれる
-
パーティションはデバイス「ファイル」であり、マウントポイントは、「ディレクトリ」である
- Linux では、どちらも広義の「ファイル」として扱われる
この設計思想に基づいて構築された Linux では
デバイスやソケットなどあらゆるリソースが 「ファイル」として表現 され、統一的なインターフェース(open / read / write / close)で操作できる 全ての入出力(I / O)操作は「ファイル」に対して行われる。
ファイルの実体
Linux のファイルシステムでは、ファイルは ファイル名、データ本体、inode で構成される。
- ファイル名
- データ本体
- データブロック
- 保存対象のデータ
- inode
- ファイルのメタデータ
- ファイル所有者、パーミッション、更新日時など
ディレクトリは特別なファイルという扱いになっている。
ディレクトリの実体
ディレクトリのデータ本体部分には、
- そのディレクトリに含まれるファイルのファイル名一覧
- そのディレクトリに含まれるファイルの inode 番号 一覧
が保存されている。
つまりディレクトリは、ディレクトリ自身が保持しているファイル名と inode 番号のマッピング情報を保持する「ファイル」と考えればよい。
わかりづらいが、ディレクトリファイル自身のメタデータは、先述のとおりディレクトリファイルの inode として保持されている。
inode
ファイルごとに作成される、ファイルのメタデータを管理するバイナリデータ。
inode 番号によって識別される。
$ ls -i ファイル
$ stat -c %i ファイル
inode には、以下のような情報が含まれている。
- ファイルの属性
- ファイルの種類(通常ファイル、ディレクトリ、リンクの種類など)
- ファイルのサイズ
- 所有者(ユーザーID、グループID)
- パーミッション
- タイムスタンプ(作成時刻、最終更新時刻、最終アクセス時刻)
- リンク数(ハードリンクの数)
- データ本体への参照
また、ファイル名と inode 番号の対応関係はディレクトリに保存される。
ファイル名はディレクトリが保持していて、 inode に含まれていない
SCSI
Small Computer System Interface
ストレージディスクとの通信時の規格の一つ。
商用サーバや、高性能のストレージで利用される。
デバイスファイル /dev/sda や /dev/sdb の sd は SCSI disk の略。
ただし、現在では SATA や USB なども /dev/sda などの sd デバイスとして扱われる。
※ SCSI
iSCSI
Internet SCSI
ストレージディスクとの通信時の規格の一つ。
リモートのストレージをローカルのディスク(SCSI デバイス)と同じように扱えるようにする。SAN を構築することができる。
クライアント側を「イニシエータ」と呼び、接続先サーバ側のストレージを「ターゲット」と呼ぶ。
通信は TCP / IP によって行う。
ATA
ストレージディスクとの通信時の規格の一つ。
家庭用 PC の HDD、SSD でよく利用される。
SATA
Serial Advanced Technology Attachment
通信規格の一つ。
PCI
Peripheral Component Interconnect
拡張カードや周辺機器を接続するためのバス規格の一つ。
PCI バスに接続されたデバイスは PCI デバイス と呼ばれる。
主な PCI デバイスには以下がある。
- GPU
- 拡張カード(NIC、サウンドカード、SCSI カード)
現在は PCI Express(PCIe) が主流で、従来の PCI よりも高速なデータ転送が可能。
PCI バスとは、CPUやチップセットと周辺機器をつなぐための共通インターフェースを指す。
$ lspci で確認することができる。
$ lspci
00:00.0 👈 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
00:01.0 👈 Ethernet controller: Red Hat, Inc. Virtio network device
00:02.0 👈 Display controller: Red Hat, Inc. Virtio 1.0 GPU (rev 01)
00:03.0 👈 Audio device: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (rev 01)
00:04.0 👈 USB controller: NEC Corporation uPD720200 USB 3.0 Host Controller (rev 03)
00:05.0 👈 USB controller: Red Hat, Inc. QEMU XHCI Host Controller (rev 01)
00:06.0 👈 SCSI storage controller: Red Hat, Inc. Virtio block device
00:07.0 👈 Communication controller: Red Hat, Inc. Virtio console
00:08.0 👈 Unclassified device [0002]: Red Hat, Inc. Virtio filesystem
00:09.0 👈 Unclassified device [00ff]: Red Hat, Inc. Virtio RNG
PCI バス(上記の出力例で言う、00:00.0 や 00:01.0 など)は以下の 3 つの要素で構成される。
バス番号:デバイス番号:ファンクション番号
- バス番号
- PCI バスの番号
- 最大 256 本
-
00は 1 番目のバス(ルートバス)を表す - ルートバスは CPU 直結で
00からさらに PCI ブリッジを介して別のバスに接続されている
- デバイス番号
- 各 PCI バスの末端に接続されたデバイスの番号
-
0〜31まで -
00は 1 番目のデバイスを表す
- ファンクション番号
- デバイスが持つ機能の番号
- 各デバイスは複数の機能を持つことができる
-
0〜7まで
UUID
Universally Unique Identifier
ストレージデバイスを一意に識別するための 128 ビットの識別子。
$ lsblk -f
$ blkid
/dev/disk/by-uuid/ にデバイスファイルに対してのシンボリックリンクとして確認することができる。
デバイスドライバ
カーネル がハードウェアを制御するためのインターフェースとして機能するソフトウェア。
Linux では カーネルモジュール として実装されることが多い。
カーネルモジュールはカーネルの一部として機能し、カーネルを再起動することなく追加、削除することができる。また、デバイスドライバをカーネルモジュールとしてカーネルに取り込むことは ロードする と表現される。
DMA
Direct Memory Access
CPU を介さずに、デバイスが直接メモリにデータを転送する仕組み。
CPU が転送処理のために占有されないため、転送時のオーバーヘッドが減り、転送速度が向上する。
現代のほとんどのシステムで有効となっている。
デバイスファイル
カーネルが周辺機器、デバイス、システム内のリソースにアクセスするための インターフェースとして機能する 特別なファイル。
物理デバイスに対応するデバイスファイルは、通常 /dev/ 配下に作成されるが、パーティションのように、動的に生成されたり削除されるファイルもある。
デバイスファイルが「通常のファイル」と同様のインターフェースを提供することにより、
openreadwriteclose
などの、通常はファイルに対して行う操作(システムコール)を、デバイスに対しても同様に行うことが可能となる。
つまり デバイスをファイルのように扱う ことが可能になる。
デバイスファイルはファイルシステムに組み込まれているが、カーネルが管理するインターフェースであり、実際のストレージ上には「通常のファイル」が持つような データ本体 が存在するわけではない。
デバイスファイルの実体はストレージ上には存在しない
デバイスファイルにアクセスを行うのはカーネル(のデバイスドライバ)であり、操作できるユーザは root のみ。
種類として キャラクタデバイス と ブロックデバイス がある。
キャラクタデバイス
Character Device
1 byte 単位(文字単位) でデータをやり取りするデバイスファイル。
-
端末(
/dev/tty1、/dev/pts/0) - キーボード(
/dev/input/event0、/dev/input/mouse0) - マウス(
/dev/input/event0、/dev/input/mouse0) - シリアルポート(
/dev/ttyS0、/dev/ttyUSB0)
ファイル種別 は c で表示される。
$ ls -l /dev/ttys1
crw--w---- 1 root tty 0x10000000 Nov 1 05:34 /dev/ttys1
バッファを持たず、ランダムアクセスを行うことができない。
文字単位でストリーム的にデータの入出力を行うため、バッファなどを使用しない即時性が求められるキーボード、マウスなどの入出力に適している。
キャラクタデバイスに対して読み書きは行えるが、シーク操作は行うことができない。シーク操作とは、デバイス内でアクセスする場所を変更する操作を指す。
ブロックデバイス
ブロック単位(一定サイズ) でデータをやりとりするデバイスファイル。
-
ハードディスク(
/dev/sda、/dev/sdb、/dev/sdc) - USB ストレージ(
/dev/sda、/dev/sdb、/dev/sdc) - CD / DVD ドライブ(
/dev/sr0、/dev/sr1、/dev/sr2)
ファイル種別は b で表示される。
$ ls -l /dev/disk0
brw-r----- 1 root operator 0x1000000 Oct 26 21:18 /dev/disk0
バッファを持っていて、ランダムアクセスが可能。
キャラクタデバイス vs ブロックデバイス
| 違い | キャラクタデバイス | ブロックデバイス |
|---|---|---|
| アクセス単位 | 1 byte | ブロック |
| バッファ | なし | あり |
| ファイル種別 | c |
b |
| ランダムアクセス | 不可 | 可能 |
デバイスファイル名のアルファベット
デバイスファイル /dev/sdX の X の位置にあるアルファベット部分 (a、b、c、…) は、物理ディスクごとに付与された識別子を表す。
起動順や接続順、OSがデバイスを認識した順番で sda、sdb、sdc という様に名前が付与される。
デバイスファイル名の数字
デバイスファイル /dev/sdaY や /dev/sdbY の Y の位置にある数字(1、2、3、 …) は、ディスク内のパーティション番号を表す。
/dev/sda にパーティションを作成した場合、/dev/sda1、/dev/sda2 のように番号が続く。
特殊な意味を持つデバイスファイル
| デバイスファイル | 意味 |
|---|---|
/dev/null |
書き込んだデータをすべて破棄する コマンド出力を破棄する際に使用される |
/dev/full |
常に「ディスクいっぱい」のエラーを返す ディスクがいっぱいの状態が必要なテストなどで利用される |
/dev/zero |
無限にゼロ (\0) を返すファイルの初期化、メモリのクリアに利用される |
/dev/random |
真の乱数を生成する(低速) 高い安全性が求められる暗号鍵の生成で利用される |
/dev/urandom |
擬似的な乱数を生成する(高速) APIキー、セッションID、一時パスワードの生成など、暗号的に安全だが高速な乱数が求められる場面で利用される |
/dev/tty |
現在の 制御端末 を返す |
/dev/console |
主に init システム やカーネル側が入出力用に使用するログメッセージの出力先として利用される |
$ lsblk
$ lsblk
※ ブロックデバイス
$ lsdev
$ lsdev
$ lspci
$ lspci -v
PCI デバイス:NIC、Bluetooth アダプタ、SCSI コントローラ など
$ lsusb
$ lsusb -v
$ lsscsi
$ lsscsi -v
SCSI デバイス:HDD、SSD、CD / DVD ドライブなど
$ lshw
ls hardware
$ lshw
$ lscpu
$ lscpu
/proc/cpuinfo の情報が表示される。
$ lsof
List Open Files
システム内で開かれているファイルやソケットを一覧表示する。
$ lsof
$ lsof -p PID
$ lsof -u ユーザ名
$ lsof ファイル名
$ lsof -i:ポート番号
$ fuser
File User
特定のファイルやディレクトリ、ソケットなどを使用しているプロセスを表示する。
$ fuser -v ファイル
$ fuser -v ディレクトリ
$ fuser -m マウントポイント
$ hdparm
HDD、SSD などのディスクのパラメータを表示、設定するためのコマンド。
$ hdparm デバイス
$ hdparm -I デバイス
$ hdparm -T デバイス
$ hdparm -t デバイス
$ hdparm -tT デバイス
$ hdparm -W デバイス
$ hdparm -W1 デバイス
$ hdparm -W0 デバイス
$ hdparm -A デバイス
$ hdparm -A1 デバイス
$ hdparm -A0 デバイス
$ hdparm -d デバイス
※ DMA
$ hdparm -d1 デバイス
$ hdparm -0 デバイス
$ sdparm
SCSI デバイスや SCSI コマンドを受け付けるデバイスのパラメータを表示、設定するためのコマンド。
$ sdparm デバイス
$ sdparm --get=パラメータ名
$ sdparm --set=パラメータ名
$ sdparm --clear=パラメータ名
| パラメータ名 | 説明 |
|---|---|
WCE |
Write Cache Enable 書き込みキャッシュの有効/無効 |
RCD |
Read Cache Disable 読み取りキャッシュの無効化 |
STANDBY |
デバイスをスタンバイ状態にする |
STOP |
デバイスを停止 |
START |
デバイスを起動 |
$ hdparm vs $ sdparm
これらのコマンドはどちらもディスクの設定を確認したり、変更するコマンドであり目的は共通だが、対象デバイスが異なる。
$ hdparm は ATA デバイス(SATA)専用のコマンドであるのに対して、$ sdparm は SCSI コマンドセットに準拠したデバイス全般(SAS、USB-SCSI、iSCSI なども含む)に使用することができる。
HDD / SSD が SATA なら $ hdparm、SCSI / SAS や USB ストレージなら $ sdparm を使用する。
$ smartctl
SMART (Self-Monitoring, Analysis and Reporting Technology) を利用して、ディスク の状態を監視・診断するための自己診断ツール。
smartmontools パッケージに含まれる。
$ smartctl -a デバイス
-H オプションをつけた場合、簡易的な自己診断が即座に実行され、PASSED(正常)もしくは FAILED(故障予兆あり)の結果が表示される。
簡易診断のため、PASSED と表示されても実は異常が存在する可能性もある。
$ smartctl -H デバイス
-t オプションをつけた場合、コマンド自体は即座に終了するが、バックグランドでセルフテストが「開始」される。
セルフテストを実行する場合、テスト種類(short / long / conveyance)を指定する必要がある。セルフテストは、本格的な異常がないかを調べる際に使用される。
$ smartctl -t テスト種類 デバイス
-t オプションの実行結果は、-l オプションで確認することができる。
$ smartctl -l selftest デバイス
udev
Universal Device Management
カーネルが検出したデバイスに対応するデバイスファイル(/dev)を、動的に作成したり、管理したりする仕組み。
かつての Linux では、接続される可能性のあるデバイスに対応するデバイスファイルを、カーネルがデバイスを認識する前に全て事前に用意しておく必要があった。これに対して、udev では接続されたデバイスに対してのみ、動的にデバイスファイルを作成することができるため、事前のデバイスファイル作成が必要ない。
例えば USB などのデバイスが接続された際、カーネルは sysfs(/sys/)と呼ばれる 仮想ファイルシステム にデバイス情報(/sys/bus/usb/devices/1-1/ など)を作成する。
sysfs に作成されるファイルは仮想ファイルであるため、ディスク上ではなくメモリ上に存在する。
また、ファイルには以下のような情報が格納されている。
- ベンダー ID(idVendor)
- 製品 ID(idProduct)
- デバイス名(product)
ユーザ空間で動作する udevd デーモンは、カーネルが作成した /sys ディレクトリを監視している。
udevd は、新しいデバイスが追加されると、動的に /dev/ にデバイスファイルを作成する。
このときの動作を /etc/udev/rules.d ディレクトリの設定ファイルを編集することによって制御することができる。
/usr/lib/udev/rules.d / /lib/udev/rules.d
ディストリビューションが提供するデフォルトの設定ファイルが配置されるディレクトリ。
詳細は 下記 を参照。
/etc/udev/rules.d
udev が使用する設定ファイルが配置されるディレクトリ。
この設定ファイルによって、カーネルがデバイスを検出した際に、デバイスファイルにどのような名前を付けたり、どのような処理を行うかを細かく制御できる。
$ ls /etc/udev/rules.d
ubuntu--vg-ubuntu--lv.rules
$ cat /etc/udev/rules.d/ubuntu--vg-ubuntu--lv.rules
# Written by curtin
SUBSYSTEM=="block", ACTION=="add|change", ENV{DM_NAME}=="ubuntu--vg-ubuntu--lv", SYMLINK+="disk/by-dname/ubuntu--vg-ubuntu--lv"
MATCH_KEY1=="value1", MATCH_KEY2=="value2", ACTION_KEY1="action1", ACTION_KEY2+="action2"
記述される内容には大きく分けて「マッチ条件」「アクション」がある。
以下の演算子に従い、記述された「条件」にマッチした場合に「アクション」が実行される。
| マッチ条件 | 説明 |
|---|---|
== |
値が等しい(比較) (例) SUBSYSTEM=="block":サブシステムが block (ブロックデバイス)の場合にマッチ |
!= |
値が等しくない(比較の否定) (例) KERNEL!="sd*":デバイス名が sd で始まらない場合にマッチ |
| 処理 | 説明 |
|---|---|
= |
値を上書き設定する (例) OWNER="root":デバイスファイルの所有者を root にする |
+= |
値をリストに追加する (例) SYMLINK+="mydisk":/dev/mydisk というシンボリックリンクを追加 |
:= |
値を強制的に設定(上書き不可) (例) NAME:="finalname":デバイスファイル名を finalname で固定 |
| マッチ条件 | 説明 |
|---|---|
SUBSYSTEM |
デバイスの種類(サブシステム)block:ブロックデバイスchar:キャラクタデバイスusb:USBtty:端末(例) SUBSYSTEM=="usb":USB デバイスの場合にマッチ |
ACTION |
イベントの種類。add:追加された時remove:取り外した時change:変更した時(例) ACTION=="add":デバイスが追加された時にマッチ |
ENV{環境変数名} |
udev が保持する環境変数に対するマッチ (例) ENV{DM_NAME}=="ubuntu--vg--ubuntu--lv"
|
KERNEL |
カーネルが割り当てたデバイス名 (例): KERNEL=="sd[a-z][0-9]"
|
ATTR{属性名} |
/sys ディレクトリ配下の属性(例) ATTR{idVendor}=="1234"
|
ID_VENDOR_ID |
USB デバイス固有のベンダ ID (例) ENV{ID_VENDOR_ID}=="1234"
|
ID_MODEL_ID |
USB デバイス固有のモデル ID (例) ENV{ID_MODEL_ID}=="1234"
|
DRIVERS |
カーネルが使用するドライバ名 (例) DRIVERS=="usb-storage"
|
| アクション | 説明 |
|---|---|
SYMLINK |
/dev ディレクトリ配下に作成されるシンボリックリンク(例) SYMLINK+="mydisk":/dev/mydisk が作成される |
NAME |
デバイスファイル名を指定 (例) NAME="mydevice0"
|
OWNER |
所有ユーザ (例) OWNER="myuser"
|
GROUP |
所有グループ (例) GROUP="disk"
|
MODE |
パーミッションの指定 (例) MODE="0660"
|
RUN |
外部スクリプトやコマンドの実行 (例) RUN+="/usr/local/bin/myscript.sh"
|
ENV{} |
udev の内部環境変数に値を設定 (例) ENV{myvar}="value"
|
$ udevadm
udev admin
udev の管理やデバッグのためのツール。
$ udevadm サブコマンド オプション
$ udevadm info --name=/dev/sda
$ udevadm control --reload
$ udevadm monitor # このまま USB 抜き差しすると、イベントが表示される
ファイルシステム
ディスク上のデータをファイル単位で操作するための基本的な仕組み。
ファイルシステムの存在によって、私たちはデータを扱う際に「ディスクの〇〇バイト目 ~ ××バイト目までのデータを読み出す」などという形式ではなく、「A ディレクトリの B ファイルを読み出す」という形式でデータを扱うことができる。
| 種類 | 特徴 |
|---|---|
ext2ext3ext4
|
Linux で最も一般的 |
XFS |
高速、大容量(Red Hat 系) 並列処理が可能 |
ZFS |
RAID 機能あり スナップショット機能あり |
Btrfs |
スナップショット、圧縮ができる RAID 機能あり 大容量 |
vfat |
Windows、USB で使用される |
exfat |
フラッシュメモリ で使用される |
iso9660 |
CD-ROM で使用される |
Linux が起動するとき、基本的にはルートファイルシステムがすでに存在しているが、さらにルートファイルシステム配下で別のファイルシステムが構築されることがある。
$ mkfs コマンドを使用することによって、パーティションに対して作成することができる。
ファイルシステムの構造(ext2 / ext3)
ext2 は、第 2 世代拡張ファイルシステム(Extended Filesystem 2)を指す。
ext3 は ext2 にジャーナリング機能を追加したもので、内部構造は基本的に ext2 と同じ。ext3 は ext2 と完全互換であり、ext2 → ext3 への変換や($ tune2fs)、ext3 を ext2 としてマウントすることができる。
$ tune2fs -j デバイス
ext2 や ext3 のファイルシステムの大きな特徴は、データとメタデータを分離して管理する 点にある。
ext2 や ext3は、ディスクを ブロック と呼ばれる単位で管理する。ブロックはファイルシステムがデータを扱う際の最小単位となる。
ファイルシステム自体がサポートするブロックサイズが決まっていて、ext2、ext3 に関しては作成($ mkfs)時に、以下のいずれかから指定する必要がある。
-
1024byte(1KB) -
2048byte(2KB) -
4096byte(4KB)
ブロックにはいくつかの種類がある。
- スーパーブロック
- ファイルシステム全体のメタデータ
- 例:ブロックサイズ、inode 数、マウント回数
- データブロック
- 実データの領域
- inode テーブル
- 複数の inode が格納される領域
ブロックによってブロックグループが形成され、ディスクは複数のブロックグループによって構成される。
ディスク
├── [ ブロックグループ 0 ]
| ├── スーパーブロック
| ├── データブロック
| └── inode テーブル
|
└── [ ブロックグループ 1 ]
├── スーパーブロック
├── データブロック
└── inode テーブル
※ 実際にはもう少し要素は多い
ルートファイルシステム
/(ルートディレクトリ)を起点とするファイルシステムのこと。
ext4 や xfs などのファイルシステムを使用して構築されるが、 ルートファイルシステムという種類があるわけではない。
カーネルがブート後、最初にマウントするファイルシステムでもある。ルートファイルシステムをマウントする パーティション を ルートパーティション という。
FHS の表にあるような主要なディレクトリが含まれている。
FHS
Filesystem Hierarchy Standard
Linux や Unix 系 OS のディレクトリ構造とその役割を規定した規格。
この標準規格に従うことで、異なるディストリビューション間でも共通のディレクトリ構成を持つことになるため、管理や運用がしやすくなる。
| ディレクトリ | 説明 |
|---|---|
/ |
ルートディレクトリ すべてのパスの起点となる |
/bin |
一般ユーザでも使用可能な基本コマンドが格納されるディレクトリ$ ls$ cp$ mv$ rm
|
/sbin |
システム管理用コマンドが格納されるディレクトリ$ fdisk$ shutdowninit
|
/lib |
共有ライブラリ が格納されるディレクトリlibc.so など |
/etc |
設定ファイルが格納されるディレクトリ/etc/passwd、/etc/fstab、/etc/ld.so.conf など |
/dev |
デバイスファイルが格納されるディレクトリ/dev/sda/dev/null
|
/home |
一般ユーザーのホームディレクトリ 肥大化しやすいため、ルートパーティション と分け、独立したパーティションとする場合が多い |
/root |
root ユーザーのホームディレクトリ |
/usr |
ユーザが利用するプログラム、ライブラリ、ドキュメントが格納されるディレクトリ/usr/bin/*/usr/sbin/*/usr/lib/*/usr/local/*
|
/opt |
追加でインストールしたソフトウェアが格納されるディレクトリ 独立したパーティションとする場合が多い |
/proc |
カーネル情報にアクセスするための 仮想ファイル(実際のディスク上には存在しない)が格納されるディレクトリ/proc/プロセスID/fd/:ファイルディスクリプタ 情報/proc/cpuinfo:CPU 情報/proc/meminfo:メモリ情報/proc/bus/usb:USB デバイス情報/proc/self/mounts:マウント情報/proc/mounts:/proc/self/mounts への シンボリックリンク/proc/swaps:使用中のスワップ領域情報 |
/sys |
デバイスやドライバの情報(udev)が格納されるディレクトリ |
/media |
USB メモリや CD-ROM などの自動マウントに使われる |
/mnt |
外部ストレージやネットワークドライブを手動で一時的にマウントするためのマウントポイントとなるディレクトリ |
/boot |
システムの起動(ブート)に関わるファイルが格納されるディレクトリ/boot/vmlinuz-バージョン:カーネル本体(圧縮ファイル)/boot/vmlinuz:カーネル本体へのシンボリックリンク |
/var |
ログや頻繁に更新されるデータが格納されるディレクトリ 独立したパーティションとする場合が多い var/cache:一時的なキャッシュファイル/var/log:ログファイル/var/lock:排他制御 に使用するためのロックファイルが格納されるディレクトリ/var/run:システムの状態を示すファイル |
/tmp |
一時ファイル スティッキービット が設定されることが多い 独立したパーティションとする場合が多い |
仮想ファイルシステム
Vertual File System, VFS
実際の物理的なストレージやディスク上(HDD や SSD など)に存在しないファイルを、ファイルシステムの中で仮想的なファイルやディレクトリとして提供する仕組み。
前述 の通り、UNIX 哲学には「Everything is a file」という哲学があるため、カーネルや OS が内部的に必要とする情報も、「ファイル」として扱われる。
【代表的な仮想ファイルシステム】
-
/proc/- カーネル、プロセス、ハードウェアの状態
-
/proc/cpuinfo:CPU 情報 -
/proc/プロセスID/fd/:ファイルディスクリプタ 情報
-
/sys/- システムの設定やデバイス情報
-
/dev/
/proc/filesystems
カーネル がサポートするファイルシステム一覧。
/proc/filesystems
$ cat /proc/filesystems
nodev sysfs
nodev tmpfs
nodev bdev
nodev proc
nodev cgroup
nodev cgroup2
nodev cpuset
nodev devtmpfs
nodev configfs
nodev debugfs
nodev tracefs
nodev securityfs
nodev sockfs
nodev bpf
nodev pipefs
nodev ramfs
nodev hugetlbfs
nodev devpts
ext3
ext2
ext4
squashfs
vfat
nodev ecryptfs
fuseblk
nodev fuse
nodev fusectl
nodev efivarfs
nodev mqueue
nodev pstore
btrfs
nodev autofs
nodev binfmt_misc
/etc/iscsi.conf
iSCSI イニシエータ(クライアント側)用の設定ファイル 。
ディストリビューションによっては /etc/iscsi/iscsi.conf が使用される。
設定項目 = 値
$ mkfs
make filesystem
パーティション 上にファイルシステムを作成する。
-t オプションで種類を指定することができる。指定しなかった場合には ext2 が作成される。
$ mkfs -t ファイルシステム デバイス # デバイス = パーティション
$ mkfs.ファイルシステム デバイス
$ mkfs -t ext4 /dev/sdb1
$ mkfs.ext4 /dev/sdb1
$ mkfs.ext2 パーティション # ext2
$ mkfs.ext3 パーティション # ext3
$ mkfs.ext4 パーティション # ext4
$ mkfs.xfs パーティション # XFS
$ mkfs.btrfs パーティション # Btrfs
$ mkfs.cramfs パーティション # cramfs
$ mkfs.vfat パーティション # FAT / VFAT
$ mkfs.minix パーティション # MINIX FS
$ mke2fs
ext 系のファイルシステム(ext2、ext3、ext4)を作成する。
内部的には $ mkfs.ext2、$ mkfs.ext3、$ mkfs.ext4 のラッパーとして動作している。
mkfs と異なり e がつく(mke2fs。mk2fs ではない。)ため注意。
$ mke2fs パーティション
$ mke2fs -t ファイルシステム パーティション
$ mke2fs -c パーティション
$ mke2fs -b ブロックサイズ
$ mke2fs -m パーセント # デフォルトは 5 %
$ mkisofs
指定したディレクトリを ISO9660 ファイルシステムのイメージ(.iso)として作成する。
ISO9660 は CD-ROM、DVD-ROM などに用いられる。
$ mkisofs -o 出力ファイル ディレクトリ
$ mkisofs -R -o 出力ファイル ディレクトリ
$ mkisofs -J -o 出力ファイル ディレクトリ
$ fsck
File System Check
ファイルシステムの整合性をチェックし、必要に応じて修復する。
クラッシュ、強制終了、電源断などのディスクの異常発生時に、ファイルシステムの破損を検出・修復するために使用される。
チェックするファイルシステムをアンマウントした状態で実行する必要がある!
$ fsck デバイス
ファイルシステム ごとに $ fsck を使い分ける必要はなく、内部的に、現在使用中のファイルシステムに応じたプログラムが呼び分けられる仕組みになっている。
$ fsck -N デバイス
$ fsck -A
$ fsck -r
$ fsck -t ファイルシステム
$ fsck -p デバイス
$ fsck -y デバイス
-y はデータ消失の可能性があるため、「すでにバックアップ済みである」などの状況下でのみ使用する。
$ fsck -n デバイス
$ e2fsck
ext2、ext3、ext4 専用のファイルシステムチェックコマンド。
$ fsck 実行時にも内部的に呼び出されるのは $ e2fsck であるため、特別 $ e2fsck を使う必要はあまりない。
$ e2fsck デバイス
$ tune2fs
Tune ext2 File System
ext2、ext3、ext4 ファイルシステムのパラメータを変更、調整(tune)する。
$ tune2fs デバイス
$ tune2fs -l デバイス
$ tune2fs -L ラベル名 デバイス
$ tune2fs -m パーセント デバイス
$ tune2fs -j デバイス
$ tune2fs -U 変更後のUUID デバイス
$ tune2fs -i 間隔 デバイス
※ 間隔:60 = 30日、2m = 2ヶ月、8w = 8 週間
$ tune2fs -c 回数 デバイス
$ debugfs
ext2、ext3、ext4 ファイルシステムのデバッグ用ツール。
対話形式でデバイスをオープンして、内部のファイルシステムを解析する。
$ debugfs デバイス
対話モードに遷移したら、$ quit で終了できる。
$ debugfs -w デバイス
読み書きモードで実行した場合、ファイルシステムを破損することがある!
$ xfs_info
XFS ファイルシステム情報を表示する。
マウント中のファイルシステムにも使用できる。
$ xfs_info マウントポイント
$ xfs_repair
XFS ファイルシステム専用の整合性チェック、修復のためのツール。
ext 系のファイルシステムでは $ fsck や $ e2fsck が使われるのに対して、XFS では $ xfs_repair が使用される。
$ xfs_repair デバイス
$ xfs_admin
XFS ファイルシステムのパラメータを変更する。
アンマウント後に実行する必要がある。
$ fsck の XFS 版ではないため、機能はラベルに特化したものになっている。
$ xfs_admin -l
$ xfs_admin -L ラベル名
$ xfs_admin -u
$ xfs_admin -U UUID
$ xfsdump
XFS ファイルシステム専用のバックアップツール。
$ xfsdump -f 出力先 デバイス
$ xfsdump -l レベル -f 出力先 デバイス
※ レベル 0:フルバックアップ
※ レベル 1 ~ 9:増分バックアップ
$ xfsdump -I デバイス
$ xfsrestore
$ xfsdump で作成したバックアップからファイルシステムを復元する。
$ xfsrestore -f バックアップファイル 復元先
$ xfsrestore -i
$ btrfs
Btrfs(B-tree filesystem)ファイルシステムを管理する。
サブコマンドで機能が分かれていて、多機能のオールインワン型の管理ツール。
$ btrfs filesystem show
$ btrfs filesystem df マウントポイント
$ btrfs filesystem label マウントポイント
$ btrfs filesystem label デバイス
$ btrfs filesystem label マウントポイント ラベル名
$ btrfs filesystem label デバイス ラベル名
$ btrfs subvolume list ディレクトリ
$ btrfs subvolume create ディレクトリ
$ btrfs subvolume delete ディレクトリ
$ btrfs subvolume snapshot 対象ディレクトリ 出力先
$ btrfs-convert
既存の ext2、ext3、ext4 ファイルシステムを、元のデータを残したまま Btrfs(B-tree filesystem)ファイルシステムに変換する。
対応しているファイルシステムは上記 3 つのみ。
$ btrfs-convert パーティション
実行後は Btrfs としてマウントできるようになる。
$ badblocks
ストレージデバイス上の不良ブロックを検出する。
HDD、SDD、USB などのブロックデバイスに対して使用される。
$ badblocks デバイス
$ badblocks -o ファイル デバイス
$ iscsiadm
iSCSI ターゲットの検知、ログイン、管理を行うコマンド。
サーバ-クライアント方式が採用される。
- クライアント
- イニシエータ
- ストレージを利用するホスト
- サーバ
- ターゲット
- 接続先の iSCSI ストレージ
- IQN(iSCSI Qualified Name)で識別される
$ iscsiadm コマンドを実行するクライアント側では、iscsid デーモンが起動している必要がある。
/etc/iscsi.conf の node.startup が automatic に設定されていれば、ターゲットを登録した際にその設定が引き継がれ、OS 起動時に自動ログインが行われる。
node.startup = automatic
なお、iscsid デーモン自体は systemd により管理されており、通常は常時起動する。
接続までに必要な処理は以下の通り。
- ターゲットの検知
- ターゲット情報の確認
- ターゲットへのログイン
- 接続状態の確認
- マウント
$ iscsiadm -m discovery -t sendtargets -p ターゲットホスト名
$ iscsiadm -m node # IQN が表示される
$ iscsiadm -m node -T ターゲット名 -p ターゲットホスト名 --login
$ iscsiadm -m session
$ cryptsetup
Debian 系で利用される、ファイルシステム暗号化ツール。
暗号化デバイスをマッピングし、/dev/mapper/仮想デバイス名 として仮想デバイスを作成する。
旧方式
旧方式は LPIC 試験では問われるが、現在では LUKS 方式が推奨されている。
$ cryptsetup create 仮想デバイス名 パーティション
Enter passphrase: 👈パスフレーズが要求される
仮想デバイスの作成は、ファイルシステム作成や、マウントより前工程で行われる。
そのため仮想デバイスを作成したら、その後は仮想デバイスに対してファイルシステム作成($ mkfs)、マウント($ mount)を行う。
マッピングを解除する場合は、アンマウント($ umount)後、以下のようにする。
$ cryptsetup remove 仮想デバイス名
LUKS 方式(推奨)
Linux Unified Key Setup
LUKS は Linux で標準的に使われるディスク暗号化の規格。
現在、推奨される新方式では以下の順にコマンドを実行する必要がある。
$ cryptsetup luksFormat パーティション
$ cryptsetup luksOpen パーティション 仮想デバイス名
旧方式と同様に、仮想デバイスを作成したら、その後は仮想デバイスに対してファイルシステム作成($ mkfs)、マウント($ mount)を行う。
$ mkfs.ext4 /dev/mapper/仮想デバイス名
$ mount /dev/mapper/仮想デバイス名 マウントポイント
マッピングを解除する場合は、アンマウント($ umount)後、以下のようにする。
$ umount マウントポイント
$ cryptsetup luksClose 仮想デバイス名
LUKS 形式の暗号化デバイスには、パーティションの先頭に「LUKS ヘッダ」が存在する。
$ crypysetup luksDump パーティション
$ crypysetup -v isLuks パーティション
LUKS では最大 8 個のパスフレーズ、鍵を登録することができる。
$ cryptsetup luksAddKey パーティション
$ cryptsetup luksRemoveKey パーティション
$ df
Disk Free
$ df
$ df -h # 1 MB = 1024 KB
$ df -H # 1 MB = 1000 KB
$ df -f ディレクトリ
$ df -f デバイス
-i オプションで inode の数を表示することもできる。Linux におけるファイルは、それぞれに対応する inode を必ず一つ持つため、inode の数はファイルの数を表す。
$ df -i
それぞれのファイルシステムには、作成可能な inode の個数が決まっており、ディスクに空き容量があったとしても inode に空きがない限り、ファイルを作成することができない。
$ df -a
$ df -t ファイルシステムのタイプ
$ df -x 除外するファイルシステムのタイプ
$ du
Disk Usage
$ du ファイル
$ du ディレクトリ
引数を指定しない場合、ディレクトリ単位で使用容量が表示される。
$ du
$ du -h
$ df と $ du の違い
$ df
ファイルシステム(パーティション)ごとの使用状況を表示する。ファイルごとの使用量はわからない。
$ du
ディレクトリやファイル単位の使用量を表示する。また使用量を表示するため、空き容量はわからない。
$ fallocate
File Allocate
ファイルシステム上に指定サイズのファイル領域を 事前に 確保する。
物理ディスクに対してファイルとして利用する領域を事前に割り当てることにより、ディスクのフラグメンテーション(断片化)を防ぎ、書き込み時のパフォーマンスを向上させることができる。
サイズを指定するための-l オプションが必須。
$ fallocate -l サイズ ファイル名
$ fallocate -l 100M ./sample # 100MB
$ fallocate -l 1G ./sample # 1GB
$ sync
ディスクキャッシュにあるデータを強制的にストレージに書き込むためのコマンド。
ディスクに対する読み書きは、通常、メモリ上のバッファに一時的に保持され、ある程度データがまとまったタイミングで実際にはディスクに書き込まれている。
これはメモリに対するアクセス速度とディスクに対するアクセス速度が大きく異なるためである。
$ sync を実行すると、ディスクにまだ書き込まれていないバッファ領域のデータを、ディスクに書き込むことができる。
$ sync
何らかの原因で強制電源 OFF しないといけない場合などに、電源 OFF によってデータが消失することを防ぐために利用される。電源 OFF 前や、アンマウント前に実行するなど。
パーティション ( MBR / GPT )
物理ストレージ(HDD や SSD)を複数の論理的な領域に区切る仕組み。
それぞれのパーティションは OS からは独立したストレージ領域として認識される。
例えばデバイス /dev/sdb をファイルシステムとして利用するには以下の操作が必要になる。
- パーティション(
/dev/sdb1)の作成
a.$ fdisk - 作成したパーティションに対するフォーマット(ファイルシステム)
a.$ mkfs - パーティション(
/dev/sdb1)のマウント
a.$ mount
ルートファイルシステム をマウントするパーティションは ルートパーティション と呼ばれる。
ファイルシステムにはいくつかの種類(ext4、ntfs、fat32)があり、それぞれのパーティションには異なるファイルシステムを作成することも可能。
パーティションの方式には MBR(Master Boot Record) と GPT(GUID Partition Table) がある。
GPT は MBR の後継版であり、作成できるパーティションの数が異なる。
- MBR → 4 個
- GPT → 128 個
パーティションの最大サイズも異なる。
- MBR → 2 TiB (2.2 TB)
- GPT → 8 ZiB (9.4 ZB)
MBR では作成できるパーティションは最大 4 つであるため、それ以上のパーティションが必要となった場合に、以下のような仮想的にパーティションを増やす仕組みがある。
-
基本パーティション
- 最大 4 つ作成可能
- ファイルシステムを設定する
-
/dev/sda1、/dev/sda2、/dev/sda3、/dev/sda4
-
拡張パーティション
- 論理パーティションを作成するための領域
- 基本パーティションの内の 1 つを拡張パーティションとすることができる
- 通常、
/dev/sda4が選択される
-
論理パーティション
- 拡張パーティション内に作成される仮想パーティション
-
/dev/sda5、/dev/sda6、...
$ fdisk / $ gdisk
パーティションを作成するためのコマンド。
ストレージ内のデータを破壊できるコマンドのため、使用には十分注意する
fixed disk : MS-DOS 時代から使われている MBR 形式のパーティション管理ツール
GPT fdisk : GPT 形式のディスクを管理するための $ fdisk に相当するツール
$ fdisk -l パーティション
$ gdisk -l パーティション
-l をつけない場合、対話モードに切り替わる。
$ fdisk デバイス
$ gdisk デバイス
対話モードに切り替わったら サブコマンド によって操作を行う。
| サブコマンド | 説明 |
|---|---|
m |
ヘルプを表示(menu) |
p |
現在のパーティション情報を表示(print) |
n |
新しいパーティションを作成(new) |
d |
既存のパーティションを削除(delete) |
t |
パーティションのタイプを変更(type) |
w |
変更を保存して終了(write) |
q |
変更せずに終了(quit) |
$ parted
Partition Editor
パーティションを作成するためのコマンド。
ストレージ内のデータを破壊できるコマンドのため、使用には十分注意する。
$ fdisk や $ gdisk では、変更を w で書き込むまで確定しないが、$ parted は即時適用される。
MBR と GPT の両方をサポートする高機能なパーティション管理ツール。
対話モードを使用せずにスクリプトによって一括処理することもできる。
$ parted デバイス
$ parted を実行すると、対話モードに切り替わる。
対話モードを使用しない場合、-s オプションを利用する。
$ parted デバイス -s サブコマンド
| サブコマンド | 説明 |
|---|---|
check 番号 |
ファイルシステムの簡単なチェックを行う |
mklabel |
新しいパーティションテーブルを作成する(make label) |
mkpart 種類 開始 終了 |
指定した種類のパーティションを作成する(make partition) |
rm 番号 |
指定したパーティションを削除する |
p / print
|
パーティションテーブルを表示する |
q / quit
|
終了する |
$ fdisk / $ gdisk / $ parted の違い
| 機能 | $ fdisk |
$ gdisk |
$ parted |
|---|---|---|---|
| MBR | ◯ | × | ◯ |
| GPT | × | ◯ | ◯ |
| 2TB 以上対応 | × | ◯ | ◯ |
| 対話モード | ◯ | ◯ | ◯ |
| スクリプト実行 | × | × | ◯ |
| パーティションサイズ変更 | × | × | ◯ |
マウント
HDD、SSD、USB などの外部のストレージを OS に認識させ、自身のディレクトリツリーに組み込むことで、そのストレージのファイルシステムにアクセスできるようすること。
Windows では独立したドライブレター(C: や D:)でストレージを識別するが、Linux ではルートディレクトリ(/) を起点とするディレクトリ構造の一部として接続する。
マウントは、特定のパーティションに対して行われ、ファイルシステムとの起点、接続点となる。
マウントするディレクトリは、」中身が空でなければならない(空にしないとどうなるか)。
マウントするディレクトリを マウントポイント と呼び、デバイス上のファイルシステムのルートディレクトリは、このマウントポイントに統合される。
通常は /dev/sdb などのディスク全体ではなく、その中の /dev/sdb1 などの パーティション をマウントする。
$ mount /dev/sdb1 /mnt/usb
パーティションとして作成された「デバイスファイル」に対して、「ディレクトリ」をマウントする
マウントポイントにする予定のディレクトリは空である必要がある
デバイスファイルとマウントポイントの違い
どちらもデータを処理するためのインターフェースとして機能するが、利用する主体が異なる。
デバイスファイルは、
カーネルによって低レベルなデータ処理を行うためのインターフェースとして機能する。実際には read() や write() などの システムコール を通じて、カーネルがデバイスとやり取りしている。
例えば、以下のような $ dd を用いた操作ではマウントポイントは意識されない。
$ dd if=/dev/sdb1 of=backup.img
一方 マウントポイントは、
ユーザによって直感的な(高レベル)ファイルシステム操作を行うためのインターフェースとして機能する。
/mnt/usb/ のようなマウントポイントは、ユーザがデバイス内のファイルにアクセスするためのディレクトリパスであり、/mnt/usb/sample.txt のように通常のファイルとして操作できる。
$ cp /mnt/usb/sample.txt /home/user1/Documents/
ただし、マウント前の /mnt/usb ディレクトリは単なる空のディレクトリであり、マウント後にデバイス内のファイルシステムと接続される。
デバイスファイル (/dev/sdb1 など) はマウントしなくても $ dd などで直接操作できるが、ファイル単位のアクセスはできない。ファイル単位の読み書きはマウントポイントを経由する必要がある。
マウントを理解する
マウントはパーティションとして作成されたデバイスファイルに対して「ディレクトリ」を指定して行われる。
サーバを構築する際、 FHS にあるディレクトリのうち、下記のディレクトリはルートパーティションとは独立したパーティションとして設計されることが多い。
| ディレクトリ | パーティションを分ける利点 |
|---|---|
/ (ルート) |
ルートファイルシステムの起点 |
/home |
ユーザデータをユーザごとに管理しやすくなる |
/var |
ログや頻繁に変更されるデータを独立させ、ルートの容量圧迫を防ぐことができる |
/boot |
ブートローダ関連のファイルを独立させることで、システムの互換性や安定性を高めることができる |
/tmp |
一時ファイルの保存領域を分け、不要なデータで / を圧迫しないようにすることができる |
/usr |
ソフトウェアやライブラリの保存領域を分け、管理しやすくなる |
/opt |
追加インストールしたソフトウェアを分けて管理することができ |
実際には以下のような対応で設定されることが多い。
| パーティション | マウントポイント | 用途 |
|---|---|---|
/dev/sda1 |
/boot/ |
OS のカーネルや GRUB の設定を格納 |
/dev/sda2 |
/ |
ルートファイルシステム |
/dev/sda3 |
/home/ |
各ユーザのデータ |
/dev/sda4 |
/var/ |
ログ、データベース、メールなど |
また下記のディレクトリについては、独立したパーティションとして分けることはあまりない。
| ディレクトリ | パーティションを分けない理由 |
|---|---|
/bin/ |
基本コマンドが含まれており、システム起動に必要なため |
/sbin/ |
/bin と同様、システム管理コマンドがあるため |
/lib/ |
/bin や /sbin のコマンドが必要とするライブラリのため |
/etc/ |
設定ファイルが格納されており、システムの一貫性を保つため |
/dev/ |
仮想ファイル を含むディレクトリのため |
/proc/ |
仮想ファイルが格納されるディレクトリのため |
/sys/ |
仮想ファイルが格納されるディレクトリのため |
ルートディレクトリをマウントするパーティションと、ルートディレクトリ内の特定のディレクトリをマウントする様子を図にしてみた。
ここで、もしマウントする前に /home/ 配下に何らかのファイルが存在していたら、どうなるのかが気になった。
調べてみると、あるディレクトリに別のファイルシステムをマウントすると、そのディレクトリのもともとの内容は 見えなくなるということだった。
/home/file1 というファイルが既に存在している状態で /home/ ディレクトリをマウントに利用すると、マウント先のデバイスのファイルシステムが表面化し、/home/file1 は見えなくなる。マウントを解除すると、再び /home/file1 が見えるようになる。
つまり、マウントポイントにする予定のディレクトリは空である必要がある。
Mac に Ubuntu をインストール した際は、こんな設定画面が出ていた。
Read-only file system と出力されたら...
/ や /etc がシステム起動時に読み取り専用モード(ro:read only)でマウントされている場合、配下のファイルを編集しようとすると
Read-only file system
と出力されることがある。
$ mount コマンドで一覧表示することで ro かどうかが確認できる。
$ mount
/dev/sda1 on / type ext4 (ro)
このような場合に、マウントし直すことで書き込み可能にすることができる。マウント済みのデバイスファイルは、再マウント時に指定する必要がない。
$ mount -o remount,rw /
ただし、この変更は再起動すると元(ro)に戻る可能性がある。
/etc/fstab
File System Table
/etc/fstab ファイルに設定されたストレージは起動時に systemd によって自動的にマウントされる。
日常的に使用するストレージにはこの設定をしていることが多い。
$ mount -o で指定できるオプション引数とは完全一致しない点に注意。
以下の様な形式で設定を記述する。
デバイスファイル マウントポイント ファイルシステム オプション dump fsck
UUID=デバイスのUUID マウントポイント ファイルシステム オプション dump fsck
/dev/sda1 /boot ext3 defaults 1 1
UUID=12345678-90ab-cdef-1234-567890abcdef / ext4 defaults 0 1
UUID=abcdef12-3456-7890-abcd-ef1234567890 /home ext4 defaults 0 2
| 設定項目 | 説明 |
|---|---|
| デバイスの UUID デバイスファイル名 |
デバイスファイル名でも良いが、UUID を使うとデバイス名の変更に影響されない。 UUID は $ lsblk -f で確認できる。 |
| マウントポイント |
マウントポイント となるディレクトリ。 スワップ 有効化の際は none。 |
| ファイルシステム |
ファイルシステム の種類。ext4、xfs、ntfs など。 |
| オプション | パフォーマンス、セキュリティ、利便性に関わるオプション(複数指定可)。defaults:デフォルトのオプションセット(rw、nouser、auto、async、exec、dev、suid)ro:読み取り専用(read only)rw:読み書き可能(read write)sw:スワップ領域としての標準オプションセットuser:一般ユーザもマウントできる(アンマウントはマウント実行ユーザのみ)users:一般ユーザもマウントできる(全てのユーザがアンマウント可能)nouser:一般ユーザのマウント禁止(user、users を指定しない場合、nouser 扱い)group:ユーザのグループがデバイスファイルの所有グループと一致すればマウントできるauto:$ mount -a 実行時にマウントされるnoauto:$ mount -a 実行時にマウントされないasync:入出力を非同期で行うsync:入出力を同期で行うatime:ファイルへのアクセスの度に inode のアクセス時刻を更新するnoatime:アクセス時刻を更新しない(高速になる)dev:ファイルシステム上のデバイスファイルが利用可能exec:バイナリの実行を許可するnoexec:バイナリの実行を許可しないloop:通常のファイルをブロックデバイスのように扱ってマウントする(イメージファイルなど)__netdev:ファイルシステムがネットワークデバイスに依存($ mount -a 実行時に、ネットワークが有効になるまでマウントが遅延される)suid:SUID、SGID を有効化するnosuid:SUID、SGID を無効化するuid=ユーザID:全てのファイル所有者を指定したユーザにするgid=グループID:全てのファイルの所有グループを指定したグループにする |
dump フラグ |
$ dump コマンドを実行した時にバックアップ対象とするかしないか有無。実際の運用ではほとんどのシステムで $ dump コマンドは使われないため 0 が一般的。0:バックアップ対象としない1:バックアップ対象とする |
fsck |
起動時にファイルシステムの整合性を $ fsck でチェックするかどうか(file system check)、またチェックする場合の優先順位(ファイルシステムの破損を防ぐために使用される)。0:チェックしない1:最優先でチェックされる。ルートファイルシステム(/)専用。2:ルート以外のパーティションでチェックを行う場合は 2 を使用する |
例えば、Ubuntu のルートファイルシステム / や /home、/boot などは、/etc/fstab に記載されているため、起動時に自動でマウントされる。
デスクトップ環境(GNOME、KDE など)では、udisks2 や gvfs などのデーモンを利用して自動マウントされることもある。
/etc/mtab
現在マウントされているファイルシステムの情報を記録するファイル。
/etc/fstab にはマウントの設定情報が定義されているのに対して、/etc/mtab には実際にマウントされているデバイス、マウントポイント、オプションが記録されている(動的に更新)。
そのため、情報を確認するためのファイルとして使用し、編集しない。
ほとんどのディストリビューションで /proc/mounts へのシンボリックリンクになっている。
/proc/mounts
現在マウントされているファイルシステムの情報を記録するファイル。
カーネル によって、動的に更新される。
$ mount
$ mount デバイス マウントポイント # デバイス = パーティション、マウントポイント = ディレクトリ
$ mount -t ファイルシステム デバイス マウントポイント
$ mount -a
引数にマウントポイント、もしくはデバイスだけを指定した場合、 /etc/fstab が参照され、指定したマウントポイントと一致するエントリ、もしくは指定したデバイスと一致するエントリがあれば、その情報を使ってマウントが行われる。
ただし、エントリに user もしくは users オプションが指定されている場合に限る。
$ mount マウントポイント
$ mount デバイス
引数無しで実行すると、マウント済みのデバイス一覧を表示することができる。
$ mount
-o オプションは複数のオプション引数を , で受け取ることができる。
$ mount -o オプション引数1,オプション引数2,オプション引数3 デバイス マウントポイント
| オプション引数 | 説明 |
|---|---|
remount |
マウント済みのファイルシステムのオプションを変更する |
ro |
読み取り専用にする |
rw |
読み書き可能にする |
noexec |
実行可能ファイルを実行不可にする |
nosuid |
SUID / SGID を無効化する |
nodev |
デバイスファイルを無効化する |
async |
非同期書き込みを有効化する |
sync |
同期書き込み(書き込みが即時反映される)を有効化する |
_netdev |
同期書き込み(書き込みが即時反映される)を有効化する |
no_netdevmout |
同期書き込み(書き込みが即時反映される)を有効化する |
※ その他オプションは /etc/fstab 参照
※ $ mount のオプションと /etc/fstab のオプションは完全一致ではない点に注意
--bind オプションを使用すると、マウント済みのパーティション内の特定のサブディレクトリを、別のディレクトリにバインドマウントすることができる。
$ mount --bind ディレクトリ マウントポイント
-o オプションの他に、-O オプション(大文字)がある。
-O は /etc/fstab 内のオプション(4 列目の「オプションフィールド」)によるフィルタリングを行うことができる。
具体的には指定したオプションを「含むエントリ」だけを対象にしたり、指定したオプションを「含まないエントリ」だけを対象にしたりできる。必ず -a と一緒に使用する必要がある。
$ mount -a -O netdev
$ mount -a -O no_netdev
$ umount
デバイスのマウントを解除(アンマウント、取り外し)する。
アンマウントすることで、デバイスを安全に取り外すことができる。
$ umount マウントポイント
$ umount デバイス
$ umount -a
$ umount -t ファイルシステム マウントポイント
$ umount -t ファイルシステム デバイス
$ umount -a -t ファイルシステム
オートマウント
CD-ROM、DVD-ROM、USB、ネットワーク上のデバイス(NFS)上のファイルシステムが、必要となったときに自動マウントを行い(必要にならないとマウントしない)、不要になったら自動的にアンマウントする仕組み。
外部メディアを毎回手動でマウントする手間が必要ない。
またファイルシステムにアクセスがあったタイミングで自動的にマウントが行われる一方で、一定時間(デフォルトでは 5 分間)アクセスがなければ自動でアンマウントが行われるため、リソースを無駄に消費しない。
NFS などのネットワークマウントでは、常時接続によるリソース消費が解消される。
systemd によるオートマウント
systemd の .automount ユニットを使用する方法。
特定のディレクトリにアクセスを行うと、そのタイミングで .mount ユニットをトリガーにしてマウントが実行される。
以下のように .mount ユニット、.automount ユニットを用意しておく必要がある。
設定例
[Unit]
Description=USB Drive
[Mount]
What=/dev/sdb1
Where=/media/usb
Type=vfat
Options=defaults
[Install]
WantedBy=multi-user.target
[Unit]
Description=USB Drive Automount
[Automount]
Where=/media/usb
[Install]
WantedBy=multi-user.target
$ systemctl enable --now media-usb.automount
autofs デーモンによるオートマウント
autofs サービス(デーモン)を利用する方法。
systemd 環境では autofs も systemd ユニットとして管理されるが、仕組み自体は従来(SysVinit時代)からあり、systemd の .automount ユニットとは別機能である。
- カーネルの
autofsモジュール - ユーザ空間デーモン
automount(autofs.service)
の連携によって実現する。
systemd 環境下では autofs.service ユニットによって提供され、これを $ systemctl start autofs によって起動する。
マスターマップファイルとスレーブマップファイルの用意が必要となる。
- マスターマップファイル
/etc/auto.master- オートマウント対象ディレクトリとスレーブマップファイルの対応を定義する
- 編集した場合、
autofs.serviceデーモンの 再起動が必要($ systemctl restart autofs)
- スレーブマップファイル
/etc/auto.***- ファイル名は任意だが
auto.***が推奨 - 実際のマウント内容を記載する
- 編集内容は
autofs.serviceデーモンが動的に検知する(再起動不要)
マスターマップファイル
/etc/auto.master
マウントベース マップファイル オプション
- マウントベース
- ディレクトリを設定する
- このディレクトリにアクセスがあった際に、スレーブマップファイルの内容に従ってマウントが実行される
- マップファイル
- 設定ファイル(へのパス)
- マウントベースごとの実際のマウントの内容を記載する
スレーブマップファイル
/etc/auto.***
キー マウントオプション :デバイスファイルパス
- キー
- マウントポイント名
- マウントベース配下に作成されるマウントポイントとなるディレクトリを指定
- マウントオプション
-
$ mount時のオプションを指定
-
- デバイスファイル名
-
:の後にマウント対象のデバイスファイル(パーティション)を指定
-
これらの設定を行った上で、以下のコマンドでサービスを起動する。
$ systemctl start autofs
スワップ
物理メモリ(RAM)の容量が不足した際に、ストレージ 上で確保される一時的なメモリ領域。
一般的に、ディスクへのアクセス速度はメモリのアクセス速度の 1 / 1000 程度。
- パーティションをスワップとして利用する方法
- ファイルをスワップとして利用する方法
がある。
ファイルをスワップとして利用する手順は以下の通り。
スワップファイルを作成する
$ fallocate を使用する方法。
$ fallocate -l 1G ./swapfile
スワップファイル作成後は $ chmod でパーミッションを変更し、ファイル所有者以外がアクセスできないようにするのが一般的。
$ chmod 600 ./swapfile
また $ fallocate でなく、$ dd を使用する方法もある。
$ dd の場合、実際にデータを 0 埋めによって書き込むため処理が低速だが、一部のファイルシステム(XFS)では $ fallocate で作成したファイルをスワップにできない場合がある。
$ dd if=/dev/zero of=/swapfile bs=1M count=1024
スワップを初期化する
$ mkswap を使用して、パーティション、もしくはファイルのスワップ領域を初期化することができる。
$ mkswap デバイス
$ mkswap パーティション
スワップを有効化する
$ swapon を使用して、スワップの有効化、無効化を行うことができる。
$ swapon デバイス
$ swapon パーティション
スワップを永続化する
$ swapon の実行によって有効化されるスワップ領域は、電源 OFF によってリセットされる。
そのため、起動の度にスワップ有効化をする、すなわちスワップの永続化を行いたい場合には /etc/fstab を設定する必要がある。
/dev/sdb1 none swap sw 0 0
スワップを確認する
$ cat /proc/swaps
$ swapon -s
※ swapon
/proc/swaps
現在有効なスワップ領域に関する情報が格納されるファイル。
カーネル によって、動的に更新される。
$ mkswap
make swap
パーティション上、もしくはファイルにスワップ領域を初期化する。
$ mkswap デバイス
$ mkswap パーティション
作成したスワップ領域は $ swapon で有効化される。
スワップ用のファイルの作り方は こちら。
$ swapon
swap on
$ swapon デバイス
$ swapon パーティション
$ swapon は、ログイン中のシェルセッション環境下でのみスワップを有効化する。そのため、特定のパーティションのスワップの有効化を行っても、再起動によってスワップが無効になるため、再度 $ swapon を実行する必要がある。
もし、スワップ有効化を永続化したい場合、/etc/fstab に以下の設定を追加する必要がある。
パーティション none swap sw 0 0
スワップファイル none swap sw 0 0
none はマウントポイント、sw はマウント時のオプションをスワップ領域用のデフォルト設定を表す。
$ mkswap で作成したスワップ領域は $ swapon で有効化する必要がある。
永続化する場合、/etc/fstb への設定追加が必要。
$ swapon -s
$ cat /proc/swaps # swapon -s を同じ出力が得られる
$ swapon -s は /proc/swaps の情報を表示するコマンドである。
$ swapoff
$ swapoff パーミッション
$ swapoff スワップファイル
$ swapoff -a
RAID
Redundant Arrays of Inexpensive Disk / Redundant Arrays of Independent Disks
ディスクを冗長化すること。
| 種類(レベル) | 内容 |
|---|---|
RAID0 |
ストライピング。 複数のディスクを 1 台のディスクのように見せて、分散してデータを書き込む。書き込みが高速になる。複数のディスクのうち、1 台が故障すると、データ全体が消失する。 |
RAID1 |
ミラーリング 複数のディスクに同じ内容を書き込む。冗長性が増し、障害時の復旧が可能となるが、速度は高速化しない。 |
RAID4 |
エラー訂正用の パリティ 情報専用のディスクを使い、これから復旧が可能となる。3 台以上のディスクが必要。 |
RAID5 |
パリティ情報を保存するが、専用ディスクを用意しない。3 台以上のディスクが必要。 |
実務でよく RAID 1 のミラーリングを RAID 0 でストライピングする(RAID 10)ことによって、高速かつ冗長な構成が採用される。
複数の物理ディスクを利用して構成する RAID をハードウェア RAID と呼び、1 台のディスク上の複数のパーティションを利用して構成する RAID をソフトウェア RAID と呼ぶ。
/etc/mdadm.conf
RAID 名、構成が格納された設定ファイル。
/proc/mdstat
RAID アレイの状態が格納されたファイル。
カーネル によって、動的に更新される。
$ cat /proc/mdstat
$ mdadm
multiple devices driver admin
RAID を管理・構築するためのコマンド。
ハードウェア RAID ではなく、カーネルの md ドライバと連携してソフトウェア RAID アレイを作成、管理する。
$ mdadm モード
【CREATE モード】
$ mdadm --create RAIDアレイ --level=RAIDレベル --raid-devices=使用するデバイス数 使用するデバイス
※ RAID レベル
【MISC モード】
$ mdadm --stop デバイス
$ mdadm --detail デバイス
【MANAGE モード】
$ mdadm --manage RAIDアレイ --add デバイス
$ mdadm --manage RAIDアレイ --remove デバイス
$ mdadm --manage RAIDアレイ --fail デバイス
【ASSEMBLE モード】
assemble=組み立てる
$ mdadm --assemble RAIDアレイ デバイス
RAID アレイには、構成情報(メタデータ)が各デバイスの先頭や末尾に保存される。Assemble モードは、このメタデータを読み取り、正しい RAID アレイを再構成する。新規作成 (--create) と違い、データを保持したまま RAID を再構成できる。
LVM
Logical Volume Manager
パーティションは一度作成すると、サイズを変更することが難しい。
LVMはパーティション管理の柔軟化を目的に開発された。
複数のディスク領域をプール化して 論理ボリューム として扱うことによって、後から拡張や縮小することが容易となる。
PV
Physical Volume
物理ボリューム。
1 台のディスクや、1 つのパーティション。
$ pvcreate で作成する。作成時はパーティションが初期化されるため、既存データは失われる。
LVM は RAID を前提としたものではないが、RAID アレイを PV として利用する構成が実際には多い。
PE
Physical Extent
物理エクステント。
VG を構成する単位。デフォルトは 4 MB。
拡張、縮小は PE 単位で行われるが、PE の単位自体を後から変更することはできない。
VG
Volume Group
複数の PV をまとめることによって構成される(ボリュームグループ)。
LVM で容量を管理する際の「母体」となる。ディスク容量は VG 単位で確保され、LV として任意のサイズで切り出して利用することができる。
$ vgcreate で作成する。
LV
Logical Volume
論理ボリューム。
VG 内の 任意のサイズ領域 を切り出した仮想パーティション。
LV は従来のパーティションを同じように ブロックデバイス として扱うことができる。
VG 内で自由に切り出して定義することができるため、複数のディスクにまたがる LV を作成したり、あるディスクから別のディスクへ移動したりすることができる。
$ lvcreate で作成し、作成後であっても $ lvextend、$ lvreduce で柔軟に拡大縮小することができる。
$ pvcreate
$ pvcreate デバイス1 デバイス2 ...
既存のデータは消失するため注意
$ pvdisplay
$ pvdisplay デバイス
$ pvs
$ pvs
$ pvscan
$ pvscan
$ pvmove
$ pvmove 移動元デバイス 移動先デバイス
$ pvremove
$ pvremove デバイス
$ vgcreate
$ vgcreate VG名 デバイス(PV) デバイス(PV) ...
-s をつけない場合 4 MB の VE によって VG が作成される。
$ vgcreate -s VG名 デバイス(PV) デバイス(PV) ...
※ サイズ:10K/10k: 10KB、10M/10m: 10MB
$ vgdisplay
$ vgdisplay VG名
$ vgs
$ vgs
$ vgscan
$ vgscan
$ vgchange
$ vgchange -ay VG名
$ vgrename
$ vgrename 旧VG名 新VG名
$ vgremove
$ vgremove VG名
$ vgextend
$ vgextend VG名 デバイス(PV)
$ vgreduce
$ vgreduce VG名 デバイス(PV)
$ vgexport
VG を一時的に別システムへ移動するためのコマンド。
$ vgexport VG名
$ vgimport
VG を一時的に別システムへ移動するためのコマンド。
$ vgimport VG名
$ vgmerge
$ vgmerge マージ先VG名 マージ元VG名
$ lvcreate
$ lvcreate -L サイズ -n LV名 VG
※ サイズ:10G/10g: 10 GB、10M/10m: 10MB、10T/10t: 10TB
$ lvdisplay
$ lvdisplay デバイス(LV)
$ lvs
$ lvs
$ lvscan
$ lvscan
$ lvrename
$ lvrename vgdata oldlv newlv
$ lvextend
$ lvextend -L 絶対サイズ デバイス(LV)
$ lvextend -L +増分サイズ デバイス(LV)
※ サイズ:10G/10g: 10 GB、10M/10m: 10MB、10T/10t: 10TB
$ lvreduce
$ lvreduce -L サイズ デバイス(LV)
$ lvremove
$ lvremove デバイス(LV)
$ file
$ file ファイル
$ touch
$ touch ファイル名
$ mkdir
Make Directory
$ mkdir ディレクトリ名
$ mkdir -p ディレクトリパス
$ mkdir -m パーミッション ディレクトリ名
$ mkdir -m で指定できる パーミッション は数値形式のみ。
$ rmdir
ディレクトリを削除する。ただし、ディレクトリ内が空の場合に限る。
$ rmdir ディレクトリ名
$ pwd
Print Working Directory
$ pwd
$ cd
Change Direcotry
$ cd パス # 相対パスもしくは絶対パスを指定できる
- を指定すると一つ前の作業ディレクトリに戻ることができる。
$ cd -
$ mv
Move
ファイルやディレクトリを移動する。
$ mv 移動元 移動先
$ mv 移動したいファイル 移動先ディレクトリ/
複数のファイルやディレクトリを一括で移動することも可能。
$ mv ファイル1 ファイル2 ファイル3 移動先ディレクトリ/
$ mv は、ファイルやディレクトリの移動だけでなく、名前の変更(リネーム)にも使用される。
「移動」と「名前変更」は本質的に「場所または名前を変更する」という点で同じ動作であり、どちらになるかは「移動先の存在」によって自動で決定される。
重要なのは 移動先が存在する場合には「移動」、存在しない場合には「名前変更」操作として扱われる 点である。
$ mv 移動したいファイル 既存ディレクトリ # 既存ディレクトリ配下に移動
$ mv 移動したいディレクトリ 既存ディレクトリ # 既存ディレクトリ配下に移動
$ mv 名前変更したいファイル 変更後ファイル名 # ファイル名の変更
$ mv 名前変更したいディレクトリ 変更後ディレクトリ名 # ディレクトリ名の変更
「名前変更」ではなく「移動」をさせたい場合、移動先を 移動先/ としておくと意図が明確になる。ただし、 / の有無は挙動には影響がない。
$ mv 移動したいファイル 既存ディレクトリ
$ mv 移動したいファイル 既存ディレクトリ/ # 推奨
$ mv 移動したいディレクトリ 既存ディレクトリ
$ mv 移動したいディレクトリ 既存ディレクトリ/ # 推奨
-f(--force)オプションは、「ファイル上書き」が発生する場合にその確認をスキップするためのオプション。
「移動」か「名前変更」かの挙動には影響を与えない。
$ mv -f old.txt new.txt # new.txt が既に存在していても、確認なしで上書きされる
$ mv -f old.txt 移動先ディレクトリ/ # 移動先に元々存在していた old.txt が上書きされる
-f は「ファイルの上書き」が発生する場合のオプションである。同名のディレクトリが存在する場合には、エラーが発生する。
$ mv -f ディレクトリ 移動先ディレクトリ
mv: cannot move 'ディレクトリ' to '移動先ディレクトリ': Directory not empty
$ cp
$ cp コピー元 コピー先
$ cp コピー元1 コピー元2 ディレクトリ/
$ cp -r コピー元ディレクトリ コピー先ディレクトリ
-p オプションで、ファイルの所有者、パーミッション、最終更新時刻などのタイムスタンプを維持したままコピーが行えr
$ cp -p コピー元ディレクトリ コピー先ディレクトリ
$ rm
Remove
$ rm ファイル
$ rm ファイル1 ファイル2 ファイル3
$ rm *
$ rm -f ファイル
$ rm -i ファイル
$ rm -r ディレクトリ
$ dirname
Directory Name
$ dirname ファイルパス
$ dirname ディレクトリパス/
$ find
特定のディレクトリツリー配下から、条件に一致するファイルを再帰的に検索する。
$ find 検索開始ディレクトリ 検索式
検索開始ディレクトリを省略すると、カレントディレクトリ配下が検索対象になる。
$ find 検索式
$ find .
特殊文字の扱い
ファイル名にスペース「 」や、コーテーション「'」などの特殊文字が含まれている場合のTips。
ファイル名がhello world.txtのようにスペースを含む場合。
"" で囲う
$ find . "hello world.txt"
バックスラッシュ \ でエスケープする
$ find . hello\ world.txt
検索式
$ find コマンドの検索式はやや特殊な構文となっている。
| 検索式 | 意味 |
|---|---|
-name |
ファイル名 |
-type |
ファイルの種類f:ファイルl:シンボリックリンクd:ディレクトリ |
-uid |
ファイル所有者の UID |
-user |
ファイルを所有するユーザ名、ユーザ ID |
-print |
検索結果を標準出力として出力 |
-atime |
最終アクセス時刻(日単位) |
-amin |
最終アクセス時刻(時間単位) |
-mtime |
最終更新時刻 |
-size |
ファイルサイズ |
-exec コマンド {} \; |
一致したファイルが指定したコマンドの引数として {} に展開され、実行されるコマンドは 1 ファイルづつ実行されるため、ファイル数が多いとコマンドの実行回数も増えるため、処理が遅くなることがある |
-exec コマンド {} + |
+ を使うことで、ファイルを一度に処理する引数をまとめて処理できるコマンド( $ rm、$ ls、$ echo など)に対して特に有効 |
-ok コマンド {} \; |
-exec と同じ確認あり |
-name
$ find 検索開始ディレクトリ -name ファイル名
$ find 検索開始ディレクトリ -name "*.txt"
-type
$ find 検索開始ディレクトリ -type f -name ファイル名
$ find 検索開始ディレクトリ -type d -name ディレクトリ名
-atime
$ find 検索開始ディレクトリ -atime -1
$ find 検索開始ディレクトリ -atime +1
-amin
$ find 検索開始ディレクトリ -amin -60
-size
$ find 検索開始ディレクトリ -size +100M
-exec
{} には一致したファイルパスが展開される。
\; で終了した場合、{} はコマンドに対して 1 つずつ渡される。一致したファイル数が多い場合、処理速度は低速になることがある。
; はシェルで特別な意味(コマンドの連続実行)を持つため、\ でエスケープする必要がある。
$ find 検索開始ディレクトリ 検索式 -exec rm {} \;
一方、+ で終了した場合、コマンドに対して {} はまとめて渡される。
指定するコマンドは引数をまとめて処理できるコマンド($ rm、$ ls、$ echo など)である必要がある。
$ find 検索開始ディレクトリ 検索式 -exec rm {} +
-perm
パーミッションを指定して検索を行う。
指定方法が 3 つある。
- 完全一致
-perm xxxx- 例:
-perm 6000→6000のみ該当
- AND 一致
-perm -xxxx- 例:
-perm -6000→4xxxかつ2xxx→6xxxが該当
- OR 一致
-perm /xxxx- 例:
-perm /6000→4xxxまたは2xxxまたは6xxxが該当
$ find 検索開始ディレクトリ -perm パーミッション条件
$ locate
ファイルを検索するためのコマンド。
事前に作成されたデータベースを使って検索を行うため、$ find よりも高速に動作する。
システム全体から検索を行う。ディレクトリを限定した検索は行うことができない。
$ locate 検索ワード
$ updatedb
$ locate が検索に使用するデータベース(/var/lib/mlocate/mlocate.db)は $ updatedb によって手動で更新することができる。
ディストリビューションによってはデータベースは cron によって定期的に更新される。
$ updatedb
$ updatedb -e ディレクトリ







