diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2013-04-07 22:19:54 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2013-04-07 22:19:54 -0400 |
commit | df016d6d7abe5b0f8e102d34527d6434f0bec924 (patch) | |
tree | f331356ca3e6c1ecf6d9e1c8a943db94e9c36712 /src/udev/udev-event.c | |
parent | f8209e1f4408278a46b4673044da60082a68997e (diff) |
src/udev/udev-event.c: restore code to allow rule generator to work
This code was dropped while importing from upstream. It is needed
to allow the legacy renaming of interfaces like eth* or wlan*.
X-Eudev-Bug: 56
X-Eudev-Bug-URL: https://github.com/gentoo/eudev/issues/56
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src/udev/udev-event.c')
-rw-r--r-- | src/udev/udev-event.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index d1880efe50..c6c5940ff6 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -752,6 +752,28 @@ out: return err; } +#ifdef ENABLE_RULE_GENERATOR +static void rename_netif_kernel_log(struct ifreq ifr) +{ + int klog; + FILE *f; + + klog = open("/dev/kmsg", O_WRONLY|O_CLOEXEC); + if (klog < 0) + return; + + f = fdopen(klog, "w"); + if (f == NULL) { + close(klog); + return; + } + + fprintf(f, "<30>udevd[%u]: renamed network interface %s to %s\n", + getpid(), ifr.ifr_name, ifr.ifr_newname); + fclose(f); +} +#endif + static int rename_netif(struct udev_event *event) { struct udev_device *dev = event->dev; @@ -773,12 +795,62 @@ static int rename_netif(struct udev_event *event) util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev)); util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name); err = ioctl(sk, SIOCSIFNAME, &ifr); + +#ifdef ENABLE_RULE_GENERATOR + int loop; + + if (err == 0) { + rename_netif_kernel_log(ifr); + goto out; + } + + /* keep trying if the destination interface name already exists */ + err = -errno; + if (err != -EEXIST) + goto out; + + /* free our own name, another process may wait for us */ + snprintf(ifr.ifr_newname, IFNAMSIZ, "rename%u", udev_device_get_ifindex(dev)); + err = ioctl(sk, SIOCSIFNAME, &ifr); + if (err < 0) { + err = -errno; + goto out; + } + + /* log temporary name */ + rename_netif_kernel_log(ifr); + + /* wait a maximum of 90 seconds for our target to become available */ + util_strscpy(ifr.ifr_name, IFNAMSIZ, ifr.ifr_newname); + util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name); + loop = 90 * 20; + while (loop--) { + const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 }; + + nanosleep(&duration, NULL); + + err = ioctl(sk, SIOCSIFNAME, &ifr); + if (err == 0) { + rename_netif_kernel_log(ifr); + break; + } + err = -errno; + if (err != -EEXIST) + break; + } + +out: + if (err < 0) + log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname); +#else if (err >= 0) { print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); } else { err = -errno; log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname); } +#endif + close(sk); return err; } |