140090Smsmith/*- 240090Smsmith * Copyright (c) 1998 Michael Smith 340090Smsmith * All rights reserved. 440090Smsmith * 540090Smsmith * Redistribution and use in source and binary forms, with or without 640090Smsmith * modification, are permitted provided that the following conditions 740090Smsmith * are met: 840090Smsmith * 1. Redistributions of source code must retain the above copyright 940090Smsmith * notice, this list of conditions and the following disclaimer. 1040090Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1140090Smsmith * notice, this list of conditions and the following disclaimer in the 1240090Smsmith * documentation and/or other materials provided with the distribution. 1340090Smsmith * 1440090Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1540090Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1640090Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1740090Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1840090Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1940090Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2040090Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2140090Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2240090Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2340090Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2440090Smsmith * SUCH DAMAGE. 2540116Sjkh */ 2640090Smsmith 2740090Smsmith/* 2840090Smsmith * The unified bootloader passes us a pointer to a preserved copy of 2994936Smux * bootstrap/kernel environment variables. We convert them to a 3094936Smux * dynamic array of strings later when the VM subsystem is up. 3140090Smsmith * 3294936Smux * We make these available through the kenv(2) syscall for userland 3394936Smux * and through getenv()/freeenv() setenv() unsetenv() testenv() for 3494936Smux * the kernel. 3540090Smsmith */ 3640090Smsmith 37116182Sobrien#include <sys/cdefs.h> 38116182Sobrien__FBSDID("$FreeBSD$"); 39116182Sobrien 4094936Smux#include <sys/types.h> 4140090Smsmith#include <sys/param.h> 4294936Smux#include <sys/proc.h> 4394936Smux#include <sys/queue.h> 4494936Smux#include <sys/lock.h> 4594936Smux#include <sys/malloc.h> 4694936Smux#include <sys/mutex.h> 47164033Srwatson#include <sys/priv.h> 4840090Smsmith#include <sys/kernel.h> 4940090Smsmith#include <sys/systm.h> 5094936Smux#include <sys/sysent.h> 5194936Smux#include <sys/sysproto.h> 5240090Smsmith#include <sys/libkern.h> 5394936Smux#include <sys/kenv.h> 5440090Smsmith 55163606Srwatson#include <security/mac/mac_framework.h> 56163606Srwatson 57141616Sphkstatic MALLOC_DEFINE(M_KENV, "kenv", "kernel environment"); 5840090Smsmith 5994936Smux#define KENV_SIZE 512 /* Maximum number of environment strings */ 6040090Smsmith 6194936Smux/* pointer to the static environment */ 6294936Smuxchar *kern_envp; 63202050Simpstatic int env_len; 64202050Simpstatic int env_pos; 6594936Smuxstatic char *kernenv_next(char *); 6694936Smux 6794936Smux/* dynamic environment variables */ 6894936Smuxchar **kenvp; 69160217Sscottlstruct mtx kenv_lock; 7094936Smux 7185385Sjhb/* 72167232Srwatson * No need to protect this with a mutex since SYSINITS are single threaded. 7394936Smux */ 7494936Smuxint dynamic_kenv = 0; 7594936Smux 7694936Smux#define KENV_CHECK if (!dynamic_kenv) \ 7794936Smux panic("%s: called before SI_SUB_KMEM", __func__) 7894936Smux 7994936Smuxint 80225617Skmacysys_kenv(td, uap) 8194936Smux struct thread *td; 8294936Smux struct kenv_args /* { 83107850Salfred int what; 84107850Salfred const char *name; 85107850Salfred char *value; 86107850Salfred int len; 8794936Smux } */ *uap; 8894936Smux{ 89160217Sscottl char *name, *value, *buffer = NULL; 90190301Scperciva size_t len, done, needed, buflen; 9194936Smux int error, i; 9295839Speter 9394936Smux KASSERT(dynamic_kenv, ("kenv: dynamic_kenv = 0")); 9494936Smux 9594936Smux error = 0; 96107849Salfred if (uap->what == KENV_DUMP) { 97106308Srwatson#ifdef MAC 98172930Srwatson error = mac_kenv_check_dump(td->td_ucred); 99106308Srwatson if (error) 100106308Srwatson return (error); 101106308Srwatson#endif 102128697Sdas done = needed = 0; 103190301Scperciva buflen = uap->len; 104190301Scperciva if (buflen > KENV_SIZE * (KENV_MNAMELEN + KENV_MVALLEN + 2)) 105190301Scperciva buflen = KENV_SIZE * (KENV_MNAMELEN + 106190301Scperciva KENV_MVALLEN + 2); 107160217Sscottl if (uap->len > 0 && uap->value != NULL) 108190301Scperciva buffer = malloc(buflen, M_TEMP, M_WAITOK|M_ZERO); 109160217Sscottl mtx_lock(&kenv_lock); 110128697Sdas for (i = 0; kenvp[i] != NULL; i++) { 111128697Sdas len = strlen(kenvp[i]) + 1; 112128697Sdas needed += len; 113190301Scperciva len = min(len, buflen - done); 114128697Sdas /* 115128697Sdas * If called with a NULL or insufficiently large 116128697Sdas * buffer, just keep computing the required size. 117128697Sdas */ 118160217Sscottl if (uap->value != NULL && buffer != NULL && len > 0) { 119160217Sscottl bcopy(kenvp[i], buffer + done, len); 120128697Sdas done += len; 12194936Smux } 12294936Smux } 123160217Sscottl mtx_unlock(&kenv_lock); 124160217Sscottl if (buffer != NULL) { 125160217Sscottl error = copyout(buffer, uap->value, done); 126160217Sscottl free(buffer, M_TEMP); 127160217Sscottl } 128128697Sdas td->td_retval[0] = ((done == needed) ? 0 : needed); 129128697Sdas return (error); 13094936Smux } 13194936Smux 132164033Srwatson switch (uap->what) { 133164033Srwatson case KENV_SET: 134164033Srwatson error = priv_check(td, PRIV_KENV_SET); 13594936Smux if (error) 13694936Smux return (error); 137164033Srwatson break; 138164033Srwatson 139164033Srwatson case KENV_UNSET: 140164033Srwatson error = priv_check(td, PRIV_KENV_UNSET); 141164033Srwatson if (error) 142164033Srwatson return (error); 143164033Srwatson break; 14494936Smux } 14594936Smux 146239257Sjh name = malloc(KENV_MNAMELEN + 1, M_TEMP, M_WAITOK); 14794936Smux 148239257Sjh error = copyinstr(uap->name, name, KENV_MNAMELEN + 1, NULL); 14994936Smux if (error) 15094936Smux goto done; 15194936Smux 152107849Salfred switch (uap->what) { 15394936Smux case KENV_GET: 154106308Srwatson#ifdef MAC 155172930Srwatson error = mac_kenv_check_get(td->td_ucred, name); 156106308Srwatson if (error) 157106308Srwatson goto done; 158106308Srwatson#endif 15994936Smux value = getenv(name); 16094936Smux if (value == NULL) { 16194936Smux error = ENOENT; 16294936Smux goto done; 16394936Smux } 16494936Smux len = strlen(value) + 1; 165107849Salfred if (len > uap->len) 166107849Salfred len = uap->len; 167107849Salfred error = copyout(value, uap->value, len); 16894936Smux freeenv(value); 16994936Smux if (error) 17094936Smux goto done; 17194936Smux td->td_retval[0] = len; 17294936Smux break; 17394936Smux case KENV_SET: 174107849Salfred len = uap->len; 17594936Smux if (len < 1) { 17694936Smux error = EINVAL; 17794936Smux goto done; 17894936Smux } 179239257Sjh if (len > KENV_MVALLEN + 1) 180239257Sjh len = KENV_MVALLEN + 1; 181111119Simp value = malloc(len, M_TEMP, M_WAITOK); 182107849Salfred error = copyinstr(uap->value, value, len, NULL); 18394936Smux if (error) { 18494936Smux free(value, M_TEMP); 18594936Smux goto done; 18694936Smux } 187106308Srwatson#ifdef MAC 188172930Srwatson error = mac_kenv_check_set(td->td_ucred, name, value); 189106308Srwatson if (error == 0) 190106308Srwatson#endif 191106308Srwatson setenv(name, value); 19294936Smux free(value, M_TEMP); 19394936Smux break; 19494936Smux case KENV_UNSET: 195106308Srwatson#ifdef MAC 196172930Srwatson error = mac_kenv_check_unset(td->td_ucred, name); 197106308Srwatson if (error) 198106308Srwatson goto done; 199106308Srwatson#endif 20094936Smux error = unsetenv(name); 20194936Smux if (error) 20294936Smux error = ENOENT; 20394936Smux break; 20494936Smux default: 20594936Smux error = EINVAL; 20694936Smux break; 20794936Smux } 20894936Smuxdone: 20994936Smux free(name, M_TEMP); 21094936Smux return (error); 21194936Smux} 21294936Smux 213202050Simpvoid 214202050Simpinit_static_kenv(char *buf, size_t len) 215202050Simp{ 216202050Simp kern_envp = buf; 217202050Simp env_len = len; 218202050Simp env_pos = 0; 219202050Simp} 220202050Simp 22194936Smux/* 22294936Smux * Setup the dynamic kernel environment. 22394936Smux */ 22494936Smuxstatic void 22594936Smuxinit_dynamic_kenv(void *data __unused) 22694936Smux{ 22794936Smux char *cp; 228222216Sjh size_t len; 229222216Sjh int i; 23094936Smux 231148585Snetchild kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV, 232148585Snetchild M_WAITOK | M_ZERO); 23394936Smux i = 0; 234249570Simp if (kern_envp && *kern_envp != '\0') { 235249408Sjchandra for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { 236249408Sjchandra len = strlen(cp) + 1; 237249408Sjchandra if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) { 238249408Sjchandra printf( 239249408Sjchandra "WARNING: too long kenv string, ignoring %s\n", 240249408Sjchandra cp); 241249408Sjchandra continue; 242249408Sjchandra } 243249408Sjchandra if (i < KENV_SIZE) { 244249408Sjchandra kenvp[i] = malloc(len, M_KENV, M_WAITOK); 245249408Sjchandra strcpy(kenvp[i++], cp); 246249408Sjchandra } else 247249408Sjchandra printf( 248249408Sjchandra "WARNING: too many kenv strings, ignoring %s\n", 249249408Sjchandra cp); 250222216Sjh } 25194936Smux } 25294936Smux kenvp[i] = NULL; 25394936Smux 254160217Sscottl mtx_init(&kenv_lock, "kernel environment", NULL, MTX_DEF); 25594936Smux dynamic_kenv = 1; 25694936Smux} 25794936SmuxSYSINIT(kenv, SI_SUB_KMEM, SI_ORDER_ANY, init_dynamic_kenv, NULL); 25894936Smux 25994936Smuxvoid 26094936Smuxfreeenv(char *env) 26194936Smux{ 26294936Smux 26394936Smux if (dynamic_kenv) 26494936Smux free(env, M_KENV); 26594936Smux} 26694936Smux 26794936Smux/* 26894936Smux * Internal functions for string lookup. 26994936Smux */ 27094936Smuxstatic char * 27194936Smux_getenv_dynamic(const char *name, int *idx) 27294936Smux{ 27394936Smux char *cp; 27494936Smux int len, i; 27594936Smux 276160217Sscottl mtx_assert(&kenv_lock, MA_OWNED); 27794936Smux len = strlen(name); 27894936Smux for (cp = kenvp[0], i = 0; cp != NULL; cp = kenvp[++i]) { 279150568Sdavidxu if ((strncmp(cp, name, len) == 0) && 280150568Sdavidxu (cp[len] == '=')) { 28194936Smux if (idx != NULL) 28294936Smux *idx = i; 28394936Smux return (cp + len + 1); 28494936Smux } 28594936Smux } 28694936Smux return (NULL); 28794936Smux} 28894936Smux 28994936Smuxstatic char * 29094936Smux_getenv_static(const char *name) 29194936Smux{ 29294936Smux char *cp, *ep; 29394936Smux int len; 29494936Smux 29594936Smux for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { 29694936Smux for (ep = cp; (*ep != '=') && (*ep != 0); ep++) 29794936Smux ; 29895467Sbde if (*ep != '=') 29995467Sbde continue; 30094936Smux len = ep - cp; 30195467Sbde ep++; 30295467Sbde if (!strncmp(name, cp, len) && name[len] == 0) 30394936Smux return (ep); 30494936Smux } 30594936Smux return (NULL); 30694936Smux} 30794936Smux 30894936Smux/* 30985385Sjhb * Look up an environment variable by name. 31094936Smux * Return a pointer to the string if found. 31194936Smux * The pointer has to be freed with freeenv() 31294936Smux * after use. 31385385Sjhb */ 31440090Smsmithchar * 31578247Spetergetenv(const char *name) 31640090Smsmith{ 31794959Smux char buf[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1]; 31894936Smux char *ret, *cp; 31994936Smux int len; 32094936Smux 32194936Smux if (dynamic_kenv) { 322160217Sscottl mtx_lock(&kenv_lock); 32394936Smux cp = _getenv_dynamic(name, NULL); 32494936Smux if (cp != NULL) { 32594959Smux strcpy(buf, cp); 326160217Sscottl mtx_unlock(&kenv_lock); 32794959Smux len = strlen(buf) + 1; 328111119Simp ret = malloc(len, M_KENV, M_WAITOK); 32994959Smux strcpy(ret, buf); 33094959Smux } else { 331160217Sscottl mtx_unlock(&kenv_lock); 33294936Smux ret = NULL; 333221607Sjh WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 334221607Sjh "getenv"); 33594959Smux } 33694936Smux } else 33794936Smux ret = _getenv_static(name); 33894936Smux return (ret); 33940090Smsmith} 34040090Smsmith 34142706Smsmith/* 34294936Smux * Test if an environment variable is defined. 34394936Smux */ 34494936Smuxint 34594936Smuxtestenv(const char *name) 34694936Smux{ 34794936Smux char *cp; 34894936Smux 34994936Smux if (dynamic_kenv) { 350160217Sscottl mtx_lock(&kenv_lock); 35194936Smux cp = _getenv_dynamic(name, NULL); 352160217Sscottl mtx_unlock(&kenv_lock); 35394936Smux } else 35494936Smux cp = _getenv_static(name); 35594936Smux if (cp != NULL) 35694936Smux return (1); 35794936Smux return (0); 35894936Smux} 35994936Smux 360202050Simpstatic int 361202050Simpsetenv_static(const char *name, const char *value) 362202050Simp{ 363202050Simp int len; 364202050Simp 365202050Simp if (env_pos >= env_len) 366202050Simp return (-1); 367202050Simp 368202050Simp /* Check space for x=y and two nuls */ 369202050Simp len = strlen(name) + strlen(value); 370202050Simp if (len + 3 < env_len - env_pos) { 371202050Simp len = sprintf(&kern_envp[env_pos], "%s=%s", name, value); 372202050Simp env_pos += len+1; 373202050Simp kern_envp[env_pos] = '\0'; 374202050Simp return (0); 375202050Simp } else 376202050Simp return (-1); 377202050Simp 378202050Simp} 379202050Simp 38094936Smux/* 38194936Smux * Set an environment variable by name. 38294936Smux */ 38394959Smuxint 38494936Smuxsetenv(const char *name, const char *value) 38594936Smux{ 38694959Smux char *buf, *cp, *oldenv; 38794959Smux int namelen, vallen, i; 38894936Smux 389202050Simp if (dynamic_kenv == 0 && env_len > 0) 390202050Simp return (setenv_static(name, value)); 391202050Simp 39294936Smux KENV_CHECK; 39394936Smux 39494959Smux namelen = strlen(name) + 1; 395239257Sjh if (namelen > KENV_MNAMELEN + 1) 39694959Smux return (-1); 39794959Smux vallen = strlen(value) + 1; 398239257Sjh if (vallen > KENV_MVALLEN + 1) 39994959Smux return (-1); 400111119Simp buf = malloc(namelen + vallen, M_KENV, M_WAITOK); 40194936Smux sprintf(buf, "%s=%s", name, value); 40294936Smux 403160217Sscottl mtx_lock(&kenv_lock); 40494936Smux cp = _getenv_dynamic(name, &i); 40594936Smux if (cp != NULL) { 40694959Smux oldenv = kenvp[i]; 40794936Smux kenvp[i] = buf; 408160217Sscottl mtx_unlock(&kenv_lock); 40994959Smux free(oldenv, M_KENV); 41094936Smux } else { 41194936Smux /* We add the option if it wasn't found */ 41294936Smux for (i = 0; (cp = kenvp[i]) != NULL; i++) 41394936Smux ; 414148585Snetchild 415148585Snetchild /* Bounds checking */ 416148585Snetchild if (i < 0 || i >= KENV_SIZE) { 417148585Snetchild free(buf, M_KENV); 418160217Sscottl mtx_unlock(&kenv_lock); 419148585Snetchild return (-1); 420148585Snetchild } 421148585Snetchild 42294936Smux kenvp[i] = buf; 42394936Smux kenvp[i + 1] = NULL; 424160217Sscottl mtx_unlock(&kenv_lock); 42594936Smux } 42694959Smux return (0); 42794936Smux} 42894936Smux 42994936Smux/* 43094936Smux * Unset an environment variable string. 43194936Smux */ 43294936Smuxint 43394936Smuxunsetenv(const char *name) 43494936Smux{ 43594959Smux char *cp, *oldenv; 43694936Smux int i, j; 43794936Smux 43894936Smux KENV_CHECK; 43994936Smux 440160217Sscottl mtx_lock(&kenv_lock); 44194936Smux cp = _getenv_dynamic(name, &i); 44294936Smux if (cp != NULL) { 44394959Smux oldenv = kenvp[i]; 44494936Smux for (j = i + 1; kenvp[j] != NULL; j++) 44594936Smux kenvp[i++] = kenvp[j]; 44694936Smux kenvp[i] = NULL; 447160217Sscottl mtx_unlock(&kenv_lock); 44894959Smux free(oldenv, M_KENV); 44994936Smux return (0); 45094936Smux } 451160217Sscottl mtx_unlock(&kenv_lock); 45294936Smux return (-1); 45394936Smux} 45494936Smux 45594936Smux/* 45685385Sjhb * Return a string value from an environment variable. 45785385Sjhb */ 45885385Sjhbint 45985385Sjhbgetenv_string(const char *name, char *data, int size) 46085385Sjhb{ 46195839Speter char *tmp; 46285385Sjhb 46395839Speter tmp = getenv(name); 46495839Speter if (tmp != NULL) { 465105354Srobert strlcpy(data, tmp, size); 46695839Speter freeenv(tmp); 46795839Speter return (1); 46895839Speter } else 46995839Speter return (0); 47085385Sjhb} 47185385Sjhb 47285385Sjhb/* 47342706Smsmith * Return an integer value from an environment variable. 47442706Smsmith */ 47542706Smsmithint 47678247Spetergetenv_int(const char *name, int *data) 47742706Smsmith{ 47895839Speter quad_t tmp; 47995839Speter int rval; 48052947Smjacob 48195839Speter rval = getenv_quad(name, &tmp); 48295839Speter if (rval) 48395839Speter *data = (int) tmp; 48495839Speter return (rval); 48552947Smjacob} 48652947Smjacob 48752947Smjacob/* 488172612Sdes * Return an unsigned integer value from an environment variable. 489172612Sdes */ 490172612Sdesint 491172612Sdesgetenv_uint(const char *name, unsigned int *data) 492172612Sdes{ 493172612Sdes quad_t tmp; 494172612Sdes int rval; 495172612Sdes 496172612Sdes rval = getenv_quad(name, &tmp); 497172612Sdes if (rval) 498172612Sdes *data = (unsigned int) tmp; 499172612Sdes return (rval); 500172612Sdes} 501172612Sdes 502172612Sdes/* 503137099Sdes * Return a long value from an environment variable. 504137099Sdes */ 505172612Sdesint 506137099Sdesgetenv_long(const char *name, long *data) 507137099Sdes{ 508137099Sdes quad_t tmp; 509172612Sdes int rval; 510137099Sdes 511137099Sdes rval = getenv_quad(name, &tmp); 512137099Sdes if (rval) 513137099Sdes *data = (long) tmp; 514137099Sdes return (rval); 515137099Sdes} 516137099Sdes 517137099Sdes/* 518137099Sdes * Return an unsigned long value from an environment variable. 519137099Sdes */ 520172612Sdesint 521137099Sdesgetenv_ulong(const char *name, unsigned long *data) 522137099Sdes{ 523137099Sdes quad_t tmp; 524172612Sdes int rval; 525137099Sdes 526137099Sdes rval = getenv_quad(name, &tmp); 527137099Sdes if (rval) 528137099Sdes *data = (unsigned long) tmp; 529137099Sdes return (rval); 530137099Sdes} 531137099Sdes 532137099Sdes/* 53352947Smjacob * Return a quad_t value from an environment variable. 53452947Smjacob */ 53585385Sjhbint 53678247Spetergetenv_quad(const char *name, quad_t *data) 53752947Smjacob{ 53895839Speter char *value; 53995839Speter char *vtp; 54095839Speter quad_t iv; 54195839Speter 54295839Speter value = getenv(name); 54395839Speter if (value == NULL) 54495839Speter return (0); 54595839Speter iv = strtoq(value, &vtp, 0); 546143319Sdes if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { 547143319Sdes freeenv(value); 54895839Speter return (0); 549143319Sdes } 550143151Sdes switch (vtp[0]) { 551143151Sdes case 't': case 'T': 552143151Sdes iv *= 1024; 553143151Sdes case 'g': case 'G': 554143151Sdes iv *= 1024; 555143151Sdes case 'm': case 'M': 556143151Sdes iv *= 1024; 557143151Sdes case 'k': case 'K': 558143151Sdes iv *= 1024; 559143151Sdes case '\0': 560143151Sdes break; 561143151Sdes default: 562143319Sdes freeenv(value); 563143151Sdes return (0); 56495839Speter } 56595839Speter *data = iv; 566143319Sdes freeenv(value); 56795839Speter return (1); 56842706Smsmith} 56940090Smsmith 57083744Speter/* 57140090Smsmith * Find the next entry after the one which (cp) falls within, return a 57240090Smsmith * pointer to its start or NULL if there are no more. 57340090Smsmith */ 57440090Smsmithstatic char * 57540090Smsmithkernenv_next(char *cp) 57640090Smsmith{ 57795839Speter 57895839Speter if (cp != NULL) { 57995839Speter while (*cp != 0) 58095839Speter cp++; 58195839Speter cp++; 58295839Speter if (*cp == 0) 58395839Speter cp = NULL; 58495839Speter } 58595839Speter return (cp); 58640090Smsmith} 58740090Smsmith 58877900Spetervoid 58977900Spetertunable_int_init(void *data) 59077900Speter{ 59177900Speter struct tunable_int *d = (struct tunable_int *)data; 59277900Speter 59377900Speter TUNABLE_INT_FETCH(d->path, d->var); 59477900Speter} 59577900Speter 59677900Spetervoid 597137099Sdestunable_long_init(void *data) 598137099Sdes{ 599137099Sdes struct tunable_long *d = (struct tunable_long *)data; 600137099Sdes 601137099Sdes TUNABLE_LONG_FETCH(d->path, d->var); 602137099Sdes} 603137099Sdes 604137099Sdesvoid 605137099Sdestunable_ulong_init(void *data) 606137099Sdes{ 607137099Sdes struct tunable_ulong *d = (struct tunable_ulong *)data; 608137099Sdes 609137099Sdes TUNABLE_ULONG_FETCH(d->path, d->var); 610137099Sdes} 611137099Sdes 612137099Sdesvoid 613180661Spjdtunable_quad_init(void *data) 614180661Spjd{ 615180661Spjd struct tunable_quad *d = (struct tunable_quad *)data; 616180661Spjd 617180661Spjd TUNABLE_QUAD_FETCH(d->path, d->var); 618180661Spjd} 619180661Spjd 620180661Spjdvoid 62177900Spetertunable_str_init(void *data) 62277900Speter{ 62377900Speter struct tunable_str *d = (struct tunable_str *)data; 62477900Speter 62577900Speter TUNABLE_STR_FETCH(d->path, d->var, d->size); 62677900Speter} 627