From b8325505c0007d742bc1639d766235951adad187 Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Wed, 21 May 2014 13:39:57 -0500
Subject: [PATCH 14/18] Some devices have immutable formatting.

It is not a good idea to try to reformat a snapshot or a btrfs subvolume.
---
 blivet/__init__.py     |  5 +++--
 blivet/deviceaction.py |  9 +++++++++
 blivet/devices.py      | 13 +++++++++++++
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/blivet/__init__.py b/blivet/__init__.py
index b77ff8b..98a03ce 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -1279,7 +1279,7 @@ class Blivet(object):
             :rtype: None
         """
         self.devicetree.registerAction(ActionCreateDevice(device))
-        if device.format.type:
+        if device.format.type and not device.formatImmutable:
             self.devicetree.registerAction(ActionCreateFormat(device))
 
     def destroyDevice(self, device):
@@ -1289,7 +1289,8 @@ class Blivet(object):
             :type device: :class:`~.devices.StorageDevice`
             :rtype: None
         """
-        if device.format.exists and device.format.type:
+        if device.format.exists and device.format.type and \
+           not device.formatImmutable:
             # schedule destruction of any formatting while we're at it
             self.devicetree.registerAction(ActionDestroyFormat(device))
 
diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
index e3a6754..9ffcc5a 100644
--- a/blivet/deviceaction.py
+++ b/blivet/deviceaction.py
@@ -507,6 +507,9 @@ class ActionCreateFormat(DeviceAction):
             If no format is specified, it is assumed that the format is already
             associated with the device.
         """
+        if device.formatImmutable:
+            raise ValueError("this device's formatting cannot be modified")
+
         DeviceAction.__init__(self, device)
         if fmt:
             self.origFormat = device.format
@@ -610,6 +613,9 @@ class ActionDestroyFormat(DeviceAction):
     typeDescStr = N_("destroy format")
 
     def __init__(self, device):
+        if device.formatImmutable:
+            raise ValueError("this device's formatting cannot be modified")
+
         DeviceAction.__init__(self, device)
         self.origFormat = self.device.format
 
@@ -687,6 +693,9 @@ class ActionResizeFormat(DeviceAction):
     typeDescStr = N_("resize format")
 
     def __init__(self, device, newsize):
+        if device.formatImmutable:
+            raise ValueError("this device's formatting cannot be modified")
+
         if not device.format.resizable:
             raise ValueError("format is not resizable")
 
diff --git a/blivet/devices.py b/blivet/devices.py
index 4ce6969..efe59b8 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -507,6 +507,7 @@ class StorageDevice(Device):
     _type = "blivet"
     _devDir = "/dev"
     sysfsBlockDir = "class/block"
+    _formatImmutable = False
     _partitionable = False
     _isDisk = False
 
@@ -1051,6 +1052,11 @@ class StorageDevice(Device):
                 open(remfile).readline().strip() == "1")
 
     @property
+    def formatImmutable(self):
+        """ Is it possible to execute format actions on this device? """
+        return self._formatImmutable or self.protected
+
+    @property
     def isDisk(self):
         return self._isDisk
 
@@ -3161,6 +3167,7 @@ class LVMSnapShotBase(object):
 class LVMSnapShotDevice(LVMSnapShotBase, LVMLogicalVolumeDevice):
     """ An LVM snapshot """
     _type = "lvmsnapshot"
+    _formatImmutable = True
 
     def __init__(self, name, parents=None, size=None, uuid=None,
                  copies=1, logSize=0, segType=None,
@@ -3407,6 +3414,7 @@ class LVMThinSnapShotDevice(LVMSnapShotBase, LVMThinLogicalVolumeDevice):
     """ An LVM Thin Snapshot """
     _type = "lvmthinsnapshot"
     _resizable = False
+    _formatImmutable = True
 
     def __init__(self, name, parents=None, sysfsPath='', origin=None,
                  fmt=None, uuid=None, size=None, exists=False, segType=None):
@@ -4960,6 +4968,10 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
 
         self._defaultSubVolumeID = None
 
+    @property
+    def formatImmutable(self):
+        return self.exists
+
     def _setFormat(self, fmt):
         """ Set the Device's format. """
         super(BTRFSVolumeDevice, self)._setFormat(fmt)
@@ -5126,6 +5138,7 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
 class BTRFSSubVolumeDevice(BTRFSDevice):
     """ A btrfs subvolume pseudo-device. """
     _type = "btrfs subvolume"
+    _formatImmutable = True
 
     def __init__(self, *args, **kwargs):
         """
-- 
1.9.0

