summaryrefslogtreecommitdiff
path: root/cinder/backup/drivers/ceph.py
diff options
context:
space:
mode:
Diffstat (limited to 'cinder/backup/drivers/ceph.py')
-rw-r--r--cinder/backup/drivers/ceph.py39
1 files changed, 25 insertions, 14 deletions
diff --git a/cinder/backup/drivers/ceph.py b/cinder/backup/drivers/ceph.py
index d21e458bf..1cb5727c2 100644
--- a/cinder/backup/drivers/ceph.py
+++ b/cinder/backup/drivers/ceph.py
@@ -64,6 +64,7 @@ from cinder import interface
from cinder import objects
from cinder import utils
import cinder.volume.drivers.rbd as rbd_driver
+from cinder.volume import volume_utils
try:
import rados
@@ -350,7 +351,6 @@ class CephBackupDriver(driver.BackupDriver):
Incremental backups use a new base name so we support old and new style
format.
"""
- # Ensure no unicode
if not backup:
return "volume-%s.backup.base" % volume_id
@@ -414,7 +414,8 @@ class CephBackupDriver(driver.BackupDriver):
src_name: str,
dest: linuxrbd.RBDVolumeIOWrapper,
dest_name: str,
- length: int) -> None:
+ length: int,
+ discard_zeros: bool = False) -> None:
"""Transfer data between files (Python IO objects)."""
LOG.debug("Transferring data between '%(src)s' and '%(dest)s'",
{'src': src_name, 'dest': dest_name})
@@ -435,13 +436,17 @@ class CephBackupDriver(driver.BackupDriver):
return
- dest.write(data)
- dest.flush()
+ if (discard_zeros and volume_utils.is_all_zero(data)):
+ action = "Discarded"
+ else:
+ dest.write(data)
+ dest.flush()
+ action = "Transferred"
delta = (time.time() - before)
rate = (self.chunk_size / delta) / 1024
- LOG.debug("Transferred chunk %(chunk)s of %(chunks)s "
- "(%(rate)dK/s)",
- {'chunk': chunk + 1,
+ LOG.debug("%(action)s chunk %(chunk)s of %(chunks)s (%(rate)dK/s)",
+ {'action': action,
+ 'chunk': chunk + 1,
'chunks': chunks,
'rate': rate})
@@ -1076,6 +1081,7 @@ class CephBackupDriver(driver.BackupDriver):
dest_file,
dest_name: str,
length: int,
+ volume_is_new: bool,
src_snap=None) -> None:
"""Restore volume using full copy i.e. all extents.
@@ -1104,7 +1110,8 @@ class CephBackupDriver(driver.BackupDriver):
self._ceph_backup_conf)
rbd_fd = linuxrbd.RBDVolumeIOWrapper(rbd_meta)
self._transfer_data(eventlet.tpool.Proxy(rbd_fd), backup_name,
- dest_file, dest_name, length)
+ dest_file, dest_name, length,
+ discard_zeros=volume_is_new)
finally:
src_rbd.close()
@@ -1280,7 +1287,8 @@ class CephBackupDriver(driver.BackupDriver):
def _restore_volume(self,
backup: 'objects.Backup',
volume: 'objects.Volume',
- volume_file: linuxrbd.RBDVolumeIOWrapper) -> None:
+ volume_file: linuxrbd.RBDVolumeIOWrapper,
+ volume_is_new: bool) -> None:
"""Restore volume from backup using diff transfer if possible.
Attempts a differential restore and reverts to full copy if diff fails.
@@ -1314,7 +1322,7 @@ class CephBackupDriver(driver.BackupDriver):
# Otherwise full copy
LOG.debug("Running full restore.")
self._full_restore(backup, volume_file, volume.name,
- length, src_snap=restore_point)
+ length, volume_is_new, src_snap=restore_point)
def _restore_metadata(self,
backup: 'objects.Backup',
@@ -1341,18 +1349,21 @@ class CephBackupDriver(driver.BackupDriver):
def restore(self,
backup: 'objects.Backup',
volume_id: str,
- volume_file: linuxrbd.RBDVolumeIOWrapper) -> None:
+ volume_file: linuxrbd.RBDVolumeIOWrapper,
+ volume_is_new: bool) -> None:
"""Restore volume from backup in Ceph object store.
If volume metadata is available this will also be restored.
"""
target_volume = self.db.volume_get(self.context, volume_id)
LOG.debug('Starting restore from Ceph backup=%(src)s to '
- 'volume=%(dest)s',
- {'src': backup.id, 'dest': target_volume.name})
+ 'volume=%(dest)s new=%(new)s',
+ {'src': backup.id, 'dest': target_volume.name,
+ 'new': volume_is_new})
try:
- self._restore_volume(backup, target_volume, volume_file)
+ self._restore_volume(backup, target_volume, volume_file,
+ volume_is_new)
# Be tolerant of IO implementations that do not support fileno()
try: