Esempio n. 1
0
static int
ntfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct ntfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flag = 0;
	args.uid = 0;
	args.gid = 0;
	args.mode = 0777;

	if ((error = ntfs_mountfs(rootvp, mp, &args, l)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	mountlist_append(mp);
	(void)ntfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Esempio n. 2
0
int
cd9660_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;
	int error;
	struct iso_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp))
			!= 0) {
		vrele(rootvp);
		return (error);
	}

	args.flags = ISOFSMNT_ROOT;
	if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	(void)cd9660_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Esempio n. 3
0
/*
 * Called by main() when ufs is going to be mounted as root.
 */
lfs_mountroot()
{
	extern struct vnode *rootvp;
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	int error;
	
	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("lfs_mountroot: can't setup bdevvp's");
		return (error);
	}
	if (error = vfs_rootmountalloc("lfs", "root_device", &mp))
		return (error);
	if (error = lfs_mountfs(rootvp, mp, p)) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp, p);
		free(mp, M_MOUNT);
		return (error);
	}
	simple_lock(&mountlist_slock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	simple_unlock(&mountlist_slock);
	(void)lfs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp, p);
	return (0);
}
Esempio n. 4
0
int
v7fs_mountroot(void)
{
    struct mount *mp;
    int error;

    DPRINTF("");
    /* On mountroot, devvp (rootdev) is opened by vfs_mountroot */
    if ((error = is_v7fs_partition (rootvp)))
        return error;

    if ((error = vfs_rootmountalloc(MOUNT_V7FS, "root_device", &mp))) {
        DPRINTF("mountalloc error=%d\n", error);
        vrele(rootvp);
        return error;
    }

    if ((error = v7fs_mountfs(rootvp, mp, _BYTE_ORDER))) {
        DPRINTF("mountfs error=%d\n", error);
        vfs_unbusy(mp, false, NULL);
        vfs_destroy(mp);
        return error;
    }

    mountlist_append(mp);

    vfs_unbusy(mp, false, NULL);

    return 0;
}
Esempio n. 5
0
int
ext2fs_mountroot(void)
{
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return ENODEV;

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return error;
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return error;
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	ext2fs_sb_setmountinfo(fs, mp);
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return 0;
}
Esempio n. 6
0
int
cd9660_mountroot(void)
{
	struct mount *mp;
	extern struct vnode *rootvp;
	struct proc *p = curproc;	/* XXX */
	int error;
	struct iso_args args;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("cd9660_mountroot: can't setup bdevvp's");
		return (error);
	}

	if ((error = vfs_rootmountalloc("cd9660", "root_device", &mp)) != 0)
		return (error);
	args.flags = ISOFSMNT_ROOT;
	if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT, 0);
		return (error);
	}

	TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	(void)cd9660_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(0);

	return (0);
}
Esempio n. 7
0
/*
 * Called by main() when ufs is going to be mounted as root.
 */
