From b54e7ff3576e495c4a1ed95a3e307b897860209b Mon Sep 17 00:00:00 2001
From: Peter Wang <peter.wang13@emc.com>
Date: Wed, 28 Mar 2018 02:44:24 -0400
Subject: [PATCH] VNX: fix performance in create/delete_volume

When in high concurrency, it is helpful to avoid commands or use
commands with "-np" option, in this patch, the following changes are
made:

* use '-np' when creating new lun.
* do not query if it's an snap-copy volume.
* do not issue unnecessary 'snap -destroy' when deleting volume.

Change-Id: I5dbeca00bfbd19133805556cdcc5214d069e3b28
---
 .../drivers/dell_emc/vnx/mocked_vnx.yaml      |  9 ++++++--
 .../drivers/dell_emc/vnx/test_client.py       |  2 +-
 cinder/volume/drivers/dell_emc/vnx/adapter.py | 10 ++++++---
 cinder/volume/drivers/dell_emc/vnx/client.py  | 21 +++++++++----------
 cinder/volume/drivers/dell_emc/vnx/driver.py  |  3 ++-
 .../vnx-perf-optimize-bd55dc3ef7584228.yaml   |  3 +++
 6 files changed, 30 insertions(+), 18 deletions(-)
 create mode 100644 releasenotes/notes/vnx-perf-optimize-bd55dc3ef7584228.yaml

diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vnx/mocked_vnx.yaml b/cinder/tests/unit/volume/drivers/dell_emc/vnx/mocked_vnx.yaml
index 12a1d6f1d12..68483d9cf8d 100644
--- a/cinder/tests/unit/volume/drivers/dell_emc/vnx/mocked_vnx.yaml
+++ b/cinder/tests/unit/volume/drivers/dell_emc/vnx/mocked_vnx.yaml
@@ -176,6 +176,7 @@ test_create_lun: &test_create_lun
       name: pool1
     _methods:
       create_lun: *lun_test_create_lun
+      with_no_poll: _context
 
   vnx:
     _properties:
@@ -191,6 +192,7 @@ test_create_lun_error: &test_create_lun_error
       create_lun:
         _raise:
           VNXCreateLunError: Unkown Error
+      with_no_poll: _context
   vnx:
     _properties:
       <<: *vnx_base_prop
@@ -254,6 +256,7 @@ test_create_lun_compression:
       <<: *pool_base_prop
     _methods:
       create_lun: *lun_test_create_lun_compression
+      with_no_poll: _context
 
   vnx:
     _properties:
@@ -274,6 +277,7 @@ test_create_lun_already_existed:
     _properties:
       <<: *pool_base_prop
     _methods:
+      with_no_poll: _context
       create_lun:
         _raise:
           VNXLunNameInUseError: Lun already exists(0x712d8d04)
@@ -451,8 +455,6 @@ test_delete_smp: &test_delete_smp
     _properties:
       <<: *lun_base_prop
       name: lun_test_delete_smp
-      attached_snapshot: *snapshot_test_delete_smp
-      is_snap_mount_point: True
     _methods:
       delete:
 
@@ -461,6 +463,7 @@ test_delete_smp: &test_delete_smp
       <<: *vnx_base_prop
     _methods:
       get_lun: *lun_test_delete_smp
+      get_snap: *snapshot_test_delete_smp
 
 test_delete_lun_not_exist:
   lun: &lun_test_delete_lun_not_exist
@@ -1233,6 +1236,7 @@ test_migrate_volume:
   pool: &migrate_pool
     _methods:
       create_lun: *src_lun_1
+      with_no_poll: _context
   vnx:
     _methods:
       get_lun:
@@ -1282,6 +1286,7 @@ test_create_cloned_volume:
   pool: &migrate_pool_2
     _methods:
       create_lun: *smp_migrate
+      with_no_poll: _context
   vnx:
     _properties:
       serial: fake_serial
diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_client.py b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_client.py
index 4df99f01499..acc94811733 100644
--- a/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_client.py
+++ b/cinder/tests/unit/volume/drivers/dell_emc/vnx/test_client.py
@@ -178,7 +178,7 @@ class TestClient(test.TestCase):
 
     @res_mock.patch_client
     def test_delete_smp(self, client, mocked):
-        client.delete_lun(mocked['lun'].name)
+        client.delete_lun(mocked['lun'].name, snap_copy='snap-as-vol')
 
     @res_mock.patch_client
     def test_delete_lun_not_exist(self, client, mocked):
diff --git a/cinder/volume/drivers/dell_emc/vnx/adapter.py b/cinder/volume/drivers/dell_emc/vnx/adapter.py
index a00e45709d7..2c0d7071e27 100644
--- a/cinder/volume/drivers/dell_emc/vnx/adapter.py
+++ b/cinder/volume/drivers/dell_emc/vnx/adapter.py
@@ -780,10 +780,13 @@ class CommonAdapter(replication.ReplicationAdapter):
     def delete_volume(self, volume):
         """Deletes an EMC volume."""
         async_migrate = utils.is_async_migrate_enabled(volume)
