diff --git a/cinder/tests/unit/windows/test_smbfs.py b/cinder/tests/unit/windows/test_smbfs.py index 8bdaedd7a7e..9f6cbb71a5f 100644 --- a/cinder/tests/unit/windows/test_smbfs.py +++ b/cinder/tests/unit/windows/test_smbfs.py @@ -178,6 +178,35 @@ class WindowsSmbFsTestCase(test.TestCase): self.assertEqual(expected, ret_val) + @mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_snapshot_backing_file') + @mock.patch.object(smbfs.WindowsSmbfsDriver, 'get_volume_format') + @mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_mount_point_base') + def test_initialize_connection_snapshot(self, mock_get_mount_base, + mock_get_volume_format, + mock_get_snap_by_backing_file): + self._smbfs_driver.shares = {self._FAKE_SHARE: self._FAKE_SHARE_OPTS} + mock_get_snap_by_backing_file.return_value = self._FAKE_VOLUME_NAME + mock_get_volume_format.return_value = 'vhdx' + mock_get_mount_base.return_value = self._FAKE_MNT_BASE + + exp_data = {'export': self._FAKE_SHARE, + 'format': 'vhdx', + 'name': self._FAKE_VOLUME_NAME, + 'options': self._FAKE_SHARE_OPTS, + 'access_mode': 'ro'} + expected = { + 'driver_volume_type': 'smbfs', + 'data': exp_data, + 'mount_point_base': self._FAKE_MNT_BASE} + ret_val = self._smbfs_driver.initialize_connection_snapshot( + self.snapshot, mock.sentinel.connector) + + self.assertEqual(expected, ret_val) + + mock_get_snap_by_backing_file.assert_called_once_with(self.snapshot) + mock_get_volume_format.assert_called_once_with(self.snapshot.volume) + mock_get_mount_base.assert_called_once_with() + def test_setup(self): self._test_setup(config=self._FAKE_SMBFS_CONFIG) diff --git a/cinder/volume/drivers/windows/smbfs.py b/cinder/volume/drivers/windows/smbfs.py index caa34bf16c5..9d7a113261c 100644 --- a/cinder/volume/drivers/windows/smbfs.py +++ b/cinder/volume/drivers/windows/smbfs.py @@ -194,6 +194,25 @@ class WindowsSmbfsDriver(remotefs_drv.RevertToSnapshotMixin, 'mount_point_base': self._get_mount_point_base() } + @coordination.synchronized('{self.driver_prefix}-{snapshot.volume.id}') + def initialize_connection_snapshot(self, snapshot, connector): + backing_file = self._get_snapshot_backing_file(snapshot) + volume = snapshot.volume + fmt = self.get_volume_format(volume) + + data = {'export': volume.provider_location, + 'format': fmt, + 'name': backing_file, + 'access_mode': 'ro'} + + if volume.provider_location in self.shares: + data['options'] = self.shares[volume.provider_location] + return { + 'driver_volume_type': self.driver_volume_type, + 'data': data, + 'mount_point_base': self._get_mount_point_base() + } + def _check_os_platform(self): if sys.platform != 'win32': _msg = _("This system platform (%s) is not supported. This " diff --git a/releasenotes/notes/smbfs-snapshot-attach-14742fe8f5864ac6.yaml b/releasenotes/notes/smbfs-snapshot-attach-14742fe8f5864ac6.yaml new file mode 100644 index 00000000000..e3f1c3aa10a --- /dev/null +++ b/releasenotes/notes/smbfs-snapshot-attach-14742fe8f5864ac6.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The SMBFS driver now supports the 'snapshot attach' feature. Special care + must be taken when attaching snapshots though, as writing to a snapshot + will corrupt the differencing image chain.