ffs_mountroot()
{
	extern struct vnode *rootvp;
	struct fs *fs;
	struct mount *mp;
	struct proc *p = current_proc();	/* XXX */
	struct ufsmount *ump;
	u_int size;
	int error;
	
	/*
	 * Get vnode for rootdev.
	 */
	if (error = bdevvp(rootdev, &rootvp)) {
		printf("ffs_mountroot: can't setup bdevvp");
		return (error);
	}
	if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) {
		vrele(rootvp); /* release the reference from bdevvp() */
		return (error);
	}

	/* Must set the MNT_ROOTFS flag before doing the actual mount */
	mp->mnt_flag |= MNT_ROOTFS;

	/* Set asynchronous flag by default */
	mp->mnt_flag |= MNT_ASYNC;

	if (error = ffs_mountfs(rootvp, mp, p)) {
		mp->mnt_vfc->vfc_refcount--;

		if (mp->mnt_kern_flag & MNTK_IO_XINFO)
		        FREE(mp->mnt_xinfo_ptr, M_TEMP);
		vfs_unbusy(mp, p);

		vrele(rootvp); /* release the reference from bdevvp() */
		FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
		return (error);
	}
	simple_lock(&mountlist_slock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	simple_unlock(&mountlist_slock);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp, p);
	inittodr(fs->fs_time);
	return (0);
}
Esempio n. 8
0
int
ffs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	struct ufsmount *ump;
	int error;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	swapdev_vp = NULL;
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("ffs_mountroot: can't setup bdevvp's\n");
		if (swapdev_vp)
			vrele(swapdev_vp);
		return (error);
	}

	if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) {
		vrele(swapdev_vp);
		vrele(rootvp);
		return (error);
	}

	if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		vrele(swapdev_vp);
		vrele(rootvp);
		return (error);
	}

	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(fs->fs_time);

	return (0);
}
Esempio n. 9
0
int
mfs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct lwp *l = curlwp;		/* XXX */
	struct ufsmount *ump;
	struct mfsnode *mfsp;
	int error = 0;

	if ((error = vfs_rootmountalloc(MOUNT_MFS, "mfs_root", &mp))) {
		vrele(rootvp);
		return (error);
	}

	mfsp = kmem_alloc(sizeof(*mfsp), KM_SLEEP);
	rootvp->v_data = mfsp;
	rootvp->v_op = mfs_vnodeop_p;
	rootvp->v_tag = VT_MFS;
	mfsp->mfs_baseoff = mfs_rootbase;
	mfsp->mfs_size = mfs_rootsize;
	mfsp->mfs_vnode = rootvp;
	mfsp->mfs_proc = NULL;		/* indicate kernel space */
	mfsp->mfs_shutdown = 0;
	cv_init(&mfsp->mfs_cv, "mfs");
	mfsp->mfs_refcnt = 1;
	bufq_alloc(&mfsp->mfs_buflist, "fcfs", 0);
	if ((error = ffs_mountfs(rootvp, mp, l)) != 0) {
		vfs_unbusy(mp, false, NULL);
		bufq_free(mfsp->mfs_buflist);
		vfs_destroy(mp);
		kmem_free(mfsp, sizeof(*mfsp));
		return (error);
	}
	mutex_enter(&mountlist_lock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	mutex_exit(&mountlist_lock);
	mp->mnt_vnodecovered = NULLVP;
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Esempio n. 10
0
int
mfs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;
	struct ufsmount *ump;
	struct mfsnode *mfsp;
	int error;

	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("mfs_mountroot: can't setup bdevvp's");
		return (error);
	}
	if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0)
		return (error);
	mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
	rootvp->v_data = mfsp;
	rootvp->v_op = mfs_vnodeop_p;
	rootvp->v_tag = VT_MFS;
	mfsp->mfs_baseoff = mfs_rootbase;
	mfsp->mfs_size = mfs_rootsize;
	mfsp->mfs_vnode = rootvp;
	mfsp->mfs_pid = p->p_pid;
	mfsp->mfs_buflist = (struct buf *)0;
	if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		free(mfsp, M_MFSNODE);
		return (error);
	}

	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr((time_t)0);

	return (0);
}
Esempio n. 11
0
int
ext2fs_mountroot(void)
{
	struct m_ext2fs *fs;
        struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	struct ufsmount *ump;
	int error;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
		panic("ext2fs_mountroot: can't setup bdevvp's");

	if ((error = vfs_rootmountalloc("ext2fs", "root_device", &mp)) != 0) {
		vrele(rootvp);
		return (error);
	}

	if ((error = ext2fs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		vrele(rootvp);
		return (error);
	}

	TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
	strlcpy(fs->e2fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->e2fs_fsmnt));
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
		strlcpy(fs->e2fs.e2fs_fsmnt, mp->mnt_stat.f_mntonname,
		    sizeof(fs->e2fs.e2fs_fsmnt));
	}
	(void)ext2fs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(fs->e2fs.e2fs_wtime);
	return (0);
}
Esempio n. 12
0
int
msdosfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct msdosfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_MSDOS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flags = MSDOSFSMNT_VERSIONED;
	args.uid = 0;
	args.gid = 0;
	args.mask = 0777;
	args.version = MSDOSFSMNT_VERSION;
	args.dirmask = 0777;

	if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	if ((error = update_mp(mp, &args)) != 0) {
		(void)msdosfs_unmount(mp, 0);
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		vrele(rootvp);
		return (error);
	}

	mountlist_append(mp);
	(void)msdosfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Esempio n. 13
