SMBFS: add fixed image support

The SMBFS driver currently supports only dynamic vhd/x images.

This change will allow configuring the driver to use fixed images
using the 'nas_volume_prov_type' config option.

Note that fixed images will always be zeroed out. We recommend
placing the images on ReFS/SSD backed storage.

Implements: blueprint smbfs-fixed-images

Change-Id: Ic9e724fcda83fea384406f45f792f7a2d4b979bb
This commit is contained in:
AlexMuresan 2017-08-21 15:19:06 +03:00
parent 4cfc201b72
commit 54c2787132
5 changed files with 80 additions and 21 deletions

View File

@ -658,6 +658,8 @@ class RemoteFSPoolMixinTestCase(test.TestCase):
self._driver.driver_volume_type = mock.sentinel.driver_volume_type
self._driver._thin_provisioning_support = (
mock.sentinel.thin_prov_support)
self._driver._thick_provisioning_support = (
mock.sentinel.thick_prov_support)
self._driver.get_version = mock.Mock(
return_value=mock.sentinel.driver_version)
@ -681,6 +683,8 @@ class RemoteFSPoolMixinTestCase(test.TestCase):
self._driver.configuration.max_over_subscription_ratio),
'thin_provisioning_support': (
mock.sentinel.thin_prov_support),
'thick_provisioning_support': (
mock.sentinel.thick_prov_support),
'QoS_support': False,
}

View File

@ -398,23 +398,27 @@ class WindowsSmbFsTestCase(test.TestCase):
self._smbfs_driver.create_volume(self.volume)
mock_create_volume.assert_called_once_with(self.volume)
def _test_create_volume(self, volume_exists=False, volume_format='vhdx'):
self._smbfs_driver.create_dynamic_vhd = mock.MagicMock()
fake_create = self._smbfs_driver._vhdutils.create_dynamic_vhd
@mock.patch('os.path.exists')
@mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_vhd_type')
def _test_create_volume(self, mock_get_vhd_type, mock_exists,
volume_exists=False, volume_format='vhdx'):
mock_exists.return_value = volume_exists
self._smbfs_driver.create_vhd = mock.MagicMock()
fake_create = self._smbfs_driver._vhdutils.create_vhd
self._smbfs_driver.get_volume_format = mock.Mock(
return_value=volume_format)
with mock.patch('os.path.exists', new=lambda x: volume_exists):
volume = self._simple_volume()
if volume_exists or volume_format not in ('vhd', 'vhdx'):
self.assertRaises(exception.InvalidVolume,
self._smbfs_driver._do_create_volume,
volume)
else:
fake_vol_path = self._FAKE_VOLUME_PATH
self._smbfs_driver._do_create_volume(volume)
fake_create.assert_called_once_with(
fake_vol_path, volume.size << 30)
volume = self._simple_volume()
if volume_exists or volume_format not in ('vhd', 'vhdx'):
self.assertRaises(exception.InvalidVolume,
self._smbfs_driver._do_create_volume,
volume)
else:
fake_vol_path = self._FAKE_VOLUME_PATH
self._smbfs_driver._do_create_volume(volume)
fake_create.assert_called_once_with(
fake_vol_path, mock_get_vhd_type.return_value,
max_internal_size=volume.size << 30)
def test_create_volume(self):
self._test_create_volume()
@ -706,7 +710,8 @@ class WindowsSmbFsTestCase(test.TestCase):
mock.sentinel.context, mock.sentinel.image_service,
fake_image_meta, upload_path, fake_img_format)
def test_copy_image_to_volume(self):
@mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_vhd_type')
def test_copy_image_to_volume(self, mock_get_vhd_type):
drv = self._smbfs_driver
drv.get_volume_format = mock.Mock(
@ -728,13 +733,15 @@ class WindowsSmbFsTestCase(test.TestCase):
mock.sentinel.image_service,
mock.sentinel.image_id,
self._FAKE_VOLUME_PATH, mock.sentinel.volume_format,
mock.sentinel.block_size)
mock.sentinel.block_size,
mock_get_vhd_type.return_value)
drv._vhdutils.resize_vhd.assert_called_once_with(
self._FAKE_VOLUME_PATH,
volume.size * units.Gi,
is_file_max_size=False)
def test_copy_volume_from_snapshot(self):
@mock.patch.object(smbfs.WindowsSmbfsDriver, '_get_vhd_type')
def test_copy_volume_from_snapshot(self, mock_get_vhd_type):
drv = self._smbfs_driver
snapshot = self._simple_snapshot()
fake_volume_info = {
@ -760,7 +767,8 @@ class WindowsSmbFsTestCase(test.TestCase):
drv._delete.assert_called_once_with(mock.sentinel.new_volume_path)
drv._vhdutils.convert_vhd.assert_called_once_with(
self._FAKE_VOLUME_PATH,
mock.sentinel.new_volume_path)
mock.sentinel.new_volume_path,
vhd_type=mock_get_vhd_type.return_value)
drv._vhdutils.resize_vhd.assert_called_once_with(
mock.sentinel.new_volume_path,
volume.size * units.Gi,
@ -802,3 +810,12 @@ class WindowsSmbFsTestCase(test.TestCase):
self.assertRaises(exception.SmbfsException,
self._smbfs_driver._get_share_from_pool_name,
mock.sentinel.pool)
def test_get_vhd_type(self):
drv = self._smbfs_driver
mock_type = drv._get_vhd_type(qemu_subformat=True)
self.assertEqual(mock_type, 'dynamic')
mock_type = drv._get_vhd_type(qemu_subformat=False)
self.assertEqual(mock_type, 3)

View File

@ -149,6 +149,7 @@ class RemoteFSDriver(driver.BaseVD):
# We let the drivers inheriting this specify
# whether thin provisioning is supported or not.
_thin_provisioning_support = False
_thick_provisioning_support = False
def __init__(self, *args, **kwargs):
super(RemoteFSDriver, self).__init__(*args, **kwargs)
@ -1727,6 +1728,8 @@ class RemoteFSPoolMixin(object):
self.configuration.max_over_subscription_ratio),
'thin_provisioning_support': (
self._thin_provisioning_support),
'thick_provisioning_support': (
self._thick_provisioning_support),
'QoS_support': False,
}

