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