diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/bsdlabel/bsdlabel.8 | 6 | ||||
-rw-r--r-- | sbin/devd/devd.cc | 23 | ||||
-rw-r--r-- | sbin/dumpfs/dumpfs.8 | 3 | ||||
-rw-r--r-- | sbin/fdisk/fdisk.8 | 7 | ||||
-rw-r--r-- | sbin/ffsinfo/ffsinfo.8 | 2 | ||||
-rw-r--r-- | sbin/geom/class/nop/gnop.8 | 9 | ||||
-rw-r--r-- | sbin/geom/class/part/gpart.8 | 12 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 15 | ||||
-rw-r--r-- | sbin/init/Makefile | 6 | ||||
-rw-r--r-- | sbin/init/init.c | 285 | ||||
-rw-r--r-- | sbin/init/pathnames.h | 10 | ||||
-rw-r--r-- | sbin/mdconfig/mdconfig.8 | 11 | ||||
-rw-r--r-- | sbin/mdconfig/mdconfig.c | 7 | ||||
-rw-r--r-- | sbin/newfs/newfs.8 | 2 | ||||
-rw-r--r-- | sbin/newfs_msdos/newfs_msdos.8 | 4 | ||||
-rw-r--r-- | sbin/newfs_nandfs/newfs_nandfs.8 | 4 | ||||
-rw-r--r-- | sbin/reboot/boot_i386.8 | 2 | ||||
-rw-r--r-- | sbin/reboot/reboot.8 | 18 | ||||
-rw-r--r-- | sbin/reboot/reboot.c | 20 |
19 files changed, 373 insertions, 73 deletions
diff --git a/sbin/bsdlabel/bsdlabel.8 b/sbin/bsdlabel/bsdlabel.8 index d31187b..8137171 100644 --- a/sbin/bsdlabel/bsdlabel.8 +++ b/sbin/bsdlabel/bsdlabel.8 @@ -445,7 +445,10 @@ to properly recognize the disk: .Bd -literal -offset indent dd if=/dev/zero of=/dev/da0 bs=512 count=32 -fdisk -BI da0 +gpart create -s MBR da0 +gpart add -t freebsd da0 +gpart set -a active -i 1 da0 +gpart bootcode -b /boot/mbr da0 dd if=/dev/zero of=/dev/da0s1 bs=512 count=32 bsdlabel -w -B da0s1 bsdlabel -e da0s1 @@ -495,6 +498,5 @@ are not generally compatible. .Xr md 4 , .Xr disktab 5 , .Xr boot0cfg 8 , -.Xr fdisk 8 , .Xr gpart 8 , .Xr newfs 8 diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index a0cb037..1667219 100644 --- a/sbin/devd/devd.cc +++ b/sbin/devd/devd.cc @@ -108,15 +108,26 @@ __FBSDID("$FreeBSD$"); /* * Since the client socket is nonblocking, we must increase its send buffer to * handle brief event storms. On FreeBSD, AF_UNIX sockets don't have a receive - * buffer, so the client can't increate the buffersize by itself. + * buffer, so the client can't increase the buffersize by itself. * * For example, when creating a ZFS pool, devd emits one 165 character - * resource.fs.zfs.statechange message for each vdev in the pool. A 64k - * buffer has enough space for almost 400 drives, which would be very large but - * not impossibly large pool. A 128k buffer has enough space for 794 drives, - * which is more than can fit in a rack with modern technology. + * resource.fs.zfs.statechange message for each vdev in the pool. The kernel + * allocates a 4608B mbuf for each message. Modern technology places a limit of + * roughly 450 drives/rack, and it's unlikely that a zpool will ever be larger + * than that. + * + * 450 drives * 165 bytes / drive = 74250B of data in the sockbuf + * 450 drives * 4608B / drive = 2073600B of mbufs in the sockbuf + * + * We can't directly set the sockbuf's mbuf limit, but we can do it indirectly. + * The kernel sets it to the minimum of a hard-coded maximum value and sbcc * + * kern.ipc.sockbuf_waste_factor, where sbcc is the socket buffer size set by + * the user. The default value of kern.ipc.sockbuf_waste_factor is 8. If we + * set the bufsize to 256k and use the kern.ipc.sockbuf_waste_factor, then the + * kernel will set the mbuf limit to 2MB, which is just large enough for 450 + * drives. It also happens to be the same as the hardcoded maximum value. */ -#define CLIENT_BUFSIZE 131072 +#define CLIENT_BUFSIZE 262144 using namespace std; diff --git a/sbin/dumpfs/dumpfs.8 b/sbin/dumpfs/dumpfs.8 index feb8758..0d41059 100644 --- a/sbin/dumpfs/dumpfs.8 +++ b/sbin/dumpfs/dumpfs.8 @@ -98,10 +98,9 @@ The flag is needed if the filesystem uses .Xr gjournal 8 . .Sh SEE ALSO -.Xr disktab 5 , .Xr fs 5 , -.Xr disklabel 8 , .Xr fsck 8 , +.Xr gpart 8 , .Xr newfs 8 , .Xr tunefs 8 .Sh HISTORY diff --git a/sbin/fdisk/fdisk.8 b/sbin/fdisk/fdisk.8 index fcab133..6894ab9 100644 --- a/sbin/fdisk/fdisk.8 +++ b/sbin/fdisk/fdisk.8 @@ -39,6 +39,13 @@ The utility can be used to divide space on the disk into slices and set one active. .Sh DESCRIPTION +.Bf -symbolic +This command is obsolete. +Users are advised to use +.Xr gpart 8 +instead. +.Ef +.Pp The .Fx utility, diff --git a/sbin/ffsinfo/ffsinfo.8 b/sbin/ffsinfo/ffsinfo.8 index 9753cf7..0c114bd 100644 --- a/sbin/ffsinfo/ffsinfo.8 +++ b/sbin/ffsinfo/ffsinfo.8 @@ -121,9 +121,9 @@ to .Pa /var/tmp/ffsinfo with all available information. .Sh SEE ALSO -.Xr disklabel 8 , .Xr dumpfs 8 , .Xr fsck 8 , +.Xr gpart 8 , .Xr growfs 8 , .Xr gvinum 8 , .Xr newfs 8 , diff --git a/sbin/geom/class/nop/gnop.8 b/sbin/geom/class/nop/gnop.8 index 0103579..ae350d0 100644 --- a/sbin/geom/class/nop/gnop.8 +++ b/sbin/geom/class/nop/gnop.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 15, 2015 +.Dd October 10, 2015 .Dt GNOP 8 .Os .Sh NAME @@ -72,9 +72,10 @@ The utility is used for setting up transparent providers on existing ones. Its main purpose is testing other GEOM classes, as it allows forced provider removal and I/O error simulation with a given probability. -It also gathers the following statistics: number of read requests, number of -write requests, number of bytes read and number of bytes written. -In addition, it can be used as a good starting point for implementing new GEOM +It also gathers statistics on the number of read, write, delete, +getattr, flush, and other requests, and the number of bytes read and written. +.Nm +can also be used as a good starting point for implementing new GEOM classes. .Pp The first argument to diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index 3421ba0..ba579bf 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 14, 2015 +.Dd December 10, 2015 .Dt GPART 8 .Os .Sh NAME @@ -1107,15 +1107,6 @@ and .Cm recover are the only operations allowed on corrupt tables. .Pp -If the first sector of a provider is corrupt, the kernel can not detect GPT -even if the partition table itself is not corrupt. -The protective MBR can be rewritten using the -.Xr dd 1 -command, to restore the ability to detect the GPT. -The copy of the protective MBR is usually located in the -.Pa /boot/pmbr -file. -.Pp If one GPT header appears to be corrupt but the other copy remains intact, the kernel will log the following: .Bd -literal -offset indent @@ -1330,7 +1321,6 @@ and /sbin/gpart backup ada0 | /sbin/gpart restore -F ada1 ada2 .Ed .Sh SEE ALSO -.Xr dd 1 , .Xr geom 4 , .Xr boot0cfg 8 , .Xr geom 8 , diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index bb9eb4a..1b89e67 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -855,7 +855,7 @@ setifmetric(const char *val, int dummy __unused, int s, strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ifr.ifr_metric = atoi(val); if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) - warn("ioctl (set metric)"); + err(1, "ioctl SIOCSIFMETRIC (set metric)"); } static void @@ -865,7 +865,7 @@ setifmtu(const char *val, int dummy __unused, int s, strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ifr.ifr_mtu = atoi(val); if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) - warn("ioctl (set mtu)"); + err(1, "ioctl SIOCSIFMTU (set mtu)"); } static void @@ -875,15 +875,12 @@ setifname(const char *val, int dummy __unused, int s, char *newname; newname = strdup(val); - if (newname == NULL) { - warn("no memory to set ifname"); - return; - } + if (newname == NULL) + err(1, "no memory to set ifname"); ifr.ifr_data = newname; if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { - warn("ioctl (set name)"); free(newname); - return; + err(1, "ioctl SIOCSIFNAME (set name)"); } strlcpy(name, newname, sizeof(name)); free(newname); @@ -910,7 +907,7 @@ setifdescr(const char *val, int dummy __unused, int s, } if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) - warn("ioctl (set descr)"); + err(1, "ioctl SIOCSIFDESCR (set descr)"); free(newdescr); } diff --git a/sbin/init/Makefile b/sbin/init/Makefile index 7497a4b..eebaf59 100644 --- a/sbin/init/Makefile +++ b/sbin/init/Makefile @@ -2,6 +2,7 @@ # $FreeBSD$ PROG= init +SRCS= init.c getmntopts.c MAN= init.8 PRECIOUSPROG= INSTALLFLAGS=-b -B.bak @@ -9,6 +10,11 @@ CFLAGS+=-DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT DPADD= ${LIBUTIL} ${LIBCRYPT} LDADD= -lutil -lcrypt +# Needed for getmntopts.c +MOUNT= ${.CURDIR}/../../sbin/mount +CFLAGS+=-I${MOUNT} +.PATH: ${MOUNT} + NO_SHARED?= YES .include <bsd.prog.mk> diff --git a/sbin/init/init.c b/sbin/init/init.c index e6f567c..af672a9 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -46,6 +46,7 @@ static const char rcsid[] = #include <sys/param.h> #include <sys/ioctl.h> +#include <sys/mman.h> #include <sys/mount.h> #include <sys/sysctl.h> #include <sys/wait.h> @@ -79,6 +80,7 @@ static const char rcsid[] = #include <login_cap.h> #endif +#include "mntopts.h" #include "pathnames.h" /* @@ -103,6 +105,7 @@ static void warning(const char *, ...) __printflike(1, 2); static void emergency(const char *, ...) __printflike(1, 2); static void disaster(int); static void badsys(int); +static void revoke_ttys(void); static int runshutdown(void); static char *strk(char *); @@ -122,6 +125,8 @@ static state_func_t clean_ttys(void); static state_func_t catatonia(void); static state_func_t death(void); static state_func_t death_single(void); +static state_func_t reroot(void); +static state_func_t reroot_phase_two(void); static state_func_t run_script(const char *); @@ -194,7 +199,7 @@ main(int argc, char *argv[]) { state_t initial_transition = runcom; char kenv_value[PATH_MAX]; - int c; + int c, error; struct sigaction sa; sigset_t mask; @@ -227,6 +232,9 @@ main(int argc, char *argv[]) case 'q': /* rescan /etc/ttys */ sig = SIGHUP; break; + case 'r': /* remount root */ + sig = SIGEMT; + break; default: goto invalid; } @@ -248,7 +256,7 @@ invalid: /* * Create an initial session. */ - if (setsid() < 0) + if (setsid() < 0 && (errno != EPERM || getsid(0) != 1)) warning("initial setsid() failed: %m"); /* @@ -262,7 +270,7 @@ invalid: * This code assumes that we always get arguments through flags, * never through bits set in some random machine register. */ - while ((c = getopt(argc, argv, "dsf")) != -1) + while ((c = getopt(argc, argv, "dsfr")) != -1) switch (c) { case 'd': devfs = 1; @@ -273,6 +281,9 @@ invalid: case 'f': runcom_mode = FASTBOOT; break; + case 'r': + initial_transition = reroot_phase_two; + break; default: warning("unrecognized flag '-%c'", c); break; @@ -288,13 +299,13 @@ invalid: handle(badsys, SIGSYS, 0); handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU, SIGXFSZ, 0); - handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGUSR1, - SIGUSR2, 0); + handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, + SIGUSR1, SIGUSR2, 0); handle(alrm_handler, SIGALRM, 0); sigfillset(&mask); delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, - SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, - SIGUSR1, SIGUSR2, 0); + SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, + SIGALRM, SIGUSR1, SIGUSR2, 0); sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -374,6 +385,16 @@ invalid: free(s); } + if (initial_transition != reroot_phase_two) { + /* + * Unmount reroot leftovers. This runs after init(8) + * gets reexecuted after reroot_phase_two() is done. + */ + error = unmount(_PATH_REROOT, MNT_FORCE); + if (error != 0 && errno != EINVAL) + warning("Cannot unmount %s: %m", _PATH_REROOT); + } + /* * Start the state machine. */ @@ -621,6 +642,229 @@ write_stderr(const char *message) write(STDERR_FILENO, message, strlen(message)); } +static int +read_file(const char *path, void **bufp, size_t *bufsizep) +{ + struct stat sb; + size_t bufsize; + void *buf; + ssize_t nbytes; + int error, fd; + + fd = open(path, O_RDONLY); + if (fd < 0) { + emergency("%s: %s", path, strerror(errno)); + return (-1); + } + + error = fstat(fd, &sb); + if (error != 0) { + emergency("fstat: %s", strerror(errno)); + close(fd); + return (error); + } + + bufsize = sb.st_size; + buf = malloc(bufsize); + if (buf == NULL) { + emergency("malloc: %s", strerror(errno)); + close(fd); + return (error); + } + + nbytes = read(fd, buf, bufsize); + if (nbytes != (ssize_t)bufsize) { + emergency("read: %s", strerror(errno)); + close(fd); + free(buf); + return (error); + } + + error = close(fd); + if (error != 0) { + emergency("close: %s", strerror(errno)); + free(buf); + return (error); + } + + *bufp = buf; + *bufsizep = bufsize; + + return (0); +} + +static int +create_file(const char *path, const void *buf, size_t bufsize) +{ + ssize_t nbytes; + int error, fd; + + fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0700); + if (fd < 0) { + emergency("%s: %s", path, strerror(errno)); + return (-1); + } + + nbytes = write(fd, buf, bufsize); + if (nbytes != (ssize_t)bufsize) { + emergency("write: %s", strerror(errno)); + close(fd); + return (-1); + } + + error = close(fd); + if (error != 0) { + emergency("close: %s", strerror(errno)); + return (-1); + } + + return (0); +} + +static int +mount_tmpfs(const char *fspath) +{ + struct iovec *iov; + char errmsg[255]; + int error, iovlen; + + iov = NULL; + iovlen = 0; + memset(errmsg, 0, sizeof(errmsg)); + build_iovec(&iov, &iovlen, "fstype", + __DECONST(void *, "tmpfs"), (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", + __DECONST(void *, fspath), (size_t)-1); + build_iovec(&iov, &iovlen, "errmsg", + errmsg, sizeof(errmsg)); + + error = nmount(iov, iovlen, 0); + if (error != 0) { + if (*errmsg != '\0') { + emergency("cannot mount tmpfs on %s: %s: %s", + fspath, errmsg, strerror(errno)); + } else { + emergency("cannot mount tmpfs on %s: %s", + fspath, strerror(errno)); + } + return (error); + } + return (0); +} + +static state_func_t +reroot(void) +{ + void *buf; + char init_path[PATH_MAX]; + size_t bufsize, init_path_len; + int error, name[4]; + + buf = NULL; + bufsize = 0; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PATHNAME; + name[3] = -1; + init_path_len = sizeof(init_path); + error = sysctl(name, 4, init_path, &init_path_len, NULL, 0); + if (error != 0) { + emergency("failed to get kern.proc.pathname: %s", + strerror(errno)); + goto out; + } + + revoke_ttys(); + runshutdown(); + + /* + * Make sure nobody can interfere with our scheme. + */ + error = kill(-1, SIGKILL); + if (error != 0) { + emergency("kill(2) failed: %s", strerror(errno)); + goto out; + } + + /* + * Copy the init binary into tmpfs, so that we can unmount + * the old rootfs without committing suicide. + */ + error = read_file(init_path, &buf, &bufsize); + if (error != 0) + goto out; + error = mount_tmpfs(_PATH_REROOT); + if (error != 0) + goto out; + error = create_file(_PATH_REROOT_INIT, buf, bufsize); + if (error != 0) + goto out; + + /* + * Execute the temporary init. + */ + execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, "-r", NULL); + emergency("cannot exec %s: %s", _PATH_REROOT_INIT, strerror(errno)); + +out: + emergency("reroot failed; going to single user mode"); + free(buf); + return (state_func_t) single_user; +} + +static state_func_t +reroot_phase_two(void) +{ + char init_path[PATH_MAX], *path, *path_component; + size_t init_path_len; + int nbytes, error; + + /* + * Ask the kernel to mount the new rootfs. + */ + error = reboot(RB_REROOT); + if (error != 0) { + emergency("RB_REBOOT failed: %s", strerror(errno)); + goto out; + } + + /* + * Figure out where the destination init(8) binary is. Note that + * the path could be different than what we've started with. Use + * the value from kenv, if set, or the one from sysctl otherwise. + * The latter defaults to a hardcoded value, but can be overridden + * by a build time option. + */ + nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path)); + if (nbytes <= 0) { + init_path_len = sizeof(init_path); + error = sysctlbyname("kern.init_path", + init_path, &init_path_len, NULL, 0); + if (error != 0) { + emergency("failed to retrieve kern.init_path: %s", + strerror(errno)); + goto out; + } + } + + /* + * Repeat the init search logic from sys/kern/init_path.c + */ + path_component = init_path; + while ((path = strsep(&path_component, ":")) != NULL) { + /* + * Execute init(8) from the new rootfs. + */ + execl(path, path, NULL); + } + emergency("cannot exec init from %s: %s", init_path, strerror(errno)); + +out: + emergency("reroot failed; going to single user mode"); + return (state_func_t) single_user; +} + /* * Bring the system up single user. */ @@ -852,8 +1096,9 @@ run_script(const char *script) if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) collect_child(wpid); if (wpid == -1) { - if (requested_transition == death_single) - return (state_func_t) death_single; + if (requested_transition == death_single || + requested_transition == reroot) + return (state_func_t) requested_transition; if (errno == EINTR) continue; warning("wait for %s on %s failed: %m; going to " @@ -1326,6 +1571,9 @@ transition_handler(int sig) current_state == multi_user || current_state == catatonia) requested_transition = catatonia; break; + case SIGEMT: + requested_transition = reroot; + break; default: requested_transition = 0; break; @@ -1498,7 +1746,6 @@ alrm_handler(int sig) static state_func_t death(void) { - session_t *sp; int block, blocked; size_t len; @@ -1515,11 +1762,7 @@ death(void) * runshutdown() will perform the initial open() call, causing * the terminal attributes to be misconfigured. */ - for (sp = sessions; sp; sp = sp->se_next) { - sp->se_flags |= SE_SHUTDOWN; - kill(sp->se_process, SIGHUP); - revoke(sp->se_device); - } + revoke_ttys(); /* Try to run the rc.shutdown script within a period of time */ runshutdown(); @@ -1565,6 +1808,18 @@ death_single(void) return (state_func_t) single_user; } +static void +revoke_ttys(void) +{ + session_t *sp; + + for (sp = sessions; sp; sp = sp->se_next) { + sp->se_flags |= SE_SHUTDOWN; + kill(sp->se_process, SIGHUP); + revoke(sp->se_device); + } +} + /* * Run the system shutdown script. * diff --git a/sbin/init/pathnames.h b/sbin/init/pathnames.h index 39eed4c..ec33b45 100644 --- a/sbin/init/pathnames.h +++ b/sbin/init/pathnames.h @@ -35,7 +35,9 @@ #include <paths.h> -#define _PATH_INITLOG "/var/log/init.log" -#define _PATH_SLOGGER "/sbin/session_logger" -#define _PATH_RUNCOM "/etc/rc" -#define _PATH_RUNDOWN "/etc/rc.shutdown" +#define _PATH_INITLOG "/var/log/init.log" +#define _PATH_SLOGGER "/sbin/session_logger" +#define _PATH_RUNCOM "/etc/rc" +#define _PATH_RUNDOWN "/etc/rc.shutdown" +#define _PATH_REROOT "/dev/reroot" +#define _PATH_REROOT_INIT _PATH_REROOT "/init" diff --git a/sbin/mdconfig/mdconfig.8 b/sbin/mdconfig/mdconfig.8 index 8cb9a69..d273128 100644 --- a/sbin/mdconfig/mdconfig.8 +++ b/sbin/mdconfig/mdconfig.8 @@ -41,7 +41,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 6, 2015 +.Dd October 10, 2015 .Dt MDCONFIG 8 .Os .Sh NAME @@ -163,11 +163,11 @@ prefix. Size of the memory disk. .Ar Size is the number of 512 byte sectors unless suffixed with a -.Cm b , k , m , g , +.Cm b , k , m , g , t , or -.Cm t +.Cm p which -denotes byte, kilobyte, megabyte, gigabyte and terabyte respectively. +denotes byte, kilobyte, megabyte, gigabyte, terabyte and petabyte respectively. When used without the .Fl r option, the @@ -304,8 +304,7 @@ mount /dev/md1.nop /mnt .Sh SEE ALSO .Xr md 4 , .Xr ffs 7 , -.Xr bsdlabel 8 , -.Xr fdisk 8 , +.Xr gpart 8 , .Xr mdmfs 8 , .Xr malloc 9 .Sh HISTORY diff --git a/sbin/mdconfig/mdconfig.c b/sbin/mdconfig/mdconfig.c index d741c77..1b4e4ce 100644 --- a/sbin/mdconfig/mdconfig.c +++ b/sbin/mdconfig/mdconfig.c @@ -88,8 +88,8 @@ usage(void) fprintf(stderr, "\t\ttype = {malloc, vnode, swap}\n"); fprintf(stderr, "\t\toption = {cluster, compress, reserve}\n"); fprintf(stderr, "\t\tsize = %%d (512 byte blocks), %%db (B),\n"); - fprintf(stderr, "\t\t %%dk (kB), %%dm (MB), %%dg (GB) or\n"); - fprintf(stderr, "\t\t %%dt (TB)\n"); + fprintf(stderr, "\t\t %%dk (kB), %%dm (MB), %%dg (GB), \n"); + fprintf(stderr, "\t\t %%dt (TB), or %%dp (PB)\n"); exit(1); } @@ -217,6 +217,9 @@ main(int argc, char **argv) else if (*p == 't' || *p == 'T') { mdio.md_mediasize <<= 30; mdio.md_mediasize <<= 10; + } else if (*p == 'p' || *p == 'P') { + mdio.md_mediasize <<= 30; + mdio.md_mediasize <<= 20; } else errx(1, "unknown suffix on -s argument"); break; diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index 6764adc..f1bdd6b 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -303,11 +303,11 @@ on file systems that contain many small files. .Xr geom 4 , .Xr disktab 5 , .Xr fs 5 , -.Xr bsdlabel 8 , .Xr camcontrol 8 , .Xr dump 8 , .Xr dumpfs 8 , .Xr fsck 8 , +.Xr gpart 8 , .Xr gjournal 8 , .Xr growfs 8 , .Xr makefs 8 , diff --git a/sbin/newfs_msdos/newfs_msdos.8 b/sbin/newfs_msdos/newfs_msdos.8 index 218da93..8901673 100644 --- a/sbin/newfs_msdos/newfs_msdos.8 +++ b/sbin/newfs_msdos/newfs_msdos.8 @@ -228,9 +228,7 @@ Create a 30MB image file, with the FAT partition starting newfs_msdos -C 30M -@63s ./somefile .Ed .Sh SEE ALSO -.Xr disktab 5 , -.Xr disklabel 8 , -.Xr fdisk 8 , +.Xr gpart 8 , .Xr newfs 8 .Sh HISTORY The diff --git a/sbin/newfs_nandfs/newfs_nandfs.8 b/sbin/newfs_nandfs/newfs_nandfs.8 index 6997430..b357547 100644 --- a/sbin/newfs_nandfs/newfs_nandfs.8 +++ b/sbin/newfs_nandfs/newfs_nandfs.8 @@ -63,9 +63,7 @@ Create a file system, using default parameters, on newfs_nandfs /dev/ada0s1 .Ed .Sh SEE ALSO -.Xr disktab 5 , -.Xr disklabel 8 , -.Xr fdisk 8 , +.Xr gpart 8 , .Xr newfs 8 .Sh HISTORY The diff --git a/sbin/reboot/boot_i386.8 b/sbin/reboot/boot_i386.8 index e21e53f..b86e318 100644 --- a/sbin/reboot/boot_i386.8 +++ b/sbin/reboot/boot_i386.8 @@ -348,9 +348,9 @@ requirement has not been adhered to. .Xr make.conf 5 , .Xr ttys 5 , .Xr boot0cfg 8 , -.Xr bsdlabel 8 , .Xr btxld 8 , .Xr config 8 , +.Xr gpart 8 , .Xr gptboot 8 , .Xr halt 8 , .Xr loader 8 , diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8 index 84dd887..420d4f8 100644 --- a/sbin/reboot/reboot.8 +++ b/sbin/reboot/reboot.8 @@ -28,7 +28,7 @@ .\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd October 11, 2010 +.Dd May 22, 2015 .Dd Jan 06, 2016 .Dt REBOOT 8 .Os @@ -43,7 +43,7 @@ .Op Fl lNnpq .Op Fl k Ar kernel .Nm -.Op Fl dlNnpq +.Op Fl dlNnpqr .Op Fl k Ar kernel .Nm fasthalt .Op Fl lNnpq @@ -122,6 +122,13 @@ the flushing of the file system cache is performed (if the .Fl n option is not specified). This option should probably not be used. +.It Fl r +The system kills all processes, unmounts all filesystems, mounts the new +root filesystem, and begins the usual startup sequence. +After changing vfs.root.mountfrom with +.Xr kenv 8 , +.Nm Fl r +can be used to change the root filesystem while preserving kernel state. .El .Pp The @@ -139,6 +146,13 @@ Normally, the 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 +Replace current root filesystem with UFS mounted from +.Pa /dev/ada0s1a : +.Bd -literal -offset indent +kenv vfs.root.mountfrom=ufs:/dev/ada0s1a +reboot -r +.Ed .Sh SEE ALSO .Xr getutxent 3 , .Xr boot 8 , diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c index 6d590ac..961ba41 100644 --- a/sbin/reboot/reboot.c +++ b/sbin/reboot/reboot.c @@ -77,7 +77,7 @@ main(int argc, char *argv[]) } else howto = 0; lflag = nflag = qflag = Nflag = 0; - while ((ch = getopt(argc, argv, "dk:lNnpq")) != -1) + while ((ch = getopt(argc, argv, "dk:lNnpqr")) != -1) switch(ch) { case 'd': howto |= RB_DUMP; @@ -102,6 +102,9 @@ main(int argc, char *argv[]) case 'q': qflag = 1; break; + case 'r': + howto |= RB_REROOT; + break; case '?': default: usage(); @@ -113,6 +116,8 @@ main(int argc, char *argv[]) errx(1, "cannot dump (-d) when halting; must reboot instead"); if (Nflag && (howto & RB_NOSYNC) != 0) errx(1, "-N cannot be used with -n"); + if ((howto & RB_REROOT) != 0 && howto != RB_REROOT) + errx(1, "-r cannot be used with -d, -n, or -p"); if (geteuid()) { errno = EPERM; err(1, NULL); @@ -143,6 +148,9 @@ main(int argc, char *argv[]) if (dohalt) { openlog("halt", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "halted by %s", user); + } else if (howto & RB_REROOT) { + openlog("reroot", 0, LOG_AUTH | LOG_CONS); + syslog(LOG_CRIT, "rerooted by %s", user); } else { openlog("reboot", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "rebooted by %s", user); @@ -176,6 +184,16 @@ main(int argc, char *argv[]) */ (void)signal(SIGPIPE, SIG_IGN); + /* + * Only init(8) can perform rerooting. + */ + if (howto & RB_REROOT) { + if (kill(1, SIGEMT) == -1) + err(1, "SIGEMT init"); + + return (0); + } + /* Just stop init -- if we fail, we'll restart it. */ if (kill(1, SIGTSTP) == -1) err(1, "SIGTSTP init"); |