Segment LUN clones in NetApp iSCSI
The NetApp ZAPI for clone_create and clone_start has a maximum size. This fix breaks the lun into consumable sizes for the ZAPI. Change-Id: Id4d0872c6099b7cfc73d806d772a3ae051a76b70 Closes-Bug: 1284182
This commit is contained in:
parent
d8cb56a045
commit
f0f52a0085
|
@ -340,6 +340,12 @@ class FakeDirectCMODEServerHandler(FakeHTTPRequestHandler):
|
|||
body = """<results status="passed"><lun-id-assigned>1
|
||||
</lun-id-assigned>
|
||||
</results>"""
|
||||
elif 'lun-get-geometry' == api:
|
||||
body = """<results status="passed"><bytes-per-sector>256
|
||||
</bytes-per-sector><cylinders>512</cylinders><max-resize-size>
|
||||
3221225472</max-resize-size><sectors-per-track>512
|
||||
</sectors-per-track><size>2147483648</size>
|
||||
<tracks-per-cylinder>256</tracks-per-cylinder></results>"""
|
||||
elif 'iscsi-service-get-iter' == api:
|
||||
body = """<results status="passed"><attributes-list>
|
||||
<iscsi-service-info>
|
||||
|
@ -636,6 +642,18 @@ class NetAppDirectCmodeISCSIDriverTestCase(test.TestCase):
|
|||
self.driver.delete_snapshot(self.snapshot)
|
||||
self.driver.delete_volume(self.volume)
|
||||
|
||||
def test_extend_vol_same_size(self):
|
||||
self.driver.create_volume(self.volume)
|
||||
self.driver.extend_volume(self.volume, self.volume['size'])
|
||||
|
||||
def test_extend_vol_direct_resize(self):
|
||||
self.driver.create_volume(self.volume)
|
||||
self.driver.extend_volume(self.volume, 3)
|
||||
|
||||
def test_extend_vol_sub_lun_clone(self):
|
||||
self.driver.create_volume(self.volume)
|
||||
self.driver.extend_volume(self.volume, 4)
|
||||
|
||||
|
||||
class NetAppDriverNegativeTestCase(test.TestCase):
|
||||
"""Test case for NetAppDriver"""
|
||||
|
|
|
@ -21,6 +21,7 @@ storage systems with installed iSCSI licenses.
|
|||
"""
|
||||
|
||||
import copy
|
||||
import math
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
|
@ -526,7 +527,7 @@ class NetAppDirectISCSIDriver(driver.ISCSIDriver):
|
|||
return lun
|
||||
|
||||
def _clone_lun(self, name, new_name, space_reserved='true',
|
||||
start_block=0, end_block=0, block_count=0):
|
||||
src_block=0, dest_block=0, block_count=0):
|
||||
"""Clone LUN with the given name to the new name."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -962,7 +963,7 @@ class NetAppDirectCmodeISCSIDriver(NetAppDirectISCSIDriver):
|
|||
return igroup_list
|
||||
|
||||
def _clone_lun(self, name, new_name, space_reserved='true',
|
||||
start_block=0, end_block=0, block_count=0):
|
||||
src_block=0, dest_block=0, block_count=0):
|
||||
"""Clone LUN with the given handle to the new name."""
|
||||
metadata = self._get_lun_attr(name, 'metadata')
|
||||
volume = metadata['Volume']
|
||||
|
@ -972,19 +973,31 @@ class NetAppDirectCmodeISCSIDriver(NetAppDirectISCSIDriver):
|
|||
'destination-path': new_name, 'space-reserve': space_reserved})
|
||||
if block_count > 0:
|
||||
block_ranges = NaElement("block-ranges")
|
||||
block_range = NaElement.create_node_with_children(
|
||||
'block-range',
|
||||
**{'source-block-number': str(start_block),
|
||||
'destination-block-number': str(end_block),
|
||||
'block-count': str(block_count)})
|
||||
block_ranges.add_child_elem(block_range)
|
||||
# zAPI can only handle 2^24 block ranges
|
||||
bc_limit = 2 ** 24 # 8GB
|
||||
segments = int(math.ceil(float(block_count) / float(bc_limit)))
|
||||
bc = block_count
|
||||
for segment in range(0, segments):
|
||||
if bc > bc_limit:
|
||||
block_count = bc_limit
|
||||
bc -= bc_limit
|
||||
else:
|
||||
block_count = bc
|
||||
block_range = NaElement.create_node_with_children(
|
||||
'block-range',
|
||||
**{'source-block-number': str(src_block),
|
||||
'destination-block-number': str(dest_block),
|
||||
'block-count': str(block_count)})
|
||||
block_ranges.add_child_elem(block_range)
|
||||
src_block = int(src_block) + int(block_count)
|
||||
dest_block = int(dest_block) + int(block_count)
|
||||
clone_create.add_child_elem(block_ranges)
|
||||
self.client.invoke_successfully(clone_create, True)
|
||||
LOG.debug(_("Cloned LUN with new name %s") % new_name)
|
||||
lun = self._get_lun_by_args(vserver=self.vserver, path='/vol/%s/%s'
|
||||
% (volume, new_name))
|
||||
if len(lun) == 0:
|
||||
msg = _("No clonned lun named %s found on the filer")
|
||||
msg = _("No cloned lun named %s found on the filer")
|
||||
raise exception.VolumeBackendAPIException(data=msg % (new_name))
|
||||
clone_meta = self._create_lun_meta(lun[0])
|
||||
self._add_lun_to_table(NetAppLun('%s:%s' % (clone_meta['Vserver'],
|
||||
|
@ -1313,7 +1326,7 @@ class NetAppDirect7modeISCSIDriver(NetAppDirectISCSIDriver):
|
|||
return (igroup, lun_id)
|
||||
|
||||
def _clone_lun(self, name, new_name, space_reserved='true',
|
||||
start_block=0, end_block=0, block_count=0):
|
||||
src_block=0, dest_block=0, block_count=0):
|
||||
"""Clone LUN with the given handle to the new name."""
|
||||
metadata = self._get_lun_attr(name, 'metadata')
|
||||
path = metadata['Path']
|
||||
|
@ -1325,12 +1338,24 @@ class NetAppDirect7modeISCSIDriver(NetAppDirectISCSIDriver):
|
|||
'no-snap': 'true'})
|
||||
if block_count > 0:
|
||||
block_ranges = NaElement("block-ranges")
|
||||
block_range = NaElement.create_node_with_children(
|
||||
'block-range',
|
||||
**{'source-block-number': str(start_block),
|
||||
'destination-block-number': str(end_block),
|
||||
'block-count': str(block_count)})
|
||||
block_ranges.add_child_elem(block_range)
|
||||
# zAPI can only handle 2^24 block ranges
|
||||
bc_limit = 2 ** 24 # 8GB
|
||||
segments = int(math.ceil(float(block_count) / float(bc_limit)))
|
||||
bc = block_count
|
||||
for segment in range(0, segments):
|
||||
if bc > bc_limit:
|
||||
block_count = bc_limit
|
||||
bc -= bc_limit
|
||||
else:
|
||||
block_count = bc
|
||||
block_range = NaElement.create_node_with_children(
|
||||
'block-range',
|
||||
**{'source-block-number': str(src_block),
|
||||
'destination-block-number': str(dest_block),
|
||||
'block-count': str(block_count)})
|
||||
block_ranges.add_child_elem(block_range)
|
||||
src_block = int(src_block) + int(block_count)
|
||||
dest_block = int(dest_block) + int(block_count)
|
||||
clone_start.add_child_elem(block_ranges)
|
||||
result = self.client.invoke_successfully(clone_start, True)
|
||||
clone_id_el = result.get_child_by_name('clone-id')
|
||||
|
|
Loading…
Reference in New Issue