From: vitas.yuzhou Date: Mon, 12 May 2014 18:57:48 +0000 (+0800) Subject: Check whether O_DIRECT is supported to iflag and oflag separately X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=2448ffd53bd224564b8fca17e4cbbace2e039597;p=openstack-build%2Fcinder-build.git Check whether O_DIRECT is supported to iflag and oflag separately The problem is when this is used for volume clear and the clear method specifies use of the 'zero' option (/dev/zero) setting iflag direct is not a valid option for that input file, but oflag direct is a valid option for output file, so we should check iflag and oflag separately. Change-Id: I4b627e95b68d56e3011cddc577c62fad0c384dba Close-Bug: 1318748 --- diff --git a/cinder/tests/test_volume_utils.py b/cinder/tests/test_volume_utils.py index fd120013c..358a5e66a 100644 --- a/cinder/tests/test_volume_utils.py +++ b/cinder/tests/test_volume_utils.py @@ -25,6 +25,7 @@ from cinder import db from cinder import exception from cinder.openstack.common import importutils from cinder.openstack.common import log as logging +from cinder.openstack.common import processutils from cinder import test from cinder.tests import fake_notifier from cinder import utils @@ -200,3 +201,19 @@ class ClearVolumeTestCase(test.TestCase): self.stubs.Set(volume_utils, 'copy_volume', fake_copy_volume) volume_utils.clear_volume(123, vol_path) + + +class CopyVolumeTestCase(test.TestCase): + + def test_copy_volume_dd_iflag_and_oflag(self): + def fake_utils_execute(*cmd, **kwargs): + if 'if=/dev/zero' in cmd and 'iflag=direct' in cmd: + raise processutils.ProcessExecutionError() + if 'of=/dev/null' in cmd and 'oflag=direct' in cmd: + raise processutils.ProcessExecutionError() + if 'iflag=direct' in cmd and 'oflag=direct' in cmd: + raise exception.InvalidInput(message='iflag/oflag error') + + volume_utils.copy_volume('/dev/zero', '/dev/null', 1024, + CONF.volume_dd_blocksize, sync=True, + ionice=None, execute=fake_utils_execute) diff --git a/cinder/volume/utils.py b/cinder/volume/utils.py index 967bcee53..0ca7b68b5 100644 --- a/cinder/volume/utils.py +++ b/cinder/volume/utils.py @@ -131,14 +131,15 @@ def _calculate_count(size_in_m, blocksize): def copy_volume(srcstr, deststr, size_in_m, blocksize, sync=False, execute=utils.execute, ionice=None): # Use O_DIRECT to avoid thrashing the system buffer cache - extra_flags = ['iflag=direct', 'oflag=direct'] - - # Check whether O_DIRECT is supported - try: - execute('dd', 'count=0', 'if=%s' % srcstr, 'of=%s' % deststr, - *extra_flags, run_as_root=True) - except processutils.ProcessExecutionError: - extra_flags = [] + extra_flags = [] + # Check whether O_DIRECT is supported to iflag and oflag separately + for flag in ['iflag=direct', 'oflag=direct']: + try: + execute('dd', 'count=0', 'if=%s' % srcstr, 'of=%s' % deststr, + flag, run_as_root=True) + extra_flags.append(flag) + except processutils.ProcessExecutionError: + pass # If the volume is being unprovisioned then # request the data is persisted before returning,