From 7c3df66659b6dcc804977845c031571cb5f7fcd5 Mon Sep 17 00:00:00 2001 From: David Lehman Date: Wed, 3 Dec 2014 17:48:43 -0600 Subject: [PATCH] Preserve names of existing partitions when hiding disks. (#1166598) They will be named based on the order in which they are added to the disk, so we must take care to add them in an order that preserves their original numbers/names. --- blivet/devicetree.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 1a7b144..6597b7f 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -1951,16 +1951,50 @@ class DeviceTree(object): if device.isDisk: # Cancel all actions on this disk and any disk related by way of an # aggregate/container device (eg: lvm volume group). + self.pruneActions() disks = [device] related_actions = [a for a in self._actions if a.device.dependsOn(device)] for related_device in (a.device for a in related_actions): disks.extend(related_device.disks) + # Cancellation of partition destroy actions must be handled + # specially. See comments further down to learn why. + partition_destroys = [a for a in related_actions + if a.isDestroy and a.isDevice and + isinstance(a.device, PartitionDevice)] + partition_destroys.sort(key=lambda a: a.device.partedPartition.number) + disks = set(disks) cancel = [a for a in self._actions if set(a.device.disks).intersection(disks)] + + # In general, we cancel actions in the reverse order we scheduled + # them. For the same reason you need to remove devices leaves-first, + # you have to add them leaves-last. Actions have effects on the + # devicetree when they are registered, and those effects are + # reversed when the actions are cancelled. for action in reversed(cancel): + if action in partition_destroys: + # Of course there is an exception to the above. Partitions + # get named based on the order in which they were added to + # the disk, so we have to make sure we add them back to the + # disk in an order that preserves their original names. + # + # Other device types don't have this problem since their + # names don't change except upon request. + for related in partition_destroys: + self.cancelAction(related) + + partition_destroys = [] + + # We just constructed the list of actions to cancel by selecting + # a subset of self._actions, so we can rest assured that any + # action not in self._actions is a partition destroy action that + # we cancelled in the block just above this comment. + if action not in self._actions: + continue + self.cancelAction(action) for d in self.getChildren(device): -- 1.9.3