diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index 7cd5808d..f6183374 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -297,6 +297,23 @@ static int sigar_perfstat_init(sigar_t *sigar) return ENOENT; } + sigar->perfstat.swap = + (perfstat_swap_func_t)dlsym(handle, + "sigar_perfstat_pagingspace"); + + if (!sigar->perfstat.swap) { + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "dlsym(sigar_perfstat_pagingspace) failed: %s", + dlerror()); + } + + dlclose(handle); + + sigar->perfstat.avail = -1; + return ENOENT; + } + sigar->perfstat.avail = 1; sigar->perfstat.handle = handle; @@ -441,7 +458,7 @@ static int swaps_get(swaps_t *swaps) int swapqry(char *path, struct pginfo *info); -int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) +static int sigar_swap_get_swapqry(sigar_t *sigar, sigar_swap_t *swap) { int status, i; @@ -489,6 +506,59 @@ int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) return SIGAR_OK; } +#define SWAP_DEV(ps) \ + ((ps.type == LV_PAGING) ? \ + ps.id.lv_paging.vgname : \ + ps.id.nfs_paging.filename) + +#define SWAP_MB_TO_BYTES(v) ((v) * (1024 * 1024)) + +static int sigar_swap_get_perfstat(sigar_t *sigar, sigar_swap_t *swap) +{ + perfstat_pagingspace_t ps; + perfstat_id_t id; + + id.name[0] = '\0'; + + SIGAR_ZERO(swap); + + do { + if (sigar->perfstat.swap(&id, &ps, sizeof(ps), 1) != 1) { + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "[swap] dev=%s query failed: %s", + SWAP_DEV(ps), + sigar_strerror(sigar, errno)); + } + continue; + } + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "[swap] dev=%s: total=%lluMb, used=%lluMb", + SWAP_DEV(ps), ps.mb_size, ps.mb_used); + } + /* convert MB sizes to bytes */ + swap->total += SWAP_MB_TO_BYTES(ps.mb_size); + swap->used += SWAP_MB_TO_BYTES(ps.mb_used); + } while (id.name[0] != '\0'); + + swap->free = swap->total - swap->used; + + return SIGAR_OK; +} + +int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) +{ + if (sigar_perfstat_init(sigar) == SIGAR_OK) { + sigar_log(sigar, SIGAR_LOG_DEBUG, "[swap] using libperfstat"); + return sigar_swap_get_perfstat(sigar, swap); + } + else { + sigar_log(sigar, SIGAR_LOG_DEBUG, "[swap] using /dev/kmem"); + return sigar_swap_get_swapqry(sigar, swap); + } +} + int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu) { int i, status; diff --git a/src/os/aix/perfstat/sigar_perfstat.c b/src/os/aix/perfstat/sigar_perfstat.c index 78e55a9d..a848e3ea 100644 --- a/src/os/aix/perfstat/sigar_perfstat.c +++ b/src/os/aix/perfstat/sigar_perfstat.c @@ -18,3 +18,10 @@ int sigar_perfstat_cpu(perfstat_id_t *id, return perfstat_cpu(id, cpu, size, num); } +int sigar_perfstat_pagingspace(perfstat_id_t *id, + perfstat_pagingspace_t *pagingspace, + size_t size, + int num) +{ + return perfstat_pagingspace(id, pagingspace, size, num); +} diff --git a/src/os/aix/sigar_os.h b/src/os/aix/sigar_os.h index 28fe097a..af467c56 100644 --- a/src/os/aix/sigar_os.h +++ b/src/os/aix/sigar_os.h @@ -33,6 +33,10 @@ typedef int (*perfstat_cpu_func_t)(perfstat_id_t *, perfstat_cpu_t *, size_t, int); +typedef int (*perfstat_swap_func_t)(perfstat_id_t *, + perfstat_pagingspace_t *, + size_t, int); + struct sigar_t { SIGAR_T_BASE; int kmem; @@ -44,6 +48,7 @@ struct sigar_t { int avail; perfstat_cpu_func_t cpu; perfstat_cpu_total_func_t cpu_total; + perfstat_swap_func_t swap; void *handle; } perfstat; int pagesize;