While the previous commit was pretty straightforward, things are different with netcf as it doesn't exposed the bits we need yet. However, we can work around it by fetching the info we need from SYSFS. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/interface/interface_backend_netcf.c | 99 +++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index 1b9ace5..40181ef 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -33,6 +33,7 @@ #include "virlog.h" #include "virstring.h" #include "viraccessapicheck.h" +#include "virfile.h" #define VIR_FROM_THIS VIR_FROM_INTERFACE @@ -240,6 +241,96 @@ static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfac return iface; } +/* Okay, the following two doesn't really belong here as they dump the info + * from SYSFS rather than netcf. But netcf is not yet exposing the info we + * need, so what. */ +#define SYSFS_PREFIX "/sys/class/net/" + +static int +interfaceGetState(const char *name, + virInterfaceState *state) +{ + int ret = -1; + char *path = NULL; + char *buf = NULL; + char *tmp; + + if (virAsprintf(&path, SYSFS_PREFIX "%s/operstate", name) < 0) + goto cleanup; + + if (virFileReadAll(path, 1024, &buf) < 0) { + virReportSystemError(errno, + _("unable to read: %s"), + path); + goto cleanup; + } + + if (!(tmp = strchr(buf, '\n'))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse: %s"), + buf); + goto cleanup; + } + + *tmp = '\0'; + + /* We shouldn't allow 0 here, because + * virInterfaceState enum starts from 1. */ + if ((*state = virInterfaceStateTypeFromString(buf)) <= 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse: %s"), + buf); + goto cleanup; + } + + ret = 0; + cleanup: + VIR_FREE(buf); + VIR_FREE(path); + return ret; +} + +static int +interfaceGetSpeed(const char *name, + unsigned long *speed) +{ + int ret = -1; + char *path = NULL; + char *buf = NULL; + char *tmp; + + if (virAsprintf(&path, SYSFS_PREFIX "%s/speed", name) < 0) + goto cleanup; + + if (virFileReadAll(path, 1024, &buf) < 0) { + /* Some devices doesn't report speed, in which case we get EINVAL */ + if (errno == EINVAL) { + ret = 0; + goto cleanup; + } + virReportSystemError(errno, + _("unable to read: %s"), + path); + goto cleanup; + } + + if (virStrToLong_ul(buf, &tmp, 10, speed) < 0 || + *tmp != '\n') { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse: %s"), + buf); + goto cleanup; + } + + ret = 1; + cleanup: + VIR_FREE(buf); + VIR_FREE(path); + return ret; +} + +/* Ond of sysfs hacks */ + static int netcfInterfaceObjIsActive(struct netcf_if *iface, bool *active) @@ -840,6 +931,14 @@ static char *netcfInterfaceGetXMLDesc(virInterfacePtr ifinfo, if (virInterfaceGetXMLDescEnsureACL(ifinfo->conn, ifacedef) < 0) goto cleanup; + if (interfaceGetState(ifacedef->name, &ifacedef->state) < 0) + goto cleanup; + + /* querying inteface speed makes sense only sometimes */ + if (ifacedef->state == VIR_INTERFACE_STATE_UP && + interfaceGetSpeed(ifacedef->name, &ifacedef->speed) < 0) + goto cleanup; + ret = virInterfaceDefFormat(ifacedef); if (!ret) { /* error was already reported */ -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list