毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。
0. はじめに
Lustreファイルシステムをシステム起動時に自動マウントするにあたり、以下の課題に対応した記録です。
- LNetサービス完了後に自動的にLustreマウントを実行したい
- 起動時のタイミング問題(LNet NI未準備)に対処したい
これを行わないとInfiniBandの初期化が終わっていない状態で、Lnetが起動してエラーになってしまいマウントされないといった問題が発生します。この問題が発生したのは、HPE社が提供するCray C500用のパッケージを使った場合なので、
環境
| 項目 | バージョン |
|---|---|
| OS | Ubuntu (カーネル 6.8.0-100-generic) |
| Lustre | 2.16.54 (DKMS) |
| OFED | Mellanox OFED 25.07 |
| InfiniBand | Mellanox ConnectX (mlx5) |
| Storage | HPE Cray C500 |
| Lustre Client Packages | lustre-client-utils_2.16.54-48-ge33c0b2-1_amd64.deb |
1. lnet.serviceにoverride.confを追加してInfiniBandの起動を待つようにする
/etc/systemd/system/lnet.service.d/override.confを以下のように作成する
[Unit]
After=network-online.target openibd.service rdma.service
[Service]
ExecStartPre=/sbin/modprobe ko2iblnd
ExecStartPre=/bin/bash -c 'for i in $(seq 1 30); do ibstat | grep -q "State: Active" && exit 0; sleep 1; done; exit 1'
ExecStart=
ExecStart=/sbin/modprobe lnet
ExecStart=/usr/sbin/lnetctl lnet configure
ExecStart=/bin/bash -c 'for i in $(seq 1 30); do /usr/sbin/lnetctl import /etc/lnet.conf 2>/dev/null && exit 0; sleep 1; done; /usr/sbin/lnetctl import /etc/lnet.conf'
2. fstabによるLustre自動マウント
/etc/fstabにsystemdの依存関係オプションを指定し、起動時に自動マウントさせます。
2-1. fstab エントリ
<サーバー1>@o2ib,<サーバー2>@o2ib:/<fsname> <マウントポイント> lustre defaults,noatime,flock,_netdev,x-systemd.requires=lnet.service,x-systemd.after=lnet.service 0 0
2-2. 重要なオプション
| オプション | 役割 |
|---|---|
x-systemd.requires=lnet.service |
lnet.serviceが起動していなければ自動的に起動する |
x-systemd.after=lnet.service |
lnet.service完了後にマウントを実行する |
_netdev |
ネットワークデバイスに依存するマウントであることをsystemdに伝える |
2-3. 前提条件
fstabのx-systemd.requiresが正しく機能するには、lnet.serviceが以下の設定を持っている必要があります。
[Service]
Type=oneshot
RemainAfterExit=yes
Type=oneshotは複数のExecStart=を許可し、RemainAfterExit=yesはコマンド完了後もサービスを active状態に維持します。これがないとsystemdは依存先が起動していないと判断し、マウントが実行されません。
3. 起動時のタイミング問題への対処
/etc/systemd/system/lnet.service.d/override.confの内容の説明です。
3-1. 症状
lnetctl lnet configureの直後にlnetctl importを実行すると、LNet NIがまだ準備できておらず以下のエラーになります。
errno: -100
descr: ! "cannot add LNet NI"
数秒後に再実行すれば成功します。
3-2. 対処
ExecStartでリトライループを使用します。リトライ中のエラー出力は2>/dev/nullで抑制し、全リトライ失敗時のみエラーを出力します。
ExecStart=/bin/bash -c 'for i in $(seq 1 30); do /usr/sbin/lnetctl import /etc/lnet.conf 2>/dev/null && exit 0; sleep 1; done; /usr/sbin/lnetctl import /etc/lnet.conf'
4. 起動シーケンス
起動シーケンスは以下のようになります。
network-online.target
↓
openibd.service / rdma.service
↓
lnet.service
├ ExecStartPre: modprobe ko2iblnd
├ ExecStartPre: IBポート Active 待機(最大30秒)
├ ExecStart: modprobe lnet
├ ExecStart: lnetctl lnet configure
└ ExecStart: lnetctl import(リトライ付き、最大30秒)
↓
wmount(fstabから自動生成)
└ mount -t lustre ...
5. トラブルシューティング
5-1. 確認コマンド集
# lnet.service の状態確認
systemctl status lnet.service --no-pager -l
# マウント状態確認
mount | grep <マウントポイント>
# systemdが生成した.mountユニットの確認
systemctl cat work.mount
# LNet NI の状態確認
sudo lnetctl net show