summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_mount.c146
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c5
2 files changed, 81 insertions, 70 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);
}
}
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 8fc3741..a8a5937 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -161,11 +161,8 @@ ffs_omount(struct mount *mp, char *path, caddr_t data, struct thread *td)
* Use NULL path to indicate we are mounting the root filesystem.
*/
if (path == NULL) {
- if ((error = bdevvp(rootdev, &rootvp))) {
- printf("ffs_mountroot: can't find rootvp\n");
+ if ((error = bdevvp(rootdev, &rootvp)) != 0)
return (error);
- }
-
if ((error = ffs_mountfs(rootvp, mp, td)) != 0)
return (error);
return (0);
OpenPOWER on IntegriCloud