This speeds up node_device_udev driver startup 11x. --- src/util/virnetdev.c | 69 +++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 52f02d3..7863e8a 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -3206,20 +3206,11 @@ virNetDevRDMAFeature(const char *ifname, * Returns 0 on success, -1 on failure. */ static int -virNetDevSendEthtoolIoctl(const char *ifname, void *cmd) +virNetDevSendEthtoolIoctl(int fd, struct ifreq *ifr) { int ret = -1; - int fd = -1; - struct ifreq ifr; - - /* Ultimately uses AF_PACKET for socket which requires privileged - * daemon support. - */ - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return ret; - ifr.ifr_data = cmd; - ret = ioctl(fd, SIOCETHTOOL, &ifr); + ret = ioctl(fd, SIOCETHTOOL, ifr); if (ret != 0) { switch (errno) { case EINVAL: /* kernel doesn't support SIOCETHTOOL */ @@ -3230,12 +3221,10 @@ virNetDevSendEthtoolIoctl(const char *ifname, void *cmd) break; default: virReportSystemError(errno, "%s", _("ethtool ioctl error")); - goto cleanup; + break; } } - cleanup: - VIR_FORCE_CLOSE(fd); return ret; } @@ -3255,10 +3244,10 @@ struct ethtool_to_virnetdev_feature { * Returns 0 if not found, 1 on success, and -1 on failure. */ static bool -virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd) +virNetDevFeatureAvailable(int fd, struct ifreq *ifr, struct ethtool_value *cmd) { - cmd = (void*)cmd; - if (virNetDevSendEthtoolIoctl(ifname, cmd) == 0 && + ifr->ifr_data = (void*)cmd; + if (virNetDevSendEthtoolIoctl(fd, ifr) == 0 && cmd->data > 0) return true; return false; @@ -3267,7 +3256,8 @@ virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd) static void virNetDevGetEthtoolFeatures(virBitmapPtr bitmap, - const char *ifname) + int fd, + struct ifreq *ifr) { size_t i; struct ethtool_value cmd = { 0 }; @@ -3306,12 +3296,12 @@ virNetDevGetEthtoolFeatures(virBitmapPtr bitmap, for (i = 0; i < ARRAY_CARDINALITY(ethtool_cmds); i++) { cmd.cmd = ethtool_cmds[i].cmd; - if (virNetDevFeatureAvailable(ifname, &cmd)) + if (virNetDevFeatureAvailable(fd, ifr, &cmd)) ignore_value(virBitmapSetBit(bitmap, ethtool_cmds[i].feat)); } cmd.cmd = ETHTOOL_GFLAGS; - if (virNetDevFeatureAvailable(ifname, &cmd)) { + if (virNetDevFeatureAvailable(fd, ifr, &cmd)) { for (i = 0; i < ARRAY_CARDINALITY(flags); i++) { if (cmd.data & flags[i].cmd) ignore_value(virBitmapSetBit(bitmap, flags[i].feat)); @@ -3332,10 +3322,12 @@ virNetDevGetEthtoolFeatures(virBitmapPtr bitmap, * Returns 0 if not found, 1 on success, and -1 on failure. */ static bool -virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd) +virNetDevGFeatureAvailable(int fd, + struct ifreq *ifr, + struct ethtool_gfeatures *cmd) { - cmd = (void*)cmd; - if (virNetDevSendEthtoolIoctl(ifname, cmd) == 0) + ifr->ifr_data = (void*)cmd; + if (virNetDevSendEthtoolIoctl(fd, ifr) == 0) return !!FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active); return false; } @@ -3343,7 +3335,8 @@ virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd) static int virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap, - const char *ifname) + int fd, + struct ifreq *ifr) { struct ethtool_gfeatures *g_cmd; @@ -3353,7 +3346,7 @@ virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap, g_cmd->cmd = ETHTOOL_GFEATURES; g_cmd->size = GFEATURES_SIZE; - if (virNetDevGFeatureAvailable(ifname, g_cmd)) + if (virNetDevGFeatureAvailable(fd, ifr, g_cmd)) ignore_value(virBitmapSetBit(bitmap, VIR_NET_DEV_FEAT_TXUDPTNL)); VIR_FREE(g_cmd); return 0; @@ -3361,7 +3354,8 @@ virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap, # else static int virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED) + int fd ATTRIBUTE_UNUSED, + struct ifreq *ifr ATTRIBUGE_UNUSED) { return 0; } @@ -3382,6 +3376,10 @@ int virNetDevGetFeatures(const char *ifname, virBitmapPtr *out) { + struct ifreq ifr; + int ret = -1; + int fd = -1; + if (!(*out = virBitmapNew(VIR_NET_DEV_FEAT_LAST))) return -1; @@ -3391,14 +3389,23 @@ virNetDevGetFeatures(const char *ifname, return 0; } - virNetDevGetEthtoolFeatures(*out, ifname); + /* Ultimately uses AF_PACKET for socket which requires privileged + * daemon support. + */ + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + goto cleanup; - if (virNetDevGetEthtoolGFeatures(*out, ifname) < 0) - return -1; + virNetDevGetEthtoolFeatures(*out, fd, &ifr); + + if (virNetDevGetEthtoolGFeatures(*out, fd, &ifr) < 0) + goto cleanup; if (virNetDevRDMAFeature(ifname, out) < 0) - return -1; - return 0; + goto cleanup; + + ret = 0; + cleanup: + return ret; } #else int -- 2.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list