summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_mountroot.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2016-01-12 10:11:29 +0000
committertrasz <trasz@FreeBSD.org>2016-01-12 10:11:29 +0000
commit355c35a189c2f841c4660bf6e63e376f77a2c04b (patch)
tree80e73a1e8e4e3f10ec17f3c3b146a796efee3373 /sys/kern/vfs_mountroot.c
parenta35cfac66cd13b8a8193084a71a760710f87703e (diff)
downloadFreeBSD-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.c47
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);
OpenPOWER on IntegriCloud