From owner-svn-src-head@freebsd.org Fri Jul 6 01:11:08 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5CBA5102396D; Fri, 6 Jul 2018 01:11:08 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0D4D5808EA; Fri, 6 Jul 2018 01:11:08 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C8E9721BEF; Fri, 6 Jul 2018 01:11:07 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w661B7W9005642; Fri, 6 Jul 2018 01:11:07 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w661B76W005640; Fri, 6 Jul 2018 01:11:07 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201807060111.w661B76W005640@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Fri, 6 Jul 2018 01:11:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336019 - in head: . usr.sbin/config X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in head: . usr.sbin/config X-SVN-Commit-Revision: 336019 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Jul 2018 01:11:08 -0000 Author: kevans Date: Fri Jul 6 01:11:06 2018 New Revision: 336019 URL: https://svnweb.freebsd.org/changeset/base/336019 Log: config(8): De-dupe hint/env vars within a single file r335653 flipped the order in which hints/env files are concatenated to match the order in which vars are processed by the kernel. This is the other hammer to drop. Use nv(9) to de-dupe entries within a single `hint` or `env` file, using the latest value specified for a key. This leaves some duplicates if a variable is specified in multiple hint/env files or via `envvar` in a kernel config, but the reversed order of concatenation (from r335653) makes this a non-issue as the latest-specified version will be seen first. This change also silently rewrote hint bits to use the same sanitization process that ian@ wrote for r335642. To the kernel, hints and env vars are basically the same thing through early boot, then get merged into the dynamic environment once kmem becomes available and the dynamic environment is created. They should be subjected to the same restrictions. libnv has been added to -legacy for the time being to support the build of config(8) with the new cnvlist API. Tested with: universe (11 host & 12 host) MFC after: 1 month Modified: head/Makefile.inc1 head/usr.sbin/config/Makefile head/usr.sbin/config/mkmakefile.c Modified: head/Makefile.inc1 ============================================================================== --- head/Makefile.inc1 Fri Jul 6 00:58:51 2018 (r336018) +++ head/Makefile.inc1 Fri Jul 6 01:11:06 2018 (r336019) @@ -1941,13 +1941,19 @@ update: .PHONY _elftoolchain_libs= lib/libelf lib/libdwarf .endif +# An updated libnv is needed for the cnv(9) API used in config(8). +# r335343 stabilized the cnvlist API used by config(8) +.if ${BOOTSTRAPPING} < 1200070 +_libnv= lib/libnv +.endif + legacy: .PHONY .if ${BOOTSTRAPPING} < ${MINIMUM_SUPPORTED_OSREL} && ${BOOTSTRAPPING} != 0 @echo "ERROR: Source upgrades from versions prior to ${MINIMUM_SUPPORTED_REL} are not supported."; \ false .endif -.for _tool in tools/build ${_elftoolchain_libs} +.for _tool in tools/build ${_elftoolchain_libs} ${_libnv} ${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJWALK}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ Modified: head/usr.sbin/config/Makefile ============================================================================== --- head/usr.sbin/config/Makefile Fri Jul 6 00:58:51 2018 (r336018) +++ head/usr.sbin/config/Makefile Fri Jul 6 01:11:06 2018 (r336019) @@ -14,11 +14,11 @@ kernconf.c: kernconf.tmpl ${FILE2C} 'char kernconfstr[] = {' ',0};' < \ ${SRCDIR}/kernconf.tmpl > kernconf.c -CFLAGS+= -I. -I${SRCDIR} +CFLAGS+= -I. -I${SRCDIR} -I${SRCTOP}/sys NO_WMISSING_VARIABLE_DECLARATIONS= -LIBADD= l sbuf +LIBADD= l nv sbuf CLEANFILES+= kernconf.c Modified: head/usr.sbin/config/mkmakefile.c ============================================================================== --- head/usr.sbin/config/mkmakefile.c Fri Jul 6 00:58:51 2018 (r336018) +++ head/usr.sbin/config/mkmakefile.c Fri Jul 6 01:11:06 2018 (r336019) @@ -49,6 +49,8 @@ static const char rcsid[] = #include #include #include +#include +#include #include #include "y.tab.h" #include "config.h" @@ -62,6 +64,10 @@ static void do_objs(FILE *); static void do_before_depend(FILE *); static int opteq(const char *, const char *); static void read_files(void); +static void sanitize_envline(char *result, const char *src); +static void process_into_file(char *line, FILE *ofp); +static void process_into_nvlist(char *line, nvlist_t *nvl); +static void dump_nvlist(nvlist_t *nvl, FILE *ofp); static void errout(const char *fmt, ...) { @@ -180,64 +186,6 @@ makefile(void) moveifchanged(path("Makefile.new"), path("Makefile")); } -/* - * Build hints.c from the skeleton - */ -void -makehints(void) -{ - FILE *ifp, *ofp; - char line[BUFSIZ]; - char *s; - struct hint *hint; - - ofp = fopen(path("hints.c.new"), "w"); - if (ofp == NULL) - err(1, "%s", path("hints.c.new")); - fprintf(ofp, "#include \n"); - fprintf(ofp, "#include \n"); - fprintf(ofp, "\n"); - fprintf(ofp, "char static_hints[] = {\n"); - STAILQ_FOREACH(hint, &hints, hint_next) { - ifp = fopen(hint->hint_name, "r"); - if (ifp == NULL) - err(1, "%s", hint->hint_name); - while (fgets(line, BUFSIZ, ifp) != NULL) { - /* zap trailing CR and/or LF */ - while ((s = strrchr(line, '\n')) != NULL) - *s = '\0'; - while ((s = strrchr(line, '\r')) != NULL) - *s = '\0'; - /* remove # comments */ - s = strchr(line, '#'); - if (s) - *s = '\0'; - /* remove any whitespace and " characters */ - s = line; - while (*s) { - if (*s == ' ' || *s == '\t' || *s == '"') { - while (*s) { - s[0] = s[1]; - s++; - } - /* start over */ - s = line; - continue; - } - s++; - } - /* anything left? */ - if (*line == '\0') - continue; - fprintf(ofp, "\"%s\\0\"\n", line); - } - fclose(ifp); - } - fprintf(ofp, "\"\\0\"\n};\n"); - fclose(ofp); - moveifchanged(path("hints.c.new"), path("hints.c")); -} - static void sanitize_envline(char *result, const char *src) { @@ -295,14 +243,96 @@ sanitize_envline(char *result, const char *src) *dst = 0; } +static void +process_into_file(char *line, FILE *ofp) +{ + char result[BUFSIZ]; + + sanitize_envline(result, line); + /* anything left? */ + if (*result == '\0') + return; + fprintf(ofp, "\"%s\\0\"\n", result); +} + +static void +process_into_nvlist(char *line, nvlist_t *nvl) +{ + char result[BUFSIZ], *s; + + sanitize_envline(result, line); + /* anything left? */ + if (*result == '\0') + return; + s = strchr(result, '='); + *s = 0; + if (nvlist_exists(nvl, result)) + nvlist_free(nvl, result); + nvlist_add_string(nvl, result, s + 1); +} + +static void +dump_nvlist(nvlist_t *nvl, FILE *ofp) +{ + const char *name; + void *cookie; + + if (nvl == NULL) + return; + + while (!nvlist_empty(nvl)) { + cookie = NULL; + name = nvlist_next(nvl, NULL, &cookie); + fprintf(ofp, "\"%s=%s\\0\"\n", name, + cnvlist_get_string(cookie)); + + cnvlist_free_string(cookie); + } +} + /* + * Build hints.c from the skeleton + */ +void +makehints(void) +{ + FILE *ifp, *ofp; + nvlist_t *nvl; + char line[BUFSIZ]; + struct hint *hint; + + ofp = fopen(path("hints.c.new"), "w"); + if (ofp == NULL) + err(1, "%s", path("hints.c.new")); + fprintf(ofp, "#include \n"); + fprintf(ofp, "#include \n"); + fprintf(ofp, "\n"); + fprintf(ofp, "char static_hints[] = {\n"); + nvl = nvlist_create(0); + STAILQ_FOREACH(hint, &hints, hint_next) { + ifp = fopen(hint->hint_name, "r"); + if (ifp == NULL) + err(1, "%s", hint->hint_name); + while (fgets(line, BUFSIZ, ifp) != NULL) + process_into_nvlist(line, nvl); + dump_nvlist(nvl, ofp); + fclose(ifp); + } + nvlist_destroy(nvl); + fprintf(ofp, "\"\\0\"\n};\n"); + fclose(ofp); + moveifchanged(path("hints.c.new"), path("hints.c")); +} + +/* * Build env.c from the skeleton */ void makeenv(void) { FILE *ifp, *ofp; - char line[BUFSIZ], result[BUFSIZ], *linep; + nvlist_t *nvl; + char line[BUFSIZ]; struct envvar *envvar; ofp = fopen(path("env.c.new"), "w"); @@ -312,27 +342,20 @@ makeenv(void) fprintf(ofp, "#include \n"); fprintf(ofp, "\n"); fprintf(ofp, "char static_env[] = {\n"); + nvl = nvlist_create(0); STAILQ_FOREACH(envvar, &envvars, envvar_next) { if (envvar->env_is_file) { ifp = fopen(envvar->env_str, "r"); 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); - } + while (fgets(line, BUFSIZ, ifp) != NULL) + process_into_nvlist(line, nvl); + dump_nvlist(nvl, ofp); fclose(ifp); - } else { - linep = envvar->env_str; - sanitize_envline(result, linep); - if (*result == '\0') - continue; - fprintf(ofp, "\"%s\\0\"\n", result); - } + } else + process_into_file(envvar->env_str, ofp); } + nvlist_destroy(nvl); fprintf(ofp, "\"\\0\"\n};\n"); fclose(ofp); moveifchanged(path("env.c.new"), path("env.c"));