Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147931864
D3204.id7333.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
30 KB
Referenced Files
None
Subscribers
None
D3204.id7333.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D3204: Fix loading files twice.
Attached
Detach File
Event Timeline
Log In to Comment