* [PATCH] Add dom0 statistics for network bonding fix
@ 2009-12-02 11:35 Michal Novotny
0 siblings, 0 replies; only message in thread
From: Michal Novotny @ 2009-12-02 11:35 UTC (permalink / raw)
To: 'xen-devel@lists.xensource.com'
[-- Attachment #1: Type: text/plain, Size: 632 bytes --]
Hi,
in c/s 20528 (rev/e6e3bf767d16) 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).
Thanks,
Michal
Signed-off-by: Michal Novotny <minovotn@redhat.com>
[-- Attachment #2: xen-xenstat-dom0-stats-with-bonding-interface-v2-delta.patch --]
[-- Type: text/x-patch, Size: 15273 bytes --]
diff -r 7ffec3fab548 tools/xenstat/libxenstat/src/xenstat_linux.c
--- a/tools/xenstat/libxenstat/src/xenstat_linux.c Wed Dec 02 08:52:50 2009 +0000
+++ b/tools/xenstat/libxenstat/src/xenstat_linux.c Wed Dec 02 12:34:49 2009 +0100
@@ -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;
-
- char tmp[256] = { 0 }, *bridge;
-
- 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);
-
- if (access(tmp, F_OK) == 0)
- bridge = de->d_name;
- }
- }
- closedir(d);
-
- return bridge;
+ struct dirent *de;
+ DIR *d;
+
+ char tmp[256] = { 0 }, *bridge;
+
+ 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);
+
+ if (access(tmp, F_OK) == 0)
+ bridge = de->d_name;
+ }
+ }
+
+ 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)
-{
- /* 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;
+ 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;
+ 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_nod
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,
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-12-02 11:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-02 11:35 [PATCH] Add dom0 statistics for network bonding fix Michal Novotny
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.