File 0001-Don-t-delete-wrong-BDM-bnc-917204.patch of Package openstack-nova-doc
From 4cc758d92ece4d33c84dd64fea1711c926f96256 Mon Sep 17 00:00:00 2001
From: Thomas Bechtold <tbechtold@suse.com>
Date: Tue, 17 Mar 2015 13:32:59 +0100
Subject: [PATCH] Don't delete wrong BDM (bnc#917204)
Use the correct BlockDeviceMapping (BDM) when volume-attach fails.
See also upstream bug lp#1349888
Change-Id: I42f6125120699cc82e2663c1b1ff7d4f6847ff3b
---
nova/compute/api.py | 6 ++----
nova/compute/manager.py | 8 ++++++--
nova/compute/rpcapi.py | 23 ++++++++++++++++++++++-
3 files changed, 30 insertions(+), 7 deletions(-)
Index: nova-2014.1.5.dev3/nova/compute/api.py
===================================================================
--- nova-2014.1.5.dev3.orig/nova/compute/api.py
+++ nova-2014.1.5.dev3/nova/compute/api.py
@@ -2787,11 +2787,9 @@ class API(base.Base):
# the same time. When db access is removed from
# 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(
+ volume_bdm = self.compute_rpcapi.reserve_block_device_name(
context, device=device, instance=instance, volume_id=volume_id,
disk_bus=disk_bus, device_type=device_type)
- volume_bdm = block_device_obj.BlockDeviceMapping.get_by_volume_id(
- context, volume_id)
try:
volume = self.volume_api.get(context, volume_id)
self.volume_api.check_attach(context, volume, instance=instance)
@@ -2802,7 +2800,7 @@ class API(base.Base):
with excutils.save_and_reraise_exception():
volume_bdm.destroy(context)
- return device
+ return volume_bdm.device_name
@wrap_check_policy
@check_instance_lock
Index: nova-2014.1.5.dev3/nova/compute/manager.py
===================================================================
--- nova-2014.1.5.dev3.orig/nova/compute/manager.py
+++ nova-2014.1.5.dev3/nova/compute/manager.py
@@ -4191,7 +4191,8 @@ class ComputeManager(manager.Manager):
@reverts_task_state
@wrap_instance_fault
def reserve_block_device_name(self, context, instance, device,
- volume_id, disk_bus=None, device_type=None):
+ volume_id, disk_bus=None, device_type=None,
+ return_bdm_object=False):
# NOTE(ndipanov): disk_bus and device_type will be set to None if not
# passed (by older clients) and defaulted by the virt driver. Remove
# default values on the next major RPC version bump.
@@ -4214,7 +4215,10 @@ class ComputeManager(manager.Manager):
disk_bus=disk_bus, device_type=device_type)
bdm.create(context)
- return device_name
+ if return_bdm_object:
+ return bdm
+ else:
+ return device_name
return do_reserve()
Index: nova-2014.1.5.dev3/nova/compute/rpcapi.py
===================================================================
--- nova-2014.1.5.dev3.orig/nova/compute/rpcapi.py
+++ nova-2014.1.5.dev3/nova/compute/rpcapi.py
@@ -21,6 +21,7 @@ from oslo import messaging
from nova import block_device
from nova import exception
+from nova.objects import block_device as objects_block_device
from nova.objects import base as objects_base
from nova.openstack.common.gettextutils import _
from nova.openstack.common import jsonutils
@@ -810,7 +811,27 @@ class ComputeAPI(object):
cctxt = self.client.prepare(server=_compute_host(None, instance),
version=version)
- return cctxt.call(ctxt, 'reserve_block_device_name', **kw)
+
+ # NOTE(toabctl): Try to get a block device mapping object (bnc#917204)
+ kw['return_bdm_object'] = True
+ try:
+ volume_bdm = cctxt.call(ctxt, 'reserve_block_device_name', **kw)
+ except TypeError as e:
+ if not "return_bdm_object" in e.message:
+ # NOTE(toabctl): Seems to be an exception unrelated to bnc#917204
+ raise
+ # NOTE(toabctl): The code on the compute node should be updated!
+ # Seems that it doesn't support the parmeter 'return_bdm_object' currently.
+ # Retry without that parameter which means, that bnc#917204 is not fixed for
+ # this code path!
+ kw.pop('return_bdm_object')
+ volume_bdm = cctxt.call(ctxt, 'reserve_block_device_name', **kw)
+
+ if not isinstance(volume_bdm, objects_block_device.BlockDeviceMapping):
+ volume_bdm = objects_block_device.BlockDeviceMapping.get_by_volume_id(
+ ctxt, volume_id)
+
+ return volume_bdm
def backup_instance(self, ctxt, instance, image_id, backup_type,
rotation):