0
int
ext2fs_mountroot(void)
{	
//	printf("ext2fs_mountroot\n");
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
	(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt,
	    sizeof(fs->e2fs_fsmnt) - 1, 0);
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
		(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
		    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
	}
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return (0);
}
Esempio n. 14
0
int
#define struct
ext2fs_mountroot(struct mount *mp)
{
	struct vnode *rootvp;
#undef struct
        struct m_ext2fs *fs;
//        struct mount *mp;
        int error;
        
        DEBUG ((EFI_D_INFO, "mountroot 1\n"));
        if (device_class(root_device) != DV_DISK)
    		return (ENONDEV);
        
        DEBUG ((EFI_D_INFO, "mountroot 2\n"));
        if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
    		vrele(rootvp);
                return (error);
        }
        
        DEBUG ((EFI_D_INFO, "mountroot 3\n"));
        if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
    		vfs_unbusy(mp,false,NULL);
    		vfs_destroy(mp);
                return (error);
        }

      DEBUG ((EFI_D_INFO, "mountroot 4\n"));
        fs = mp->fs;
        memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
        (void) copystr(mp->f_mntonname, fs->e2fs_fsmnt,
            sizeof(fs->e2fs_fsmnt) - 1, 0);
        if (fs->e2fs.e2fs_rev > E2FS_REV0) {
                memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
                (void) copystr(mp->f_mntonname, fs->e2fs.e2fs_fsmnt,
                    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
        }
        vfs_unbusy(mp, false, NULL);
        return (0);
Esempio n. 15
0
/*
 * Internal version of mount system call for diskless setup.
 * Separate function because we used to call it twice.
 * (once for root and once for swap)
 */
static int
nfs_mount_diskless(struct nfs_dlmount *ndmntp, const char *mntname, struct mount **mpp, struct vnode **vpp, struct lwp *l)
	/* mntname:	 mount point name */
{
	struct mount *mp;
	struct mbuf *m;
	int error;

	vfs_rootmountalloc(MOUNT_NFS, mntname, &mp);

	mp->mnt_op = &nfs_vfsops;

	/*
	 * Historical practice expects NFS root file systems to
	 * be initially mounted r/w.
	 */
	mp->mnt_flag &= ~MNT_RDONLY;

	/* Get mbuf for server sockaddr. */
	m = m_get(M_WAIT, MT_SONAME);
	if (m == NULL)
		panic("nfs_mountroot: mget soname for %s", mntname);
	MCLAIM(m, &nfs_mowner);
	memcpy(mtod(m, void *), (void *)ndmntp->ndm_args.addr,
	      (m->m_len = ndmntp->ndm_args.addr->sa_len));

	error = mountnfs(&ndmntp->ndm_args, mp, m, mntname,
			 ndmntp->ndm_args.hostname, vpp, l);
	if (error) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		printf("nfs_mountroot: mount %s failed: %d\n",
		       mntname, error);
	} else
		*mpp = mp;

	return (error);
}
Esempio n. 16
0
/*
 * Mount (mountfrom) as the root filesystem.
 */
