From: Michael Goldish <mgoldish@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org
Subject: [KVM-AUTOTEST PATCH 13/17] KVM test: make migrate() a VM method
Date: Mon, 3 Jan 2011 20:27:14 +0200 [thread overview]
Message-ID: <1294079238-21239-13-git-send-email-mgoldish@redhat.com> (raw)
In-Reply-To: <1294079238-21239-1-git-send-email-mgoldish@redhat.com>
This should make it easier to run things in parallel to migration, because the
method switches the VM object's __dict__ instead of the VM object itself.
Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
client/tests/kvm/kvm_vm.py | 142 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 142 insertions(+), 0 deletions(-)
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index d236359..d6ca782 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -1348,6 +1348,148 @@ class VM:
return self.serial_login(internal_timeout)
+ def migrate(self, timeout=3600, protocol="tcp", cancel_delay=None,
+ offline=False, stable_check=False, clean=True,
+ save_path="/tmp", dest_host="localhost", remote_port=None):
+ """
+ Migrate the VM.
+
+ If the migration is local, the VM object's state is switched with that
+ of the destination VM. Otherwise, the state is switched with that of
+ a dead VM (returned by self.clone()).
+
+ @param timeout: Time to wait for migration to complete.
+ @param protocol: Migration protocol ('tcp', 'unix' or 'exec').
+ @param cancel_delay: If provided, specifies a time duration after which
+ migration will be canceled. Used for testing migrate_cancel.
+ @param offline: If True, pause the source VM before migration.
+ @param stable_check: If True, compare the VM's state after migration to
+ its state before migration and raise an exception if they
+ differ.
+ @param clean: If True, delete the saved state files (relevant only if
+ stable_check is also True).
+ @save_path: The path for state files.
+ @param dest_host: Destination host (defaults to 'localhost').
+ @param remote_port: Port to use for remote migration.
+ """
+ def mig_finished():
+ o = self.monitor.info("migrate")
+ if isinstance(o, str):
+ return "status: active" not in o
+ else:
+ return o.get("status") != "active"
+
+ def mig_succeeded():
+ o = self.monitor.info("migrate")
+ if isinstance(o, str):
+ return "status: completed" in o
+ else:
+ return o.get("status") == "completed"
+
+ def mig_failed():
+ o = self.monitor.info("migrate")
+ if isinstance(o, str):
+ return "status: failed" in o
+ else:
+ return o.get("status") == "failed"
+
+ def mig_cancelled():
+ o = self.monitor.info("migrate")
+ if isinstance(o, str):
+ return ("Migration status: cancelled" in o or
+ "Migration status: canceled" in o)
+ else:
+ return (o.get("status") == "cancelled" or
+ o.get("status") == "canceled")
+
+ def wait_for_migration():
+ if not kvm_utils.wait_for(mig_finished, timeout, 2, 2,
+ "Waiting for migration to finish..."):
+ raise VMMigrateTimeoutError("Timeout expired while waiting "
+ "for migration to finish")
+
+ local = dest_host == "localhost"
+
+ clone = self.clone()
+ if local:
+ if stable_check:
+ # Pause the dest vm after creation
+ extra_params = clone.params.get("extra_params", "") + " -S"
+ clone.params["extra_params"] = extra_params
+ clone.create(migration_mode=protocol, mac_source=self)
+
+ try:
+ if protocol == "tcp":
+ if local:
+ uri = "tcp:localhost:%d" % clone.migration_port
+ else:
+ uri = "tcp:%s:%d" % (dest_host, remote_port)
+ elif protocol == "unix":
+ uri = "unix:%s" % clone.migration_file
+ elif protocol == "exec":
+ uri = '"exec:nc localhost %s"' % clone.migration_port
+
+ if offline:
+ self.monitor.cmd("stop")
+
+ self.monitor.migrate(uri)
+
+ if cancel_delay:
+ time.sleep(cancel_delay)
+ self.monitor.cmd("migrate_cancel")
+ if not kvm_utils.wait_for(mig_cancelled, 60, 2, 2,
+ "Waiting for migration "
+ "cancellation"):
+ raise VMMigrateCancelError("Cannot cancel migration")
+ return
+
+ wait_for_migration()
+
+ # Report migration status
+ if mig_succeeded():
+ logging.info("Migration completed successfully")
+ elif mig_failed():
+ raise VMMigrateFailedError("Migration failed")
+ else:
+ raise VMMigrateFailedError("Migration ended with unknown "
+ "status")
+
+ # Switch self <-> clone
+ temp = self.clone(copy_state=True)
+ self.__dict__ = clone.__dict__
+ clone = temp
+
+ # From now on, clone is the source VM that will soon be destroyed
+ # and self is the destination VM that will remain alive. If this
+ # is remote migration, self is a dead VM object.
+
+ if local and stable_check:
+ try:
+ save1 = os.path.join(save_path, "src-" + clone.instance)
+ save2 = os.path.join(save_path, "dst-" + self.instance)
+ clone.save_to_file(save1)
+ self.save_to_file(save2)
+ # Fail if we see deltas
+ md5_save1 = utils.hash_file(save1)
+ md5_save2 = utils.hash_file(save2)
+ if md5_save1 != md5_save2:
+ raise VMMigrateStateMismatchError(md5_save1,
+ md5_save2)
+ finally:
+ if clean:
+ if os.path.isfile(save1):
+ os.remove(save1)
+ if os.path.isfile(save2):
+ os.remove(save2)
+
+ finally:
+ # If we're doing remote migration and it's completed successfully,
+ # self points to a dead VM object
+ if self.is_alive():
+ self.monitor.cmd("cont")
+ clone.destroy(gracefully=False)
+
+
def send_key(self, keystr):
"""
Send a key event to the VM.
--
1.7.3.4
next prev parent reply other threads:[~2011-01-03 18:27 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-03 18:27 [KVM-AUTOTEST PATCH 01/17] KVM test: introduce exception classes for _remote_login() and _remote_scp() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 02/17] KVM test: kvm_utils.py: reorder remote_login(), remote_scp(), copy_files_to(), etc Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 03/17] KVM test: use the new LoginError and SCPError exceptions Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 04/17] KVM test: add VM.wait_for_login() and kvm_utils.wait_for_login() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 05/17] KVM test: use the new wait_for_login() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 06/17] KVM test: rename VM.remote_login() to VM.login() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 07/17] KVM test: introduce VM exceptions Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 08/17] KVM test: let kvm_vm.create_image() raise a CmdError if qemu-img fails Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 09/17] KVM test: use the new VM exceptions Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 10/17] KVM test: add VM.verify_alive() and Monitor.verify_responsive() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 11/17] KVM test: use VM.verify_alive() instead of kvm_test_utils.get_living_vm() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 12/17] KVM test: kvm_preprocessing.py: simplify handling of params['migration_mode'] Michael Goldish
2011-01-03 18:27 ` Michael Goldish [this message]
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 14/17] KVM test: simplify migration_with_reboot and migration_with_file_transfer Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 15/17] KVM test: use VM.migrate() instead of kvm_test_utils.migrate() Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 16/17] KVM test: reorder kvm_utils.copy_files_from() path parameters Michael Goldish
2011-01-03 18:27 ` [KVM-AUTOTEST PATCH 17/17] KVM test: rename path parameters in kvm_vm.copy_files_*() Michael Goldish
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1294079238-21239-13-git-send-email-mgoldish@redhat.com \
--to=mgoldish@redhat.com \
--cc=autotest@test.kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.