kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Goldish <mgoldish@redhat.com>
To: Feng Yang <fyang@redhat.com>
Cc: autotest@test.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH] KVM Test: Extend migration test to test unix, exec and migrate_cancel
Date: Wed, 26 May 2010 13:22:54 +0300	[thread overview]
Message-ID: <4BFCF67E.5060103@redhat.com> (raw)
In-Reply-To: <1274848911-20759-1-git-send-email-fyang@redhat.com>

On 05/26/2010 07:41 AM, Feng Yang wrote:
> Update migrate() in kvm_test_utils.py to support unix, exec protocol
> and migration cancel test.
> Add four migration sub test. There are tcp, unix, exec and mig_cancel.
> migrate_cancel only work in tcp protocol.
> 
> Signed-off-by: Feng Yang <fyang@redhat.com>
> ---
>  client/tests/kvm/kvm_test_utils.py     |   96 +++++++++++++++++++++++++------
>  client/tests/kvm/tests/migration.py    |    7 ++-
>  client/tests/kvm/tests_base.cfg.sample |   11 ++++
>  3 files changed, 94 insertions(+), 20 deletions(-)
> 
> diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py
> index 24e2bf5..a3d6217 100644
> --- a/client/tests/kvm/kvm_test_utils.py
> +++ b/client/tests/kvm/kvm_test_utils.py
> @@ -108,13 +108,17 @@ def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0,
>      return session
>  
>  
> -def migrate(vm, env=None):
> +def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp",
> +            mig_cancel=False):
>      """
>      Migrate a VM locally and re-register it in the environment.
>  
>      @param vm: The VM to migrate.
>      @param env: The environment dictionary.  If omitted, the migrated VM will
>              not be registered.
> +    @param mig_timeout: timeout value for migration.
> +    @param mig_protocol: migration protocol
> +    @param mig_cancel: Test migrate_cancel or not when protocol is tcp.
>      @return: The post-migration VM.
>      """
>      # Helper functions
> @@ -126,6 +130,10 @@ def migrate(vm, env=None):
>          s, o = vm.send_monitor_cmd("info migrate")
>          return s == 0 and "Migration status: completed" in o
>  
> +    def mig_canceled():
> +        s, o = vm.send_monitor_cmd("info migrate")
> +        return s == 0 and "Migration status: cancelled" in o
> +
>      def mig_failed():
>          s, o = vm.send_monitor_cmd("info migrate")
>          return s == 0 and "Migration status: failed" in o
> @@ -135,29 +143,73 @@ def migrate(vm, env=None):
>      if not "info migrate" in o:
>          raise error.TestError("Migration is not supported")
>  
> -    # Clone the source VM and ask the clone to wait for incoming migration
> -    dest_vm = vm.clone()
> -    if not dest_vm.create(for_migration=True):
> -        raise error.TestError("Could not create dest VM")
> -
> -    try:
> +    if mig_protocol == "tcp":
> +        migration_port = kvm_utils.find_free_port(5200, 6000)
> +        mig_extra_params = " -incoming tcp:0:%d" % migration_port
>          # Define the migration command
> -        cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
> -        logging.debug("Migrating with command: %s" % cmd)
> -
> -        # Migrate
> -        s, o = vm.send_monitor_cmd(cmd)
> -        if s:
> -            logging.error("Migration command failed (command: %r, output: %r)"
> -                          % (cmd, o))
> -            raise error.TestFail("Migration command failed")
> -
> -        # Wait for migration to finish
> -        if not kvm_utils.wait_for(mig_finished, 90, 2, 2,
> +        mig_cmd = "migrate -d tcp:localhost:%d" % migration_port
> +    if mig_protocol == "unix":
> +        file = os.path.join("/tmp/", mig_protocol +
> +                                     time.strftime("%Y%m%d-%H%M%S"))
> +        mig_extra_params = " -incoming unix:%s" % file
> +        mig_cmd = "migrate unix:%s" % file
> +
> +    if mig_protocol == "exec":
> +        file = os.path.join("/tmp/", mig_protocol +
> +                                     time.strftime("%Y%m%d-%H%M%S"))
> +        mig_extra_params = " -incoming \"exec: gzip -c -d %s\"" % file
> +        mig_cmd = "migrate \"exec:gzip -c > %s\"" % file
> +
> +        vm.send_monitor_cmd("stop")
> +        vm.send_monitor_cmd(mig_cmd, timeout=mig_timeout)
> +        if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
>                                    "Waiting for migration to finish..."):
>              raise error.TestFail("Timeout elapsed while waiting for migration "
>                                   "to finish")
>  
> +    # Clone the source VM and ask the clone to wait for incoming migration
> +    params = vm.params
> +    if params.has_key("extra_params"):
> +        params["extra_params"] += mig_extra_params
> +    else:
> +        params["extra_params"] = mig_extra_params

This looks like a good patch.  I'd like to point out some things though:

1. It is preferable not to add migration params to extra_params.  If we
do that, the preprocessor of the next test will look at the qemu command
(which contains extra_params) to decide if the VM should be restarted,
and the VM will be restarted even when it shouldn't.  If the parameters
of the VM of the next test are exactly identical to those of the current
test, except for migration parameters, then there's no need to restart
the VM.  Including migration parameters in extra_params will cause the
VM to be restarted anyway.

