mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-21 18:27:22 +00:00
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
This commit is contained in:
parent
0df5f65908
commit
ecc834241f
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in a new issue