Merge "ceph backup support for EXCLUSIVE_LOCK and JOURNALING features"

This commit is contained in:
Jenkins 2017-02-15 14:37:21 +00:00 committed by Gerrit Code Review
commit 7127e28507
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):

View File

@ -22,6 +22,7 @@ import uuid
import mock
from os_brick.initiator import linuxrbd
from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_serialization import jsonutils
from oslo_utils import units
import six
@ -42,6 +43,8 @@ from cinder.tests.unit import fake_constants as fake
# NOTE: this must be initialised in test setUp().
RAISED_EXCEPTIONS = []
CONF = cfg.CONF
class MockException(Exception):
@ -202,8 +205,13 @@ class BackupCephTestCase(test.TestCase):
def test_get_rbd_support(self):
del self.service.rbd.RBD_FEATURE_LAYERING
del self.service.rbd.RBD_FEATURE_STRIPINGV2
del self.service.rbd.RBD_FEATURE_EXCLUSIVE_LOCK
del self.service.rbd.RBD_FEATURE_JOURNALING
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'))
oldformat, features = self.service._get_rbd_support()
self.assertTrue(oldformat)
@ -221,6 +229,28 @@ class BackupCephTestCase(test.TestCase):
self.assertFalse(oldformat)
self.assertEqual(1 | 2, features)
# initially, backup_ceph_image_journals = False. test that
# the flags are defined, but that they are not returned.
self.service.rbd.RBD_FEATURE_EXCLUSIVE_LOCK = 4
oldformat, features = self.service._get_rbd_support()
self.assertFalse(oldformat)
self.assertEqual(1 | 2, features)
self.service.rbd.RBD_FEATURE_JOURNALING = 64
oldformat, features = self.service._get_rbd_support()
self.assertFalse(oldformat)
self.assertEqual(1 | 2, features)
# test that the config setting properly sets the FEATURE bits.
# because journaling requires exclusive-lock, these are set
# at the same time.
CONF.set_override("backup_ceph_image_journals", True)
oldformat, features = self.service._get_rbd_support()
self.assertFalse(oldformat)
self.assertEqual(1 | 2 | 4 | 64, features)
@common_mocks
def test_get_most_recent_snap(self):
last = 'backup.%s.snap.9824923.1212' % (uuid.uuid4())

View File

@ -0,0 +1,4 @@
---
features:
- Added new BoolOpt ``backup_ceph_image_journals`` for enabling the Ceph
image features required to support RBD mirroring of Cinder backup pool.