util: new function virNetDevOpenvswitchInterfaceGetMaster()

This function retrieves the name of the OVS bridge that the given
netdev is attached to. This separate function is necessary because OVS
set the IFLA_MASTER attribute to "ovs-system" for all netdevs that are
attached to an OVS bridge, so the standard method of retrieving the
master can't be used.

Signed-off-by: Laine Stump <laine@laine.org>
ACKed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Laine Stump 2018-07-01 19:24:19 -04:00
parent fbe4a458b6
commit 032548c42a
3 changed files with 63 additions and 0 deletions

View File

@ -2389,6 +2389,7 @@ virNetDevMidonetUnbindPort;
virNetDevOpenvswitchAddPort;
virNetDevOpenvswitchGetMigrateData;
virNetDevOpenvswitchGetVhostuserIfname;
virNetDevOpenvswitchInterfaceGetMaster;
virNetDevOpenvswitchInterfaceStats;
virNetDevOpenvswitchRemovePort;
virNetDevOpenvswitchSetMigrateData;

View File

@ -404,6 +404,62 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname,
return ret;
}
/**
* virNetDeOpenvswitchGetMaster:
* @ifname: name of interface we're interested in
* @master: used to return a string containing the name of @ifname's "master"
* (this is the bridge or bond device that this device is attached to)
*
* Returns 0 on success, -1 on failure (if @ifname has no master
* @master will be NULL, but return value will still be 0 (success)).
*
* NB: This function is needed because the IFLA_MASTER attribute of an
* interface in a netlink dump (see virNetDevGetMaster()) will always
* return "ovs-system" for any interface that is attached to an OVS
* switch. When that happens, virNetDevOpenvswitchInterfaceGetMaster()
* must be called to get the "real" master of the interface.
*/
int
virNetDevOpenvswitchInterfaceGetMaster(const char *ifname, char **master)
{
virCommandPtr cmd = NULL;
int ret = -1;
int exitstatus;
*master = NULL;
cmd = virCommandNew(OVSVSCTL);
virNetDevOpenvswitchAddTimeout(cmd);
virCommandAddArgList(cmd, "iface-to-br", ifname, NULL);
virCommandSetOutputBuffer(cmd, master);
if (virCommandRun(cmd, &exitstatus) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to run command to get OVS master for "
"interface %s"), ifname);
goto cleanup;
}
/* non-0 exit code just means that the interface has no master in OVS */
if (exitstatus != 0)
VIR_FREE(*master);
if (*master) {
/* truncate at the first newline */
char *nl = strchr(*master, '\n');
if (nl)
*nl = '\0';
}
VIR_DEBUG("OVS master for %s is %s", ifname, *master ? *master : "(none)");
ret = 0;
cleanup:
return ret;
}
/**
* virNetDevOpenvswitchVhostuserGetIfname:
* @path: the path of the unix socket

View File

@ -47,6 +47,9 @@ int virNetDevOpenvswitchAddPort(const char *brname,
int virNetDevOpenvswitchRemovePort(const char *brname, const char *ifname)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevOpenvswitchInterfaceGetMaster(const char *ifname, char **master)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
@ -57,6 +60,9 @@ int virNetDevOpenvswitchInterfaceStats(const char *ifname,
virDomainInterfaceStatsPtr stats)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevOpenvswitchInterfaceGetMaster(const char *ifname, char **master)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevOpenvswitchGetVhostuserIfname(const char *path,
char **ifname)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;