LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (http://www.linuxquestions.org/questions/linux-networking-3/)
-   -   overriding /etc/udev/rules.d/70-persistent-net.rules (http://www.linuxquestions.org/questions/linux-networking-3/overriding-etc-udev-rules-d-70-persistent-net-rules-903234/)

Skaperen 09-15-2011 03:29 PM

overriding /etc/udev/rules.d/70-persistent-net.rules
 
I've tried replacing /etc/udev/rules.d/70-persistent-net.rules with my own rules that I believe should work for my situations. However, udev is replacing that file at times. It does not always do so, but sometimes it does.

I tried renaming my rules to another file name, and I remove the /etc/udev/rules.d/70-persistent-net.rules file. Sometimes nothing happens here and all works well. But sometimes udev generates /etc/udev/rules.d/70-persistent-net.rules (it's always the same wrong way each time). When both rules exist, the interfaces have the wrong names.

I want to do one of:

1. Get udev to stop generating its rules (that are wrong).
2. Get udev to generate correct rules.
3. Make my rules always override the generated rules.

My rules match interfaces based on bus device address, not ethernet MAC address. Here's a little script I wrote to generate what I believe are better rules than udev generates:
Code:

#!/bin/bash

# Generate udev rules to order interfaces in the same order as their bus addresses.

if ! test -d /sys/devices ; then
    echo "${0}: ERROR: /sys appears to not be mounted" 1>&2
    exit 1
fi

scansys() {
    find /sys/devices -type d -wholename '/sys/devices/pci*/net' -print
}

extract() {
    awk -F/ '{printf "%s eth%u\n",$(NF-1),NR-1;}'
}

generate() {
    echo '# these rules are for persistence based on bus device address'
    awk '{printf "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNELS==\"%s\", KERNEL==\"eth*\", NAME=\"%s\"\n",$1,$2;}'
}

scansys | extract | sort | generate

This just outputs the generated rules to stdout, if you want to try it and see what it does.

ccolumbu 09-15-2011 05:33 PM

You want ifrename (redhat OS based answer)
 
You want to install the wireless-tools package via yum (which provides ifrename) if you don't already have it, as well as ethtool for testing.
Code:

yum install wireless-tools ethtool
Then create an /etc/init.d script for ifrename and an /etc/iftab config file (see below).

Once you have the script and the iftab you can test it, if you are at the console. Do not try this remotely!
First blink the nic so you know it is not what you want (it should make the link like blink at a steady rate. It helps if the NIC is not plugged in):
Code:

ethtool -p eth0
Now run this:
Code:

/etc/init.d/network stop
/etc/init.d/ifrename restart
/etc/init.d/network start

Then test again, and the cards should have changed assignments:
Code:

ethtool -p eth0
Once that works simply add ifrename to your startup:
Code:

chkconfig ifrename on
/etc/iftab example:
Code:

eth0 mac <mac of the NIC you want as eth0 like: ##:##:##:##:##:##>
eth1 mac <mac of the NIC you want as eth1 like: ##:##:##:##:##:##>
. . .
ethN mac <mac of the NIC you want as ethN like: ##:##:##:##:##:##>

Here is an ifrename init.d script:
Code:

#!/bin/sh
#
# chkconfig: 2345 09 60
# description: /sbin/ifrename
# processname: ifrename
#

# Source function library.
. /etc/rc.d/init.d/functions

[ -x /sbin/ifrename ] || exit 0

# Define where ifrename is installed.
DAEMON="/sbin/ifrename"
OPTIONS="-t"

RETVAL=0

start() {
        if status $DAEMON > /dev/null; then
                echo -n $"$DAEMON: already running "
                failure
                echo
                return 1
        fi

        # Start daemons.
        echo -n $"Starting ifrename: "
        daemon $DAEMON $OPTIONS
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ifrename
        echo
        return $RETVAL
}

stop() {
        # Stop daemons.
        echo -n $"Shutting down ifrename: "
        echo OK
        return 0
}

restart() {
        stop
        sleep 1
        start
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  status)
        status ifrename
        ;;
  *)
        echo "Usage: /etc/init.d/ifrename {start|stop|restart|status}"
        exit 1
esac

exit $?


Skaperen 09-16-2011 02:29 PM

The example given shows only doing it by MAC address. How can I do this with your example, but by BUS address?

Note that I do NOT want a specific address to interface name mapping. Instead, I want the interfaces sorted by BUS address to be named sequentially (e.g. eth0 for the lowest BUS address, eth1 for the next lowest BUS address, and so on).

Woodsman 09-16-2011 02:53 PM

Would renaming your rule set to 99-persistent-net.rules help? Your rule set would run after udev checks/resets 70-persistent-net.rules.

ccolumbu 09-16-2011 11:21 PM

Ifrename has a bunch of options, read this for non-mac specific solutions:
http://linux.die.net/man/5/iftab

Skaperen 09-17-2011 08:15 PM

Quote:

Originally Posted by ccolumbu (Post 4474139)
Ifrename has a bunch of options, read this for non-mac specific solutions:
http://linux.die.net/man/5/iftab

Sure, ifrename could do the renaming once. But it doesn't have an automatic means to juggle conflicting names. That is, if you need to rename eth1 to eth0, and eth0 to eth1, there is a conflict. I've tried that with ifrename and it didn't change anything. It only reported the first conflict. Somehow, udev, if it needs to switch, automatically handles it. I presume it renames one of the interfaces first to a temporary name, then renames as needed to get the interfaces back in line.

Also, if udev is running, ifrename and udev can interfere with each other. And I do need to run udev. I just need to find out how to make udev not mangle the files I make.

ccolumbu 09-18-2011 12:25 AM

if you give ifrename the -t flag it can handle conflicts, I run both right now on multiple servers. and regularly rename eth0 -> eth1, then eth1 -> eth0.
Read the page I set you it tells you how to do everything you asked.

Skaperen 09-19-2011 11:14 AM

Quote:

Originally Posted by ccolumbu (Post 4474920)
if you give ifrename the -t flag it can handle conflicts, I run both right now on multiple servers. and regularly rename eth0 -> eth1, then eth1 -> eth0.
Read the page I set you it tells you how to do everything you asked.

There is still interference from udev. It changes things around afterwards. So the only solution I see is to do it through udev. When I give udev a ruleset to do this, but named different than the default ruleset it generates, it doesn't seem to use this ruleset at all, but it does not delete it. When I give that ruleset the same name as what udev would generate with MAC addresses, it USUALLY does not replace it, but SOMETIMES it does. I have not worked out the situation where it does replace it. But I suspect it might be a situation where the kernel named the interfaces differently because of the random probe responses coming in differently.

ccolumbu 09-19-2011 11:15 PM

Is it reporting it 1 way in ifconfig, but correctly when yo use ethtool -p ethX?
This is a problem I have reported on the CentOS bug tracker.

Test to see if ethX is the card you expect by running ethtool -p ethX and looking to see which one blinks.

I don't know anything about udev, so I can't be of additional help.
Sorry.

Skaperen 09-20-2011 10:32 AM

Quote:

Originally Posted by ccolumbu (Post 4476749)
Is it reporting it 1 way in ifconfig, but correctly when yo use ethtool -p ethX?
This is a problem I have reported on the CentOS bug tracker.

Test to see if ethX is the card you expect by running ethtool -p ethX and looking to see which one blinks.

I don't know anything about udev, so I can't be of additional help.
Sorry.

I have already tested that the cards go where expected when individually bringing them up and down. The only issue is that udev re-arranges the interface names.

Before I ever did anything, it would lock in MAC addresses to names, and store a rules file to do that. But binding name to MAC is wrong for what I'm doing for two reasons. We do move systems that reside on hard drives from one machine to another at times. We also change NIC cards at times. That's when udev fouls up the network arrangement. While in the local data room, we could get on the console and fix the udev rules, this is not so easy for remote machines where staff are less technically inclined. At first, I corrected this by putting in a set of rules for all ethernets that precluded any renaming by udev. But this disables the ability to correct for kernel probe order errors. So it merely improved the situation, but did not correct it.

My latest change to bind interface naming order to bus address order appears to add more improvement. Most of the time udev accepts the rules my script generates and the interface names come up in the expected order. But rarely, maybe about 1 in 80 times booting, udev ignores the rules my script generates, and substitutes them with its own, just as if the rules were not there. I verified the rules were there by running my script, which also lists the new file it makes, right before udev starts, in the script that starts udev itself. But I see no log messages about udev deciding the rules were to be replaced. It just silently replaces them in these rare cases.

FYI, I was running a test by rebooting a test machine every 72 seconds. A script that was doing the reboot via ssh would do this about 80 to 100 times just fine, then suddenly it cannot connect because the target machine's . Checking the console of the test target showed that the kernel did have the interfaces out of order, my script did run and generate rules, udev did not follow those rules, and replaced the rules with its own, being the same as if there had been no rules at all. I cannot rule out a system error in the filesystem that caused the rules to not be present for udev. I did add a sync command in the init script right before it lists the generated rules file. I'm considering running udev entirely under strace to keep a log of all system calls it does. I hope strace doesn't break it.

Magnusg 05-23-2012 03:57 PM

Skaperen, thanks for the script. It was really helpful to me.

Keep in mind, /etc/udev/rules.d/70-persistent-net.rules on RHEL6 and others is updated by /lib/udev/write_net_rules.

I used your script to replace write_net_rules, worked like a charm and make sure that 70-persistent-net.rules becomes more stable.
Keep in mind, /lib/udev/write_net_rules is owned by the udev RPM on RHEL6, so updating it would require you to reapply your changed write_net_rules.
I did this by putting your script in a RHN Satellite configuration channel.

This is described more in detail here: http://blog.hacka.net/#post64

Again, thanks Skaperen.

z_haseeb 03-06-2014 09:24 PM

@ Skaperen

CURRENTLY i AM FACING THE SAME PROBLEM. mAY THIS RESOLVE YOUR PROBLEM.
1.) create a copy of , /etc/udev/rules.d/70-persistent-net.rules to some where.
2.) run rm -rf , /etc/udev/rules.d/70-persistent-net.rules under rc.local
3.) cp /WHERE-YOU-COPIED-THE-FILE /etc/udev/rules.d/70-persistent-net.rules


(correct me if I am wrong)


All times are GMT -5. The time now is 05:18 AM.