+        snap_copy = (utils.construct_snap_name(volume) if
+                     utils.is_snapcopy_enabled(volume) else None)
         self.cleanup_lun_replication(volume)
         try:
             self.client.delete_lun(volume.name,
-                                   force=self.force_delete_lun_in_sg)
+                                   force=self.force_delete_lun_in_sg,
+                                   snap_copy=snap_copy)
         except storops_ex.VNXLunUsedByFeatureError:
             # Case 1. Migration not finished, cleanup related stuff.
             if async_migrate:
@@ -797,8 +800,9 @@ class CommonAdapter(replication.ReplicationAdapter):
             # Here, we assume no Cinder managed snaps, and add it to queue
             # for later deletion
             self.client.delay_delete_lun(volume.name)
-        # Case 2. Migration already finished, delete temp snap if exists.
-        if async_migrate:
+        # Case 2. Migration already finished, try to delete the temp snap
+        # only when it's a cloned volume.
+        if async_migrate and volume.source_volid:
             self.client.delete_snapshot(utils.construct_snap_name(volume))
 
     def extend_volume(self, volume, new_size):
diff --git a/cinder/volume/drivers/dell_emc/vnx/client.py b/cinder/volume/drivers/dell_emc/vnx/client.py
index abbafc71c39..fd7ae283a26 100644
--- a/cinder/volume/drivers/dell_emc/vnx/client.py
+++ b/cinder/volume/drivers/dell_emc/vnx/client.py
@@ -102,11 +102,12 @@ class Client(object):
                    qos_specs=None):
         pool = self.vnx.get_pool(name=pool)
         try:
-            lun = pool.create_lun(lun_name=name,
-                                  size_gb=size,
-                                  provision=provision,
-                                  tier=tier,
-                                  ignore_thresholds=ignore_thresholds)
+            with pool.with_no_poll():
+                lun = pool.create_lun(lun_name=name,
+                                      size_gb=size,
+                                      provision=provision,
+                                      tier=tier,
+                                      ignore_thresholds=ignore_thresholds)
         except storops_ex.VNXLunNameInUseError:
             lun = self.vnx.get_lun(name=name)
 
@@ -140,17 +141,15 @@ class Client(object):
             lun = self.get_lun(name=volume.name)
             return lun.lun_id
 
-    def delete_lun(self, name, force=False):
+    def delete_lun(self, name, force=False, snap_copy=False):
         """Deletes a LUN or mount point."""
         lun = self.get_lun(name=name)
-        smp_attached_snap = (lun.attached_snapshot if lun.is_snap_mount_point
-                             else None)
-
         try:
             # Do not delete the snapshots of the lun.
             lun.delete(force_detach=True, detach_from_sg=force)
-            if smp_attached_snap:
-                smp_attached_snap.delete()
+            if snap_copy:
+                snap = self.vnx.get_snap(name=snap_copy)
+                snap.delete()
         except storops_ex.VNXLunNotFoundError as ex:
             LOG.info("LUN %(name)s is already deleted. This message can "
                      "be safely ignored. Message: %(msg)s",
diff --git a/cinder/volume/drivers/dell_emc/vnx/driver.py b/cinder/volume/drivers/dell_emc/vnx/driver.py
index 40c3c3eba37..6b33d344c48 100644
--- a/cinder/volume/drivers/dell_emc/vnx/driver.py
+++ b/cinder/volume/drivers/dell_emc/vnx/driver.py
@@ -80,9 +80,10 @@ class VNXDriver(driver.ManageableVD,
           12.0.0 - Add `volume revert to snapshot` support
           12.1.0 - Adjust max_luns_per_storage_group and
                    check_max_pool_luns_threshold
+          12.1.1 - Fix perf issue when create/delete volume
     """
 
-    VERSION = '12.01.00'
+    VERSION = '12.01.01'
     VENDOR = 'Dell EMC'
     # ThirdPartySystems wiki page
     CI_WIKI_NAME = "EMC_VNX_CI"
diff --git a/releasenotes/notes/vnx-perf-optimize-bd55dc3ef7584228.yaml b/releasenotes/notes/vnx-perf-optimize-bd55dc3ef7584228.yaml
new file mode 100644
index 00000000000..2442bf31cdc
--- /dev/null
+++ b/releasenotes/notes/vnx-perf-optimize-bd55dc3ef7584228.yaml
@@ -0,0 +1,3 @@
+---
+other:
+  - "Dell EMC VNX driver: Enhances the performance of create/delete volume."