@@ -8847,7 +8847,7 @@ def _rollback_volume_bdms(self, context, bdms, original_bdms, instance):
8847
8847
@wrap_instance_fault
8848
8848
def _rollback_live_migration(self, context, instance,
8849
8849
dest, migrate_data=None,
8850
- migration_status='error ',
8850
+ migration_status='failed ',
8851
8851
source_bdms=None):
8852
8852
"""Recovers Instance/volume state from migrating -> running.
8853
8853
@@ -8988,9 +8988,8 @@ def _rollback_live_migration(self, context, instance,
8988
8988
phase=fields.NotificationPhase.END,
8989
8989
bdms=bdms)
8990
8990
8991
- # TODO(luyao): set migration status to 'failed' but not 'error'
8992
- # which means rollback_live_migration is done, we have successfully
8993
- # cleaned up and returned instance back to normal status.
8991
+ # NOTE(luyao): we have cleanup everything and get instance
8992
+ # back to normal status, now set migration status to 'failed'
8994
8993
self._set_migration_status(migration, migration_status)
8995
8994
8996
8995
@wrap_exception()
@@ -10508,11 +10507,14 @@ def _run_pending_deletes(self, context):
10508
10507
10509
10508
@periodic_task.periodic_task(spacing=CONF.instance_delete_interval)
10510
10509
def _cleanup_incomplete_migrations(self, context):
10511
- """Delete instance files on failed resize/revert-resize operation
10512
-
10513
- During resize/revert-resize operation, if that instance gets deleted
10514
- in-between then instance files might remain either on source or
10515
- destination compute node because of race condition.
10510
+ """Cleanup on failed resize/revert-resize operation and
10511
+ failed rollback live migration operation.
10512
+
10513
+ During resize/revert-resize operation, or after a failed rollback
10514
+ live migration operation, if that instance gets deleted then instance
10515
+ files might remain either on source or destination compute node and
10516
+ other specific resources might not be cleaned up because of the race
10517
+ condition.
10516
10518
"""
10517
10519
LOG.debug('Cleaning up deleted instances with incomplete migration ')
10518
10520
migration_filters = {'host': CONF.host,
@@ -10534,21 +10536,29 @@ def _cleanup_incomplete_migrations(self, context):
10534
10536
context, inst_filters, expected_attrs=attrs, use_slave=True)
10535
10537
10536
10538
for instance in instances:
10537
- if instance.host != CONF.host:
10538
- for migration in migrations:
10539
- if instance.uuid == migration.instance_uuid:
10540
- # Delete instance files if not cleanup properly either
10541
- # from the source or destination compute nodes when
10542
- # the instance is deleted during resizing.
10543
- self.driver.delete_instance_files(instance)
10544
- try:
10545
- migration.status = 'failed'
10546
- migration.save()
10547
- except exception.MigrationNotFound:
10548
- LOG.warning("Migration %s is not found.",
10549
- migration.id,
10550
- instance=instance)
10551
- break
10539
+ if instance.host == CONF.host:
10540
+ continue
10541
+ for migration in migrations:
10542
+ if instance.uuid != migration.instance_uuid:
10543
+ continue
10544
+ self.driver.delete_instance_files(instance)
10545
+ # we are not sure whether the migration_context is applied
10546
+ # during incompleted migrating, we need to apply/revert
10547
+ # migration_context to get instance object content matching
10548
+ # current host.
10549
+ revert = (True if migration.source_compute == CONF.host
10550
+ else False)
10551
+ with instance.mutated_migration_context(revert=revert):
10552
+ self.driver.cleanup_lingering_instance_resources(instance)
10553
+
10554
+ try:
10555
+ migration.status = 'failed'
10556
+ migration.save()
10557
+ except exception.MigrationNotFound:
10558
+ LOG.warning("Migration %s is not found.",
10559
+ migration.id,
10560
+ instance=instance)
10561
+ break
10552
10562
10553
10563
@messaging.expected_exceptions(exception.InstanceQuiesceNotSupported,
10554
10564
exception.QemuGuestAgentNotEnabled,
0 commit comments