summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-06-10 17:44:47 +0000
committerGerrit Code Review <review@openstack.org>2017-06-10 17:44:47 +0000
commit7c30084d848bb45f713f5dd74988725578334150 (patch)
tree0e8bc91b9a5a3f236115e1ab3974df5adb7ea65d
parentc4fd270609af207e0ab422b980dd74d5e551a09f (diff)
parentef853e038d9a3e9bfe02287c7c01c80b7a022ed6 (diff)
Merge "Use VIR_DOMAIN_BLOCK_REBASE_COPY_DEV when rebasing" into stable/ocata
-rw-r--r--nova/tests/unit/virt/libvirt/fakelibvirt.py1
-rw-r--r--nova/tests/unit/virt/libvirt/test_driver.py52
-rw-r--r--nova/tests/unit/virt/libvirt/test_guest.py6
-rw-r--r--nova/virt/libvirt/driver.py16
-rw-r--r--nova/virt/libvirt/guest.py4
5 files changed, 66 insertions, 13 deletions
diff --git a/nova/tests/unit/virt/libvirt/fakelibvirt.py b/nova/tests/unit/virt/libvirt/fakelibvirt.py
index 99a5544..f6555fd 100644
--- a/nova/tests/unit/virt/libvirt/fakelibvirt.py
+++ b/nova/tests/unit/virt/libvirt/fakelibvirt.py
@@ -53,6 +53,7 @@ VIR_DOMAIN_XML_MIGRATABLE = 8
53VIR_DOMAIN_BLOCK_REBASE_SHALLOW = 1 53VIR_DOMAIN_BLOCK_REBASE_SHALLOW = 1
54VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT = 2 54VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT = 2
55VIR_DOMAIN_BLOCK_REBASE_COPY = 8 55VIR_DOMAIN_BLOCK_REBASE_COPY = 8
56VIR_DOMAIN_BLOCK_REBASE_COPY_DEV = 32
56 57
57VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC = 1 58VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC = 1
58VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT = 2 59VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT = 2
diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index c4b4328..b67f9aa 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -14745,7 +14745,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
14745 save.assert_called_once_with() 14745 save.assert_called_once_with()
14746 14746
14747 @mock.patch('nova.virt.libvirt.guest.BlockDevice.is_job_complete') 14747 @mock.patch('nova.virt.libvirt.guest.BlockDevice.is_job_complete')
14748 def test_swap_volume(self, mock_is_job_complete): 14748 def test_swap_volume_file(self, mock_is_job_complete):
14749 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI()) 14749 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
14750 14750
14751 mock_dom = mock.MagicMock() 14751 mock_dom = mock.MagicMock()
@@ -14761,7 +14761,10 @@ class LibvirtConnTestCase(test.NoDBTestCase):
14761 mock_dom.isPersistent.return_value = True 14761 mock_dom.isPersistent.return_value = True
14762 mock_is_job_complete.return_value = True 14762 mock_is_job_complete.return_value = True
14763 14763
14764 drvr._swap_volume(guest, srcfile, dstfile, 1) 14764 drvr._swap_volume(guest, srcfile,
14765 mock.MagicMock(source_type='file',
14766 source_path=dstfile),
14767 1)
14765 14768
14766 mock_dom.XMLDesc.assert_called_once_with( 14769 mock_dom.XMLDesc.assert_called_once_with(
14767 flags=(fakelibvirt.VIR_DOMAIN_XML_INACTIVE | 14770 flags=(fakelibvirt.VIR_DOMAIN_XML_INACTIVE |
@@ -14774,6 +14777,44 @@ class LibvirtConnTestCase(test.NoDBTestCase):
14774 srcfile, 1 * units.Gi / units.Ki) 14777 srcfile, 1 * units.Gi / units.Ki)
14775 mock_define.assert_called_once_with(xmldoc) 14778 mock_define.assert_called_once_with(xmldoc)
14776 14779
14780 @mock.patch('nova.virt.libvirt.guest.BlockDevice.is_job_complete')
14781 def test_swap_volume_block(self, mock_is_job_complete):
14782 """If the swapped volume is type="block", make sure that we give
14783 libvirt the correct VIR_DOMAIN_BLOCK_REBASE_COPY_DEV flag to ensure the
14784 correct type="block" XML is generated (bug 1691195)
14785 """
14786 drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
14787
14788 mock_dom = mock.MagicMock()
14789 guest = libvirt_guest.Guest(mock_dom)
14790
14791 with mock.patch.object(drvr._conn, 'defineXML',
14792 create=True) as mock_define:
14793 xmldoc = "<domain/>"
14794 srcfile = "/first/path"
14795 dstfile = "/second/path"
14796
14797 mock_dom.XMLDesc.return_value = xmldoc
14798 mock_dom.isPersistent.return_value = True
14799 mock_is_job_complete.return_value = True
14800
14801 drvr._swap_volume(guest, srcfile,
14802 mock.MagicMock(source_type='block',
14803 source_path=dstfile),
14804 1)
14805
14806 mock_dom.XMLDesc.assert_called_once_with(
14807 flags=(fakelibvirt.VIR_DOMAIN_XML_INACTIVE |
14808 fakelibvirt.VIR_DOMAIN_XML_SECURE))
14809 mock_dom.blockRebase.assert_called_once_with(
14810 srcfile, dstfile, 0, flags=(
14811 fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_COPY |
14812 fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV |
14813 fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))
14814 mock_dom.blockResize.assert_called_once_with(
14815 srcfile, 1 * units.Gi / units.Ki)
14816 mock_define.assert_called_once_with(xmldoc)
14817
14777 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume') 14818 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._disconnect_volume')
14778 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume') 14819 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._swap_volume')
14779 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config') 14820 @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_config')
@@ -14807,8 +14848,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
14807 mock_dom.UUIDString.return_value = 'uuid' 14848 mock_dom.UUIDString.return_value = 'uuid'
14808 get_guest.return_value = guest 14849 get_guest.return_value = guest
14809 disk_info = {'bus': 'virtio', 'type': 'disk', 'dev': 'vdb'} 14850 disk_info = {'bus': 'virtio', 'type': 'disk', 'dev': 'vdb'}
14810 get_volume_config.return_value = mock.MagicMock( 14851 conf = mock.MagicMock(source_path='/fake-new-volume')
14811 source_path='/fake-new-volume') 14852 get_volume_config.return_value = conf
14812 14853
14813 conn.swap_volume(old_connection_info, new_connection_info, instance, 14854 conn.swap_volume(old_connection_info, new_connection_info, instance,
14814 '/dev/vdb', 1) 14855 '/dev/vdb', 1)
@@ -14816,8 +14857,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
14816 get_guest.assert_called_once_with(instance) 14857 get_guest.assert_called_once_with(instance)
14817 connect_volume.assert_called_once_with(new_connection_info, disk_info) 14858 connect_volume.assert_called_once_with(new_connection_info, disk_info)
14818 14859
14819 swap_volume.assert_called_once_with(guest, 'vdb', 14860 swap_volume.assert_called_once_with(guest, 'vdb', conf, 1)
14820 '/fake-new-volume', 1)
14821 disconnect_volume.assert_called_once_with(old_connection_info, 'vdb') 14861 disconnect_volume.assert_called_once_with(old_connection_info, 'vdb')
14822 14862
14823 def test_swap_volume_driver_source_is_volume(self): 14863 def test_swap_volume_driver_source_is_volume(self):
diff --git a/nova/tests/unit/virt/libvirt/test_guest.py b/nova/tests/unit/virt/libvirt/test_guest.py
index 780ad07..d2d341d 100644
--- a/nova/tests/unit/virt/libvirt/test_guest.py
+++ b/nova/tests/unit/virt/libvirt/test_guest.py
@@ -659,6 +659,12 @@ class GuestBlockTestCase(test.NoDBTestCase):
659 'vda', "foo", 0, 659 'vda', "foo", 0,
660 flags=fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE) 660 flags=fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE)
661 661
662 def test_rebase_copy_dev(self):
663 self.gblock.rebase("foo", copy_dev=True)
664 self.domain.blockRebase.assert_called_once_with(
665 'vda', "foo", 0,
666 flags=fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV)
667
662 def test_commit(self): 668 def test_commit(self):
663 self.gblock.commit("foo", "top") 669 self.gblock.commit("foo", "top")
664 self.domain.blockCommit.assert_called_once_with( 670 self.domain.blockCommit.assert_called_once_with(
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index bf44713..88fea16 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -1242,7 +1242,7 @@ class LibvirtDriver(driver.ComputeDriver):
1242 with excutils.save_and_reraise_exception(): 1242 with excutils.save_and_reraise_exception():
1243 self._disconnect_volume(connection_info, disk_dev) 1243 self._disconnect_volume(connection_info, disk_dev)
1244 1244
1245 def _swap_volume(self, guest, disk_path, new_path, resize_to): 1245 def _swap_volume(self, guest, disk_path, conf, resize_to):
1246 """Swap existing disk with a new block device.""" 1246 """Swap existing disk with a new block device."""
1247 dev = guest.get_block_device(disk_path) 1247 dev = guest.get_block_device(disk_path)
1248 1248
@@ -1266,9 +1266,13 @@ class LibvirtDriver(driver.ComputeDriver):
1266 guest.delete_configuration(support_uefi) 1266 guest.delete_configuration(support_uefi)
1267 1267
1268 try: 1268 try:
1269 # Start copy with VIR_DOMAIN_REBASE_REUSE_EXT flag to 1269 # Start copy with VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT flag to
1270 # allow writing to existing external volume file 1270 # allow writing to existing external volume file. Use
1271 dev.rebase(new_path, copy=True, reuse_ext=True) 1271 # VIR_DOMAIN_BLOCK_REBASE_COPY_DEV if it's a block device to
1272 # make sure XML is generated correctly (bug 1691195)
1273 copy_dev = conf.source_type == 'block'
1274 dev.rebase(conf.source_path, copy=True, reuse_ext=True,
1275 copy_dev=copy_dev)
1272 while not dev.is_job_complete(): 1276 while not dev.is_job_complete():
1273 time.sleep(0.5) 1277 time.sleep(0.5)
1274 1278
@@ -1281,7 +1285,7 @@ class LibvirtDriver(driver.ComputeDriver):
1281 1285
1282 except Exception as exc: 1286 except Exception as exc:
1283 LOG.exception(_LE("Failure rebasing volume %(new_path)s on " 1287 LOG.exception(_LE("Failure rebasing volume %(new_path)s on "
1284 "%(new_path)s."), {'new_path': new_path, 1288 "%(new_path)s."), {'new_path': conf.source_path,
1285 'old_path': disk_path}) 1289 'old_path': disk_path})
1286 raise exception.VolumeRebaseFailed(reason=six.text_type(exc)) 1290 raise exception.VolumeRebaseFailed(reason=six.text_type(exc))
1287 1291
@@ -1318,7 +1322,7 @@ class LibvirtDriver(driver.ComputeDriver):
1318 raise NotImplementedError(_("Swap only supports host devices")) 1322 raise NotImplementedError(_("Swap only supports host devices"))
1319 1323
1320 try: 1324 try:
1321 self._swap_volume(guest, disk_dev, conf.source_path, resize_to) 1325 self._swap_volume(guest, disk_dev, conf, resize_to)
1322 except exception.VolumeRebaseFailed: 1326 except exception.VolumeRebaseFailed:
1323 with excutils.save_and_reraise_exception(): 1327 with excutils.save_and_reraise_exception():
1324 self._disconnect_volume(new_connection_info, disk_dev) 1328 self._disconnect_volume(new_connection_info, disk_dev)
diff --git a/nova/virt/libvirt/guest.py b/nova/virt/libvirt/guest.py
index 87a7d35..4d2e47e 100644
--- a/nova/virt/libvirt/guest.py
+++ b/nova/virt/libvirt/guest.py
@@ -726,7 +726,7 @@ class BlockDevice(object):
726 end=status['end']) 726 end=status['end'])
727 727
728 def rebase(self, base, shallow=False, reuse_ext=False, 728 def rebase(self, base, shallow=False, reuse_ext=False,
729 copy=False, relative=False): 729 copy=False, relative=False, copy_dev=False):
730 """Copy data from backing chain into a new disk 730 """Copy data from backing chain into a new disk
731 731
732 This copies data from backing file(s) into overlay(s), giving 732 This copies data from backing file(s) into overlay(s), giving
@@ -739,10 +739,12 @@ class BlockDevice(object):
739 pre-created 739 pre-created
740 :param copy: Start a copy job 740 :param copy: Start a copy job
741 :param relative: Keep backing chain referenced using relative names 741 :param relative: Keep backing chain referenced using relative names
742 :param copy_dev: Treat the destination as type="block"
742 """ 743 """
743 flags = shallow and libvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW or 0 744 flags = shallow and libvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW or 0
744 flags |= reuse_ext and libvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT or 0 745 flags |= reuse_ext and libvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT or 0
745 flags |= copy and libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY or 0 746 flags |= copy and libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY or 0
747 flags |= copy_dev and libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV or 0
746 flags |= relative and libvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE or 0 748 flags |= relative and libvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE or 0
747 return self._guest._domain.blockRebase( 749 return self._guest._domain.blockRebase(
748 self._disk, base, self.REBASE_DEFAULT_BANDWIDTH, flags=flags) 750 self._disk, base, self.REBASE_DEFAULT_BANDWIDTH, flags=flags)