Why Does My Linux VM's Virtual NIC Show Up As eth1?

Got a Red Hat Enterprise Linux (or CentOS, or Scientific Linux, or Oracle Enterprise Linux, etc.) 6 VM that won’t bring up it’s single network interface after you clone it?

Get the following error when you try using /sbin/ifup to enable it?

"Device eth0 does not seem to be present, delaying initialization."

When you use “/sbin/ifconfig -a” you see eth1 where eth0 should be?

eth1      Link encap:Ethernet  HWaddr 00:50:56:9B:00:85  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:812 errors:0 dropped:0 overruns:0 frame:0
          TX packets:214 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:72509 (70.8 KiB)  TX bytes:28324 (27.6 KiB)
lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

What the heck?

It’s the udev persistent network interface rules. If you delete /etc/udev/rules.d/70-persistent-net.rules it’ll rebuild them during the next boot, based on the current state of the host, and you’ll get eth0 back. You can also edit it to change the list of MAC addresses.

There are a couple of ways to disable this functionality permanently.

1. You can remove /lib/udev/rules.d/75-persistent-net-generator.rules. The problem with this approach is that when there’s an update to udev it’ll likely replace the file again and recreate the problem.

2. You could make it part of your machine cloning process, or template prep. All that does is set yourself up for potential problems later, though. Like when you’re on vacation and the new guy clones an already-running VM. Or you do, and you’ve forgotten about this problem… :)

3. You could hijack the rule in /lib/udev/rules.d/75-persistent-net-generator.rules that creates this stuff:

KERNEL!="eth*|ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end"

Invert the logic by changing the “!=” to a “==” so it always skips eth* (and everything else in the list):

KERNEL=="eth*|ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end"

You could also remove just eth* from the list if you still wanted to preserve the behavior for other interfaces:

KERNEL!="ath*|wlan*[0-9]|msh*|ra*|sta*|ctc*|lcs*|hsi*", GOTO="persistent_net_generator_end"

This is what I’m doing. I’m hoping that Red Hat does the right thing during a patch by recognizing that the file is changed and not overwriting it.

Update: Read the comments. Lars left a good one, set the 70-persistent-net.rules file to immutable. Also, he reminded me that RPM will tell you what files are config files, if you ask it. :) Thanks man.

Comments on this entry are closed.

  • The same applies to Debian/Ubuntu variants, except that the udev rules are in /etc/udev/rules.d/70-persistent-net.rules

    Cheers,
    Jake

  • If the rpm that installs this file is well-behaved and has these files labeled as config files, upon update it will place the new, incoming config file as /lib/udev/rules.d/75-persistent-net-generator.rules.rpmnew and not overwrite changes you have made.

    If you delete the file, however, it will just install the new one in place and you will have the same error again.

    • …and I just tested it, and the .rpmnew file does not appear to get read by udev, so the behavior stays as I left it. Cool.

      Red Hat, at times, has deviated from the .rpmnew standard, but that’s usually a bug in their packaging. Lately they’ve been good about it, but assumptions are no substitute for testing.

  • That’s part of the logic to keep network interface names stable even as interfaces are added or removed. The cloned machine has a new network interface with new MAC address so treats it as a different network interface than its existing config. I thought the VMware agent would fix this on initial boot by editing ifcfg-eth0 so that the new MAC was associated with an IP you could specify during the clone process, is there some other config that VMware tools isn’t updating or are we not using the agent to assign an IP address on the machine when cloning?

    • In many cases people choose not to customize the OS via vCenter during the cloning process, and this issue would bite them in the duff. Depends on why they’re cloning. That was the case for me when I found this problem.

      There’s a lot of new logic to stabilize the device names under RHEL 6 and I’m not really sure if I like it yet or not, personally. I’ve never had issues with detection order or interface reassignment, mostly because most of my VMs have a single vNIC. These new features just get in the way for me.

  • I have seen this issue with VMware Server 2.x, using Ubuntu/Debian VM’s. Removing and re-adding the NIC doesn’t resolve this either, as suggested in some forums.
    Thanks for the info, Bob!

  • The RedHat/Centos udev package — at least for CentOS 6 — does not label the files in /lib/udev as config files. There are only three files so labelled in the package:

    # rpm -q –configfiles udev
    /etc/scsi_id.cfg
    /etc/sysconfig/udev
    /etc/udev/udev.conf

    These are the only files that will get handled specially when installing a new package. The actual mechanism looks like this:

    – If a configuration file was not changed by the system administrator, rpm will install the new version of the appropriate file. No action by the system administrator is required.

    – If a configuration file was changed by the system administrator before the update, rpm saves the changed file with the extension .rpmorig or .rpmsave (backup file) and installs the version from the new package, but only if the originally installed file and the newer version are different.

    – .rpmnew files appear if the configuration file already exists and if the noreplace label was specified in the .spec file.

    Any other files will simply be replaced by the version in the updated package…which means that changes to /lib/udev/rules.d/75-persistent-generator.rules will be lost. In fact, if you examine this file, the very first comment says:

    # do not edit this file, it will be overwritten on update

    A more permanent solution is to set the “immutable” bit on /etc/udev/rules.d/70-persistent-net.rules:

    chattr +i /etc/udev/rules.d/70-persistent-net.rules

    This will prevent udev from writing to the file, which effectively disables this mechanism in a fashion that will persist across updates.

    • I swear, half the reason I blog is because some guy like you will come along and drop some knowledge on my ass. Awesome. I’d forgotten about immutable (more like purged it from memory, it’s caused me problems before). Good fix here, though.

      Thank you!

  • Only to say that, for unexperienced users, the correct command meant is
    chattr +i /etc/udev/rules.d/70-persistent-net.rules
    and not
    chmod +i /etc/udev/rules.d/70-persistent-net.rules

    • Thanks — I edited his comment to correct it.

  • Another little note that may prove useful to those who only have half a clue (like me!) Just making the change mentioned here won’t necessarily solve the problem, as eth0 may still be tied to a specific MAC. Edit /etc/sysconfig/network-scripts/ifcfg-eth0 and comment out or delete the HWADDR line to remove that link, and eth0 should then work regardless of what MAC a particular copy/clone of the VM ends up with.

  • I have seen this issue with RHEL 6.2 on Hyper-V(Windows Server 2008 R2)
    Thanks to your posts have solved my problem.

  • Just wanted to say thanks for this post; saved me lots of hair pulling.