2011年8月7日日曜日

CentOS 6.0 で NIC と ethX の対応を固定化する

CentOS 6.0 で NIC 交換 (オンボードの場合はマザーボード交換も含む) した場合でも、ethX が変化しないように、固定化する方法です。RHEL6 でも同様にして可能。
2015-01-18追記、CentOS7/RHEL7についてはこちらを参照。

CentOS 6.0 のデフォルトでは、MAC アドレスと ethX を対応付けており、交換により MAC が変化すると、自動的に新たな対応関係が作られるようになっているため、ethX がずれてしまいます。対応関係は、/etc/udev/rules.d/70-persistent-net.rules に設定されます。
このあたりについては、前に書いた記事を参照してください。

CentOS 6.0 で NIC 交換した場合の挙動
CentOS 6.0 で NIC と ethX の対応を変更する

以上が基礎知識ですが、まずは、この 70-persistent-net.rules を無効化します。
少々、荒っぽいやり方ですが、ルールが自動生成されないように、/dev/null へシンボリックリンクを張ってしまいます。
[root@centos6 ~]# ln -s -f /dev/null /etc/udev/rules.d/70-persistent-net.rules
[root@centos6 ~]# ls -l /etc/udev/rules.d/70-persistent-net.rules
lrwxrwxrwx 1 root root 9 Aug  7 12:07 /etc/udev/rules.d/70-persistent-net.rules -> /dev/null
このとき messages に、次のメッセージが出ますが、一時的なものなので、気にする必要はありません。
Aug  7 12:07:22 centos6 udevd[406]: can not read '/etc/udev/rules.d/70-persistent-net.rules'

次に、/etc/udev/rules.d/65-eth.rules ファイルを新規作成して、次のように記載します。
ACTION=="add", KERNEL=="eth*", ID=="0000:02:01.0", DRIVERS=="?*", ATTR{type}=="1", NAME="eth2", OPTIONS="last_rule"
ACTION=="add", KERNEL=="eth*", ID=="0000:02:04.0", DRIVERS=="?*", ATTR{type}=="1", NAME="eth3", OPTIONS="last_rule"
ここで、0000:02:01.0 や 0000:02:04.0 は PCI アドレスです。lspci で表示される値に、0000: (domain と呼ばれる管理番号ですが、普通のマシンは 0000 です) をつけた値です。この PCI アドレスは、ethtool コマンドで確認することもできます。
[root@centos6 ~]# ethtool -i eth2
driver: e1000
version: 7.3.21-k6-NAPI
firmware-version: N/A
bus-info: 0000:02:01.0
[root@centos6 ~]# ethtool -i eth3
driver: e1000
version: 7.3.21-k6-NAPI
firmware-version: N/A
bus-info: 0000:02:04.0
書き忘れそうでしたが、この方法を用いる場合は、/etc/sysconfig/network-scripts/ifcfg-ethX の HWADDR= は設定しないほうが良いです。設定した場合は、MAC のチェックが行われ、一致しなければ ifup が失敗します。

最後に、再起動します。設定内容によっては、立ち上げ時に、ethX の入れ替えを行ったことを示すメッセージが出力されます。
Aug  7 12:45:05 centos6 kernel: udev: renamed network interface eth0 to eth2
Aug  7 12:45:05 centos6 kernel: udev: renamed network interface eth1 to eth3
この環境では、NIC は 2本 (eth0, eth1) なのですが、ここで紹介した PCI アドレスによる固定化方法により、eth2 および eth3 に変更しています。

udev に関して、次の記事を一読されると理解が深まるものと思います。

参考URL:
http://gihyo.jp/dev/serial/01/sc-literacy/0015?page=1
http://donko.jp/LFS/LFS6.4jp/chapter07/network.html

