From aedca89268ed4fd6be41e55a605f011033ad1fb5 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 9 Sep 2014 15:36:56 +0200 Subject: [PATCH] udev: net_setup_link - open ethtool and rtnl connections lazily --- src/libsystemd/sd-rtnl/rtnl-util.c | 26 ++++++++----------- src/libsystemd/sd-rtnl/rtnl-util.h | 2 +- src/udev/net/ethtool-util.c | 40 ++++++++++++++++++++++++------ src/udev/net/ethtool-util.h | 6 ++--- src/udev/net/link-config.c | 40 +++--------------------------- 5 files changed, 51 insertions(+), 63 deletions(-) diff --git a/src/libsystemd/sd-rtnl/rtnl-util.c b/src/libsystemd/sd-rtnl/rtnl-util.c index fe0f34e12..1ec1fa8d2 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 94af3b172..fa3592df9 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 3ec245eca..54cb92809 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 f44de5076..690b1a65a 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 64ff00dc0..ee2865a86 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; -- 2.30.2