implement disk i/o metrics
This commit is contained in:
parent
5630d9a48a
commit
1a4f8ae004
|
@ -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"
|
||||||
|
|
||||||
int sigar_get_multi_kstats(sigar_t *sigar,
|
int sigar_get_multi_kstats(sigar_t *sigar,
|
||||||
kstat_list_t *kl,
|
kstat_list_t *kl,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
#define my_pread(fd, ptr, type, offset) \
|
#define my_pread(fd, ptr, type, offset) \
|
||||||
(pread(fd, ptr, sizeof(type), offset) == sizeof(type))
|
(pread(fd, ptr, sizeof(type), offset) == sizeof(type))
|
||||||
|
|
|
@ -220,6 +220,8 @@ struct sigar_t {
|
||||||
proc_objname_func_t pobjname;
|
proc_objname_func_t pobjname;
|
||||||
proc_dirname_func_t pdirname;
|
proc_dirname_func_t pdirname;
|
||||||
proc_exename_func_t pexename;
|
proc_exename_func_t pexename;
|
||||||
|
|
||||||
|
sigar_cache_t *fsdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define kSTAT_uint(v, type) \
|
#define kSTAT_uint(v, type) \
|
||||||
|
|
|
@ -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 <sys/link.h>
|
#include <sys/link.h>
|
||||||
#include <sys/lwp.h>
|
#include <sys/lwp.h>
|
||||||
|
@ -92,6 +92,8 @@ int sigar_os_open(sigar_t **sig)
|
||||||
sigar->pfree = NULL;
|
sigar->pfree = NULL;
|
||||||
sigar->pobjname = NULL;
|
sigar->pobjname = NULL;
|
||||||
|
|
||||||
|
sigar->fsdev = NULL;
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +129,9 @@ int sigar_os_close(sigar_t *sigar)
|
||||||
if (sigar->plib) {
|
if (sigar->plib) {
|
||||||
dlclose(sigar->plib);
|
dlclose(sigar->plib);
|
||||||
}
|
}
|
||||||
|
if (sigar->fsdev) {
|
||||||
|
sigar_cache_destroy(sigar->fsdev);
|
||||||
|
}
|
||||||
free(sigar);
|
free(sigar);
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
@ -1116,11 +1121,223 @@ 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_frsize / 512)) >> 1)
|
((buf.f * (buf.f_frsize / 512)) >> 1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char device[PATH_MAX];
|
||||||
|
char name[8];
|
||||||
|
int instance;
|
||||||
|
} fsdev_path_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char module[8];
|
||||||
|
int instance;
|
||||||
|
char partition;
|
||||||
|
} fs_kstat_t;
|
||||||
|
|
||||||
|
static fsdev_path_t *get_fsdev_paths(sigar_t *sigar,
|
||||||
|
sigar_file_system_list_t *fslist)
|
||||||
|
{
|
||||||
|
int i, ndisk, size;
|
||||||
|
char buffer[BUFSIZ], *ptr;
|
||||||
|
char *dev, *inst, *drv;
|
||||||
|
fsdev_path_t *paths, *mapping;
|
||||||
|
FILE *fp = fopen("/etc/path_to_inst", "r");
|
||||||
|
|
||||||
|
if (!fp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0, ndisk=0; i<fslist->number; i++) {
|
||||||
|
sigar_file_system_t *fsp = &fslist->data[i];
|
||||||
|
if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
|
||||||
|
ndisk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size = sizeof(*paths) * (ndisk+1);
|
||||||
|
mapping = paths = malloc(size);
|
||||||
|
memset(mapping, '\0', size);
|
||||||
|
|
||||||
|
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
||||||
|
/* eat dust java */
|
||||||
|
char *q;
|
||||||
|
|
||||||
|
SIGAR_SKIP_SPACE(ptr);
|
||||||
|
if (*ptr == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*ptr == '"') {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
dev = ptr;
|
||||||
|
if (!(q = strchr(ptr, '"'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ptr = q+1;
|
||||||
|
*q = '\0';
|
||||||
|
SIGAR_SKIP_SPACE(ptr);
|
||||||
|
inst = ptr;
|
||||||
|
while (sigar_isdigit(*ptr)) {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
*ptr = '\0';
|
||||||
|
ptr++;
|
||||||
|
SIGAR_SKIP_SPACE(ptr);
|
||||||
|
if (*ptr == '"') {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
drv = ptr;
|
||||||
|
if (!(q = strchr(ptr, '"'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
if (!(strEQ(drv, "sd") ||
|
||||||
|
strEQ(drv, "ssd") ||
|
||||||
|
strEQ(drv, "st") ||
|
||||||
|
strEQ(drv, "cmdk")))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
paths->instance = atoi(inst);
|
||||||
|
if (!kstat_lookup(sigar->kc, drv, paths->instance, NULL)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIGAR_SSTRCPY(paths->device, dev);
|
||||||
|
SIGAR_SSTRCPY(paths->name, drv);
|
||||||
|
|
||||||
|
if (--ndisk < 0) {
|
||||||
|
/* XXX prevent overflow */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
paths++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FSDEV_ID(sb) (sb.st_ino + sb.st_dev)
|
||||||
|
|
||||||
|
static int create_fsdev_cache(sigar_t *sigar)
|
||||||
|
{
|
||||||
|
fsdev_path_t *paths, *mapping;
|
||||||
|
sigar_file_system_list_t fslist;
|
||||||
|
int i, j;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
sigar->fsdev = sigar_cache_new(15);
|
||||||
|
|
||||||
|
status = sigar_file_system_list_get(sigar, &fslist);
|
||||||
|
|
||||||
|
if (status != SIGAR_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(mapping = get_fsdev_paths(sigar, &fslist))) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<fslist.number; i++) {
|
||||||
|
sigar_file_system_t *fsp = &fslist.data[i];
|
||||||
|
|
||||||
|
if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
|
||||||
|
char device[PATH_MAX+1], *ptr=device;
|
||||||
|
int len = readlink(fsp->dev_name, device, sizeof(device)-1);
|
||||||
|
char *s;
|
||||||
|
char partition;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
device[len] = '\0';
|
||||||
|
while (strnEQ(ptr, "../", 3)) {
|
||||||
|
ptr += 3;
|
||||||
|
}
|
||||||
|
if (strnEQ(ptr, "devices", 7)) {
|
||||||
|
ptr += 7;
|
||||||
|
}
|
||||||
|
if ((s = strchr(ptr, ':'))) {
|
||||||
|
partition = *(s+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j=0, paths=mapping; paths->name[0]; j++) {
|
||||||
|
if (strnEQ(paths->device, ptr, strlen(paths->device))) {
|
||||||
|
sigar_cache_entry_t *ent;
|
||||||
|
struct stat sb;
|
||||||
|
int retval = stat(fsp->dir_name, &sb);
|
||||||
|
fs_kstat_t *fs_kstat;
|
||||||
|
|
||||||
|
if (retval == 0) {
|
||||||
|
fs_kstat = malloc(sizeof(*fs_kstat));
|
||||||
|
|
||||||
|
/* e.g. sd9,g
|
||||||
|
* module == sd
|
||||||
|
* instance == 9
|
||||||
|
* partition == 8
|
||||||
|
*/
|
||||||
|
SIGAR_SSTRCPY(fs_kstat->module, paths->name);
|
||||||
|
fs_kstat->instance = paths->instance;
|
||||||
|
fs_kstat->partition = partition;
|
||||||
|
ent = sigar_cache_get(sigar->fsdev, FSDEV_ID(sb));
|
||||||
|
ent->value = fs_kstat;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
paths++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sigar_file_system_list_destroy(sigar, &fslist);
|
||||||
|
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_fs_kstat(sigar_t *sigar,
|
||||||
|
sigar_file_system_usage_t *fsusage,
|
||||||
|
fs_kstat_t *fsk)
|
||||||
|
{
|
||||||
|
kstat_t *ksp;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
kstat_chain_update(sigar->kc);
|
||||||
|
ksp = kstat_lookup(sigar->kc, fsk->module, fsk->instance, NULL);
|
||||||
|
|
||||||
|
if (!ksp) {
|
||||||
|
return ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ksp) {
|
||||||
|
if (!strEQ(ksp->ks_module, fsk->module)) {
|
||||||
|
break; /* chain goes beyond our module */
|
||||||
|
}
|
||||||
|
if ((ptr = strchr(ksp->ks_name, ','))) {
|
||||||
|
if (*(ptr+1) == fsk->partition) {
|
||||||
|
kstat_io_t io;
|
||||||
|
kstat_read(sigar->kc, ksp, &io);
|
||||||
|
fsusage->disk_reads = io.reads;
|
||||||
|
fsusage->disk_writes = io.writes;
|
||||||
|
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksp = ksp->ks_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
struct statvfs buf;
|
struct statvfs buf;
|
||||||
|
struct stat sb;
|
||||||
|
sigar_cache_entry_t *ent;
|
||||||
|
|
||||||
if (statvfs(dirname, &buf) != 0) {
|
if (statvfs(dirname, &buf) != 0) {
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -1135,6 +1352,22 @@ int sigar_file_system_usage_get(sigar_t *sigar,
|
||||||
|
|
||||||
SIGAR_DISK_STATS_NOTIMPL(fsusage);
|
SIGAR_DISK_STATS_NOTIMPL(fsusage);
|
||||||
|
|
||||||
|
if (!sigar->fsdev) {
|
||||||
|
if (create_fsdev_cache(sigar) != SIGAR_OK) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(dirname, &sb) < 0) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
ent = sigar_cache_get(sigar->fsdev, FSDEV_ID(sb));
|
||||||
|
if (ent->value == NULL) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_fs_kstat(sigar, fsusage, (fs_kstat_t *)ent->value);
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue