From 8a3c7d30914c7cd1f85583316980ece3c33ed3d1 Mon Sep 17 00:00:00 2001 From: Brian Elliott Date: Tue, 27 Nov 2012 16:49:58 +0000 Subject: Make resize and multi-node work properly together Added node support to migrations and update node properly in 'resize_instance'. bug 1081355 Change-Id: I003d34e3f7ed9ce2feda19ee5ce210ed4ba7eaa1 --- nova/compute/manager.py | 16 +++++++++++----- nova/compute/resource_tracker.py | 17 +++++++++++------ nova/compute/rpcapi.py | 8 +++++--- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a0835d107..7d793ad8c 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -307,7 +307,7 @@ class ComputeVirtAPI(virtapi.VirtAPI): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '2.19' + RPC_API_VERSION = '2.20' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1770,7 +1770,7 @@ class ComputeManager(manager.SchedulerDependentManager): QUOTAS.rollback(context, reservations) def _prep_resize(self, context, image, instance, instance_type, - reservations, request_spec, filter_properties): + reservations, request_spec, filter_properties, node): if not filter_properties: filter_properties = {} @@ -1787,7 +1787,7 @@ class ComputeManager(manager.SchedulerDependentManager): raise exception.MigrationError(msg) limits = filter_properties.get('limits', {}) - rt = self._get_resource_tracker(instance.get('node')) + rt = self._get_resource_tracker(node) with rt.resize_claim(context, instance, instance_type, limits=limits) \ as claim: migration_ref = claim.migration @@ -1802,12 +1802,17 @@ class ComputeManager(manager.SchedulerDependentManager): @wrap_instance_fault def prep_resize(self, context, image, instance, instance_type, reservations=None, request_spec=None, - filter_properties=None): + filter_properties=None, node=None): """Initiates the process of moving a running instance to another host. Possibly changes the RAM and disk size in the process. """ + if node is None: + node = self.driver.get_available_nodes()[0] + LOG.debug(_("No node specified, defaulting to %(node)s") % + locals()) + with self._error_out_instance_on_exception(context, instance['uuid'], reservations): compute_utils.notify_usage_exists( @@ -1816,7 +1821,7 @@ class ComputeManager(manager.SchedulerDependentManager): context, instance, "resize.prep.start") try: self._prep_resize(context, image, instance, instance_type, - reservations, request_spec, filter_properties) + reservations, request_spec, filter_properties, node) except Exception: # try to re-schedule the resize elsewhere: self._reschedule_resize_or_reraise(context, image, instance, @@ -1911,6 +1916,7 @@ class ComputeManager(manager.SchedulerDependentManager): instance = self._instance_update(context, instance['uuid'], host=migration['dest_compute'], + node=migration['dest_node'], task_state=task_states.RESIZE_MIGRATED, expected_task_state=task_states. RESIZE_MIGRATING) diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index ac46f31da..b3e9538bd 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -167,7 +167,9 @@ class ResourceTracker(object): return db.migration_create(context.elevated(), {'instance_uuid': instance['uuid'], 'source_compute': instance['host'], + 'source_node': instance['node'], 'dest_compute': self.host, + 'dest_node': self.nodename, 'dest_host': self.driver.get_host_ip_addr(), 'old_instance_type_id': old_instance_type['id'], 'new_instance_type_id': instance_type['id'], @@ -258,7 +260,8 @@ class ResourceTracker(object): self._update_usage_from_instances(resources, instances) # Grab all in-progress migrations: - migrations = db.migration_get_in_progress_by_host(context, self.host) + migrations = db.migration_get_in_progress_by_host_and_node(context, + self.host, self.nodename) self._update_usage_from_migrations(resources, migrations) @@ -377,15 +380,17 @@ class ResourceTracker(object): uuid = migration['instance_uuid'] LOG.audit(_("Updating from migration %s") % uuid) - incoming = (migration['dest_compute'] == self.host) - outbound = (migration['source_compute'] == self.host) - same_host = (incoming and outbound) + incoming = (migration['dest_compute'] == self.host and + migration['dest_node'] == self.nodename) + outbound = (migration['source_compute'] == self.host and + migration['source_node'] == self.nodename) + same_node = (incoming and outbound) instance = self.tracked_instances.get(uuid, None) itype = None - if same_host: - # same host resize. record usage for whichever instance type the + if same_node: + # same node resize. record usage for whichever instance type the # instance is *not* in: if (instance['instance_type_id'] == migration['old_instance_type_id']): diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 6f69a3cd8..bdb2c4d2d 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -147,6 +147,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 2.17 - Add get_backdoor_port() 2.18 - Add bdms to rebuild_instance 2.19 - Add node to run_instance + 2.20 - Add node to prep_resize ''' # @@ -357,16 +358,17 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): def prep_resize(self, ctxt, image, instance, instance_type, host, reservations=None, request_spec=None, - filter_properties=None): + filter_properties=None, node=None): instance_p = jsonutils.to_primitive(instance) instance_type_p = jsonutils.to_primitive(instance_type) self.cast(ctxt, self.make_msg('prep_resize', instance=instance_p, instance_type=instance_type_p, image=image, reservations=reservations, request_spec=request_spec, - filter_properties=filter_properties), + filter_properties=filter_properties, + node=node), _compute_topic(self.topic, ctxt, host, None), - version='2.10') + version='2.20') def reboot_instance(self, ctxt, instance, block_device_info, network_info, reboot_type): -- cgit