From 991a7b8b43bb311cc647d8ac037b0b549281e9c4 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 18 Mar 2015 13:08:28 +0100 Subject: [PATCH 1/2] parse_mount(): Use vfs.mountroot.timeout for ZFS root pools as well Instead of trying to figure out the required vdevs to wait for, just call kernel_mount() until it works or the time is up. Fancier approaches are conceivable ... If the current approach is kept, it may make sense to add a flag to tell kernel_mount() not to free the mount args. As an alternative the retrying could be delegated to kernel_mount() itself. Obtained from: ElectroBSD --- sys/kern/vfs_mountroot.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index a33e376..b38b3f1 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -707,7 +707,7 @@ parse_mount(char **conf) char *errmsg; struct mntarg *ma; char *dev, *fs, *opts, *tok; - int error; + int delay, error, timeout; error = parse_token(conf, &tok); if (error) @@ -748,15 +748,29 @@ parse_mount(char **conf) if (error != 0) goto out; - 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; + do { + 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 (strcmp(fs, "zfs") != 0) + break; + timeout -= delay; + if (timeout > 0 && error) { + pause("rmdev", delay); + printf("Mounting from %s:%s failed with error %d. " + "%d seconds left. Retrying.\n", fs, dev, error, + timeout / hz); + } + } while (timeout > 0 && error); out: if (error) { printf("Mounting from %s:%s failed with error %d", @@ -960,8 +974,12 @@ 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. + * For ZFS we can't simply wait for a specific device + * as we only know the pool name. To work around this, + * parse_mount() will retry the mount later on. + * + * While retrying for NFS could be implemented similarly + * it is currently not supported. */ if (strcmp(fs, "zfs") == 0 || strstr(fs, "nfs") != NULL || dev[0] == '\0') { -- 2.7.4 From 1210680f74b8ad5831e43c155287d8456d711641 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Nov 2015 14:21:15 +0100 Subject: [PATCH 2/2] parse_mount(): Use the vfs.mountroot.timeout for NFS as well Note that this hasn't actually been tested yet. Obtained from: ElectroBSD --- sys/kern/vfs_mountroot.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index b38b3f1..4fcc289 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -761,7 +761,7 @@ parse_mount(char **conf) ma = parse_mountroot_options(ma, opts); error = kernel_mount(ma, MNT_ROOTFS); - if (strcmp(fs, "zfs") != 0) + if (strcmp(fs, "zfs") != 0 || strstr(fs, "nfs") != NULL) break; timeout -= delay; if (timeout > 0 && error) { @@ -974,12 +974,9 @@ vfs_mountroot_wait_if_neccessary(const char *fs, const char *dev) int delay, timeout; /* - * For ZFS we can't simply wait for a specific device + * For ZFS and NFS we can't simply wait for a specific device * as we only know the pool name. To work around this, * parse_mount() will retry the mount later on. - * - * While retrying for NFS could be implemented similarly - * it is currently not supported. */ if (strcmp(fs, "zfs") == 0 || strstr(fs, "nfs") != NULL || dev[0] == '\0') { -- 2.7.4