summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMuneyuki Noguchi <noguchimn@nttdata.co.jp>2011-04-22 06:29:49 +0000
committerTarmac <>2011-04-22 06:29:49 +0000
commitc028a791c8434a3c58ff1c7e0cd02b2f9f5b8417 (patch)
tree4c7400f5a825cb89e3bc004040704087f0c07c58
parent32bb38fad4bd86406d714827743fbfe2e134f53d (diff)
parentc9fb4cdf18781a819b410e7e67ae2cf09091a524 (diff)
Restore volume state on migration failure to fix lp742256.
-rw-r--r--nova/compute/manager.py20
-rw-r--r--nova/virt/libvirt_conn.py2
-rw-r--r--nova/volume/api.py7
3 files changed, 25 insertions, 4 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 99833de85..86a9e87b0 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -52,6 +52,7 @@ from nova import log as logging
from nova import manager
from nova import rpc
from nova import utils
+from nova import volume
from nova.compute import power_state
from nova.virt import driver
@@ -761,6 +762,14 @@ class ComputeManager(manager.SchedulerDependentManager):
self.db.volume_detached(context, volume_id)
return True
+ def remove_volume(self, context, volume_id):
+ """Remove volume on compute host.
+
+ :param context: security context
+ :param volume_id: volume ID
+ """
+ self.volume_manager.remove_compute_volume(context, volume_id)
+
@exception.wrap_exception
def compare_cpu(self, context, cpu_info):
"""Checks that the host cpu is compatible with a cpu given by xml.
@@ -980,7 +989,7 @@ class ComputeManager(manager.SchedulerDependentManager):
"Domain not found: no domain with matching name.\" "
"This error can be safely ignored."))
- def recover_live_migration(self, ctxt, instance_ref, host=None):
+ def recover_live_migration(self, ctxt, instance_ref, host=None, dest=None):
"""Recovers Instance/volume state from migrating -> running.
:param ctxt: security context
@@ -998,8 +1007,13 @@ class ComputeManager(manager.SchedulerDependentManager):
'state': power_state.RUNNING,
'host': host})
- for volume in instance_ref['volumes']:
- self.db.volume_update(ctxt, volume['id'], {'status': 'in-use'})
+ if dest:
+ volume_api = volume.API()
+ for volume_ref in instance_ref['volumes']:
+ volume_id = volume_ref['id']
+ self.db.volume_update(ctxt, volume_id, {'status': 'in-use'})
+ if dest:
+ volume_api.remove_from_compute(ctxt, volume_id, dest)
def periodic_tasks(self, context=None):
"""Tasks to be run at a periodic interval."""
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 85688f739..e9e5175bd 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -1566,7 +1566,7 @@ class LibvirtConnection(driver.ComputeDriver):
FLAGS.live_migration_bandwidth)
except Exception:
- recover_method(ctxt, instance_ref)
+ recover_method(ctxt, instance_ref, dest=dest)
raise
# Waiting for completion of live_migration.
diff --git a/nova/volume/api.py b/nova/volume/api.py
index 4b4bb9dc5..09befb647 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -103,3 +103,10 @@ class API(base.Base):
# TODO(vish): abstract status checking?
if volume['status'] == "available":
raise exception.ApiError(_("Volume is already detached"))
+
+ def remove_from_compute(self, context, volume_id, host):
+ """Remove volume from specified compute host."""
+ rpc.call(context,
+ self.db.queue_get_for(context, FLAGS.compute_topic, host),
+ {"method": "remove_volume",
+ "args": {'volume_id': volume_id}})