Option to specify max servers for live evacuate

The current behaviour of live evacuate is to naively request that all
servers on the hypervisor be evacuated. The more VMs are migrated
simultaneously, the more bandwidth is required. Once a certain number
of migrating VMs is reached, there is not enough bandwidth to cope
with the rate at which they dirty their memory. The migrations will
thus never complete.

The correct solution to this would be a whole lot of work on the Nova
side. As a stopgap measure, this patch introduces a --max-servers
option to host-evacuate-live. With this option, the user can control
the number of VMs that are live-migrated at the same time, thus
allowing the user to avoid the dirty memory scenario described above.

Change-Id: I17bad5f3253d6657fc1e6610159fc8e3921e6ea4
This commit is contained in:
Artom Lifshitz 2015-09-02 16:47:44 +00:00
parent 893bf9313c
commit 3d9c01b2d3
2 changed files with 18 additions and 0 deletions

View File

@ -1583,6 +1583,14 @@ class ShellTest(utils.TestCase):
self.assert_called('POST', '/servers/uuid3/action', body, pos=3) self.assert_called('POST', '/servers/uuid3/action', body, pos=3)
self.assert_called('POST', '/servers/uuid4/action', body, pos=4) self.assert_called('POST', '/servers/uuid4/action', body, pos=4)
def test_host_evacuate_list_with_max_servers(self):
self.run_command('host-evacuate-live --max-servers 1 hyper')
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
body = {'os-migrateLive': {'host': None,
'block_migration': False,
'disk_over_commit': False}}
self.assert_called('POST', '/servers/uuid1/action', body, pos=1)
def test_reset_state(self): def test_reset_state(self):
self.run_command('reset-state sample-server') self.run_command('reset-state sample-server')
self.assert_called('POST', '/servers/1234/action', self.assert_called('POST', '/servers/1234/action',

View File

@ -54,15 +54,25 @@ def _server_live_migrate(cs, server, args):
action='store_true', action='store_true',
default=False, default=False,
help=_('Enable disk overcommit.')) help=_('Enable disk overcommit.'))
@cliutils.arg(
'--max-servers',
type=int,
dest='max_servers',
metavar='<max_servers>',
help='Maximum number of servers to live migrate simultaneously')
def do_host_evacuate_live(cs, args): def do_host_evacuate_live(cs, args):
"""Live migrate all instances of the specified host """Live migrate all instances of the specified host
to other available hosts. to other available hosts.
""" """
hypervisors = cs.hypervisors.search(args.host, servers=True) hypervisors = cs.hypervisors.search(args.host, servers=True)
response = [] response = []
migrating = 0
for hyper in hypervisors: for hyper in hypervisors:
for server in getattr(hyper, 'servers', []): for server in getattr(hyper, 'servers', []):
response.append(_server_live_migrate(cs, server, args)) response.append(_server_live_migrate(cs, server, args))
migrating = migrating + 1
if args.max_servers is not None and migrating >= args.max_servers:
break
utils.print_list(response, ["Server UUID", "Live Migration Accepted", utils.print_list(response, ["Server UUID", "Live Migration Accepted",
"Error Message"]) "Error Message"])