Huawei: Add share sectorsize config in Huawei driver

Data in the file system consists of fixed-length disk blocks.
The size of the blocks (also known as file system sector size)
affects disk space usage and performance.
The value of blocks can be 4 KB, 8 KB, 16 KB, 32 KB, or 64 KB.

Change-Id: I95a9aa7e071c470c21dc0fa009ba96a7c7439ce6
Implements: blueprint huawei-driver-block-size-config
This commit is contained in:
liucheng 2016-05-17 12:47:27 +08:00
parent 5c961ab615
commit 96795787ae
6 changed files with 157 additions and 2 deletions

View File

@ -84,6 +84,7 @@ storage systems, the driver configuration file is as follows:
<Filesystem>
<StoragePool>xxxxxxxxx</StoragePool>
<AllocType>xxxxxxxx</AllocType>
<SectorSize>64</SectorSize>
<WaitInterval>3</WaitInterval>
<Timeout>60</Timeout>
<NFSClient>
@ -109,6 +110,11 @@ storage systems, the driver configuration file is as follows:
- `UserPassword` is a password of an administrator.
- `StoragePool` is a name of a storage pool to be used.
- `AllocType` is the file system space allocation type, optional value is "Thick" or "Thin".
- `SectorSize` is the size of the disk blocks, optional value can be "4", "8", "16", "32" or "64",
and the units is KB. If "sectorsize" is configured in both share_type and xml file, the value
of sectorsize in the share_type will be used. If "sectorsize" is configured in neither
share_type nor xml file, huawei storage backends will provide a default value(64) when creating
a new share.
- `WaitInterval` is the interval time of querying the file system status.
- `Timeout` is the timeout period for waiting command execution of a device to
complete.
@ -179,6 +185,8 @@ commit makes the Huawei driver report the following boolean capabilities:
* qos:latency
* qos:iotype
- capabilities:huawei_sectorsize
The scheduler will choose a host that supports the needed
capability when the CapabilityFilter is used and a share
type uses one or more of the following extra-specs:
@ -203,6 +211,10 @@ type uses one or more of the following extra-specs:
* qos:latency=10
* qos:iotype=0
- capabilities:huawei_sectorsize='<is> True' or '<is> False'
* huawei_sectorsize:sectorsize=4
`thin_provisioning` will be reported as [True, False] for Huawei backends.
`dedupe` will be reported as [True, False] for Huawei backends.
@ -221,6 +233,8 @@ ensuring the quality of critical services.
`qos` will be reported as True for backends that use QoS (Quality of Service)
specification.
`huawei_sectorsize` will be reported as [True, False] for Huawei backends.
Restrictions
------------

View File

@ -80,11 +80,13 @@ OPTS_CAPABILITIES = {
'huawei_smartpartition': False,
'thin_provisioning': None,
'qos': False,
'huawei_sectorsize': None,
}
OPTS_VALUE = {
'cachename': None,
'partitionname': None,
'sectorsize': None,
}
OPTS_VALUE.update(OPTS_QOS_VALUE)
@ -92,5 +94,8 @@ OPTS_VALUE.update(OPTS_QOS_VALUE)
OPTS_ASSOCIATE = {
'huawei_smartcache': 'cachename',
'huawei_smartpartition': 'partitionname',
'huawei_sectorsize': 'sectorsize',
'qos': OPTS_QOS_VALUE,
}
VALID_SECTOR_SIZES = ('4', '8', '16', '32', '64')

View File

@ -298,6 +298,7 @@ class V3StorageConnection(driver.HuaweiBase):
compression=[True, False],
huawei_smartcache=[True, False],
huawei_smartpartition=[True, False],
huawei_sectorsize=[True, False],
)
stats_dict["pools"].append(pool)
@ -630,6 +631,8 @@ class V3StorageConnection(driver.HuaweiBase):
' so dedupe or compression cannot be set.')
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)
if extra_specs['sectorsize']:
fileparam['SECTORSIZE'] = extra_specs['sectorsize'] * units.Ki
return fileparam

View File

