Make sure device support Direct before setting
We added '-t none' option to the qemu-img convert operation in image_utils.py a while back to accomodate a couple of backend devices that didn't flush writes on disconnect. (Change: I7a04f683add8c23b9125fe837c4048ccc3ac224d) The only problem here is that some backend devices don't support Direct mode and raise an exception and fail when setting this option. This patch adds a simple check using dd to see if the dest supports the Direct flag and only sets '-t none' if the device does in fact support it. Additionally it was brought up that even yet other backends are using file devices not blk devices. In their case setting Direct will still work, however it's sub-optimal as qemu-convert has internal mechanisms to make sure flushing etc are done correctly and efficiently for those devices. So to accomodate that particular use case I'm also adding a check if blk dev that can be used for determining whether to set Direct for the qemu-convert process. Change-Id: I34127ac373ceadcfb6fc2662628b1a91eb7b0046 Closes-Bug: 1375487
This commit is contained in:
@@ -285,18 +285,26 @@ def _calculate_count(size_in_m, blocksize):
|
||||
return blocksize, int(count)
|
||||
|
||||
|
||||
def check_for_odirect_support(src, dest, flag='oflag=direct'):
|
||||
|
||||
# Check whether O_DIRECT is supported
|
||||
try:
|
||||
utils.execute('dd', 'count=0', 'if=%s' % src, 'of=%s' % dest,
|
||||
flag, run_as_root=True)
|
||||
return True
|
||||
except processutils.ProcessExecutionError:
|
||||
return False
|
||||
|
||||
|
||||
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 = []
|
||||
# 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 check_for_odirect_support(srcstr, deststr, 'iflag=direct'):
|
||||
extra_flags.append('iflag=direct')
|
||||
|
||||
if check_for_odirect_support(srcstr, deststr, 'oflag=direct'):
|
||||
extra_flags.append('oflag=direct')
|
||||
|
||||
# If the volume is being unprovisioned then
|
||||
# request the data is persisted before returning,
|
||||
|
||||
Reference in New Issue
Block a user