diskstats and slabinfo
This commit is contained in:
@ -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;
|
||||
|
116
proc/sysinfo.c
116
proc/sysinfo.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user