public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Michael Goldish <mgoldish@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org
Subject: [KVM-AUTOTEST PATCH 12/28] KVM test: use VM.clone() in make_qemu_command()
Date: Mon, 27 Dec 2010 18:01:39 +0200	[thread overview]
Message-ID: <1293465715-16599-12-git-send-email-mgoldish@redhat.com> (raw)
In-Reply-To: <1293465715-16599-1-git-send-email-mgoldish@redhat.com>

When make_qemu_command() is called in order to see if a VM should be restarted
using a different qemu command line, construction of the qemu command should be
based only on the parameters provided to make_qemu_command() (name, params,
root_dir).  However, some VM methods are called which use the internal state of
the VM (self.params).  For example, when calling make_qemu_command() with
params that define 3 NICs, for a VM that currently has only 1 NIC,
make_qemu_command() will call VM.get_ifname() for 2 NICs that don't exist in
self.params.
To solve this, allow VM.clone() to copy the state of the VM to the clone, and
use such a clone with altered params in make_qemu_command(), instead of using
'self'.  That way, all methods that use self.params will use the correct
(altered) params in make_qemu_command().

Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
 client/tests/kvm/kvm_vm.py |   72 ++++++++++++++++++++++++++-----------------
 1 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index aeb7448..b80d2c2 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -97,7 +97,7 @@ class VM:
     This class handles all basic VM operations.
     """
 
-    def __init__(self, name, params, root_dir, address_cache):
+    def __init__(self, name, params, root_dir, address_cache, state=None):
         """
         Initialize the object and set a few attributes.
 
@@ -106,30 +106,35 @@ class VM:
                 (see method make_qemu_command for a full description)
         @param root_dir: Base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
+        @param state: If provided, use this as self.__dict__
         """
-        self.process = None
-        self.serial_console = None
-        self.redirs = {}
-        self.vnc_port = 5900
-        self.monitors = []
-        self.pci_assignable = None
-        self.netdev_id = []
-        self.uuid = None
+        if state:
+            self.__dict__ = state
+        else:
+            self.process = None
+            self.serial_console = None
+            self.redirs = {}
+            self.vnc_port = 5900
+            self.monitors = []
+            self.pci_assignable = None
+            self.netdev_id = []
+            self.uuid = None
+
+            # Find a unique identifier for this VM
+            while True:
+                self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
+                                 kvm_utils.generate_random_string(4))
+                if not glob.glob("/tmp/*%s" % self.instance):
+                    break
 
         self.name = name
         self.params = params
         self.root_dir = root_dir
         self.address_cache = address_cache
 
-        # Find a unique identifier for this VM
-        while True:
-            self.instance = (time.strftime("%Y%m%d-%H%M%S-") +
-                             kvm_utils.generate_random_string(4))
-            if not glob.glob("/tmp/*%s" % self.instance):
-                break
-
 
-    def clone(self, name=None, params=None, root_dir=None, address_cache=None):
+    def clone(self, name=None, params=None, root_dir=None, address_cache=None,
+              copy_state=False):
         """
         Return a clone of the VM object with optionally modified parameters.
         The clone is initially not alive and needs to be started using create().
@@ -140,6 +145,8 @@ class VM:
         @param params: Optional new VM creation parameters
         @param root_dir: Optional new base directory for relative filenames
         @param address_cache: A dict that maps MAC addresses to IP addresses
+        @param copy_state: If True, copy the original VM's state to the clone.
+                Mainly useful for make_qemu_command().
         """
         if name is None:
             name = self.name
@@ -149,7 +156,11 @@ class VM:
             root_dir = self.root_dir
         if address_cache is None:
             address_cache = self.address_cache
-        return VM(name, params, root_dir, address_cache)
+        if copy_state:
+            state = self.__dict__.copy()
+        else:
+            state = None
+        return VM(name, params, root_dir, address_cache, state)
 
 
     def make_qemu_command(self, name=None, params=None, root_dir=None):
@@ -350,6 +361,9 @@ class VM:
         if params is None: params = self.params
         if root_dir is None: root_dir = self.root_dir
 
+        # Clone this VM using the new params
+        vm = self.clone(name, params, root_dir, copy_state=True)
+
         qemu_binary = kvm_utils.get_path(root_dir, params.get("qemu_binary",
                                                               "qemu"))
         # Get the output of 'qemu -help' (log a message in case this call never
@@ -369,14 +383,14 @@ class VM:
         # Add monitors
         for monitor_name in kvm_utils.get_sub_dict_names(params, "monitors"):
             monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
-            monitor_filename = self.get_monitor_filename(monitor_name)
+            monitor_filename = vm.get_monitor_filename(monitor_name)
             if monitor_params.get("monitor_type") == "qmp":
                 qemu_cmd += add_qmp_monitor(help, monitor_filename)
             else:
                 qemu_cmd += add_human_monitor(help, monitor_filename)
 
         # Add serial console redirection
-        qemu_cmd += add_serial(help, self.get_serial_console_filename())
+        qemu_cmd += add_serial(help, vm.get_serial_console_filename())
 
         for image_name in kvm_utils.get_sub_dict_names(params, "images"):
             image_params = kvm_utils.get_sub_dict(params, image_name)
@@ -396,18 +410,18 @@ class VM:
         for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"):
             redir_params = kvm_utils.get_sub_dict(params, redir_name)
             guest_port = int(redir_params.get("guest_port"))
-            host_port = self.redirs.get(guest_port)
+            host_port = vm.redirs.get(guest_port)
             redirs += [(host_port, guest_port)]
 
         vlan = 0
         for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
             nic_params = kvm_utils.get_sub_dict(params, nic_name)
             try:
-                netdev_id = self.netdev_id[vlan]
+                netdev_id = vm.netdev_id[vlan]
             except IndexError:
                 netdev_id = None
             # Handle the '-net nic' part
-            mac = self.get_mac_address(vlan)
+            mac = vm.get_mac_address(vlan)
             qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac,
                                 netdev_id, nic_params.get("nic_extra_params"))
             # Handle the '-net tap' or '-net user' part
@@ -421,7 +435,7 @@ class VM:
             if tftp:
                 tftp = kvm_utils.get_path(root_dir, tftp)
             qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"),
-                                self.get_ifname(vlan),
+                                vm.get_ifname(vlan),
                                 script, downscript, tftp,
                                 nic_params.get("bootp"), redirs, netdev_id,
                                 nic_params.get("vhost") == "yes")
@@ -478,27 +492,27 @@ class VM:
             qemu_cmd += add_tcp_redir(help, host_port, guest_port)
 
         if params.get("display") == "vnc":
-            qemu_cmd += add_vnc(help, self.vnc_port)
+            qemu_cmd += add_vnc(help, vm.vnc_port)
         elif params.get("display") == "sdl":
             qemu_cmd += add_sdl(help)
         elif params.get("display") == "nographic":
             qemu_cmd += add_nographic(help)
 
         if params.get("uuid") == "random":
-            qemu_cmd += add_uuid(help, self.uuid)
+            qemu_cmd += add_uuid(help, vm.uuid)
         elif params.get("uuid"):
             qemu_cmd += add_uuid(help, params.get("uuid"))
 
         if params.get("testdev") == "yes":
-            qemu_cmd += add_testdev(help, self.get_testlog_filename())
+            qemu_cmd += add_testdev(help, vm.get_testlog_filename())
 
         if params.get("disable_hpet") == "yes":
             qemu_cmd += add_no_hpet(help)
 
         # If the PCI assignment step went OK, add each one of the PCI assigned
         # devices to the qemu command line.
-        if self.pci_assignable:
-            for pci_id in self.pa_pci_ids:
+        if vm.pci_assignable:
+            for pci_id in vm.pa_pci_ids:
                 qemu_cmd += add_pcidevice(help, pci_id)
 
         extra_params = params.get("extra_params")
-- 
1.7.3.3

  parent reply	other threads:[~2010-12-27 16:01 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-27 16:01 [KVM-AUTOTEST PATCH 01/28] KVM test: introduce a helper class to run a function in the background Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 02/28] KVM test: kvm_utils.py: add a convenience function to run functions in parallel Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 03/28] KVM test: corrections to migration_with_reboot Michael Goldish
2010-12-28 12:25   ` [Autotest] " Jason Wang
2010-12-28 12:42     ` Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 04/28] KVM test: migration_with_reboot: use kvm_utils.Thread Michael Goldish
2010-12-28 12:27   ` [Autotest] " Jason Wang
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 05/28] KVM test: vmstop: " Michael Goldish
2010-12-28 12:29   ` [Autotest] " Jason Wang
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 06/28] KVM test: migration_with_file_transfer: " Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 07/28] KVM test: migration_with_file_transfer: use unique host filename Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 08/28] KVM test: migration_with_file_transfer: verify transfer correctness Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 09/28] KVM test: remove kvm_test_utils.BackgroundTest Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 10/28] KVM test: avoid printing address cache messages too often Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 11/28] KVM test: make_qemu_command(): catch IndexError when accessing self.netdev_id Michael Goldish
2010-12-28 13:23   ` [Autotest] " Jason Wang
2010-12-28 14:23     ` Michael Goldish
2010-12-27 16:01 ` Michael Goldish [this message]
2010-12-28 13:13   ` [KVM-AUTOTEST PATCH 12/28] KVM test: use VM.clone() in make_qemu_command() Jason Wang
2010-12-28 14:17     ` Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 13/28] KVM test: don't print the contents of env before and after tests Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 14/28] KVM test: fix md5sum verification of ISO files Michael Goldish
2010-12-28 13:25   ` Jason Wang
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 15/28] KVM test: kvm_subprocess.py: increase default timeout from 30 to 60 secs Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 16/28] KVM test: whql_submission: run a user specified shell command before the test Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 17/28] KVM test: whql_submission: make the HDD tests run on a non-system drive Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 18/28] KVM test: whql: rename the whql_submission variant to whql.submission Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 19/28] KVM test: whql.submission: don't run jobs that require manual intervention Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 20/28] KVM test: whql.submission: add unclassified USB tablet tests Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 21/28] KVM test: refactor whql_submission_15.cs and whql_submission.py Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 22/28] KVM test: whql: add a network submission Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 23/28] KVM test: whql.submission: use a different submission name for each submission category Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 24/28] KVM test: whql.client_install: setup auto logon for DTMLLUAdminUser Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 25/28] KVM test: whql.submission: don't use any cdroms Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 26/28] KVM test: whql.submission: support VirtIO network tests Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 27/28] KVM test: whql.submission: reorder DeviceData Michael Goldish
2010-12-27 16:01 ` [KVM-AUTOTEST PATCH 28/28] KVM test: whql_submission.py: log in using all NICs before running tests 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=1293465715-16599-12-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox