Fix RBD incremental backup
Since the default get_backup_device method doesn't return enough Ceph connection information, RBD incremental backup will fail, resulting in full backups being performed when an incremental is requested. Closes-Bug: #1578036 Co-Author: Gorka Eguileor <geguileo@redhat.com> Change-Id: I41d1ec84db58f4bf0f7362cec022f2c3380e5ee2
This commit is contained in:
parent
910f534382
commit
53522164dc
cinder
@ -17,6 +17,7 @@
|
||||
import math
|
||||
import os
|
||||
import tempfile
|
||||
import uuid
|
||||
|
||||
import castellan
|
||||
import ddt
|
||||
@ -26,6 +27,7 @@ from oslo_utils import imageutils
|
||||
from oslo_utils import units
|
||||
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
import cinder.image.glance
|
||||
from cinder.image import image_utils
|
||||
@ -183,6 +185,7 @@ class RBDTestCase(test.TestCase):
|
||||
self.cfg.rbd_store_chunk_size = 4
|
||||
self.cfg.rados_connection_retries = 3
|
||||
self.cfg.rados_connection_interval = 5
|
||||
self.cfg.backup_use_temp_snapshot = False
|
||||
|
||||
mock_exec = mock.Mock()
|
||||
mock_exec.return_value = ('', '')
|
||||
@ -2147,6 +2150,53 @@ class RBDTestCase(test.TestCase):
|
||||
'rbd', 'import', '--pool', 'rbd', '--order', 22,
|
||||
'/imgfile', self.volume_c.name)
|
||||
|
||||
@mock.patch('cinder.objects.Volume.get_by_id')
|
||||
@mock.patch('cinder.db.volume_glance_metadata_get', return_value={})
|
||||
@common_mocks
|
||||
def test_get_backup_device_ceph(self, mock_gm_get, volume_get_by_id):
|
||||
# Use the same volume for backup (volume_a)
|
||||
volume_get_by_id.return_value = self.volume_a
|
||||
driver = self.driver
|
||||
|
||||
self._create_backup_db_entry(fake.BACKUP_ID, self.volume_a['id'], 1)
|
||||
backup = objects.Backup.get_by_id(self.context, fake.BACKUP_ID)
|
||||
backup.service = 'asdf#ceph'
|
||||
|
||||
ret = driver.get_backup_device(self.context, backup)
|
||||
self.assertEqual(ret, (self.volume_a, False))
|
||||
|
||||
def _create_backup_db_entry(self, backupid, volid, size,
|
||||
userid=str(uuid.uuid4()),
|
||||
projectid=str(uuid.uuid4())):
|
||||
backup = {'id': backupid, 'size': size, 'volume_id': volid,
|
||||
'user_id': userid, 'project_id': projectid}
|
||||
return db.backup_create(self.context, backup)['id']
|
||||
|
||||
@mock.patch('cinder.volume.driver.BaseVD._get_backup_volume_temp_snapshot')
|
||||
@mock.patch('cinder.volume.driver.BaseVD._get_backup_volume_temp_volume')
|
||||
@mock.patch('cinder.objects.Volume.get_by_id')
|
||||
@mock.patch('cinder.db.volume_glance_metadata_get', return_value={})
|
||||
@common_mocks
|
||||
def test_get_backup_device_other(self,
|
||||
mock_gm_get,
|
||||
volume_get_by_id,
|
||||
mock_get_temp_volume,
|
||||
mock_get_temp_snapshot):
|
||||
# Use a cloned volume for backup (volume_b)
|
||||
self.volume_a.previous_status = 'in-use'
|
||||
mock_get_temp_volume.return_value = self.volume_b
|
||||
mock_get_temp_snapshot.return_value = (self.volume_b, False)
|
||||
|
||||
volume_get_by_id.return_value = self.volume_a
|
||||
driver = self.driver
|
||||
|
||||
self._create_backup_db_entry(fake.BACKUP_ID, self.volume_a['id'], 1)
|
||||
backup = objects.Backup.get_by_id(self.context, fake.BACKUP_ID)
|
||||
backup.service = 'asdf'
|
||||
|
||||
ret = driver.get_backup_device(self.context, backup)
|
||||
self.assertEqual(ret, (self.volume_b, False))
|
||||
|
||||
|
||||
class ManagedRBDTestCase(test_driver.BaseDriverTestCase):
|
||||
driver_name = "cinder.volume.drivers.rbd.RBDDriver"
|
||||
|
@ -36,6 +36,7 @@ from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder import objects
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
from cinder.volume import configuration
|
||||
@ -1770,3 +1771,16 @@ class RBDDriver(driver.CloneableImageVD, driver.MigrateVD,
|
||||
volume.set_snap(None)
|
||||
if not children and volume.is_protected_snap(snapshot.name):
|
||||
volume.unprotect_snap(snapshot.name)
|
||||
|
||||
def get_backup_device(self, context, backup):
|
||||
"""Get a backup device from an existing volume.
|
||||
|
||||
To support incremental backups on Ceph to Ceph we don't clone
|
||||
the volume.
|
||||
"""
|
||||
|
||||
if not backup.service.endswith('ceph') or backup.snapshot_id:
|
||||
return super(RBDDriver, self).get_backup_device(context, backup)
|
||||
|
||||
volume = objects.Volume.get_by_id(context, backup.volume_id)
|
||||
return (volume, False)
|
||||
|
Loading…
x
Reference in New Issue
Block a user