前回の記事を書いてしばらくしてから思いつきました、「tmp*に退避する位ならinitramfsでは予測可能な命名でもいいのでは?」と。
そうした場合、
- 別々のudevルールで設定できるので上手く設定すればinitramfsを更新しても問題ない。
- 1度目の命名をわざわざ全てのデバイスに対して行わなくてよい。(勝手にeth*が空いてくれる)
- 万が一2度目の命名に失敗してもtmp*ではなく予測可能な命名になる。
手順1
まずsystemd/udevの予測可能な命名を有効にするため、cat /proc/cmdline
を実行する等してnet.ifnames=0
になっていないことを確認してください。
手順2
2段階udev命名を行うために、使用予定の全てのドライバをinitramfsに含めます。前回の対処法ex3ではmodprobe.dのsoftdepを使って横着しましたが今回は正攻法でやります。
RHEL系の場合
add_drivers+="e1000e tg3 ixgbe igb"
Debian系の場合
e1000e
tg3
ixgbe
igb
手順3
「initramfsでは予測可能な命名になり、ルートマウント後はユーザ定義の命名ルールを使用する」挙動を設定します。initramfsでは(lib)/80-net-setup-link.rulesが有効となり、ルートマウント後は(etc)/50-net-fixed.rulesが動作する様にすればいい訳です。そのために50-net-fixed.rulesのinitramfsへの書き込みを確実に防ぐ必要があります。
ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{address}=="aa:aa:aa:aa:aa:aa" , NAME="eth0"
:
RHEL系の場合
デフォルトでは自作のudevルールは自動でinitramfsに書き込まれないのでそのままinitramfsを更新します。前回記事で/etc/dracut.conf.d/net-fixed-rules.confを作成していた場合は削除してください。
$ sudo dracut -f
Debian系の場合
ちょっとややこしいです。initramfs-tools-coreパッケージの/usr/share/initramfs-tools/hooks/udevフックによって、/etc/udev/rule.d/以下のudevルールは/lib/udev/rules.d/以下に同名のルールが存在しない場合に/lib/…に移動してinitramfsに書き込まれます。そのため/lib/…の方に空ファイルを作成します。
$ sudo touch /lib/udev/rules.d/50-net-fixed.rules
その後initramfsを更新します。
$ sudo update-initramfs -u -k all
動作確認
異種のネットワークデバイス(オンボード/Intel X520-DA/Intel I350/Broadcom BCM5720)を挿してそれらを任意のeth*に振り直して確認しました(括弧内はポート番号)。
ドライバ | デバイス | 予測可能な命名 | 振り直し後 |
---|---|---|---|
e1000e | オンボード | enp0s25 | eth0 |
tg3 | BCM5721(1) | enp9s0f0 | eth1 |
tg3 | BCM5721(2) | enp9s0f1 | eth2 |
ixgbe | X520-DA(1) | ens4f0 | eth3 |
ixgbe | X520-DA(2) | ens4f1 | eth4 |
igb | I350(1) | ens1f0 | eth5 |
igb | I350(2) | ens1f1 | eth6 |
igb | I350(3) | ens1f2 | eth7 |
igb | I350(4) | ens1f3 | eth8 |
以下のログの通り、initramfsで予測可能な命名→ルートマウント→eth*に振り直しと動作しています。何パターンか振り直し方を変えてもちゃんと動作してくれました。
... kernel: tg3 0000:03:00.1 ens4f1: renamed from eth1
... kernel: tg3 0000:03:00.0 ens4f0: renamed from eth0
... kernel: e1000e 0000:00:19.0 enp0s25: renamed from eth0
... kernel: ixgbe 0000:01:00.0 ens1f0: renamed from eth1
... kernel: ixgbe 0000:01:00.1 ens1f1: renamed from eth4
... kernel: igb 0000:09:00:1 enp9s0f1: renamed from eth2
... kernel: igb 0000:09:00:0 enp9s0f0: renamed from eth0
... kernel: igb 0000:09:00:2 enp9s0f2: renamed from eth3
... kernel: igb 0000:09:00:3 enp9s0f3: renamed from eth1
:
... systemd[1]: Starting Remount Root and Kernel File Systems...
:
... kernel: tg3 0000:03:00.1 eth2: renamed from ens4f1
... kernel: tg3 0000:03:00.0 eth1: renamed from ens4f0
... kernel: ixgbe 0000:01:00.1 eth4: renamed from ens1f1
... kernel: ixgbe 0000:01:00.0 eth3: renamed from ens1f0
... kernel: igb 0000:09:00.1 eth6: renamed from enp9s0f1
... kernel: igb 0000:09:00.3 eth8: renamed from enp9s0f3
... kernel: igb 0000:09:00.0 eth6: renamed from enp9s0f0
... kernel: igb 0000:09:00.2 eth7: renamed from enp9s0f2
... kernel: e1000e 0000:00:19.0 eth0: renamed from enp0s25
RHEL系の場合古い環境を引き継いでいて、70-persistent-net.rulesがあったりifcfg-*にHWADDR行があるとudevルール優先順位の都合で想定通りに動きません。うまく動作しない場合、これらの設定でeth*に命名されていないかチェックしてください。
結び
トリッキーですが一応安定して動く解決策が見つかりました。しかし「ユーザ操作によるeth*命名はカーネルが予約している名前空間の侵害」というスタンスは変わりません。可能な限り回避すべきです。