diskstats and slabinfo

This commit is contained in:
albert
2003-06-08 17:28:06 +00:00
parent 87402486f7
commit 5c99a21b72
10 changed files with 395 additions and 37 deletions

View File

@ -10,7 +10,7 @@ global:
Hertz; smp_num_cpus;
sprint_uptime; uptime; user_from_uid; print_uptime; loadavg;
pretty_print_signals; print_given_signals; unix_print_signals; signal_name_to_number; signal_number_to_name;
meminfo; vminfo; getstat;
meminfo; vminfo; getstat; getdiskstat; getslabinfo;
kb_active; kb_inactive; kb_main_buffers; kb_main_cached;
kb_main_free; kb_main_total; kb_main_used; kb_swap_free;
kb_swap_total; kb_swap_used; kb_main_shared;

View File

@ -4,8 +4,10 @@
// This file is placed under the conditions of the GNU Library
// General Public License, version 2, or any later version.
// See file COPYING for information on distribution conditions.
/* File for parsing top-level /proc entities. */
//
// File for parsing top-level /proc entities. */
//
// June 2003, Fabian Frederick, disk and slab info
#include <stdio.h>
#include <stdlib.h>
@ -172,7 +174,9 @@ static void old_Hertz_hack(void){
#define AT_CLKTCK 17 /* frequency of times() */
#endif
extern char** environ;
#define NOTE_NOT_FOUND 42
//extern char** environ;
/* for ELF executables, notes are pushed before environment and args */
static unsigned long find_elf_note(unsigned long findme){
@ -182,7 +186,7 @@ static unsigned long find_elf_note(unsigned long findme){
if(ep[0]==findme) return ep[1];
ep+=2;
}
return 42;
return NOTE_NOT_FOUND;
}
static void init_libproc(void) __attribute__((constructor));
@ -195,7 +199,7 @@ static void init_libproc(void){
if(linux_version_code > LINUX_VERSION(2, 4, 0)){
Hertz = find_elf_note(AT_CLKTCK);
if(Hertz!=42) return;
if(Hertz!=NOTE_NOT_FOUND) return;
fprintf(stderr, "2.4 kernel w/o ELF notes? -- report to albert@users.sf.net\n");
}
old_Hertz_hack();
@ -651,3 +655,105 @@ nextline:
}
}
///////////////////////////////////////////////////////////////////////
// based on Fabian Frederick's /proc/diskstats parser
static unsigned int getFileLines(const char* szFile){
char szBuffer[1024];
FILE *fdiskStat;
int lines=0;
if ((fdiskStat=fopen (szFile,"rb"))){
while (fgets(szBuffer, 1024, fdiskStat)){
lines++;
}
fclose(fdiskStat);
}
return lines;
}
unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **partitions){
FILE* fd;
buff[BUFFSIZE-1] = 0;
int units,
i,
disk_type,
disk_num,
cDisk=0,
cPartition=0;
*disks = NULL;
*partitions = NULL;
units = getFileLines("/proc/diskstats");
fd = fopen("/proc/diskstats", "rb");
if(!fd) crash("/proc/diskstats");
for (i=0; i<units; i++){
if (!fgets(buff,BUFFSIZE-1,fd)){
fclose(fd);
crash("/proc/diskstats");
}
sscanf(buff, " %d %d", &disk_type, &disk_num);
if (disk_num == 0){
(*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat));
sscanf(buff, " %d %*d %15s %u %u %llu %u %u %u %llu %u %u %u %u",
&(*disks)[cDisk].disk_type,
//&unused,
(*disks)[cDisk].disk_name,
&(*disks)[cDisk].reads,
&(*disks)[cDisk].merged_reads,
&(*disks)[cDisk].reads_sectors,
&(*disks)[cDisk].milli_reading,
&(*disks)[cDisk].writes,
&(*disks)[cDisk].merged_writes,
&(*disks)[cDisk].written_sectors,
&(*disks)[cDisk].milli_writing,
&(*disks)[cDisk].inprogress_IO,
&(*disks)[cDisk].milli_spent_IO,
&(*disks)[cDisk].weighted_milli_spent_IO
);
cDisk++;
}else{
(*partitions) = realloc(*partitions, (cPartition+1)*sizeof(struct partition_stat));
fflush(stdout);
sscanf(buff, " %d %d %15s %u %llu %u %u",
&(*partitions)[cPartition].disk_type,
&(*partitions)[cPartition].partition_num,
(*partitions)[cPartition].partition_name,
&(*partitions)[cPartition].reads,
&(*partitions)[cPartition].reads_sectors,
&(*partitions)[cPartition].writes,
&(*partitions)[cPartition].requested_writes
);
(*partitions)[cPartition++].parent_disk = &((*disks)[cDisk-1]);
}
}
fclose(fd);
return cDisk;
}
/////////////////////////////////////////////////////////////////////////////
// based on Fabian Frederick's /proc/slabinfo parser
unsigned int getslabinfo (struct slab_cache **slab){
FILE* fd;
int cSlab = 0;
buff[BUFFSIZE-1] = 0;
*slab = NULL;
fd = fopen("/proc/slabinfo", "rb");
if(!fd) crash("/proc/slabinfo");
while (fgets(buff,BUFFSIZE-1,fd)){
if(!memcmp("slabinfo - version:",buff,19)) continue; // skip header
if(*buff == '#') continue; // skip comments
(*slab) = realloc(*slab, (cSlab+1)*sizeof(struct slab_cache));
sscanf(buff, "%47s %u %u %u %u", // allow 47; max seen is 24
(*slab)[cSlab].name,
&(*slab)[cSlab].active_objs,
&(*slab)[cSlab].num_objs,
&(*slab)[cSlab].objsize,
&(*slab)[cSlab].objperslab
) ;
cSlab++;
}
fclose(fd);
return cSlab;
}

View File

@ -88,5 +88,44 @@ extern unsigned long vm_allocstall;
extern void vminfo(void);
typedef struct disk_stat{
unsigned int disk_type;
char disk_name [16];
unsigned reads;
unsigned merged_reads;
unsigned long long reads_sectors;
unsigned milli_reading;
unsigned writes;
unsigned merged_writes;
unsigned long long written_sectors;
unsigned milli_writing;
unsigned inprogress_IO;
unsigned milli_spent_IO;
unsigned weighted_milli_spent_IO;
}disk_stat;
typedef struct partition_stat{
unsigned int disk_type;
unsigned int partition_num;
char partition_name [16];
struct disk_stat* parent_disk;
unsigned reads;
unsigned long long reads_sectors;
unsigned writes;
unsigned requested_writes;
}partition_stat;
extern unsigned int getdiskstat (struct disk_stat**,struct partition_stat**);
typedef struct slab_cache{
char name[48];
unsigned active_objs;
unsigned num_objs;
unsigned objsize;
unsigned objperslab;
}slab_cache;
extern unsigned int getslabinfo (struct slab_cache**);
EXTERN_C_END
#endif /* SYSINFO_H */