Changeset View
Standalone View
sys/kern/vfs_mountroot.c
Show First 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct vfsoptlist *opts; | struct vfsoptlist *opts; | ||||
struct vfsconf *vfsp; | struct vfsconf *vfsp; | ||||
struct mount *mp; | struct mount *mp; | ||||
int error; | int error; | ||||
*mpp = NULL; | *mpp = NULL; | ||||
if (rootdevmp != NULL) { | |||||
/* | |||||
* Already have /dev; this happens during rerooting. | |||||
*/ | |||||
vfs_busy(rootdevmp, 0); | |||||
kib: Where is the paired unbusy() done ? In vfs_mountroot_shuffle() ?
I have troubles convincing… | |||||
Not Done Inline ActionsWell, because we remove tmpfs from the mountlist, the situation after this point is the same for both the usual boot and reroot: there is one filesystem, and it's devfs. The rest of the mountroot code should thus behave in exactly the same way in both cases (that's the whole point of messing with the mountlist). trasz: Well, because we remove tmpfs from the mountlist, the situation after this point is the same… | |||||
Not Done Inline ActionsI probably can now verbalize my unhappiness with the list manipulations. Consider the difference between real root mount and reroot operations. Real root is mounted while system did not even started init binary; there is no usermode acting in parallel. On the other hand, your code executes the same code, which relies on specific state of the mount list, and on the stability of the list state, while usermode is running. Nothing prevents a malicious code from mounting something in parallel, breaking your algorithm. I mark the patch as reviewed, since I do not see any more 'small' bugs. Move it forward if you want, but note my vigilance with the robustness of the approach. kib: I probably can now verbalize my unhappiness with the list manipulations. Consider the… | |||||
Not Done Inline ActionsIn addition to the previous comment, shouldn't the error from vfs_busy() checked ? Otherwise, at least, vfs_unbusy() would negate the counter. kib: In addition to the previous comment, shouldn't the error from vfs_busy() checked ? Otherwise… | |||||
*mpp = rootdevmp; | |||||
} else { | |||||
vfsp = vfs_byname("devfs"); | vfsp = vfs_byname("devfs"); | ||||
KASSERT(vfsp != NULL, ("Could not find devfs by name")); | KASSERT(vfsp != NULL, ("Could not find devfs by name")); | ||||
if (vfsp == NULL) | if (vfsp == NULL) | ||||
return (ENOENT); | return (ENOENT); | ||||
mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); | mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); | ||||
error = VFS_MOUNT(mp); | error = VFS_MOUNT(mp); | ||||
KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); | KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); | opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); | ||||
TAILQ_INIT(opts); | TAILQ_INIT(opts); | ||||
mp->mnt_opt = opts; | mp->mnt_opt = opts; | ||||
mtx_lock(&mountlist_mtx); | mtx_lock(&mountlist_mtx); | ||||
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); | TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); | ||||
mtx_unlock(&mountlist_mtx); | mtx_unlock(&mountlist_mtx); | ||||
*mpp = mp; | *mpp = mp; | ||||
rootdevmp = mp; | rootdevmp = mp; | ||||
} | |||||
set_rootvnode(); | set_rootvnode(); | ||||
error = kern_symlinkat(td, "/", AT_FDCWD, "dev", UIO_SYSSPACE); | error = kern_symlinkat(td, "/", AT_FDCWD, "dev", UIO_SYSSPACE); | ||||
if (error) | if (error) | ||||
printf("kern_symlink /dev -> / returns %d\n", error); | printf("kern_symlink /dev -> / returns %d\n", error); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 798 Lines • Show Last 20 Lines |
Where is the paired unbusy() done ? In vfs_mountroot_shuffle() ?
I have troubles convincing myself that it does happen, at least that it does happen always.