]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Avoid OSError in get_blkdev_major_minor with network filesystems
authorTomoki Sekiyama <tomoki.sekiyama@hds.com>
Sat, 19 Jul 2014 02:23:55 +0000 (22:23 -0400)
committerTomoki Sekiyama <tomoki.sekiyama@hds.com>
Thu, 24 Jul 2014 16:38:32 +0000 (12:38 -0400)
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

cinder/tests/test_utils.py
cinder/utils.py

index ff7b8c7ee07bbbb97e19a1f8cf63a1eda427a3bc..1766a2745e47b80a76876e6af47c758aa7eb34d9 100644 (file)
@@ -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):
index 0807e94647aabefd27b70d95c762c7ed580b0d6c..45ffc123a3868739838ec4e2ec8129dd73dcc2d8 100644 (file)
@@ -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