From 4aad631348e9217e74f499c6369ed2d99f2b55a3 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 17 Aug 2010 17:44:10 -0700 Subject: [PATCH] libkvm - Adjust kvm_getswapinfo() to use the new vm.swap_info_array sysctl * kvm_getswapinfo() attempts to use the new sysctl and if it fails, or if the kvm is operating on a kernel core file, reverts to the namelist. --- lib/libkvm/kvm_getswapinfo.c | 85 +++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/lib/libkvm/kvm_getswapinfo.c b/lib/libkvm/kvm_getswapinfo.c index 66c9259074..3e7915dc10 100644 --- a/lib/libkvm/kvm_getswapinfo.c +++ b/lib/libkvm/kvm_getswapinfo.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -53,6 +55,9 @@ #include #include #include +#include + +#include "kvm_private.h" static struct nlist kvm_swap_nl[] = { { "_swapblist" }, /* new radix swap list */ @@ -74,6 +79,8 @@ static int dmmax; static void getswapinfo_radix(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags); +static int kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, + int swap_max, int flags); #define SVAR(var) __STRING(var) /* to force expansion */ #define KGET(idx, var) \ @@ -102,7 +109,7 @@ kvm_getswapinfo( int swap_max, int flags ) { - int ti = 0; + int ti; /* * clear cache @@ -112,6 +119,15 @@ kvm_getswapinfo( return(0); } + /* + * Use sysctl if possible + */ + if (kvm_ishost(kd) && (flags & SWIF_DUMP_TREE) == 0) { + ti = kvm_getswapinfo_sysctl(kd, swap_ary, swap_max, flags); + if (ti >= 0) + return(ti); + } + /* * namelist */ @@ -158,7 +174,6 @@ kvm_getswapinfo( kvm_swap_nl_cached = 1; } - { struct swdevt *sw; int i; @@ -462,3 +477,69 @@ getswapinfo_radix(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) swap_ary[0].ksw_used -= blcopy.bl_free; } } + +static +int +kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, + int swap_max, int flags) +{ + size_t bytes = 0; + size_t ksize; + int ti; + int n; + int i; + char *xswbuf; + struct xswdev *xsw; + + if (sysctlbyname("vm.swap_info_array", NULL, &bytes, NULL, 0) < 0) + return(-1); + if (bytes == 0) + return(-1); + xswbuf = malloc(bytes); + if (sysctlbyname("vm.swap_info_array", xswbuf, &bytes, NULL, 0) < 0) + return(-1); + if (bytes == 0) + return(-1); + + bzero(swap_ary, sizeof(struct kvm_swap) * swap_max); + --swap_max; + + /* + * Calculate size of xsw entry returned by kernel (it can be larger + * than the one we have if there is a version mismatch). + * + * Then iterate the list looking for live swap devices. + */ + ksize = ((struct xswdev *)xswbuf)->xsw_size; + n = (int)(bytes / ksize); + + for (i = ti = 0; i < n && ti < swap_max; ++i) { + xsw = (void *)((char *)xswbuf + i * ksize); + + if ((xsw->xsw_flags & SW_FREED) == 0) + continue; + + swap_ary[ti].ksw_total = xsw->xsw_nblks; + swap_ary[ti].ksw_used = xsw->xsw_used; + swap_ary[ti].ksw_flags = xsw->xsw_flags; + + if (xsw->xsw_dev == NODEV) { + snprintf( + swap_ary[ti].ksw_devname, + sizeof(swap_ary[ti].ksw_devname), + "%s", + "[NFS swap]" + ); + } else { + snprintf( + swap_ary[ti].ksw_devname, + sizeof(swap_ary[ti].ksw_devname), + "%s%s", + ((flags & SWIF_DEV_PREFIX) ? _PATH_DEV : ""), + devname(xsw->xsw_dev, S_IFCHR) + ); + } + ++ti; + } + return(ti); +} -- 2.41.0