config(8): Make 'env' files consistent with other file-accepting options

Previously, only one 'env' file could be specified. Later 'env' directives
would overwrite earlier 'env' directives. This is inconsistent with every
other file-accepting directives which process files in order, including
hints.

A caveat applies to both hints and env that isn't mentioned: they're
concatenated in the order of appearance, so they're not actually applied in
the way one might think by supplying:

hints x
hints y

Hints in x will take precedence over same-name hints in y due to how
the kernel processes them, stopping at the first line that matches the hint
we're searching for. Future work will flip the order of concatenation so
that later files may still properly override earlier files.

In practice, this likely doesn't matter at all due to the nature of the
beast.
This commit is contained in:
Kyle Evans 2018-06-26 03:56:10 +00:00
parent 1aae236569
commit 4edfa9085a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=335652
4 changed files with 55 additions and 40 deletions

View File

@ -23,7 +23,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 22, 2018 .Dd June 26, 2018
.Dt CONFIG 5 .Dt CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -124,6 +124,18 @@ the compiled-in environment instead, unless the boot environment contains
This directive is useful for setting kernel tunables in This directive is useful for setting kernel tunables in
embedded environments that do not start from embedded environments that do not start from
.Xr loader 8 . .Xr loader 8 .
.Pp
All
.Ic env
and
.Ic envvar
directives will be processed and added to the staitc environment in the order of
appearance.
Note that within
.Ar filename ,
the first appearance of a given variable will be the first one seen by the
kernel, effectively shadowing any later appearances of the same variable within
.Ar filename .
.\" -------- ENVVAR -------- .\" -------- ENVVAR --------
.Pp .Pp
.It Ic envvar Ar setting .It Ic envvar Ar setting
@ -133,11 +145,13 @@ compiled-in environment.
must be of the form must be of the form
.Dq Va name=value . .Dq Va name=value .
Optional quotes are supported in both name and value. Optional quotes are supported in both name and value.
All environment variables specified with .Pp
.Ic envvar All
will be set after any
.Ic env .Ic env
files are included. and
.Ic envvar
directives will be processed and added to the staitc environment in the order of
appearance.
.\" -------- FILES -------- .\" -------- FILES --------
.Pp .Pp
.It Ic files Ar filename .It Ic files Ar filename

View File

@ -37,6 +37,7 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -142,6 +143,7 @@ SLIST_HEAD(, opt_list) otab;
struct envvar { struct envvar {
char *env_str; char *env_str;
bool env_is_file;
STAILQ_ENTRY(envvar) envvar_next; STAILQ_ENTRY(envvar) envvar_next;
}; };
@ -175,7 +177,6 @@ SLIST_HEAD(, includepath) includepath;
#define OPT_AUTOGEN "CONFIG_AUTOGENERATED" #define OPT_AUTOGEN "CONFIG_AUTOGENERATED"
extern char *ident; extern char *ident;
extern char *env;
extern char kernconfstr[]; extern char kernconfstr[];
extern int do_trace; extern int do_trace;
extern int envmode; extern int envmode;

View File

