[systemd-commits] 2 commits - src/libsystemd src/udev

Tom Gundersen tomegun at kemper.freedesktop.org
Tue Sep 9 13:42:02 PDT 2014


 src/libsystemd/sd-rtnl/rtnl-util.c |   38 ++++++++++++++++++-----------------
 src/libsystemd/sd-rtnl/rtnl-util.h |    4 +--
 src/udev/net/ethtool-util.c        |   40 +++++++++++++++++++++++++++++--------
 src/udev/net/ethtool-util.h        |    6 ++---
 src/udev/net/link-config.c         |   40 +++----------------------------------
 src/udev/udev-event.c              |   23 +++++++--------------
 src/udev/udev.h                    |    2 +
 src/udev/udevd.c                   |    8 +++++++
 8 files changed, 79 insertions(+), 82 deletions(-)

New commits:
commit aedca89268ed4fd6be41e55a605f011033ad1fb5
Author: Tom Gundersen <teg at jklm.no>
Date:   Tue Sep 9 15:36:56 2014 +0200

    udev: net_setup_link - open ethtool and rtnl connections lazily

diff --git a/src/libsystemd/sd-rtnl/rtnl-util.c b/src/libsystemd/sd-rtnl/rtnl-util.c
index fe0f34e..1ec1fa8 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.c
+++ b/src/libsystemd/sd-rtnl/rtnl-util.c
@@ -55,10 +55,9 @@ int rtnl_set_link_name(sd_rtnl **rtnl, int ifindex, const char *name) {
         return 0;
 }
 
-int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
+int rtnl_set_link_properties(sd_rtnl **rtnl, int ifindex, const char *alias,
                              const struct ether_addr *mac, unsigned mtu) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *message = NULL;
-        bool need_update = false;
         int r;
 
         assert(rtnl);
@@ -67,7 +66,13 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
         if (!alias && !mac && mtu == 0)
                 return 0;
 
-        r = sd_rtnl_message_new_link(rtnl, &message, RTM_SETLINK, ifindex);
+        if (!*rtnl) {
+                r = sd_rtnl_open(rtnl, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
         if (r < 0)
                 return r;
 
@@ -75,32 +80,23 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
                 r = sd_rtnl_message_append_string(message, IFLA_IFALIAS, alias);
                 if (r < 0)
                         return r;
-
-                need_update = true;
-
         }
 
         if (mac) {
                 r = sd_rtnl_message_append_ether_addr(message, IFLA_ADDRESS, mac);
                 if (r < 0)
                         return r;
-
-                need_update = true;
         }
 
         if (mtu > 0) {
                 r = sd_rtnl_message_append_u32(message, IFLA_MTU, mtu);
                 if (r < 0)
                         return r;
-
-                need_update = true;
         }
 
-        if  (need_update) {
-                r = sd_rtnl_call(rtnl, message, 0, NULL);
-                if (r < 0)
-                        return r;
-        }
+        r = sd_rtnl_call(*rtnl, message, 0, NULL);
+        if (r < 0)
+                return r;
 
         return 0;
 }
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.h b/src/libsystemd/sd-rtnl/rtnl-util.h
index 94af3b1..fa3592d 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.h
+++ b/src/libsystemd/sd-rtnl/rtnl-util.h
@@ -35,7 +35,7 @@ bool rtnl_message_type_is_addr(uint16_t type);
 bool rtnl_message_type_is_route(uint16_t type);
 
 int rtnl_set_link_name(sd_rtnl **rtnl, int ifindex, const char *name);