2011-08-12追記
Fedora 15 では、biosdevname が使えるとか。参考メモ。
http://ja.community.dell.com/techcenter/b/weblog/archive/2011/08/03/fedora-15.aspx
2011-12-10追記、RHEL6.1 以降でもbiosdevnameが利用できるようです。DellマシンではデフォルトON、その他ベンダではデフォルトOFF。ブートパラメータとしてbiosdevname={0|1} を渡すことで切り替えも可能。HW が対応している必要があるので、事前に biosdevname コマンド(-i ethXX オプション)で名前解決可能かどうか確かめたほうがいいです。ただ、実際に試してみると、em1 や p1p1 みたいなインタフェース名って気色悪く感じました。あと、おそらく ethXX を決め打ちにしているアプリケーションがありそうなので、まだまだ業務サーバで利用はできないと思います。きっと普及までには5年ぐらいの歳月がかかるのではないかと思う。
なお、ブートパラメータとして指定する biosdevname=1 は、カーネルが解釈するわけではありません。Fedora 15 以降 または RHEL6.1 以降の環境で、/lib/udev/rules.d/71-biosdevname.rules を参照してください。この中から /proc/cmdline を読み取るという仕掛けのようです。/proc/cmdline を伝言板のように使うこの実装は醜いと思うんですがね。


2011-08-17追記
Fedora 15 で、上に書いた 65-eth.rules を使うと、ID= は将来の udev で廃止になるから使うなというようなメッセージが出るようです。
Aug 18 00:20:35 fedora15 udevd[358]: ID= will be removed in a future udev version, please use KERNEL= to match the event device, or KERNELS= to match a parent device, in /etc/udev/rules.d/65-eth.rules:2
そこで、別解です。次のルールであれば、Fedora 15 でも CentOS 6.0 でも使えるようです。
ACTION=="add", SUBSYSTEMS=="pci", KERNELS=="0000:02:01.0", DRIVERS=="?*", NAME="eth2", OPTIONS="last_rule"
ACTION=="add", SUBSYSTEMS=="pci", KERNELS=="0000:02:04.0", DRIVERS=="?*", NAME="eth3", OPTIONS="last_rule"
udev ルールに使える attribute は、次のようにして確認できます。
[root@centos6 ~]# udevadm info -a -p /sys/class/net/eth2

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth2':
    KERNEL=="eth2"
    SUBSYSTEM=="net"
    DRIVER==""
    ATTR{addr_assign_type}=="0"
    ATTR{addr_len}=="6"
    ATTR{dev_id}=="0x0"
    ATTR{ifalias}==""
    ATTR{iflink}=="2"
    ATTR{ifindex}=="2"
    ATTR{features}=="0x10ba9"
    ATTR{type}=="1"
    ATTR{link_mode}=="0"
    ATTR{address}=="00:0c:29:xx:xx:xx"
    ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
    ATTR{carrier}=="1"
    ATTR{speed}=="1000"
    ATTR{duplex}=="full"
    ATTR{dormant}=="0"
    ATTR{operstate}=="up"
    ATTR{mtu}=="1500"
    ATTR{flags}=="0x1003"
    ATTR{tx_queue_len}=="1000"

  looking at parent device '/devices/pci0000:00/0000:00:11.0/0000:02:01.0':
    KERNELS=="0000:02:01.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="e1000"
    ATTRS{vendor}=="0x8086"
    ATTRS{device}=="0x100f"
    ATTRS{subsystem_vendor}=="0x15ad"
    ATTRS{subsystem_device}=="0x0750"
    ATTRS{class}=="0x020000"
    ATTRS{irq}=="19"
    ATTRS{local_cpus}=="3"
    ATTRS{local_cpulist}=="0-1"
    ATTRS{modalias}=="pci:v00008086d0000100Fsv000015ADsd00000750bc02sc00i00"
    ATTRS{numa_node}=="-1"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

  looking at parent device '/devices/pci0000:00/0000:00:11.0':
    KERNELS=="0000:00:11.0"
    SUBSYSTEMS=="pci"
    DRIVERS==""
    ATTRS{vendor}=="0x15ad"
    ATTRS{device}=="0x0790"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{class}=="0x060401"
    ATTRS{irq}=="0"
    ATTRS{local_cpus}=="3"
    ATTRS{local_cpulist}=="0-1"
    ATTRS{modalias}=="pci:v000015ADd00000790sv00000000sd00000000bc06sc04i01"
    ATTRS{numa_node}=="-1"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}=="1"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

2015-01-16追記
RHEL7/CentOS7 の場合について、別の記事を書きました。

0 件のコメント:

コメントを投稿

人気ブログランキングへ にほんブログ村 IT技術ブログへ