summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_hints.c
diff options
context:
space:
mode:
authormux <mux@FreeBSD.org>2002-04-17 13:06:36 +0000
committermux <mux@FreeBSD.org>2002-04-17 13:06:36 +0000
commita207e41bef089b8849a230f44088a562d0b5d19f (patch)
treecb447f9f2a04a764ece9fcefc6fa6b52d19870b8 /sys/kern/subr_hints.c
parentc79270302c4767b589a4fe70da3ba9866936358f (diff)
downloadFreeBSD-src-a207e41bef089b8849a230f44088a562d0b5d19f.zip
FreeBSD-src-a207e41bef089b8849a230f44088a562d0b5d19f.tar.gz
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
Diffstat (limited to 'sys/kern/subr_hints.c')
-rw-r--r--sys/kern/subr_hints.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/sys/kern/subr_hints.c b/sys/kern/subr_hints.c
index 3ca9d5b..ddcba4a 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;
OpenPOWER on IntegriCloud