disk metrics for 2.4 kernel
This commit is contained in:
parent
bb42c93df4
commit
72b3a4c55b
|
@ -24,6 +24,7 @@
|
||||||
#define PROC_PSTATUS "/status"
|
#define PROC_PSTATUS "/status"
|
||||||
|
|
||||||
#define SYS_BLOCK "/sys/block"
|
#define SYS_BLOCK "/sys/block"
|
||||||
|
#define PROC_PARTITIONS "/proc/partitions"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* /proc/self/stat fields:
|
* /proc/self/stat fields:
|
||||||
|
@ -130,6 +131,10 @@ int sigar_os_open(sigar_t **sigar)
|
||||||
if (stat(SYS_BLOCK, &sb) == 0) {
|
if (stat(SYS_BLOCK, &sb) == 0) {
|
||||||
(*sigar)->iostat = IOSTAT_SYS;
|
(*sigar)->iostat = IOSTAT_SYS;
|
||||||
}
|
}
|
||||||
|
else if (stat(PROC_PARTITIONS, &sb) == 0) {
|
||||||
|
/* XXX file exists does not mean is has the fields */
|
||||||
|
(*sigar)->iostat = IOSTAT_PARTITIONS;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
(*sigar)->iostat = IOSTAT_NONE;
|
(*sigar)->iostat = IOSTAT_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1006,42 +1011,57 @@ int sigar_file_system_list_get(sigar_t *sigar,
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_iostat_sys(sigar_t *sigar,
|
static char *get_fsdev(sigar_t *sigar,
|
||||||
const char *dirname,
|
const char *dirname,
|
||||||
sigar_file_system_usage_t *fsusage)
|
char *fsdev)
|
||||||
{
|
{
|
||||||
/* open source is really great */
|
/* XXX cache this shit */
|
||||||
/* see how intuitive this is */
|
|
||||||
struct mntent ent;
|
struct mntent ent;
|
||||||
char buf[1025]; /* buffer for strings within ent */
|
char buf[1025]; /* buffer for strings within ent */
|
||||||
char stat[1025];
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *name, *fsdev = NULL, *ptr;
|
char *ptr = NULL;
|
||||||
int partition, status;
|
|
||||||
|
|
||||||
if (!(fp = setmntent(MOUNTED, "r"))) {
|
if (!(fp = setmntent(MOUNTED, "r"))) {
|
||||||
return errno;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (getmntent_r(fp, &ent, buf, sizeof(buf))) {
|
while (getmntent_r(fp, &ent, buf, sizeof(buf))) {
|
||||||
if (strEQ(ent.mnt_dir, dirname)) {
|
if (strEQ(ent.mnt_dir, dirname)) {
|
||||||
fsdev = ent.mnt_fsname;
|
ptr = ent.mnt_fsname;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endmntent(fp);
|
endmntent(fp);
|
||||||
|
|
||||||
if (!fsdev) {
|
if (!ptr) {
|
||||||
return ENOENT;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strnEQ(fsdev, "/dev/", 5)) {
|
if (!strnEQ(ptr, "/dev/", 5)) {
|
||||||
return ENOENT;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsdev += 5;
|
ptr += 5;
|
||||||
name = fsdev;
|
|
||||||
|
strcpy(fsdev, ptr);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_iostat_sys(sigar_t *sigar,
|
||||||
|
const char *dirname,
|
||||||
|
sigar_file_system_usage_t *fsusage)
|
||||||
|
{
|
||||||
|
char stat[1025], dev[1025];
|
||||||
|
char *name, *ptr, *fsdev;
|
||||||
|
int partition, status;
|
||||||
|
|
||||||
|
name = fsdev = get_fsdev(sigar, dirname, dev);
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
while (!sigar_isdigit(*fsdev)) {
|
while (!sigar_isdigit(*fsdev)) {
|
||||||
fsdev++;
|
fsdev++;
|
||||||
|
@ -1052,12 +1072,12 @@ static int get_iostat_sys(sigar_t *sigar,
|
||||||
|
|
||||||
sprintf(stat, SYS_BLOCK "/%s/%s%d/stat", name, name, partition);
|
sprintf(stat, SYS_BLOCK "/%s/%s%d/stat", name, name, partition);
|
||||||
|
|
||||||
status = sigar_file2str(stat, buf, sizeof(buf));
|
status = sigar_file2str(stat, dev, sizeof(dev));
|
||||||
if (status != SIGAR_OK) {
|
if (status != SIGAR_OK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = buf;
|
ptr = dev;
|
||||||
ptr = sigar_skip_token(ptr);
|
ptr = sigar_skip_token(ptr);
|
||||||
fsusage->disk_reads = sigar_strtoul(ptr);
|
fsusage->disk_reads = sigar_strtoul(ptr);
|
||||||
ptr = sigar_skip_token(ptr);
|
ptr = sigar_skip_token(ptr);
|
||||||
|
@ -1066,6 +1086,49 @@ static int get_iostat_sys(sigar_t *sigar,
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_iostat_procp(sigar_t *sigar,
|
||||||
|
const char *dirname,
|
||||||
|
sigar_file_system_usage_t *fsusage)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[1025], dev[1025];
|
||||||
|
char *name, *ptr;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
name = get_fsdev(sigar, dirname, dev);
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(name);
|
||||||
|
|
||||||
|
if (!(fp = fopen(PROC_PARTITIONS, "r"))) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)fgets(buffer, sizeof(buffer), fp); /* skip header */
|
||||||
|
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
||||||
|
/* major, minor, #blocks */
|
||||||
|
ptr = sigar_skip_multiple_token(ptr, 3);
|
||||||
|
SIGAR_SKIP_SPACE(ptr);
|
||||||
|
|
||||||
|
if (strnEQ(ptr, name, len)) {
|
||||||
|
ptr = sigar_skip_token(ptr); /* name */
|
||||||
|
fsusage->disk_reads = sigar_strtoul(ptr); /* rio */
|
||||||
|
/* rmerge, rsect, ruse */
|
||||||
|
ptr = sigar_skip_multiple_token(ptr, 3);
|
||||||
|
fsusage->disk_writes = sigar_strtoul(ptr); /* wio */
|
||||||
|
fclose(fp);
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
|
|
||||||
#define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \
|
#define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \
|
||||||
|
@ -1088,10 +1151,30 @@ int sigar_file_system_usage_get(sigar_t *sigar,
|
||||||
fsusage->free_files = buf.f_ffree;
|
fsusage->free_files = buf.f_ffree;
|
||||||
fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
|
fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
|
||||||
|
|
||||||
if (sigar->iostat == IOSTAT_SYS) {
|
/*
|
||||||
|
* 2.2 has metrics /proc/stat, but wtf is the device mapping?
|
||||||
|
* 2.4 has /proc/partitions w/ the metrics.
|
||||||
|
* 2.6 has /proc/partitions w/o the metrics.
|
||||||
|
* instead the metrics are within the /proc-like /sys filesystem.
|
||||||
|
* also has /proc/diskstats
|
||||||
|
*/
|
||||||
|
switch (sigar->iostat) {
|
||||||
|
case IOSTAT_SYS:
|
||||||
if (get_iostat_sys(sigar, dirname, fsusage) == SIGAR_OK) {
|
if (get_iostat_sys(sigar, dirname, fsusage) == SIGAR_OK) {
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case IOSTAT_PARTITIONS:
|
||||||
|
if (get_iostat_procp(sigar, dirname, fsusage) == SIGAR_OK) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* case IOSTAT_SOME_OTHER_WIERD_THING:
|
||||||
|
* break;
|
||||||
|
*/
|
||||||
|
case IOSTAT_NONE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsusage->disk_reads = fsusage->disk_writes = 0;
|
fsusage->disk_reads = fsusage->disk_writes = 0;
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
IOSTAT_NONE,
|
IOSTAT_NONE,
|
||||||
|
IOSTAT_PARTITIONS,
|
||||||
IOSTAT_SYS /* 2.6 */
|
IOSTAT_SYS /* 2.6 */
|
||||||
} linux_iostat_e;
|
} linux_iostat_e;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue