From 0d47799beaad6fb390c4761fef8d84d665f9b189 Mon Sep 17 00:00:00 2001
From: Mudassir Latif <mudassir.latif@purestorage.com>
Date: Mon, 24 Nov 2014 19:00:47 -0800
Subject: [PATCH] PureISCSIDriver:Handle delete called on already deleted
 volume

If the delete_volume method gets an error from Purity
saying volume does not exist, don't proceed with attempt
at deletion

Change-Id: I2a830e43c876433da4cdb50eabe4fb66b7eb6faf
Closes-Bug: #1395826
---
 cinder/tests/test_pure.py     | 18 ++++++++++++++++++
 cinder/volume/drivers/pure.py | 17 ++++++++---------
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/cinder/tests/test_pure.py b/cinder/tests/test_pure.py
index f2081d9d6..7e650c02e 100644
--- a/cinder/tests/test_pure.py
+++ b/cinder/tests/test_pure.py
@@ -199,6 +199,24 @@ class PureISCSIDriverTestCase(test.TestCase):
             self.driver.create_cloned_volume, VOLUME, SRC_VOL)
         SRC_VOL["size"] = 2  # reset size
 
+    def test_delete_volume_already_deleted(self):
+        self.array.list_volume_hosts.side_effect = exception.PureAPIException(
+            code=400, reason="Volume does not exist")
+        self.driver.delete_volume(VOLUME)
+        self.assertFalse(self.array.destroy_volume.called)
+        self.array.list_volume_hosts.side_effect = None
+        self.assert_error_propagates([self.array.destroy_volume],
+                                     self.driver.delete_volume, VOLUME)
+        # Testing case where array.destroy_volume returns an exception
+        #  because volume already deleted
+        self.array.destroy_volume.side_effect = exception.PureAPIException(
+            code=400, reason="Volume does not exist")
+        self.driver.delete_volume(VOLUME)
+        self.assertTrue(self.array.destroy_volume.called)
+        self.array.destroy_volume.side_effect = None
+        self.assert_error_propagates([self.array.destroy_volume],
+                                     self.driver.delete_volume, VOLUME)
+
     def test_delete_volume(self):
         vol_name = VOLUME["name"] + "-cinder"
         self.driver.delete_volume(VOLUME)
diff --git a/cinder/volume/drivers/pure.py b/cinder/volume/drivers/pure.py
index 46d6f3678..2a2d7944c 100644
--- a/cinder/volume/drivers/pure.py
+++ b/cinder/volume/drivers/pure.py
@@ -133,21 +133,20 @@ class PureISCSIDriver(san.SanISCSIDriver):
         """Disconnect all hosts and delete the volume"""
         LOG.debug("Enter PureISCSIDriver.delete_volume.")
         vol_name = _get_vol_name(volume)
-
-        connected_hosts = self._array.list_volume_hosts(vol_name)
-        for host_info in connected_hosts:
-            host_name = host_info["host"]
-            self._disconnect_host(host_name, vol_name)
-
         try:
+            connected_hosts = self._array.list_volume_hosts(vol_name)
+            for host_info in connected_hosts:
+                host_name = host_info["host"]
+                self._disconnect_host(host_name, vol_name)
             self._array.destroy_volume(vol_name)
         except exception.PureAPIException as err:
             with excutils.save_and_reraise_exception() as ctxt:
-                if err.kwargs["code"] == 400:
+                if err.kwargs["code"] == 400 and \
+                        "Volume does not exist" in err.msg:
                     # Happens if the volume does not exist.
                     ctxt.reraise = False
-                    LOG.error(_LE("Volume deletion failed with message: %s") %
-                              err.msg)
+                    LOG.warn(_LW("Volume deletion failed with message: %s")
+                             % err.msg)
         LOG.debug("Leave PureISCSIDriver.delete_volume.")
 
     def create_snapshot(self, snapshot):
-- 
2.45.2