diff options
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/udev/udev-event.c | 72 |
2 files changed, 76 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 0ecd158329..68dd9df50c 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,10 @@ AC_ARG_ENABLE([rule-generator], AS_HELP_STRING([--enable-rule-generator], [enable legacy persistent network, cdrom support]), [], [enable_rule_generator=no]) +if test "x${enable_rule_generator}" != xno; then + AC_DEFINE([ENABLE_RULE_GENERATOR], [1], [Define if we are enabling rule generator]) +fi + AM_CONDITIONAL([ENABLE_RULE_GENERATOR], [test "x$enable_rule_generator" = xyes]) # ------------------------------------------------------------------------------ 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; } |