diff options
author | Maxime Henrion <mux@FreeBSD.org> | 2002-04-17 13:06:36 +0000 |
---|---|---|
committer | Maxime Henrion <mux@FreeBSD.org> | 2002-04-17 13:06:36 +0000 |
commit | d786139c76ad8d7cd25f962f7e67d4af98685418 (patch) | |
tree | cb447f9f2a04a764ece9fcefc6fa6b52d19870b8 /sys/kern/subr_hints.c | |
parent | fd448168b76dbe56823963e1d17872d0673e13ca (diff) | |
download | src-d786139c76ad8d7cd25f962f7e67d4af98685418.tar.gz src-d786139c76ad8d7cd25f962f7e67d4af98685418.zip |
Rework the kernel environment subsystem. We now convert the static
environment needed at boot time to a dynamic subsystem when VM is
up. The dynamic kernel environment is protected by an sx lock.
This adds some new functions to manipulate the kernel environment :
freeenv(), setenv(), unsetenv() and testenv(). freeenv() has to be
called after every getenv() when you have finished using the string.
testenv() only tests if an environment variable is present, and
doesn't require a freeenv() call. setenv() and unsetenv() are self
explanatory.
The kenv(2) syscall exports these new functionalities to userland,
mainly for kenv(1).
Reviewed by: peter
Notes
Notes:
svn path=/head/; revision=94936
Diffstat (limited to 'sys/kern/subr_hints.c')
-rw-r--r-- | sys/kern/subr_hints.c | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/sys/kern/subr_hints.c b/sys/kern/subr_hints.c index 3ca9d5bc5c09..ddcba4a6c0f3 100644 --- a/sys/kern/subr_hints.c +++ b/sys/kern/subr_hints.c @@ -27,6 +27,8 @@ */ #include <sys/param.h> +#include <sys/lock.h> +#include <sys/sx.h> #include <sys/systm.h> #include <sys/bus.h> @@ -34,6 +36,7 @@ * Access functions for device resources. */ +static int checkmethod = 1; static char *hintp; /* @@ -47,7 +50,7 @@ res_find(int *line, int *startln, const char **ret_name, int *ret_namelen, int *ret_unit, const char **ret_resname, int *ret_resnamelen, const char **ret_value) { - int n = 0, hit; + int n = 0, hit, use_kenv, i = 0; char r_name[32]; int r_unit; char r_resname[32]; @@ -55,40 +58,69 @@ res_find(int *line, int *startln, const char *s, *cp; char *p; - if (hintp == NULL) { + use_kenv = 0; + if (checkmethod) { switch (hintmode) { case 0: /* config supplied nothing */ - hintp = kern_envp; break; case 1: /* static hints only */ hintp = static_hints; + checkmethod = 0; break; case 2: /* fallback mode */ - cp = kern_envp; - while (cp) { - if (strncmp(cp, "hint.", 5) == 0) { - cp = NULL; - hintp = kern_envp; - break; + if (dynamic_kenv) { + sx_slock(&kenv_lock); + cp = kenvp[0]; + for (i = 0; cp != NULL; cp = kenvp[++i]) { + if (!strncmp(cp, "hint.", 5)) { + use_kenv = 1; + checkmethod = 0; + break; + } } - while (*cp != '\0') + sx_sunlock(&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++; - cp++; - if (*cp == '\0') { - cp = NULL; - hintp = static_hints; - break; + if (*cp == '\0') { + cp = NULL; + hintp = static_hints; + break; + } } } break; default: break; } - if (hintp == NULL) - hintp = kern_envp; + if (hintp == NULL) { + if (dynamic_kenv) { + use_kenv = 1; + checkmethod = 0; + } else + hintp = kern_envp; + } } - cp = hintp; + if (use_kenv) { + sx_slock(&kenv_lock); + i = 0; + cp = kenvp[0]; + if (cp == NULL) { + sx_sunlock(&kenv_lock); + return (ENOENT); + } + } else { + cp = hintp; + } while (cp) { hit = 1; (*line)++; @@ -116,6 +148,8 @@ res_find(int *line, int *startln, hit = 0; if (hit) break; + if (use_kenv) + cp = kenvp[++i]; while (*cp != '\0') cp++; cp++; @@ -124,6 +158,8 @@ res_find(int *line, int *startln, break; } } + if (use_kenv) + sx_sunlock(&kenv_lock); if (cp == NULL) return ENOENT; |