diff options
author | trasz <trasz@FreeBSD.org> | 2016-01-12 10:11:29 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2016-01-12 10:11:29 +0000 |
commit | 355c35a189c2f841c4660bf6e63e376f77a2c04b (patch) | |
tree | 80e73a1e8e4e3f10ec17f3c3b146a796efee3373 /sys/kern/vfs_mountroot.c | |
parent | a35cfac66cd13b8a8193084a71a760710f87703e (diff) | |
download | FreeBSD-src-355c35a189c2f841c4660bf6e63e376f77a2c04b.zip FreeBSD-src-355c35a189c2f841c4660bf6e63e376f77a2c04b.tar.gz |
MFC r287964:
Kernel part of reroot support - a way to change rootfs without reboot.
Note that the mountlist manipulations are somewhat fragile, and not very
pretty. The reason for this is to avoid changing vfs_mountroot(), which
is (obviously) rather mission-critical, but not very well documented,
and thus hard to test properly. It might be possible to rework it to use
its own simple root mount mechanism instead of vfs_mountroot().
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D2698
Diffstat (limited to 'sys/kern/vfs_mountroot.c')
-rw-r--r-- | sys/kern/vfs_mountroot.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 5c49ff7..184976a 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -220,28 +220,39 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp) *mpp = NULL; - vfsp = vfs_byname("devfs"); - KASSERT(vfsp != NULL, ("Could not find devfs by name")); - if (vfsp == NULL) - return (ENOENT); - - mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); + if (rootdevmp != NULL) { + /* + * Already have /dev; this happens during rerooting. + */ + error = vfs_busy(rootdevmp, 0); + if (error != 0) + return (error); + *mpp = rootdevmp; + } else { + vfsp = vfs_byname("devfs"); + KASSERT(vfsp != NULL, ("Could not find devfs by name")); + if (vfsp == NULL) + return (ENOENT); + + mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); + + error = VFS_MOUNT(mp); + KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); + if (error) + return (error); - error = VFS_MOUNT(mp); - KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); - if (error) - return (error); + opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); + TAILQ_INIT(opts); + mp->mnt_opt = opts; - opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); - TAILQ_INIT(opts); - mp->mnt_opt = opts; + mtx_lock(&mountlist_mtx); + TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); + mtx_unlock(&mountlist_mtx); - mtx_lock(&mountlist_mtx); - TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); - mtx_unlock(&mountlist_mtx); + *mpp = mp; + rootdevmp = mp; + } - *mpp = mp; - rootdevmp = mp; set_rootvnode(); error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); |