To clarify, an example: let's say there's a migration test with a VM:
image_name = img
mem = 512
smp = 2

and then a reboot test with an identical VM:
image_name = img
mem = 512
smp = 2

There's no need to restart the VM because the qemu commands are
identical.  However, if the first VM has "extra_params = -incoming ...",
the qemu commands will be different, even though the VMs are identical
(except for the fact that the first VM is a migrated one).

We need to think of a way to pass these migration parameters without
putting them in extra_params or in anything else that
make_qemu_command() uses.

2. It is preferable to choose ports in VM.create(), where vnc and redir
ports are chosen.  This is especially important for running in parallel,
and also for consistency.

I haven't read the patch thoroughly yet, so I'll post more comments
after I do that.

Thanks,
Michael

> +    dest_vm = vm.clone(params=params)
> +    if not dest_vm.create():
> +        raise error.TestError("Could not create dest VM")
> +    try:
> +        if mig_protocol != "exec":
> +            logging.debug("Migrating with command: %s" % mig_cmd)
> +
> +            # Migrate
> +            s, o = vm.send_monitor_cmd(mig_cmd, timeout=mig_timeout)
> +            if s:
> +                logging.error("Migration command failed (command: %r, output:"
> +                              " %r)"  % (mig_cmd, o))
> +                raise error.TestFail("Migration command failed")
> +
> +            if mig_protocol == "tcp" and mig_cancel:
> +                # Sleep two seconds before send migrate_cancel command.
> +                time.sleep(2)
> +                s, o = vm.send_monitor_cmd("migrate_cancel")
> +                if not kvm_utils.wait_for(mig_canceled, 60, 2, 2,
> +                                          "Waiting for migration cancel"):
> +                    raise error.TestFail("Fail to cancel migration")
> +                s, o = dest_vm.send_monitor_cmd("info status")
> +                if "paused" not in o:
> +                    raise error.TestFail("Fail to cancel migration, dest VM"
> +                                          "is not paused")
> +                s, o = vm.send_monitor_cmd("info status")
> +                if "running" not in o:
> +                     raise error.TestFail("VM status is not running after"
> +                                          " migration canceled")
> +                return vm
> +
> +            # Wait for migration to finish
> +            if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
> +                                      "Waiting for migration to finish..."):
> +                raise error.TestFail("Timeout elapsed while waiting for "
> +                                      "migration to finish")
> +
>          # Report migration status
>          if mig_succeeded():
>              logging.info("Migration finished successfully")
> @@ -166,6 +218,12 @@ def migrate(vm, env=None):
>          else:
>              raise error.TestFail("Migration ended with unknown status")
>  
> +        if mig_protocol == "exec":
> +            s, o = dest_vm.send_monitor_cmd("info status")
> +            if "paused" in o:
> +                logging.debug("Dest VM is in paused status")
> +                dest_vm.send_monitor_cmd("c")
> +
>          # Kill the source VM
>          vm.destroy(gracefully=False)
>  
> diff --git a/client/tests/kvm/tests/migration.py b/client/tests/kvm/tests/migration.py
> index b8f171c..9cdafc9 100644
> --- a/client/tests/kvm/tests/migration.py
> +++ b/client/tests/kvm/tests/migration.py
> @@ -22,6 +22,10 @@ def run_migration(test, params, env):
>      vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
>      session = kvm_test_utils.wait_for_login(vm)
>  
> +    mig_timeout = float(params.get("mig_timeout", "3600"))
> +    mig_protocol = params.get("migration_protocol", "tcp")
> +    mig_cancel = bool(params.get("mig_cancel"))
> +
>      # Get the output of migration_test_command
>      test_command = params.get("migration_test_command")
>      reference_output = session.get_command_output(test_command)
> @@ -43,7 +47,8 @@ def run_migration(test, params, env):
>          session2.close()
>  
>          # Migrate the VM
> -        dest_vm = kvm_test_utils.migrate(vm, env)
> +        dest_vm = kvm_test_utils.migrate(vm, env,mig_timeout, mig_protocol,
> +                                         mig_cancel)
>  
>          # Log into the guest again
>          logging.info("Logging into guest after migration...")
> diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
> index 3a56b65..509d8eb 100644
> --- a/client/tests/kvm/tests_base.cfg.sample
> +++ b/client/tests/kvm/tests_base.cfg.sample
> @@ -105,6 +105,17 @@ variants:
>          kill_vm_on_error = yes
>          iterations = 2
>          used_mem = 1024
> +        mig_timeout = 3600
> +        variants:
> +            - tcp:
> +                migration_protocol = "tcp"
> +            - unix:
> +                migration_protocol = "unix"
> +            - exec:
> +                migration_protocol = "exec"
> +            - mig_cancel:
> +                migration_protocol = "tcp"
> +                mig_cancel = True
>  
>      - boot_savevm: install setup unattended_install
>          type = boot_savevm

      reply	other threads:[~2010-05-26 10:22 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-26  4:41 [PATCH] KVM Test: Extend migration test to test unix, exec and migrate_cancel Feng Yang
2010-05-26 10:22 ` Michael Goldish [this message]

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=4BFCF67E.5060103@redhat.com \
    --to=mgoldish@redhat.com \
    --cc=autotest@test.kernel.org \
    --cc=fyang@redhat.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).