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>
This commit is contained in:
Keir Fraser committed 2009-12-02 13:45:35 +00:00
1 parent fe356defec
commit 80d4e9ca77
1 file changed
+191 -185
+191 -185
View File
@@ -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;
/* 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 = "([^:]*):([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)"
"[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*"
"([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)[ ]*([^ ]*)";
/* 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;
/* 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;
}
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];
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);
/* 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"));
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);
}
}
}
memset(tmp, 0, matches[i].rm_eo - matches[i].rm_so);
}
}
}
free(tmp);
regfree(&r);
free(tmp);
regfree(&r);
return 0;
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);
/* 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;
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);
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].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);
/* 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 */
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,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.