Lines 81-86
Link Here
|
81 |
|
81 |
|
82 |
static char StatBuf[ STATBUFSIZE ]; |
82 |
static char StatBuf[ STATBUFSIZE ]; |
83 |
static char VmStatBuf[ STATBUFSIZE ]; |
83 |
static char VmStatBuf[ STATBUFSIZE ]; |
|
|
84 |
static char IOStatBuf[ STATBUFSIZE ]; /* Buffer for /proc/diskstats */ |
84 |
static int Dirty = 0; |
85 |
static int Dirty = 0; |
85 |
|
86 |
|
86 |
/* We have observed deviations of up to 5% in the accuracy of the timer |
87 |
/* We have observed deviations of up to 5% in the accuracy of the timer |
Lines 113-118
Link Here
|
113 |
static int processDisk( char* tag, char* buf, const char* label, int idx ); |
114 |
static int processDisk( char* tag, char* buf, const char* label, int idx ); |
114 |
static void processStat( void ); |
115 |
static void processStat( void ); |
115 |
static int processDiskIO( const char* buf ); |
116 |
static int processDiskIO( const char* buf ); |
|
|
117 |
static int process26DiskIO( const char* buf ); |
116 |
static void cleanupDiskList( void ); |
118 |
static void cleanupDiskList( void ); |
117 |
|
119 |
|
118 |
static int initStatDisk( char* tag, char* buf, const char* label, |
120 |
static int initStatDisk( char* tag, char* buf, const char* label, |
Lines 274-279
Link Here
|
274 |
return 0; |
276 |
return 0; |
275 |
} |
277 |
} |
276 |
|
278 |
|
|
|
279 |
static int process26DiskIO( const char* buf ) |
280 |
{ |
281 |
/* Process values from /proc/diskstats (Linux >= 2.6.x) */ |
282 |
|
283 |
/* For each disk /proc/diskstats includes lines as follows: |
284 |
* 3 0 hda 1314558 74053 26451438 14776742 1971172 4607401 52658448 202855090 0 9597019 217637839 |
285 |
* 3 1 hda1 178 360 0 0 |
286 |
* 3 2 hda2 354 360 0 0 |
287 |
* 3 3 hda3 354 360 0 0 |
288 |
* 3 4 hda4 0 0 0 0 |
289 |
* 3 5 hda5 529506 9616000 4745856 37966848 |
290 |
* |
291 |
* - See Documentation/iostats.txt for details on the changes |
292 |
*/ |
293 |
int major, minor; |
294 |
char devname[16]; |
295 |
unsigned long total, |
296 |
rio, rmrg, rblk, rtim, |
297 |
wio, wmrg, wblk, wtim, |
298 |
ioprog, iotim, iotimw; |
299 |
DiskIOInfo *ptr = DiskIO; |
300 |
DiskIOInfo *last = 0; |
301 |
char sensorName[128]; |
302 |
|
303 |
switch (sscanf(buf, "%d %d %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", |
304 |
&major, &minor, devname, |
305 |
&rio, &rmrg, &rblk, &rtim, |
306 |
&wio, &wmrg, &wblk, &wtim, |
307 |
&ioprog, &iotim, &iotimw)) |
308 |
{ |
309 |
case 7: |
310 |
/* Partition stats entry */ |
311 |
/* Adjust read fields rio rmrg rblk rtim -> rio rblk wio wblk */ |
312 |
wblk = rtim; |
313 |
wio = rblk; |
314 |
rblk = rmrg; |
315 |
|
316 |
total = rio + wio; |
317 |
|
318 |
break; |
319 |
case 14: |
320 |
/* Disk stats entry */ |
321 |
total = rio + wio; |
322 |
|
323 |
break; |
324 |
default: |
325 |
/* Something unexepected */ |
326 |
return -1; |
327 |
} |
328 |
|
329 |
last = 0; |
330 |
ptr = DiskIO; |
331 |
while (ptr) |
332 |
{ |
333 |
if (ptr->major == major && ptr->minor == minor) |
334 |
{ |
335 |
/* The IO device has already been registered. */ |
336 |
ptr->total.delta = total - ptr->total.old; |
337 |
ptr->total.old = total; |
338 |
ptr->rio.delta = rio - ptr->rio.old; |
339 |
ptr->rio.old = rio; |
340 |
ptr->wio.delta = wio - ptr->wio.old; |
341 |
ptr->wio.old = wio; |
342 |
ptr->rblk.delta = rblk - ptr->rblk.old; |
343 |
ptr->rblk.old = rblk; |
344 |
ptr->wblk.delta = wblk - ptr->wblk.old; |
345 |
ptr->wblk.old = wblk; |
346 |
ptr->alive = 1; |
347 |
break; |
348 |
} |
349 |
|
350 |
last = ptr; |
351 |
ptr = ptr->next; |
352 |
} |
353 |
|
354 |
if (!ptr) |
355 |
{ |
356 |
/* The IO device has not been registered yet. We need to add it. */ |
357 |
ptr = (DiskIOInfo*)malloc( sizeof( DiskIOInfo ) ); |
358 |
ptr->major = major; |
359 |
ptr->minor = minor; |
360 |
ptr->total.delta = 0; |
361 |
ptr->total.old = total; |
362 |
ptr->rio.delta = 0; |
363 |
ptr->rio.old = rio; |
364 |
ptr->wio.delta = 0; |
365 |
ptr->wio.old = wio; |
366 |
ptr->rblk.delta = 0; |
367 |
ptr->rblk.old = rblk; |
368 |
ptr->wblk.delta = 0; |
369 |
ptr->wblk.old = wblk; |
370 |
ptr->alive = 1; |
371 |
ptr->next = 0; |
372 |
if (last) |
373 |
{ |
374 |
/* Append new entry at end of list. */ |
375 |
last->next = ptr; |
376 |
} |
377 |
else |
378 |
{ |
379 |
/* List is empty, so we insert the fist element into the list. */ |
380 |
DiskIO = ptr; |
381 |
} |
382 |
|
383 |
sprintf(sensorName, "disk/%d:%d/total", major, minor); |
384 |
registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo, |
385 |
StatSM); |
386 |
sprintf(sensorName, "disk/%d:%d/rio", major, minor); |
387 |
registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo, |
388 |
StatSM); |
389 |
sprintf(sensorName, "disk/%d:%d/wio", major, minor); |
390 |
registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo, |
391 |
StatSM); |
392 |
sprintf(sensorName, "disk/%d:%d/rblk", major, minor); |
393 |
registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo, |
394 |
StatSM); |
395 |
sprintf(sensorName, "disk/%d:%d/wblk", major, minor); |
396 |
registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo, |
397 |
StatSM); |
398 |
} |
399 |
|
400 |
return 0; |
401 |
} |
402 |
|
277 |
static void cleanupDiskList( void ) |
403 |
static void cleanupDiskList( void ) |
278 |
{ |
404 |
{ |
279 |
DiskIOInfo* ptr = DiskIO; |
405 |
DiskIOInfo* ptr = DiskIO; |
Lines 323-328
Link Here
|
323 |
char tag[ 32 ]; |
449 |
char tag[ 32 ]; |
324 |
char* statBufP = StatBuf; |
450 |
char* statBufP = StatBuf; |
325 |
char* vmstatBufP = VmStatBuf; |
451 |
char* vmstatBufP = VmStatBuf; |
|
|
452 |
char* iostatBufP = IOStatBuf; |
326 |
|
453 |
|
327 |
sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 ); |
454 |
sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 ); |
328 |
sprintf( tagFormat, "%%%ds", (int)sizeof( tag ) - 1 ); |
455 |
sprintf( tagFormat, "%%%ds", (int)sizeof( tag ) - 1 ); |
Lines 397-402
Link Here
|
397 |
} |
524 |
} |
398 |
} |
525 |
} |
399 |
|
526 |
|
|
|
527 |
/* Process values from /proc/diskstats (Linux >= 2.6.x) */ |
528 |
while (sscanf(iostatBufP, format, buf) == 1) |
529 |
{ |
530 |
buf[sizeof(buf) - 1] = '\0'; |
531 |
iostatBufP += strlen(buf) + 1; /* move IOstatBufP to next line */ |
532 |
|
533 |
process26DiskIO(buf); |
534 |
} |
535 |
|
400 |
/* save exact time inverval between this and the last read of /proc/stat */ |
536 |
/* save exact time inverval between this and the last read of /proc/stat */ |
401 |
timeInterval = currSampling.tv_sec - lastSampling.tv_sec + |
537 |
timeInterval = currSampling.tv_sec - lastSampling.tv_sec + |
402 |
( currSampling.tv_usec - lastSampling.tv_usec ) / 1000000.0; |
538 |
( currSampling.tv_usec - lastSampling.tv_usec ) / 1000000.0; |
Lines 439-444
Link Here
|
439 |
* |
575 |
* |
440 |
* Linux kernel >= 2.4.0 have one or more disk_io: lines instead of |
576 |
* Linux kernel >= 2.4.0 have one or more disk_io: lines instead of |
441 |
* the disk_* lines. |
577 |
* the disk_* lines. |
|
|
578 |
* |
579 |
* Linux kernel >= 2.6.x(?) have disk I/O stats in /proc/diskstats |
580 |
* and no disk relevant lines are found in /proc/stat |
442 |
*/ |
581 |
*/ |
443 |
|
582 |
|
444 |
char format[ 32 ]; |
583 |
char format[ 32 ]; |
Lines 447-452
Link Here
|
447 |
char tag[ 32 ]; |
586 |
char tag[ 32 ]; |
448 |
char* statBufP = StatBuf; |
587 |
char* statBufP = StatBuf; |
449 |
char* vmstatBufP = VmStatBuf; |
588 |
char* vmstatBufP = VmStatBuf; |
|
|
589 |
char* iostatBufP = IOStatBuf; |
450 |
|
590 |
|
451 |
StatSM = sm; |
591 |
StatSM = sm; |
452 |
|
592 |
|
Lines 466-472
Link Here
|
466 |
registerMonitor( "cpu/nice", "integer", printCPUNice, printCPUNiceInfo, StatSM ); |
606 |
registerMonitor( "cpu/nice", "integer", printCPUNice, printCPUNiceInfo, StatSM ); |
467 |
registerMonitor( "cpu/sys", "integer", printCPUSys, printCPUSysInfo, StatSM ); |
607 |
registerMonitor( "cpu/sys", "integer", printCPUSys, printCPUSysInfo, StatSM ); |
468 |
registerMonitor( "cpu/idle", "integer", printCPUIdle, printCPUIdleInfo, StatSM ); |
608 |
registerMonitor( "cpu/idle", "integer", printCPUIdle, printCPUIdleInfo, StatSM ); |
469 |
} else if ( strncmp( "cpu", tag, 3 ) == 0 ) { |
609 |
} else if ( strncmp( "cpu", tag, 3 ) == 0 ) { |
470 |
char cmdName[ 24 ]; |
610 |
char cmdName[ 24 ]; |
471 |
/* Load for each SMP CPU */ |
611 |
/* Load for each SMP CPU */ |
472 |
int id; |
612 |
int id; |
Lines 562-567
Link Here
|
562 |
} |
702 |
} |
563 |
} |
703 |
} |
564 |
|
704 |
|
|
|
705 |
/* Process values from /proc/diskstats (Linux >= 2.6.x) */ |
706 |
while (sscanf(iostatBufP, format, buf) == 1) |
707 |
{ |
708 |
buf[sizeof(buf) - 1] = '\0'; |
709 |
iostatBufP += strlen(buf) + 1; /* move IOstatBufP to next line */ |
710 |
|
711 |
process26DiskIO(buf); |
712 |
} |
713 |
|
565 |
if ( CPUCount > 0 ) |
714 |
if ( CPUCount > 0 ) |
566 |
SMPLoad = (CPULoadInfo*)malloc( sizeof( CPULoadInfo ) * CPUCount ); |
715 |
SMPLoad = (CPULoadInfo*)malloc( sizeof( CPULoadInfo ) * CPUCount ); |
567 |
|
716 |
|
Lines 579-585
Link Here
|
579 |
|
728 |
|
580 |
free( OldIntr ); |
729 |
free( OldIntr ); |
581 |
OldIntr = 0; |
730 |
OldIntr = 0; |
582 |
|
731 |
|
583 |
free( Intr ); |
732 |
free( Intr ); |
584 |
Intr = 0; |
733 |
Intr = 0; |
585 |
} |
734 |
} |
Lines 622-627
Link Here
|
622 |
close( fd ); |
771 |
close( fd ); |
623 |
VmStatBuf[ n ] = '\0'; |
772 |
VmStatBuf[ n ] = '\0'; |
624 |
|
773 |
|
|
|
774 |
/* Linux >= 2.6.x has disk I/O stats in /proc/diskstats */ |
775 |
IOStatBuf[ 0 ] = '\0'; |
776 |
if ( ( fd = open( "/proc/diskstats", O_RDONLY ) ) < 0 ) |
777 |
return 0; /* failure is okay, only exists for Linux >= 2.6.x */ |
778 |
|
779 |
if ( ( n = read( fd, IOStatBuf, STATBUFSIZE - 1 ) ) == STATBUFSIZE - 1 ) { |
780 |
log_error( "Internal buffer too small to read \'/proc/diskstats\'" ); |
781 |
|
782 |
close( fd ); |
783 |
return -1; |
784 |
} |
785 |
|
786 |
close( fd ); |
787 |
IOStatBuf[ n ] = '\0'; |
788 |
|
625 |
return 0; |
789 |
return 0; |
626 |
} |
790 |
} |
627 |
|
791 |
|