Index: vfs_mount.c =================================================================== RCS file: /private/FreeBSD/src/sys/kern/vfs_mount.c,v retrieving revision 1.138 diff -u -p -r1.138 vfs_mount.c --- vfs_mount.c 30 Jul 2004 22:08:52 -0000 1.138 +++ vfs_mount.c 25 Aug 2004 20:13:19 -0000 @@ -111,6 +111,8 @@ static int vfs_donmount(struct thread *t 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"); @@ -1201,73 +1203,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. @@ -1289,7 +1299,6 @@ vfs_mountroot_try(const char *mountfrom) const char *devname; int error; char patt[32]; - int s; vfsname = NULL; path = NULL; @@ -1299,9 +1308,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); @@ -1329,8 +1342,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 */ @@ -1350,9 +1361,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); @@ -1362,6 +1371,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); } @@ -1373,6 +1384,7 @@ static int vfs_mountroot_ask(void) { char name[128]; + int error; for(;;) { printf("\nManual root filesystem specification:\n"); @@ -1393,8 +1405,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); } } Index: ../ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /private/FreeBSD/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.240 diff -u -p -r1.240 ffs_vfsops.c --- ../ufs/ffs/ffs_vfsops.c 30 Jul 2004 22:08:52 -0000 1.240 +++ ../ufs/ffs/ffs_vfsops.c 25 Aug 2004 19:51:36 -0000 @@ -161,11 +161,8 @@ ffs_omount(struct mount *mp, char *path, * 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);