]> xenbits.xensource.com Git - libvirt.git/commitdiff
Reuse the socket in virNetDevGetFeatures
authorJán Tomko <jtomko@redhat.com>
Fri, 3 Jun 2016 18:46:05 +0000 (20:46 +0200)
committerJán Tomko <jtomko@redhat.com>
Tue, 7 Jun 2016 12:13:11 +0000 (14:13 +0200)
This speeds up node_device_udev driver startup 11x.

src/util/virnetdev.c

index 956cacd5fde91e2aff89c8ac4b7a6d8f80f87940..e6c57ac0e83563ad8a778d1f01357c1eee75153f 100644 (file)
@@ -3200,26 +3200,17 @@ virNetDevRDMAFeature(const char *ifname,
  * virNetDevSendEthtoolIoctl
  * This function sends ethtool ioctl request
  *
- * @ifname: name of the interface
- * @cmd: reference to an ethtool command structure
+ * @fd: socket to operate on
+ * @ifr: struct ifreq with the command
  *
  * 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;
 }
 
@@ -3249,16 +3238,17 @@ struct virNetDevEthtoolFeatureCmd {
  * virNetDevFeatureAvailable
  * This function checks for the availability of a network device feature
  *
- * @ifname: name of the interface
+ * @fd: socket to operate on
+ * @ifr: struct ifreq with the command
  * @cmd: reference to an ethtool command structure
  *
  * Returns true if the feature is available, false otherwise.
  */
 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 +3257,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 };
@@ -3307,13 +3298,13 @@ 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));
     }
 
 # if HAVE_DECL_ETHTOOL_GFLAGS
     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));
@@ -3328,16 +3319,19 @@ virNetDevGetEthtoolFeatures(virBitmapPtr bitmap,
  * virNetDevGFeatureAvailable
  * This function checks for the availability of a network device gfeature
  *
- * @ifname: name of the interface
- * @cmd: reference to a gfeatures ethtool command structure
+ * @fd: socket to operate on
+ * @ifr: struct ifreq with the command
+ * @cmd: reference to an ethtool command structure
  *
  * Returns true if the feature is available, false otherwise.
  */
 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;
 }
@@ -3345,7 +3339,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;
 
@@ -3355,7 +3350,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;
@@ -3363,7 +3358,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;
 }
@@ -3384,6 +3380,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;
 
@@ -3393,14 +3393,24 @@ 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:
+    VIR_FORCE_CLOSE(fd);
+    return ret;
 }
 #else
 int