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
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)
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,