From: Tyrel D. <ty...@us...> - 2011-11-29 06:28:12
|
Update of /cvsroot/sblim/gather/plugin In directory vz-cvs-3.sog:/tmp/cvs-serv11567/plugin Modified Files: metricKvm.c metricVirt.c metricVirt.h repositoryKvm.c Log Message: Fixed 3444879: add VM Block IO Metrics Index: metricVirt.c =================================================================== RCS file: /cvsroot/sblim/gather/plugin/metricVirt.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- metricVirt.c 27 Oct 2011 16:33:10 -0000 1.15 +++ metricVirt.c 29 Nov 2011 06:28:09 -0000 1.16 @@ -1,7 +1,7 @@ /* * $Id$ * - * (C) Copyright IBM Corp. 2009, 2009 + * (C) Copyright IBM Corp. 2009, 2011 * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE @@ -104,11 +104,122 @@ return tconn; } + +/* ---------------------------------------------------------------------------*/ +/* parseDomainXML */ +/* parse domain XML and collect block io stats */ +/* ---------------------------------------------------------------------------*/ +static struct vdisk_type *parseDomainXML(virDomainPtr domain) +{ + char *cur; + char *end; + char *temp; + virDomainBlockInfo blkinfo; + virDomainBlockStatsStruct blkstats; + struct vdisk_type *disk = NULL; + struct vdisk_type *head = NULL; + int parse = 0; + int type = 0; + + parse = 1; + cur = virDomainGetXMLDesc(domain, 0); + + while (parse) { + if ((cur = strstr(cur, "<disk"))) { + cur = strstr(cur, "type=\'"); + cur = cur + 6; + + switch (*cur) { + case 'f': + type = 0; + break; + case 'b': + type = 1; + break; + default: + continue; + } + + end = strstr(cur, "</disk"); + + temp = strstr(cur, "<source"); + if (temp > end) { + continue; + } + + cur = temp; + + if (type) { + cur = strstr(cur, "dev=\'"); + cur = cur + 5; + } else { + cur = strstr(cur, "file=\'"); + cur = cur + 6; + } + + end = strstr(cur, "\'"); + + if (!disk) { + disk = malloc(sizeof(struct vdisk_type)); + disk->next = NULL; + head = disk; + } else { + disk->next = malloc(sizeof(struct vdisk_type)); + disk = disk->next; + disk->next = NULL; + } + + disk->source = malloc(end - cur + 1); + disk->source = strncpy(disk->source, cur, end - cur); + disk->source[end - cur] = 0; + + cur = strstr(cur, "<target"); + cur = strstr(cur, "dev=\'"); + cur = cur + 5; + + end = strstr(cur, "\'"); + + disk->target = malloc(end - cur + 1); + disk->target = strncpy(disk->target, cur, end - cur); + disk->target[end - cur] = 0; + + virDomainGetBlockInfo(domain, disk->source, &blkinfo, 0); + disk->capacity = blkinfo.capacity; + virDomainBlockStats(domain, disk->target, &blkstats, + sizeof(virDomainBlockStatsStruct)); + + /* Convert to Kilobytes */ + disk->read = blkstats.rd_bytes / 1024; + disk->write = blkstats.wr_bytes / 1024; + } else { + parse = 0; + } + } + + return head; +} + +static void freeBlkIOData(int domains) +{ + struct vdisk_type * cur, * head; + int i; + + for (i = 0; i < domains; i++) { + head = domain_statistics.blkio[i]; + + while (head) { + cur = head; + head = cur->next; + free(cur); + } + } +} + + /* ---------------------------------------------------------------------------*/ /* collectDomainSchedStats */ /* get scheduler statistics for a given domain */ /* ---------------------------------------------------------------------------*/ - static void collectDomainSchedStats(int cnt) { FILE * fd = NULL; @@ -276,7 +387,11 @@ virConnectClose(conn); return VIRT_NOUPD; } else { - node_statistics.num_active_domains = 0; // reset number of domains + /* free previous running domain vdisk data */ + freeBlkIOData(node_statistics.num_active_domains); + + /* reset domain numbers */ + node_statistics.num_active_domains = 0; node_statistics.num_inactive_domains = 0; node_statistics.total_domains = 0; last_time_sampled = time(NULL); @@ -338,6 +453,7 @@ domain_statistics.state[cnt] = dinfo.state; collectDomainSchedStats(cnt); + domain_statistics.blkio[cnt] = parseDomainXML(domain); #ifdef DEBUG fprintf(stderr, "--- %s(%i) : %s (%d)\n\t claimed %lu max %lu\n\t time %f cpus %hu\n", @@ -898,3 +1014,79 @@ return -1; } + +int virtMetricRetrVirtualBlockIOStats(int mid, MetricReturner mret) +{ + MetricValue *mv = NULL; + struct vdisk_type * disk; + char values[25*3+4]; + char * resource; + +#ifdef DEBUG + fprintf(stderr, + "--- %s(%i) : Retrieving VirtualBlockIOStats\n", + __FILE__, __LINE__); +#endif + + if (collectDomainStats() == VIRT_FAIL) + return -1; + + if (mret == NULL) { +#ifdef DEBUG + fprintf(stderr, + "--- %s(%i) : Returner pointer is NULL\n", + __FILE__, __LINE__); +#endif + } else { +#ifdef DEBUG + fprintf(stderr, + "--- %s(%i) : Sampling for VirtualBlockIOStats\n", + __FILE__, __LINE__); +#endif + + int i; + +#ifdef DEBUG + fprintf(stderr, + "--- %s(%i) : num_active_domains %d\n", + __FILE__, __LINE__, node_statistics.num_active_domains); +#endif + + for (i = 0; i < node_statistics.total_domains; i++) { + + disk = domain_statistics.blkio[i]; + + while (disk) { + + memset(values,0,sizeof(values)); + sprintf(values,"%lld:%lld:%lld:", disk->read, disk->write, disk->capacity); + + resource = malloc(strlen(domain_statistics.domain_name[i]) + + strlen(disk->source) + strlen(disk->target) + 3); + sprintf(resource,"%s:%s:%s", domain_statistics.domain_name[i], disk->source, disk->target); + + mv = calloc(1, sizeof(MetricValue) + + (strlen(values) + 1) + + (strlen(resource) + 1)); + + if (mv) { + mv->mvId = mid; + mv->mvTimeStamp = time(NULL); + mv->mvDataType = MD_STRING; + mv->mvDataLength = strlen(values) + 1; + mv->mvData = (char *) mv + sizeof(MetricValue); + strcpy(mv->mvData, values); + mv->mvResource = (char *) mv + sizeof(MetricValue) + (strlen(values) + 1); + strcpy(mv->mvResource, resource); + mret(mv); + } + + disk = disk->next; + } + } + + return 1; + } + + return -1; +} Index: repositoryKvm.c =================================================================== RCS file: /cvsroot/sblim/gather/plugin/repositoryKvm.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- repositoryKvm.c 11 May 2011 01:42:58 -0000 1.8 +++ repositoryKvm.c 29 Nov 2011 06:28:09 -0000 1.9 @@ -1,7 +1,7 @@ /* * $Id$ * - * (C) Copyright IBM Corp. 2009 + * (C) Copyright IBM Corp. 2009, 2011 * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE @@ -50,7 +50,7 @@ /* ---------------------------------------------------------------------------*/ -static MetricCalculationDefinition metricCalcDef[17]; +static MetricCalculationDefinition metricCalcDef[21]; // metric _Internal_CPUTime static MetricCalculator metricCalcCPUTime; @@ -94,9 +94,16 @@ // metric WaitSum // static MetricCalculator metricCalcWaitSum +// metric VirtualBlockIOStats +static MetricCalculator metricCalcVirtualBlockIOStats; +static MetricCalculator metricCalcBlockRead; +static MetricCalculator metricCalcBlockWrite; +static MetricCalculator metricCalcBlockCapacity; + /* unit definitions */ static char *muKiloBytes = "Kilobytes"; +static char *muBytes = "Bytes"; static char *muPercent = "Percent"; static char *muMicroSeconds = "MicroSeconds"; static char *muMilliSeconds = "MilliSeconds"; @@ -105,6 +112,12 @@ /* ---------------------------------------------------------------------------*/ +enum indices { BLK_READ, BLK_WRITE, BLK_CAP }; +static unsigned long long kvm_getData(char * data, char index); + + +/* ---------------------------------------------------------------------------*/ + int _DefinedRepositoryMetrics(MetricRegisterId * mr, const char *pluginname, size_t * mcnum, @@ -328,8 +341,57 @@ metricCalcDef[16].mcDataType = MD_UINT64; metricCalcDef[16].mcCalc = metricCalcSchedulerStats; metricCalcDef[16].mcUnits = muMicroSeconds; + + metricCalcDef[17].mcVersion = MD_VERSION; + metricCalcDef[17].mcName = "_VirtualBlockIOStats"; + metricCalcDef[17].mcId = mr(pluginname, metricCalcDef[17].mcName); + metricCalcDef[17].mcMetricType = + MD_PERIODIC | MD_RETRIEVED | MD_POINT; + metricCalcDef[17].mcIsContinuous = MD_FALSE; + metricCalcDef[17].mcCalculable = MD_NONCALCULABLE; + metricCalcDef[17].mcDataType = MD_STRING; + metricCalcDef[17].mcCalc = metricCalcVirtualBlockIOStats; + metricCalcDef[17].mcUnits = muNA; + + metricCalcDef[18].mcVersion = MD_VERSION; + metricCalcDef[18].mcName = "BlockRead"; + metricCalcDef[18].mcId = mr(pluginname, metricCalcDef[18].mcName); + metricCalcDef[18].mcMetricType = + MD_PERIODIC | MD_CALCULATED | MD_INTERVAL; + metricCalcDef[18].mcChangeType = MD_GAUGE; + metricCalcDef[18].mcIsContinuous = MD_TRUE; + metricCalcDef[18].mcCalculable = MD_SUMMABLE; + metricCalcDef[18].mcDataType = MD_UINT64; + metricCalcDef[18].mcAliasId=metricCalcDef[17].mcId; + metricCalcDef[18].mcCalc = metricCalcBlockRead; + metricCalcDef[18].mcUnits = muKiloBytes; + + metricCalcDef[19].mcVersion = MD_VERSION; + metricCalcDef[19].mcName = "BlockWrite"; + metricCalcDef[19].mcId = mr(pluginname, metricCalcDef[19].mcName); + metricCalcDef[19].mcMetricType = + MD_PERIODIC | MD_CALCULATED | MD_INTERVAL; + metricCalcDef[19].mcChangeType = MD_GAUGE; + metricCalcDef[19].mcIsContinuous = MD_TRUE; + metricCalcDef[19].mcCalculable = MD_SUMMABLE; + metricCalcDef[19].mcDataType = MD_UINT64; + metricCalcDef[19].mcAliasId=metricCalcDef[17].mcId; + metricCalcDef[19].mcCalc = metricCalcBlockWrite; + metricCalcDef[19].mcUnits = muKiloBytes; + + metricCalcDef[20].mcVersion=MD_VERSION; + metricCalcDef[20].mcName="BlockCapacity"; + metricCalcDef[20].mcId=mr(pluginname,metricCalcDef[20].mcName); + metricCalcDef[20].mcMetricType=MD_PERIODIC|MD_CALCULATED|MD_POINT; + metricCalcDef[20].mcChangeType=MD_GAUGE; + metricCalcDef[20].mcIsContinuous=MD_TRUE; + metricCalcDef[20].mcCalculable=MD_NONSUMMABLE; + metricCalcDef[20].mcDataType=MD_UINT64; + metricCalcDef[20].mcAliasId=metricCalcDef[17].mcId; + metricCalcDef[20].mcCalc=metricCalcBlockCapacity; + metricCalcDef[20].mcUnits=muBytes; - *mcnum = 17; + *mcnum = 21; *mc = metricCalcDef; return 0; } @@ -692,5 +754,144 @@ } /* ---------------------------------------------------------------------------*/ +/* Virtual Block IO Stats */ +/* ---------------------------------------------------------------------------*/ + +size_t metricCalcVirtualBlockIOStats( MetricValue *mv, + int mnum, + void *v, + size_t vlen ) { + +#ifdef DEBUG + fprintf(stderr,"--- %s(%i) : Calculate VirtualBlockIOStats\n", + __FILE__,__LINE__); +#endif + /* plain copy */ + if (mv && (vlen>=mv->mvDataLength) && (mnum==1) ) { + memcpy(v,mv->mvData,mv->mvDataLength); + return mv->mvDataLength; + } + return -1; +} + +/* ---------------------------------------------------------------------------*/ +/* BlockRead */ +/* ---------------------------------------------------------------------------*/ + +size_t metricCalcBlockRead( MetricValue *mv, + int mnum, + void *v, + size_t vlen ) +{ + unsigned long long br = 0; + unsigned long long b1 = 0; + unsigned long long b2 = 0; + +#ifdef DEBUG + fprintf(stderr,"--- %s(%i) : Calculate BlockRead\n", + __FILE__,__LINE__); +#endif + if ( mv && (vlen>=sizeof(unsigned long long)) && (mnum>=1) ) { + + b1 = kvm_getData(mv[0].mvData, BLK_READ); + if( mnum > 1 ) { + b2 = kvm_getData(mv[mnum-1].mvData, BLK_READ); + br = b1-b2; + } + else { br = b1; } + + memcpy(v,&br,sizeof(unsigned long long)); + return sizeof(unsigned long long); + } + return -1; +} + +/* ---------------------------------------------------------------------------*/ +/* BlockWrite */ +/* ---------------------------------------------------------------------------*/ + +size_t metricCalcBlockWrite( MetricValue *mv, + int mnum, + void *v, + size_t vlen ) +{ + unsigned long long br = 0; + unsigned long long b1 = 0; + unsigned long long b2 = 0; + +#ifdef DEBUG + fprintf(stderr,"--- %s(%i) : Calculate BlockWrite\n", + __FILE__,__LINE__); +#endif + if ( mv && (vlen>=sizeof(unsigned long long)) && (mnum>=1) ) { + + b1 = kvm_getData(mv[0].mvData, BLK_WRITE); + if( mnum > 1 ) { + b2 = kvm_getData(mv[mnum-1].mvData, BLK_WRITE); + br = b1-b2; + } + else { br = b1; } + + memcpy(v,&br,sizeof(unsigned long long)); + return sizeof(unsigned long long); + } + return -1; +} + +/* ---------------------------------------------------------------------------*/ +/* BlockCapacity */ +/* ---------------------------------------------------------------------------*/ + +size_t metricCalcBlockCapacity( MetricValue *mv, + int mnum, + void *v, + size_t vlen ) +{ + unsigned long long ct = 0; + +#ifdef DEBUG + fprintf(stderr,"--- %s(%i) : Calculate BlockCapacity\n", + __FILE__,__LINE__); +#endif + if ( mv && (vlen>=sizeof(unsigned long long)) && (mnum>=1) ) { + + ct = kvm_getData(mv[0].mvData, BLK_CAP); + + memcpy(v,&ct,sizeof(unsigned long long)); + return sizeof(unsigned long long); + } + return -1; +} + +/* ---------------------------------------------------------------------------*/ +/* tool function on internal raw metrics */ +/* ---------------------------------------------------------------------------*/ + +unsigned long long kvm_getData(char * data, char index) +{ + char * hlp = NULL; + char * end = NULL; + char bytes[128]; + unsigned long long val = 0; + int i = 0; + + hlp = data; + if ((end = strchr(hlp, ':')) != NULL) { + for (i = 0; i < index; i++) { + hlp = ++end; + if ((end = strchr(hlp, ':')) == NULL) { + return val; + } + } + + memset(bytes, 0, sizeof(bytes)); + strncpy(bytes, hlp, strlen(hlp) - strlen(end)); + val = strtoll(bytes, (char**) NULL, 10); + } + + return val; +} + +/* ---------------------------------------------------------------------------*/ /* end of repositoryKvm.c */ /* ---------------------------------------------------------------------------*/ Index: metricVirt.h =================================================================== RCS file: /cvsroot/sblim/gather/plugin/metricVirt.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- metricVirt.h 7 Oct 2011 00:08:52 -0000 1.7 +++ metricVirt.h 29 Nov 2011 06:28:09 -0000 1.8 @@ -1,7 +1,7 @@ /* * $Id$ * - * (C) Copyright IBM Corp. 2009 + * (C) Copyright IBM Corp. 2009, 2011 * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE @@ -33,6 +33,15 @@ #define VIRT_NOUPD 1 #define VIRT_FAIL -1 +struct vdisk_type { + char * source; + char * target; + unsigned long long read; + unsigned long long write; + unsigned long long capacity; + struct vdisk_type * next; +}; + struct node_statistics_type { int num_active_domains; int num_inactive_domains; @@ -51,6 +60,7 @@ unsigned char state[MAX_DOMAINS]; unsigned long long cpu_used[MAX_DOMAINS]; unsigned long long cpu_ready[MAX_DOMAINS]; + struct vdisk_type * blkio[MAX_DOMAINS]; } domain_statistics; int testHypervisor(int type); @@ -63,5 +73,6 @@ MetricRetriever virtMetricRetrVirtualSystemState; MetricRetriever virtMetricRetrCPUUsedTimeCounter; MetricRetriever virtMetricRetrCPUReadyTimeCounter; +MetricRetriever virtMetricRetrVirtualBlockIOStats; #endif Index: metricKvm.c =================================================================== RCS file: /cvsroot/sblim/gather/plugin/metricKvm.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- metricKvm.c 12 May 2011 00:46:29 -0000 1.6 +++ metricKvm.c 29 Nov 2011 06:28:09 -0000 1.7 @@ -1,7 +1,8 @@ /* * $Id$ * - * (C) Copyright IBM Corp. 2009 + * (C) Copyright IBM Corp. 2009, 2011 + * * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE @@ -45,7 +46,7 @@ #include <ctype.h> /* --- metric callback retrievers to be exported --- */ -static MetricDefinition metricDef[10]; +static MetricDefinition metricDef[11]; /* --- required plugin functions --- */ int _DefinedMetrics(MetricRegisterId * mr, @@ -156,8 +157,16 @@ metricDef[9].mdSampleInterval = 60; metricDef[9].mproc = virtMetricRetrCPUReadyTimeCounter; metricDef[9].mdeal = free; + + metricDef[10].mdVersion = MD_VERSION; + metricDef[10].mdName = "_VirtualBlockIOStats"; + metricDef[10].mdReposPluginName = "librepositoryKvm.so"; + metricDef[10].mdId = mr(pluginname, metricDef[10].mdName); + metricDef[10].mdSampleInterval = 60; + metricDef[10].mproc = virtMetricRetrVirtualBlockIOStats; + metricDef[10].mdeal = free; - *mdnum = 10; + *mdnum = 11; } else { *mdnum = 0; } |