@ -110,6 +110,7 @@ class SmartX(object):
opts = self.get_smartprovisioning_opts(opts)
opts = self.get_smartcache_opts(opts)
opts = self.get_smartpartition_opts(opts)
opts = self.get_sectorsize_opts(opts)
qos = self.get_qos_opts(opts)
return opts, qos
@ -170,6 +171,26 @@ class SmartX(object):
return opts
def get_sectorsize_opts(self, opts):
value = None
if strutils.bool_from_string(opts.get('huawei_sectorsize')):
value = opts.get('sectorsize')
if not value:
root = self.helper._read_xml()
sectorsize = root.findtext('Filesystem/SectorSize')
if sectorsize:
sectorsize = sectorsize.strip()
value = sectorsize
if value:
if value not in constants.VALID_SECTOR_SIZES:
raise exception.InvalidInput(
reason=(_('Illegal value(%s) specified for sectorsize: '
'set to either 4, 8, 16, 32 or 64.') % value))
else:
opts['sectorsize'] = int(value)
return opts
def get_qos_opts(self, opts):
qos = {}
if not strutils.bool_from_string(opts.get('qos')):

View File

@ -1160,6 +1160,11 @@ class HuaweiShareDriverTestCase(test.TestCase):
share = None
return share
def mock_share_type(self, share_type):
self.mock_object(db,
'share_type_get',
mock.Mock(return_value=share_type))
def test_conf_product_fail(self):
self.recreate_fake_conf_file(product_flag=False)
self.driver.plugin.configuration.manila_huawei_conf_file = (
@ -1374,6 +1379,99 @@ class HuaweiShareDriverTestCase(test.TestCase):
self.assertEqual(constants.ALLOC_TYPE_THICK_FLAG,
self.driver.plugin.helper.alloc_type)
@ddt.data(*constants.VALID_SECTOR_SIZES)
def test_create_share_with_sectorsize_in_type(self, sectorsize):
share_type = {
'extra_specs': {
'capabilities:huawei_sectorsize': "<is> true",
'huawei_sectorsize:sectorsize': sectorsize,
},
}
self.mock_share_type(share_type)
self.driver.plugin.helper.login()
location = self.driver.create_share(self._context, self.share_nfs,
self.share_server)
self.assertEqual("100.115.10.68:/share_fake_uuid", location)
self.assertTrue(db.share_type_get.called)
@ddt.data('128', 'xx', 'None', ' ')
def test_create_share_with_illegal_sectorsize_in_type(self, sectorsize):
share_type = {
'extra_specs': {
'capabilities:huawei_sectorsize': "<is> true",
'huawei_sectorsize:sectorsize': sectorsize,
},
}
self.mock_share_type(share_type)
self.driver.plugin.helper.login()
self.assertRaises(exception.InvalidShare,
self.driver.create_share,
self._context,
self.share_nfs,
self.share_server)
@ddt.data({'extra_specs': {'capabilities:huawei_sectorsize': "<is> false",
'huawei_sectorsize:sectorsize': '0'}, 'xmlvalue': '4'},
{'extra_specs': {'capabilities:huawei_sectorsize': "<is> False",
'huawei_sectorsize:sectorsize': '128'}, 'xmlvalue': '8'},
{'extra_specs': {'capabilities:huawei_sectorsize': "false",
'huawei_sectorsize:sectorsize': 'a'}, 'xmlvalue': '16'},
{'extra_specs': {'capabilities:huawei_sectorsize': "False",
'huawei_sectorsize:sectorsize': 'xx'}, 'xmlvalue': '32'},
{'extra_specs': {'capabilities:huawei_sectorsize': "true",
'huawei_sectorsize:sectorsize': 'None'}, 'xmlvalue': '64'},
{'extra_specs': {'capabilities:huawei_sectorsize': "True",
'huawei_sectorsize:sectorsize': ' '}, 'xmlvalue': ' '},
{'extra_specs': {'capabilities:huawei_sectorsize': "True",
'huawei_sectorsize:sectorsize': ''}, 'xmlvalue': ''})
@ddt.unpack
def test_create_share_with_invalid_type_valid_xml(self, extra_specs,
xmlvalue):
fake_share_type = {}
fake_share_type['extra_specs'] = extra_specs
self.mock_share_type(fake_share_type)
self.recreate_fake_conf_file(sectorsize_value=xmlvalue)
self.driver.plugin.configuration.manila_huawei_conf_file = (
self.fake_conf_file)
self.driver.plugin.helper.login()
location = self.driver.create_share(self._context, self.share_nfs,
self.share_server)
self.assertEqual("100.115.10.68:/share_fake_uuid", location)
self.assertTrue(db.share_type_get.called)
@ddt.data({'extra_specs': {'capabilities:huawei_sectorsize': "<is> false",
'huawei_sectorsize:sectorsize': '4'}, 'xmlvalue': '0'},
{'extra_specs': {'capabilities:huawei_sectorsize': "<is> False",
'huawei_sectorsize:sectorsize': '8'}, 'xmlvalue': '128'},
{'extra_specs': {'capabilities:huawei_sectorsize': "false",
'huawei_sectorsize:sectorsize': '16'}, 'xmlvalue': 'a'},
{'extra_specs': {'capabilities:huawei_sectorsize': "False",
'huawei_sectorsize:sectorsize': '32'}, 'xmlvalue': 'xx'},
{'extra_specs': {'capabilities:huawei_sectorsize': "true",
'huawei_sectorsize:sectorsize': '64'}, 'xmlvalue': 'None'})
@ddt.unpack
def test_create_share_with_invalid_type_illegal_xml(self, extra_specs,
xmlvalue):
fake_share_type = {}
fake_share_type['extra_specs'] = extra_specs
self.mock_share_type(fake_share_type)
self.recreate_fake_conf_file(sectorsize_value=xmlvalue)
self.driver.plugin.configuration.manila_huawei_conf_file = (
self.fake_conf_file)
self.driver.plugin.helper.login()
self.assertRaises(exception.InvalidShare,
self.driver.create_share,
self._context,
self.share_nfs,
self.share_server)
def test_shrink_share_success(self):
self.driver.plugin.helper.shrink_share_flag = False
self.driver.plugin.helper.login()
@ -2158,6 +2256,7 @@ class HuaweiShareDriverTestCase(test.TestCase):
thin_provisioning=[True, False],
huawei_smartcache=[True, False],
huawei_smartpartition=[True, False],
huawei_sectorsize=[True, False],
)
expected["pools"].append(pool)
self.assertEqual(expected, self.driver._stats)
@ -3475,6 +3574,7 @@ class HuaweiShareDriverTestCase(test.TestCase):
pool_node_flag=True, timeout_flag=True,
wait_interval_flag=True,
alloctype_value='Thick',
sectorsize_value='4',
multi_url=False,
logical_port='100.115.10.68'):
doc = xml.dom.minidom.Document()
@ -3584,6 +3684,12 @@ class HuaweiShareDriverTestCase(test.TestCase):
alloctype.appendChild(alloctype_text)
lun.appendChild(alloctype)
if sectorsize_value:
sectorsize = doc.createElement('SectorSize')
sectorsize_text = doc.createTextNode(sectorsize_value)
sectorsize.appendChild(sectorsize_text)
lun.appendChild(sectorsize)
prefetch = doc.createElement('Prefetch')
prefetch.setAttribute('Type', '0')
prefetch.setAttribute('Value', '0')
@ -3597,6 +3703,7 @@ class HuaweiShareDriverTestCase(test.TestCase):
pool_node_flag=True, timeout_flag=True,
wait_interval_flag=True,
alloctype_value='Thick',
sectorsize_value='4',
multi_url=False,
logical_port='100.115.10.68'):
self.tmp_dir = tempfile.mkdtemp()
@ -3605,6 +3712,6 @@ class HuaweiShareDriverTestCase(test.TestCase):
self.create_fake_conf_file(self.fake_conf_file, product_flag,
username_flag, pool_node_flag,
timeout_flag, wait_interval_flag,
alloctype_value, multi_url,
logical_port)
alloctype_value, sectorsize_value,
multi_url, logical_port)
self.addCleanup(os.remove, self.fake_conf_file)

View File

@ -0,0 +1,5 @@
---
features:
- Huawei driver supports setting the backend 'sectorsize' while creating shares
and administrators can use this capability via the share types extra-spec
'huawei_sectorsize:sectorsize' or via the XML configuration file.