mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Move virstat.c code to virnetdevtap.c
This is just a code move of virstat.c to virnetdevtap.c
This commit is contained in:
committed by
Michal Privoznik
parent
9b6de7c506
commit
e0d893e86d
@@ -33,7 +33,13 @@
|
||||
#include "viralloc.h"
|
||||
#include "virlog.h"
|
||||
#include "virstring.h"
|
||||
#include "datatypes.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <regex.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -44,6 +50,9 @@
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <net/if_tap.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETIFADDRS) && defined(AF_LINK)
|
||||
# include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||
|
||||
@@ -601,3 +610,137 @@ int virNetDevTapCreateInBridgePort(const char *brname,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-------------------- interface stats --------------------*/
|
||||
/* Just reads the named interface, so not Xen or QEMU-specific.
|
||||
* NB. Caller must check that libvirt user is trying to query
|
||||
* the interface of a domain they own. We do no such checking.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
int
|
||||
virNetDevTapInterfaceStats(const char *ifname,
|
||||
virDomainInterfaceStatsPtr stats)
|
||||
{
|
||||
int ifname_len;
|
||||
FILE *fp;
|
||||
char line[256], *colon;
|
||||
|
||||
fp = fopen("/proc/net/dev", "r");
|
||||
if (!fp) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Could not open /proc/net/dev"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifname_len = strlen(ifname);
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
long long dummy;
|
||||
long long rx_bytes;
|
||||
long long rx_packets;
|
||||
long long rx_errs;
|
||||
long long rx_drop;
|
||||
long long tx_bytes;
|
||||
long long tx_packets;
|
||||
long long tx_errs;
|
||||
long long tx_drop;
|
||||
|
||||
/* The line looks like:
|
||||
* " eth0:..."
|
||||
* Split it at the colon.
|
||||
*/
|
||||
colon = strchr(line, ':');
|
||||
if (!colon) continue;
|
||||
*colon = '\0';
|
||||
if (colon-ifname_len >= line &&
|
||||
STREQ(colon-ifname_len, ifname)) {
|
||||
/* IMPORTANT NOTE!
|
||||
* /proc/net/dev vif<domid>.nn sees the network from the point
|
||||
* of view of dom0 / hypervisor. So bytes TRANSMITTED by dom0
|
||||
* are bytes RECEIVED by the domain. That's why the TX/RX fields
|
||||
* appear to be swapped here.
|
||||
*/
|
||||
if (sscanf(colon+1,
|
||||
"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
|
||||
&tx_bytes, &tx_packets, &tx_errs, &tx_drop,
|
||||
&dummy, &dummy, &dummy, &dummy,
|
||||
&rx_bytes, &rx_packets, &rx_errs, &rx_drop,
|
||||
&dummy, &dummy, &dummy, &dummy) != 16)
|
||||
continue;
|
||||
|
||||
stats->rx_bytes = rx_bytes;
|
||||
stats->rx_packets = rx_packets;
|
||||
stats->rx_errs = rx_errs;
|
||||
stats->rx_drop = rx_drop;
|
||||
stats->tx_bytes = tx_bytes;
|
||||
stats->tx_packets = tx_packets;
|
||||
stats->tx_errs = tx_errs;
|
||||
stats->tx_drop = tx_drop;
|
||||
VIR_FORCE_FCLOSE(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
VIR_FORCE_FCLOSE(fp);
|
||||
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("/proc/net/dev: Interface not found"));
|
||||
return -1;
|
||||
}
|
||||
#elif defined(HAVE_GETIFADDRS) && defined(AF_LINK)
|
||||
int
|
||||
virNetDevTapInterfaceStats(const char *ifname,
|
||||
virDomainInterfaceStatsPtr stats)
|
||||
{
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct if_data *ifd;
|
||||
int ret = -1;
|
||||
|
||||
if (getifaddrs(&ifap) < 0) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Could not get interface list"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family != AF_LINK)
|
||||
continue;
|
||||
|
||||
if (STREQ(ifa->ifa_name, ifname)) {
|
||||
ifd = (struct if_data *)ifa->ifa_data;
|
||||
stats->tx_bytes = ifd->ifi_ibytes;
|
||||
stats->tx_packets = ifd->ifi_ipackets;
|
||||
stats->tx_errs = ifd->ifi_ierrors;
|
||||
stats->tx_drop = ifd->ifi_iqdrops;
|
||||
stats->rx_bytes = ifd->ifi_obytes;
|
||||
stats->rx_packets = ifd->ifi_opackets;
|
||||
stats->rx_errs = ifd->ifi_oerrors;
|
||||
# ifdef HAVE_STRUCT_IF_DATA_IFI_OQDROPS
|
||||
stats->rx_drop = ifd->ifi_oqdrops;
|
||||
# else
|
||||
stats->rx_drop = 0;
|
||||
# endif
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Interface not found"));
|
||||
|
||||
freeifaddrs(ifap);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int
|
||||
virNetDevTapInterfaceStats(const char *ifname ATTRIBUTE_UNUSED,
|
||||
virDomainInterfaceStatsPtr stats ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("interface stats not implemented on this platform"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
Reference in New Issue
Block a user