Merge "StorPool: wait for the device to be resized."

This commit is contained in:
Zuul 2020-02-19 17:11:03 +00:00 committed by Gerrit Code Review
commit 2a6e8d405e
2 changed files with 62 additions and 4 deletions

View File

@ -16,6 +16,8 @@
from __future__ import absolute_import from __future__ import absolute_import
import os import os
import time
import six import six
from oslo_log import log as logging from oslo_log import log as logging
@ -212,11 +214,27 @@ class StorPoolConnector(base.BaseLinuxConnector):
# should have picked up the change already, so it is enough to query # should have picked up the change already, so it is enough to query
# the actual disk device to see if its size is correct. # the actual disk device to see if its size is correct.
# #
# TODO(pp): query the API to see if this is really the case
volume_id = connection_properties.get('volume', None) volume_id = connection_properties.get('volume', None)
if volume_id is None: if volume_id is None:
raise exception.BrickException( raise exception.BrickException(
'Invalid StorPool connection data, no volume ID specified.') 'Invalid StorPool connection data, no volume ID specified.')
# Get the expected (new) size from the StorPool API
volume = self._attach.volumeName(volume_id) volume = self._attach.volumeName(volume_id)
LOG.debug('Querying the StorPool API for the size of %(vol)s',
{'vol': volume})
vdata = self._attach.api().volumeList(volume)[0]
LOG.debug('Got size %(size)d', {'size': vdata.size})
# Wait for the StorPool client to update the size of the local device
path = '/dev/storpool/' + volume path = '/dev/storpool/' + volume
return self._get_device_size(path) for _ in range(10):
size = self._get_device_size(path)
LOG.debug('Got local size %(size)d', {'size': size})
if size == vdata.size:
return size
time.sleep(0.1)
else:
size = self._get_device_size(path)
LOG.debug('Last attempt: local size %(size)d', {'size': size})
return size

View File

@ -79,13 +79,16 @@ class StorPoolConnectorTestCase(test_connector.ConnectorTestCase):
def volumeName(self, vid): def volumeName(self, vid):
return volumeNameExt(vid) return volumeNameExt(vid)
def get_fake_size(self):
return self.fakeSize
def execute(self, *cmd, **kwargs): def execute(self, *cmd, **kwargs):
if cmd[0] == 'blockdev': if cmd[0] == 'blockdev':
self.assertEqual(len(cmd), 3) self.assertEqual(len(cmd), 3)
self.assertEqual(cmd[1], '--getsize64') self.assertEqual(cmd[1], '--getsize64')
self.assertEqual(cmd[2], '/dev/storpool/' + self.assertEqual(cmd[2], '/dev/storpool/' +
self.volumeName(self.fakeProp['volume'])) self.volumeName(self.fakeProp['volume']))
return (str(self.fakeSize) + '\n', None) return (str(self.get_fake_size()) + '\n', None)
raise Exception("Unrecognized command passed to " + raise Exception("Unrecognized command passed to " +
type(self).__name__ + ".execute(): " + type(self).__name__ + ".execute(): " +
str.join(", ", map(lambda s: "'" + s + "'", cmd))) str.join(", ", map(lambda s: "'" + s + "'", cmd)))
@ -148,5 +151,42 @@ class StorPoolConnectorTestCase(test_connector.ConnectorTestCase):
self.test_connect_volume() self.test_connect_volume()
self.fakeSize += 1024 * 1024 * 1024 self.fakeSize += 1024 * 1024 * 1024
newSize = self.connector.extend_volume(self.fakeProp)
size_list = [self.fakeSize, self.fakeSize - 1, self.fakeSize - 2]
vdata = mock.MagicMock(spec=['size'])
vdata.size = self.fakeSize
vdata_list = [[vdata]]
def fake_volume_list(name):
self.assertEqual(
name,
self.adb.volumeName(self.fakeProp['volume'])
)
return vdata_list.pop()
api = mock.MagicMock(spec=['volumeList'])
api.volumeList = mock.MagicMock(spec=['__call__'])
with mock.patch.object(
self.adb, attribute='api', spec=['__call__']
) as fake_api, mock.patch.object(
self, attribute='get_fake_size', spec=['__call__']
) as fake_size, mock.patch('time.sleep') as fake_sleep:
fake_api.return_value = api
api.volumeList.side_effect = fake_volume_list
fake_size.side_effect = size_list.pop
newSize = self.connector.extend_volume(self.fakeProp)
self.assertEqual(fake_api.call_count, 1)
self.assertEqual(api.volumeList.call_count, 1)
self.assertListEqual(vdata_list, [])
self.assertEqual(fake_size.call_count, 3)
self.assertListEqual(size_list, [])
self.assertEqual(fake_sleep.call_count, 2)
self.assertEqual(newSize, self.fakeSize) self.assertEqual(newSize, self.fakeSize)