add retry logic to is_block_device function

In testing the os.stat command was throwing a unhandled exception.
This Patch adds a try block around the os.stat command and if unable
to execute with out error in "CONF.deploy.iscsi_verify_attempts"
it rasies InstanceDeployFailure

Change-Id: Ibf5483435b02fab64bd4f0d368326b9ecbb4cc07
Closes-bug: #1417307
This commit is contained in:
Chris Krelle 2015-02-17 21:28:03 -08:00
parent 6901c8bfa5
commit 271c773e74
2 changed files with 33 additions and 2 deletions

View File

@ -240,8 +240,21 @@ def make_partitions(dev, root_mb, swap_mb, ephemeral_mb,
def is_block_device(dev):
"""Check whether a device is block or not."""
s = os.stat(dev)
return stat.S_ISBLK(s.st_mode)
attempts = CONF.deploy.iscsi_verify_attempts
for attempt in range(attempts):
try:
s = os.stat(dev)
except OSError as e:
LOG.debug("Unable to stat device %(dev)s. Attempt %(attempt)d "
"out of %(total)d. Error: %(err)s", {"dev": dev,
"attempt": attempt + 1, "total": attempts, "err": e})
time.sleep(1)
else:
return stat.S_ISBLK(s.st_mode)
msg = _("Unable to stat device %(dev)s after attempting to verify "
"%(attempts)d times.") % {'dev': dev, 'attempts': attempts}
LOG.error(msg)
raise exception.InstanceDeployFailure(msg)
def dd(src, dst):

View File

@ -18,6 +18,7 @@ import base64
import gzip
import os
import shutil
import stat
import tempfile
import fixtures
@ -638,6 +639,23 @@ class OtherFunctionTestCase(tests_base.TestCase):
actual = utils.get_dev('1.2.3.4', 5678, 'iqn.fake', 9)
self.assertEqual(expected, actual)
@mock.patch.object(os, 'stat')
@mock.patch.object(stat, 'S_ISBLK')
def test_is_block_device_works(self, mock_is_blk, mock_os):
device = '/dev/disk/by-path/ip-1.2.3.4:5678-iscsi-iqn.fake-lun-9'
mock_is_blk.return_value = True
mock_os().st_mode = 10000
self.assertTrue(utils.is_block_device(device))
mock_is_blk.assert_called_once_with(mock_os().st_mode)
@mock.patch.object(os, 'stat')
def test_is_block_device_raises(self, mock_os):
device = '/dev/disk/by-path/ip-1.2.3.4:5678-iscsi-iqn.fake-lun-9'
mock_os.side_effect = OSError
self.assertRaises(exception.InstanceDeployFailure,
utils.is_block_device, device)
mock_os.assert_has_calls([mock.call(device)] * 3)
@mock.patch.object(os.path, 'getsize')
@mock.patch.object(images, 'converted_size')
def test_get_image_mb(self, mock_csize, mock_getsize):