implement disk metrics
This commit is contained in:
parent
35dfc19937
commit
5630d9a48a
|
@ -1,7 +1,7 @@
|
||||||
#include "sigar.h"
|
#include "sigar.h"
|
||||||
#include "sigar_private.h"
|
#include "sigar_private.h"
|
||||||
#include "sigar_os.h"
|
|
||||||
#include "sigar_util.h"
|
#include "sigar_util.h"
|
||||||
|
#include "sigar_os.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <nlist.h>
|
#include <nlist.h>
|
||||||
|
@ -144,6 +144,8 @@ int sigar_os_open(sigar_t **sigar)
|
||||||
|
|
||||||
(*sigar)->aix_version = atoi(name.version);
|
(*sigar)->aix_version = atoi(name.version);
|
||||||
|
|
||||||
|
(*sigar)->diskmap = NULL;
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +166,9 @@ int sigar_os_close(sigar_t *sigar)
|
||||||
if (sigar->perfstat.handle) {
|
if (sigar->perfstat.handle) {
|
||||||
dlclose(sigar->perfstat.handle);
|
dlclose(sigar->perfstat.handle);
|
||||||
}
|
}
|
||||||
|
if (sigar->diskmap) {
|
||||||
|
sigar_cache_destroy(sigar->diskmap);
|
||||||
|
}
|
||||||
free(sigar);
|
free(sigar);
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
@ -1366,10 +1371,119 @@ int sigar_file_system_list_get(sigar_t *sigar,
|
||||||
#define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \
|
#define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \
|
||||||
((buf.f * (buf.f_bsize / 512)) >> 1)
|
((buf.f * (buf.f_bsize / 512)) >> 1)
|
||||||
|
|
||||||
|
#define LSPV_CMD "/usr/sbin/lspv"
|
||||||
|
|
||||||
|
#define FSDEV_ID(sb) (sb.st_ino + sb.st_dev)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dont have per-partition metrics on aix.
|
||||||
|
* need to build a mount point => diskname map.
|
||||||
|
* see 'lspv -l hdisk0' for example.
|
||||||
|
*/
|
||||||
|
static int create_diskmap(sigar_t *sigar)
|
||||||
|
{
|
||||||
|
FILE *fp = popen(LSPV_CMD, "r");
|
||||||
|
char buffer[BUFSIZ], *ptr;
|
||||||
|
|
||||||
|
sigar->diskmap = sigar_cache_new(25);
|
||||||
|
|
||||||
|
if (!fp) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
||||||
|
FILE *lfp;
|
||||||
|
char cmd[256], disk[56];
|
||||||
|
char *s = strchr(ptr, ' ');
|
||||||
|
if (s) {
|
||||||
|
*s = '\0';
|
||||||
|
}
|
||||||
|
strcpy(disk, ptr);
|
||||||
|
sprintf(cmd, LSPV_CMD " -l %s", disk);
|
||||||
|
if (!(lfp = popen(cmd, "r"))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)fgets(buffer, sizeof(buffer), lfp); /* skip disk: */
|
||||||
|
(void)fgets(buffer, sizeof(buffer), lfp); /* skip headers */
|
||||||
|
while ((ptr = fgets(buffer, sizeof(buffer), lfp))) {
|
||||||
|
sigar_cache_entry_t *ent;
|
||||||
|
struct stat sb;
|
||||||
|
int retval;
|
||||||
|
/* LV NAME LPs PPs DISTRIBUTION */
|
||||||
|
ptr = sigar_skip_multiple_token(ptr, 4);
|
||||||
|
SIGAR_SKIP_SPACE(ptr);
|
||||||
|
if ((s = strchr(ptr, '\n'))) {
|
||||||
|
*s = '\0';
|
||||||
|
}
|
||||||
|
if (strEQ(ptr, "N/A")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
retval = stat(ptr, &sb);
|
||||||
|
ent = sigar_cache_get(sigar->diskmap, FSDEV_ID(sb));
|
||||||
|
if (retval == 0) {
|
||||||
|
ent->value = strdup(disk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pclose(lfp);
|
||||||
|
}
|
||||||
|
pclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_disk_metrics(sigar_t *sigar,
|
||||||
|
sigar_file_system_usage_t *fsusage,
|
||||||
|
char *diskname)
|
||||||
|
{
|
||||||
|
/* XXX some caching can optimize */
|
||||||
|
int fd, i;
|
||||||
|
int cnt;
|
||||||
|
struct iostat iostat;
|
||||||
|
struct dkstat dkstat, *dp;
|
||||||
|
struct nlist nl[] = {
|
||||||
|
{ "iostat" },
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((fd = open("/dev/mem", O_RDONLY)) <= 0) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
i = knlist(nl, 1, sizeof(struct nlist));
|
||||||
|
|
||||||
|
if (i == -1) {
|
||||||
|
close(fd);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nl[i].n_value == 0) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
lseek(fd, nl[0].n_value, SEEK_SET);
|
||||||
|
read(fd, &iostat, sizeof(iostat));
|
||||||
|
|
||||||
|
for (dp = iostat.dkstatp, cnt = iostat.dk_cnt;
|
||||||
|
cnt && dp;
|
||||||
|
--cnt, dp = dkstat.dknextp)
|
||||||
|
{
|
||||||
|
lseek(fd, (long)dp, SEEK_SET);
|
||||||
|
read(fd, &dkstat, sizeof(dkstat));
|
||||||
|
if (strEQ(diskname, dkstat.diskname)) {
|
||||||
|
fsusage->disk_reads = dkstat.dk_rblks;
|
||||||
|
fsusage->disk_writes = dkstat.dk_wblks;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int sigar_file_system_usage_get(sigar_t *sigar,
|
int sigar_file_system_usage_get(sigar_t *sigar,
|
||||||
const char *dirname,
|
const char *dirname,
|
||||||
sigar_file_system_usage_t *fsusage)
|
sigar_file_system_usage_t *fsusage)
|
||||||
{
|
{
|
||||||
|
sigar_cache_entry_t *ent;
|
||||||
|
struct stat sb;
|
||||||
|
int status;
|
||||||
struct statfs buf;
|
struct statfs buf;
|
||||||
|
|
||||||
if (statfs((char *)dirname, &buf) != 0) {
|
if (statfs((char *)dirname, &buf) != 0) {
|
||||||
|
@ -1385,6 +1499,23 @@ int sigar_file_system_usage_get(sigar_t *sigar,
|
||||||
|
|
||||||
SIGAR_DISK_STATS_NOTIMPL(fsusage);
|
SIGAR_DISK_STATS_NOTIMPL(fsusage);
|
||||||
|
|
||||||
|
if (!sigar->diskmap) {
|
||||||
|
status = create_diskmap(sigar);
|
||||||
|
if (status != SIGAR_OK) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = stat(dirname, &sb);
|
||||||
|
if (status == 0) {
|
||||||
|
sigar_cache_entry_t *ent =
|
||||||
|
sigar_cache_get(sigar->diskmap, FSDEV_ID(sb));
|
||||||
|
if (!ent->value) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
get_disk_metrics(sigar, fsusage, (char *)ent->value);
|
||||||
|
}
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct sigar_t {
|
||||||
char model[128];
|
char model[128];
|
||||||
char self_path[SIGAR_PATH_MAX]; /* path to where libsigar.so lives */
|
char self_path[SIGAR_PATH_MAX]; /* path to where libsigar.so lives */
|
||||||
int aix_version;
|
int aix_version;
|
||||||
|
sigar_cache_t *diskmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HAVE_STRERROR_R
|
#define HAVE_STRERROR_R
|
||||||
|
|
Loading…
Reference in New Issue