From 0007d255d9b20da4e5bbcdbaf5813104fbc092da Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Wed, 16 Jan 2013 16:23:48 +0000 Subject: [PATCH] ensure zeros are written out when clearing volumes Note O_DIRECT is _not_ used when copying from /dev/zero and there are issues with enabling that (see 444cd542). Therefore we arrange to have dd issue an fdatasync() to ensure the data is persisted, lest it be discarded from the write cache when the device is unprovisioned. * cinder/volume/drivers/lvm.py (_copy_volume): Add 'conv=fdatasync' to the dd option list if O_DIRECT isn't used when clearing (which it won't as descrived above). Fixes bug: 1100363 Change-Id: I76789557754ebaeb6d52bb34548a2ef17808fbf6 --- cinder/volume/drivers/lvm.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py index b1b217d73..b3bde19b8 100644 --- a/cinder/volume/drivers/lvm.py +++ b/cinder/volume/drivers/lvm.py @@ -85,21 +85,27 @@ class LVMVolumeDriver(driver.VolumeDriver): self._try_execute(*cmd, run_as_root=True) - def _copy_volume(self, srcstr, deststr, size_in_g): + def _copy_volume(self, srcstr, deststr, size_in_g, clearing=False): # Use O_DIRECT to avoid thrashing the system buffer cache - direct_flags = ('iflag=direct', 'oflag=direct') + extra_flags = ['iflag=direct', 'oflag=direct'] # Check whether O_DIRECT is supported try: self._execute('dd', 'count=0', 'if=%s' % srcstr, 'of=%s' % deststr, - *direct_flags, run_as_root=True) + *extra_flags, run_as_root=True) except exception.ProcessExecutionError: - direct_flags = () + extra_flags = [] + + # If the volume is being unprovisioned then + # request the data is persisted before returning, + # so that it's not discarded from the cache. + if clearing and not extra_flags: + extra_flags.append('conv=fdatasync') # Perform the copy self._execute('dd', 'if=%s' % srcstr, 'of=%s' % deststr, 'count=%d' % (size_in_g * 1024), 'bs=1M', - *direct_flags, run_as_root=True) + *extra_flags, run_as_root=True) def _volume_not_present(self, volume_name): path_name = '%s/%s' % (FLAGS.volume_group, volume_name) @@ -184,7 +190,8 @@ class LVMVolumeDriver(driver.VolumeDriver): if FLAGS.volume_clear == 'zero': if size_in_m == 0: - return self._copy_volume('/dev/zero', vol_path, size_in_g) + return self._copy_volume('/dev/zero', vol_path, size_in_g, + clearing=True) else: clear_cmd = ['shred', '-n0', '-z', '-s%dMiB' % size_in_m] elif FLAGS.volume_clear == 'shred': -- 2.45.2