Page MenuHomeFreeBSD

D3709.id9369.diff
No OneTemporary

D3709.id9369.diff

Index: etc/defaults/rc.conf
===================================================================
--- etc/defaults/rc.conf
+++ etc/defaults/rc.conf
@@ -23,6 +23,7 @@
#rc_debug="NO" # Set to YES to enable debugging output from rc.d
rc_info="NO" # Enables display of informational messages at boot.
+rc_parallel="NO" # Run startup scripts in parallel
rc_startmsgs="YES" # Show "Starting foo:" messages at boot
rcshutdown_timeout="90" # Seconds to wait before terminating rc.shutdown
early_late_divider="FILESYSTEMS" # Script that separates early/late
@@ -84,6 +85,7 @@
#geli_mirror_home_flags="-k /etc/geli/home.keys"
root_rw_mount="YES" # Set to NO to inhibit remounting root read-write.
+root_hold_delay="30" # Time to wait for root mount hold release.
fsck_y_enable="NO" # Set to YES to do fsck -y if the initial preen fails.
fsck_y_flags="" # Additional flags for fsck -y
background_fsck="YES" # Attempt to run fsck in the background where possible.
Index: etc/rc.d/mountcritlocal
===================================================================
--- etc/rc.d/mountcritlocal
+++ etc/rc.d/mountcritlocal
@@ -15,7 +15,7 @@
mountcritlocal_start()
{
- local err
+ local err holders waited
# Set up the list of network filesystem types for which mounting
# should be delayed until after network initialization.
@@ -35,8 +35,42 @@
mount_excludes="${mount_excludes}${fstype},"
done
mount_excludes=${mount_excludes%,}
+
+ # Originally, root mount hold had to be released before mounting the root
+ # filesystem. This delayed the boot, so it was changed to only wait if
+ # the root device isn't readily available. This can result in this script
+ # executing before all the devices - such as graid(8) - are available.
+ # Thus, should the mount fail, we will wait for the root mount hold release
+ # and retry.
mount -a -t ${mount_excludes}
err=$?
+ if [ $? -ne 0 ]; then
+ echo
+ echo 'Mounting /etc/fstab filesystems failed,' \
+ 'will retry after root mount hold release'
+
+ waited=0
+ while [ ${waited} -lt ${root_hold_delay} ]; do
+ holders="$(sysctl -n vfs.root_mount_hold)"
+ if [ -z "${holders}" ]; then
+ break;
+ fi
+ if [ ${waited} -eq 0 ]; then
+ echo -n "Waiting ${root_hold_delay}s" \
+ "for the root mount holders: ${holders}"
+ else
+ echo -n .
+ fi
+ if [ ${waited} -eq ${root_hold_delay} ]; then
+ break 2
+ fi
+ sleep 1
+ waited=$(($waited + 1))
+ done
+ mount -a -t ${mount_excludes}
+ err=$?
+ fi
+
check_startmsgs && echo '.'
case ${err} in
@@ -44,7 +78,7 @@
;;
*)
echo 'Mounting /etc/fstab filesystems failed,' \
- ' startup aborted'
+ 'startup aborted'
stop_boot true
;;
esac
Index: sys/kern/vfs_mountroot.c
===================================================================
--- sys/kern/vfs_mountroot.c
+++ sys/kern/vfs_mountroot.c
@@ -88,6 +88,8 @@
static int parse_mount(char **);
static struct mntarg *parse_mountroot_options(struct mntarg *, const char *);
+static int sysctl_vfs_root_mount_hold(SYSCTL_HANDLER_ARGS);
+static int vfs_mountroot_wait_if_neccessary(const char *fs, const char *dev);
/*
* The vnode of the system's root (/ in the filesystem, without chroot
@@ -129,6 +131,35 @@
static int root_mount_timeout = 3;
TUNABLE_INT("vfs.mountroot.timeout", &root_mount_timeout);
+SYSCTL_PROC(_vfs, OID_AUTO, root_mount_hold,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ NULL, 0, sysctl_vfs_root_mount_hold, "A",
+ "List of root mount hold tokens");
+
+static int
+sysctl_vfs_root_mount_hold(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sb;
+ struct root_hold_token *h;
+ int error;
+
+ sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
+
+ mtx_lock(&root_holds_mtx);
+ LIST_FOREACH(h, &root_holds, list) {
+ if (h != LIST_FIRST(&root_holds))
+ sbuf_putc(&sb, ' ');
+ sbuf_printf(&sb, "%s", h->who);
+ }
+ mtx_unlock(&root_holds_mtx);
+
+ error = sbuf_finish(&sb);
+ if (error == 0)
+ error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
+ sbuf_delete(&sb);
+ return (error);
+}
+
struct root_hold_token *
root_mount_hold(const char *identifier)
{
@@ -673,7 +704,7 @@
char *errmsg;
struct mntarg *ma;
char *dev, *fs, *opts, *tok;
- int delay, error, timeout;
+ int error;
error = parse_token(conf, &tok);
if (error)
@@ -710,20 +741,9 @@
goto out;
}
- if (strcmp(fs, "zfs") != 0 && strstr(fs, "nfs") == NULL &&
- dev[0] != '\0' && !parse_mount_dev_present(dev)) {
- printf("mountroot: waiting for device %s ...\n", dev);
- delay = hz / 10;
- timeout = root_mount_timeout * hz;
- do {
- pause("rmdev", delay);
- timeout -= delay;
- } while (timeout > 0 && !parse_mount_dev_present(dev));
- if (timeout <= 0) {
- error = ENODEV;
- goto out;
- }
- }
+ error = vfs_mountroot_wait_if_neccessary(fs, dev);
+ if (error != 0)
+ goto out;
ma = NULL;
ma = mount_arg(ma, "fstype", fs, -1);
@@ -931,6 +951,51 @@
}
}
+static int
+vfs_mountroot_wait_if_neccessary(const char *fs, const char *dev)
+{
+ int delay, timeout;
+
+ /*
+ * In case of ZFS and NFS we don't have a way to wait for
+ * specific device.
+ */
+ if (strcmp(fs, "zfs") == 0 || strstr(fs, "nfs") != NULL ||
+ dev[0] == '\0') {
+ vfs_mountroot_wait();
+ return (0);
+ }
+
+ /*
+ * Otherwise, no point in waiting if the device is already there.
+ * Note that we must wait for GEOM to finish reconfiguring itself,
+ * eg for geom_part(4) to finish tasting.
+ */
+ DROP_GIANT();
+ g_waitidle();
+ PICKUP_GIANT();
+ if (parse_mount_dev_present(dev))
+ return (0);
+
+ /*
+ * No luck. Let's wait. This code looks weird, but it's that way
+ * to behave exactly as it used to work before.
+ */
+ vfs_mountroot_wait();
+ printf("mountroot: waiting for device %s...\n", dev);
+ delay = hz / 10;
+ timeout = root_mount_timeout * hz;
+ do {
+ pause("rmdev", delay);
+ timeout -= delay;
+ } while (timeout > 0 && !parse_mount_dev_present(dev));
+
+ if (timeout <= 0)
+ return (ENODEV);
+
+ return (0);
+}
+
void
vfs_mountroot(void)
{
@@ -942,8 +1007,6 @@
td = curthread;
- vfs_mountroot_wait();
-
sb = sbuf_new_auto();
vfs_mountroot_conf0(sb);
sbuf_finish(sb);

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 27, 7:06 AM (31 m, 9 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28052094
Default Alt Text
D3709.id9369.diff (6 KB)

Event Timeline