curtin-dev team mailing list archive
-
curtin-dev team
-
Mailing list archive
-
Message #01642
[Merge] ~mwhudson/curtin:lp-1928839 into curtin:master
Michael Hudson-Doyle has proposed merging ~mwhudson/curtin:lp-1928839 into curtin:master.
Commit message:
fix tearing down ChrootableTarget when mounts appear while it is set up
There are several bug reports that boil down to
ChrootableTarget.__exit__ failing to unmount bind mounts with "target is
busy". For example, ssh-ing in while running tends to do this, because
that creates a mount in /run and then umounting /target/run fails
because of the sub mount. Fix this by marking the mountpoints
recursively private and then unmounting them recursively.
LP: #1928839
LP: #1934775
Requested reviews:
Server Team CI bot (server-team-bot): continuous-integration
curtin developers (curtin-dev)
Related bugs:
Bug #1928839 in curtin: "MaaS/Curtin fail to unmount /target/run way too often"
https://bugs.launchpad.net/curtin/+bug/1928839
Bug #1934775 in curtin: "Installer crash when trying to unmount target"
https://bugs.launchpad.net/curtin/+bug/1934775
For more details, see:
https://code.launchpad.net/~mwhudson/curtin/+git/curtin/+merge/405670
Hopefully this fixes a problem that's always niggled at me.
--
Your team curtin developers is requested to review the proposed merge of ~mwhudson/curtin:lp-1928839 into curtin:master.
diff --git a/curtin/util.py b/curtin/util.py
index be063d7..7be3033 100644
--- a/curtin/util.py
+++ b/curtin/util.py
@@ -695,7 +695,22 @@ class ChrootableTarget(object):
log_call(subp, ['udevadm', 'settle'])
for p in reversed(self.umounts):
- do_umount(p)
+ # Consider the following sequence:
+ #
+ # mkdir a a/b c
+ # mount --bind a c
+ # mount -t sysfs sysfs a/b
+ # umount c
+ #
+ # This umount fails with "mountpoint is busy", because of
+ # the mountpoint at c/b. But if we unmount c recursively,
+ # a/b ends up getting unmounted. What we need to do is to
+ # make the mountpoints c and c/b "private" so that
+ # unmounting them does not propagate to the mount tree c
+ # was cloned from (See "Shared subtree operations" in
+ # mount(8) for more on this).
+ subp(['mount', '--make-rprivate', p])
+ do_umount(p, recursive=True)
rconf = paths.target_path(self.target, "/etc/resolv.conf")
if self.sys_resolvconf and self.rconf_d: