[blivet:rhel7/master] Remove all dependent devices leaves first when hiding (#1078163)

mulhern amulhern at redhat.com
Thu Mar 20 13:55:56 UTC 2014


Resolves: rhbz#1078163

The major change is that the recursive structure of the function goes
away. In the new structure all actions are removed and then all dependent
devices are removed, including the device itself.

all) We use getDependentDevices to get the dependent devices, hopefully all
of them.
leaves first) We iteratively remove leaf devices from the list of
dependent devices until the list is empty.

We believe that at this stage, if actions have been canceled correctly,
that there is no device in the list of dependent devices that has
already been removed.

Signed-off-by: mulhern <amulhern at redhat.com>
---
 blivet/devicetree.py | 45 +++++++++++++++++++--------------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 8ec0852..674efec 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -1824,31 +1824,17 @@ class DeviceTree(object):
            If a device exists, performs some special actions and places
            it on a list of hidden devices.
 
-           Mixes recursion and side effects, most significantly in the code
-           that removes all the actions. However, this code is a null op
-           in every case except the first base case that is reached,
-           where all actions are removed. This means that when a device
-           is removed explicitly in this function by means of a direct call to
-           _removeDevices it is guaranteed that all actions have already
-           been canceled.
-
-           The recursion guarantees that when a device is removed by an explicit
-           _removeDevice call it is a leaf device.
-
-           It also guarantees that hidden devices are added to self._hidden
+           The method guarantees that hidden devices are added to self._hidden
            in a topologically sorted order (assuming edges are child
            relationships), leaves first.
 
            If a device does not exist then it must have been removed by the
-           cancelation of all the actions, so it does not need to be removed
-           explicitly.
+           cancelation of all the actions. All devices that are explicitly
+           removed in this method are, consequently, existent devices.
         """
         if device in self._hidden:
             return
 
-        for d in self.getChildren(device):
-            self.hide(d)
-
         log.info("hiding device %s %s (id %d)" % (device.type,
                                                   device.name,
                                                   device.id))
@@ -1856,19 +1842,26 @@ class DeviceTree(object):
         for action in reversed(self._actions):
             self.cancelAction(action)
 
-        if not device.exists:
-            return
+        dependents = self.getDependentDevices(device)
+        dependents.reverse()
+        dependents.append(device)
+
+        while dependents:
+            leaves = [ dev for dev in dependents if dev.isleaf ]
+            for leaf in leaves:
+
+                self._removeDevice(leaf, moddisk=False)
 
-        self._removeDevice(device, moddisk=False)
+                self._hidden.append(leaf)
+                lvm.lvm_cc_addFilterRejectRegexp(leaf.name)
 
-        self._hidden.append(device)
-        lvm.lvm_cc_addFilterRejectRegexp(device.name)
+                if isinstance(leaf, DASDDevice):
+                    self.dasd.remove(leaf)
 
-        if isinstance(device, DASDDevice):
-            self.dasd.remove(device)
+                if leaf.name not in self.names:
+                    self.names.append(leaf.name)
 
-        if device.name not in self.names:
-            self.names.append(device.name)
+                dependents.remove(leaf)
 
     def unhide(self, device):
         # the hidden list should be in leaves-first order
-- 
1.8.3.1



More information about the anaconda-patches mailing list