nextboot: Reimplement missing -a option

* Reimplement the -a option which was available in the original shell
  script and is still documented.

* Print the correct usage string when invoked as nextboot.

* Add the -D option to the manual page synopsis.

MFC after:	1 week
Fixes:		fd6d47375a ("rescue,nextboot: Install nextboot as a link to reboot, rm nextboot.sh")
Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D54120
This commit is contained in:
Dag-Erling Smørgrav
2025-12-08 11:30:17 +01:00
parent e540e8b2c0
commit de670c611b
2 changed files with 36 additions and 12 deletions
+2 -2
View File
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd March 29, 2022 .Dd December 8, 2025
.Dt NEXTBOOT 8 .Dt NEXTBOOT 8
.Os .Os
.Sh NAME .Sh NAME
@@ -30,7 +30,7 @@
.Nd "specify an alternate kernel and boot flags for the next reboot" .Nd "specify an alternate kernel and boot flags for the next reboot"
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl af .Op Fl aDf
.Op Fl e Ar variable=value .Op Fl e Ar variable=value
.Op Fl k Ar kernel .Op Fl k Ar kernel
.Op Fl o Ar options .Op Fl o Ar options
+32 -8
View File
@@ -112,12 +112,13 @@ zfsbootcfg(const char *pool, bool force)
} }
static void static void
write_nextboot(const char *fn, const char *env, bool force) write_nextboot(const char *fn, const char *env, bool append, bool force)
{ {
char tmp[PATH_MAX]; char tmp[PATH_MAX];
FILE *fp; FILE *fp;
struct statfs sfs; struct statfs sfs;
int tmpfd; ssize_t ret;
int fd, tmpfd;
bool supported = false; bool supported = false;
bool zfs = false; bool zfs = false;
@@ -145,6 +146,7 @@ write_nextboot(const char *fn, const char *env, bool force)
E("Path too long %s", fn); E("Path too long %s", fn);
if (strlcat(tmp, ".XXXXXX", sizeof(tmp)) >= sizeof(tmp)) if (strlcat(tmp, ".XXXXXX", sizeof(tmp)) >= sizeof(tmp))
E("Path too long %s", fn); E("Path too long %s", fn);
tmpfd = mkstemp(tmp); tmpfd = mkstemp(tmp);
if (tmpfd == -1) if (tmpfd == -1)
E("mkstemp %s", tmp); E("mkstemp %s", tmp);
@@ -153,6 +155,21 @@ write_nextboot(const char *fn, const char *env, bool force)
if (fp == NULL) if (fp == NULL)
E("fdopen %s", tmp); E("fdopen %s", tmp);
if (append) {
if ((fd = open(fn, O_RDONLY)) < 0) {
if (errno != ENOENT)
E("open %s", fn);
} else {
do {
ret = copy_file_range(fd, NULL, tmpfd, NULL,
SSIZE_MAX, 0);
if (ret < 0)
E("copy %s to %s", fn, tmp);
} while (ret > 0);
close(fd);
}
}
if (fprintf(fp, "%s%s", if (fprintf(fp, "%s%s",
supported ? "nextboot_enable=\"YES\"\n" : "", supported ? "nextboot_enable=\"YES\"\n" : "",
env != NULL ? env : "") < 0) { env != NULL ? env : "") < 0) {
@@ -216,7 +233,7 @@ add_env(char **env, const char *key, const char *value)
* Different options are valid for different programs. * Different options are valid for different programs.
*/ */
#define GETOPT_REBOOT "cDde:fk:lNno:pqr" #define GETOPT_REBOOT "cDde:fk:lNno:pqr"
#define GETOPT_NEXTBOOT "De:fk:o:" #define GETOPT_NEXTBOOT "aDe:fk:o:"
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
@@ -225,7 +242,7 @@ main(int argc, char *argv[])
const struct passwd *pw; const struct passwd *pw;
struct stat st; struct stat st;
int ch, howto = 0, i, sverrno; int ch, howto = 0, i, sverrno;
bool Dflag, fflag, lflag, Nflag, nflag, qflag; bool aflag, Dflag, fflag, lflag, Nflag, nflag, qflag;
uint64_t pageins; uint64_t pageins;
const char *user, *kernel = NULL, *getopts = GETOPT_REBOOT; const char *user, *kernel = NULL, *getopts = GETOPT_REBOOT;
char *env = NULL, *v; char *env = NULL, *v;
@@ -240,9 +257,12 @@ main(int argc, char *argv[])
/* reboot */ /* reboot */
howto = 0; howto = 0;
} }
Dflag = fflag = lflag = Nflag = nflag = qflag = false; aflag = Dflag = fflag = lflag = Nflag = nflag = qflag = false;
while ((ch = getopt(argc, argv, getopts)) != -1) { while ((ch = getopt(argc, argv, getopts)) != -1) {
switch(ch) { switch(ch) {
case 'a':
aflag = true;
break;
case 'c': case 'c':
howto |= RB_POWERCYCLE; howto |= RB_POWERCYCLE;
break; break;
@@ -363,7 +383,7 @@ main(int argc, char *argv[])
} }
if (env != NULL) if (env != NULL)
write_nextboot(PATH_NEXTBOOT, env, fflag); write_nextboot(PATH_NEXTBOOT, env, aflag, fflag);
if (donextboot) if (donextboot)
exit (0); exit (0);
@@ -483,10 +503,14 @@ main(int argc, char *argv[])
static void static void
usage(void) usage(void)
{ {
if (donextboot) {
(void)fprintf(stderr, dohalt ? fprintf(stderr, "usage: nextboot [-aDf] "
"[-e name=value] [-k kernel] [-o options]\n");
} else {
fprintf(stderr, dohalt ?
"usage: halt [-clNnpq] [-k kernel]\n" : "usage: halt [-clNnpq] [-k kernel]\n" :
"usage: reboot [-cdlNnpqr] [-k kernel]\n"); "usage: reboot [-cdlNnpqr] [-k kernel]\n");
}
exit(1); exit(1);
} }