diff --git a/driver.py b/driver.py index 1ed6409..da284bb 100644 --- a/driver.py +++ b/driver.py @@ -90,6 +90,7 @@ from nova.virt.libvirt import imagebackend from nova.virt.libvirt import imagecache from nova.virt.libvirt import utils as libvirt_utils from nova.virt import netutils +from nova.virt import images native_threading = patcher.original("threading") native_Queue = patcher.original("Queue") @@ -852,7 +853,41 @@ class LibvirtDriver(driver.ComputeDriver): # tree, this shouldn't block deletion of # the instance as whole. try: + + # pivotal story 684427 + file_backed_disk = target + '/disk' + if os.path.exists(file_backed_disk): + + vol_size = int(images.qemu_img_info(file_backed_disk).virtual_size) + bs = 1024 * 1024 + direct_flags = ('oflag=direct',) + sync_flags = () + remaining_bytes = vol_size + + LOG.info(_('Writing %s bytes of zeros to file backed disk %s') % (vol_size, file_backed_disk)) + + # The loop caters for versions of dd that + # don't support the iflag=count_bytes option. + while remaining_bytes: + zero_blocks = remaining_bytes / bs + seek_blocks = (vol_size - remaining_bytes) / bs + zero_cmd = ('dd', 'bs=%s' % bs, + 'if=/dev/zero', 'of=%s' % file_backed_disk, + 'seek=%s' % seek_blocks, 'count=%s' % zero_blocks) + zero_cmd += direct_flags + zero_cmd += sync_flags + if zero_blocks: + utils.execute(*zero_cmd, run_as_root=True) + remaining_bytes %= bs + bs /= 1024 # Limit to 3 iterations + # Use O_DIRECT with initial block size and fdatasync otherwise + direct_flags = () + sync_flags = ('conv=fdatasync',) + + # now that we've overritten the file with 0s, we can + # safely remove it shutil.rmtree(target) + except OSError, e: LOG.error(_("Failed to cleanup directory %(target)s: %(e)s" ) % locals())