はじめに
Linuxサーバを運用していると、ストレージ追加やUSB機器の認識、ネットワークインターフェースの追加、さらには「ディスクが認識されない」「デバイスファイルが作成されない」といった障害対応など、デバイス管理の知識が必要になる場面は少なくありません。
しかし、多くのエンジニアは mount や lsblk、fdisk などのコマンドを利用する機会はあっても、Linuxカーネルが内部でどのようにデバイスを認識し、デバイスドライバを割り当て、/dev 配下のデバイスファイルを生成しているのかを詳しく理解する機会は意外と少ないのではないでしょうか。
本記事では、Linuxのデバイス管理の仕組みを、インフラエンジニア向けに分かりやすく解説します。
具体的には、以下の内容を扱います。
- Linuxカーネルとデバイスドライバの役割
- デバイスファイル(
/dev)の仕組み - メジャー番号・マイナー番号の意味
udevによるデバイスファイル生成の流れ
これらの仕組みを理解することで、ストレージ追加やデバイス認識トラブルだけでなく、Linux内部の動作をより深く理解できるようになります。
Linuxのデバイス管理
LinuxサーバではディスクやNIC、USB機器などさまざまなハードウェアが利用されています。しかしLinuxアプリケーションは、これらのハードウェアを直接操作しているわけではありません。Linuxカーネルがデバイスドライバを介してデバイスを管理し、ユーザ空間へ機能を提供しています。
Linuxのデバイス管理について説明する前に、まずはLinuxがどのようにハードウェアを扱っているのかを理解しておきましょう。
サーバに新しいデバイスが追加された場合、Linuxは内部で次のような処理を行います。
- デバイスを検知する
- 適切なデバイスドライバを割り当てる
- デバイスファイルを作成する
- ユーザ空間から利用できる状態にする
この一連の仕組みを「デバイス管理」と呼びます。
デバイスドライバ
Linuxでハードウェアを利用するには、「デバイスドライバ」が必要です。デバイスドライバとは、OSとハードウェアの橋渡しを行うソフトウェアです。例えば、アプリケーションがディスクへデータを書き込む場合でも、アプリケーション自身が直接ディスクを制御しているわけではありません。内部では、Linuxカーネルとデバイスドライバを経由してハードウェアへアクセスしています。
デバイス読み書き処理の流れ
デバイス読み書き処理の流れを簡単に表すと、以下のようになります。

