Browse Source

Stop filtering out 'accepted' for in-progress migrations

Live migrations are created with an 'accepted' status. Resource claims
on the destination are done with the migration in 'accepted' status.
The status is set to 'preparing' a bit later, right before running
pre_live_migration(). Migrations with status 'accepted' are filtered
out by the database layer when getting in-progress migrations. Thus,
there's a time window after resource claims but before 'preparing'
during which resources have been claimed but the migration is not
considered in-progress by the database layer. During that window, the
instance's host is the source - that's only updated once the live
migration finishes. If the update available resources periodic task
runs during that window, it'll free the instance's resource from the
destination because neither the instance nor any of its in-progress
migrations are associated with the destination. This means that other
incoming instances are able to consume resources that should not be
available. This patch stops filtering out the 'accepted' status in the
database layer when retrieving in-progress migrations.

Change-Id: I4c56925ed35bc3275ca1ac6c30d7fd641ad84260
Closes-bug: 1845146
(cherry picked from commit 6ec686c26b)
changes/87/685387/2
Artom Lifshitz 3 years ago committed by Matt Riedemann
parent
commit
45c2ba37bc
  1. 8
      nova/db/sqlalchemy/api.py
  2. 5
      nova/tests/unit/db/test_db_api.py

8
nova/db/sqlalchemy/api.py

@ -4419,10 +4419,10 @@ def migration_get_in_progress_by_host_and_node(context, host, node):
models.Migration.source_node == node),
and_(models.Migration.dest_compute == host,
models.Migration.dest_node == node))).\
filter(~models.Migration.status.in_(['accepted', 'confirmed',
'reverted', 'error',
'failed', 'completed',
'cancelled', 'done'])).\
filter(~models.Migration.status.in_(['confirmed', 'reverted',
'error', 'failed',
'completed', 'cancelled',
'done'])).\
options(_joinedload_all('instance.system_metadata')).\
all()

5
nova/tests/unit/db/test_db_api.py

@ -1153,7 +1153,6 @@ class MigrationTestCase(test.TestCase):
self.assertNotEqual('reverted', migration['status'])
self.assertNotEqual('error', migration['status'])
self.assertNotEqual('failed', migration['status'])
self.assertNotEqual('accepted', migration['status'])
self.assertNotEqual('done', migration['status'])
self.assertNotEqual('cancelled', migration['status'])
@ -1169,7 +1168,7 @@ class MigrationTestCase(test.TestCase):
migrations = db.migration_get_in_progress_by_host_and_node(self.ctxt,
'host1', 'a')
# 2 as source + 1 as dest
self.assertEqual(3, len(migrations))
self.assertEqual(4, len(migrations))
self._assert_in_progress(migrations)
def test_in_progress_host1_nodeb(self):
@ -1182,7 +1181,7 @@ class MigrationTestCase(test.TestCase):
migrations = db.migration_get_in_progress_by_host_and_node(self.ctxt,
'host2', 'b')
# 2 as dest, 1 as source
self.assertEqual(3, len(migrations))
self.assertEqual(4, len(migrations))
self._assert_in_progress(migrations)
def test_instance_join(self):

Loading…
Cancel
Save