]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add optional ionice to volume clearing process
authorDuncan Thomas <duncan.thomas@hp.com>
Wed, 19 Feb 2014 19:03:24 +0000 (19:03 +0000)
committerDuncan Thomas <duncan.thomas@hp.com>
Wed, 26 Feb 2014 20:22:27 +0000 (20:22 +0000)
Allow the volume clearing process to have an ionice priority set to
reduce the performance impact of volume zeroing. Note that this may
cause volume clearing processes to get backed up on  a busy system, use
with care.

DocImpact
Change-Id: I2d556f57aaca8a8ccc6f0f767f1cec28c3f9bc86
Implements: blueprint when-deleting-volume-dd-performance

cinder/tests/test_volume_utils.py
cinder/volume/driver.py
cinder/volume/utils.py
etc/cinder/cinder.conf.sample

index 4bb1464ea2e65ff660a02099304731495d8129ef..9ebda307762f847f4ecc870f8b8c83470f0a1418 100644 (file)
@@ -158,19 +158,46 @@ class ClearVolumeTestCase(test.TestCase):
         CONF.volume_clear = 'zero'
         CONF.volume_clear_size = 0
         CONF.volume_dd_blocksize = '1M'
+        CONF.volume_clear_ionice = None
         self.mox.StubOutWithMock(volume_utils, 'copy_volume')
         volume_utils.copy_volume("/dev/zero", "volume_path", 1024,
                                  CONF.volume_dd_blocksize, sync=True,
-                                 execute=utils.execute)
+                                 ionice=None, execute=utils.execute)
         self.mox.ReplayAll()
         volume_utils.clear_volume(1024, "volume_path")
 
     def test_clear_volume_zero(self):
         CONF.volume_clear = 'zero'
         CONF.volume_clear_size = 1
+        CONF.volume_clear_ionice = None
+        self.mox.StubOutWithMock(volume_utils, 'copy_volume')
+        volume_utils.copy_volume("/dev/zero", "volume_path", 1,
+                                 CONF.volume_dd_blocksize, sync=True,
+                                 ionice=None, execute=utils.execute)
+        self.mox.ReplayAll()
+        volume_utils.clear_volume(1024, "volume_path")
+
+    def test_clear_volume_ionice(self):
+        CONF.volume_clear = 'zero'
+        CONF.volume_clear_size = 0
+        CONF.volume_dd_blocksize = '1M'
+        CONF.volume_clear_ionice = '-c3'
+        self.mox.StubOutWithMock(volume_utils, 'copy_volume')
+        volume_utils.copy_volume("/dev/zero", "volume_path", 1024,
+                                 CONF.volume_dd_blocksize, sync=True,
+                                 ionice=CONF.volume_clear_ionice,
+                                 execute=utils.execute)
+        self.mox.ReplayAll()
+        volume_utils.clear_volume(1024, "volume_path")
+
+    def test_clear_volume_zero_ionice(self):
+        CONF.volume_clear = 'zero'
+        CONF.volume_clear_size = 1
+        CONF.volume_clear_ionice = '-c3'
         self.mox.StubOutWithMock(volume_utils, 'copy_volume')
         volume_utils.copy_volume("/dev/zero", "volume_path", 1,
                                  CONF.volume_dd_blocksize, sync=True,
+                                 ionice=CONF.volume_clear_ionice,
                                  execute=utils.execute)
         self.mox.ReplayAll()
         volume_utils.clear_volume(1024, "volume_path")
index 22dc586b6bd75ae011883a09bc1cad8744b994cb..59311d96553ea05512fbe586185debfc413caab8 100644 (file)
@@ -73,6 +73,11 @@ volume_opts = [
     cfg.IntOpt('volume_clear_size',
                default=0,
                help='Size in MiB to wipe at start of old volumes. 0 => all'),
+    cfg.StrOpt('volume_clear_ionice',
+               default=None,
+               help='The flag to pass to ionice to alter the i/o priority '
+                    'of the process used to zero a volume after deletion, '
+                    'for example "-c3" for idle only priority.'),
     cfg.StrOpt('iscsi_helper',
                default='tgtadm',
                help='iscsi target user-land tool to use'),
index 4827f8833069bb2de76a7a51b0883a11ab99bd57..adcad8905fa40212c3a39df6629a699c474421d7 100644 (file)
@@ -158,7 +158,7 @@ def _calculate_count(size_in_m, blocksize):
 
 
 def copy_volume(srcstr, deststr, size_in_m, blocksize, sync=False,
-                execute=utils.execute):
+                execute=utils.execute, ionice=None):
     # Use O_DIRECT to avoid thrashing the system buffer cache
     extra_flags = ['iflag=direct', 'oflag=direct']
 
@@ -177,15 +177,19 @@ def copy_volume(srcstr, deststr, size_in_m, blocksize, sync=False,
 
     blocksize, count = _calculate_count(size_in_m, blocksize)
 
+    cmd = ['dd', 'if=%s' % srcstr, 'of=%s' % deststr,
+           'count=%d' % count, 'bs=%s' % blocksize]
+    cmd.extend(extra_flags)
+
+    if ionice is not None:
+        cmd = ['ionice', ionice] + cmd
+
     # Perform the copy
-    execute('dd', 'if=%s' % srcstr, 'of=%s' % deststr,
-            'count=%d' % count,
-            'bs=%s' % blocksize,
-            *extra_flags, run_as_root=True)
+    execute(*cmd, run_as_root=True)
 
 
 def clear_volume(volume_size, volume_path, volume_clear=None,
-                 volume_clear_size=None):
+                 volume_clear_size=None, volume_clear_ionice=None):
     """Unprovision old volumes to prevent data leaking between users."""
     if volume_clear is None:
         volume_clear = CONF.volume_clear
@@ -196,12 +200,16 @@ def clear_volume(volume_size, volume_path, volume_clear=None,
     if volume_clear_size == 0:
         volume_clear_size = volume_size
 
+    if volume_clear_ionice is None:
+        volume_clear_ionice = CONF.volume_clear_ionice
+
     LOG.info(_("Performing secure delete on volume: %s") % volume_path)
 
     if volume_clear == 'zero':
         return copy_volume('/dev/zero', volume_path, volume_clear_size,
                            CONF.volume_dd_blocksize,
-                           sync=True, execute=utils.execute)
+                           sync=True, execute=utils.execute,
+                           ionice=volume_clear_ionice)
     elif volume_clear == 'shred':
         clear_cmd = ['shred', '-n3']
         if volume_clear_size:
index 2fb2679989711c679c3ec909548e68cc825385ca..73de852424a8d38ae64f15e9ac42800b6587aee3 100644 (file)
 # (integer value)
 #volume_clear_size=0
 
+# The flag to pass to ionice to alter the i/o priority of the
+# process used to zero a volume after deletion, for example
+# "-c3" for idle only priority. (string value)
+#volume_clear_ionice=<None>
+
 # iscsi target user-land tool to use (string value)
 #iscsi_helper=tgtadm