[NetApp] LUN space allocation support
Space allocation is an important NetApp driver specific feature. This needs to be set when the cinder volume is created. This is not related to thin/thick provisioning feature of cinder volumes.It is independent of that. It enables ONTAP to reclaim space automatically when host deletes data.This helps ONTAP and host to see the actual space correctly when the host deletes data. It also helps to keep a LUN (cinder volume) online when the LUN (cinder volume) in ontap runs out of space and containing volume (in ONTAP) cannot automatically grow more space. User can configure it by using volume type extra spec. By default Space allocation value is disabled for ONTAP LUN netapp:space_allocation: "<is> True" # to enable space allocation netapp:space_allocation: "<is> False" # to disable space allocation Blueprint: netapp-space-allocation-support Change-Id: Ib7072f3093067ecd8ad84e396aaecec8f15c49ba
This commit is contained in:
parent
0425c08f3d
commit
48d922cf62
@ -2347,6 +2347,9 @@ LUN_GET_ITER_RESULT = [
|
||||
'OsType': LUN_GET_ITER_REST['records'][0]['os_type'],
|
||||
'SpaceReserved':
|
||||
LUN_GET_ITER_REST['records'][0]['space']['guarantee']['requested'],
|
||||
'SpaceAllocated':
|
||||
LUN_GET_ITER_REST['records'][0]['space']
|
||||
['scsi_thin_provisioning_support_enabled'],
|
||||
'UUID': LUN_GET_ITER_REST['records'][0]['uuid'],
|
||||
},
|
||||
{
|
||||
@ -2360,6 +2363,9 @@ LUN_GET_ITER_RESULT = [
|
||||
'OsType': LUN_GET_ITER_REST['records'][1]['os_type'],
|
||||
'SpaceReserved':
|
||||
LUN_GET_ITER_REST['records'][1]['space']['guarantee']['requested'],
|
||||
'SpaceAllocated':
|
||||
LUN_GET_ITER_REST['records'][1]['space']
|
||||
['scsi_thin_provisioning_support_enabled'],
|
||||
'UUID': LUN_GET_ITER_REST['records'][1]['uuid'],
|
||||
},
|
||||
]
|
||||
|
@ -55,7 +55,8 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
self.fake_volume = six.text_type(uuid.uuid4())
|
||||
self.fake_lun = six.text_type(uuid.uuid4())
|
||||
self.fake_size = '1024'
|
||||
self.fake_metadata = {'OsType': 'linux', 'SpaceReserved': 'true'}
|
||||
self.fake_metadata = {'OsType': 'linux', 'SpaceReserved': 'true',
|
||||
'SpaceAllocated': 'true'}
|
||||
self.mock_send_request = self.mock_object(
|
||||
self.client.connection, 'send_request')
|
||||
|
||||
@ -89,14 +90,23 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
self.assertIsNone(self.client.check_is_naelement(element))
|
||||
self.assertRaises(ValueError, self.client.check_is_naelement, None)
|
||||
|
||||
@ddt.data({'ontap_version': (9, 4, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 4, 0), 'space_reservation': 'false'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'false'})
|
||||
@ddt.data({'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'}, )
|
||||
@ddt.unpack
|
||||
def test_create_lun(self, ontap_version, space_reservation):
|
||||
def test_create_lun(self, ontap_version, space_reservation, space_alloc):
|
||||
expected_path = '/vol/%s/%s' % (self.fake_volume, self.fake_lun)
|
||||
self.fake_metadata['SpaceReserved'] = space_reservation
|
||||
self.fake_metadata['SpaceAllocated'] = space_alloc
|
||||
expected_space_reservation = space_reservation
|
||||
self.mock_object(self.client, 'get_ontap_version',
|
||||
return_value=ontap_version)
|
||||
@ -127,7 +137,9 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
'size': initial_size,
|
||||
'ostype': self.fake_metadata['OsType'],
|
||||
'space-reservation-enabled':
|
||||
expected_space_reservation})
|
||||
expected_space_reservation,
|
||||
'space-allocation-enabled':
|
||||
space_alloc})
|
||||
self.connection.invoke_successfully.assert_called_with(
|
||||
mock.ANY, True)
|
||||
|
||||
@ -141,15 +153,25 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
else:
|
||||
mock_set_space_reservation.assert_not_called()
|
||||
|
||||
@ddt.data({'ontap_version': (9, 4, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 4, 0), 'space_reservation': 'false'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'false'})
|
||||
@ddt.data({'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'}, )
|
||||
@ddt.unpack
|
||||
def test_create_lun_exact_size(self, ontap_version, space_reservation):
|
||||
def test_create_lun_exact_size(self, ontap_version,
|
||||
space_reservation, space_alloc):
|
||||
expected_path = '/vol/%s/%s' % (self.fake_volume, self.fake_lun)
|
||||
self.connection.get_api_version.return_value = (1, 110)
|
||||
self.fake_metadata['SpaceReserved'] = space_reservation
|
||||
self.fake_metadata['SpaceAllocated'] = space_alloc
|
||||
expected_space_reservation = self.fake_metadata['SpaceReserved']
|
||||
self.mock_object(self.client, 'get_ontap_version',
|
||||
return_value=ontap_version)
|
||||
@ -181,7 +203,9 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
'ostype': self.fake_metadata['OsType'],
|
||||
'use-exact-size': 'true',
|
||||
'space-reservation-enabled':
|
||||
expected_space_reservation})
|
||||
expected_space_reservation,
|
||||
'space-allocation-enabled':
|
||||
space_alloc})
|
||||
self.connection.invoke_successfully.assert_called_with(
|
||||
mock.ANY, True)
|
||||
|
||||
@ -195,18 +219,27 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
else:
|
||||
mock_set_space_reservation.assert_not_called()
|
||||
|
||||
@ddt.data({'ontap_version': (9, 4, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 4, 0), 'space_reservation': 'false'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'true'},
|
||||
{'ontap_version': (9, 6, 0), 'space_reservation': 'false'})
|
||||
@ddt.data({'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 4, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'true',
|
||||
'space_alloc': 'true'},
|
||||
{'ontap_version': (9, 6, 0),
|
||||
'space_reservation': 'false',
|
||||
'space_alloc': 'false'}, )
|
||||
@ddt.unpack
|
||||
def test_create_lun_with_qos_policy_group_name(
|
||||
self, ontap_version, space_reservation):
|
||||
self, ontap_version, space_reservation, space_alloc):
|
||||
expected_path = '/vol/%s/%s' % (self.fake_volume, self.fake_lun)
|
||||
expected_qos_group_name = 'qos_1'
|
||||
mock_request = mock.Mock()
|
||||
|
||||
self.fake_metadata['SpaceReserved'] = space_reservation
|
||||
self.fake_metadata['SpaceAllocated'] = space_alloc
|
||||
expected_space_reservation = self.fake_metadata['SpaceReserved']
|
||||
self.mock_object(self.client, 'get_ontap_version',
|
||||
return_value=ontap_version)
|
||||
@ -239,7 +272,9 @@ class NetAppBaseClientTestCase(test.TestCase):
|
||||
**{'path': expected_path, 'size': initial_size,
|
||||
'ostype': self.fake_metadata['OsType'],
|
||||
'space-reservation-enabled':
|
||||
expected_space_reservation})
|
||||
expected_space_reservation,
|
||||
'space-allocation-enabled':
|
||||
space_alloc})
|
||||
mock_request.add_new_child.assert_called_with(
|
||||
'qos-policy-group', expected_qos_group_name)
|
||||
self.connection.invoke_successfully.assert_called_with(
|
||||
|
@ -854,6 +854,7 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
||||
'uuid': fake.UUID1,
|
||||
'fields': 'svm.name,location.volume.name,space.size,'
|
||||
'location.qtree.name,name,os_type,'
|
||||
'space.scsi_thin_provisioning_support_enabled,'
|
||||
'space.guarantee.requested,uuid'
|
||||
}
|
||||
|
||||
@ -884,6 +885,7 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
||||
'name': path,
|
||||
'fields': 'svm.name,location.volume.name,space.size,'
|
||||
'location.qtree.name,name,os_type,'
|
||||
'space.scsi_thin_provisioning_support_enabled,'
|
||||
'space.guarantee.requested,uuid'
|
||||
}
|
||||
|
||||
@ -1678,6 +1680,8 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
||||
'space.size': str(initial_size),
|
||||
'os_type': metadata['OsType'],
|
||||
'space.guarantee.requested': metadata['SpaceReserved'],
|
||||
'space.scsi_thin_provisioning_support_enabled':
|
||||
metadata['SpaceAllocated'],
|
||||
'qos_policy.name': fake.QOS_POLICY_GROUP_NAME
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,19 @@ JOB_UUID = 'fb132b04-6422-43ce-9451-ee819f0131a4'
|
||||
LUN_METADATA = {
|
||||
'OsType': None,
|
||||
'SpaceReserved': 'true',
|
||||
'SpaceAllocated': 'false',
|
||||
'Path': PATH,
|
||||
'Qtree': None,
|
||||
'Volume': POOL_NAME,
|
||||
}
|
||||
LUN_METADATA_WITH_SPACE_ALLOCATION = {
|
||||
'OsType': None,
|
||||
'SpaceReserved': 'true',
|
||||
'Path': PATH,
|
||||
'SpaceAllocated': 'true',
|
||||
'Qtree': None,
|
||||
'Volume': POOL_NAME,
|
||||
}
|
||||
NAMESPACE_METADATA = {
|
||||
'OsType': None,
|
||||
'Path': PATH_NAMESPACE,
|
||||
@ -239,6 +248,7 @@ ISCSI_VOLUME = {
|
||||
'name': 'fake_volume',
|
||||
'id': 'fake_id',
|
||||
'provider_auth': 'fake provider auth',
|
||||
'provider_location': 'iscsi:/dummy_path'
|
||||
}
|
||||
|
||||
ISCSI_LUN = {'name': ISCSI_VOLUME, 'lun_id': 42}
|
||||
@ -250,6 +260,7 @@ ISCSI_CONNECTION_PROPERTIES = {
|
||||
'auth_method': 'fake_method',
|
||||
'auth_password': 'auth',
|
||||
'auth_username': 'provider',
|
||||
'discard': True,
|
||||
'discovery_auth_method': 'fake_method',
|
||||
'discovery_auth_username': 'provider',
|
||||
'discovery_auth_password': 'auth',
|
||||
@ -289,7 +300,7 @@ IGROUP1 = {'initiator-group-os-type': 'linux',
|
||||
'initiator-group-name': IGROUP1_NAME}
|
||||
|
||||
QOS_SPECS = {}
|
||||
EXTRA_SPECS = {}
|
||||
EXTRA_SPECS = {'netapp:space_allocation': '<is> True'}
|
||||
MAX_THROUGHPUT = '21734278B/s'
|
||||
MIN_IOPS = '256iops'
|
||||
MAX_IOPS = '512iops'
|
||||
|
@ -136,22 +136,97 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.library._create_lun.assert_called_once_with(
|
||||
fake.POOL_NAME, fake.LUN_NAME, volume_size_in_bytes,
|
||||
fake.LUN_METADATA, fake.QOS_POLICY_GROUP_NAME, False)
|
||||
fake.LUN_METADATA,
|
||||
fake.QOS_POLICY_GROUP_NAME, False)
|
||||
self.library._get_volume_model_update.assert_called_once_with(
|
||||
fake.VOLUME)
|
||||
self.assertEqual(
|
||||
0, self.library. _mark_qos_policy_group_for_deletion.call_count)
|
||||
self.assertEqual(0, block_base.LOG.error.call_count)
|
||||
|
||||
def test_create_volume_space_allocation_extra_spec_false(self):
|
||||
volume_size_in_bytes = int(fake.SIZE) * units.Gi
|
||||
self.mock_object(na_utils, 'get_volume_extra_specs',
|
||||
return_value={
|
||||
'netapp:space_allocation': '<is> False'
|
||||
}
|
||||
)
|
||||
self.mock_object(na_utils, 'log_extra_spec_warnings')
|
||||
self.mock_object(block_base, 'LOG')
|
||||
self.mock_object(volume_utils, 'extract_host',
|
||||
return_value=fake.POOL_NAME)
|
||||
self.mock_object(self.library, '_setup_qos_for_volume',
|
||||
return_value=fake.QOS_POLICY_GROUP_INFO)
|
||||
self.mock_object(self.library, '_create_lun')
|
||||
self.mock_object(self.library, '_create_lun_handle')
|
||||
self.mock_object(self.library, '_add_lun_to_table')
|
||||
self.mock_object(self.library, '_mark_qos_policy_group_for_deletion')
|
||||
self.mock_object(self.library, '_get_volume_model_update')
|
||||
|
||||
self.library.create_volume(fake.VOLUME)
|
||||
|
||||
self.library._create_lun.assert_called_once_with(
|
||||
fake.POOL_NAME, fake.LUN_NAME, volume_size_in_bytes,
|
||||
fake.LUN_METADATA,
|
||||
fake.QOS_POLICY_GROUP_NAME, False)
|
||||
self.library._get_volume_model_update.assert_called_once_with(
|
||||
fake.VOLUME)
|
||||
self.assertEqual(
|
||||
0, self.library._mark_qos_policy_group_for_deletion.call_count)
|
||||
self.assertEqual(0, block_base.LOG.error.call_count)
|
||||
|
||||
def test_create_volume_space_allocation_extra_spec_true(self):
|
||||
volume_size_in_bytes = int(fake.SIZE) * units.Gi
|
||||
self.mock_object(na_utils, 'get_volume_extra_specs',
|
||||
return_value={
|
||||
'netapp:space_allocation': '<is> True'
|
||||
}
|
||||
)
|
||||
self.mock_object(na_utils, 'log_extra_spec_warnings')
|
||||
self.mock_object(block_base, 'LOG')
|
||||
self.mock_object(volume_utils, 'extract_host',
|
||||
return_value=fake.POOL_NAME)
|
||||
self.mock_object(self.library, '_setup_qos_for_volume',
|
||||
return_value=fake.QOS_POLICY_GROUP_INFO)
|
||||
self.mock_object(self.library, '_create_lun')
|
||||
self.mock_object(self.library, '_create_lun_handle')
|
||||
self.mock_object(self.library, '_add_lun_to_table')
|
||||
self.mock_object(self.library, '_mark_qos_policy_group_for_deletion')
|
||||
self.mock_object(self.library, '_get_volume_model_update')
|
||||
|
||||
self.library.create_volume(fake.VOLUME)
|
||||
|
||||
self.library._create_lun.assert_called_once_with(
|
||||
fake.POOL_NAME, fake.LUN_NAME, volume_size_in_bytes,
|
||||
fake.LUN_METADATA_WITH_SPACE_ALLOCATION,
|
||||
fake.QOS_POLICY_GROUP_NAME, False)
|
||||
self.library._get_volume_model_update.assert_called_once_with(
|
||||
fake.VOLUME)
|
||||
self.assertEqual(
|
||||
0, self.library._mark_qos_policy_group_for_deletion.call_count)
|
||||
self.assertEqual(0, block_base.LOG.error.call_count)
|
||||
|
||||
def test_create_volume_no_pool(self):
|
||||
self.mock_object(volume_utils, 'extract_host', return_value=None)
|
||||
|
||||
self.assertRaises(exception.InvalidHost, self.library.create_volume,
|
||||
fake.VOLUME)
|
||||
|
||||
def test_space_allocation_exception_path(self):
|
||||
self.mock_object(block_base, 'LOG')
|
||||
self.mock_object(na_utils, 'get_volume_extra_specs',
|
||||
return_value={'netapp:space_allocation': 'xyz'})
|
||||
self.mock_object(self.library, '_setup_qos_for_volume',
|
||||
return_value=fake.QOS_POLICY_GROUP_INFO)
|
||||
self.mock_object(self.library, '_create_lun', side_effect=Exception)
|
||||
self.mock_object(self.library, '_mark_qos_policy_group_for_deletion')
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.library.create_volume, fake.VOLUME)
|
||||
|
||||
def test_create_volume_exception_path(self):
|
||||
self.mock_object(block_base, 'LOG')
|
||||
self.mock_object(na_utils, 'get_volume_extra_specs')
|
||||
self.mock_object(na_utils, 'get_volume_extra_specs',
|
||||
return_value={})
|
||||
self.mock_object(self.library, '_setup_qos_for_volume',
|
||||
return_value=fake.QOS_POLICY_GROUP_INFO)
|
||||
self.mock_object(self.library, '_create_lun', side_effect=Exception)
|
||||
@ -767,6 +842,9 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_get_targets_from_list',
|
||||
return_value=target_details_list)
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_is_space_alloc_enabled',
|
||||
return_value=True)
|
||||
self.zapi_client.get_iscsi_service_details.return_value = (
|
||||
fake.ISCSI_SERVICE_IQN)
|
||||
self.mock_object(na_utils,
|
||||
@ -796,6 +874,10 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
fake.ISCSI_CONNECTION_PROPERTIES['data']
|
||||
['discovery_auth_username'],
|
||||
target_info['data']['discovery_auth_username'])
|
||||
self.assertEqual(
|
||||
fake.ISCSI_CONNECTION_PROPERTIES['data']
|
||||
['discard'],
|
||||
target_info['data']['discard'])
|
||||
|
||||
self.assertEqual(fake.ISCSI_CONNECTION_PROPERTIES, target_info)
|
||||
block_base.NetAppBlockStorageLibrary._map_lun.assert_called_once_with(
|
||||
@ -815,6 +897,9 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
self.zapi_client.get_iscsi_target_details.return_value = None
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_get_targets_from_list')
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_is_space_alloc_enabled',
|
||||
return_value=True)
|
||||
self.mock_object(na_utils,
|
||||
'get_iscsi_connection_properties',
|
||||
return_value=fake.ISCSI_CONNECTION_PROPERTIES)
|
||||
@ -826,6 +911,9 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
self.assertEqual(
|
||||
0, block_base.NetAppBlockStorageLibrary
|
||||
._get_targets_from_list.call_count)
|
||||
self.assertEqual(
|
||||
0, block_base.NetAppBlockStorageLibrary
|
||||
._is_space_alloc_enabled.call_count)
|
||||
self.assertEqual(
|
||||
0, self.zapi_client.get_iscsi_service_details.call_count)
|
||||
self.assertEqual(
|
||||
@ -840,6 +928,9 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_get_targets_from_list',
|
||||
return_value=None)
|
||||
self.mock_object(block_base.NetAppBlockStorageLibrary,
|
||||
'_is_space_alloc_enabled',
|
||||
return_value=True)
|
||||
self.mock_object(na_utils, 'get_iscsi_connection_properties')
|
||||
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
@ -848,6 +939,9 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
|
||||
self.assertEqual(0, self.zapi_client
|
||||
.get_iscsi_service_details.call_count)
|
||||
self.assertEqual(0,
|
||||
block_base.NetAppBlockStorageLibrary
|
||||
._is_space_alloc_enabled.call_count)
|
||||
self.assertEqual(0, na_utils.get_iscsi_connection_properties
|
||||
.call_count)
|
||||
|
||||
|
@ -224,12 +224,17 @@ class NetAppBlockStorageLibrary(object):
|
||||
|
||||
extra_specs = na_utils.get_volume_extra_specs(volume)
|
||||
|
||||
space_allocation = volume_utils.is_boolean_str(
|
||||
extra_specs.get('netapp:space_allocation')
|
||||
)
|
||||
LOG.debug('create_volume space_allocation %r', space_allocation)
|
||||
lun_name = volume['name']
|
||||
|
||||
size = int(volume['size']) * units.Gi
|
||||
|
||||
metadata = {'OsType': self.lun_ostype,
|
||||
'SpaceReserved': self.lun_space_reservation,
|
||||
'SpaceAllocated': str(space_allocation).lower(),
|
||||
'Path': '/vol/%s/%s' % (pool_name, lun_name)}
|
||||
|
||||
qos_policy_group_info = self._setup_qos_for_volume(volume, extra_specs)
|
||||
@ -712,6 +717,16 @@ class NetAppBlockStorageLibrary(object):
|
||||
" post clone resize LUN %s.", seg[-1])
|
||||
LOG.error("Exception details: %s", e)
|
||||
|
||||
def _is_space_alloc_enabled(self, path):
|
||||
"""Gets space allocation details for the LUN."""
|
||||
LOG.debug("Getting LUN space allocation enabled.")
|
||||
lun_infos = self.zapi_client.get_lun_by_args(path=path)
|
||||
if not lun_infos:
|
||||
seg = path.split('/')
|
||||
msg = _('Failure getting LUN info for %s' % seg[-1])
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
return lun_infos[0]['SpaceAllocated'] == "true"
|
||||
|
||||
def _get_lun_block_count(self, path):
|
||||
"""Gets block counts for the LUN."""
|
||||
LOG.debug("Getting LUN block count.")
|
||||
@ -844,6 +859,7 @@ class NetAppBlockStorageLibrary(object):
|
||||
"""
|
||||
|
||||
initiator_name = connector['initiator']
|
||||
lun_path = volume['provider_location'].split(':')[1]
|
||||
name = volume['name']
|
||||
lun_id = self._map_lun(name, [initiator_name], 'iscsi', None)
|
||||
|
||||
@ -874,7 +890,7 @@ class NetAppBlockStorageLibrary(object):
|
||||
properties = na_utils.get_iscsi_connection_properties(lun_id, volume,
|
||||
iqn, addresses,
|
||||
ports)
|
||||
|
||||
properties['discard'] = self._is_space_alloc_enabled(lun_path)
|
||||
if self.configuration.use_chap_auth:
|
||||
chap_username, chap_password = self._configure_chap(initiator_name)
|
||||
self._add_chap_properties(properties, chap_username, chap_password)
|
||||
|
@ -130,6 +130,10 @@ class Client(object):
|
||||
params = {'path': path, 'size': str(initial_size),
|
||||
'ostype': metadata['OsType'],
|
||||
'space-reservation-enabled': space_reservation}
|
||||
|
||||
if "SpaceAllocated" in metadata:
|
||||
params['space-allocation-enabled'] = metadata['SpaceAllocated']
|
||||
|
||||
version = self.get_ontapi_version()
|
||||
if version >= (1, 110):
|
||||
params['use-exact-size'] = 'true'
|
||||
|
@ -545,6 +545,8 @@ class Client(client_base.Client):
|
||||
meta_dict['OsType'] = lun.get_child_content('multiprotocol-type')
|
||||
meta_dict['SpaceReserved'] = \
|
||||
lun.get_child_content('is-space-reservation-enabled')
|
||||
meta_dict['SpaceAllocated'] = \
|
||||
lun.get_child_content('is-space-alloc-enabled')
|
||||
meta_dict['UUID'] = lun.get_child_content('uuid')
|
||||
meta_dict['BlockSize'] = lun.get_child_content('block-size')
|
||||
return meta_dict
|
||||
|
@ -663,6 +663,7 @@ class RestClient(object):
|
||||
'svm.name': self.vserver,
|
||||
'fields': 'svm.name,location.volume.name,space.size,'
|
||||
'location.qtree.name,name,os_type,'
|
||||
'space.scsi_thin_provisioning_support_enabled,'
|
||||
'space.guarantee.requested,uuid'
|
||||
}
|
||||
|
||||
@ -683,6 +684,8 @@ class RestClient(object):
|
||||
lun_info['Path'] = lun['name']
|
||||
lun_info['OsType'] = lun['os_type']
|
||||
lun_info['SpaceReserved'] = lun['space']['guarantee']['requested']
|
||||
lun_info['SpaceAllocated'] = \
|
||||
lun['space']['scsi_thin_provisioning_support_enabled']
|
||||
lun_info['UUID'] = lun['uuid']
|
||||
|
||||
lun_list.append(lun_info)
|
||||
@ -695,6 +698,7 @@ class RestClient(object):
|
||||
query = {
|
||||
'fields': 'svm.name,location.volume.name,space.size,'
|
||||
'location.qtree.name,name,os_type,'
|
||||
'space.scsi_thin_provisioning_support_enabled,'
|
||||
'space.guarantee.requested,uuid'
|
||||
}
|
||||
|
||||
@ -723,6 +727,8 @@ class RestClient(object):
|
||||
lun_info['Path'] = lun['name']
|
||||
lun_info['OsType'] = lun['os_type']
|
||||
lun_info['SpaceReserved'] = lun['space']['guarantee']['requested']
|
||||
lun_info['SpaceAllocated'] = \
|
||||
lun['space']['scsi_thin_provisioning_support_enabled']
|
||||
lun_info['UUID'] = lun['uuid']
|
||||
|
||||
# NOTE(nahimsouza): Currently, ONTAP REST API does not have the
|
||||
@ -1305,13 +1311,15 @@ class RestClient(object):
|
||||
|
||||
path = f'/vol/{volume_name}/{lun_name}'
|
||||
space_reservation = metadata['SpaceReserved']
|
||||
space_allocation = metadata['SpaceAllocated']
|
||||
initial_size = size
|
||||
|
||||
body = {
|
||||
'name': path,
|
||||
'space.size': str(initial_size),
|
||||
'os_type': metadata['OsType'],
|
||||
'space.guarantee.requested': space_reservation
|
||||
'space.guarantee.requested': space_reservation,
|
||||
'space.scsi_thin_provisioning_support_enabled': space_allocation
|
||||
}
|
||||
|
||||
if qos_policy_group_name:
|
||||
|
@ -0,0 +1,9 @@
|
||||
features:
|
||||
- |
|
||||
NetApp iSCSI/FCP drivers: NetApp space allocation feature allows ONTAP
|
||||
and host to see the actual space correctly when host deletes data.
|
||||
It also notifies the host when the LUN cannot accept write data due
|
||||
to lack of space on the volume, and makes the LUN read-only
|
||||
(rather than going offline). This feature can be enabled or
|
||||
disabled on cinder volumes by using volume type extra specs with
|
||||
the ``netapp:space_allocation`` property.
|
Loading…
Reference in New Issue
Block a user