From: Tomoki Sekiyama Date: Sat, 19 Jul 2014 02:23:55 +0000 (-0400) Subject: Avoid OSError in get_blkdev_major_minor with network filesystems X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=38096b2405899adc63b7ee5f85a4d3b2a66991a7;p=openstack-build%2Fcinder-build.git Avoid OSError in get_blkdev_major_minor with network filesystems To avoid OSError (File not found) thrown for volumes on network filesystems during volume copy with CONF.volume_copy_bps_limit, this patch adds a check of whether the specified file is on the local block devices to get_blkdev_major_minor(). It also adds a testcase for get_blkdev_major_minor with a file on nfs and fixes it with a regular file. Change-Id: I0b725bba07ad632bfa0c922bfce1652efe59b033 Closes-Bug: 1348230 --- diff --git a/cinder/tests/test_utils.py b/cinder/tests/test_utils.py index ff7b8c7ee..1766a2745 100644 --- a/cinder/tests/test_utils.py +++ b/cinder/tests/test_utils.py @@ -584,18 +584,17 @@ class GenericUtilsTestCase(test.TestCase): mock_stat.return_value = stat_result dev = utils.get_blkdev_major_minor(test_device) self.assertEqual('253:7', dev) - mock_stat.aseert_called_once_with(test_device) + mock_stat.assert_called_once_with(test_device) @mock.patch('os.stat') @mock.patch.object(utils, 'execute') - def test_get_blkdev_major_minor_file(self, mock_exec, mock_stat): - + def _test_get_blkdev_major_minor_file(self, test_partition, + mock_exec, mock_stat): mock_exec.return_value = ( - 'Filesystem Size Used Avail Use% Mounted on\n' - '/dev/made_up_disk1 4096 2048 2048 50% /tmp\n', None) + 'Filesystem Size Used Avail Use%% Mounted on\n' + '%s 4096 2048 2048 50%% /tmp\n' % test_partition, None) test_file = '/tmp/file' - test_partition = '/dev/made_up_disk1' test_disk = '/dev/made_up_disk' class stat_result_file: @@ -620,11 +619,20 @@ class GenericUtilsTestCase(test.TestCase): mock_stat.side_effect = fake_stat dev = utils.get_blkdev_major_minor(test_file) + mock_stat.assert_any_call(test_file) + mock_exec.assert_called_once_with('df', test_file) + if test_partition.startswith('/'): + mock_stat.assert_any_call(test_partition) + mock_stat.assert_any_call(test_disk) + return dev + + def test_get_blkdev_major_minor_file(self): + dev = self._test_get_blkdev_major_minor_file('/dev/made_up_disk1') self.assertEqual('8:64', dev) - mock_exec.aseert_called_once_with(test_file) - mock_stat.aseert_called_once_with(test_file) - mock_stat.aseert_called_once_with(test_partition) - mock_stat.aseert_called_once_with(test_disk) + + def test_get_blkdev_major_minor_file_nfs(self): + dev = self._test_get_blkdev_major_minor_file('nfs-server:/export/path') + self.assertIsNone(dev) class MonkeyPatchTestCase(test.TestCase): diff --git a/cinder/utils.py b/cinder/utils.py index 0807e9464..45ffc123a 100644 --- a/cinder/utils.py +++ b/cinder/utils.py @@ -820,6 +820,9 @@ def get_blkdev_major_minor(path, lookup_for_file=True): # lookup the mounted disk which the file lies on out, _err = execute('df', path) devpath = out.split("\n")[1].split()[0] + if devpath[0] is not '/': + # the file is on a network file system + return None return get_blkdev_major_minor(devpath, False) else: msg = _("Unable to get a block device for file \'%s\'") % path