@ -82,7 +82,6 @@
struct device_head dtab; struct device_head dtab;
char *ident; char *ident;
char *env;
int envmode; int envmode;
int hintmode; int hintmode;
int yyline; int yyline;
@ -99,6 +98,7 @@ int yywrap(void);
static void newdev(char *name); static void newdev(char *name);
static void newfile(char *name); static void newfile(char *name);
static void newenvvar(char *name, bool is_file);
static void rmdev_schedule(struct device_head *dh, char *name); static void rmdev_schedule(struct device_head *dh, char *name);
static void newopt(struct opt_head *list, char *name, char *value, int append); static void newopt(struct opt_head *list, char *name, char *value, int append);
static void rmopt_schedule(struct opt_head *list, char *name); static void rmopt_schedule(struct opt_head *list, char *name);
@ -191,20 +191,8 @@ Config_spec:
| |
MAXUSERS NUMBER { maxusers = $2; } | MAXUSERS NUMBER { maxusers = $2; } |
PROFILE NUMBER { profiling = $2; } | PROFILE NUMBER { profiling = $2; } |
ENV ID { ENV ID { newenvvar($2, true); } |
env = $2; ENVVAR ENVLINE { newenvvar($2, false); } |
envmode = 1;
} |
ENVVAR ENVLINE {
struct envvar *envvar;
envvar = (struct envvar *)calloc(1, sizeof (struct envvar));
if (envvar == NULL)
err(EXIT_FAILURE, "calloc");
envvar->env_str = $2;
STAILQ_INSERT_TAIL(&envvars, envvar, envvar_next);
envmode = 1;
} |
HINTS ID { HINTS ID {
struct hint *hint; struct hint *hint;
@ -361,7 +349,21 @@ newfile(char *name)
nl->f_name = name; nl->f_name = name;
STAILQ_INSERT_TAIL(&fntab, nl, f_next); STAILQ_INSERT_TAIL(&fntab, nl, f_next);
} }
static void
newenvvar(char *name, bool is_file)
{
struct envvar *envvar;
envvar = (struct envvar *)calloc(1, sizeof (struct envvar));
if (envvar == NULL)
err(EXIT_FAILURE, "calloc");
envvar->env_str = name;
envvar->env_is_file = is_file;
STAILQ_INSERT_TAIL(&envvars, envvar, envvar_next);
envmode = 1;
}
/* /*
* Find a device in the list of devices. * Find a device in the list of devices.
*/ */

View File

@ -306,13 +306,6 @@ makeenv(void)
char line[BUFSIZ], result[BUFSIZ], *linep; char line[BUFSIZ], result[BUFSIZ], *linep;
struct envvar *envvar; struct envvar *envvar;
if (env) {
ifp = fopen(env, "r");
if (ifp == NULL)
err(1, "%s", env);
} else {
ifp = NULL;
}
ofp = fopen(path("env.c.new"), "w"); ofp = fopen(path("env.c.new"), "w");
if (ofp == NULL) if (ofp == NULL)
err(1, "%s", path("env.c.new")); err(1, "%s", path("env.c.new"));
@ -321,22 +314,27 @@ makeenv(void)
fprintf(ofp, "\n"); fprintf(ofp, "\n");
fprintf(ofp, "int envmode = %d;\n", envmode); fprintf(ofp, "int envmode = %d;\n", envmode);
fprintf(ofp, "char static_env[] = {\n"); fprintf(ofp, "char static_env[] = {\n");
if (ifp) { STAILQ_FOREACH(envvar, &envvars, envvar_next) {
while (fgets(line, BUFSIZ, ifp) != NULL) { if (envvar->env_is_file) {
sanitize_envline(result, line); ifp = fopen(envvar->env_str, "r");
/* anything left? */ if (ifp == NULL)
err(1, "%s", envvar->env_str);
while (fgets(line, BUFSIZ, ifp) != NULL) {
sanitize_envline(result, line);
/* anything left? */
if (*result == '\0')
continue;
fprintf(ofp, "\"%s\\0\"\n", result);
}
fclose(ifp);
} else {
linep = envvar->env_str;
sanitize_envline(result, linep);
if (*result == '\0') if (*result == '\0')
continue; continue;
fprintf(ofp, "\"%s\\0\"\n", result); fprintf(ofp, "\"%s\\0\"\n", result);
} }
} }
STAILQ_FOREACH(envvar, &envvars, envvar_next) {
linep = envvar->env_str;
sanitize_envline(result, linep);
if (*result == '\0')
continue;
fprintf(ofp, "\"%s\\0\"\n", result);
}
fprintf(ofp, "\"\\0\"\n};\n"); fprintf(ofp, "\"\\0\"\n};\n");
if (ifp) if (ifp)
fclose(ifp); fclose(ifp);