Problem with udev and ethX naming in latest Fedora 19.

Ben Greear greearb at candelatech.com
Thu Aug 15 17:42:03 UTC 2013


On 08/15/2013 08:14 AM, Reindl Harald wrote:
>
>
> Am 15.08.2013 16:53, schrieb Ben Greear:
>> On 08/15/2013 07:18 AM, Reindl Harald wrote:
>>>
>>>
>>> Am 15.08.2013 16:05, schrieb Ben Greear:
>>>>> with 4 NIC's this was never predictable and mostly luck
>>>>> the only stupid thing is that this this new crap names also appear
>>>>> if there is only one NIC or at least only identical ones with
>>>>> the same driver what makes race-conditions unlikely
>>>>
>>>> I understand why the names come up jumbled on bootup, but there is no excuse
>>>> for udev not being able to properly rename them as requested
>>>
>>> ask Kay Sievers , he is able to explain it to you too
>>>
>>> in short:
>>> the kernel may also rename the devices as they come up
>>> if kernel want make one nic to eth1 and udev at the same time another one -> collision
>>
>> That's fine.  Udev can just detect the collision and try again, potentially
>> moving the other one to a new name.  That is what it has done for years,
>> in between bugs that caused eth0.rename devices to be left lying around.
>
> well complain at the udev/systemd-guys and the ones before who came up with "biosdevname"
> you know that, i know that, you asked, i gave you an answer
> more can hardly do a *user* in this case
>

I opened a bug against udev..will see if it gets any response.

In the meantime, here is a perl script that will rename.  I wasn't sure the
limitations of other rename tools, but perhaps they would have worked fine.

You would use it like this:

lf_ifrename.pl eth0 00:30:48:fc:17:a2
lf_ifrename.pl eth1 00:30:48:fc:17:a3
lf_ifrename.pl eth2 00:e0:ed:1c:ec:e4
lf_ifrename.pl eth3 00:e0:ed:1c:ec:e5


It *should* deal with races and device name conflicts.

Someday I'll make this parse the udev 70-persistent-net.rules file (if it
exists) and use that instead of having to specify the MAC on the command line.

That should kludge around the current udev limitations while being backwards
compat with working udev, and still keeping the configuration all in one
place.


#!/usr/bin/perl

use strict;

my $ignore_err = 1;

my $dev = $ARGV[0];
my $mac = $ARGV[1];

if ((length($mac) == 0) || (length($dev) == 0)) {
   print "USAGE: lf_ifrename.pl [dev] [mac]\n";
   print "MAC: $mac  DEV: $dev\n";
   exit 0;
}

my $emac = `cat /sys/class/net/$dev/address`;
chomp($emac);

if ($emac eq $mac) {
   print("rename: Device $dev is already configured properly, mac: $emac\n");
   exit 0;
}

my $rdev = "";
# Find existing dev with this MAC.
my @lns = `ls /sys/class/net/*/address`;
my $i;
for ($i = 0; $i<@lns; $i++) {
   my $ln = $lns[$i];
   chomp($ln);
   my $addr = `cat $ln`;
   chomp($addr);
   if ($addr =~ /$mac/i) {
     $ln =~ /\/sys\/class\/net\/(\S+)\/address/;
     $rdev = $1;
   }
}

if ($rdev eq "") {
   print "ERROR:  rename: Could not find network device with address: $mac\n";
   exit 1;
}

# Try 10 times, this works around possible races with new devices
# being created..though that should not happen in most cases.
my $mx = 10;
for ($i = 0; $i<$mx; $i++) {
   if (-e "/sys/class/net/$dev/address") {
     # Need to change it, first admin down
     print "Attempting rename of device: $dev to $dev.r\n";
     do_cmd("ifdown $dev > /dev/null 2>&1", 1);
     do_cmd("ip link set dev $dev down > /dev/null 2>&1", 1); # Just to be sure
     do_cmd("ip link set dev $dev name $dev.r > /dev/null 2>&1", 1);
   }

   # And now rename target device.
   print "Attempting rename of device: $rdev to $dev\n";
   do_cmd("ifdown $rdev > /dev/null 2>&1", 1);
   do_cmd("ip link set dev $rdev down > /dev/null 2>&1", 1); # Just to be sure
   do_cmd("ip link set dev $rdev name $dev > /dev/null 2>&1", 1);

   # Bring up newly renamed device
   do_cmd("ifup $dev > /dev/null 2>&1", 1);

   # And switch names in case if we had to rename a target
   # temporarily.
   if (-e "/sys/class/net/$dev.r/address") {
     print "Attempting rename of device: $dev.r to $rdev.\n";
     do_cmd("ifdown $dev.r > /dev/null 2>&1", 1);
     do_cmd("ip link set dev $dev.r down > /dev/null 2>&1", 1); # Just to be sure
     do_cmd("ip link set dev $dev.r name $rdev > /dev/null 2>&1", 1);

     # Bring up newly renamed device
     do_cmd("ifup $rdev > /dev/null 2>&1", 1);
   }

   # Check everything worked...exit peacefully if so.
   my $cmac = `cat /sys/class/net/$dev/address`;
   chomp($cmac);

   if ($cmac eq $mac) {
     print("Completed rename of device:  Dev: $dev mac: $mac\n");
     exit 0;
   }
   print("Failed to properly rename device, will try again.\n");
}

print("ERROR:  Failed to properly rename device, giving up!\n");
exit 1;


sub do_cmd {
   my $err = 1;
   my $cmd = shift;
   my $ok_to_fail = shift;
   print("$cmd\n");
   $err = system("$cmd");
   if ($err != 0) {
     if (!($ok_to_fail || $ignore_err)) {
       note("\n\n# FATAL:  Command failed, lf_ifrename.pl script is aborting!!\n");
       die("$cmd  $!\n\n");
     }
     else {
       print "# WARNING:  Command failed, not fatal: $cmd\n";
     }
   }
   return $err
}


-- 
Ben Greear <greearb at candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



More information about the users mailing list