git: ecc834241fc3 - main - reboot: Implement -e from nextboot
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 12 Feb 2024 18:53:43 UTC
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. */