diff options
author | pjd <pjd@FreeBSD.org> | 2004-09-23 10:13:18 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2004-09-23 10:13:18 +0000 |
commit | 99b0ffd3c0991c325d4dfcc78af450e65f31b53e (patch) | |
tree | b6e24d5e3d76cd840e06a759f7d87adadcda0e7a /sys/kern/vfs_mount.c | |
parent | 49324bfed438d33dd53f2cce94f2f94f8eeecd78 (diff) | |
download | FreeBSD-src-99b0ffd3c0991c325d4dfcc78af450e65f31b53e.zip FreeBSD-src-99b0ffd3c0991c325d4dfcc78af450e65f31b53e.tar.gz |
Introduce new /boot/loader.conf variable: root_mount_delay.
It can be used to delay mounting root partition to give a chance to GEOM
providers to show up.
Now, when there is no needed provider, vfs_rootmount() function will look
for it every second and if it can't be find in defined time, it'll ask
for root device name (before this change it was done immediately).
This will allow to boot from gmirror device in degraded mode.
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r-- | sys/kern/vfs_mount.c | 146 |
1 files changed, 80 insertions, 66 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 8e547b0..0699283 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -111,6 +111,8 @@ static int vfs_donmount(struct thread *td, int fsflags, static int usermount = 0; SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "Unprivileged users may mount and unmount file systems"); +static int mount_root_delay = 5; +TUNABLE_INT("mount_root_delay", &mount_root_delay); MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); @@ -1202,73 +1204,81 @@ void vfs_mountroot(void) { char *cp; - int error, i, asked = 0; - + int asked, error, i, nrootdevs; + + asked = 0; + error = EDOOFUS; + nrootdevs = sizeof(rootdevnames) / sizeof(rootdevnames[0]); + if (mount_root_delay <= 0) + mount_root_delay = 1; + for (; mount_root_delay > 0; mount_root_delay--) { + /* + * Wait for GEOM to settle down + */ + g_waitidle(); - /* - * Wait for GEOM to settle down - */ - g_waitidle(); + /* + * We are booted with instructions to prompt for the root filesystem. + */ + if (boothowto & RB_ASKNAME) { + if (!vfs_mountroot_ask()) + return; + asked = 1; + } - /* - * We are booted with instructions to prompt for the root filesystem. - */ - if (boothowto & RB_ASKNAME) { - if (!vfs_mountroot_ask()) - return; - asked = 1; - } + /* + * The root filesystem information is compiled in, and we are + * booted with instructions to use it. + */ + if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { + if ((error = vfs_mountroot_try(ctrootdevname)) == 0) + return; + ctrootdevname = NULL; + } - /* - * The root filesystem information is compiled in, and we are - * booted with instructions to use it. - */ - if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { - if (!vfs_mountroot_try(ctrootdevname)) - return; - ctrootdevname = NULL; - } + /* + * We've been given the generic "use CDROM as root" flag. This is + * necessary because one media may be used in many different + * devices, so we need to search for them. + */ + if (boothowto & RB_CDROM) { + for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { + error = vfs_mountroot_try(cdrom_rootdevnames[i]); + if (error == 0) + return; + } + } - /* - * We've been given the generic "use CDROM as root" flag. This is - * necessary because one media may be used in many different - * devices, so we need to search for them. - */ - if (boothowto & RB_CDROM) { - for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { - if (!vfs_mountroot_try(cdrom_rootdevnames[i])) + /* + * Try to use the value read by the loader from /etc/fstab, or + * supplied via some other means. This is the preferred + * mechanism. + */ + cp = getenv("vfs.root.mountfrom"); + if (cp != NULL) { + error = vfs_mountroot_try(cp); + freeenv(cp); + if (error == 0) return; } - } - - /* - * Try to use the value read by the loader from /etc/fstab, or - * supplied via some other means. This is the preferred - * mechanism. - */ - cp = getenv("vfs.root.mountfrom"); - if (cp != NULL) { - error = vfs_mountroot_try(cp); - freeenv(cp); - if (!error) - return; - } - /* - * Try values that may have been computed by code during boot - */ - if (!vfs_mountroot_try(rootdevnames[0])) - return; - if (!vfs_mountroot_try(rootdevnames[1])) - return; + /* + * Try values that may have been computed by code during boot + */ + for (i = 0; i < nrootdevs; i++) { + if ((error = vfs_mountroot_try(rootdevnames[i])) == 0) + return; + } - /* - * If we (still) have a compiled-in default, try it. - */ - if (ctrootdevname != NULL) - if (!vfs_mountroot_try(ctrootdevname)) + /* + * If we (still) have a compiled-in default, try it. + */ + if ((error = vfs_mountroot_try(ctrootdevname)) == 0) return; + tsleep(&mount_root_delay, PRIBIO, "mroot", hz); + } + printf("Root mount failed: %d.\n", error); /* * Everything so far has failed, prompt on the console if we haven't * already tried that. @@ -1290,7 +1300,6 @@ vfs_mountroot_try(const char *mountfrom) const char *devname; int error; char patt[32]; - int s; vfsname = NULL; path = NULL; @@ -1300,9 +1309,13 @@ vfs_mountroot_try(const char *mountfrom) if (mountfrom == NULL) return (error); /* don't complain */ - s = splcam(); /* Overkill, but annoying without it */ - printf("Mounting root from %s\n", mountfrom); - splx(s); + if (bootverbose) { + int s; + + s = splcam(); /* Overkill, but annoying without it */ + printf("Trying to mount root from %s\n", mountfrom); + splx(s); + } /* parse vfs name and path */ vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK); @@ -1330,8 +1343,6 @@ vfs_mountroot_try(const char *mountfrom) diskdev = getdiskbyname(path); if (diskdev != NULL) rootdev = diskdev; - else - printf("setrootbyname failed\n"); } /* If the root device is a type "memory disk", mount RW */ @@ -1351,9 +1362,7 @@ done: if (error != 0) { if (mp != NULL) vfs_mount_destroy(mp, curthread); - printf("Root mount failed: %d\n", error); } else { - /* register with list of mounted filesystems */ mtx_lock(&mountlist_mtx); TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); @@ -1363,6 +1372,8 @@ done: inittodr(mp->mnt_time); vfs_unbusy(mp, curthread); error = VFS_START(mp, 0, curthread); + if (error == 0) + printf("Mounted root from %s.\n", mountfrom); } return (error); } @@ -1374,6 +1385,7 @@ static int vfs_mountroot_ask(void) { char name[128]; + int error; for(;;) { printf("\nManual root filesystem specification:\n"); @@ -1394,8 +1406,10 @@ vfs_mountroot_ask(void) g_dev_print(); continue; } - if (!vfs_mountroot_try(name)) + if ((error = vfs_mountroot_try(name)) == 0) return (0); + else + printf("Root mount failed: %d\n", error); } } |