git: 9e2b87207ba1 - main - Allow additional "options" files to be specified in kernel config

From: Stephen J. Kiernan <stevek_at_FreeBSD.org>
Date: Wed, 18 Sep 2024 17:02:49 UTC
The branch main has been updated by stevek:

URL: https://cgit.FreeBSD.org/src/commit/?id=9e2b87207ba1949f402e169416f63ab5cdbf3dd4

commit 9e2b87207ba1949f402e169416f63ab5cdbf3dd4
Author:     Stephen J. Kiernan <stevek@FreeBSD.org>
AuthorDate: 2024-09-18 17:02:42 +0000
Commit:     Stephen J. Kiernan <stevek@FreeBSD.org>
CommitDate: 2024-09-18 17:02:42 +0000

    Allow additional "options" files to be specified in kernel config
    
    The "includeoptions" directive can be used to specify an additional
    options file to be used.
    
    This is useful in conjunction with the "files" directive for build
    environments to be able to add custom files and options.
    
    Add "-v" flag to enable verbose mode. Added some additional error
    messages when in verbose mode.
    
    Obtained from:  Juniper Networks, Inc.
    Reviewed by:    imp
    Differential Revision: https://reviews.freebsd.org/D39540
---
 usr.sbin/config/config.5     |  9 +++++++++
 usr.sbin/config/config.8     |  4 +++-
 usr.sbin/config/config.h     |  2 ++
 usr.sbin/config/config.y     | 22 ++++++++++++++++++++++
 usr.sbin/config/lang.l       |  1 +
 usr.sbin/config/main.cc      |  7 ++++++-
 usr.sbin/config/mkoptions.cc | 21 +++++++++++++++++++--
 7 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/config/config.5 b/usr.sbin/config/config.5
index f77b79a31510..8c2c62b706bd 100644
--- a/usr.sbin/config/config.5
+++ b/usr.sbin/config/config.5
@@ -239,6 +239,15 @@ Read subsequent text from file
 and return to the current file after
 .Ar filename
 is successfully processed.
+.\" -------- INCLUDEOPTIONS --------
+.Pp
+.It .Ic includeoptions Ar filename
+Specifies a file containing a list of additional options
+specific to that kernel configuration file.
+This is useful for build environments that need to add
+custom options and is often used in conjunction with the
+.Ic makeoption
+directive.
 .\" -------- MACHINE --------
 .Pp
 .It Ic machine Ar arch Op Ar cpuarch
diff --git a/usr.sbin/config/config.8 b/usr.sbin/config/config.8
index ccb61cdf2786..e0912a4bc104 100644
--- a/usr.sbin/config/config.8
+++ b/usr.sbin/config/config.8
@@ -33,7 +33,7 @@
 .Nd build system configuration files
 .Sh SYNOPSIS
 .Nm
-.Op Fl CVgp
+.Op Fl CVgpv
 .Op Fl I Ar path
 .Op Fl d Ar destdir
 .Op Fl s Ar srcdir
@@ -99,6 +99,8 @@ file.
 This option makes sense only if
 .Cd "options INCLUDE_CONFIG_FILE"
 entry was present in your configuration file.
+.It Fl v
+Turns on verbose output.
 .It Ar SYSTEM_NAME
 Specify the name of the system configuration file
 containing device specifications, configuration options
diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h
index 16562a7f8210..6085c52d1b95 100644
--- a/usr.sbin/config/config.h
+++ b/usr.sbin/config/config.h
@@ -260,9 +260,11 @@ extern const	char *yyfile;
 extern STAILQ_HEAD(file_list_head, file_list) ftab;
 
 extern STAILQ_HEAD(files_name_head, files_name) fntab;
+extern STAILQ_HEAD(options_files_name_head, files_name) optfntab;
 
 extern int	debugging;
 extern int	found_defaults;
+extern int	verbose;
 
 extern int	maxusers;
 extern int	versreq;
diff --git a/usr.sbin/config/config.y b/usr.sbin/config/config.y
index 4120ffa54b1c..15139197dbb6 100644
--- a/usr.sbin/config/config.y
+++ b/usr.sbin/config/config.y
@@ -24,6 +24,7 @@
 %token	NOMAKEOPTION 
 %token	SEMICOLON
 %token	INCLUDE
+%token	INCLUDEOPTIONS
 %token	FILES
 
 %token	<str>	ENVLINE
@@ -83,6 +84,7 @@ int	yyline;
 const	char *yyfile;
 struct  file_list_head ftab;
 struct  files_name_head fntab;
+struct	options_files_name_head optfntab;
 char	errbuf[80];
 int	maxusers;
 
@@ -93,6 +95,7 @@ int yywrap(void);
 
 static void newdev(char *name);
 static void newfile(char *name);
+static void newoptionsfile(char *name);
 static void newenvvar(char *name, bool is_file);
 static void rmdev_schedule(struct device_head *dh, char *name);
 static void newopt(struct opt_head *list, char *name, char *value, int append, int dupe);
