Changeset View
Changeset View
Standalone View
Standalone View
lib/libkvm/kvm_getswapinfo.c
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include "kvm_private.h" | #include "kvm_private.h" | ||||
static struct nlist kvm_swap_nl[] = { | static struct nlist kvm_swap_nl[] = { | ||||
{ .n_name = "_swtailq" }, /* list of swap devices and sizes */ | { .n_name = "_swtailq" }, /* list of swap devices and sizes */ | ||||
{ .n_name = "_dmmax" }, /* maximum size of a swap block */ | |||||
{ .n_name = NULL } | { .n_name = NULL } | ||||
}; | }; | ||||
#define NL_SWTAILQ 0 | #define NL_SWTAILQ 0 | ||||
#define NL_DMMAX 1 | |||||
static int kvm_swap_nl_cached = 0; | static int kvm_swap_nl_cached = 0; | ||||
static int unswdev; /* number of found swap dev's */ | static int unswdev; /* number of found swap dev's */ | ||||
static int dmmax; | |||||
static int kvm_getswapinfo_kvm(kvm_t *, struct kvm_swap *, int, int); | static int kvm_getswapinfo_kvm(kvm_t *, struct kvm_swap *, int, int); | ||||
static int kvm_getswapinfo_sysctl(kvm_t *, struct kvm_swap *, int, int); | static int kvm_getswapinfo_sysctl(kvm_t *, struct kvm_swap *, int, int); | ||||
static int nlist_init(kvm_t *); | static int nlist_init(kvm_t *); | ||||
static int getsysctl(kvm_t *, const char *, void *, size_t); | |||||
#define KREAD(kd, addr, obj) \ | #define KREAD(kd, addr, obj) \ | ||||
(kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj)) | (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj)) | ||||
#define KGET(idx, var) \ | #define KGET(idx, var) \ | ||||
KGET2(kvm_swap_nl[(idx)].n_value, var, kvm_swap_nl[(idx)].n_name) | KGET2(kvm_swap_nl[(idx)].n_value, var, kvm_swap_nl[(idx)].n_name) | ||||
#define KGET2(addr, var, msg) \ | #define KGET2(addr, var, msg) \ | ||||
if (KREAD(kd, (u_long)(addr), (var))) { \ | if (KREAD(kd, (u_long)(addr), (var))) { \ | ||||
_kvm_err(kd, kd->program, "cannot read %s", msg); \ | _kvm_err(kd, kd->program, "cannot read %s", msg); \ | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | kvm_getswapinfo_kvm(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, | ||||
if (!nlist_init(kd)) | if (!nlist_init(kd)) | ||||
return (-1); | return (-1); | ||||
bzero(&tot, sizeof(tot)); | bzero(&tot, sizeof(tot)); | ||||
KGET(NL_SWTAILQ, &swtailq); | KGET(NL_SWTAILQ, &swtailq); | ||||
sp = TAILQ_FIRST(&swtailq); | sp = TAILQ_FIRST(&swtailq); | ||||
for (i = 0; sp != NULL; i++) { | for (i = 0; sp != NULL; i++) { | ||||
KGET2(sp, &swinfo, "swinfo"); | KGET2(sp, &swinfo, "swinfo"); | ||||
ttl = swinfo.sw_nblks - dmmax; | ttl = swinfo.sw_nblks; | ||||
if (i < swap_max - 1) { | if (i < swap_max - 1) { | ||||
bzero(&swap_ary[i], sizeof(swap_ary[i])); | bzero(&swap_ary[i], sizeof(swap_ary[i])); | ||||
swap_ary[i].ksw_total = ttl; | swap_ary[i].ksw_total = ttl; | ||||
swap_ary[i].ksw_used = swinfo.sw_used; | swap_ary[i].ksw_used = swinfo.sw_used; | ||||
swap_ary[i].ksw_flags = swinfo.sw_flags; | swap_ary[i].ksw_flags = swinfo.sw_flags; | ||||
GETSWDEVNAME(swinfo.sw_dev, swap_ary[i].ksw_devname, | GETSWDEVNAME(swinfo.sw_dev, swap_ary[i].ksw_devname, | ||||
flags); | flags); | ||||
} | } | ||||
tot.ksw_total += ttl; | tot.ksw_total += ttl; | ||||
tot.ksw_used += swinfo.sw_used; | tot.ksw_used += swinfo.sw_used; | ||||
sp = TAILQ_NEXT(&swinfo, sw_list); | sp = TAILQ_NEXT(&swinfo, sw_list); | ||||
} | } | ||||
if (i >= swap_max) | if (i >= swap_max) | ||||
i = swap_max - 1; | i = swap_max - 1; | ||||
if (i >= 0) | if (i >= 0) | ||||
swap_ary[i] = tot; | swap_ary[i] = tot; | ||||
return(i); | return(i); | ||||
} | } | ||||
#define GETSYSCTL(kd, name, var) \ | |||||
getsysctl(kd, name, &(var), sizeof(var)) | |||||
/* The maximum MIB length for vm.swap_info and an additional device number */ | /* The maximum MIB length for vm.swap_info and an additional device number */ | ||||
#define SWI_MAXMIB 3 | #define SWI_MAXMIB 3 | ||||
int | int | ||||
kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, | kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, | ||||
int flags) | int flags) | ||||
{ | { | ||||
int ti; | int ti; | ||||
swblk_t ttl; | swblk_t ttl; | ||||
size_t mibi, len; | size_t mibi, len; | ||||
int soid[SWI_MAXMIB]; | int soid[SWI_MAXMIB]; | ||||
struct xswdev xsd; | struct xswdev xsd; | ||||
struct kvm_swap tot; | struct kvm_swap tot; | ||||
if (!GETSYSCTL(kd, "vm.dmmax", dmmax)) | |||||
return -1; | |||||
mibi = SWI_MAXMIB - 1; | mibi = SWI_MAXMIB - 1; | ||||
if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) { | if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) { | ||||
_kvm_err(kd, kd->program, "sysctlnametomib failed: %s", | _kvm_err(kd, kd->program, "sysctlnametomib failed: %s", | ||||
strerror(errno)); | strerror(errno)); | ||||
return -1; | return -1; | ||||
} | } | ||||
bzero(&tot, sizeof(tot)); | bzero(&tot, sizeof(tot)); | ||||
for (unswdev = 0;; unswdev++) { | for (unswdev = 0;; unswdev++) { | ||||
Show All 12 Lines | if (len != sizeof(xsd)) { | ||||
return -1; | return -1; | ||||
} | } | ||||
if (xsd.xsw_version != XSWDEV_VERSION) { | if (xsd.xsw_version != XSWDEV_VERSION) { | ||||
_kvm_err(kd, kd->program, "struct xswdev version " | _kvm_err(kd, kd->program, "struct xswdev version " | ||||
"mismatch; kernel and libkvm out of sync?"); | "mismatch; kernel and libkvm out of sync?"); | ||||
return -1; | return -1; | ||||
} | } | ||||
ttl = xsd.xsw_nblks - dmmax; | ttl = xsd.xsw_nblks; | ||||
if (unswdev < swap_max - 1) { | if (unswdev < swap_max - 1) { | ||||
bzero(&swap_ary[unswdev], sizeof(swap_ary[unswdev])); | bzero(&swap_ary[unswdev], sizeof(swap_ary[unswdev])); | ||||
swap_ary[unswdev].ksw_total = ttl; | swap_ary[unswdev].ksw_total = ttl; | ||||
swap_ary[unswdev].ksw_used = xsd.xsw_used; | swap_ary[unswdev].ksw_used = xsd.xsw_used; | ||||
swap_ary[unswdev].ksw_flags = xsd.xsw_flags; | swap_ary[unswdev].ksw_flags = xsd.xsw_flags; | ||||
GETSWDEVNAME(xsd.xsw_dev, swap_ary[unswdev].ksw_devname, | GETSWDEVNAME(xsd.xsw_dev, swap_ary[unswdev].ksw_devname, | ||||
flags); | flags); | ||||
} | } | ||||
Show All 21 Lines | if (kvm_nlist(kd, kvm_swap_nl) < 0) | ||||
return (0); | return (0); | ||||
/* Required entries */ | /* Required entries */ | ||||
if (kvm_swap_nl[NL_SWTAILQ].n_value == 0) { | if (kvm_swap_nl[NL_SWTAILQ].n_value == 0) { | ||||
_kvm_err(kd, kd->program, "unable to find swtailq"); | _kvm_err(kd, kd->program, "unable to find swtailq"); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (kvm_swap_nl[NL_DMMAX].n_value == 0) { | |||||
_kvm_err(kd, kd->program, "unable to find dmmax"); | |||||
return (0); | |||||
} | |||||
/* Get globals, type of swap */ | |||||
KGET(NL_DMMAX, &dmmax); | |||||
kvm_swap_nl_cached = 1; | kvm_swap_nl_cached = 1; | ||||
return (1); | |||||
} | |||||
static int | |||||
getsysctl(kvm_t *kd, const char *name, void *ptr, size_t len) | |||||
{ | |||||
size_t nlen = len; | |||||
if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) { | |||||
_kvm_err(kd, kd->program, "cannot read sysctl %s:%s", name, | |||||
strerror(errno)); | |||||
return (0); | |||||
} | |||||
if (nlen != len) { | |||||
_kvm_err(kd, kd->program, "sysctl %s has unexpected size", name); | |||||
return (0); | |||||
} | |||||
return (1); | return (1); | ||||
} | } |