diff options
| author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2007-04-03 11:45:28 +0000 |
|---|---|---|
| committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2007-04-03 11:45:28 +0000 |
| commit | afd894bb129069074447f4f566b735b79795e1ad (patch) | |
| tree | bd155e34b6b2cf2489f0fca16579e78f5af04472 | |
| parent | bff64a4db3bb361cddf2a3b1265ded2de18307b3 (diff) | |
Notes
| -rw-r--r-- | sys/kern/vfs_mount.c | 68 | ||||
| -rw-r--r-- | sys/sys/systm.h | 1 |
2 files changed, 59 insertions, 10 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 2f8023011857..d4a2f109f2bc 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1305,6 +1305,11 @@ struct root_hold_token { static LIST_HEAD(, root_hold_token) root_holds = LIST_HEAD_INITIALIZER(&root_holds); +static int root_mount_complete = 0; + +/* + * Hold root mount. + */ struct root_hold_token * root_mount_hold(const char *identifier) { @@ -1318,6 +1323,9 @@ root_mount_hold(const char *identifier) return (h); } +/* + * Release root mount. + */ void root_mount_rel(struct root_hold_token *h) { @@ -1329,8 +1337,11 @@ root_mount_rel(struct root_hold_token *h) free(h, M_DEVBUF); } +/* + * Wait for all subsystems to release root mount. + */ static void -root_mount_wait(void) +root_mount_prepare(void) { struct root_hold_token *h; @@ -1352,6 +1363,40 @@ root_mount_wait(void) } } +/* + * Root was mounted, share the good news. + */ +static void +root_mount_done(void) +{ + + mtx_lock(&mountlist_mtx); + root_mount_complete = 1; + wakeup(&root_mount_complete); + mtx_unlock(&mountlist_mtx); +} + +/* + * Wait until root is mounted. + */ +void +root_mount_wait(void) +{ + + /* + * Panic on an obvious deadlock - the function can't be called from + * a thread which is doing the whole SYSINIT stuff. + */ + KASSERT(curthread->td_proc->p_pid != 0, + ("root_mount_wait: cannot be called from the swapper thread")); + mtx_lock(&mountlist_mtx); + while (!root_mount_complete) { + msleep(&root_mount_complete, &mountlist_mtx, PZERO, "rootwait", + hz); + } + mtx_unlock(&mountlist_mtx); +} + static void set_rootvnode(struct thread *td) { @@ -1507,7 +1552,7 @@ vfs_mountroot(void) char *cp; int error, i, asked = 0; - root_mount_wait(); + root_mount_prepare(); mount_zone = uma_zcreate("Mountpoints", sizeof(struct mount), NULL, NULL, mount_init, mount_fini, @@ -1519,7 +1564,7 @@ vfs_mountroot(void) */ if (boothowto & RB_ASKNAME) { if (!vfs_mountroot_ask()) - return; + goto mounted; asked = 1; } @@ -1529,7 +1574,7 @@ vfs_mountroot(void) */ if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { if (!vfs_mountroot_try(ctrootdevname)) - return; + goto mounted; ctrootdevname = NULL; } @@ -1541,7 +1586,7 @@ vfs_mountroot(void) if (boothowto & RB_CDROM) { for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { if (!vfs_mountroot_try(cdrom_rootdevnames[i])) - return; + goto mounted; } } @@ -1555,32 +1600,35 @@ vfs_mountroot(void) error = vfs_mountroot_try(cp); freeenv(cp); if (!error) - return; + goto mounted; } /* * Try values that may have been computed by code during boot */ if (!vfs_mountroot_try(rootdevnames[0])) - return; + goto mounted; if (!vfs_mountroot_try(rootdevnames[1])) - return; + goto mounted; /* * If we (still) have a compiled-in default, try it. */ if (ctrootdevname != NULL) if (!vfs_mountroot_try(ctrootdevname)) - return; + goto mounted; /* * Everything so far has failed, prompt on the console if we haven't * already tried that. */ if (!asked) if (!vfs_mountroot_ask()) - return; + goto mounted; panic("Root mount failed, startup aborted."); + +mounted: + root_mount_done(); } /* diff --git a/sys/sys/systm.h b/sys/sys/systm.h index f0d04d3ad4c5..673619e13944 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -339,6 +339,7 @@ struct root_hold_token; struct root_hold_token *root_mount_hold(const char *identifier); void root_mount_rel(struct root_hold_token *h); +void root_mount_wait(void); /* |
