render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
5c27b6
From f97142c91f965c0087fcf99122bcd7c0777ef287 Mon Sep 17 00:00:00 2001
5c27b6
Message-Id: <f97142c91f965c0087fcf99122bcd7c0777ef287@dist-git>
5c27b6
From: Laine Stump <laine@laine.org>
5c27b6
Date: Thu, 13 Apr 2017 14:29:34 -0400
5c27b6
Subject: [PATCH] util: after hostdev assignment, restore VF MAC address via
5c27b6
 setting admin MAC
5c27b6
5c27b6
It takes longer to explain this than to fix it...
5c27b6
5c27b6
In the past we weren't able to save the VF's own MAC address *at all*
5c27b6
when using it for hostdev assignment, because we had already unbound
5c27b6
the VF from the host net driver prior to saving its config. With the
5c27b6
previous patch, that problem has been solved, so we now have the VF's
5c27b6
MAC address saved and can move on to the *next* problem, which is twofold:
5c27b6
5c27b6
1) during teardown we restore the config before we've re-bound, so the
5c27b6
   VF doesn't have a net driver, and thus we can't set its MAC address
5c27b6
   directly.
5c27b6
5c27b6
2) even if we delay restoring the config until the VF is bound to a
5c27b6
   net driver, the request to set its MAC address would fail, since
5c27b6
   (during device setup) we had set the "admin MAC" for the VF via an
5c27b6
   RTM_SETLINK to the PF - once you've set the admin MAC for a VF, the
5c27b6
   VF driver (either on host or on guest) is not allowed to change the
5c27b6
   VF's MAC address "forever" (well, until you reload the PF driver,
5c27b6
   but that requires destroying and recreating every single VF, which
5c27b6
   isn't something you can require).
5c27b6
5c27b6
The solution is to keep the restoration of config at the same place,
5c27b6
but to set the *admin MAC* to the address you want the VF to have -
5c27b6
when the VF net driver is later initialized (as a part of re-binding
5c27b6
to the VF net driver) its MAC will be initialized to the current value
5c27b6
of the admin MAC.
5c27b6
5c27b6
Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
5c27b6
Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4)
5c27b6
5c27b6
(cherry picked from commit d6ef331f112ab51af7d14c59cd0b460c2e9609a8)
5c27b6
---
5c27b6
 src/util/virhostdev.c | 24 ++++++++++++++++++++++++
5c27b6
 1 file changed, 24 insertions(+)
5c27b6
5c27b6
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
5c27b6
index f07e50d2c..fe87fa7d7 100644
5c27b6
--- a/src/util/virhostdev.c
5c27b6
+++ b/src/util/virhostdev.c
5c27b6
@@ -544,6 +544,30 @@ virHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
5c27b6
                                          &adminMAC, &vlan, &MAC);
5c27b6
 
5c27b6
         if (ret == 0) {
5c27b6
+            /* if a MAC was stored for the VF, we should now restore
5c27b6
+             * that as the adminMAC. We have to do it this way because
5c27b6
+             * the VF is still not bound to the host's net driver, so
5c27b6
+             * we can't directly set its MAC (and even after it is
5c27b6
+             * re-bound to the host net driver, it will still have its
5c27b6
+             * "administratively set" flag on, and that prohibits the
5c27b6
+             * VF's net driver from directly setting the MAC
5c27b6
+             * anyway). But it we set the desired VF MAC as the "admin
5c27b6
+             * MAC" *now*, then when the VF is re-bound to the host
5c27b6
+             * net driver (which will happen soon after returning from
5c27b6
+             * this function), that adminMAC will be set (by the PF)
5c27b6
+             * as the VF's new initial MAC.
5c27b6
+             *
5c27b6
+             * If no MAC was stored for the VF, that means it wasn't
5c27b6
+             * bound to a net driver before we used it anyway, so the
5c27b6
+             * adminMAC is all we have, and we can just restore it
5c27b6
+             * directly.
5c27b6
+             */
5c27b6
+            if (MAC) {
5c27b6
+                VIR_FREE(adminMAC);
5c27b6
+                adminMAC = MAC;
5c27b6
+                MAC = NULL;
5c27b6
+            }
5c27b6
+
5c27b6
             ignore_value(virNetDevSetNetConfig(linkdev, vf,
5c27b6
                                                adminMAC, vlan, MAC, true));
5c27b6
         }
5c27b6
-- 
5c27b6
2.12.2
5c27b6