🐧

Linuxコマンドを深掘り – lsblk 【Debian】

2023/12/25に公開

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

上記はブロックデバイスの一覧を出力する例です。謎の数字が表示されますが...これはlsblkMAJ: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