Revert r335995 due to accidental changes snuck in
This commit is contained in:
parent
81dac87135
commit
e28687347f
@ -57,21 +57,14 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
static char *_getenv_dynamic_locked(const char *name, int *idx);
|
||||
static char *_getenv_dynamic(const char *name, int *idx);
|
||||
|
||||
static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
|
||||
|
||||
#define KENV_SIZE 512 /* Maximum number of environment strings */
|
||||
|
||||
/* pointer to the config-generated static environment */
|
||||
/* pointer to the static environment */
|
||||
char *kern_envp;
|
||||
|
||||
/* pointer to the md-static environment */
|
||||
char *md_envp;
|
||||
static int md_env_len;
|
||||
static int md_env_pos;
|
||||
|
||||
static int env_len;
|
||||
static int env_pos;
|
||||
static char *kernenv_next(char *);
|
||||
|
||||
/* dynamic environment variables */
|
||||
@ -227,8 +220,15 @@ sys_kenv(td, uap)
|
||||
* environment obtained from a boot loader, or to provide an empty buffer into
|
||||
* which MD code can store an initial environment using kern_setenv() calls.
|
||||
*
|
||||
* kern_envp is set to the static_env generated by config(8). This implements
|
||||
* the env keyword described in config(5).
|
||||
* When a copy of an initial environment is passed in, we start by scanning that
|
||||
* env for overrides to the compiled-in envmode and hintmode variables.
|
||||
*
|
||||
* If the global envmode is 1, the environment is initialized from the global
|
||||
* static_env[], regardless of the arguments passed. This implements the env
|
||||
* keyword described in config(5). In this case env_pos is set to env_len,
|
||||
* causing kern_setenv() to return -1 (if len > 0) or panic (if len == 0) until
|
||||
* the dynamic environment is available. The envmode and static_env variables
|
||||
* are defined in env.c which is generated by config(8).
|
||||
*
|
||||
* If len is non-zero, the caller is providing an empty buffer. The caller will
|
||||
* subsequently use kern_setenv() to add up to len bytes of initial environment
|
||||
@ -237,93 +237,30 @@ sys_kenv(td, uap)
|
||||
* If len is zero, the caller is providing a pre-loaded buffer containing
|
||||
* environment strings. Additional strings cannot be added until the dynamic
|
||||
* environment is available. The memory pointed to must remain stable at least
|
||||
* until sysinit runs init_dynamic_kenv() and preferably until after SI_SUB_KMEM
|
||||
* is finished so that subr_hints routines may continue to use it until the
|
||||
* environments have been fully merged at the end of the pass. If no initial
|
||||
* environment is available from the boot loader, passing a NULL pointer allows
|
||||
* the static_env to be installed if it is configured. In this case, any call
|
||||
* to kern_setenv() prior to the setup of the dynamic environment will result in
|
||||
* a panic.
|
||||
* until sysinit runs init_dynamic_kenv(). If no initial environment is
|
||||
* available from the boot loader, passing a NULL pointer allows the static_env
|
||||
* to be installed if it is configured.
|
||||
*/
|
||||
void
|
||||
init_static_kenv(char *buf, size_t len)
|
||||
{
|
||||
char *eval;
|
||||
char *cp;
|
||||
|
||||
for (cp = buf; cp != NULL && cp[0] != '\0'; cp += strlen(cp) + 1) {
|
||||
if (strcmp(cp, "static_env.disabled=1") == 0)
|
||||
envmode = 0;
|
||||
if (strcmp(cp, "static_hints.disabled=1") == 0)
|
||||
hintmode = 0;
|
||||
}
|
||||
|
||||
md_envp = buf;
|
||||
md_env_len = len;
|
||||
md_env_pos = 0;
|
||||
|
||||
/*
|
||||
* static_env and static_hints may both be disabled, but in slightly
|
||||
* different ways. For static_env, we just don't setup kern_envp and
|
||||
* it's as if a static env wasn't even provided. For static_hints,
|
||||
* we effectively zero out the buffer to stop the rest of the kernel
|
||||
* from being able to use it.
|
||||
*
|
||||
* We're intentionally setting this up so that static_hints.disabled may
|
||||
* be specified in either the MD env or the static env. This keeps us
|
||||
* consistent in our new world view.
|
||||
*/
|
||||
eval = kern_getenv("static_env.disabled");
|
||||
if (eval == NULL || strcmp(eval, "1") != 0)
|
||||
if (envmode == 1) {
|
||||
kern_envp = static_env;
|
||||
eval = kern_getenv("static_hints.disabled");
|
||||
if (eval != NULL && strcmp(eval, "1") == 0)
|
||||
*static_hints = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
init_dynamic_kenv_from(char *init_env, int *curpos)
|
||||
{
|
||||
char *cp, *cpnext, *eqpos, *found;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (init_env && *init_env != '\0') {
|
||||
found = NULL;
|
||||
i = *curpos;
|
||||
for (cp = init_env; cp != NULL; cp = cpnext) {
|
||||
cpnext = kernenv_next(cp);
|
||||
len = strlen(cp) + 1;
|
||||
if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
|
||||
printf(
|
||||
"WARNING: too long kenv string, ignoring %s\n",
|
||||
cp);
|
||||
goto sanitize;
|
||||
}
|
||||
eqpos = strchr(cp, '=');
|
||||
if (eqpos == NULL) {
|
||||
printf(
|
||||
"WARNING: malformed static env value, ignoring %s\n",
|
||||
cp);
|
||||
goto sanitize;
|
||||
}
|
||||
*eqpos = 0;
|
||||
/*
|
||||
* De-dupe the environment as we go. We don't add the
|
||||
* duplicated assignments because config(8) will flip
|
||||
* the order of the static environment around to make
|
||||
* kernel processing match the order of specification
|
||||
* in the kernel config.
|
||||
*/
|
||||
found = _getenv_dynamic_locked(cp, NULL);
|
||||
*eqpos = '=';
|
||||
if (found != NULL)
|
||||
goto sanitize;
|
||||
if (i > KENV_SIZE) {
|
||||
printf(
|
||||
"WARNING: too many kenv strings, ignoring %s\n",
|
||||
cp);
|
||||
goto sanitize;
|
||||
}
|
||||
|
||||
kenvp[i] = malloc(len, M_KENV, M_WAITOK);
|
||||
strcpy(kenvp[i++], cp);
|
||||
sanitize:
|
||||
explicit_bzero(cp, len - 1);
|
||||
}
|
||||
*curpos = i;
|
||||
env_len = len;
|
||||
env_pos = len;
|
||||
} else {
|
||||
kern_envp = buf;
|
||||
env_len = len;
|
||||
env_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,15 +270,34 @@ init_dynamic_kenv_from(char *init_env, int *curpos)
|
||||
static void
|
||||
init_dynamic_kenv(void *data __unused)
|
||||
{
|
||||
int dynamic_envpos;
|
||||
char *cp, *cpnext;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV,
|
||||
M_WAITOK | M_ZERO);
|
||||
|
||||
dynamic_envpos = 0;
|
||||
init_dynamic_kenv_from(md_envp, &dynamic_envpos);
|
||||
init_dynamic_kenv_from(kern_envp, &dynamic_envpos);
|
||||
kenvp[dynamic_envpos] = NULL;
|
||||
i = 0;
|
||||
if (kern_envp && *kern_envp != '\0') {
|
||||
for (cp = kern_envp; cp != NULL; cp = cpnext) {
|
||||
cpnext = kernenv_next(cp);
|
||||
len = strlen(cp) + 1;
|
||||
if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
|
||||
printf(
|
||||
"WARNING: too long kenv string, ignoring %s\n",
|
||||
cp);
|
||||
continue;
|
||||
}
|
||||
if (i < KENV_SIZE) {
|
||||
kenvp[i] = malloc(len, M_KENV, M_WAITOK);
|
||||
strcpy(kenvp[i++], cp);
|
||||
explicit_bzero(cp, strlen(cp));
|
||||
} else
|
||||
printf(
|
||||
"WARNING: too many kenv strings, ignoring %s\n",
|
||||
cp);
|
||||
}
|
||||
}
|
||||
kenvp[i] = NULL;
|
||||
|
||||
mtx_init(&kenv_lock, "kernel environment", NULL, MTX_DEF);
|
||||
dynamic_kenv = 1;
|
||||
@ -362,11 +318,12 @@ freeenv(char *env)
|
||||
* Internal functions for string lookup.
|
||||
*/
|
||||
static char *
|
||||
_getenv_dynamic_locked(const char *name, int *idx)
|
||||
_getenv_dynamic(const char *name, int *idx)
|
||||
{
|
||||
char *cp;
|
||||
int len, i;
|
||||
|
||||
mtx_assert(&kenv_lock, MA_OWNED);
|
||||
len = strlen(name);
|
||||
for (cp = kenvp[0], i = 0; cp != NULL; cp = kenvp[++i]) {
|
||||
if ((strncmp(cp, name, len) == 0) &&
|
||||
@ -380,20 +337,12 @@ _getenv_dynamic_locked(const char *name, int *idx)
|
||||
}
|
||||
|
||||
static char *
|
||||
_getenv_dynamic(const char *name, int *idx)
|
||||
{
|
||||
|
||||
mtx_assert(&kenv_lock, MA_OWNED);
|
||||
return (_getenv_dynamic_locked(name, idx));
|
||||
}
|
||||
|
||||
static char *
|
||||
_getenv_static_from(char *chkenv, const char *name)
|
||||
_getenv_static(const char *name)
|
||||
{
|
||||
char *cp, *ep;
|
||||
int len;
|
||||
|
||||
for (cp = chkenv; cp != NULL; cp = kernenv_next(cp)) {
|
||||
for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) {
|
||||
for (ep = cp; (*ep != '=') && (*ep != 0); ep++)
|
||||
;
|
||||
if (*ep != '=')
|
||||
@ -406,20 +355,6 @@ _getenv_static_from(char *chkenv, const char *name)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
_getenv_static(const char *name)
|
||||
{
|
||||
char *val;
|
||||
|
||||
val = _getenv_static_from(md_envp, name);
|
||||
if (val != NULL)
|
||||
return (val);
|
||||
val = _getenv_static_from(kern_envp, name);
|
||||
if (val != NULL)
|
||||
return (val);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up an environment variable by name.
|
||||
* Return a pointer to the string if found.
|
||||
@ -464,25 +399,20 @@ testenv(const char *name)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set an environment variable in the MD-static environment. This cannot
|
||||
* feasibly be done on config(8)-generated static environments as they don't
|
||||
* generally include space for extra variables.
|
||||
*/
|
||||
static int
|
||||
setenv_static(const char *name, const char *value)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (md_env_pos >= md_env_len)
|
||||
if (env_pos >= env_len)
|
||||
return (-1);
|
||||
|
||||
/* Check space for x=y and two nuls */
|
||||
len = strlen(name) + strlen(value);
|
||||
if (len + 3 < md_env_len - md_env_pos) {
|
||||
len = sprintf(&md_envp[md_env_pos], "%s=%s", name, value);
|
||||
md_env_pos += len+1;
|
||||
md_envp[md_env_pos] = '\0';
|
||||
if (len + 3 < env_len - env_pos) {
|
||||
len = sprintf(&kern_envp[env_pos], "%s=%s", name, value);
|
||||
env_pos += len+1;
|
||||
kern_envp[env_pos] = '\0';
|
||||
return (0);
|
||||
} else
|
||||
return (-1);
|
||||
@ -498,7 +428,7 @@ kern_setenv(const char *name, const char *value)
|
||||
char *buf, *cp, *oldenv;
|
||||
int namelen, vallen, i;
|
||||
|
||||
if (dynamic_kenv == 0 && md_env_len > 0)
|
||||
if (dynamic_kenv == 0 && env_len > 0)
|
||||
return (setenv_static(name, value));
|
||||
|
||||
KENV_CHECK;
|
||||
|
@ -31,35 +31,60 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#define FBACK_MDENV 0 /* MD env (e.g. loader.conf) */
|
||||
#define FBACK_STENV 1 /* Static env */
|
||||
#define FBACK_STATIC 2 /* static_hints */
|
||||
|
||||
/*
|
||||
* We'll use hintenv_merged to indicate that the dynamic environment has been
|
||||
* properly prepared for hint usage. This implies that the dynamic environment
|
||||
* has already been setup (dynamic_kenv) and that we have added any supplied
|
||||
* static_hints to the dynamic environment.
|
||||
*/
|
||||
static int hintenv_merged;
|
||||
#define HINTMODE_KENV 0
|
||||
#define HINTMODE_STATIC 1
|
||||
#define HINTMODE_FALLBACK 2
|
||||
|
||||
/*
|
||||
* Access functions for device resources.
|
||||
*/
|
||||
|
||||
static void
|
||||
static_hints_to_env(void *data __unused)
|
||||
static int checkmethod = 1;
|
||||
static char *hintp;
|
||||
|
||||
/*
|
||||
* Define kern.hintmode sysctl, which only accept value 2, that cause to
|
||||
* switch from Static KENV mode to Dynamic KENV. So systems that have hints
|
||||
* compiled into kernel will be able to see/modify KENV (and hints too).
|
||||
*/
|
||||
|
||||
static int
|
||||
sysctl_hintmode(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
const char *cp;
|
||||
char *line, *eq;
|
||||
int eqidx, i;
|
||||
int eqidx, error, i, value;
|
||||
|
||||
value = hintmode;
|
||||
|
||||
/* Fetch candidate for new hintmode value */
|
||||
error = sysctl_handle_int(oidp, &value, 0, req);
|
||||
if (error || req->newptr == NULL)
|
||||
return (error);
|
||||
|
||||
if (value != HINTMODE_FALLBACK)
|
||||
/* Only accept swithing to hintmode 2 */
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* The rest of the sysctl handler is just making sure that our
|
||||
* environment is consistent with the world we've already seen.
|
||||
* If we came from kenv at all, then we have nothing to do: static
|
||||
* kenv will get merged into dynamic kenv as soon as kmem becomes
|
||||
* available, dynamic kenv is the environment we'd be setting these
|
||||
* things in anyways. Therefore, we have nothing left to do unless
|
||||
* we came from a static hints configuration.
|
||||
*/
|
||||
if (hintmode != HINTMODE_STATIC) {
|
||||
hintmode = value;
|
||||
return (0);
|
||||
}
|
||||
|
||||
cp = static_hints;
|
||||
while (cp && *cp != '\0') {
|
||||
@ -70,48 +95,20 @@ static_hints_to_env(void *data __unused)
|
||||
eqidx = eq - cp;
|
||||
|
||||
i = strlen(cp);
|
||||
line = malloc(i + 1, M_TEMP, M_WAITOK);
|
||||
line = malloc(i+1, M_TEMP, M_WAITOK);
|
||||
strcpy(line, cp);
|
||||
line[eqidx] = line[i] = '\0';
|
||||
/*
|
||||
* Before adding a hint to the dynamic environment, check if
|
||||
* another value for said hint has already been added. This is
|
||||
* needed because static environment overrides static hints and
|
||||
* dynamic environment overrides all.
|
||||
*/
|
||||
if (testenv(line) == 0)
|
||||
kern_setenv(line, line + eqidx + 1);
|
||||
line[eqidx] = '\0';
|
||||
kern_setenv(line, line + eqidx + 1);
|
||||
free(line, M_TEMP);
|
||||
cp += i + 1;
|
||||
}
|
||||
hintenv_merged = 1;
|
||||
|
||||
hintmode = value;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Any time after dynamic env is setup */
|
||||
SYSINIT(hintenv, SI_SUB_KMEM, SI_ORDER_ANY, static_hints_to_env, NULL);
|
||||
|
||||
/*
|
||||
* Checks the environment to see if we even have any hints. If it has no hints,
|
||||
* then res_find can take the hint that there's no point in searching it and
|
||||
* either move on to the next environment or fail early.
|
||||
*/
|
||||
static bool
|
||||
_res_checkenv(char *envp)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp = envp;
|
||||
while (cp) {
|
||||
if (strncmp(cp, "hint.", 5) == 0)
|
||||
return (true);
|
||||
while (*cp != '\0')
|
||||
cp++;
|
||||
cp++;
|
||||
if (*cp == '\0')
|
||||
break;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
SYSCTL_PROC(_kern, OID_AUTO, hintmode, CTLTYPE_INT|CTLFLAG_RW,
|
||||
&hintmode, 0, sysctl_hintmode, "I", "Get/set current hintmode");
|
||||
|
||||
/*
|
||||
* Evil wildcarding resource string lookup.
|
||||
@ -119,103 +116,82 @@ _res_checkenv(char *envp)
|
||||
* The start point can be remembered for incremental searches.
|
||||
*/
|
||||
static int
|
||||
res_find(char **hintp_cookie, int *line, int *startln,
|
||||
res_find(int *line, int *startln,
|
||||
const char *name, int *unit, const char *resname, const char *value,
|
||||
const char **ret_name, int *ret_namelen, int *ret_unit,
|
||||
const char **ret_resname, int *ret_resnamelen, const char **ret_value)
|
||||
{
|
||||
int dyn_used = 0, fbacklvl = FBACK_MDENV, hit, i = 0, n = 0;
|
||||
int n = 0, hit, i = 0;
|
||||
char r_name[32];
|
||||
int r_unit;
|
||||
int r_unit, use_kenv = (hintmode != HINTMODE_STATIC && dynamic_kenv);
|
||||
char r_resname[32];
|
||||
char r_value[128];
|
||||
const char *s, *cp;
|
||||
char *hintp, *p;
|
||||
char *p;
|
||||
|
||||
|
||||
/*
|
||||
* We are expecting that the caller will pass us a hintp_cookie that
|
||||
* they are tracking. Upon entry, if *hintp_cookie is *not* set, this
|
||||
* indicates to us that we should be figuring out based on the current
|
||||
* environment where to search. This keeps us sane throughout the
|
||||
* entirety of a single search.
|
||||
*/
|
||||
if (*hintp_cookie == NULL) {
|
||||
if (checkmethod) {
|
||||
hintp = NULL;
|
||||
if (hintenv_merged) {
|
||||
/*
|
||||
* static_hints, if it was previously used, has
|
||||
* already been folded in to the environment
|
||||
* by this point.
|
||||
*/
|
||||
mtx_lock(&kenv_lock);
|
||||
cp = kenvp[0];
|
||||
for (i = 0; cp != NULL; cp = kenvp[++i]) {
|
||||
if (!strncmp(cp, "hint.", 5)) {
|
||||
hintp = kenvp[0];
|
||||
break;
|
||||
|
||||
switch (hintmode) {
|
||||
case HINTMODE_KENV: /* loader hints in environment only */
|
||||
break;
|
||||
case HINTMODE_STATIC: /* static hints only */
|
||||
hintp = static_hints;
|
||||
checkmethod = 0;
|
||||
break;
|
||||
case HINTMODE_FALLBACK: /* fallback mode */
|
||||
if (dynamic_kenv) {
|
||||
mtx_lock(&kenv_lock);
|
||||
cp = kenvp[0];
|
||||
for (i = 0; cp != NULL; cp = kenvp[++i]) {
|
||||
if (!strncmp(cp, "hint.", 5)) {
|
||||
use_kenv = 1;
|
||||
checkmethod = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&kenv_lock);
|
||||
} else {
|
||||
cp = kern_envp;
|
||||
while (cp) {
|
||||
if (strncmp(cp, "hint.", 5) == 0) {
|
||||
cp = NULL;
|
||||
hintp = kern_envp;
|
||||
break;
|
||||
}
|
||||
while (*cp != '\0')
|
||||
cp++;
|
||||
cp++;
|
||||
if (*cp == '\0') {
|
||||
cp = NULL;
|
||||
hintp = static_hints;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx_unlock(&kenv_lock);
|
||||
dyn_used = 1;
|
||||
} else {
|
||||
/*
|
||||
* We'll have a chance to keep coming back here until
|
||||
* we've actually exhausted all of our possibilities.
|
||||
* We might have chosen the MD/Static env because it
|
||||
* had some kind of hints, but perhaps it didn't have
|
||||
* the hint we are looking for. We don't provide any
|
||||
* fallback when searching the dynamic environment.
|
||||
*/
|
||||
fallback:
|
||||
if (dyn_used || fbacklvl >= FBACK_STATIC)
|
||||
return (ENOENT);
|
||||
|
||||
if (fbacklvl <= FBACK_MDENV &&
|
||||
_res_checkenv(md_envp)) {
|
||||
hintp = md_envp;
|
||||
goto found;
|
||||
}
|
||||
fbacklvl++;
|
||||
|
||||
if (fbacklvl <= FBACK_STENV &&
|
||||
_res_checkenv(kern_envp)) {
|
||||
hintp = kern_envp;
|
||||
goto found;
|
||||
}
|
||||
fbacklvl++;
|
||||
|
||||
/* We'll fallback to static_hints if needed/can */
|
||||
if (fbacklvl <= FBACK_STATIC &&
|
||||
_res_checkenv(static_hints))
|
||||
hintp = static_hints;
|
||||
found:
|
||||
fbacklvl++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (hintp == NULL) {
|
||||
if (dynamic_kenv) {
|
||||
use_kenv = 1;
|
||||
checkmethod = 0;
|
||||
} else
|
||||
hintp = kern_envp;
|
||||
}
|
||||
|
||||
if (hintp == NULL)
|
||||
return (ENOENT);
|
||||
*hintp_cookie = hintp;
|
||||
} else {
|
||||
hintp = *hintp_cookie;
|
||||
if (hintenv_merged && hintp == kenvp[0])
|
||||
dyn_used = 1;
|
||||
else
|
||||
/*
|
||||
* If we aren't using the dynamic environment, we need
|
||||
* to run through the proper fallback procedure again.
|
||||
* This is so that we do continuations right if we're
|
||||
* working with *line and *startln.
|
||||
*/
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (dyn_used) {
|
||||
if (use_kenv) {
|
||||
mtx_lock(&kenv_lock);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
cp = hintp;
|
||||
cp = kenvp[0];
|
||||
if (cp == NULL) {
|
||||
mtx_unlock(&kenv_lock);
|
||||
return (ENOENT);
|
||||
}
|
||||
} else
|
||||
cp = hintp;
|
||||
while (cp) {
|
||||
hit = 1;
|
||||
(*line)++;
|
||||
@ -224,28 +200,25 @@ res_find(char **hintp_cookie, int *line, int *startln,
|
||||
else
|
||||
n = sscanf(cp, "hint.%32[^.].%d.%32[^=]=%127s",
|
||||
r_name, &r_unit, r_resname, r_value);
|
||||
/* We'll circumvent all of the checks if we already know */
|
||||
if (hit) {
|
||||
if (n != 4) {
|
||||
printf("CONFIG: invalid hint '%s'\n", cp);
|
||||
p = strchr(cp, 'h');
|
||||
*p = 'H';
|
||||
hit = 0;
|
||||
}
|
||||
if (hit && startln && *startln >= 0 && *line < *startln)
|
||||
hit = 0;
|
||||
if (hit && name && strcmp(name, r_name) != 0)
|
||||
hit = 0;
|
||||
if (hit && unit && *unit != r_unit)
|
||||
hit = 0;
|
||||
if (hit && resname && strcmp(resname, r_resname) != 0)
|
||||
hit = 0;
|
||||
if (hit && value && strcmp(value, r_value) != 0)
|
||||
hit = 0;
|
||||
if (hit)
|
||||
break;
|
||||
if (hit && n != 4) {
|
||||
printf("CONFIG: invalid hint '%s'\n", cp);
|
||||
p = strchr(cp, 'h');
|
||||
*p = 'H';
|
||||
hit = 0;
|
||||
}
|
||||
if (dyn_used) {
|
||||
if (hit && startln && *startln >= 0 && *line < *startln)
|
||||
hit = 0;
|
||||
if (hit && name && strcmp(name, r_name) != 0)
|
||||
hit = 0;
|
||||
if (hit && unit && *unit != r_unit)
|
||||
hit = 0;
|
||||
if (hit && resname && strcmp(resname, r_resname) != 0)
|
||||
hit = 0;
|
||||
if (hit && value && strcmp(value, r_value) != 0)
|
||||
hit = 0;
|
||||
if (hit)
|
||||
break;
|
||||
if (use_kenv) {
|
||||
cp = kenvp[++i];
|
||||
if (cp == NULL)
|
||||
break;
|
||||
@ -259,10 +232,10 @@ res_find(char **hintp_cookie, int *line, int *startln,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dyn_used)
|
||||
if (use_kenv)
|
||||
mtx_unlock(&kenv_lock);
|
||||
if (cp == NULL)
|
||||
goto fallback;
|
||||
return ENOENT;
|
||||
|
||||
s = cp;
|
||||
/* This is a bit of a hack, but at least is reentrant */
|
||||
@ -300,13 +273,11 @@ resource_find(int *line, int *startln,
|
||||
{
|
||||
int i;
|
||||
int un;
|
||||
char *hintp;
|
||||
|
||||
*line = 0;
|
||||
hintp = NULL;
|
||||
|
||||
/* Search for exact unit matches first */
|
||||
i = res_find(&hintp, line, startln, name, unit, resname, value,
|
||||
i = res_find(line, startln, name, unit, resname, value,
|
||||
ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen,
|
||||
ret_value);
|
||||
if (i == 0)
|
||||
@ -315,7 +286,7 @@ resource_find(int *line, int *startln,
|
||||
return ENOENT;
|
||||
/* If we are still here, search for wildcard matches */
|
||||
un = -1;
|
||||
i = res_find(&hintp, line, startln, name, &un, resname, value,
|
||||
i = res_find(line, startln, name, &un, resname, value,
|
||||
ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen,
|
||||
ret_value);
|
||||
if (i == 0)
|
||||
|
@ -269,7 +269,7 @@ ttydev_open(struct cdev *dev, int oflags, int devtype __unused,
|
||||
struct thread *td)
|
||||
{
|
||||
struct tty *tp;
|
||||
int cflags, error;
|
||||
int error;
|
||||
|
||||
tp = dev->si_drv1;
|
||||
error = 0;
|
||||
@ -325,14 +325,7 @@ ttydev_open(struct cdev *dev, int oflags, int devtype __unused,
|
||||
if (TTY_CALLOUT(tp, dev) || dev == dev_console)
|
||||
tp->t_termios.c_cflag |= CLOCAL;
|
||||
|
||||
cflags = 0;
|
||||
if (tp->t_termios.c_cflag & CDTR_IFLOW)
|
||||
cflags |= SER_DTR;
|
||||
if (tp->t_termios.c_cflag & CRTS_IFLOW)
|
||||
cflags |= SER_RTS;
|
||||
|
||||
if (cflags != 0)
|
||||
ttydevsw_modem(tp, cflags, 0);
|
||||
ttydevsw_modem(tp, SER_DTR|SER_RTS, 0);
|
||||
|
||||
error = ttydevsw_open(tp);
|
||||
if (error != 0)
|
||||
|
@ -156,10 +156,11 @@ void kassert_panic(const char *fmt, ...) __printflike(1, 2);
|
||||
* XXX most of these variables should be const.
|
||||
*/
|
||||
extern int osreldate;
|
||||
extern int envmode;
|
||||
extern int hintmode; /* 0 = off. 1 = config, 2 = fallback */
|
||||
extern int dynamic_kenv;
|
||||
extern struct mtx kenv_lock;
|
||||
extern char *kern_envp;
|
||||
extern char *md_envp;
|
||||
extern char static_env[];
|
||||
extern char static_hints[]; /* by config for now */
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 5, 2018
|
||||
.Dd June 26, 2018
|
||||
.Dt CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -114,24 +114,12 @@ are defined in the file
|
||||
.Pp
|
||||
.It Ic env Ar filename
|
||||
Specifies a filename containing a kernel environment definition.
|
||||
.Pp
|
||||
The kernel will augment this compiled-in environment with the environment
|
||||
prepared for it at boot time by
|
||||
The kernel normally uses an environment prepared for it at boot time
|
||||
by
|
||||
.Xr loader 8 .
|
||||
Environment variables specified in the
|
||||
.Xr loader 8
|
||||
environment will take precedence over environment variables specified in
|
||||
.Ar filename ,
|
||||
and environment variables specified in the dynamic environment take precedence
|
||||
over both of these.
|
||||
.Pp
|
||||
.Va static_env.disabled=1
|
||||
may be specified in the
|
||||
.Xr loader 8
|
||||
environment to disable use of this compiled-in environment.
|
||||
This option has no effect if specified in any environment after the
|
||||
.Xr loader 8
|
||||
environment is processed.
|
||||
This directive makes the kernel ignore the boot environment and use
|
||||
the compiled-in environment instead, unless the boot environment contains
|
||||
.Va static_env.disabled=1 .
|
||||
.Pp
|
||||
This directive is useful for setting kernel tunables in
|
||||
embedded environments that do not start from
|
||||
@ -184,28 +172,9 @@ time (see
|
||||
.Xr device.hints 5 ) .
|
||||
This directive configures the kernel to use the static device configuration
|
||||
listed in
|
||||
.Ar filename .
|
||||
.Pp
|
||||
Hints provided in this static device configuration will be overwritten in the
|
||||
order in which they're encountered.
|
||||
Hints in the compiled-in environment takes precedence over compiled-in hints,
|
||||
and hints in the environment prepared for the kernel by
|
||||
.Xr loader 8
|
||||
takes precedence over hints in the compiled-in environment.
|
||||
.Pp
|
||||
Once the dynamic environment becomes available, all compiled-in hints will be
|
||||
added to the dynamic environment if they do not already have an override in
|
||||
the dynamic environment.
|
||||
The dynamic environment will then be used for all searches of hints.
|
||||
.Pp
|
||||
.Va static_hints.disabled=1
|
||||
may be specified in either a compiled-in environment or the
|
||||
.Xr loader 8
|
||||
environment to disable use of these hints files.
|
||||
This option has no effect if specified in any environment after the
|
||||
.Xr loader 8
|
||||
environment is processed.
|
||||
.Pp
|
||||
.Ar filename ,
|
||||
unless the boot environment contains
|
||||
.Va static_hints.disabled=1 .
|
||||
The file
|
||||
.Ar filename
|
||||
must conform to the syntax specified by
|
||||
|
@ -179,6 +179,8 @@ SLIST_HEAD(, includepath) includepath;
|
||||
extern char *ident;
|
||||
extern char kernconfstr[];
|
||||
extern int do_trace;
|
||||
extern int envmode;
|
||||
extern int hintmode;
|
||||
extern int incignore;
|
||||
|
||||
char *get_word(FILE *);
|
||||
|
@ -82,7 +82,8 @@
|
||||
|
||||
struct device_head dtab;
|
||||
char *ident;
|
||||
char *env;
|
||||
int envmode;
|
||||
int hintmode;
|
||||
int yyline;
|
||||
const char *yyfile;
|
||||
struct file_list_head ftab;
|
||||
@ -200,6 +201,7 @@ Config_spec:
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
hint->hint_name = $2;
|
||||
STAILQ_INSERT_HEAD(&hints, hint, hint_next);
|
||||
hintmode = 1;
|
||||
}
|
||||
|
||||
System_spec:
|
||||
@ -359,6 +361,7 @@ newenvvar(char *name, bool is_file)
|
||||
envvar->env_str = name;
|
||||
envvar->env_is_file = is_file;
|
||||
STAILQ_INSERT_HEAD(&envvars, envvar, envvar_next);
|
||||
envmode = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -197,6 +197,7 @@ makehints(void)
|
||||
fprintf(ofp, "#include <sys/types.h>\n");
|
||||
fprintf(ofp, "#include <sys/systm.h>\n");
|
||||
fprintf(ofp, "\n");
|
||||
fprintf(ofp, "int hintmode = %d;\n", hintmode);
|
||||
fprintf(ofp, "char static_hints[] = {\n");
|
||||
STAILQ_FOREACH(hint, &hints, hint_next) {
|
||||
ifp = fopen(hint->hint_name, "r");
|
||||
@ -311,6 +312,7 @@ makeenv(void)
|
||||
fprintf(ofp, "#include <sys/types.h>\n");
|
||||
fprintf(ofp, "#include <sys/systm.h>\n");
|
||||
fprintf(ofp, "\n");
|
||||
fprintf(ofp, "int envmode = %d;\n", envmode);
|
||||
fprintf(ofp, "char static_env[] = {\n");
|
||||
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
|
||||
if (envvar->env_is_file) {
|
||||
|
Loading…
Reference in New Issue
Block a user