ceph backup support for EXCLUSIVE_LOCK and JOURNALING features

Ceph Jewel has introduced the ability to mirror its pools. If configured
to do so, the rbd-mirror daemon will replay an image's journals to
replicate the image at a remote Ceph store. In order for an image to be
mirrored, the 'exclusive-lock' and 'journaling' feature bits need to be
enabled per image.

Ceph documentation recommends using "rbd features default = 125" in the
Ceph configuration to enable these feature bits for all newly created
images. However, if an image has an explicit set of feature bits asked
for during its creation, that request overrides what is set for "rbd
features default". The Ceph backup driver is specifcally asking for
"stripingv2" and "layering"; thus ignoring what is set at "rbd features
default".

This patch adds a new configuration option, 'backup_ceph_image_journals'
which adds these feature bits to the 'features' set returned by
_get_rbd_support(). If 'backup_ceph_image_journals' is set to True and
the underlying installation of RBD does not support either JOURNALING or
EXCLUSIVE_LOCK, an error is logged and 'BackupCephInvalidArgs' is raised
whenever an operation attempts to create a new Cepd object.

Change-Id: Iea9dc18ab68891c99d008157220365d184caf508
Implements: blueprint backup-ceph-driver-journaling-exculsive-lock-features
This commit is contained in:
Eric M Gonzalez
2016-12-20 10:43:21 -06:00
parent 0ed3a80d6c
commit dc96c948f7
3 changed files with 66 additions and 0 deletions

View File

@@ -88,6 +88,9 @@ service_opts = [
help='RBD stripe unit to use when creating a backup image.'),
cfg.IntOpt('backup_ceph_stripe_count', default=0,
help='RBD stripe count to use when creating a backup image.'),
cfg.BoolOpt('backup_ceph_image_journals', default=False,
help='If True, apply JOURNALING and EXCLUSIVE_LOCK feature '
'bits to the backup RBD objects to allow mirroring'),
cfg.BoolOpt('restore_discard_excess_bytes', default=True,
help='If True, always discard excess bytes when restoring '
'volumes i.e. pad with zeroes.')
@@ -222,6 +225,16 @@ class CephBackupDriver(driver.BackupDriver):
"""Determine if striping is supported by our version of librbd."""
return hasattr(self.rbd, 'RBD_FEATURE_STRIPINGV2')
@property
def _supports_exclusive_lock(self):
"""Determine if exclusive-lock is supported by librbd."""
return hasattr(self.rbd, 'RBD_FEATURE_EXCLUSIVE_LOCK')
@property
def _supports_journaling(self):
"""Determine if journaling is supported by our version of librbd."""
return hasattr(self.rbd, 'RBD_FEATURE_JOURNALING')
def _get_rbd_support(self):
"""Determine RBD features supported by our version of librbd."""
old_format = True
@@ -233,6 +246,25 @@ 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(_LE("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")
)
return (old_format, features)
def _connect_to_rados(self, pool=None):