Linuxコマンドを深掘り – lsblk 【Debian】
MedOps Technologiesの杉田です。開発では主にインフラを担当しております。「原理に立ち返るインフラ管理」をモットーに、物理サーバ管理からクラウド構築まで日々奮闘中です。
弊社ではDebianを採用することが多く、Debianベースの物理サーバー、クラウドインスタンス、Dockerコンテナを複数運用しています。
今回は、「いまこのサーバのディスクってどんな感じなんだっけ?」と思った時に便利なlsblk
コマンドについてです。基本的な使い方と出力の見方、オプション、そしてコマンドの動作原理まで深掘りしていきたいと思います。
lsblkとは「ブロックデバイス一覧」
lsblkコマンドは"list block devices"を略したコマンドです。
Linuxではデバイスを主にキャラクタデバイスとブロックデバイスに分類します(ref)。キャラクタデバイスは「バイト単位でのデータ転送」として抽象できるデバイスを指します(ref)。キーボードやマウスなどがその例です。
ブロックデバイスは「ブロック単位でのデータ転送」が可能なデバイスで、ストリーム前提のキャラクタデバイスと違い、ランダムアクセス可能なものを指します(ref)。実例としてHDDやSSDなどがあります。
つまりlsblkは、HDDやSSDなどブロックデバイスの一覧を出力するコマンドと理解することができます。
lsblkを実行してみる
lsblkはsudoなしに実行可能です。
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 931.5G 0 disk
├─sda1 8:1 0 1007K 0 part
├─sda2 8:2 0 512M 0 part
└─sda3 8:3 0 446.6G 0 part
├─pve-swap 253:0 0 8G 0 lvm [SWAP]
├─pve-root 253:1 0 96G 0 lvm /
├─pve-data_tmeta 253:2 0 3.3G 0 lvm
│ └─pve-data-tpool 253:4 0 320.1G 0 lvm
│ ├─pve-data 253:5 0 320.1G 1 lvm
│ ├─pve-vm--1001--cloudinit 253:6 0 4M 0 lvm
│ ├─pve-vm--1001--disk--0 253:7 0 128G 0 lvm
.
.
.
上記はdebianベースのproxmoxホストで実行した結果の一部です。デフォルトで出力されるカラムの意味を説明します。
NAME
ブロックデバイスの名前です。Debianのドキュメントを読めばわかりますが、sdXはハードディスクを指します(SSDでもsdXになります)。
sda
は1番目のハードディスク、sdb
は2番目のハードディスク、sda1
はsdaの最初のパーティション、といった感じです。論理ボリュームにはpve-root
など任意の名前がついています。
sdXのsdって何だ?
SCSI deviceの略ですが、LinuxではSATA等の他のストレージインターフェースでもSCSI device扱いされます。SCSIはSmall Computer System Interfaceの略で、「スカジー」などと発音します。現在ではSAS規格にラップされているようです。ストレージインターフェースの歴史はこの記事が参考になります。
MAJ:MIN
Major Number: Minor Numberの略です。前者はデバイスドライバの番号で、後者は同一ドライバを使用しているデバイスを区別するためだけの番号です。
もう少し噛み砕きます。LinuxはOSレベルでキーボードやSCSIデバイス向けにドライバを実装しており、それぞれに番号を振っています。例えば、SCSIデバイス(ディスクは基本これです)のドライバは8番が振られています。
凡例は
$ cat /proc/devices
で取得可能です。
RM
Removable Deviceのことで、抜き差しできるかのフラッグです。
Removable Deviceの場合は1になります。
SIZE
シンプルにサイズです。
RO
Read Onlyのことです。Read Onlyの場合は1になります。
TYPE
ブロックデバイスのタイプです。代表的なものを解説します。
- disk: 物理ディスク
- part: パーティション
- lvm: 論理ボリューム
MOUNTPOINT
ブロックデバイスにファイルシステムがマウントされていれば、そのパスがここに表示されます。
その他の出力可能カラム
lsblk
はオプションを指定すれば上記のカラム以外の情報も取得できます。
取得可能カラムは以下です(英語ですがlsblk --help
で同じ一覧を得られます)。
カラム名 | 説明 |
---|---|
NAME | デバイス名 |
KNAME | 内部カーネルデバイス名 |
PATH | デバイスノードのパス |
MAJ:MIN | メジャー:マイナーデバイス番号 |
FSAVAIL | 利用可能なファイルシステムサイズ |
FSSIZE | ファイルシステムサイズ |
FSTYPE | ファイルシステムのタイプ |
FSUSED | 使用中のファイルシステムサイズ |
FSUSE% | ファイルシステム使用率 |
FSVER | ファイルシステムのバージョン |
MOUNTPOINT | デバイスがマウントされている場所 |
LABEL | ファイルシステムのラベル |
UUID | ファイルシステムのUUID |
PTUUID | パーティションテーブル識別子(通常はUUID) |
PTTYPE | パーティションテーブルのタイプ |
PARTTYPE | パーティションのタイプコードまたはUUID |
PARTTYPENAME | パーティションのタイプ名 |
PARTLABEL | パーティションのラベル |
PARTUUID | パーティションのUUID |
PARTFLAGS | パーティションのフラグ |
RA | デバイスのリードアヘッド |
RO | リードオンリーデバイス |
RM | 取り外し可能なデバイス(USB、PCMCIA、...) |
HOTPLUG | 取り外し可能またはホットプラグデバイス |
MODEL | デバイス識別子 |
SERIAL | ディスクシリアル番号 |
SIZE | デバイスのサイズ |
STATE | デバイスの状態 |
OWNER | ユーザー名 |
GROUP | グループ名 |
MODE | デバイスノードのアクセス権限 |
ALIGNMENT | アラインメントオフセット |
MIN-IO | 最小I/Oサイズ |
OPT-IO | 最適なI/Oサイズ |
PHY-SEC | 物理セクタサイズ |
LOG-SEC | 論理セクタサイズ |
ROTA | 回転デバイス |
SCHED | I/Oスケジューラ名 |
RQ-SIZE | リクエストキューサイズ |
TYPE | デバイスのタイプ |
DISC-ALN | 切り捨てアラインメントオフセット |
DISC-GRAN | 切り捨ての粒度 |
DISC-MAX | 切り捨て最大バイト数 |
DISC-ZERO | 切り捨てがデータをゼロにするかどうか |
WSAME | ライトセームの最大バイト数 |
WWN | 一意のストレージ識別子 |
RAND | ランダム性を追加 |
PKNAME | 内部親カーネルデバイス名 |
HCTL | SCSIのホスト:チャンネル:ターゲット:Lun |
TRAN | デバイスの輸送タイプ |
SUBSYSTEMS | 重複しないサブシステムのチェーン |
REV | デバイスのリビジョン |
VENDOR | デバイスのベンダー |
ZONED | ゾーンモデル |
DAX | DAX対応デバイス |
-o
オプションを使ってlsblk -o NAME,KNAME,PATH
などと一から選んだり、lsblk -o +UUID
などデフォルトカラムに追加したりできます。
またlsblk -fs
とすればファイルシステム系のカラムが選ばれます。その他の選択肢はlsblk --help
で確認してください。
lsblkの動作原理
man lsblk
を実行すると以下のような説明があります(太字は筆者によるもの)。
lsblk lists information about all available or the specified block devices. The lsblk command reads the sysfs filesystem and udev db to gather information. If the udev db is not available or lsblk is compiled without udev support than it tries to read LA-
BELs, UUIDs and filesystem types from the block device. In this case root permissions are necessary.
「lsblkコマンドはsysfsファイルシステムとudevデータベースから情報を集める」とのことです。ソースコードリーディングは筆者が挫折したので、せめてsysfsとudevについて説明したいと思います。
sysfs
man sysfs
で以下の説明が得られます。
The sysfs filesystem is a pseudo-filesystem which provides an interface to kernel data structures. (More precisely, the files and directories in sysfs provide a view of the kobject structures defined internally within the kernel.) The files under sysfs provide information about devices, kernel modules, filesystems, and other kernel components.
sysfsは仮想的なファイルシステムで、Linuxカーネルのデータ構造に対するインターフェースを提供しているとのことです。具体的にはデバイス、カーネルモジュール、ファイルシステム、その他カーネルコンポーネントの情報を提供しています。
lsblk
コマンドは内部でブロックデバイス情報を取得する必要があり、その手段としてsysfsインターフェースを使っている、というのは一定の納得感があるかと思います。
sysfs
は/sys
にマウントされているため、イメージをつけるために少し確認してみましょう。
$ ls /sys/dev/block
253:0 253:1 253:10 253:11 253:12 253:13 253:14 253:2 253:3 253:4 253:5 253:6 253:7 253:8 253:9 7:0 7:1 7:2 7:3 7:4 7:5 7:6 7:7 8:0 8:1 8:2 8:3
上記はブロックデバイスの一覧を出力する例です。謎の数字が表示されますが...これはlsblk
のMAJ:MIN
カラムで見たことがありますね!
ということで、皆さんも/sys
以下を覗いてみてください。ある程度の実感を得られると思います。(私もこれ以上の説明ができず情けないです)
udevデータベース
man udev
(中略、太字は筆者)
udev supplies the system software with device events, manages permissions of device nodes and may create additional symlinks in the /dev/ directory, or renames network interfaces. The kernel usually just assigns unpredictable device names based on the order of discovery. Meaningful symlinks or network device names provide a way to reliably identify devices based on their properties or current configuration. (中略) All device information udev processes is stored in the udev database and sent out to possible event subscribers. Access to all stored data and the event sources is provided by the library libudev.
udevはデバイスイベント(USB抜き差しとかプリンターのネットワーク状態遷移とか)に関わるシステムソフトウェアを提供したり、デバイスの権限管理及び/dev
ディレクトリへのシンボリックリンク追加をおこなったり、ネットワークインターフェースの名称変更などをおこなっています。udevが処理したデバイス情報がudevデータベースに保存されています。
最近のDebianではudevデータベースの実体は/run/udev/data
にあります。udevadm
コマンドでデータベースの参照・変更が可能です。
まとめ
lsblk
コマンド一つをみても勉強することが盛りだくさんです。これからも様々なコマンドを深掘りしていき、Linuxの原理的理解を進めていければと思います。
ここまで読んでいただきありがとうございました。
Discussion