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:
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user