05 December 2011

NIC Replacement in Linux

In the past, I've found it slightly annoying that if I needed to swap
out a network interface card (NIC), Red Hat distros of Linux would kindly
backup the interface configuration for that interface and generate a stub
DHCP configuration in its place.  This leaves the host potentially with
an improper network configuration.  The following details the necessary
changes on the OS so that the new NIC will be appropriately identified
and configured.  (Of note, the details below will not likely work with
RHEL 6+, which removes the need for 'kudzu', though it should work fine
on on earlier RHEL distros.)  Our host details:
        HOST:                   humboldt
        PROMPT:                 sh-3.2#
        OS:                     CentOS 5.6 Linux
        eth1 OLD DRIVER:        e1000
        eth1 OLD MAC / HW Addr: 08:00:27:57:A6:AE
        eth1 NEW DRIVER:        pcnet32
        eth1 OLD MAC / HW Addr: 08:00:27:47:51:21
To exemplify our situation, I've cloned a CentOS VM instance and simply
swapped the network interface type for "eth1", changing it from an Intel
GigE interface (e1000) to an AMD 79c970 interface (pcnet32).  The MAC /
HWaddr is also updated as a result.  After the switch, the first thing
to do is boot the host to single user.  Select the appropriate boot
entry from GRUB and before the 5 seconds timeout, hit 'e' so that we
can update the kernel boot parameters:
         GNU GRUB  version 0.97  (639K lower / 1047488K upper memory)

        CentOS 5.6 (2.6.18 238.el5)               <==================


           Use the <up> and <down> keys to select which entry is highlighted.
           Press enter to boot the selected OS, 'e' to edit the
           commands before booting, 'a' to modify the kernel arguments
           before booting, or 'c' for a command-line.

        The highlighted entry will be booted automatically in 5 seconds.
The following screen will be presented:
         GNU GRUB  version 0.97  (639K lower / 1047488K upper memory)

        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-238.el5 ro root=LABEL=/
        initrd /boot/initrd-2.6.18-238.el5.img

           Use the <up> and <down> keys to select which entry is highlighted.
           Press 'b' to boot, 'e' to edit the selected command in the
           boot sequence, 'c' for a command-line, 'o' to open a new line
           after ('O' for before) the selected line, 'd' to remove the
           selected line, or escape to go back to the main menu.
Update the "kernel" entry from this:
                kernel /boot/vmlinuz-2.6.18-238.el5 ro root=LABEL=/
to this:
                kernel /boot/vmlinuz-2.6.18-238.el5 ro root=LABEL=/ -s
Hit 'enter' then hit 'b' to boot the host to single user.  The screen
will clear and the boot process will begin:
        root (hd0,0)
         Filesystem type is ext2fs, partition type 0x83
        kernel /boot/vmlinuz-2.6.18-238.el5 ro root=LABEL=/
           [Linux-bzImage, setup=0x1e00, size=0x1fd63c]
        initrd /boot/initrd-2.6.18-238.el5.img
           [Linux-initrd @ 0x37d60000, 0x28f833 bytes]
        <snip...>
        Mounting local filesystems:                               [  OK  ]
        Enabling local filesystem quotas:                         [  OK  ]
        Enabling /etc/fstab swaps:                                [  OK  ]
        sh-3.2#
Once at the shell prompt, we run 'kudzu', telling it to probe only the
network class but not to make any updates:
        sh-3.2# /sbin/kudzu -c network -p | /bin/grep -A3 eth
        device: eth0
        driver: e1000
        desc: "Intel Corporation 82540EM Gigabit Ethernet Controller"
        network.hwaddr: 08:00:27:76:96:81
        --
        device: eth1
        driver: pcnet32
        desc: "Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]"
        network.hwaddr: 08:00:27:47:51:21
A quick check of "hwconf" shows us the original driver, description,
and HWaddr for "eth1" which need to be updated:
        sh-3.2# /bin/grep -A3 eth /etc/sysconfig/hwconf
        device: eth0
        driver: e1000
        desc: "Intel Corporation 82540EM Gigabit Ethernet Controller"
        network.hwaddr: 08:00:27:76:96:81
        --
        device: eth1
        driver: e1000
        desc: "Intel Corporation 82540EM Gigabit Ethernet Controller"
        network.hwaddr: 08:00:27:57:a6:ae
Since "hwconf" is where 'kudzu' stores information about the system's
hardware, we'll need to update the entry for "eth1" so that it reflects
the output from our previous 'kudzu' run listed above:
        sh-3.2# /bin/vi /etc/sysconfig/hwconf
        <snip...>
        sh-3.2# /bin/grep -A3 eth /etc/sysconfig/hwconf
        device: eth0
        driver: e1000
        desc: "Intel Corporation 82540EM Gigabit Ethernet Controller"
        network.hwaddr: 08:00:27:76:96:81
        --
        device: eth1
        driver: pcnet32
        desc: "Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]"
        network.hwaddr: 08:00:27:47:51:21
After updating "hwconf", we now need to update the "HWADDR" variable in
"ifcfg-eth1":
        sh-3.2# /bin/vi /etc/sysconfig/network-scripts/ifcfg-eth1
        <snip...>
        sh-3.2# /bin/egrep -h 'DEVICE|HWADDR' /etc/sysconfig/network-scripts/ifcfg-eth1
        DEVICE=eth1
        HWADDR=08:00:27:47:51:21
Now that both files have been updated, exit out of shell which will
automatically start booting the host to the default runlevel (rl),
in this case, rl 3:
        sh-3.2# exit
        logout
        INIT: Entering runlevel: 3
        Entering non-interactive startup                          [  OK  ]
        Starting background readahead:                            [  OK  ]
        Checking for hardware changes                             [  OK  ]
        Bringing up loopback interface:                           [  OK  ]
        Bringing up interface eth1:                               [  OK  ]
        <snip...>
        #screen clears to console login:

        CentOS release 5.6 (Final)
        Kernel 2.6.18-238.el5 on an x86_64

        humboldt login: _
Our work is now complete and our network interfaces should function as
they did prior to the NIC change.  Since the configuration details within
"hwconf" and "ifcfg-eth1" match each other, "eth1" will be configured
as we expect and intend rather than its config file being moved to
"ifcfg-eth1.bak".

2 comments:

Anonymous said...

Any experience doing this on NICs that had their ports bonded?

troy said...

Anonymous,

While I don't recall doing so, I wouldn't think it would be any different on the server side. I expect the bonding configuration would be unaffected and you would simply need to update the details for the underlying physical interfaces similarly to what I've done for "eth1" in this post.

--troy