Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Feb 2024 18:53:43 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: ecc834241fc3 - main - reboot: Implement -e from nextboot
Message-ID:  <202402121853.41CIrhvE030646@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

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

commit ecc834241fc3ab23990291e7e99fd05a34af05f1
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-12 18:45:48 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-02-12 18:45:48 +0000

    reboot: Implement -e from nextboot
    
    Implement -e foo=bar to add loader environment variables to
    nextboot.conf. bar is enclosed in quotes if it isn't already.
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D43827
---
 sbin/reboot/reboot.8 | 19 +++++++++++++++++++
 sbin/reboot/reboot.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8
index e53de69e97ae..a60512fa0c59 100644
--- a/sbin/reboot/reboot.8
+++ b/sbin/reboot/reboot.8
@@ -37,15 +37,19 @@
 .Sh SYNOPSIS
 .Nm halt
 .Op Fl DflNnpq
+.Op Fl e Ar variable=value
 .Op Fl k Ar kernel
 .Nm
 .Op Fl cDdflNnpqr
+.Op Fl e Ar variable=value
 .Op Fl k Ar kernel
 .Nm fasthalt
 .Op Fl DflNnpq
+.Op Fl e Ar variable=value
 .Op Fl k Ar kernel
 .Nm fastboot
 .Op Fl dDflNnpq
+.Op Fl e Ar variable=value
 .Op Fl k Ar kernel
 .Sh DESCRIPTION
 The
@@ -87,6 +91,21 @@ This option is
 supported only when rebooting, and it has no effect unless a dump
 device has previously been specified with
 .Xr dumpon 8 .
+.It Fl e Ar variable=value
+Sets
+.Va variable
+to
+.Va value
+in the loader's and kernel's environment.
+If
+.Va value
+is not already enclosed in double quotes, they will be added before writing to the
+.Nm nextboot
+configuration.
+Care should be taken if
+.Va value
+contains any characters that are special to the shell or loader's configuration
+parsing code.
 .It Fl k Ar kname
 Boot the specified kernel
 .Ar kname
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index d598c857d255..875f00c01ef9 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -88,7 +88,7 @@ zfsbootcfg(const char *pool, bool force)
 }
 
 static void
-write_nextboot(const char *fn, const char *kernel, bool force)
+write_nextboot(const char *fn, const char *env, const char *kernel, bool force)
 {
 	FILE *fp;
 	struct statfs sfs;
@@ -114,8 +114,9 @@ write_nextboot(const char *fn, const char *kernel, bool force)
 	if (fp == NULL)
 		E("Can't create %s to boot %s", fn, kernel);
 
-	if (fprintf(fp,"%skernel=\"%s\"\n",
+	if (fprintf(fp,"%s%skernel=\"%s\"\n",
 	    supported ? "nextboot_enable=\"YES\"\n" : "",
+	    env != NULL ? env : "",
 	    kernel) < 0) {
 		int e;
 
@@ -129,6 +130,40 @@ write_nextboot(const char *fn, const char *kernel, bool force)
 	fclose(fp);
 }
 
+static char *
+split_kv(char *raw)
+{
+	char *eq;
+	int len;
+
+	eq = strchr(raw, '=');
+	if (eq == NULL)
+		errx(1, "No = in environment string %s", raw);
+	*eq++ = '\0';
+	len = strlen(eq);
+	if (len == 0)
+		errx(1, "Invalid null value %s=", raw);
+	if (eq[0] == '"') {
+		if (len < 2 || eq[len - 1] != '"')
+			errx(1, "Invalid string '%s'", eq);
+		eq[len - 1] = '\0';
+		return (eq + 1);
+	}
+	return (eq);
+}
+
+static void
+add_env(char **env, const char *key, const char *value)
+{
+	char *oldenv;
+
+	oldenv = *env;
+	asprintf(env, "%s%s=\"%s\"\n", oldenv != NULL ? oldenv : "", key, value);
+	if (env == NULL)
+		errx(1, "No memory to build env array");
+	free(oldenv);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -138,6 +173,8 @@ main(int argc, char *argv[])
 	bool Dflag, fflag, lflag, Nflag, nflag, qflag;
 	uint64_t pageins;
 	const char *user, *kernel = NULL;
+	char *env = NULL, *v;
+
 
 	if (strstr(getprogname(), "halt") != NULL) {
 		dohalt = true;
@@ -145,7 +182,7 @@ main(int argc, char *argv[])
 	} else
 		howto = 0;
 	Dflag = fflag = lflag = Nflag = nflag = qflag = false;
-	while ((ch = getopt(argc, argv, "cDdk:lNnpqr")) != -1)
+	while ((ch = getopt(argc, argv, "cDde:k:lNnpqr")) != -1)
 		switch(ch) {
 		case 'c':
 			howto |= RB_POWERCYCLE;
@@ -156,6 +193,10 @@ main(int argc, char *argv[])
 		case 'd':
 			howto |= RB_DUMP;
 			break;
+		case 'e':
+			v = split_kv(optarg);
+			add_env(&env, optarg, v);
+			break;
 		case 'f':
 			fflag = true;
 			break;
@@ -233,7 +274,7 @@ main(int argc, char *argv[])
 				errx(1, "%s is not a file", k);
 			free(k);
 		}
-		write_nextboot(PATH_NEXTBOOT, kernel, fflag);
+		write_nextboot(PATH_NEXTBOOT, env, kernel, fflag);
 	}
 
 	/* Log the reboot. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202402121853.41CIrhvE030646>