Add support for RBD fast-diff feature for backups stored in Ceph

This change enables the FAST_DIFF feature for backup images stored
    via Ceph RBD. It is enabled together with EXCLUSIVE_LOCK and
    OBJECT_MAP as required.

    With FAST_DIFF enabled, the generation of diffs between images and
    snapshots as well as determining the actual data usage of a snapshot
    is sped up significantly.

Closes-Bug #1907964

Change-Id: I5e35de28007558267f9215cbac03a38d7c74612c
(cherry picked from commit 0e88073882)
This commit is contained in:
Christian Rohmann 2020-12-13 15:07:10 +01:00
parent 990cba70ee
commit cbf9def32b
3 changed files with 56 additions and 17 deletions

View File

@ -244,6 +244,11 @@ class CephBackupDriver(driver.BackupDriver):
"""Determine if journaling is supported by our version of librbd."""
return hasattr(self.rbd, 'RBD_FEATURE_JOURNALING')
@property
def _supports_fast_diff(self):
"""Determine if fast-diff is supported by our version of librbd."""
return hasattr(self.rbd, 'RBD_FEATURE_FAST_DIFF')
def _get_rbd_support(self):
"""Determine RBD features supported by our version of librbd."""
old_format = True
@ -255,24 +260,22 @@ class CephBackupDriver(driver.BackupDriver):
old_format = False
features |= self.rbd.RBD_FEATURE_STRIPINGV2
# journaling requires exclusive_lock; check both together
if CONF.backup_ceph_image_journals:
if self._supports_exclusive_lock and self._supports_journaling:
old_format = False
features |= (self.rbd.RBD_FEATURE_EXCLUSIVE_LOCK |
self.rbd.RBD_FEATURE_JOURNALING)
else:
# FIXME (tasker): when the backup manager supports loading the
# driver during its initialization, this exception should be
# moved to the driver's initialization so that it can stop
# the service from starting when the underyling RBD does not
# support the requested features.
LOG.error("RBD journaling not supported - unable to "
"support per image mirroring in backup pool")
raise exception.BackupInvalidCephArgs(
_("Image Journaling set but RBD backend does "
"not support journaling")
)
LOG.debug("RBD journaling supported by backend and requested "
"via config. Enabling it together with "
"exclusive-lock")
old_format = False
features |= (self.rbd.RBD_FEATURE_EXCLUSIVE_LOCK |
self.rbd.RBD_FEATURE_JOURNALING)
# NOTE(christian_rohmann): Check for fast-diff support and enable it
if self._supports_fast_diff:
LOG.debug("RBD also supports fast-diff, enabling it "
"together with exclusive-lock and object-map")
old_format = False
features |= (self.rbd.RBD_FEATURE_EXCLUSIVE_LOCK |
self.rbd.RBD_FEATURE_OBJECT_MAP |
self.rbd.RBD_FEATURE_FAST_DIFF)
return (old_format, features)
@ -294,6 +297,16 @@ class CephBackupDriver(driver.BackupDriver):
with rbd_driver.RADOSClient(self, self._ceph_backup_pool):
pass
# NOTE(christian_rohmann): Check features required for journaling
if CONF.backup_ceph_image_journals:
if not self._supports_exclusive_lock and self._supports_journaling:
LOG.error("RBD journaling not supported - unable to "
"support per image mirroring in backup pool")
raise exception.BackupInvalidCephArgs(
_("Image Journaling set but RBD backend does "
"not support journaling")
)
def _connect_to_rados(self, pool=None):
"""Establish connection to the backup Ceph cluster."""
client = eventlet.tpool.Proxy(self.rados.Rados(

View File

@ -237,11 +237,15 @@ class BackupCephTestCase(test.TestCase):
del self.service.rbd.RBD_FEATURE_STRIPINGV2
del self.service.rbd.RBD_FEATURE_EXCLUSIVE_LOCK
del self.service.rbd.RBD_FEATURE_JOURNALING
del self.service.rbd.RBD_FEATURE_OBJECT_MAP
del self.service.rbd.RBD_FEATURE_FAST_DIFF
self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_LAYERING'))
self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_STRIPINGV2'))
self.assertFalse(hasattr(self.service.rbd,
'RBD_FEATURE_EXCLUSIVE_LOCK'))
self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_JOURNALING'))
self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_OBJECT_MAP'))
self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_FAST_DIFF'))
oldformat, features = self.service._get_rbd_support()
self.assertTrue(oldformat)
@ -281,6 +285,17 @@ class BackupCephTestCase(test.TestCase):
self.assertFalse(oldformat)
self.assertEqual(1 | 2 | 4 | 64, features)
#
# test that FAST_DIFF is enabled if supported by RBD
# this also enables OBJECT_MAP as required by Ceph
#
self.service.rbd.RBD_FEATURE_OBJECT_MAP = 8
self.service.rbd.RBD_FEATURE_FAST_DIFF = 16
oldformat, features = self.service._get_rbd_support()
self.assertFalse(oldformat)
self.assertEqual(1 | 2 | 4 | 8 | 16 | 64, features)
@common_mocks
def test_get_backup_snap_name(self):
snap_name = 'backup.%s.snap.3824923.1412' % (fake.VOLUME3_ID)

View File

@ -0,0 +1,11 @@
---
fixes:
- |
RBD driver `bug #1907964
<https://bugs.launchpad.net/cinder/+bug/1907964>`_: Add support
for fast-diff on backup images stored in Ceph.
Provided fast-diff is supported by the backend it will automatically be
enabled and used.
With fast-diff enabled, the generation of diffs between images and
snapshots as well as determining the actual data usage of a snapshot
is speed up significantly.