aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstat
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-02 13:45:35 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-02 13:45:35 +0000
commit80d4e9ca778762a4911977e7a90a1299b00a8629 (patch)
tree504db88852d4b3de21a6f7d8d206b65e2aced95d /tools/xenstat
parentfe356defec5b50c1faab672bf488d68c9c996917 (diff)
downloadxen-80d4e9ca778762a4911977e7a90a1299b00a8629.tar.gz
xen-80d4e9ca778762a4911977e7a90a1299b00a8629.tar.bz2
xen-80d4e9ca778762a4911977e7a90a1299b00a8629.zip
xenstat: Fixes for 20528:e6e3bf767d16 (stats for dom0 network bonding)
In above c/s I introduced dom0 statistics for case we use network bonding. The indentation was not good for xenstat C codebase and also some modifications were done to the logic, mainly not using the parsed variables we don't care about (as we care only about {tx|rx}{bytes,packets,errs,drops} and no other variable from /proc/net/dev) by passing NULLs to variables we don't care about. Also dom0 statistics alteration was fixed to include {tx|rx}{drop,errs} for dom0 (previous version of my patch was not having this code applied). Signed-off-by: Michal Novotny <minovotn@redhat.com>
Diffstat (limited to 'tools/xenstat')
-rw-r--r--tools/xenstat/libxenstat/src/xenstat_linux.c402
1 files changed, 204 insertions, 198 deletions
diff --git a/tools/xenstat/libxenstat/src/xenstat_linux.c b/tools/xenstat/libxenstat/src/xenstat_linux.c
index 4f22b593aa..c17423d3f3 100644
--- a/tools/xenstat/libxenstat/src/xenstat_linux.c
+++ b/tools/xenstat/libxenstat/src/xenstat_linux.c
@@ -66,180 +66,182 @@ static const char PROCNETDEV_HEADER[] =
/* Use excludeName parameter to avoid adding bridges we don't care about, eg. virbr0 */
char *getBridge(char *excludeName)
{
- struct dirent *de;
- DIR *d;
+ struct dirent *de;
+ DIR *d;
- char tmp[256] = { 0 }, *bridge;
+ char tmp[256] = { 0 }, *bridge;
- bridge = (char *)malloc(16 * sizeof(char));
+ bridge = (char *)malloc(16 * sizeof(char));
- d = opendir("/sys/class/net");
- while ((de = readdir(d)) != NULL) {
- if ((strlen(de->d_name) > 0) && (de->d_name[0] != '.')
- && (strstr(de->d_name, excludeName) == NULL)) {
- sprintf(tmp, "/sys/class/net/%s/bridge", de->d_name);
+ d = opendir("/sys/class/net");
+ while ((de = readdir(d)) != NULL) {
+ if ((strlen(de->d_name) > 0) && (de->d_name[0] != '.')
+ && (strstr(de->d_name, excludeName) == NULL)) {
+ sprintf(tmp, "/sys/class/net/%s/bridge", de->d_name);
- if (access(tmp, F_OK) == 0)
- bridge = de->d_name;
- }
- }
- closedir(d);
+ if (access(tmp, F_OK) == 0)
+ bridge = de->d_name;
+ }
+ }
- return bridge;
+ closedir(d);
+
+ return bridge;
}
/* parseNetLine provides regular expression based parsing for lines from /proc/net/dev, all the */
/* information are parsed but not all are used in our case, ie. for xenstat */
int parseNetDevLine(char *line, char *iface, unsigned long long *rxBytes, unsigned long long *rxPackets,
- unsigned long long *rxErrs, unsigned long long *rxDrops, unsigned long long *rxFifo,
- unsigned long long *rxFrames, unsigned long long *rxComp, unsigned long long *rxMcast,
- unsigned long long *txBytes, unsigned long long *txPackets, unsigned long long *txErrs,
- unsigned long long *txDrops, unsigned long long *txFifo, unsigned long long *txColls,
- unsigned long long *txCarrier, unsigned long long *txComp)
+ unsigned long long *rxErrs, unsigned long long *rxDrops, unsigned long long *rxFifo,
+ unsigned long long *rxFrames, unsigned long long *rxComp, unsigned long long *rxMcast,
+ unsigned long long *txBytes, unsigned long long *txPackets, unsigned long long *txErrs,
+ unsigned long long *txDrops, unsigned long long *txFifo, unsigned long long *txColls,
+ unsigned long long *txCarrier, unsigned long long *txComp)
{
- /* Temporary/helper variables */
- int ret;
- char *tmp;
- int i = 0, x = 0, col = 0;
- regex_t r;
- regmatch_t matches[19];
- int num = 19;
-
- /* Regular exception to parse all the information from /proc/net/dev line */
- char *regex = "([^:]*):([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)"
- "[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*"
- "([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)";
-
- /* Initialize all variables called has passed as non-NULL to zeros */
- if (iface != NULL)
- memset(iface, 0, sizeof(iface));
- if (rxBytes != NULL)
- *rxBytes = 0;
- if (rxPackets != NULL)
- *rxPackets = 0;
- if (rxErrs != NULL)
- *rxErrs = 0;
- if (rxDrops != NULL)
- *rxDrops = 0;
- if (rxFifo != NULL)
- *rxFifo = 0;
- if (rxFrames != NULL)
- *rxFrames = 0;
- if (rxPackets != NULL)
- *rxPackets = 0;
- if (rxComp != NULL)
- *rxComp = 0;
- if (txBytes != NULL)
- *txBytes = 0;
- if (txPackets != NULL)
- *txPackets = 0;
- if (txErrs != NULL)
- *txErrs = 0;
- if (txDrops != NULL)
- *txDrops = 0;
- if (txFifo != NULL)
- *txFifo = 0;
- if (txColls != NULL)
- *txColls = 0;
- if (txCarrier != NULL)
- *txCarrier = 0;
- if (txComp != NULL)
- *txComp = 0;
-
- if ((ret = regcomp(&r, regex, REG_EXTENDED))) {
- regfree(&r);
- return ret;
- }
-
- tmp = (char *)malloc( sizeof(char) );
- if (regexec (&r, line, num, matches, REG_EXTENDED) == 0){
- for (i = 1; i < num; i++) {
- /* The expression matches are empty sometimes so we need to check it first */
- if (matches[i].rm_eo - matches[i].rm_so > 0) {
- /* Col variable contains current id of non-empty match */
- col++;
- tmp = (char *)realloc(tmp, (matches[i].rm_eo - matches[i].rm_so + 1) * sizeof(char));
- for (x = matches[i].rm_so; x < matches[i].rm_eo; x++)
- tmp[x - matches[i].rm_so] = line[x];
-
- /* We populate all the fields from /proc/net/dev line */
- if (i > 1) {
- unsigned long long ullTmp = strtoull(tmp, NULL, 10);
-
- switch (col) {
- case 2: if (rxBytes != NULL)
- *rxBytes = ullTmp;
- break;
- case 3: if (rxPackets != NULL)
- *rxPackets = ullTmp;
- break;
- case 4: if (rxErrs != NULL)
- *rxErrs = ullTmp;
- break;
- case 5: if (rxDrops != NULL)
- *rxDrops = ullTmp;
- break;
- case 6: if (rxFifo != NULL)
- *rxFifo = ullTmp;
- break;
- case 7: if (rxFrames != NULL)
- *rxFrames = ullTmp;
- break;
- case 8: if (rxComp != NULL)
- *rxComp = ullTmp;
- break;
- case 9: if (rxMcast != NULL)
- *rxMcast = ullTmp;
- break;
- case 10: if (txBytes != NULL)
- *txBytes = ullTmp;
- break;
- case 11: if (txPackets != NULL)
- *txPackets = ullTmp;
- break;
- case 12: if (txErrs != NULL)
- *txErrs = ullTmp;
- case 13: if (txDrops != NULL)
- *txDrops = ullTmp;
- break;
- case 14: if (txFifo != NULL)
- *txFifo = ullTmp;
- break;
- case 15: if (txColls != NULL)
- *txColls = ullTmp;
- break;
- case 16: if (txCarrier != NULL)
- *txCarrier = ullTmp;
- break;
- case 17: if (txComp != NULL)
- *txComp = ullTmp;
- break;
- }
- }
- else
- /* There were errors when parsing this directly in RE. strpbrk() helps */
- if (iface != NULL)
- strcpy(iface, strpbrk(tmp, "abcdefghijklmnopqrstvuwxyz0123456789"));
-
- memset(tmp, 0, matches[i].rm_eo - matches[i].rm_so);
- }
- }
- }
-
- free(tmp);
- regfree(&r);
-
- return 0;
+ /* Temporary/helper variables */
+ int ret;
+ char *tmp;
+ int i = 0, x = 0, col = 0;
+ regex_t r;
+ regmatch_t matches[19];
+ int num = 19;
+
+ /* Regular exception to parse all the information from /proc/net/dev line */
+ char *regex = "([^:]*):([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)"
+ "[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*"
+ "([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)";
+
+ /* Initialize all variables called has passed as non-NULL to zeros */
+ if (iface != NULL)
+ memset(iface, 0, sizeof(iface));
+ if (rxBytes != NULL)
+ *rxBytes = 0;
+ if (rxPackets != NULL)
+ *rxPackets = 0;
+ if (rxErrs != NULL)
+ *rxErrs = 0;
+ if (rxDrops != NULL)
+ *rxDrops = 0;
+ if (rxFifo != NULL)
+ *rxFifo = 0;
+ if (rxFrames != NULL)
+ *rxFrames = 0;
+ if (rxPackets != NULL)
+ *rxPackets = 0;
+ if (rxComp != NULL)
+ *rxComp = 0;
+ if (txBytes != NULL)
+ *txBytes = 0;
+ if (txPackets != NULL)
+ *txPackets = 0;
+ if (txErrs != NULL)
+ *txErrs = 0;
+ if (txDrops != NULL)
+ *txDrops = 0;
+ if (txFifo != NULL)
+ *txFifo = 0;
+ if (txColls != NULL)
+ *txColls = 0;
+ if (txCarrier != NULL)
+ *txCarrier = 0;
+ if (txComp != NULL)
+ *txComp = 0;
+
+ if ((ret = regcomp(&r, regex, REG_EXTENDED))) {
+ regfree(&r);
+ return ret;
+ }
+
+ tmp = (char *)malloc( sizeof(char) );
+ if (regexec (&r, line, num, matches, REG_EXTENDED) == 0){
+ for (i = 1; i < num; i++) {
+ /* The expression matches are empty sometimes so we need to check it first */
+ if (matches[i].rm_eo - matches[i].rm_so > 0) {
+ /* Col variable contains current id of non-empty match */
+ col++;
+ tmp = (char *)realloc(tmp, (matches[i].rm_eo -
+ matches[i].rm_so + 1) * sizeof(char));
+ for (x = matches[i].rm_so; x < matches[i].rm_eo; x++)
+ tmp[x - matches[i].rm_so] = line[x];
+
+ /* We populate all the fields from /proc/net/dev line */
+ if (i > 1) {
+ unsigned long long ullTmp = strtoull(tmp, NULL, 10);
+
+ switch (col) {
+ case 2: if (rxBytes != NULL)
+ *rxBytes = ullTmp;
+ break;
+ case 3: if (rxPackets != NULL)
+ *rxPackets = ullTmp;
+ break;
+ case 4: if (rxErrs != NULL)
+ *rxErrs = ullTmp;
+ break;
+ case 5: if (rxDrops != NULL)
+ *rxDrops = ullTmp;
+ break;
+ case 6: if (rxFifo != NULL)
+ *rxFifo = ullTmp;
+ break;
+ case 7: if (rxFrames != NULL)
+ *rxFrames = ullTmp;
+ break;
+ case 8: if (rxComp != NULL)
+ *rxComp = ullTmp;
+ break;
+ case 9: if (rxMcast != NULL)
+ *rxMcast = ullTmp;
+ break;
+ case 10: if (txBytes != NULL)
+ *txBytes = ullTmp;
+ break;
+ case 11: if (txPackets != NULL)
+ *txPackets = ullTmp;
+ break;
+ case 12: if (txErrs != NULL)
+ *txErrs = ullTmp;
+ break;
+ case 13: if (txDrops != NULL)
+ *txDrops = ullTmp;
+ break;
+ case 14: if (txFifo != NULL)
+ *txFifo = ullTmp;
+ break;
+ case 15: if (txColls != NULL)
+ *txColls = ullTmp;
+ break;
+ case 16: if (txCarrier != NULL)
+ *txCarrier = ullTmp;
+ break;
+ case 17: if (txComp != NULL)
+ *txComp = ullTmp;
+ break;
+ }
+ }
+ else
+ /* There were errors when parsing this directly in RE. strpbrk() helps */
+ if (iface != NULL)
+ strcpy(iface, strpbrk(tmp, "abcdefghijklmnopqrstvuwxyz0123456789"));
+
+ memset(tmp, 0, matches[i].rm_eo - matches[i].rm_so);
+ }
+ }
+ }
+
+ free(tmp);
+ regfree(&r);
+
+ return 0;
}
/* Collect information about networks */
int xenstat_collect_networks(xenstat_node * node)
{
- /* Helper variables for parseNetDevLine() function defined above */
- int i;
- char line[512] = { 0 }, iface[16] = { 0 }, devBridge[16] = { 0 }, devNoBridge[16] = { 0 };
- unsigned long long rxBytes, rxPackets, rxErrs, rxDrops, rxFifo, rxFrames, rxComp, rxMcast;
- unsigned long long txBytes, txPackets, txErrs, txDrops, txFifo, txColls, txCarrier, txComp;
+ /* Helper variables for parseNetDevLine() function defined above */
+ int i;
+ char line[512] = { 0 }, iface[16] = { 0 }, devBridge[16] = { 0 }, devNoBridge[16] = { 0 };
+ unsigned long long rxBytes, rxPackets, rxErrs, rxDrops, txBytes, txPackets, txErrs, txDrops;
struct priv_data *priv = get_priv_data(node->handle);
@@ -276,46 +278,50 @@ int xenstat_collect_networks(xenstat_node * node)
fseek(priv->procnetdev, sizeof(PROCNETDEV_HEADER) - 1,
SEEK_SET);
- /* We get the bridge devices for use with bonding interface to get bonding interface stats */
- snprintf(devBridge, 16, "%s", getBridge("vir"));
- snprintf(devNoBridge, 16, "p%s", devBridge);
-
- while (fgets(line, 512, priv->procnetdev)) {
- xenstat_domain *domain;
- xenstat_network net;
- unsigned int domid;
-
- parseNetDevLine(line, iface, &rxBytes, &rxPackets, &rxErrs, &rxDrops, &rxFifo, &rxFrames, &rxComp,
- &rxMcast, &txBytes, &txPackets, &txErrs, &txDrops, &txFifo, &txColls, &txCarrier, &txComp);
-
- /* If the device parsed is network bridge and both tx & rx packets are zero, we are most */
- /* likely using bonding so we alter the configuration for dom0 to have bridge stats */
- if ((strstr(iface, devBridge) != NULL) && (strstr(iface, devNoBridge) == NULL)) {
- domain = xenstat_node_domain(node, 0);
- for (i = 0; i < domain->num_networks; i++) {
- if ((domain->networks[i].id == 0) && (domain->networks[i].tbytes == 0)
- && (domain->networks[i].rbytes == 0)) {
- domain->networks[i].tbytes = txBytes;
- domain->networks[i].tpackets = txPackets;
- domain->networks[i].rbytes = rxBytes;
- domain->networks[i].rpackets = rxPackets;
- }
- }
- }
- else /* Otherwise we need to preserve old behaviour */
- if (strstr(iface, "vif") != NULL) {
- sscanf(iface, "vif%u.%u", &domid, &net.id);
-
- net.tbytes = txBytes;
- net.tpackets = txPackets;
- net.terrs = txErrs;
- net.tdrop = txDrops;
- net.rbytes = rxBytes;
- net.rpackets = rxPackets;
- net.rerrs = rxErrs;
- net.rdrop = rxDrops;
-
- /* FIXME: this does a search for the domid */
+ /* We get the bridge devices for use with bonding interface to get bonding interface stats */
+ snprintf(devBridge, 16, "%s", getBridge("vir"));
+ snprintf(devNoBridge, 16, "p%s", devBridge);
+
+ while (fgets(line, 512, priv->procnetdev)) {
+ xenstat_domain *domain;
+ xenstat_network net;
+ unsigned int domid;
+
+ parseNetDevLine(line, iface, &rxBytes, &rxPackets, &rxErrs, &rxDrops, NULL, NULL, NULL,
+ NULL, &txBytes, &txPackets, &txErrs, &txDrops, NULL, NULL, NULL, NULL);
+
+ /* If the device parsed is network bridge and both tx & rx packets are zero, we are most */
+ /* likely using bonding so we alter the configuration for dom0 to have bridge stats */
+ if ((strstr(iface, devBridge) != NULL) && (strstr(iface, devNoBridge) == NULL)) {
+ domain = xenstat_node_domain(node, 0);
+ for (i = 0; i < domain->num_networks; i++) {
+ if ((domain->networks[i].id == 0) && (domain->networks[i].tbytes == 0)
+ && (domain->networks[i].rbytes == 0)) {
+ domain->networks[i].tbytes = txBytes;
+ domain->networks[i].tpackets = txPackets;
+ domain->networks[i].terrs = txErrs;
+ domain->networks[i].tdrop = txDrops;
+ domain->networks[i].rbytes = rxBytes;
+ domain->networks[i].rpackets = rxPackets;
+ domain->networks[i].rerrs = rxErrs;
+ domain->networks[i].rdrop = rxDrops;
+ }
+ }
+ }
+ else /* Otherwise we need to preserve old behaviour */
+ if (strstr(iface, "vif") != NULL) {
+ sscanf(iface, "vif%u.%u", &domid, &net.id);
+
+ net.tbytes = txBytes;
+ net.tpackets = txPackets;
+ net.terrs = txErrs;
+ net.tdrop = txDrops;
+ net.rbytes = rxBytes;
+ net.rpackets = rxPackets;
+ net.rerrs = rxErrs;
+ net.rdrop = rxDrops;
+
+ /* FIXME: this does a search for the domid */
domain = xenstat_node_domain(node, domid);
if (domain == NULL) {
fprintf(stderr,