Add root_mount_wait() function which can be used to wait until the root

file system is mounted. This is useful for kernel modules loaded from
/boot/loader.conf, that have to access file system.
This commit is contained in:
Pawel Jakub Dawidek 2007-04-03 11:45:28 +00:00
parent bff64a4db3
commit afd894bb12
2 changed files with 59 additions and 10 deletions

View File

@ -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();
}
/*

View File

@ -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);
/*