From 94f331dbc839444a533f95f183fcf1ae0899e150 Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Aug 24 2020 15:23:09 +0000 Subject: appcreate: Ensure Btrfs volumes and subvolumes are torn down last This should ensure that the appliance image finalization does not get stuck with out-of-order sequence of unmounting to clean up the disk creation working area. --- diff --git a/appcreate/partitionedfs.py b/appcreate/partitionedfs.py index 5f343e5..50206c4 100644 --- a/appcreate/partitionedfs.py +++ b/appcreate/partitionedfs.py @@ -225,12 +225,14 @@ class PartitionedMount(Mount): def __calculate_mountorder(self): btrfs_mountOrder = [] + btrfs_unmountOrder = [] for p in self.partitions: if p['fstype'] == 'btrfs': btrfs_mountOrder.append(p['mountpoint']) + btrfs_unmountOrder.append(p['mountpoint']) else: self.mountOrder.append(p['mountpoint']) - self.unmountOrder.append(p['mountpoint']) + self.unmountOrder.append(p['mountpoint']) self.mountOrder.sort() btrfs_mountOrder.sort() @@ -238,7 +240,12 @@ class PartitionedMount(Mount): self.mountOrder = btrfs_mountOrder + self.mountOrder self.unmountOrder.sort() self.unmountOrder.reverse() - logging.info(str(self.mountOrder)) + btrfs_unmountOrder.sort() + btrfs_unmountOrder.reverse() + # Btrfs mountpoints must be last in the list + self.unmountOrder = self.unmountOrder + btrfs_unmountOrder + logging.debug("Mount order: %s" % str(self.mountOrder)) + logging.debug("Unmount order: %s" % str(self.unmountOrder)) def cleanup(self): Mount.cleanup(self) @@ -251,20 +258,6 @@ class PartitionedMount(Mount): pass def unmount(self): - if self.subvolumes: - ordered = [] - others = [] - for s in self.subvolumes: - if s['mountpoint'] == '/': - others.append(s) - else: - ordered.append(s) - - ordered += others - - for s in ordered: - subprocess.call(['umount', "%s%s" % (self.mountdir, s['mountpoint'])]) - for mp in self.unmountOrder: if mp == 'swap': continue @@ -281,6 +274,27 @@ class PartitionedMount(Mount): pass p['mount'] = None + if self.subvolumes: + ordered = [] + others = [] + for s in self.subvolumes: + if s['mountpoint'] == '/': + others.append(s) + else: + ordered.append(s) + + ordered = ordered + others + + for s in ordered: + logging.info("Unmounting directory %s%s" % (self.mountdir, s['mountpoint'])) + rc = subprocess.call(['umount', "%s%s" % (self.mountdir, s['mountpoint'])]) + if rc != 0: + logging.warning("Unmounting directory %s%s failed, using lazy " + "umount" % (self.mountdir, s['mountpoint'])) + print("Unmounting directory %s%s failed, using lazy umount" % + (self.mountdir, s['mountpoint']), file=sys.stdout) + subprocess.call(['umount', '-l', "%s%s" % (self.mountdir, s['mountpoint'])]) + def setup_subvolumes(self): others = [] ordered = []