Index: head/lib/libkvm/kvm.h =================================================================== --- head/lib/libkvm/kvm.h (revision 311100) +++ head/lib/libkvm/kvm.h (revision 311101) @@ -1,109 +1,109 @@ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)kvm.h 8.1 (Berkeley) 6/2/93 * $FreeBSD$ */ #ifndef _KVM_H_ #define _KVM_H_ #include #include #include /* Default version symbol. */ #define VRS_SYM "_version" #define VRS_KEY "VERSION" #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif typedef uint64_t kvaddr_t; /* An address in a target image. */ struct kvm_nlist { const char *n_name; unsigned char n_type; kvaddr_t n_value; }; typedef struct __kvm kvm_t; struct kinfo_proc; struct proc; struct kvm_swap { char ksw_devname[32]; - int ksw_used; - int ksw_total; + u_int ksw_used; + u_int ksw_total; int ksw_flags; - int ksw_reserved1; - int ksw_reserved2; + u_int ksw_reserved1; + u_int ksw_reserved2; }; #define SWIF_DEV_PREFIX 0x0002 __BEGIN_DECLS int kvm_close(kvm_t *); int kvm_dpcpu_setcpu(kvm_t *, unsigned int); char **kvm_getargv(kvm_t *, const struct kinfo_proc *, int); int kvm_getcptime(kvm_t *, long *); char **kvm_getenvv(kvm_t *, const struct kinfo_proc *, int); char *kvm_geterr(kvm_t *); int kvm_getloadavg(kvm_t *, double [], int); int kvm_getmaxcpu(kvm_t *); int kvm_getncpus(kvm_t *); void *kvm_getpcpu(kvm_t *, int); uint64_t kvm_counter_u64_fetch(kvm_t *, u_long); struct kinfo_proc * kvm_getprocs(kvm_t *, int, int, int *); int kvm_getswapinfo(kvm_t *, struct kvm_swap *, int, int); int kvm_native(kvm_t *); int kvm_nlist(kvm_t *, struct nlist *); int kvm_nlist2(kvm_t *, struct kvm_nlist *); kvm_t *kvm_open (const char *, const char *, const char *, int, const char *); kvm_t *kvm_openfiles (const char *, const char *, const char *, int, char *); kvm_t *kvm_open2 (const char *, const char *, int, char *, int (*)(const char *, kvaddr_t *)); ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t); ssize_t kvm_read_zpcpu(kvm_t *, unsigned long, void *, size_t, int); ssize_t kvm_read2(kvm_t *, kvaddr_t, void *, size_t); ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t); __END_DECLS #endif /* !_KVM_H_ */ Index: head/lib/libkvm/kvm_getswapinfo.3 =================================================================== --- head/lib/libkvm/kvm_getswapinfo.3 (revision 311100) +++ head/lib/libkvm/kvm_getswapinfo.3 (revision 311101) @@ -1,111 +1,111 @@ .\" Copyright (C) 1999 Matthew Dillon. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd January 22, 1999 +.Dd January 2, 2017 .Dt KVM_SWAPINFO 3 .Os .Sh NAME .Nm kvm_getswapinfo .Nd return swap summary statistics for the system .Sh LIBRARY .Lb libkvm .Sh SYNOPSIS .In kvm.h .Ft int .Fn kvm_getswapinfo "kvm_t *kd" "struct kvm_swap *" "int maxswap" "int flags" .Sh DESCRIPTION The .Fn kvm_getswapinfo function fills an array of .Vt kvm_swap structures with swap summary information for each swap device, for up to .Fa maxswap \- 1 devices. The number of devices, up to .Fa maxswap \- 1, is returned. A grand total of all swap devices (including any devices that go beyond .Fa maxswap \- 1) is returned in one additional array entry. This entry is not counted in the return value. Thus, if you specify a .Fa maxswap value of 1, the function will typically return the value 0 and the single .Vt kvm_swap structure will be filled with the grand total over all swap devices. The grand total is calculated from all available swap devices whether or not you made room for them all in the array. The grand total is returned. .Pp The flags argument is currently unused and must be passed as 0. .Pp If an error occurs, -1 is returned. .Pp Each swap partition and the grand total is summarized in the .Vt kvm_swap structure. This structure contains the following fields: .Pp .Bl -item -offset indent -compact .It .Va char ksw_devname[] ; .It -.Va int ksw_total ; +.Va u_int ksw_total ; .It -.Va int ksw_used ; +.Va u_int ksw_used ; .It .Va int ksw_flags ; .El .Pp Values are in .Dv PAGE_SIZE Ns 'd chunks (see .Xr getpagesize 3 ) . .Va ksw_flags contains a copy of the swap device flags. .Sh CACHING This function caches the nlist values for various kernel variables which it reuses in successive calls. You may call the function with .Fa kd == .Dv NULL to clear the cache. .Sh DIAGNOSTICS If the load average was unobtainable, \-1 is returned; otherwise, the number of swap devices actually retrieved is returned. .Pp If the name of the swap device does not fit in the static char buffer in the structure, it is truncated. The buffer is always zero terminated. .Sh SEE ALSO .Xr kvm 3 Index: head/lib/libkvm/kvm_getswapinfo.c =================================================================== --- head/lib/libkvm/kvm_getswapinfo.c (revision 311100) +++ head/lib/libkvm/kvm_getswapinfo.c (revision 311101) @@ -1,267 +1,269 @@ /* * Copyright (c) 1999, Matthew Dillon. All Rights Reserved. * Copyright (c) 2001, Thomas Moestl. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kvm_private.h" static struct nlist kvm_swap_nl[] = { { .n_name = "_swtailq" }, /* list of swap devices and sizes */ { .n_name = "_dmmax" }, /* maximum size of a swap block */ { .n_name = NULL } }; #define NL_SWTAILQ 0 #define NL_DMMAX 1 static int kvm_swap_nl_cached = 0; 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_sysctl(kvm_t *, struct kvm_swap *, int, int); static int nlist_init(kvm_t *); static int getsysctl(kvm_t *, const char *, void *, size_t); #define KREAD(kd, addr, obj) \ (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj)) #define KGET(idx, var) \ KGET2(kvm_swap_nl[(idx)].n_value, var, kvm_swap_nl[(idx)].n_name) #define KGET2(addr, var, msg) \ if (KREAD(kd, (u_long)(addr), (var))) { \ _kvm_err(kd, kd->program, "cannot read %s", msg); \ return (-1); \ } #define GETSWDEVNAME(dev, str, flags) \ if (dev == NODEV) { \ strlcpy(str, "[NFS swap]", sizeof(str)); \ } else { \ snprintf( \ str, sizeof(str),"%s%s", \ ((flags & SWIF_DEV_PREFIX) ? _PATH_DEV : ""), \ devname(dev, S_IFCHR) \ ); \ } int kvm_getswapinfo(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) { /* * clear cache */ if (kd == NULL) { kvm_swap_nl_cached = 0; return(0); } if (ISALIVE(kd)) { return kvm_getswapinfo_sysctl(kd, swap_ary, swap_max, flags); } else { return kvm_getswapinfo_kvm(kd, swap_ary, swap_max, flags); } } int kvm_getswapinfo_kvm(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) { - int i, ttl; + int i; + swblk_t ttl; TAILQ_HEAD(, swdevt) swtailq; struct swdevt *sp, swinfo; struct kvm_swap tot; if (!kd->arch->ka_native(kd)) { _kvm_err(kd, kd->program, "cannot read swapinfo from non-native core"); return (-1); } if (!nlist_init(kd)) return (-1); bzero(&tot, sizeof(tot)); KGET(NL_SWTAILQ, &swtailq); sp = TAILQ_FIRST(&swtailq); for (i = 0; sp != NULL; i++) { KGET2(sp, &swinfo, "swinfo"); ttl = swinfo.sw_nblks - dmmax; if (i < swap_max - 1) { bzero(&swap_ary[i], sizeof(swap_ary[i])); swap_ary[i].ksw_total = ttl; swap_ary[i].ksw_used = swinfo.sw_used; swap_ary[i].ksw_flags = swinfo.sw_flags; GETSWDEVNAME(swinfo.sw_dev, swap_ary[i].ksw_devname, flags); } tot.ksw_total += ttl; tot.ksw_used += swinfo.sw_used; sp = TAILQ_NEXT(&swinfo, sw_list); } if (i >= swap_max) i = swap_max - 1; if (i >= 0) swap_ary[i] = tot; 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 */ #define SWI_MAXMIB 3 int kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max, int flags) { - int ti, ttl; + int ti; + swblk_t ttl; size_t mibi, len; int soid[SWI_MAXMIB]; struct xswdev xsd; struct kvm_swap tot; if (!GETSYSCTL(kd, "vm.dmmax", dmmax)) return -1; mibi = SWI_MAXMIB - 1; if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) { _kvm_err(kd, kd->program, "sysctlnametomib failed: %s", strerror(errno)); return -1; } bzero(&tot, sizeof(tot)); for (unswdev = 0;; unswdev++) { soid[mibi] = unswdev; len = sizeof(xsd); if (sysctl(soid, mibi + 1, &xsd, &len, NULL, 0) == -1) { if (errno == ENOENT) break; _kvm_err(kd, kd->program, "cannot read sysctl: %s.", strerror(errno)); return -1; } if (len != sizeof(xsd)) { _kvm_err(kd, kd->program, "struct xswdev has unexpected " "size; kernel and libkvm out of sync?"); return -1; } if (xsd.xsw_version != XSWDEV_VERSION) { _kvm_err(kd, kd->program, "struct xswdev version " "mismatch; kernel and libkvm out of sync?"); return -1; } ttl = xsd.xsw_nblks - dmmax; if (unswdev < swap_max - 1) { bzero(&swap_ary[unswdev], sizeof(swap_ary[unswdev])); swap_ary[unswdev].ksw_total = ttl; swap_ary[unswdev].ksw_used = xsd.xsw_used; swap_ary[unswdev].ksw_flags = xsd.xsw_flags; GETSWDEVNAME(xsd.xsw_dev, swap_ary[unswdev].ksw_devname, flags); } tot.ksw_total += ttl; tot.ksw_used += xsd.xsw_used; } ti = unswdev; if (ti >= swap_max) ti = swap_max - 1; if (ti >= 0) swap_ary[ti] = tot; return(ti); } static int nlist_init(kvm_t *kd) { if (kvm_swap_nl_cached) return (1); if (kvm_nlist(kd, kvm_swap_nl) < 0) return (0); /* Required entries */ if (kvm_swap_nl[NL_SWTAILQ].n_value == 0) { _kvm_err(kd, kd->program, "unable to find swtailq"); 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; 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); }