static int
vfs_mountroot_try(const char *mountfrom)
{
	struct mount	*mp;
	char		*vfsname, *devname;
	int		error;
	char		patt[32];
	const char	*cp, *ep;
	char		*mf;

	vfsname = NULL;
	devname = NULL;
	mp      = NULL;
	error   = EINVAL;

	if (mountfrom == NULL)
		return(error);		/* don't complain */

	crit_enter();
	kprintf("Mounting root from %s\n", mountfrom);
	crit_exit();

	cp = mountfrom;
	/* parse vfs name and devname */
	vfsname = kmalloc(MFSNAMELEN, M_MOUNT, M_WAITOK);
	devname = kmalloc(MNAMELEN, M_MOUNT, M_WAITOK);
	mf = kmalloc(MFSNAMELEN+MNAMELEN, M_MOUNT, M_WAITOK);
	for(;;) {
		for (ep = cp; (*ep != 0) && (*ep != ';'); ep++);
		bzero(vfsname, MFSNAMELEN);
		bzero(devname, MNAMELEN);
		bzero(mf, MFSNAMELEN+MNAMELEN);
		strncpy(mf, cp, MFSNAMELEN+MNAMELEN);

		vfsname[0] = devname[0] = 0;
		ksprintf(patt, "%%%d[a-z0-9]:%%%ds", MFSNAMELEN, MNAMELEN);
		if (ksscanf(mf, patt, vfsname, devname) < 1)
			goto end;

		/* allocate a root mount */
		error = vfs_rootmountalloc(vfsname,
				devname[0] != 0 ? devname : ROOTNAME, &mp);
		if (error != 0) {
			kprintf("Can't allocate root mount for filesystem '%s': %d\n",
			       vfsname, error);
			goto end;
		}
		mp->mnt_flag |= MNT_ROOTFS;

		/* do our best to set rootdev */
		if ((strcmp(vfsname, "hammer") != 0) && (devname[0] != 0) &&
		    setrootbyname(devname))
			kprintf("setrootbyname failed\n");

		/* If the root device is a type "memory disk", mount RW */
		if (rootdev != NULL && dev_is_good(rootdev) &&
		    (dev_dflags(rootdev) & D_MEMDISK)) {
			mp->mnt_flag &= ~MNT_RDONLY;
		}

		error = VFS_MOUNT(mp, NULL, NULL, proc0.p_ucred);

		if (!error)
			break;
end:
		if(*ep == 0)
			break;
		cp = ep + 1;
	}

	if (vfsname != NULL)
		kfree(vfsname, M_MOUNT);
	if (devname != NULL)
		kfree(devname, M_MOUNT);
	if (mf != NULL)
		kfree(mf, M_MOUNT);
	if (error == 0) {
		/* register with list of mounted filesystems */
		mountlist_insert(mp, MNTINS_FIRST);

		/* sanity check system clock against root fs timestamp */
		inittodr(mp->mnt_time);
		vfs_unbusy(mp);
		if (mp->mnt_syncer == NULL) {
			error = vfs_allocate_syncvnode(mp);
			if (error)
				kprintf("Warning: no syncer vp for root!\n");
			error = 0;
		}
	} else {
		if (mp != NULL) {
			vfs_unbusy(mp);
			kfree(mp, M_MOUNT);
		}
		kprintf("Root mount failed: %d\n", error);
	}
	return(error);
}
Esempio n. 17
0
/*
 * vfs_mountrootfs
 *
 * Common entry point for root mounts
 *
 * PARAMETERS:
 * 		NONE
 *
 * RETURNS:	0	Success
 *		!0	error number (errno.h)
 *
 * LOCK STATE:
 *		ENTRY
 *			<no locks held>
 *		EXIT
 *			<no locks held>
 *
 * NOTES:
 *		This code is currently supported only for use for
 *		the FFS file system type.  This is a matter of
 *		fixing the other file systems, not this code!
 */
static void
vfs_mountrootfs(void *unused)
{
	struct mount		*mp;
	int			i, err;
	struct proc		*p = curproc;	/* XXX */
	dev_t			orootdev;

#ifdef BOOTP
	bootpc_init();
#endif
	/*
	 *  New root mount structure
	 */
	if ((err = vfs_rootmountalloc(mountrootfsname, ROOTNAME, &mp))) {
		printf("error %d: ", err);
		panic("cannot mount root\n");
		return ;
	}
	mp->mnt_flag		|= MNT_ROOTFS;

	/*
	 * Attempt the mount
	 */
	err = ENXIO;
	orootdev = rootdev;
	if (rootdevs[0] == NODEV)
		rootdevs[0] = rootdev;
	for (i = 0; i < sizeof(rootdevs) / sizeof(rootdevs[0]); i++) {
		if (rootdevs[i] == NODEV)
			break;
		rootdev = rootdevs[i];
		if (rootdev != orootdev) {
			printf("changing root device to %s\n", rootdevnames[i]);
			orootdev = rootdev;
		}
		strncpy(mp->mnt_stat.f_mntfromname,
		    rootdevnames[i] ? rootdevnames[i] : ROOTNAME, MNAMELEN - 1);
		err = VFS_MOUNT(mp, NULL, NULL, NULL, p);
		if (err != ENXIO)
			break;
	}
	if (err) {
		/*
		 * XXX should ask the user for the name in some cases.
		 * Why do we call vfs_unbusy() here and not after ENXIO
		 * is returned above?
		 */
		vfs_unbusy(mp, p);
		/*
		 * free mount struct before failing
		 * (hardly worthwhile with the PANIC eh?)
		 */
		free( mp, M_MOUNT);
		printf("error %d: ", err);
		panic("cannot mount root (2)\n");
		return;
	}

	simple_lock(&mountlist_slock);

	/*
	 * Add fs to list of mounted file systems
	 */
	CIRCLEQ_INSERT_HEAD(&mountlist, mp, mnt_list);

	simple_unlock(&mountlist_slock);
	vfs_unbusy(mp, p);

	/* root mount, update system time from FS specific data*/
	inittodr(mp->mnt_time);
	return;
}