diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2021-04-30 15:20:50 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2021-04-30 17:56:41 -0700 |
commit | 9f0ba8d603de49e52f7ed75cecb092ad0d0d0771 (patch) | |
tree | b25b7e54c1c5479c94d4a177f226b932edb4ba73 /src/property/mount.lisp | |
parent | 691c81810e647ef7d780f4f3546ee8856f777b07 (diff) | |
download | consfigurator-9f0ba8d603de49e52f7ed75cecb092ad0d0d0771.tar.gz |
MOUNT:UNMOUNTED-BELOW: stop calling 'mount --make-rslave'
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
Diffstat (limited to 'src/property/mount.lisp')
-rw-r--r-- | src/property/mount.lisp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/property/mount.lisp b/src/property/mount.lisp index fe805ad..72eb8d7 100644 --- a/src/property/mount.lisp +++ b/src/property/mount.lisp @@ -19,14 +19,42 @@ (named-readtables:in-readtable :consfigurator) (defprop unmounted-below :posix (dir) - "Unmount anything mounted at or below DIR." + "Unmount anything mounted at or below DIR. + +Not aware of shared subtrees, so you might need to use the --make-rslave +option to mount(1) first. For example, if you did 'mount --rbind /dev +chroot/dev' then unless you also execute 'mount --make-rslave chroot/dev', +this property will empty /dev, breaking all kinds of things." (:desc #?"${dir} unmounted") (:hostattrs - (declare (ignore dir)) - ;; findmnt(1) & arguments to mount(1)/umount(1) we use are from util-linux + ;; findmnt(1) & --recursive argument to umount(1) are from util-linux (os:required 'os:linux)) (:apply (with-change-if-changes-file-content ("/proc/mounts") + ;; We used to call --make-rslave as we worked through, but for mounts + ;; which were *not* made using the --rbind option to mount(1) or similar, + ;; doing that can can get us into a state where we can unmount everything + ;; we can see under DIR but the kernel will still consider the block + ;; device to be in use. That's a bit much for this property to deal + ;; with, so we require that the caller call --make-rslave as appropriate. + ;; + ;; In addition to that problem, we would also require multiple unmount + ;; passes; for example if we + ;; + ;; % mount --bind chroot chroot + ;; % mount proc chroot/proc -t proc + ;; % mount --make-rslave chroot + ;; + ;; then we would need + ;; + ;; % umount chroot/proc + ;; % umount chroot + ;; % umount chroot/proc + ;; + ;; because the --make-rslave leaves us with two independent mounts of + ;; /proc, and the second can't be removed until the bind mount is + ;; removed. (This situation arises because :CHROOT.FORK connections bind + ;; mount the chroot on itself if it is not already a mount point.) (let* ((dir (ensure-directory-pathname dir)) (all-mounts (mapcar #'ensure-directory-pathname @@ -36,10 +64,6 @@ (loop as next = (pop sorted) while next do (loop while (subpathp (car sorted) next) do (pop sorted)) - ;; If any of the mounts were made with --rbind then unmounting - ;; will unmount the source filesystems too (e.g. things - ;; mounted under /dev), so use --make-rslave to prevent that. - (mrun "mount" "--make-rslave" next) (mrun "umount" "--recursive" next)))))) (defproplist unmounted-below-and-removed :posix (dir) |