From bb42c93df494e77d15badfe22014df20636f396c Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Sun, 5 Dec 2004 07:10:18 +0000 Subject: [PATCH] linux 2.6 iostats --- src/os/linux/linux_sigar.c | 78 ++++++++++++++++++++++++++++++++++++++ src/os/linux/sigar_os.h | 6 +++ 2 files changed, 84 insertions(+) diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index 8c6f2631..33ff5337 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -23,6 +23,8 @@ #define PROC_PSTAT "/stat" #define PROC_PSTATUS "/status" +#define SYS_BLOCK "/sys/block" + /* * /proc/self/stat fields: * 1 - pid @@ -103,6 +105,7 @@ int sigar_os_open(sigar_t **sigar) { char buffer[BUFSIZ], *ptr; int status = sigar_file2str(PROC_STAT, buffer, sizeof(buffer)); + struct stat sb; *sigar = malloc(sizeof(**sigar)); @@ -124,6 +127,13 @@ int sigar_os_open(sigar_t **sigar) (*sigar)->ht_enabled = -1; + if (stat(SYS_BLOCK, &sb) == 0) { + (*sigar)->iostat = IOSTAT_SYS; + } + else { + (*sigar)->iostat = IOSTAT_NONE; + } + return SIGAR_OK; } @@ -996,6 +1006,66 @@ int sigar_file_system_list_get(sigar_t *sigar, return SIGAR_OK; } +static int get_iostat_sys(sigar_t *sigar, + const char *dirname, + sigar_file_system_usage_t *fsusage) +{ + /* open source is really great */ + /* see how intuitive this is */ + struct mntent ent; + char buf[1025]; /* buffer for strings within ent */ + char stat[1025]; + FILE *fp; + char *name, *fsdev = NULL, *ptr; + int partition, status; + + if (!(fp = setmntent(MOUNTED, "r"))) { + return errno; + } + + while (getmntent_r(fp, &ent, buf, sizeof(buf))) { + if (strEQ(ent.mnt_dir, dirname)) { + fsdev = ent.mnt_fsname; + break; + } + } + + endmntent(fp); + + if (!fsdev) { + return ENOENT; + } + + if (!strnEQ(fsdev, "/dev/", 5)) { + return ENOENT; + } + + fsdev += 5; + name = fsdev; + + while (!sigar_isdigit(*fsdev)) { + fsdev++; + } + + partition = strtoul(fsdev, NULL, 0); + *fsdev = '\0'; + + sprintf(stat, SYS_BLOCK "/%s/%s%d/stat", name, name, partition); + + status = sigar_file2str(stat, buf, sizeof(buf)); + if (status != SIGAR_OK) { + return status; + } + + ptr = buf; + ptr = sigar_skip_token(ptr); + fsusage->disk_reads = sigar_strtoul(ptr); + ptr = sigar_skip_token(ptr); + fsusage->disk_writes = sigar_strtoul(ptr); + + return SIGAR_OK; +} + #include #define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \ @@ -1018,6 +1088,14 @@ int sigar_file_system_usage_get(sigar_t *sigar, fsusage->free_files = buf.f_ffree; fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage); + if (sigar->iostat == IOSTAT_SYS) { + if (get_iostat_sys(sigar, dirname, fsusage) == SIGAR_OK) { + return SIGAR_OK; + } + } + + fsusage->disk_reads = fsusage->disk_writes = 0; + return SIGAR_OK; } diff --git a/src/os/linux/sigar_os.h b/src/os/linux/sigar_os.h index 09019cca..592e62ae 100644 --- a/src/os/linux/sigar_os.h +++ b/src/os/linux/sigar_os.h @@ -30,6 +30,11 @@ typedef struct { char state; } linux_proc_stat_t; +typedef enum { + IOSTAT_NONE, + IOSTAT_SYS /* 2.6 */ +} linux_iostat_e; + struct sigar_t { SIGAR_T_BASE; int ram; @@ -37,6 +42,7 @@ struct sigar_t { linux_proc_stat_t last_proc_stat; int ht_enabled; int lcpu; + linux_iostat_e iostat; }; #define HAVE_STRERROR_R