From dcabd6159abcdccd99e55495ec005926465007a8 Mon Sep 17 00:00:00 2001 From: MotoKen Date: Fri, 5 Oct 2012 14:34:32 +0800 Subject: Fix reserve_block_device_name while attach volume The block device name will not be reserved in current implementation due to missing volume_id in block_device_mapping. This will cause block_device.instance_block_mapping does not return the ebs device which should be reserved. This patch adds the volume_id to block_device_mapping while reserving block device name and changes the rpcapi to send the volume_id. Fixes bug 1062033 Change-Id: I8f08b568619fefa99850de0bee7d605749d53b0a --- nova/compute/api.py | 2 +- nova/compute/manager.py | 5 +++-- nova/compute/rpcapi.py | 8 +++++--- nova/tests/compute/test_rpcapi.py | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'nova') diff --git a/nova/compute/api.py b/nova/compute/api.py index 20523170f..349b15f77 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1848,7 +1848,7 @@ class API(base.Base): # compute, the bdm will be created here and we will # have to make sure that they are assigned atomically. device = self.compute_rpcapi.reserve_block_device_name( - context, device=device, instance=instance) + context, device=device, instance=instance, volume_id=volume_id) try: volume = self.volume_api.get(context, volume_id) self.volume_api.check_attach(context, volume) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 920ed658b..38a9494f4 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -210,7 +210,7 @@ def _get_image_meta(context, image_ref): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '2.2' + RPC_API_VERSION = '2.3' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1961,7 +1961,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @reverts_task_state @wrap_instance_fault - def reserve_block_device_name(self, context, instance, device): + def reserve_block_device_name(self, context, instance, device, volume_id): @utils.synchronized(instance['uuid']) def do_reserve(): @@ -1970,6 +1970,7 @@ class ComputeManager(manager.SchedulerDependentManager): device) # NOTE(vish): create bdm here to avoid race condition values = {'instance_uuid': instance['uuid'], + 'volume_id': volume_id, 'device_name': result} self.db.block_device_mapping_create(context, values) return result diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 2e3873c19..560b1ab05 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -130,6 +130,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 2.1 - Adds orig_sys_metadata to rebuild_instance() 2.2 - Adds slave_info parameter to add_aggregate_host() and remove_aggregate_host() + 2.3 - Adds volume_id to reserve_block_device_name() ''' # @@ -458,11 +459,12 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic = _compute_topic(self.topic, ctxt, host, None) return self.call(ctxt, self.make_msg('get_host_uptime'), topic) - def reserve_block_device_name(self, ctxt, instance, device): + def reserve_block_device_name(self, ctxt, instance, device, volume_id): instance_p = jsonutils.to_primitive(instance) return self.call(ctxt, self.make_msg('reserve_block_device_name', - instance=instance_p, device=device), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p, device=device, volume_id=volume_id), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='2.3') def snapshot_instance(self, ctxt, instance, image_id, image_type, backup_type, rotation): diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index b0fc9c7c8..c5a5768c5 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -228,7 +228,8 @@ class ComputeRpcAPITestCase(test.TestCase): def test_reserve_block_device_name(self): self._test_compute_api('reserve_block_device_name', 'call', - instance=self.fake_instance, device='device') + instance=self.fake_instance, device='device', volume_id='id', + version='2.3') def refresh_provider_fw_rules(self): self._test_compute_api('refresh_provider_fw_rules', 'cast', -- cgit