From owner-svn-src-head@freebsd.org Fri Oct 30 15:35:05 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 79A10A207A3; Fri, 30 Oct 2015 15:35:05 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 38DE01C3D; Fri, 30 Oct 2015 15:35:05 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9UFZ4ft068215; Fri, 30 Oct 2015 15:35:04 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9UFZ4Xv068214; Fri, 30 Oct 2015 15:35:04 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201510301535.t9UFZ4Xv068214@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Fri, 30 Oct 2015 15:35:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290196 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Oct 2015 15:35:05 -0000 Author: trasz Date: Fri Oct 30 15:35:04 2015 New Revision: 290196 URL: https://svnweb.freebsd.org/changeset/base/290196 Log: Make root mount wait mechanism smarter, by making it wait only if the root device doesn't yet exist. Reviewed by: kib@, marcel@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3709 Modified: head/sys/kern/vfs_mountroot.c Modified: head/sys/kern/vfs_mountroot.c ============================================================================== --- head/sys/kern/vfs_mountroot.c Fri Oct 30 14:50:29 2015 (r290195) +++ head/sys/kern/vfs_mountroot.c Fri Oct 30 15:35:04 2015 (r290196) @@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$"); static int parse_mount(char **); static struct mntarg *parse_mountroot_options(struct mntarg *, const char *); +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 @@ -673,7 +674,7 @@ parse_mount(char **conf) 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 +711,9 @@ parse_mount(char **conf) 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 +921,51 @@ vfs_mountroot_wait(void) } } +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 +977,6 @@ vfs_mountroot(void) td = curthread; - vfs_mountroot_wait(); - sb = sbuf_new_auto(); vfs_mountroot_conf0(sb); sbuf_finish(sb);