mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
virnetdev: Introduce virNetDevGetLinkInfo
The purpose of this function is to fetch link state and link speed for given NIC name from the SYSFS. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
3db89662c2
commit
05630cf4e5
@ -1542,6 +1542,7 @@ virNetDevClearIPv4Address;
|
|||||||
virNetDevExists;
|
virNetDevExists;
|
||||||
virNetDevGetIndex;
|
virNetDevGetIndex;
|
||||||
virNetDevGetIPv4Address;
|
virNetDevGetIPv4Address;
|
||||||
|
virNetDevGetLinkInfo;
|
||||||
virNetDevGetMAC;
|
virNetDevGetMAC;
|
||||||
virNetDevGetMTU;
|
virNetDevGetMTU;
|
||||||
virNetDevGetPhysicalFunction;
|
virNetDevGetPhysicalFunction;
|
||||||
|
@ -1832,3 +1832,97 @@ virNetDevRestoreNetConfig(const char *linkdev ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(__linux__) && defined(HAVE_LIBNL) */
|
#endif /* defined(__linux__) && defined(HAVE_LIBNL) */
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
int
|
||||||
|
virNetDevGetLinkInfo(const char *ifname,
|
||||||
|
virInterfaceLinkPtr lnk)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *path = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *tmp;
|
||||||
|
int tmp_state;
|
||||||
|
unsigned int tmp_speed;
|
||||||
|
|
||||||
|
if (virNetDevSysfsFile(&path, ifname, "operstate") < 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 ((tmp_state = virInterfaceStateTypeFromString(buf)) <= 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to parse: %s"),
|
||||||
|
buf);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
lnk->state = tmp_state;
|
||||||
|
|
||||||
|
VIR_FREE(path);
|
||||||
|
VIR_FREE(buf);
|
||||||
|
|
||||||
|
if (virNetDevSysfsFile(&path, ifname, "speed") < 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_ui(buf, &tmp, 10, &tmp_speed) < 0 ||
|
||||||
|
*tmp != '\n') {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to parse: %s"),
|
||||||
|
buf);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Workaround broken kernel API. If the link is unplugged then
|
||||||
|
* depending on the NIC driver, link speed can be reported as -1.
|
||||||
|
* However, the value is printed out as unsigned integer instead of
|
||||||
|
* signed one. Terrifying but true. */
|
||||||
|
lnk->speed = (int) tmp_speed == -1 ? 0 : tmp_speed;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(buf);
|
||||||
|
VIR_FREE(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDevGetLinkInfo(const char *ifname,
|
||||||
|
virInterfaceLinkPtr lnk)
|
||||||
|
{
|
||||||
|
/* Port me */
|
||||||
|
VIR_DEBUG("Getting link info on %s is not implemented on this platform");
|
||||||
|
lnk->speed = lnk->state = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(__linux__) */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
# include "virnetlink.h"
|
# include "virnetlink.h"
|
||||||
# include "virmacaddr.h"
|
# include "virmacaddr.h"
|
||||||
# include "virpci.h"
|
# include "virpci.h"
|
||||||
|
# include "device_conf.h"
|
||||||
|
|
||||||
# ifdef HAVE_STRUCT_IFREQ
|
# ifdef HAVE_STRUCT_IFREQ
|
||||||
typedef struct ifreq virIfreq;
|
typedef struct ifreq virIfreq;
|
||||||
@ -145,4 +146,8 @@ int virNetDevGetVirtualFunctionInfo(const char *vfname, char **pfname,
|
|||||||
int *vf)
|
int *vf)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
int virNetDevGetLinkInfo(const char *ifname,
|
||||||
|
virInterfaceLinkPtr lnk)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
#endif /* __VIR_NETDEV_H__ */
|
#endif /* __VIR_NETDEV_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user