From b4d124d42116770d78ee62e98a2719a113fd613e Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 20 Mar 2018 22:57:14 +0000 Subject: [PATCH] MFC r330745: Make root mount timeout logic work for filesystems other than ufs. The vfs.mountroot.timeout tunable and .timeout directive in a mount.conf(5) file allow specifying a wait timeout for the device(s) hosting the root filesystem to become usable. The current mechanism for waiting for devices and detecting their availability can't be used for zfs-hosted filesystems. See the comment #20 in the PR for some expanded detail on these points. This change adds retry logic to the actual root filesystem mount. That is, insted of relying on device availability using device name lookups, it uses the kernel_mount() call itself to detect whether the filesystem can be mounted, and loops until it succeeds or the configured timeout is exceeded. These changes are based on the patch attached to the PR, but it's rewritten enough that all mistakes belong to me. PR: 208882 git-svn-id: svn://svn.freebsd.org/base/stable/10@331276 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/kern/vfs_mountroot.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 12cddff1e..1c3e477c3 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -741,15 +741,31 @@ parse_mount(char **conf) } } - ma = NULL; - ma = mount_arg(ma, "fstype", fs, -1); - ma = mount_arg(ma, "fspath", "/", -1); - ma = mount_arg(ma, "from", dev, -1); - ma = mount_arg(ma, "errmsg", errmsg, ERRMSGL); - ma = mount_arg(ma, "ro", NULL, 0); - ma = parse_mountroot_options(ma, opts); - error = kernel_mount(ma, MNT_ROOTFS); + delay = hz / 10; + timeout = root_mount_timeout * hz; + + for (;;) { + ma = NULL; + ma = mount_arg(ma, "fstype", fs, -1); + ma = mount_arg(ma, "fspath", "/", -1); + ma = mount_arg(ma, "from", dev, -1); + ma = mount_arg(ma, "errmsg", errmsg, ERRMSGL); + ma = mount_arg(ma, "ro", NULL, 0); + ma = parse_mountroot_options(ma, opts); + + error = kernel_mount(ma, MNT_ROOTFS); + if (error == 0 || timeout <= 0) + break; + if (root_mount_timeout * hz == timeout || + (bootverbose && timeout % hz == 0)) { + printf("Mounting from %s:%s failed with error %d; " + "retrying for %d more second%s\n", fs, dev, error, + timeout / hz, (timeout / hz > 1) ? "s" : ""); + } + pause("rmretry", delay); + timeout -= delay; + } out: if (error) { printf("Mounting from %s:%s failed with error %d", -- 2.45.0