diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index bdcb83deb2f1..e7edce3bf959 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -19985,9 +19985,10 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock.patch('nova.virt.libvirt.utils.get_disk_backing_file'), mock.patch('nova.virt.libvirt.utils.create_cow_image'), mock.patch('nova.virt.libvirt.utils.extract_snapshot'), - mock.patch.object(drvr, '_set_quiesced') + mock.patch.object(drvr, '_set_quiesced'), + mock.patch.object(drvr, '_can_quiesce') ) as (mock_define, mock_size, mock_backing, mock_create_cow, - mock_snapshot, mock_quiesce): + mock_snapshot, mock_quiesce, mock_can_quiesce): xmldoc = "" srcfile = "/first/path" @@ -20002,7 +20003,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, guest = libvirt_guest.Guest(mock_dom) if not can_quiesce: - mock_quiesce.side_effect = ( + mock_can_quiesce.side_effect = ( exception.InstanceQuiesceNotSupported( instance_id=self.test_instance['id'], reason='test')) @@ -20033,6 +20034,7 @@ class LibvirtConnTestCase(test.NoDBTestCase, mock_define.assert_called_once_with(xmldoc) mock_quiesce.assert_any_call(mock.ANY, self.test_instance, mock.ANY, True) + if can_quiesce: mock_quiesce.assert_any_call(mock.ANY, self.test_instance, mock.ANY, False) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 134f9d553d89..94e7b1945aa7 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -3271,14 +3271,15 @@ class LibvirtDriver(driver.ComputeDriver): libvirt_utils.create_cow_image(src_back_path, disk_delta, src_disk_size) - quiesced = False try: - self._set_quiesced(context, instance, image_meta, True) - quiesced = True + self._can_quiesce(instance, image_meta) except exception.NovaException as err: - if self._requires_quiesce(image_meta): + if image_meta.properties.get('os_require_quiesce', False): + LOG.error('Quiescing instance failed but image property ' + '"os_require_quiesce" is set: %(reason)s.', + {'reason': err}, instance=instance) raise - LOG.info('Skipping quiescing instance: %(reason)s.', + LOG.info('Quiescing instance not available: %(reason)s.', {'reason': err}, instance=instance) try: @@ -3299,12 +3300,24 @@ class LibvirtDriver(driver.ComputeDriver): while not dev.is_job_complete(): time.sleep(0.5) + finally: + quiesced = False + try: + # NOTE: The freeze FS is applied after the end of + # the mirroring of the disk to minimize the time of + # the freeze. The mirror between both disks is finished, + # sync continuously, and stopped after abort_job(). + self.quiesce(context, instance, image_meta) + quiesced = True + except exception.NovaException as err: + LOG.info('Skipping quiescing instance: %(reason)s.', + {'reason': err}, instance=instance) + dev.abort_job() nova.privsep.path.chown(disk_delta, uid=os.getuid()) - finally: self._host.write_instance_config(xml) if quiesced: - self._set_quiesced(context, instance, image_meta, False) + self.unquiesce(context, instance, image_meta) # Convert the delta (CoW) image with a backing file to a flat # image with no backing file.