19b50d902SRodney W. Grimes /*- 29b50d902SRodney W. Grimes * Copyright (c) 1980, 1992, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349ff712b0SMark Murray #include <sys/cdefs.h> 359ff712b0SMark Murray 369ff712b0SMark Murray __FBSDID("$FreeBSD$"); 379ff712b0SMark Murray 389ff712b0SMark Murray #ifdef lint 399ff712b0SMark Murray static const char sccsid[] = "@(#)fetch.c 8.1 (Berkeley) 6/6/93"; 409ff712b0SMark Murray #endif 419b50d902SRodney W. Grimes 429b50d902SRodney W. Grimes #include <sys/types.h> 43342e2faaSThomas Moestl #include <sys/sysctl.h> 44342e2faaSThomas Moestl 45821df508SXin LI #include <err.h> 469ff712b0SMark Murray #include <errno.h> 47342e2faaSThomas Moestl #include <stdlib.h> 489ff712b0SMark Murray #include <string.h> 49342e2faaSThomas Moestl 509b50d902SRodney W. Grimes #include "systat.h" 519b50d902SRodney W. Grimes #include "extern.h" 529b50d902SRodney W. Grimes 539b50d902SRodney W. Grimes int 5493b9f504SXin LI kvm_ckread(void *a, void *b, int l) 559b50d902SRodney W. Grimes { 569b50d902SRodney W. Grimes if (kvm_read(kd, (u_long)a, b, l) != l) { 579b50d902SRodney W. Grimes if (verbose) 589ff712b0SMark Murray error("error reading kmem at %p", a); 599b50d902SRodney W. Grimes return (0); 609b50d902SRodney W. Grimes } 619b50d902SRodney W. Grimes else 629b50d902SRodney W. Grimes return (1); 639b50d902SRodney W. Grimes } 64342e2faaSThomas Moestl 6593b9f504SXin LI void getsysctl(const char *name, void *ptr, size_t len) 66342e2faaSThomas Moestl { 67342e2faaSThomas Moestl size_t nlen = len; 689ff712b0SMark Murray if (sysctlbyname(name, ptr, &nlen, NULL, 0) != 0) { 69342e2faaSThomas Moestl error("sysctl(%s...) failed: %s", name, 70342e2faaSThomas Moestl strerror(errno)); 71342e2faaSThomas Moestl } 72342e2faaSThomas Moestl if (nlen != len) { 73d62de5c4SThomas Moestl error("sysctl(%s...) expected %lu, got %lu", name, 74d62de5c4SThomas Moestl (unsigned long)len, (unsigned long)nlen); 75342e2faaSThomas Moestl } 76342e2faaSThomas Moestl } 77342e2faaSThomas Moestl 78342e2faaSThomas Moestl /* 79342e2faaSThomas Moestl * Read sysctl data with variable size. Try some times (with increasing 80342e2faaSThomas Moestl * buffers), fail if still too small. 81342e2faaSThomas Moestl * This is needed sysctls with possibly raplidly increasing data sizes, 82342e2faaSThomas Moestl * but imposes little overhead in the case of constant sizes. 83342e2faaSThomas Moestl * Returns NULL on error, or a pointer to freshly malloc()'ed memory that holds 84342e2faaSThomas Moestl * the requested data. 85342e2faaSThomas Moestl * If szp is not NULL, the size of the returned data will be written into *szp. 86342e2faaSThomas Moestl */ 87342e2faaSThomas Moestl 88342e2faaSThomas Moestl /* Some defines: Number of tries. */ 89342e2faaSThomas Moestl #define SD_NTRIES 10 90342e2faaSThomas Moestl /* Percent of over-allocation (initial) */ 91342e2faaSThomas Moestl #define SD_MARGIN 10 92342e2faaSThomas Moestl /* 93342e2faaSThomas Moestl * Factor for over-allocation in percent (the margin is increased by this on 94342e2faaSThomas Moestl * any failed try). 95342e2faaSThomas Moestl */ 96342e2faaSThomas Moestl #define SD_FACTOR 50 97342e2faaSThomas Moestl /* Maximum supported MIB depth */ 98342e2faaSThomas Moestl #define SD_MAXMIB 16 99342e2faaSThomas Moestl 100342e2faaSThomas Moestl char * 10193b9f504SXin LI sysctl_dynread(const char *n, size_t *szp) 102342e2faaSThomas Moestl { 103342e2faaSThomas Moestl char *rv = NULL; 104342e2faaSThomas Moestl int mib[SD_MAXMIB]; 105342e2faaSThomas Moestl size_t mibsz = SD_MAXMIB; 106342e2faaSThomas Moestl size_t mrg = SD_MARGIN; 107342e2faaSThomas Moestl size_t sz; 108342e2faaSThomas Moestl int i; 109342e2faaSThomas Moestl 110342e2faaSThomas Moestl /* cache the MIB */ 111342e2faaSThomas Moestl if (sysctlnametomib(n, mib, &mibsz) == -1) { 112342e2faaSThomas Moestl if (errno == ENOMEM) { 113342e2faaSThomas Moestl error("XXX: SD_MAXMIB too small, please bump!"); 114342e2faaSThomas Moestl } 115342e2faaSThomas Moestl return NULL; 116342e2faaSThomas Moestl } 117342e2faaSThomas Moestl for (i = 0; i < SD_NTRIES; i++) { 118342e2faaSThomas Moestl /* get needed buffer size */ 119342e2faaSThomas Moestl if (sysctl(mib, mibsz, NULL, &sz, NULL, 0) == -1) 120342e2faaSThomas Moestl break; 121342e2faaSThomas Moestl sz += sz * mrg / 100; 122342e2faaSThomas Moestl if ((rv = (char *)malloc(sz)) == NULL) { 123342e2faaSThomas Moestl error("Out of memory!"); 124342e2faaSThomas Moestl return NULL; 125342e2faaSThomas Moestl } 126342e2faaSThomas Moestl if (sysctl(mib, mibsz, rv, &sz, NULL, 0) == -1) { 127342e2faaSThomas Moestl free(rv); 128342e2faaSThomas Moestl rv = NULL; 129342e2faaSThomas Moestl if (errno == ENOMEM) { 130342e2faaSThomas Moestl mrg += mrg * SD_FACTOR / 100; 131342e2faaSThomas Moestl } else 132342e2faaSThomas Moestl break; 133342e2faaSThomas Moestl } else { 134342e2faaSThomas Moestl /* success */ 135342e2faaSThomas Moestl if (szp != NULL) 136342e2faaSThomas Moestl *szp = sz; 137342e2faaSThomas Moestl break; 138342e2faaSThomas Moestl } 139342e2faaSThomas Moestl } 140342e2faaSThomas Moestl 141342e2faaSThomas Moestl return rv; 142342e2faaSThomas Moestl } 143