Page MenuHomeFreeBSD

D3204.id7333.diff
No OneTemporary

D3204.id7333.diff

Index: etc/autofs/special_hosts
===================================================================
--- etc/autofs/special_hosts
+++ etc/autofs/special_hosts
@@ -12,6 +12,10 @@
out=`showmount -e "$1"`
[ $? -eq 0 ] || exit 1
+
+# The point of the sub() below is to replace leading plus signs with
+# a hash; plus has special meaning in maps.
echo "$out" | awk -v host="$1" \
- 'NR > 1 { printf "%s\t%s:%s ", $1, host, $1 } END { printf "\n" }'
+ 'NR > 1 { l=$1; sub(/\+\+*/, "#", l); printf "%s\t%s:%s ", l, host, $1 }
+ END { printf "\n" }'
Index: etc/motd
===================================================================
--- etc/motd
+++ etc/motd
@@ -1,6 +1,6 @@
FreeBSD ?.?.? (UNKNOWN)
-Welcome to FreeBSD!
+ Welcome to FreeBSD!
Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories: https://www.FreeBSD.org/security/
Index: games/pom/pom.6
===================================================================
--- games/pom/pom.6
+++ games/pom/pom.6
@@ -33,7 +33,7 @@
.Os
.Sh NAME
.Nm pom
-.Nd display the phase of the moon
+.Nd display the phase of the Moon
.Sh SYNOPSIS
.Nm
.Op Fl p
@@ -42,7 +42,7 @@
.Sh DESCRIPTION
The
.Nm
-utility displays the current phase of the moon.
+utility displays the current phase of the Moon.
Useful for selecting software completion target dates and predicting
managerial behavior.
.Pp
@@ -54,13 +54,13 @@
.Fl d
and
.Fl t
-to specify a specific date and time for which the phase of the moon
+to specify a specific date and time for which the phase of the Moon
has to be calculated.
If
.Fl d
but not
.Fl t
-has been specified, it will calculate the phase of the moon on that
+has been specified, it will calculate the phase of the Moon on that
day at midnight.
.Sh SEE ALSO
`Practical Astronomy with Your Calculator' by Duffett-Smith.
Index: lib/libc/sys/reboot.2
===================================================================
--- lib/libc/sys/reboot.2
+++ lib/libc/sys/reboot.2
@@ -113,6 +113,9 @@
before the processor is halted or rebooted.
This option may be useful if file system changes have been made manually
or if the processor is on fire.
+.It Dv RB_REROOT
+Instead of rebooting, unmount all filesystems except the one containing
+currently-running executable, and mount the new root filesystem.
.It Dv RB_RDONLY
Initially mount the root file system read-only.
This is currently the default, and this option has been deprecated.
Index: sbin/init/Makefile
===================================================================
--- sbin/init/Makefile
+++ sbin/init/Makefile
@@ -2,12 +2,19 @@
# $FreeBSD$
PROG= init
+SRCS= init.c
+SRCS+= getmntopts.c
MAN= init.8
PRECIOUSPROG=
INSTALLFLAGS=-b -B.bak
CFLAGS+=-DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT
LIBADD= util crypt
+# Needed for getmntopts.c
+MOUNT= ${.CURDIR}/../../sbin/mount
+CFLAGS+=-I${MOUNT}
+.PATH: ${MOUNT}
+
NO_SHARED?= YES
.include <bsd.prog.mk>
Index: sbin/init/init.c
===================================================================
--- sbin/init/init.c
+++ sbin/init/init.c
@@ -46,6 +46,7 @@
#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 @@
#include <login_cap.h>
#endif
+#include "mntopts.h"
#include "pathnames.h"
/*
@@ -122,6 +124,8 @@
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 *);
@@ -193,7 +197,7 @@
{
state_t initial_transition = runcom;
char kenv_value[PATH_MAX];
- int c;
+ int c, error;
struct sigaction sa;
sigset_t mask;
@@ -226,6 +230,9 @@
case 'q': /* rescan /etc/ttys */
sig = SIGHUP;
break;
+ case 'r': /* remount root */
+ sig = SIGEMT;
+ break;
default:
goto invalid;
}
@@ -247,8 +254,13 @@
/*
* Create an initial session.
*/
- if (setsid() < 0)
- warning("initial setsid() failed: %m");
+ if (setsid() < 0) {
+ if (errno == EPERM && getsid(0) == getpid()) {
+ /* Okay, we've already done setsid() before. */
+ } else {
+ warning("initial setsid() failed: %m");
+ }
+ }
/*
* Establish an initial user so that programs running
@@ -261,7 +273,7 @@
* 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;
@@ -272,6 +284,9 @@
case 'f':
runcom_mode = FASTBOOT;
break;
+ case 'R':
+ initial_transition = reroot_phase_two;
+ break;
default:
warning("unrecognized flag '-%c'", c);
break;
@@ -287,13 +302,13 @@
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;
@@ -373,6 +388,15 @@
free(s);
}
+ if (initial_transition != reroot_phase_two) {
+ /*
+ * Unmount reroot leftovers.
+ */
+ error = unmount(_PATH_REROOT, MNT_FORCE);
+ if (error != 0 && errno != EINVAL)
+ warning("Cannot unmount %s: %m", _PATH_REROOT);
+ }
+
/*
* Start the state machine.
*/
@@ -620,6 +644,184 @@
write(STDERR_FILENO, message, strlen(message));
}
+static int
+read_file(const char *path, void **bufp, size_t *bufsizep)
+{
+ struct stat sb;
+ int error, fd;
+ size_t bufsize;
+ void *buf;
+ ssize_t nbytes;
+
+ 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));
+ return (error);
+ }
+
+ bufsize = sb.st_size;
+ buf = malloc(bufsize);
+ if (buf == NULL) {
+ emergency("malloc: %s", strerror(errno));
+ return (error);
+ }
+
+ nbytes = read(fd, buf, bufsize);
+ if (nbytes != (ssize_t)bufsize) {
+ emergency("read: %s", strerror(errno));
+ 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, void *buf, size_t bufsize)
+{
+ int error, fd;
+ ssize_t nbytes;
+
+ 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));
+ return (-1);
+ }
+
+ error = close(fd);
+ if (error != 0) {
+ emergency("close: %s", strerror(errno));
+ free(buf);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+mount_tmpfs(const char *fspath)
+{
+ struct iovec *iov = NULL;
+ char errmsg[255];
+ int error, 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)
+{
+ int error;
+ void *buf;
+ size_t bufsize;
+
+ /*
+ * Copy the init binary into tmpfs, so that we can unmount
+ * the old rootfs without committing suicide.
+ */
+ error = read_file(_PATH_INIT, &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");
+
+ /*
+ * Make sure we don't loop when calling single_user on error.
+ */
+ howto = RB_AUTOBOOT;
+ Reboot = FALSE;
+ return (state_func_t) single_user;
+}
+
+static state_func_t
+reroot_phase_two(void)
+{
+ int 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;
+ }
+
+ /*
+ * Execute init(8) from the new rootfs.
+ *
+ * Note that at this point, all this warning() stuff is useless
+ * anyway; we don't have stderr nor stdout.
+ */
+ execl(_PATH_INIT, _PATH_INIT, NULL);
+ emergency("cannot exec %s: %s", _PATH_INIT, strerror(errno));
+
+out:
+ /*
+ * Make sure we don't loop when calling single_user on error.
+ */
+ howto = RB_AUTOBOOT;
+ Reboot = FALSE;
+ emergency("reroot failed; going to single user mode");
+ return (state_func_t) single_user;
+}
+
/*
* Bring the system up single user.
*/
@@ -641,6 +843,8 @@
#ifdef DEBUGSHELL
char altshell[128];
#endif
+ if (howto == RB_REROOT)
+ return (reroot());
if (Reboot) {
/* Instead of going single user, let's reboot the machine */
@@ -1308,6 +1512,8 @@
howto = RB_POWEROFF;
case SIGUSR1:
howto |= RB_HALT;
+ case SIGEMT:
+ howto = RB_REROOT;
case SIGINT:
Reboot = TRUE;
case SIGTERM:
Index: sbin/init/pathnames.h
===================================================================
--- sbin/init/pathnames.h
+++ sbin/init/pathnames.h
@@ -35,7 +35,10 @@
#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_INIT "/sbin/init"
+#define _PATH_REROOT "/tmp"
+#define _PATH_REROOT_INIT _PATH_REROOT "/init"
Index: sbin/kldstat/Makefile
===================================================================
--- sbin/kldstat/Makefile
+++ sbin/kldstat/Makefile
@@ -29,4 +29,6 @@
PROG= kldstat
MAN= kldstat.8
+LIBADD= util
+
.include <bsd.prog.mk>
Index: sbin/kldstat/kldstat.c
===================================================================
--- sbin/kldstat/kldstat.c
+++ sbin/kldstat/kldstat.c
@@ -36,6 +36,8 @@
#include <sys/module.h>
#include <sys/linker.h>
+#include <libutil.h>
+
#define POINTER_WIDTH ((int)(sizeof(void *) * 2 + 2))
static void
@@ -51,18 +53,28 @@
}
static void
-printfile(int fileid, int verbose)
+printfile(int fileid, int verbose, int humanized)
{
struct kld_file_stat stat;
int modid;
+ char buf[6];
stat.version = sizeof(struct kld_file_stat);
- if (kldstat(fileid, &stat) < 0)
+ if (kldstat(fileid, &stat) < 0) {
err(1, "can't stat file id %d", fileid);
- else
- printf("%2d %4d %p %-8zx %s",
- stat.id, stat.refs, stat.address, stat.size,
- stat.name);
+ } else {
+ if (humanized) {
+ humanize_number(buf, sizeof(buf), stat.size,
+ "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE);
+ printf("%2d %4d %p %-8s %s",
+ stat.id, stat.refs, stat.address, buf,
+ stat.name);
+ } else {
+ printf("%2d %4d %p %-8zx %s",
+ stat.id, stat.refs, stat.address, stat.size,
+ stat.name);
+ }
+ }
if (verbose) {
printf(" (%s)\n", stat.pathname);
@@ -78,8 +90,8 @@
static void
usage(void)
{
- fprintf(stderr, "usage: kldstat [-q] [-v] [-i id] [-n filename]\n");
- fprintf(stderr, " kldstat [-q] [-m modname]\n");
+ fprintf(stderr, "usage: kldstat [-h] [-q] [-v] [-i id] [-n filename]\n");
+ fprintf(stderr, " kldstat [-h] [-q] [-m modname]\n");
exit(1);
}
@@ -87,6 +99,7 @@
main(int argc, char** argv)
{
int c;
+ int humanized = 0;
int verbose = 0;
int fileid = 0;
int quiet = 0;
@@ -94,8 +107,11 @@
char* modname = NULL;
char* p;
- while ((c = getopt(argc, argv, "i:m:n:qv")) != -1)
+ while ((c = getopt(argc, argv, "hi:m:n:qv")) != -1)
switch (c) {
+ case 'h':
+ humanized = 1;
+ break;
case 'i':
fileid = (int)strtoul(optarg, &p, 10);
if (*p != '\0')
@@ -157,10 +173,10 @@
printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' ');
if (fileid != 0)
- printfile(fileid, verbose);
+ printfile(fileid, verbose, humanized);
else
for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid))
- printfile(fileid, verbose);
+ printfile(fileid, verbose, humanized);
return 0;
}
Index: sbin/mdconfig/mdconfig.8
===================================================================
--- sbin/mdconfig/mdconfig.8
+++ sbin/mdconfig/mdconfig.8
@@ -37,12 +37,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 30, 2013
+.Dd July 25, 2015
.Dt MDCONFIG 8
.Os
.Sh NAME
.Nm mdconfig
-.Nd configure and enable memory disks
+.Nd configure memory disks
.Sh SYNOPSIS
.Nm
.Fl a
@@ -75,7 +75,7 @@
.Sh DESCRIPTION
The
.Nm
-utility configures and enables
+utility is used to configure
.Xr md 4
devices.
.Pp
@@ -103,7 +103,7 @@
.Fl o Cm reserve
option is not set, creating and filling a large
malloc-backed memory disk is a very easy way to
-panic a system.
+panic the system.
.It Cm vnode
A file specified with
.Fl f Ar file
@@ -164,11 +164,6 @@
.Cm t
which
denotes byte, kilobyte, megabyte, gigabyte and terabyte respectively.
-The
-.Fl a
-and
-.Fl t Ar swap
-options are implied if not specified.
.It Fl S Ar sectorsize
Sectorsize to use for the memory disk, in bytes.
.It Fl x Ar sectors/track
@@ -206,6 +201,11 @@
.It Oo Cm no Oc Ns Cm force
Disable/enable extra sanity checks to prevent the user from doing something
that might adversely affect the system.
+This can be used with the
+.Fl u
+flag, to forcibly destroy an
+.Xr md 4
+disk that is still in use.
.It Oo Cm no Oc Ns Cm readonly
Enable/disable readonly mode.
.El
@@ -227,66 +227,55 @@
.Fl t Ar vnode
.Fl f Ar file .
.Sh EXAMPLES
-Create a 4 megabyte
-.Xr malloc 9
-backed memory disk.
+Create a disk with /tmp/boot.flp as backing storage.
The name of the allocated unit will be printed on stdout, such as
-.Dq Li md3 :
+.Dq Li md0 :
.Pp
-.Dl mdconfig -a -t malloc -s 4m
+.Dl mdconfig /tmp/boot.flp
.Pp
-Create a disk named
-.Pa /dev/md4
-with
-.Pa /tmp/boot.flp
-as backing storage:
+Create a 1 gigabyte
+.Cm swap
+backed memory disk named
+.Dq Li md3 :
.Pp
-.Dl mdconfig -a -t vnode -f /tmp/boot.flp -u md4
+.Dl mdconfig -s 1g -u md3
.Pp
Detach and free all resources used by
-.Pa /dev/md4 :
+.Pa /dev/md3 :
+.Pp
+.Dl mdconfig -du md3
+.Pp
+Show detailed information on currently configured memory disks:
+.Pp
+.Dl mdconfig -lv
.Pp
-.Dl mdconfig -d -u md4
+Resize the
+.Dq Li md3
+memory disk to 2 gigabytes:
.Pp
-Create a 128MByte swap backed disk, initialize an
+.Dl mdconfig -rs 2g -u md3
+.Pp
+Create a 1 gigabyte
+.Cm swap
+backed disk, initialize an
.Xr ffs 7
file system on it, and mount it on
.Pa /tmp :
.Bd -literal -offset indent
-mdconfig -a -t swap -s 128M -u md10
+mdconfig -s 1g -u md10
newfs -U /dev/md10
mount /dev/md10 /tmp
chmod 1777 /tmp
.Ed
.Pp
-Create a 5MB file-backed disk
-.Po Fl a
-and
-.Fl t Ar vnode
-are implied
-.Pc :
-.Bd -literal -offset indent
-dd if=/dev/zero of=somebackingfile bs=1k count=5k
-mdconfig -f somebackingfile -u md0
-bsdlabel -w md0 auto
-newfs md0c
-mount /dev/md0c /mnt
-.Ed
-.Pp
-Create an
-.Xr md 4
-device out of an ISO 9660 CD image file
-.Po Fl a
-and
-.Fl t Ar vnode
-are implied
-.Pc , using the first available
+Create a memory disk out of an ISO 9660 CD image file,
+using the first available
.Xr md 4
-device, and then mount the new memory disk:
+device, and then mount it:
.Bd -literal -offset indent
-mount -t cd9660 /dev/`mdconfig -f cdimage.iso` /mnt
-.Pp
+mount -t cd9660 /dev/`mdconfig cdimage.iso` /mnt
.Ed
+.Pp
Create a file-backed device from a hard disk image that begins
with 512K of raw header information.
.Xr gnop 8
@@ -294,7 +283,7 @@
.Pa md1.nop
to the start of the filesystem in the image.
.Bd -literal -offset indent
-mdconfig -f diskimage.img -u md1
+mdconfig -u md1 diskimage.img
gnop create -o 512K md1
mount /dev/md1.nop /mnt
.Ed
Index: sbin/rcorder/rcorder.c
===================================================================
--- sbin/rcorder/rcorder.c
+++ sbin/rcorder/rcorder.c
@@ -151,12 +151,14 @@
static void initialize(void);
static void generate_ordering(void);
+static int parallel = 0;
+
int
main(int argc, char *argv[])
{
int ch;
- while ((ch = getopt(argc, argv, "dk:s:")) != -1)
+ while ((ch = getopt(argc, argv, "dk:ps:")) != -1)
switch (ch) {
case 'd':
#ifdef DEBUG
@@ -168,6 +170,9 @@
case 'k':
strnode_add(&keep_list, optarg, 0);
break;
+ case 'p':
+ parallel = 1;
+ break;
case 's':
strnode_add(&skip_list, optarg, 0);
break;
@@ -657,6 +662,9 @@
*/
while (head->next != NULL)
do_file(head->next->fnode);
+
+ if (parallel)
+ printf("\n");
}
static int
@@ -763,7 +771,7 @@
/* if we were already in progress, don't print again */
if (was_set == 0 && skip_ok(fnode) && keep_ok(fnode))
- printf("%s\n", fnode->filename);
+ printf("%s%s", fnode->filename, parallel ? " " : "\n");
if (fnode->next != NULL) {
fnode->next->last = fnode->last;
@@ -803,4 +811,7 @@
DPRINTF((stderr, "generate on %s\n", fn_head->next->filename));
do_file(fn_head->next);
}
+
+ if (parallel)
+ printf("\n");
}
Index: sbin/reboot/reboot.8
===================================================================
--- sbin/reboot/reboot.8
+++ 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
.Dt REBOOT 8
.Os
.Sh NAME
@@ -42,7 +42,7 @@
.Op Fl lnpq
.Op Fl k Ar kernel
.Nm
-.Op Fl dlnpq
+.Op Fl dlnpqr
.Op Fl k Ar kernel
.Nm fasthalt
.Op Fl lnpq
@@ -111,6 +111,12 @@
.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.
+It can be used after updating vfs.root.mountfrom using
+.Xr kenv 8 ,
+to change the root filesystem while preserving kernel state.
.El
.Pp
The
Index: sbin/reboot/reboot.c
===================================================================
--- sbin/reboot/reboot.c
+++ sbin/reboot/reboot.c
@@ -77,7 +77,7 @@
} else
howto = 0;
lflag = nflag = qflag = 0;
- while ((ch = getopt(argc, argv, "dk:lnpq")) != -1)
+ while ((ch = getopt(argc, argv, "dk:lnpqr")) != -1)
switch(ch) {
case 'd':
howto |= RB_DUMP;
@@ -98,6 +98,9 @@
case 'q':
qflag = 1;
break;
+ case 'r':
+ howto |= RB_REROOT;
+ break;
case '?':
default:
usage();
@@ -107,6 +110,8 @@
if ((howto & (RB_DUMP | RB_HALT)) == (RB_DUMP | RB_HALT))
errx(1, "cannot dump (-d) when halting; must reboot instead");
+ if ((howto & RB_REROOT) != 0 && (howto & RB_REROOT) != RB_REROOT)
+ errx(1, "-r flag is mutually exclusive with -d, -n, and -p");
if (geteuid()) {
errno = EPERM;
err(1, NULL);
@@ -137,6 +142,9 @@
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);
@@ -170,6 +178,16 @@
*/
(void)signal(SIGPIPE, SIG_IGN);
+ /*
+ * Nobody but 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");
Index: share/man/man9/Makefile
===================================================================
--- share/man/man9/Makefile
+++ share/man/man9/Makefile
@@ -1739,6 +1739,7 @@
vfs_getopt.9 vfs_setopt.9 \
vfs_getopt.9 vfs_setopt_part.9 \
vfs_getopt.9 vfs_setopts.9
+MLINKS+=vgone.9 vgonel.9
MLINKS+=vhold.9 vdrop.9 \
vhold.9 vdropl.9 \
vhold.9 vholdl.9
Index: share/man/man9/vgone.9
===================================================================
--- share/man/man9/vgone.9
+++ share/man/man9/vgone.9
@@ -37,6 +37,7 @@
.In sys/vnode.h
.Ft void
.Fn vgone "struct vnode *vp"
+.Fn vgonel "struct vnode *vp"
.Sh DESCRIPTION
The
.Fn vgone
@@ -56,6 +57,11 @@
.Fn vgone
function takes an exclusively locked vnode, and returns with the vnode
exclusively locked.
+The
+.Fn vgonel
+differs from
+.Fn vgone
+by requiring the vnode interlock to be held.
.Sh SEE ALSO
.Xr vnode 9
.Sh AUTHORS
Index: sys/boot/common/module.c
===================================================================
--- sys/boot/common/module.c
+++ sys/boot/common/module.c
@@ -102,6 +102,7 @@
static int
command_load(int argc, char *argv[])
{
+ struct preloaded_file *fp;
char *typestr;
int dofile, dokld, ch, error;
@@ -139,6 +140,13 @@
command_errmsg = "invalid load type";
return(CMD_ERROR);
}
+
+ fp = file_findfile(argv[1], typestr);
+ if (fp) {
+ sprintf(command_errbuf, "warning: file '%s' already loaded", argv[1]);
+ return (CMD_ERROR);
+ }
+
return (file_loadraw(argv[1], typestr, 1) ? CMD_OK : CMD_ERROR);
}
/*
Index: sys/dev/iscsi/iscsi.c
===================================================================
--- sys/dev/iscsi/iscsi.c
+++ sys/dev/iscsi/iscsi.c
@@ -2322,11 +2322,23 @@
{
struct iscsi_session *is;
- ISCSI_DEBUG("removing all sessions due to shutdown");
+ /*
+ * Trying to reconnect during system shutdown would lead to hang.
+ */
+ fail_on_disconnection = 1;
+ /*
+ * If we have any sessions waiting for reconnection, request
+ * maintenance thread to fail them immediately instead of waiting
+ * for reconnect timeout.
+ */
sx_slock(&sc->sc_lock);
- TAILQ_FOREACH(is, &sc->sc_sessions, is_next)
- iscsi_session_terminate(is);
+ TAILQ_FOREACH(is, &sc->sc_sessions, is_next) {
+ ISCSI_SESSION_LOCK(is);
+ if (is->is_waiting_for_iscsid)
+ iscsi_session_reconnect(is);
+ ISCSI_SESSION_UNLOCK(is);
+ }
sx_sunlock(&sc->sc_lock);
}
@@ -2352,12 +2364,7 @@
}
sc->sc_cdev->si_drv1 = sc;
- /*
- * Note that this needs to get run before dashutdown(). Otherwise,
- * when rebooting with iSCSI session with outstanding requests,
- * but disconnected, dashutdown() will hang on cam_periph_runccb().
- */
- sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_post_sync,
+ sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
iscsi_shutdown, sc, SHUTDOWN_PRI_FIRST);
return (0);
@@ -2375,7 +2382,7 @@
}
if (sc->sc_shutdown_eh != NULL)
- EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->sc_shutdown_eh);
+ EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_eh);
sx_slock(&sc->sc_lock);
TAILQ_FOREACH_SAFE(is, &sc->sc_sessions, is_next, tmp)
Index: sys/fs/devfs/devfs_vfsops.c
===================================================================
--- sys/fs/devfs/devfs_vfsops.c
+++ sys/fs/devfs/devfs_vfsops.c
@@ -182,6 +182,8 @@
fmp = VFSTODEVFS(mp);
KASSERT(fmp->dm_mount != NULL,
("devfs_unmount unmounted devfs_mount"));
+ if (mntflags & MNT_FORCE)
+ flags |= FORCECLOSE;
/* There is 1 extra root vnode reference from devfs_mount(). */
error = vflush(mp, 1, flags, curthread);
if (error)
Index: sys/geom/geom_dev.c
===================================================================
--- sys/geom/geom_dev.c
+++ sys/geom/geom_dev.c
@@ -358,6 +358,13 @@
#else
e = 0;
#endif
+
+ /*
+ * This happens on attempt to open a device node with O_EXEC.
+ */
+ if (r + w + e == 0)
+ return (EINVAL);
+
if (w) {
/*
* When running in very secure mode, do not allow
@@ -401,6 +408,10 @@
#else
e = 0;
#endif
+
+ if (r + w + e == 0)
+ return (EINVAL);
+
sc = cp->private;
mtx_lock(&sc->sc_mtx);
sc->sc_open += r + w + e;
Index: sys/kern/kern_shutdown.c
===================================================================
--- sys/kern/kern_shutdown.c
+++ sys/kern/kern_shutdown.c
@@ -50,6 +50,7 @@
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/eventhandler.h>
+#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
@@ -154,6 +155,7 @@
static void shutdown_halt(void *junk, int howto);
static void shutdown_panic(void *junk, int howto);
static void shutdown_reset(void *junk, int howto);
+static int kern_reroot(void);
/* register various local shutdown events */
static void
@@ -172,9 +174,6 @@
SYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL);
-/*
- * The system call that results in a reboot.
- */
/* ARGSUSED */
int
sys_reboot(struct thread *td, struct reboot_args *uap)
@@ -188,9 +187,17 @@
if (error == 0)
error = priv_check(td, PRIV_REBOOT);
if (error == 0) {
- mtx_lock(&Giant);
- kern_reboot(uap->opt);
- mtx_unlock(&Giant);
+ if (uap->opt & RB_REROOT) {
+ mtx_lock(&Giant);
+ error = kern_reroot();
+ mtx_unlock(&Giant);
+ } else {
+ mtx_lock(&Giant);
+ kern_reboot(uap->opt);
+ swapoff_all();
+ DELAY(100000); /* wait for console output to finish */
+ mtx_unlock(&Giant);
+ }
}
return (error);
}
@@ -454,6 +461,52 @@
}
/*
+ * The system call that results in changing the rootfs.
+ */
+static int
+kern_reroot(void)
+{
+ struct vnode *oldrootvnode;
+ struct mount *mp;
+
+ if (curproc->p_pid != 1)
+ return (EPERM);
+
+ /*
+ * Remove the filesystem containing currently-running executable
+ * from the mount list, to prevent it from being unmounted
+ * by vfs_unmountall(), and to avoid confusing vfs_mountroot().
+ */
+ mp = curproc->p_textvp->v_mount;
+
+ mtx_lock(&mountlist_mtx);
+ TAILQ_REMOVE(&mountlist, mp, mnt_list);
+ mtx_unlock(&mountlist_mtx);
+
+ oldrootvnode = rootvnode;
+
+ /*
+ * Actually change the rootfs.
+ */
+ vfs_unmountall();
+ vfs_mountroot();
+
+ /*
+ * Update all references to the old rootvnode.
+ */
+ mountcheckdirs(oldrootvnode, rootvnode);
+
+ /*
+ * Add the temporary filesystem back.
+ */
+ mtx_lock(&mountlist_mtx);
+ TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
+ mtx_unlock(&mountlist_mtx);
+
+ return (0);
+}
+
+/*
* If the shutdown was a clean halt, behave accordingly.
*/
static void
Index: sys/kern/vfs_subr.c
===================================================================
--- sys/kern/vfs_subr.c
+++ sys/kern/vfs_subr.c
@@ -2709,10 +2709,12 @@
* If FORCECLOSE is set, forcibly close the vnode.
*/
if (vp->v_usecount == 0 || (flags & FORCECLOSE)) {
+#if 0
VNASSERT(vp->v_usecount == 0 ||
vp->v_op != &devfs_specops ||
(vp->v_type != VCHR && vp->v_type != VBLK), vp,
("device VNODE %p is FORCECLOSED", vp));
+#endif
vgonel(vp);
} else {
busy++;
@@ -3554,40 +3556,50 @@
void
vfs_unmountall(void)
{
- struct mount *mp;
- struct thread *td;
+ struct mount *mp, *devmp, *tmp;
int error;
CTR1(KTR_VFS, "%s: unmounting all filesystems", __func__);
- td = curthread;
+
+ devmp = NULL;
/*
* Since this only runs when rebooting, it is not interlocked.
*/
- while(!TAILQ_EMPTY(&mountlist)) {
- mp = TAILQ_LAST(&mountlist, mntlist);
+ TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, tmp) {
vfs_ref(mp);
- error = dounmount(mp, MNT_FORCE, td);
+
+ /*
+ * Forcibly unmounting /dev before / would prevent proper
+ * unmount of the latter.
+ */
+ if (strcmp(mp->mnt_stat.f_mntonname, "/dev") == 0) {
+ devmp = mp;
+ continue;
+ }
+
+ printf("%s: unmounting %s\n", __func__, mp->mnt_stat.f_mntonname);
+ error = dounmount(mp, MNT_FORCE, curthread);
if (error != 0) {
- TAILQ_REMOVE(&mountlist, mp, mnt_list);
- /*
- * XXX: Due to the way in which we mount the root
- * file system off of devfs, devfs will generate a
- * "busy" warning when we try to unmount it before
- * the root. Don't print a warning as a result in
- * order to avoid false positive errors that may
- * cause needless upset.
- */
- if (strcmp(mp->mnt_vfc->vfc_name, "devfs") != 0) {
- printf("unmount of %s failed (",
- mp->mnt_stat.f_mntonname);
- if (error == EBUSY)
- printf("BUSY)\n");
- else
- printf("%d)\n", error);
- }
- } else {
- /* The unmount has removed mp from the mountlist */
+ printf("unmount of %s failed (",
+ mp->mnt_stat.f_mntonname);
+ if (error == EBUSY)
+ printf("BUSY)\n");
+ else
+ printf("%d)\n", error);
+ }
+ }
+
+ if (devmp != NULL) {
+ printf("%s: unmounting %s\n", __func__, devmp->mnt_stat.f_mntonname);
+ error = dounmount(devmp, MNT_FORCE, curthread);
+ if (error != 0) {
+ printf("unmount of %s failed (",
+ devmp->mnt_stat.f_mntonname);
+ if (error == EBUSY)
+ printf("BUSY)\n");
+ else
+ printf("%d)\n", error);
}
}
}
Index: sys/sys/reboot.h
===================================================================
--- sys/sys/reboot.h
+++ sys/sys/reboot.h
@@ -59,6 +59,7 @@
#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
#define RB_PAUSE 0x100000 /* pause after each output line during probe */
+#define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */
#define RB_MULTIPLE 0x20000000 /* use multiple consoles */
#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
Index: usr.sbin/ctld/ctl.conf.5
===================================================================
--- usr.sbin/ctld/ctl.conf.5
+++ usr.sbin/ctld/ctl.conf.5
@@ -60,15 +60,10 @@
.Dl ...
}
-.No lun Ar name No {
-.Dl path Ar path
-}
-
.No target Ar name {
.Dl auth-group Ar name
.Dl portal-group Ar name Op Ar agname
.Dl port Ar name
-.Dl lun Ar number Ar name
.Dl lun Ar number No {
.Dl path Ar path
.Dl }

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 6:29 PM (4 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29727357
Default Alt Text
D3204.id7333.diff (30 KB)

Event Timeline