1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-22 14:50:27 +03:00

util: new internal function to permit silent failure of virNetDevSetMAC()

We will want to allow silent failure of virNetDevSetMAC() in the case
that the SIOSIFHWADDR ioctl fails with errno == EADDRNOTAVAIL. (Yes,
that is very specific, but we really *do* want a logged failure in all
other circumstances, and don't want to duplicate code in the caller
for the other possibilities).

This patch renames the 3 different virNetDevSetMAC() functions to
virNetDevSetMACInternal(), adding a 3rd arg called "quiet" and making
them static (because this extra control will only be needed within
virnetdev.c). A new global virNetDevSetMAC() is defined that calls
whichever of the three *Internal() functions gets compiled with quiet
= false. Callers in virnetdev.c that want to notice a failure with
errno == EADDRNOTAVAIL and retry with a different strategy rather than
immediately failing, can call virNetDevSetMACInternal(..., true).
This commit is contained in:
Laine Stump 2017-03-09 14:04:16 -05:00
parent 251d179bf2
commit f4ef3a71f8

View File

@ -222,17 +222,20 @@ int virNetDevExists(const char *ifname)
#if defined(SIOCGIFHWADDR) && defined(SIOCSIFHWADDR) && \ #if defined(SIOCGIFHWADDR) && defined(SIOCSIFHWADDR) && \
defined(HAVE_STRUCT_IFREQ) defined(HAVE_STRUCT_IFREQ)
/** /**
* virNetDevSetMAC: * virNetDevSetMACInternal:
* @ifname: interface name to set MTU for * @ifname: interface name to set MTU for
* @macaddr: MAC address * @macaddr: MAC address
* @quiet: true if a failure to set MAC address with errno == EADDRNOTAVAIL
* should be silent (still returns error, but without log)
* *
* This function sets the @macaddr for a given interface @ifname. This * This function sets the @macaddr for a given interface @ifname.
* gets rid of the kernel's automatically assigned random MAC.
* *
* Returns 0 in case of success or -1 on failure * Returns 0 in case of success or -1 on failure
*/ */
int virNetDevSetMAC(const char *ifname, static int
const virMacAddr *macaddr) virNetDevSetMACInternal(const char *ifname,
const virMacAddr *macaddr,
bool quiet)
{ {
int fd = -1; int fd = -1;
int ret = -1; int ret = -1;
@ -254,6 +257,9 @@ int virNetDevSetMAC(const char *ifname,
if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
char macstr[VIR_MAC_STRING_BUFLEN]; char macstr[VIR_MAC_STRING_BUFLEN];
if (quiet && errno == EADDRNOTAVAIL)
goto cleanup;
virReportSystemError(errno, virReportSystemError(errno,
_("Cannot set interface MAC to %s on '%s'"), _("Cannot set interface MAC to %s on '%s'"),
virMacAddrFormat(macaddr, macstr), ifname); virMacAddrFormat(macaddr, macstr), ifname);
@ -266,10 +272,16 @@ int virNetDevSetMAC(const char *ifname,
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(fd);
return ret; return ret;
} }
#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \
#elif defined(SIOCSIFLLADDR) && defined(HAVE_STRUCT_IFREQ) && \
HAVE_DECL_LINK_ADDR HAVE_DECL_LINK_ADDR
int virNetDevSetMAC(const char *ifname,
const virMacAddr *macaddr)
static int
virNetDevSetMACInternal(const char *ifname,
const virMacAddr *macaddr,
bool quiet)
{ {
struct ifreq ifr; struct ifreq ifr;
struct sockaddr_dl sdl; struct sockaddr_dl sdl;
@ -288,6 +300,9 @@ int virNetDevSetMAC(const char *ifname,
ifr.ifr_addr.sa_len = VIR_MAC_BUFLEN; ifr.ifr_addr.sa_len = VIR_MAC_BUFLEN;
if (ioctl(s, SIOCSIFLLADDR, &ifr) < 0) { if (ioctl(s, SIOCSIFLLADDR, &ifr) < 0) {
if (quiet && errno == EADDRNOTAVAIL)
goto cleanup;
virReportSystemError(errno, virReportSystemError(errno,
_("Cannot set interface MAC to %s on '%s'"), _("Cannot set interface MAC to %s on '%s'"),
mac + 1, ifname); mac + 1, ifname);
@ -300,18 +315,34 @@ int virNetDevSetMAC(const char *ifname,
return ret; return ret;
} }
#else #else
int virNetDevSetMAC(const char *ifname,
const virMacAddr *macaddr ATTRIBUTE_UNUSED)
static int
virNetDevSetMACInternal(const char *ifname,
const virMacAddr *macaddr ATTRIBUTE_UNUSED,
bool quiet ATTRIBUTE_UNUSED)
{ {
virReportSystemError(ENOSYS, virReportSystemError(ENOSYS,
_("Cannot set interface MAC on '%s'"), _("Cannot set interface MAC on '%s'"),
ifname); ifname);
return -1; return -1;
} }
#endif #endif
int
virNetDevSetMAC(const char *ifname,
const virMacAddr *macaddr)
{
return virNetDevSetMACInternal(ifname, macaddr, false);
}
#if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ) #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ)
/** /**
* virNetDevGetMAC: * virNetDevGetMAC: