Blob Blame History Raw
From 75d8b7e1afe532a93605e8ec83878830238d1fc2 Mon Sep 17 00:00:00 2001
Message-Id: <75d8b7e1afe532a93605e8ec83878830238d1fc2@dist-git>
From: Laine Stump <laine@laine.org>
Date: Thu, 13 Apr 2017 14:29:32 -0400
Subject: [PATCH] util: replace virHostdevNetConfigReplace with
 ...(Save|Set)NetConfig()

These two operations will need to be separated so that saving of the
original config is done before detaching the host net driver, and
setting the new config is done after attaching vfio-pci. This patch
splits the single function into two, but for now calls them together
(to make bisecting easier if there is a regression).

Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4)

(cherry picked from commit b684734bef7d475a5d3f20acf6d46c4a34e77d63)
---
 src/util/virhostdev.c | 93 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 70 insertions(+), 23 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index a715aae12..b869ebc0c 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -390,10 +390,65 @@ virHostdevNetConfigVirtPortProfile(const char *linkdev, int vf,
 }
 
 
+/**
+ * virHostdevSaveNetConfig:
+ * @hostdev: config object describing a hostdev device
+ * @stateDir: directory to save device state into
+ *
+ * If the given hostdev device is an SRIOV network VF and *does not*
+ * have a <virtualport> element (ie, it isn't being configured via
+ * 802.11Qbh), determine its PF+VF#, and use that to save its current
+ * "admin" MAC address and VF tag (the ones saved in the PF
+ * driver).
+ *
+ * Returns 0 on success, -1 on failure.
+ */
 static int
-virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
-                           const unsigned char *uuid,
-                           const char *stateDir)
+virHostdevSaveNetConfig(virDomainHostdevDefPtr hostdev,
+                        const char *stateDir)
+{
+    int ret = -1;
+    char *linkdev = NULL;
+    int vf = -1;
+
+    if (!virHostdevIsPCINetDevice(hostdev) ||
+        virDomainNetGetActualVirtPortProfile(hostdev->parent.data.net))
+       return 0;
+
+    if (virHostdevIsVirtualFunction(hostdev) != 1) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Interface type hostdev is currently supported on"
+                         " SR-IOV Virtual Functions only"));
+        goto cleanup;
+    }
+
+    if (virHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
+        goto cleanup;
+
+    if (virNetDevSaveNetConfig(linkdev, vf, stateDir, true) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(linkdev);
+    return ret;
+}
+
+
+/**
+ * virHostdevSetNetConfig:
+ * @hostdev: config object describing a hostdev device
+ * @uuid: uuid of the domain
+ *
+ * If the given hostdev device is an SRIOV network VF, determine its
+ * PF+VF#, and use that to set the "admin" MAC address and VF tag (the
+ * ones saved in the PF driver).xs
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int
+virHostdevSetNetConfig(virDomainHostdevDefPtr hostdev,
+                       const unsigned char *uuid)
 {
     char *linkdev = NULL;
     virNetDevVlanPtr vlan;
@@ -402,12 +457,8 @@ virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
     int vf = -1;
     bool port_profile_associate = true;
 
-    if (virHostdevIsVirtualFunction(hostdev) != 1) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("Interface type hostdev is currently supported on"
-                         " SR-IOV Virtual Functions only"));
-        goto cleanup;
-    }
+    if (!virHostdevIsPCINetDevice(hostdev))
+        return 0;
 
     if (virHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
         goto cleanup;
@@ -428,11 +479,6 @@ virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
             goto cleanup;
         }
     } else {
-        /* Save/Set only mac and vlan */
-
-        if (virNetDevSaveNetConfig(linkdev, vf, stateDir, true) < 0)
-            goto cleanup;
-
         if (virNetDevSetNetConfig(linkdev, vf, &hostdev->parent.data.net->mac,
                                   vlan, NULL, true) < 0) {
             goto cleanup;
@@ -445,6 +491,7 @@ virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
     return ret;
 }
 
+
 /* @oldStateDir:
  * For upgrade purpose:
  * To an existing VM on QEMU, the hostdev netconfig file is originally stored
@@ -660,16 +707,16 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
     }
 
     /* Step 4: For SRIOV network devices, Now that we have detached the
-     * the network device, set the netdev config */
+     * the network device, set the new netdev config */
     for (i = 0; i < nhostdevs; i++) {
-         virDomainHostdevDefPtr hostdev = hostdevs[i];
-         if (!virHostdevIsPCINetDevice(hostdev))
-             continue;
-         if (virHostdevNetConfigReplace(hostdev, uuid,
-                                        mgr->stateDir) < 0) {
-             goto resetvfnetconfig;
-         }
-         last_processed_hostdev_vf = i;
+
+        if (virHostdevSaveNetConfig(hostdevs[i], mgr->stateDir) < 0)
+            goto resetvfnetconfig;
+
+        if (virHostdevSetNetConfig(hostdevs[i], uuid) < 0)
+            goto resetvfnetconfig;
+
+        last_processed_hostdev_vf = i;
     }
 
     /* Step 5: Move devices from the inactive list to the active list */
-- 
2.12.2