diff options
author | David Lehman <dlehman@redhat.com> | 2009-03-03 00:14:32 -0600 |
---|---|---|
committer | David Lehman <dlehman@redhat.com> | 2009-03-03 00:14:32 -0600 |
commit | 96fecb7804f26db1e113f7fa9a1d4bacbb85fcc1 (patch) | |
tree | 8df7f428552ea14ee2149570aba6755ab91c948e /storage/devicetree.py | |
parent | 1fd89ae9fc8e2ca44430702f7d988112a8a8c080 (diff) | |
download | anaconda-96fecb7804f26db1e113f7fa9a1d4bacbb85fcc1.tar.gz anaconda-96fecb7804f26db1e113f7fa9a1d4bacbb85fcc1.tar.xz anaconda-96fecb7804f26db1e113f7fa9a1d4bacbb85fcc1.zip |
Add method pruneActions to remove redundant actions from the queue.
At some point this can probably be triggered from registerAction,
but for now this is simplest. The basic problem is that, when
registering an action, you have to leave the device's previous
action intact so the new action can be cancelled in the event of
a failure like partition allocation. This leads to the possibility
that lots of dialog clicking will lead to a very long sequence of
actions that can/should be distilled to a minimal sequence.
There could be problems lurking here with regard to device
identity/equality.
Diffstat (limited to 'storage/devicetree.py')
-rw-r--r-- | storage/devicetree.py | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/storage/devicetree.py b/storage/devicetree.py index cdd41f070..b6fee30b1 100644 --- a/storage/devicetree.py +++ b/storage/devicetree.py @@ -152,6 +152,162 @@ class DeviceTree(object): self._populate() + def pruneActions(self): + """ Prune loops and redundant actions from the queue. """ + # handle device destroy actions + actions = self.findActions(type="destroy", object="device") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + # XXX this may finally necessitate object ids + loops = self.findActions(device=a.device, + type="destroy", + object="device") + + if len(loops) == 1: + continue + + # remove all actions on this device from after the first + # destroy up through the last destroy + dev_actions = self.findActions(device=a.device) + for rem in dev_actions: + start = self._actions.index(a) + end = self._actions.index(loops[-1]) + if start < self._actions.index(rem) <= end: + self._actions.remove(rem) + + # device create actions + actions = self.findActions(type="create", object="device") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="create", + object="device") + + if len(loops) == 1: + continue + + # remove all all actions on this device up to the last create + dev_actions = self.findActions(device=a.device) + for rem in dev_actions: + end = self._actions.index(loops[-1]) + if start < self._actions.index(rem) < end: + self._actions.remove(rem) + + # device resize actions + actions = self.findActions(type="resize", object="device") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="resize", + object="device") + + if len(loops) == 1: + continue + + # remove all but the last resize action on this device + for rem in loops[:-1]: + self._actions.remove(rem) + + # format destroy + # XXX I don't think there's a way for these loops to happen + actions = self.findActions(type="destroy", object="format") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="destroy", + object="format") + + if len(loops) == 1: + continue + + # remove all actions on this device's format from after the + # first destroy up through the last destroy + dev_actions = self.findActions(device=a.device, object="format") + for rem in dev_actions: + start = self._actions.index(a) + end = self._actions.index(loops[-1]) + if start < self._actions.index(rem) <= end: + self._actions.remove(rem) + + # format create + # XXX I don't think there's a way for these loops to happen + actions = self.findActions(type="create", object="format") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="create", + object="format") + + if len(loops) == 1: + continue + + # remove all all actions on this device's format up to the last + # create + dev_actions = self.findActions(device=a.device, object="format") + for rem in dev_actions: + end = self._actions.index(loops[-1]) + if start < self._actions.index(rem) < end: + self._actions.remove(rem) + + # format resize + actions = self.findActions(type="resize", object="format") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="resize", + object="format") + + if len(loops) == 1: + continue + + # remove all but the last resize action on this format + for rem in loops[:-1]: + self._actions.remove(rem) + + # format migrate + # XXX I don't think there's away for these loops to occur + actions = self.findActions(type="migrate", object="format") + for a in actions: + if a not in self._actions: + # we may have removed some of the actions in a previous + # iteration of this loop + continue + + loops = self.findActions(device=a.device, + type="migrate", + object="format") + + if len(loops) == 1: + continue + + # remove all but the last migrate action on this format + for rem in loops[:-1]: + self._actions.remove(rem) + def processActions(self, dryRun=None): """ Execute all registered actions. """ def cmpActions(x, y): @@ -255,6 +411,12 @@ class DeviceTree(object): # in most cases the actions will already be sorted because of the # rules for registration, but let's not rely on that + for action in self._actions: + log.debug("action: %s" % action) + log.debug("pruning action queue...") + self.pruneActions() + for action in self._actions: + log.debug("action: %s" % action) self._actions.sort(cmpActions) for action in self._actions: log.info("executing action: %s" % action) |