Date: Tue, 29 Jan 2008 23:51:08 +1100 (EST) From: Edwin Groothuis <edwin@mavetju.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/120114: [patch] sbin/reboot - add features available in Solaris. Message-ID: <20080129125108.822C3356@k7.mavetju> Resent-Message-ID: <200801291300.m0TD05Oj045189@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 120114
>Category: bin
>Synopsis: [patch] sbin/reboot - add features available in Solaris.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Jan 29 13:00:05 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Edwin Groothuis
>Release: FreeBSD 6.2-RELEASE-p4 i386
>Organization:
-
>Environment:
System: FreeBSD k7.mavetju 6.2-RELEASE-p4 FreeBSD 6.2-RELEASE-p4 #0: Thu Apr 26 17:55:55 UTC 2007 root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/SMP i386
>Description:
Solaris has the feature of being able to set boot loader options
with the -o option or after the command.
Nextboot -k and reboot -k can only specify the directory (/boot/kernel),
but not the kernel name (/boot/kernel/kernel.debug)
Nextboot insists on having the -k option for the kernel directory,
but that can be grabbed from the kern.bootfile sysctl.
Add -c option to reboot which reboots with the current kernel instaed
of the one specified in /boot/loader.conf. (to ease the use of -k
and -b option)
I will handle this with mentor (grog@)
>How-To-Repeat:
>Fix:
Index: nextboot.8
===================================================================
RCS file: /home/ncvs/src/sbin/reboot/nextboot.8,v
retrieving revision 1.4
diff -u -r1.4 nextboot.8
--- nextboot.8 12 Dec 2002 17:25:56 -0000 1.4
+++ nextboot.8 29 Jan 2008 12:50:23 -0000
@@ -34,23 +34,29 @@
.Nm
.Op Fl f
.Op Fl o Ar options
-.Fl k Ar kernel
+.Op Fl b Ar bootfile
+.Op Fl k Ar kernel
.Nm
.Fl D
.Sh DESCRIPTION
The
.Nm
-utility allows specifying an alternate kernel and/or boot flags for the
-next time the machine is booted.
+utility allows specifying an alternate kernel, kernel bootfile and/or boot
+flags for the next time the machine is booted.
Once the
.Xr loader 8
-loads in the new kernel
-information, it is deleted so in case the new kernel hangs the machine,
-once it is rebooted, the machine will automatically revert to its previous
-configuration.
+loads in the new kernel information, it is deleted so in case the
+new kernel hangs the machine, once it is rebooted, the machine will
+automatically revert to its previous configuration.
.Pp
The options are as follows:
-.Bl -tag -width ".Fl o Ar options"
+.Bl -tag -width ".Fl b Ar bootfile"
+.It Fl b Ar bootfile
+This option specifies the kernel name, relative to
+.Pa /boot/kernel
+or whatever the
+.Fl k
+option sets the kernel directory to.
.It Fl D
Invoking
.Nm
@@ -90,7 +96,11 @@
.Pp
To enable into single user mode with the normal kernel:
.Pp
-.Dl "nextboot -o ""-s"" -k kernel"
+.Dl "nextboot -o ""-s"""
+.Pp
+To boot a kernel with debugging symbols:
+.Pp
+.Dl "nextboot -b kernel.debug"
.Pp
To remove an existing nextboot configuration:
.Pp
Index: nextboot.sh
===================================================================
RCS file: /home/ncvs/src/sbin/reboot/nextboot.sh,v
retrieving revision 1.3
diff -u -r1.3 nextboot.sh
--- nextboot.sh 18 Jan 2006 04:48:45 -0000 1.3
+++ nextboot.sh 29 Jan 2008 12:50:23 -0000
@@ -10,12 +10,15 @@
nextboot_file="/boot/nextboot.conf"
display_usage() {
- echo "Usage: nextboot [-f] [-o options] -k kernel"
+ echo "Usage: nextboot [-f] [-o options] [-b bootfile] -k kernel"
echo " nextboot -D"
}
-while getopts "Dfk:o:" argument ; do
+while getopts "b:Dfk:o:" argument ; do
case "${argument}" in
+ b)
+ bootfile="${OPTARG}"
+ ;;
D)
delete="YES"
;;
@@ -40,9 +43,13 @@
exit 0
fi
-if [ "xxx${kernel}" = "xxx" ]; then
- display_usage
- exit 1
+if [ -z "${bootfile}" ]; then
+ bootfile=`sysctl -n kern.bootfile | sed -e 's,^.*/,,'`
+fi
+
+if [ -z "${kernel}" ]; then
+ kernel=`sysctl -n kern.bootfile | \
+ sed -e 's,/boot/,,' | sed -e 's,/.*$,,`
fi
if [ ${force} = "NO" -a ! -d /boot/${kernel} ]; then
@@ -50,8 +57,14 @@
exit 1
fi
+if [ ${force} = "NO" -a ! -f /boot/${kernel}/${bootfile} ]; then
+ echo "Error: /boot/${kernel}/${bootfile} doesn't exist. Use -f to override."
+ exit 1
+fi
+
cat > ${nextboot_file} << EOF
nextboot_enable="YES"
kernel="${kernel}"
+bootfile="${bootfile}"
kernel_options="${kernel_options}"
EOF
Index: reboot.8
===================================================================
RCS file: /home/ncvs/src/sbin/reboot/reboot.8,v
retrieving revision 1.24
diff -u -r1.24 reboot.8
--- reboot.8 22 Nov 2006 13:12:34 -0000 1.24
+++ reboot.8 29 Jan 2008 12:50:23 -0000
@@ -39,17 +39,29 @@
.Nd stopping and restarting the system
.Sh SYNOPSIS
.Nm halt
-.Op Fl lnpq
-.Op Fl k Ar kernel
-.Nm
-.Op Fl dlnpq
-.Op Fl k Ar kernel
+.Op Fl clnpq
+.Op Fl o Ar options
+.Op Fl b Ar kernel-name
+.Op Fl k Ar kernel-directory
+.Op Fl - Ar options ...
+.Nm
+.Op Fl cdlnpq
+.Op Fl o Ar options
+.Op Fl b Ar kernel-name
+.Op Fl k Ar kernel-directory
+.Op Fl - Ar options ...
.Nm fasthalt
-.Op Fl lnpq
-.Op Fl k Ar kernel
+.Op Fl clnpq
+.Op Fl o Ar options
+.Op Fl b Ar kernel-name
+.Op Fl k Ar kernel-directory
+.Op Fl - Ar options ...
.Nm fastboot
-.Op Fl dlnpq
-.Op Fl k Ar kernel
+.Op Fl cdlnpq
+.Op Fl o Ar options
+.Op Fl b Ar kernel-name
+.Op Fl k Ar kernel-directory
+.Op Fl - Ar options ...
.Sh DESCRIPTION
The
.Nm halt
@@ -73,9 +85,20 @@
supported only when rebooting, and it has no effect unless a dump
device has previously been specified with
.Xr dumpon 8 .
-.It Fl k Ar kernel
-Boot the specified
+.It Fl k Ar kernel-directory
+Boot from the specified
+.Ar kernel-directory
+on the next system boot.
+If the kernel boots successfully, the
+.Em default
+kernel will be booted on successive boots, this is a one-shot option.
+If the boot fails, the system will continue attempting to boot
.Ar kernel
+until the boot process is interrupted and a valid kernel booted.
+This may change in the future.
+.It Fl b Ar kernel-name
+Boot the specified
+.Ar kernel-name
on the next system boot.
If the kernel boots successfully, the
.Em default
@@ -84,6 +107,11 @@
.Ar kernel
until the boot process is interrupted and a valid kernel booted.
This may change in the future.
+.It Fl c
+Reboot the system with the current kernel, obtained from kern.bootfile
+sysctl.
+.It Fl o
+This option allows the passing of kernel flags for the next boot.
.It Fl l
The halt or reboot is
.Em not
@@ -129,6 +157,26 @@
utility is used when the system needs to be halted or restarted, giving
users advance warning of their impending doom and cleanly terminating
specific programs.
+.Sh EXAMPLES
+.Pp
+Reboot the system:
+.Pp
+.Dl "reboot"
+.Pp
+Reboot the system into single user mode:
+.Pp
+.Dl "reboot -o -s"
+.Dl "reboot -- -s"
+.Pp
+Reboot the system into a GENERIC kernel:
+.Pp
+.Dl "reboot -k GENERIC"
+.Pp
+Reboot the system into a kernel with debugging symbols:
+.Pp
+.Dl "reboot -b kernel.debug"
+.Pp
+.Pp
.Sh SEE ALSO
.Xr wtmp 5 ,
.Xr boot 8 ,
Index: reboot.c
===================================================================
RCS file: /home/ncvs/src/sbin/reboot/reboot.c,v
retrieving revision 1.26
diff -u -r1.26 reboot.c
--- reboot.c 2 Aug 2006 13:05:38 -0000 1.26
+++ reboot.c 29 Jan 2008 12:50:23 -0000
@@ -41,9 +41,12 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sbin/reboot/reboot.c,v 1.26 2006/08/02 13:05:38 bms Exp $");
+#include <sys/param.h>
+#include <sys/imgact.h>
#include <sys/reboot.h>
-#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/types.h>
#include <signal.h>
#include <err.h>
#include <errno.h>
@@ -56,6 +59,8 @@
#include <string.h>
#include <unistd.h>
+#define NEXTBOOT "/boot/nextboot.conf"
+
static void usage(void);
static u_int get_pageins(void);
@@ -65,18 +70,28 @@
main(int argc, char *argv[])
{
const struct passwd *pw;
- int ch, howto, i, fd, lflag, nflag, qflag, pflag, sverrno;
+ int ch, howto, i, cflag, lflag, nflag, qflag, pflag, sverrno;
u_int pageins;
- const char *p, *user, *kernel = NULL;
+ const char *p, *user, *kernel = NULL, *bootfile = NULL;
+ char sysctl_bootfile[200];
+ char args[MAXSHELLCMDLEN];
if (strstr((p = rindex(*argv, '/')) ? p + 1 : *argv, "halt")) {
dohalt = 1;
howto = RB_HALT;
} else
howto = 0;
- lflag = nflag = qflag = 0;
- while ((ch = getopt(argc, argv, "dk:lnpq")) != -1)
+ cflag = lflag = nflag = pflag = qflag = 0;
+ *args = '\0';
+
+ while ((ch = getopt(argc, argv, "b:cdk:lno:pq")) != -1)
switch(ch) {
+ case 'b':
+ bootfile = optarg;
+ break;
+ case 'c':
+ cflag = 1;
+ break;
case 'd':
howto |= RB_DUMP;
break;
@@ -90,6 +105,10 @@
nflag = 1;
howto |= RB_NOSYNC;
break;
+ case 'o':
+ if (*args != '\0') strcat(args, " ");
+ strcat(args, optarg);
+ break;
case 'p':
pflag = 1;
howto |= RB_POWEROFF;
@@ -104,6 +123,14 @@
argc -= optind;
argv += optind;
+ /* Concat all arguments after the -- on the command line */
+ while (argc > 0) {
+ if (*args != '\0') strcat(args, " ");
+ strcat(args, *argv);
+ argv++;
+ argc--;
+ }
+
if ((howto & (RB_DUMP | RB_HALT)) == (RB_DUMP | RB_HALT))
errx(1, "cannot dump (-d) when halting; must reboot instead");
if (geteuid()) {
@@ -111,21 +138,47 @@
err(1, NULL);
}
+ if (cflag) {
+ int max = sizeof(sysctl_bootfile) - 1;
+ char *c;
+ if (sysctlbyname("kern.bootfile",
+ sysctl_bootfile, &max, NULL, 0) < 0) {
+ perror("sysctl: kern.bootfile");
+ errx(1, NULL);
+ }
+
+ /*
+ * Split /boot/kernel/kernel.debug into kernel and kernel.debug
+ */
+ c = strchr(sysctl_bootfile, '/') + 1;
+ c = strchr(c, '/') + 1;
+ kernel = c;
+ c = strchr(c, '/');
+ *c = '\0';
+ bootfile = c + 1;
+ }
+
if (qflag) {
reboot(howto);
err(1, NULL);
}
- if (kernel != NULL) {
- fd = open("/boot/nextboot.conf", O_WRONLY | O_CREAT | O_TRUNC,
- 0444);
- if (fd > -1) {
- (void)write(fd, "nextboot_enable=\"YES\"\n", 22);
- (void)write(fd, "kernel=\"", 8L);
- (void)write(fd, kernel, strlen(kernel));
- (void)write(fd, "\"\n", 2);
- close(fd);
+ if (bootfile != NULL || kernel != NULL || *args != '\0') {
+ FILE *f;
+
+ if ((f = fopen(NEXTBOOT, "w")) == NULL) {
+ perror("fopen");
+ errx(1, NULL);
}
+ fprintf(f, "nextboot_enable=\"YES\"\n");
+ if (kernel != NULL)
+ fprintf(f, "kernel=\"%s\"\n", kernel);
+ if (bootfile != NULL)
+ fprintf(f, "bootfile=\"%s\"\n", bootfile);
+ if (*args != '\0')
+ fprintf(f, "kernel_options=\"%s\"\n", args);
+ fclose(f);
+ chmod(NEXTBOOT, 0444);
}
/* Log the reboot. */
@@ -219,7 +272,8 @@
static void
usage()
{
- (void)fprintf(stderr, "usage: %s [-%slnpq] [-k kernel]\n",
+ (void)fprintf(stderr,
+ "usage: %s [-%slnpq] [-b bootfile] [-k kernel] [-o options]\n",
getprogname(), dohalt ? "" : "d");
exit(1);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080129125108.822C3356>