@@ -135,6 +138,10 @@ Spec:
 		  	include($2, 0);
 		};
 		|
+	INCLUDEOPTIONS PATH SEMICOLON { newoptionsfile($2); };
+		|
+	INCLUDEOPTIONS ID SEMICOLON { newoptionsfile($2); };
+		|
 	FILES ID SEMICOLON { newfile($2); };
 	        |
 	SEMICOLON
@@ -335,6 +342,21 @@ newfile(char *name)
 	STAILQ_INSERT_TAIL(&fntab, nl, f_next);
 }
 
+/*
+ * Add a new options file to the list of options files.
+ */
+static void
+newoptionsfile(char *name)
+{
+	struct files_name *nl;
+
+	nl = (struct files_name *) calloc(1, sizeof *nl);
+	if (nl == NULL)
+		err(EXIT_FAILURE, "calloc");
+	nl->f_name = name;
+	STAILQ_INSERT_TAIL(&optfntab, nl, f_next);
+}
+
 static void
 newenvvar(char *name, bool is_file)
 {
diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l
index a6558237db5a..2052d98d1fdd 100644
--- a/usr.sbin/config/lang.l
+++ b/usr.sbin/config/lang.l
@@ -80,6 +80,7 @@ struct kt {
 	{ "nooption",	NOOPTION },
 	{ "nooptions",	NOOPTION },
 	{ "include",	INCLUDE },
+	{ "includeoptions", INCLUDEOPTIONS },
 	{ "files", 	FILES },
 	{ 0, 0 },
 };
diff --git a/usr.sbin/config/main.cc b/usr.sbin/config/main.cc
index 0c0b9bb27dc3..1e89cbf3230a 100644
--- a/usr.sbin/config/main.cc
+++ b/usr.sbin/config/main.cc
@@ -78,6 +78,7 @@ char 	srcdir[MAXPATHLEN];
 int	debugging;
 int	found_defaults;
 int	incignore;
+int	verbose;
 
 /*
  * Preserve old behaviour in INCLUDE_CONFIG_FILE handling (files are included
@@ -130,7 +131,8 @@ main(int argc, char **argv)
 	STAILQ_INIT(&ftab);
 	STAILQ_INIT(&hints);
 	STAILQ_INIT(&envvars);
-	while ((ch = getopt(argc, argv, "Cd:gI:mps:Vx:")) != -1)
+	STAILQ_INIT(&optfntab);
+	while ((ch = getopt(argc, argv, "Cd:gI:mps:Vvx:")) != -1)
 		switch (ch) {
 		case 'C':
 			filebased = 1;
@@ -165,6 +167,9 @@ main(int argc, char **argv)
 		case 'V':
 			printf("%d\n", CONFIGVERS);
 			exit(0);
+		case 'v':
+			verbose++;
+			break;
 		case 'x':
 			kernfile = optarg;
 			break;
diff --git a/usr.sbin/config/mkoptions.cc b/usr.sbin/config/mkoptions.cc
index 1580700dc08d..3b5ed17e455c 100644
--- a/usr.sbin/config/mkoptions.cc
+++ b/usr.sbin/config/mkoptions.cc
@@ -38,6 +38,7 @@
 #include <err.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/param.h>
 #include "config.h"
 #include "y.tab.h"
@@ -71,7 +72,9 @@ options(void)
 	}	
 
 	if (maxusers == 0) {
-		/* fprintf(stderr, "maxusers not specified; will auto-size\n"); */
+		if (verbose)
+			fprintf(stderr,
+			    "maxusers not specified; will auto-size\n");
 	} else if (maxusers < users.u_min) {
 		fprintf(stderr, "minimum of %d maxusers assumed\n",
 		    users.u_min);
@@ -363,8 +366,15 @@ read_option_file(const char *fname, int flags)
 	char genopt[MAXPATHLEN];
 
 	fp = fopen(fname, "r");
-	if (fp == NULL)
+	if (fp == NULL) {
+		if (verbose) {
+			getcwd(genopt, sizeof(genopt));
+			fprintf(stderr, "Unable to open options file: %s\n",
+			    fname);
+			fprintf(stderr, "CWD: %s\n", genopt);
+		}
 		return (0);
+	}
 	while (!(wd = get_word(fp)).eof()) {
 		if (wd.eol())
 			continue;
@@ -417,6 +427,7 @@ static void
 read_options(void)
 {
 	char fname[MAXPATHLEN];
+	struct files_name *nl, *tnl;
 
 	SLIST_INIT(&otab);
 	read_option_file("../../conf/options", 0);
@@ -426,6 +437,12 @@ read_options(void)
 		(void)snprintf(fname, sizeof fname, "options.%s", machinename);
 		read_option_file(fname, 0);
 	}
+	for (nl = STAILQ_FIRST(&optfntab); nl != NULL; nl = tnl) {
+		read_option_file(nl->f_name, 0);
+		tnl = STAILQ_NEXT(nl, f_next);
+		free(nl->f_name);
+		free(nl);
+	}
 	read_option_file("../../conf/options-compat", OL_ALIAS);
 }