Blame SOURCES/libvirt-util-new-internal-function-to-permit-silent-failure-of-virNetDevSetMAC.patch

5c27b6
From 4ebaf75b8d1650d1067483b16ad243cb204ba8dc Mon Sep 17 00:00:00 2001
5c27b6
Message-Id: <4ebaf75b8d1650d1067483b16ad243cb204ba8dc@dist-git>
5c27b6
From: Laine Stump <laine@laine.org>
5c27b6
Date: Thu, 13 Apr 2017 14:29:27 -0400
5c27b6
Subject: [PATCH] util: new internal function to permit silent failure of
5c27b6
 virNetDevSetMAC()
5c27b6
5c27b6
We will want to allow silent failure of virNetDevSetMAC() in the case
5c27b6
that the SIOSIFHWADDR ioctl fails with errno == EADDRNOTAVAIL. (Yes,
5c27b6
that is very specific, but we really *do* want a logged failure in all
5c27b6
other circumstances, and don't want to duplicate code in the caller
5c27b6
for the other possibilities).
5c27b6
5c27b6
This patch renames the 3 different virNetDevSetMAC() functions to
5c27b6
virNetDevSetMACInternal(), adding a 3rd arg called "quiet" and making
5c27b6
them static (because this extra control will only be needed within
5c27b6
virnetdev.c). A new global virNetDevSetMAC() is defined that calls
5c27b6
whichever of the three *Internal() functions gets compiled with quiet
5c27b6
= false. Callers in virnetdev.c that want to notice a failure with
5c27b6
errno == EADDRNOTAVAIL and retry with a different strategy rather than
5c27b6
immediately failing, can call virNetDevSetMACInternal(..., true).
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 f4ef3a71f8abc83771952604d309b39ca3ea64cf)
5c27b6
---
5c27b6
 src/util/virnetdev.c | 51 +++++++++++++++++++++++++++++++++++++++++----------
5c27b6
 1 file changed, 41 insertions(+), 10 deletions(-)
5c27b6
5c27b6
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
5c27b6
index 766638dd3..ffc2fb4e4 100644
5c27b6
--- a/src/util/virnetdev.c
5c27b6
+++ b/src/util/virnetdev.c
5c27b6
@@ -222,17 +222,20 @@ int virNetDevExists(const char *ifname)
5c27b6
 #if defined(SIOCGIFHWADDR) && defined(SIOCSIFHWADDR) && \
5c27b6
     defined(HAVE_STRUCT_IFREQ)
5c27b6
 /**
5c27b6
- * virNetDevSetMAC:
5c27b6
+ * virNetDevSetMACInternal:
5c27b6
  * @ifname: interface name to set MTU for
5c27b6
  * @macaddr: MAC address
5c27b6
+ * @quiet: true if a failure to set MAC address with errno == EADDRNOTAVAIL
5c27b6
+ *         should be silent (still returns error, but without log)
5c27b6
  *
5c27b6
- * This function sets the @macaddr for a given interface @ifname. This
5c27b6
- * gets rid of the kernel's automatically assigned random MAC.
5c27b6
+ * This function sets the @macaddr for a given interface @ifname.
5c27b6
  *
5c27b6
  * Returns 0 in case of success or -1 on failure
5c27b6
  */
5c27b6
-int virNetDevSetMAC(const char *ifname,
5c27b6
-                    const virMacAddr *macaddr)
5c27b6
+static int
5c27b6
+virNetDevSetMACInternal(const char *ifname,
5c27b6
+                        const virMacAddr *macaddr,
5c27b6
+                        bool quiet)
5c27b6
 {
5c27b6
     int fd = -1;
5c27b6
     int ret = -1;
5c27b6
@@ -254,6 +257,9 @@ int virNetDevSetMAC(const char *ifname,
5c27b6
     if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
5c27b6
         char macstr[VIR_MAC_STRING_BUFLEN];
5c27b6
 
5c27b6
+        if (quiet && errno == EADDRNOTAVAIL)
5c27b6
+            goto cleanup;
5c27b6
+
5c27b6
         virReportSystemError(errno,
5c27b6
                              _("Cannot set interface MAC to %s on '%s'"),
5c27b6
                              virMacAddrFormat(macaddr, macstr), ifname);
5c27b6
@@ -266,10 +272,16 @@ int virNetDevSetMAC(const char *ifname,
5c27b6
     VIR_FORCE_CLOSE(fd);
5c27b6
     return ret;
5c27b6
 }
5c27b6
-#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \
5c27b6
+
5c27b6
+
5c27b6
+#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) &&   \
5c27b6
     HAVE_DECL_LINK_ADDR
5c27b6
-int virNetDevSetMAC(const char *ifname,
5c27b6
-                    const virMacAddr *macaddr)
5c27b6
+
5c27b6
+
5c27b6
+static int
5c27b6
+virNetDevSetMACInternal(const char *ifname,
5c27b6
+                        const virMacAddr *macaddr,
5c27b6
+                        bool quiet)
5c27b6
 {
5c27b6
         struct ifreq ifr;
5c27b6
         struct sockaddr_dl sdl;
5c27b6
@@ -288,6 +300,9 @@ int virNetDevSetMAC(const char *ifname,
5c27b6
         ifr.ifr_addr.sa_len = VIR_MAC_BUFLEN;
5c27b6
 
5c27b6
         if (ioctl(s, SIOCSIFLLADDR, &ifr) < 0) {
5c27b6
+            if (quiet && errno == EADDRNOTAVAIL)
5c27b6
+                goto cleanup;
5c27b6
+
5c27b6
             virReportSystemError(errno,
5c27b6
                                  _("Cannot set interface MAC to %s on '%s'"),
5c27b6
                                  mac + 1, ifname);
5c27b6
@@ -300,18 +315,34 @@ int virNetDevSetMAC(const char *ifname,
5c27b6
 
5c27b6
         return ret;
5c27b6
 }
5c27b6
+
5c27b6
+
5c27b6
 #else
5c27b6
-int virNetDevSetMAC(const char *ifname,
5c27b6
-                    const virMacAddr *macaddr ATTRIBUTE_UNUSED)
5c27b6
+
5c27b6
+
5c27b6
+static int
5c27b6
+virNetDevSetMACInternal(const char *ifname,
5c27b6
+                        const virMacAddr *macaddr ATTRIBUTE_UNUSED,
5c27b6
+                        bool quiet ATTRIBUTE_UNUSED)
5c27b6
 {
5c27b6
     virReportSystemError(ENOSYS,
5c27b6
                          _("Cannot set interface MAC on '%s'"),
5c27b6
                          ifname);
5c27b6
     return -1;
5c27b6
 }
5c27b6
+
5c27b6
+
5c27b6
 #endif
5c27b6
 
5c27b6
 
5c27b6
+int
5c27b6
+virNetDevSetMAC(const char *ifname,
5c27b6
+                const virMacAddr *macaddr)
5c27b6
+{
5c27b6
+    return virNetDevSetMACInternal(ifname, macaddr, false);
5c27b6
+}
5c27b6
+
5c27b6
+
5c27b6
 #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ)
5c27b6
 /**
5c27b6
  * virNetDevGetMAC:
5c27b6
-- 
5c27b6
2.12.2
5c27b6