diff options
author | trasz <trasz@FreeBSD.org> | 2015-10-30 15:52:10 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2015-10-30 15:52:10 +0000 |
commit | e52d6f1e4a485dde1baf3a1e057bcdbf73ebbf7b (patch) | |
tree | de89f37ec395b87059ddc577708871cb63ebb789 /sys/kern/vfs_mountroot.c | |
parent | 3b970d7ccc00f84d53bef1b8094f2907ff67b750 (diff) | |
download | FreeBSD-src-e52d6f1e4a485dde1baf3a1e057bcdbf73ebbf7b.zip FreeBSD-src-e52d6f1e4a485dde1baf3a1e057bcdbf73ebbf7b.tar.gz |
After r290196, the kernel won't wait for stuff like gmirror nodes
if they are not required for mounting rootfs. However, it's possible
that some setups try to mount them in mountcritlocal (ie from fstab).
Export the list of current root mount holds using a new sysctl,
vfs.root_mount_hold, and make mountcritlocal retry if "mount -a" fails
and the list is not empty.
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D3709
Diffstat (limited to 'sys/kern/vfs_mountroot.c')
-rw-r--r-- | sys/kern/vfs_mountroot.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 2691a6e..cf24253 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$"); 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); /* @@ -130,6 +131,35 @@ static int root_mount_complete; 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) { |