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