From b2587dc177f176da35e6a44e35b605cee907c643 Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Mon, 11 Aug 2014 15:33:20 -0500
Subject: [PATCH 15/26] Lock related devices during action execute and cancel.

---
 blivet/deviceaction.py | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
index 3dc6b99..f87e2ae 100644
--- a/blivet/deviceaction.py
+++ b/blivet/deviceaction.py
@@ -33,7 +33,7 @@ from parted import partitionFlag, PARTITION_LBA
 from .i18n import _, N_
 from .callbacks import CreateFormatPreData, CreateFormatPostData
 from .callbacks import ResizeFormatPreData, ResizeFormatPostData
-from .threads import LockedObjectID, SynchronizedMeta
+from .threads import LockedObjectID, SynchronizedMeta, lock_list_attr, lock_attr
 
 import logging
 log = logging.getLogger("blivet")
@@ -157,6 +157,7 @@ class DeviceAction(LockedObjectID):
         """ apply changes related to the action to the device(s) """
         self._applied = True
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         """
         Perform the action.
@@ -269,6 +270,8 @@ class DeviceAction(LockedObjectID):
         return util.unicodeize(self._toString())
 
     @property
+    @lock_attr('format')
+    @lock_attr('device')
     def related(self):
         """ A list of objects to lock before executing this action. """
         objs = []
@@ -313,6 +316,7 @@ class ActionCreateDevice(DeviceAction):
         # FIXME: assert device.fs is None
         DeviceAction.__init__(self, device)
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionCreateDevice, self).execute(callbacks=None)
         self.device.create()
@@ -356,6 +360,7 @@ class ActionDestroyDevice(DeviceAction):
         # XXX should we insist that device.fs be None?
         DeviceAction.__init__(self, device)
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionDestroyDevice, self).execute(callbacks=None)
         self.device.destroy()
@@ -467,10 +472,12 @@ class ActionResizeDevice(DeviceAction):
         self.device.targetSize = self._targetSize
         super(ActionResizeDevice, self).apply()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionResizeDevice, self).execute(callbacks=None)
         self.device.resize()
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -548,6 +555,7 @@ class ActionCreateFormat(DeviceAction):
         self.device.format = self._format
         super(ActionCreateFormat, self).apply()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionCreateFormat, self).execute(callbacks=None)
         if callbacks and callbacks.create_format_pre:
@@ -600,6 +608,7 @@ class ActionCreateFormat(DeviceAction):
             msg = _("Created %(type)s on %(device)s") % {"type": self.device.format.type, "device": self.device.path}
             callbacks.create_format_post(CreateFormatPostData(msg))
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -659,6 +668,7 @@ class ActionDestroyFormat(DeviceAction):
         self.device.format = None
         super(ActionDestroyFormat, self).apply()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         """ wipe the filesystem signature from the device """
         super(ActionDestroyFormat, self).execute(callbacks=None)
@@ -669,6 +679,7 @@ class ActionDestroyFormat(DeviceAction):
         if not status:
             self.device.teardown()
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -763,6 +774,7 @@ class ActionResizeFormat(DeviceAction):
         self.device.format.targetSize = self._targetSize
         super(ActionResizeFormat, self).apply()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionResizeFormat, self).execute(callbacks=None)
         if callbacks and callbacks.resize_format_pre:
@@ -776,6 +788,7 @@ class ActionResizeFormat(DeviceAction):
             msg = _("Resized filesystem on %(device)s") % {"device": self.device.path}
             callbacks.resize_format_post(ResizeFormatPostData(msg))
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -829,6 +842,7 @@ class ActionAddMember(DeviceAction):
         self.container.parents.append(self.device)
         super(ActionAddMember, self).apply()
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -836,6 +850,7 @@ class ActionAddMember(DeviceAction):
         self.container.parents.remove(self.device)
         super(ActionAddMember, self).cancel()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionAddMember, self).execute(callbacks=None)
         self.container.add(self.device)
@@ -900,6 +915,7 @@ class ActionRemoveMember(DeviceAction):
         self.container.parents.remove(self.device)
         super(ActionRemoveMember, self).apply()
 
+    @lock_list_attr('related')
     def cancel(self):
         if not self._applied:
             return
@@ -907,11 +923,14 @@ class ActionRemoveMember(DeviceAction):
         self.container.parents.append(self.device)
         super(ActionRemoveMember, self).cancel()
 
+    @lock_list_attr('related')
     def execute(self, callbacks=None):
         super(ActionRemoveMember, self).execute(callbacks=None)
         self.container.remove(self.device)
 
     @property
+    @lock_attr('format')
+    @lock_attr('device')
     def related(self):
         objs = self.container.parents[:]
         objs.extend(p.format for p in self.container.parents)
-- 
1.9.3

