Revision 6906a9d8 lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
3631 | 3631 |
|
3632 | 3632 |
self.feedback_fn("* done") |
3633 | 3633 |
|
3634 |
def _RevertDiskStatus(self): |
|
3635 |
"""Try to revert the disk status after a failed migration. |
|
3636 |
|
|
3637 |
""" |
|
3638 |
target_node = self.target_node |
|
3639 |
try: |
|
3640 |
self._EnsureSecondary(target_node) |
|
3641 |
self._GoStandalone() |
|
3642 |
self._GoReconnect(False) |
|
3643 |
self._WaitUntilSync() |
|
3644 |
except errors.OpExecError, err: |
|
3645 |
self.LogWarning("Migration failed and I can't reconnect the" |
|
3646 |
" drives: error '%s'\n" |
|
3647 |
"Please look and recover the instance status" % |
|
3648 |
str(err)) |
|
3649 |
|
|
3650 |
def _AbortMigration(self): |
|
3651 |
"""Call the hypervisor code to abort a started migration. |
|
3652 |
|
|
3653 |
""" |
|
3654 |
instance = self.instance |
|
3655 |
target_node = self.target_node |
|
3656 |
migration_info = self.migration_info |
|
3657 |
|
|
3658 |
abort_result = self.rpc.call_finalize_migration(target_node, |
|
3659 |
instance, |
|
3660 |
migration_info, |
|
3661 |
False) |
|
3662 |
abort_msg = abort_result.RemoteFailMsg() |
|
3663 |
if abort_msg: |
|
3664 |
logging.error("Aborting migration failed on target node %s: %s" % |
|
3665 |
(target_node, abort_msg)) |
|
3666 |
# Don't raise an exception here, as we stil have to try to revert the |
|
3667 |
# disk status, even if this step failed. |
|
3668 |
|
|
3634 | 3669 |
def _ExecMigration(self): |
3635 | 3670 |
"""Migrate an instance. |
3636 | 3671 |
|
... | ... | |
3654 | 3689 |
" synchronized on target node," |
3655 | 3690 |
" aborting migrate." % dev.iv_name) |
3656 | 3691 |
|
3692 |
# First get the migration information from the remote node |
|
3693 |
result = self.rpc.call_migration_info(source_node, instance) |
|
3694 |
msg = result.RemoteFailMsg() |
|
3695 |
if msg: |
|
3696 |
log_err = ("Failed fetching source migration information from %s: %s" % |
|
3697 |
(source_node, msg)) |
|
3698 |
logging.error(log_err) |
|
3699 |
raise errors.OpExecError(log_err) |
|
3700 |
|
|
3701 |
self.migration_info = migration_info = result.data[1] |
|
3702 |
|
|
3703 |
# Then switch the disks to master/master mode |
|
3657 | 3704 |
self._EnsureSecondary(target_node) |
3658 | 3705 |
self._GoStandalone() |
3659 | 3706 |
self._GoReconnect(True) |
3660 | 3707 |
self._WaitUntilSync() |
3661 | 3708 |
|
3709 |
self.feedback_fn("* preparing %s to accept the instance" % target_node) |
|
3710 |
result = self.rpc.call_accept_instance(target_node, |
|
3711 |
instance, |
|
3712 |
migration_info, |
|
3713 |
self.nodes_ip[target_node]) |
|
3714 |
|
|
3715 |
msg = result.RemoteFailMsg() |
|
3716 |
if msg: |
|
3717 |
logging.error("Instance pre-migration failed, trying to revert" |
|
3718 |
" disk status: %s", msg) |
|
3719 |
self._AbortMigration() |
|
3720 |
self._RevertDiskStatus() |
|
3721 |
raise errors.OpExecError("Could not pre-migrate instance %s: %s" % |
|
3722 |
(instance.name, msg)) |
|
3723 |
|
|
3662 | 3724 |
self.feedback_fn("* migrating instance to %s" % target_node) |
3663 | 3725 |
time.sleep(10) |
3664 | 3726 |
result = self.rpc.call_instance_migrate(source_node, instance, |
... | ... | |
3668 | 3730 |
if msg: |
3669 | 3731 |
logging.error("Instance migration failed, trying to revert" |
3670 | 3732 |
" disk status: %s", msg) |
3671 |
try: |
|
3672 |
self._EnsureSecondary(target_node) |
|
3673 |
self._GoStandalone() |
|
3674 |
self._GoReconnect(False) |
|
3675 |
self._WaitUntilSync() |
|
3676 |
except errors.OpExecError, err: |
|
3677 |
self.LogWarning("Migration failed and I can't reconnect the" |
|
3678 |
" drives: error '%s'\n" |
|
3679 |
"Please look and recover the instance status" % |
|
3680 |
str(err)) |
|
3681 |
|
|
3733 |
self._AbortMigration() |
|
3734 |
self._RevertDiskStatus() |
|
3682 | 3735 |
raise errors.OpExecError("Could not migrate instance %s: %s" % |
3683 | 3736 |
(instance.name, msg)) |
3684 | 3737 |
time.sleep(10) |
... | ... | |
3687 | 3740 |
# distribute new instance config to the other nodes |
3688 | 3741 |
self.cfg.Update(instance) |
3689 | 3742 |
|
3743 |
result = self.rpc.call_finalize_migration(target_node, |
|
3744 |
instance, |
|
3745 |
migration_info, |
|
3746 |
True) |
|
3747 |
msg = result.RemoteFailMsg() |
|
3748 |
if msg: |
|
3749 |
logging.error("Instance migration succeeded, but finalization failed:" |
|
3750 |
" %s" % msg) |
|
3751 |
raise errors.OpExecError("Could not finalize instance migration: %s" % |
|
3752 |
msg) |
|
3753 |
|
|
3690 | 3754 |
self._EnsureSecondary(source_node) |
3691 | 3755 |
self._WaitUntilSync() |
3692 | 3756 |
self._GoStandalone() |
Also available in: Unified diff