diff options
author | Kay Sievers <kay.sievers@suse.de> | 2006-07-03 00:58:35 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@suse.de> | 2006-07-03 00:58:35 +0200 |
commit | b879c303a787e9430a5234aff3c1185ff9a4b019 (patch) | |
tree | 861be9834e22a35e8b14f8a77d810e149272af95 | |
parent | e0595b53b5ea6cb922fc17ecdbbf4188319c55d0 (diff) |
netif rename: optimistic loop for the name to become free
Parts from Ubuntu's 70-ifrename.patch.
-rw-r--r-- | extras/volume_id/lib/reiserfs.c | 2 | ||||
-rw-r--r-- | udev_device.c | 44 | ||||
-rw-r--r-- | udevd.h | 2 |
3 files changed, 40 insertions, 8 deletions
diff --git a/extras/volume_id/lib/reiserfs.c b/extras/volume_id/lib/reiserfs.c index abeb06b88f..770f726825 100644 --- a/extras/volume_id/lib/reiserfs.c +++ b/extras/volume_id/lib/reiserfs.c @@ -66,7 +66,7 @@ int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off) if (buf == NULL) return -1; - rs = (struct reiserfs_super_block *) buf;; + rs = (struct reiserfs_super_block *) buf; if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { strcpy(id->type_version, "3.5"); id->type = "reiserfs"; diff --git a/udev_device.c b/udev_device.c index ab4965c3a1..3c4ac913ed 100644 --- a/udev_device.c +++ b/udev_device.c @@ -81,7 +81,7 @@ dev_t udev_device_get_devt(struct udevice *udev) return makedev(0, 0); } -static int rename_net_if(struct udevice *udev) +static int rename_netif(struct udevice *udev) { int sk; struct ifreq ifr; @@ -100,12 +100,44 @@ static int rename_net_if(struct udevice *udev) memset(&ifr, 0x00, sizeof(struct ifreq)); strlcpy(ifr.ifr_name, udev->dev->kernel_name, IFNAMSIZ); strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); - retval = ioctl(sk, SIOCSIFNAME, &ifr); - if (retval != 0) - err("error changing net interface name: %s", strerror(errno)); - close(sk); + if (retval != 0) { + int loop; + + /* see if the destination interface name already exists */ + if (errno != EEXIST) { + err("error changing netif name: %s", strerror(errno)); + goto exit; + } + + /* free our own name, another process may wait for us */ + strlcpy(ifr.ifr_newname, udev->dev->kernel_name, IFNAMSIZ); + strlcat(ifr.ifr_newname, "_rename", IFNAMSIZ); + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval != 0) { + err("error changing netif name: %s", strerror(errno)); + goto exit; + } + /* wait 30 seconds for our target to become available */ + strlcpy(ifr.ifr_name, ifr.ifr_newname, IFNAMSIZ); + strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); + loop = 30 * 20; + while (loop--) { + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval != 0) { + if (errno != EEXIST) { + err("error changing net interface name: %s", strerror(errno)); + break; + } + dbg("wait for netif '%s' to become free, loop=%i", udev->name, (30 * 20) - loop); + usleep(1000 * 1000 / 20); + } + } + } + +exit: + close(sk); return retval; } @@ -181,7 +213,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) if (strcmp(udev->name, udev->dev->kernel_name) != 0) { char *pos; - retval = rename_net_if(udev); + retval = rename_netif(udev); if (retval != 0) goto exit; info("renamed netif to '%s'", udev->name); @@ -32,7 +32,7 @@ #define EVENT_SEQNUM ".udev/uevent_seqnum" /* maximum limit of forked childs */ -#define UDEVD_MAX_CHILDS 64 +#define UDEVD_MAX_CHILDS 256 /* start to throttle forking if maximum number of running childs in our session is reached */ #define UDEVD_MAX_CHILDS_RUNNING 16 |