① アプリケーションが read()/write() を呼び出す
アプリケーションは read() や write() を呼び出し、デバイスへの読み書きを要求します。
② デバイスファイルを参照する
Linuxカーネルは、指定されたデバイスファイル(例:/dev/sda)を参照し、対応する inode を取得します。
③ メジャー番号・マイナー番号を取得する
inode に保存されているメジャー番号とマイナー番号を取得し、どのデバイスドライバを利用するかを判断するための情報を取得します。
④ デバイスドライバを選択する
メジャー番号をもとに、対応するデバイスドライバ(例:sd ドライバ)を選択します。
⑤ 対象デバイスを特定する
デバイスドライバは、マイナー番号を利用して自身が管理する対象デバイスを特定します。
⑥ ハードウェアへI/Oを実行する
デバイスドライバがハードウェアへI/Oを実行し、読み書き結果をアプリケーションへ返します。
代表的なデバイスドライバ
| デバイス | ドライバ例 |
|---|---|
| SATA/SCSIディスク | sd |
| NVMe SSD | nvme |
| USB機器 | usb |
| ネットワークカード | e1000, ixgbe など |
デバイスファイル
Linuxでは、ディスクやUSB、キーボードなどのハードウェアを「デバイスファイル」として扱います。アプリケーションは通常のファイル操作(open/read/write)を通じてデバイスへアクセスします。
デバイスファイルは/devディレクトリ配下に作成されます。例えば以下のようなものがあります。
– ストレージ (/dev/sda, /dev/nvme0n1)
– 端末 (/dev/tty, /dev/pts)
– 特殊デバイス (/dev/null, /dev/zero)
– 仮想/論理デバイス (/dev/mapper)
– シリアル/外部I/O (/dev/ttyUSB0)
Linuxでは「Everything is a file(すべてをファイルとして扱う)」という思想があり、ハードウェアもファイル経由で操作されます。ファイル経由の操作にすることで、アプリケーションはデバイスごとに複雑な操作を意識する必要がなく、共通のインターフェースで扱えるという利点があります。
主要なデバイスファイルである/dev/sda、/dev/ttyについて見てみましょう。
[root@quiz ~]# ll /dev/
~~
brw-rw---- 1 root disk 8, 0 Dec 19 08:55 sda
brw-rw---- 1 root disk 8, 1 Dec 19 08:55 sda1
brw-rw---- 1 root disk 8, 2 Dec 19 08:55 sda2
brw-rw---- 1 root disk 8, 3 Dec 19 08:55 sda3
~~
crw-rw-rw- 1 root tty 5, 0 Mar 1 06:50 tty
crw--w---- 1 root tty 4, 0 Dec 19 08:55 tty0
crw--w---- 1 root tty 4, 1 Dec 19 08:55 tty1
crw--w---- 1 root tty 4, 10 Dec 19 08:55 tty10特に確認すべきポイントは以下の3つです。
- 先頭文字
b(ブロックデバイス)かc(キャラクタデバイス)か、を示しています。
ブロックデバイスとは、ディスクなどのストレージデバイス(HDD、SSD、USBストレージなど)を指しています。ブロック単位(通常512Bや4KB)で読み書きを行うことが特徴です。
キャラクタデバイスとは、キーボードやターミナルなど、1文字単位・ストリーム形式でデータを扱うデバイスとなります。 - デバイス名
sda や tty など、何のデバイスを示しているかを確認できます。 - メジャー/マイナー番号
カーネルがどのデバイスドライバで処理するかを示す識別子を確認できます。例えば、/dev/sdaにおて、デバイスドライバ種別を示すメジャー番号が8となっており、個別デバイスを示すマイナーバージョンは0となっています。
brw-rw—- 1 root disk 8, 0 Dec 19 08:55 sda
Linuxではメジャー番号、マイナー番号を認識して、以下の流れでディスク読み書きを実行します。
1.カーネルがデバイスファイルを見る
2.メジャー番号を確認
3.対応するドライバを呼ぶ
4.マイナー番号で対象デバイスを特定
5.読み書き実行
主なデバイスのメジャーバージョンは以下となります。
ブロックデバイス(ストレージ系)のメジャー番号:
| メジャー番号 | デバイス / ドライバ | 用途 |
|---|---|---|
| 1 | RAM disk (ramdisk) | メモリ上の仮想ディスク |
| 7 | Loop device (loop) | ISOマウント、イメージファイル |
| 8 | SCSI disk (sd) | SATA / SAS / USBストレージ |
| 9 | MD (md) | ソフトウェアRAID |
| 11 | SCSI CD-ROM (sr) | CD/DVD |
| 65–71 | 追加SCSI disk | 複数ディスク拡張 |
| 253 | Device Mapper (dm) | LVM, multipath, LUKS |
| 259 | blkext | NVMeなど拡張ブロック |
※ストレージデバイスはランダムアクセスが可能であり、一定サイズのブロック単位で効率的に読み書きを行うため、ブロックデバイスとして扱われます。
キャラクタデバイス(端末・制御系)のメジャー番号:
| メジャー番号 | デバイス / ドライバ | 用途 |
|---|---|---|
| 1 | Memory devices | /dev/null, /dev/zero, /dev/random |
| 4 | TTY devices | 仮想端末 |
| 5 | Console / PTY | /dev/tty, /dev/console |
| 10 | Misc devices | 雑多な制御デバイス |
| 13 | Input devices | キーボード、マウス |
| 136–143 | Pseudo terminals | SSHセッションなど |
ちなみに、現在利用しているデバイス/メジャー番号は、/proc/devices にて確認することが可能です。
[root@localhost ~]# cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
~~Truncated~~
Block devices:
8 sd
9 md
65 sd
66 sd
67 sd
68 sd
udevによるデバイス管理
古いLinuxでは、デバイスファイルを静的に管理していましたが、現在は udev により動的に管理されています。udevは、デバイス接続イベントを監視し、自動的に /dev 配下へデバイスファイルを生成する仕組みです。Linuxカーネルと連携して、以下の流れでデバイスファイルが作成されます。

- ハードウェア接続
USBメモリやディスクなどのハードウェアが接続されます。 - Linuxカーネルがデバイスを検知
dmesg に以下のようなログが出力されます。
usb 2-1: new high-speed USB device
sd 6:0:0:0: Attached SCSI removable disk - sysfs (/sys) にデバイス情報を作成
Linuxカーネルは、検知したデバイスをカーネルオブジェクト(kobject)として登録し、その情報を sysfs (/sys) ※に公開します。
※sysfs :デバイス、デバイスドライバ、カーネルオブジェクトに関する情報をカーネル空間からユーザー空間へ公開するための仮想ファイルシステム - uevent(イベント通知)
Linuxカーネルは kobject_uevent() を実行し、Netlinkソケット※経由で uevent を送信します。
※Linuxカーネルとユーザー空間のプロセスがイベントや情報をやり取りするための通信インターフェース - udevd がイベントを受信
udev を実際に動作させるデーモンプロセスであるudevd(systemd-udevd)がイベントを受信します。 - udevがsysfsを参照
/sysディレクトリに公開されたデバイス情報を参照 - udevルールを参照
udevルールに従って、デバイス名や権限、シンボリックリンクなどの設定を適用します。 - /dev にデバイスファイル生成
devtmpfsによりベースとなるデバイスファイル(例:/dev/sdb、/dev/sdb1)が生成されます。その後、udevがルールに従ってデバイス名やアクセス権限、シンボリックリンクなどを設定します。
また、ハードウェアが取り外されると、Linuxカーネルは removeイベントを通知します。これを受けたudevは不要となったデバイスノードやシンボリックリンクを削除します。
※sysfsの詳細は以下を参照
sysfs – _The_ filesystem for exporting kernel objects — The Linux Kernel documentation
※udevの詳細は以下を参照
udev
まとめ
Linuxでは、ハードウェアは単純に「接続すれば使える」わけではなく、Linuxカーネル・デバイスドライバ・sysfs・udev が連携することで利用可能になっています。
内部では以下のような流れでデバイス管理が行われています。
– Linuxカーネルがデバイスを検知
– 適切なデバイスドライバを割り当て
– sysfs (/sys) にデバイス情報を公開
– uevent を userspace へ通知
– udev(systemd-udevd) がイベントを受信
– udev が sysfs を参照
– /dev 配下へデバイスファイルを生成
Linuxでは「Everything is a file」という思想のもと、ディスクや端末などのハードウェアもファイルとして扱われています。そのため、デバイスファイル・メジャー番号・マイナー番号の仕組みを理解することは、Linux内部動作を理解するうえで非常に重要です。
実際の障害調査では、「デバイスを認識しているか」「適切なドライバが割り当てられているか」「udevによってデバイスファイルが作成されているか」の3点を確認することで、多くのデバイス関連トラブルの原因を切り分けることができます。
ストレージ管理やファイルシステムに関する記事も書いているので、合わせてご参照ください。
Linux LVMディスク拡張を徹底解説|PV・VG・LV拡張からオンライン容量拡張まで
Linux Multipathを徹底解説|iSCSI構築からWWID・Device Mapper・フェイルオーバまで
Linuxエンジニア必見!ファイルシステムの基礎知識と仕組みをわかりやすく解説


コメント