View File

@ -17,6 +17,7 @@ import os
import sys
from os_brick.remotefs import windows_remotefs as remotefs_brick
from os_win import constants as os_win_const
from os_win import utilsfactory
from oslo_config import cfg
from oslo_log import log as logging
@ -117,6 +118,11 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
_always_use_temp_snap_when_cloning = False
_thin_provisioning_support = True
_vhd_type_mapping = {'thin': os_win_const.VHD_TYPE_DYNAMIC,
'thick': os_win_const.VHD_TYPE_FIXED}
_vhd_qemu_subformat_mapping = {'thin': 'dynamic',
'thick': 'fixed'}
def __init__(self, *args, **kwargs):
self._remotefsclient = None
super(WindowsSmbfsDriver, self).__init__(*args, **kwargs)
@ -134,6 +140,12 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
self._smbutils = utilsfactory.get_smbutils()
self._diskutils = utilsfactory.get_diskutils()
thin_enabled = (
CONF.backend_defaults.nas_volume_prov_type ==
'thin')
self._thin_provisioning_support = thin_enabled
self._thick_provisioning_support = not thin_enabled
def do_setup(self, context):
self._check_os_platform()
@ -329,7 +341,10 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
err_msg = _("Unsupported volume format: %s ") % volume_format
raise exception.InvalidVolume(err_msg)
self._vhdutils.create_dynamic_vhd(volume_path, volume_size_bytes)
vhd_type = self._get_vhd_type()
self._vhdutils.create_vhd(volume_path, vhd_type,
max_internal_size=volume_size_bytes)
def _ensure_share_mounted(self, smbfs_share):
mnt_flags = None
@ -520,12 +535,14 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
"""Fetch the image from image_service and write it to the volume."""
volume_path = self.local_path(volume)
volume_format = self.get_volume_format(volume, qemu_format=True)
volume_subformat = self._get_vhd_type(qemu_subformat=True)
self._delete(volume_path)
image_utils.fetch_to_volume_format(
context, image_service, image_id,
volume_path, volume_format,
self.configuration.volume_dd_blocksize)
self.configuration.volume_dd_blocksize,
volume_subformat)
self._vhdutils.resize_vhd(self.local_path(volume),
volume.size * units.Gi,
@ -553,9 +570,12 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
snapshot_path = os.path.join(vol_dir, img_info.backing_file)
volume_path = self.local_path(volume)
vhd_type = self._get_vhd_type()
self._delete(volume_path)
self._vhdutils.convert_vhd(snapshot_path,
volume_path)
volume_path,
vhd_type=vhd_type)
self._vhdutils.resize_vhd(volume_path, volume_size * units.Gi,
is_file_max_size=False)
@ -580,3 +600,13 @@ class WindowsSmbfsDriver(remotefs_drv.RemoteFSPoolMixin,
msg % dict(pool_name=pool_name,
pool_mappings=self._pool_mappings))
return share
def _get_vhd_type(self, qemu_subformat=False):
prov_type = CONF.backend_defaults.nas_volume_prov_type
if qemu_subformat:
vhd_type = self._vhd_qemu_subformat_mapping[prov_type]
else:
vhd_type = self._vhd_type_mapping[prov_type]
return vhd_type

View File

@ -0,0 +1,5 @@
---
features:
- |
The SMBFS volume driver can now be configured to use fixed vhd/x images
through the 'nas_volume_prov_type' config option.