-int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
+int rtnl_set_link_properties(sd_rtnl **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
 
 int rtnl_log_parse_error(int r);
 int rtnl_log_create_error(int r);
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index 3ec245e..54cb928 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -63,7 +63,7 @@ int ethtool_connect(int *ret) {
         return 0;
 }
 
-int ethtool_get_driver(int fd, const char *ifname, char **ret) {
+int ethtool_get_driver(int *fd, const char *ifname, char **ret) {
         struct ethtool_drvinfo ecmd = {
                 .cmd = ETHTOOL_GDRVINFO
         };
@@ -73,9 +73,17 @@ int ethtool_get_driver(int fd, const char *ifname, char **ret) {
         char *d;
         int r;
 
+        if (*fd < 0) {
+                r = ethtool_connect(fd);
+                if (r < 0) {
+                        log_warning("link_config: could not connect to ethtool: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
 
-        r = ioctl(fd, SIOCETHTOOL, &ifr);
+        r = ioctl(*fd, SIOCETHTOOL, &ifr);
         if (r < 0)
                 return -errno;
 
@@ -87,7 +95,7 @@ int ethtool_get_driver(int fd, const char *ifname, char **ret) {
         return 0;
 }
 
-int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex duplex)
+int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex)
 {
         struct ethtool_cmd ecmd = {
                 .cmd = ETHTOOL_GSET
@@ -101,9 +109,17 @@ int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex dup
         if (speed == 0 && duplex == _DUP_INVALID)
                 return 0;
 
+        if (*fd < 0) {
+                r = ethtool_connect(fd);
+                if (r < 0) {
+                        log_warning("link_config: could not connect to ethtool: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
 
-        r = ioctl(fd, SIOCETHTOOL, &ifr);
+        r = ioctl(*fd, SIOCETHTOOL, &ifr);
         if (r < 0)
                 return -errno;
 
@@ -132,7 +148,7 @@ int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex dup
         if (need_update) {
                 ecmd.cmd = ETHTOOL_SSET;
 
-                r = ioctl(fd, SIOCETHTOOL, &ifr);
+                r = ioctl(*fd, SIOCETHTOOL, &ifr);
                 if (r < 0)
                         return -errno;
         }
@@ -140,7 +156,7 @@ int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex dup
         return 0;
 }
 
-int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol) {
+int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) {
         struct ethtool_wolinfo ecmd = {
                 .cmd = ETHTOOL_GWOL
         };
@@ -153,9 +169,17 @@ int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol) {
         if (wol == _WOL_INVALID)
                 return 0;
 
+        if (*fd < 0) {
+                r = ethtool_connect(fd);
+                if (r < 0) {
+                        log_warning("link_config: could not connect to ethtool: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
 
-        r = ioctl(fd, SIOCETHTOOL, &ifr);
+        r = ioctl(*fd, SIOCETHTOOL, &ifr);
         if (r < 0)
                 return -errno;
 
@@ -185,7 +209,7 @@ int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol) {
         if (need_update) {
                 ecmd.cmd = ETHTOOL_SWOL;
 
-                r = ioctl(fd, SIOCETHTOOL, &ifr);
+                r = ioctl(*fd, SIOCETHTOOL, &ifr);
                 if (r < 0)
                         return -errno;
         }
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index f44de50..690b1a6 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -42,9 +42,9 @@ typedef enum WakeOnLan {
 
 int ethtool_connect(int *ret);
 
-int ethtool_get_driver(int fd, const char *ifname, char **ret);
-int ethtool_set_speed(int fd, const char *ifname, unsigned int speed, Duplex duplex);
-int ethtool_set_wol(int fd, const char *ifname, WakeOnLan wol);
+int ethtool_get_driver(int *fd, const char *ifname, char **ret);
+int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
+int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
 
 const char *duplex_to_string(Duplex d) _const_;
 Duplex duplex_from_string(const char *d) _pure_;
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 64ff00d..ee2865a 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -88,30 +88,6 @@ int link_config_ctx_new(link_config_ctx **ret) {
         return 0;
 }
 
-static int link_config_ctx_connect(link_config_ctx *ctx) {
-        int r;
-
-        if (ctx->ethtool_fd == -1) {
-                r = ethtool_connect(&ctx->ethtool_fd);
-                if (r < 0) {
-                        log_warning("link_config: could not connect to ethtool: %s",
-                                    strerror(-r));
-                        return r;
-                }
-        }
-
-        if (!ctx->rtnl) {
-                r = sd_rtnl_open(&ctx->rtnl, 0);
-                if (r < 0) {
-                        log_warning("link_config: could not connect to rtnl: %s",
-                                    strerror(-r));
-                        return r;
-                }
-        }
-
-        return 0;
-}
-
 static void link_configs_free(link_config_ctx *ctx) {
         link_config *link, *link_next;
 
@@ -361,22 +337,18 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
         assert(device);
         assert(name);
 
-        r = link_config_ctx_connect(ctx);
-        if (r < 0)
-                return r;
-
         old_name = udev_device_get_sysname(device);
         if (!old_name)
                 return -EINVAL;
 
-        r = ethtool_set_speed(ctx->ethtool_fd, old_name, config->speed / 1024,
+        r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024,
                               config->duplex);
         if (r < 0)
                 log_warning("Could not set speed or duplex of %s to %u Mbps (%s): %s",
                             old_name, config->speed / 1024,
                             duplex_to_string(config->duplex), strerror(-r));
 
-        r = ethtool_set_wol(ctx->ethtool_fd, old_name, config->wol);
+        r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
         if (r < 0)
                 log_warning("Could not set WakeOnLan of %s to %s: %s",
                             old_name, wol_to_string(config->wol), strerror(-r));
@@ -449,7 +421,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                         mac = config->mac;
         }
 
-        r = rtnl_set_link_properties(ctx->rtnl, ifindex, config->alias, mac,
+        r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac,
                                      config->mtu);
         if (r < 0) {
                 log_warning("Could not set Alias, MACAddress or MTU on %s: %s",
@@ -467,15 +439,11 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret
         char *driver;
         int r;
 
-        r = link_config_ctx_connect(ctx);
-        if (r < 0)
-                return r;
-
         name = udev_device_get_sysname(device);
         if (!name)
                 return -EINVAL;
 
-        r = ethtool_get_driver(ctx->ethtool_fd, name, &driver);
+        r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver);
         if (r < 0)
                 return r;
 

commit 4c83d994566718043e61e568cc214bdc4587f869
Author: Tom Gundersen <teg at jklm.no>
Date:   Tue Sep 9 11:15:37 2014 +0200

    udev: event - keep one rtnl per worker, rather than per event
    
    Creating the rtnl context is cheap, but freeing it may not be, due to
    synchronous close().
    
    Also drop some excessive logging. We now log about the changing ifname
    exactly once.

diff --git a/src/libsystemd/sd-rtnl/rtnl-util.c b/src/libsystemd/sd-rtnl/rtnl-util.c
index 0bc2c9b..fe0f34e 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.c
+++ b/src/libsystemd/sd-rtnl/rtnl-util.c
@@ -26,7 +26,7 @@
 #include "rtnl-util.h"
 #include "rtnl-internal.h"
 
-int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name) {
+int rtnl_set_link_name(sd_rtnl **rtnl, int ifindex, const char *name) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *message = NULL;
         int r;
 
@@ -34,7 +34,13 @@ int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name) {
         assert(ifindex > 0);
         assert(name);
 
-        r = sd_rtnl_message_new_link(rtnl, &message, RTM_SETLINK, ifindex);
+        if (!*rtnl) {
+                r = sd_rtnl_open(rtnl, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
         if (r < 0)
                 return r;
 
@@ -42,7 +48,7 @@ int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name) {
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_call(rtnl, message, 0, NULL);
+        r = sd_rtnl_call(*rtnl, message, 0, NULL);
         if (r < 0)
                 return r;
 
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.h b/src/libsystemd/sd-rtnl/rtnl-util.h
index 2963f02..94af3b1 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.h
+++ b/src/libsystemd/sd-rtnl/rtnl-util.h
@@ -34,7 +34,7 @@ bool rtnl_message_type_is_link(uint16_t type);
 bool rtnl_message_type_is_addr(uint16_t type);
 bool rtnl_message_type_is_route(uint16_t type);
 
-int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name);
+int rtnl_set_link_name(sd_rtnl **rtnl, int ifindex, const char *name);
 int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
 
 int rtnl_log_parse_error(int r);
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 18b92ca..1bbf41e 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -53,6 +53,7 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
 void udev_event_unref(struct udev_event *event) {
         if (event == NULL)
                 return;
+        sd_rtnl_unref(event->rtnl);
         udev_list_cleanup(&event->run_list);
         udev_list_cleanup(&event->seclabel_list);
         free(event->program_result);
@@ -746,30 +747,24 @@ out:
 
 static int rename_netif(struct udev_event *event) {
         struct udev_device *dev = event->dev;
-        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
         char name[IFNAMSIZ];
         const char *oldname;
         int r;
 
         oldname = udev_device_get_sysname(dev);
 
-        log_debug("changing net interface name from '%s' to '%s'",
-                  oldname, event->name);
-
         strscpy(name, IFNAMSIZ, event->name);
 
-        r = sd_rtnl_open(&rtnl, 0);
-        if (r < 0)
+        r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name);
+        if (r < 0) {
+                log_error("error changing net interface name '%s' to '%s': %s",
+                          oldname, name, strerror(-r));
                 return r;
+        }
 
-        r = rtnl_set_link_name(rtnl, udev_device_get_ifindex(dev), name);
-        if (r < 0)
-                log_error("error changing net interface name %s to %s: %s",
-                          oldname, name, strerror(-r));
-        else
-                print_kmsg("renamed network interface %s to %s\n", oldname, name);
+        print_kmsg("renamed network interface '%s' to '%s'\n", oldname, name);
 
-        return r;
+        return 0;
 }
 
 void udev_event_execute_rules(struct udev_event *event,
@@ -832,8 +827,6 @@ void udev_event_execute_rules(struct udev_event *event,
 
                         r = rename_netif(event);
                         if (r >= 0) {
-                                log_debug("renamed netif to '%s'", event->name);
-
                                 /* remember old name */
                                 udev_device_add_property(dev, "INTERFACE_OLD", udev_device_get_sysname(dev));
 
diff --git a/src/udev/udev.h b/src/udev/udev.h
index faa8f56..ed01da3 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -23,6 +23,7 @@
 #include <signal.h>
 
 #include "macro.h"
+#include "sd-rtnl.h"
 #include "libudev.h"
 #include "libudev-private.h"
 #include "util.h"
@@ -44,6 +45,7 @@ struct udev_event {
         int exec_delay;
         usec_t birth_usec;
         int fd_signal;
+        sd_rtnl *rtnl;
         unsigned int builtin_run;
         unsigned int builtin_ret;
         bool sigterm;
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index e72c5b2..be0acc3 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -48,6 +48,7 @@
 
 #include "udev.h"
 #include "udev-util.h"
+#include "rtnl-util.h"
 #include "sd-daemon.h"
 #include "cgroup-util.h"
 #include "dev-setup.h"
@@ -200,6 +201,7 @@ static void worker_new(struct event *event) {
         case 0: {
                 struct udev_device *dev = NULL;
                 int fd_monitor;
+                _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
                 struct epoll_event ep_signal, ep_monitor;
                 sigset_t mask;
                 int rc = EXIT_SUCCESS;
@@ -301,11 +303,17 @@ static void worker_new(struct event *event) {
                                 }
                         }
 
+                        /* needed for renaming netifs */
+                        udev_event->rtnl = rtnl;
+
                         /* apply rules, create node, symlinks */
                         udev_event_execute_rules(udev_event, event_timeout_usec, rules, &sigmask_orig);
 
                         udev_event_execute_run(udev_event, event_timeout_usec, &sigmask_orig);
 
+                        /* in case rtnl was initialized */
+                        rtnl = sd_rtnl_ref(udev_event->rtnl);
+
                         /* apply/restore inotify watch */
                         if (udev_event->inotify_watch) {
                                 udev_watch_begin(udev, dev);



More information about the systemd-commits mailing list