1 定位源码: /nova/api/openstack/compute/contrib/admin_actions.py----def _migrate_live:
def _migrate_live(self, req, id, body):
"""Permit admins to (live) migrate a server to a new host."""
context = req.environ["nova.context"]
authorize(context, 'migrateLive')
try:
block_migration = body["os-migrateLive"]["block_migration"]
disk_over_commit = body["os-migrateLive"]["disk_over_commit"]
host = body["os-migrateLive"]["host"]
except (TypeError, KeyError):
msg = _("host, block_migration and disk_over_commit must "
"be specified for live migration.")
raise exc.HTTPBadRequest(explanation=msg)
try:
block_migration = strutils.bool_from_string(block_migration,
strict=True)
disk_over_commit = strutils.bool_from_string(disk_over_commit,
strict=True)
except ValueError as err:
raise exc.HTTPBadRequest(explanation=six.text_type(err))
<strong>instance = common.get_instance(self.compute_api, context, id,
want_objects=True)
try:
self.compute_api.live_migrate(context, instance, block_migration,
disk_over_commit, host)</strong>
except (exception.NoValidHost,
exception.ComputeServiceUnavailable,
exception.InvalidHypervisorType,
exception.InvalidCPUInfo,
exception.UnableToMigrateToSelf,
exception.DestinationHypervisorTooOld,
exception.InvalidLocalStorage,
exception.InvalidSharedStorage,
exception.HypervisorUnavailable,
exception.InstanceNotRunning,
exception.MigrationPreCheckError,
exception.LiveMigrationWithOldNovaNotSafe) as ex:
raise exc.HTTPBadRequest(explanation=ex.format_message())
except exception.InstanceNotFound as e:
raise exc.HTTPNotFound(explanation=e.format_message())
except exception.InstanceIsLocked as e:
raise exc.HTTPConflict(explanation=e.format_message())
except exception.InstanceInvalidState as state_error:
common.raise_http_conflict_for_instance_invalid_state(state_error,
'os-migrateLive', id)
except Exception:
if host is None:
msg = _("Live migration of instance %s to another host "
"failed") % id
else:
msg = _("Live migration of instance %(id)s to host %(host)s "
"failed") % {'id': id, 'host': host}
LOG.exception(msg)
# Return messages from scheduler
raise exc.HTTPBadRequest(explanation=msg)
return webob.Response(status_int=202)
定位黑体部分才是迁移的关键代码 live_migrate
这部分代码主要做如下两件事
1 更新实例的记录,如果任务或者虚拟机状态发生改变则发送一个状态更新的通知; #返回更新后的实例信息; 发送通知,来报告实例中发生的任何改变;
2 调用call方法实现在主题topic的模式上发送实时迁移虚拟机的消息,并等待回应;如果目标主机没有定义,则由调度算法选取一个主机; 检测是否可以执行实时迁移; 这个检测是运行在目标主机上的,然后返回检测结果给源主机;返回获取的目标主机; # 执行迁移;
在执行一个一个live_migrateTask的时候,涉及到openstack当中的rpc机制,会将一个topic为“live_migration”的类型的消息,cast到消息队列当中,等待结果
def cast(self, ctxt, method, **kwargs):
msg = self._make_msg(method, **kwargs)
topic = self._get_topic()
self.cells_rpcapi.proxy_rpc_to_manager(ctxt, msg, topic)
Proxy RPC to a compute manager. The host in the topic should be encoded with the target cell name.