| Index: client/tests/kvm/kvm_vm.py
 | 
| diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 | 
| index f6f168486e6178b1de61b1d3ba72a27c1bbe80d2..a860437f6ea41e92d8f069b8bdc6e3a61d45e7f6 100755
 | 
| --- a/client/tests/kvm/kvm_vm.py
 | 
| +++ b/client/tests/kvm/kvm_vm.py
 | 
| @@ -24,8 +24,6 @@ def get_image_filename(params, root_dir):
 | 
|      """
 | 
|      image_name = params.get("image_name", "image")
 | 
|      image_format = params.get("image_format", "qcow2")
 | 
| -    if params.get("image_raw_device") == "yes":
 | 
| -        return image_name
 | 
|      image_filename = "%s.%s" % (image_name, image_format)
 | 
|      image_filename = kvm_utils.get_path(root_dir, image_filename)
 | 
|      return image_filename
 | 
| @@ -97,7 +95,7 @@ class VM:
 | 
|      This class handles all basic VM operations.
 | 
|      """
 | 
|  
 | 
| -    def __init__(self, name, params, root_dir, address_cache, state=None):
 | 
| +    def __init__(self, name, params, root_dir, address_cache):
 | 
|          """
 | 
|          Initialize the object and set a few attributes.
 | 
|  
 | 
| @@ -106,35 +104,30 @@ 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__
 | 
|          """
 | 
| -        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.process = None
 | 
| +        self.serial_console = None
 | 
| +        self.redirs = {}
 | 
| +        self.vnc_port = 5900
 | 
| +        self.monitors = []
 | 
| +        self.pci_assignable = None
 | 
| +        self.netdev_id = []
 | 
| +        self.uuid = None
 | 
|  
 | 
|          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,
 | 
| -              copy_state=False):
 | 
| +
 | 
| +    def clone(self, name=None, params=None, root_dir=None, address_cache=None):
 | 
|          """
 | 
|          Return a clone of the VM object with optionally modified parameters.
 | 
|          The clone is initially not alive and needs to be started using create().
 | 
| @@ -145,8 +138,6 @@ 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
 | 
| @@ -156,11 +147,7 @@ class VM:
 | 
|              root_dir = self.root_dir
 | 
|          if address_cache is None:
 | 
|              address_cache = self.address_cache
 | 
| -        if copy_state:
 | 
| -            state = self.__dict__.copy()
 | 
| -        else:
 | 
| -            state = None
 | 
| -        return VM(name, params, root_dir, address_cache, state)
 | 
| +        return VM(name, params, root_dir, address_cache)
 | 
|  
 | 
|  
 | 
|      def make_qemu_command(self, name=None, params=None, root_dir=None):
 | 
| @@ -249,22 +236,25 @@ class VM:
 | 
|  
 | 
|          def add_nic(help, vlan, model=None, mac=None, netdev_id=None,
 | 
|                      nic_extra_params=None):
 | 
| -            if has_option(help, "netdev"):
 | 
| -                netdev_vlan_str = ",netdev=%s" % netdev_id
 | 
| -            else:
 | 
| -                netdev_vlan_str = ",vlan=%d" % vlan
 | 
|              if has_option(help, "device"):
 | 
| +                if model == "virtio":
 | 
| +                    model="virtio-net-pci"
 | 
|                  if not model:
 | 
| -                    model = "rtl8139"
 | 
| -                elif model == "virtio":
 | 
| -                    model = "virtio-net-pci"
 | 
| -                cmd = " -device %s" % model + netdev_vlan_str
 | 
| +                    model= "rtl8139"
 | 
| +                cmd = " -device %s" % model
 | 
|                  if mac:
 | 
| -                    cmd += ",mac='%s'" % mac
 | 
| +                    cmd += ",mac=%s" % mac
 | 
| +                if has_option(help, "netdev"):
 | 
| +                    cmd += ",netdev=%s" % netdev_id
 | 
| +                else:
 | 
| +                    cmd += "vlan=%d,"  % vlan
 | 
|                  if nic_extra_params:
 | 
|                      cmd += ",%s" % nic_extra_params
 | 
|              else:
 | 
| -                cmd = " -net nic" + netdev_vlan_str
 | 
| +                if has_option(help, "netdev"):
 | 
| +                    cmd = " -net nic,netdev=%s" % netdev_id
 | 
| +                else:
 | 
| +                    cmd = " -net nic,vlan=%d" % vlan
 | 
|                  if model:
 | 
|                      cmd += ",model=%s" % model
 | 
|                  if mac:
 | 
| @@ -273,11 +263,11 @@ class VM:
 | 
|  
 | 
|          def add_net(help, vlan, mode, ifname=None, script=None,
 | 
|                      downscript=None, tftp=None, bootfile=None, hostfwd=[],
 | 
| -                    netdev_id=None, netdev_extra_params=None):
 | 
| +                    netdev_id=None, vhost=False):
 | 
|              if has_option(help, "netdev"):
 | 
|                  cmd = " -netdev %s,id=%s" % (mode, netdev_id)
 | 
| -                if netdev_extra_params:
 | 
| -                    cmd += ",%s" % netdev_extra_params
 | 
| +                if vhost:
 | 
| +                    cmd +=",vhost=on"
 | 
|              else:
 | 
|                  cmd = " -net %s,vlan=%d" % (mode, vlan)
 | 
|              if mode == "tap":
 | 
| @@ -361,9 +351,6 @@ 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
 | 
| @@ -381,19 +368,19 @@ class VM:
 | 
|          # Add the VM's name
 | 
|          qemu_cmd += add_name(help, name)
 | 
|          # Add monitors
 | 
| -        for monitor_name in params.objects("monitors"):
 | 
| -            monitor_params = params.object_params(monitor_name)
 | 
| -            monitor_filename = vm.get_monitor_filename(monitor_name)
 | 
| +        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)
 | 
|              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, vm.get_serial_console_filename())
 | 
| +        qemu_cmd += add_serial(help, self.get_serial_console_filename())
 | 
|  
 | 
| -        for image_name in params.objects("images"):
 | 
| -            image_params = params.object_params(image_name)
 | 
| +        for image_name in kvm_utils.get_sub_dict_names(params, "images"):
 | 
| +            image_params = kvm_utils.get_sub_dict(params, image_name)
 | 
|              if image_params.get("boot_drive") == "no":
 | 
|                  continue
 | 
|              qemu_cmd += add_drive(help,
 | 
| @@ -407,23 +394,20 @@ class VM:
 | 
|                                    image_params.get("image_boot") == "yes")
 | 
|  
 | 
|          redirs = []
 | 
| -        for redir_name in params.objects("redirs"):
 | 
| -            redir_params = params.object_params(redir_name)
 | 
| +        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 = vm.redirs.get(guest_port)
 | 
| +            host_port = self.redirs.get(guest_port)
 | 
|              redirs += [(host_port, guest_port)]
 | 
|  
 | 
|          vlan = 0
 | 
| -        for nic_name in params.objects("nics"):
 | 
| -            nic_params = params.object_params(nic_name)
 | 
| -            try:
 | 
| -                netdev_id = vm.netdev_id[vlan]
 | 
| -            except IndexError:
 | 
| -                netdev_id = None
 | 
| +        for nic_name in kvm_utils.get_sub_dict_names(params, "nics"):
 | 
| +            nic_params = kvm_utils.get_sub_dict(params, nic_name)
 | 
|              # Handle the '-net nic' part
 | 
| -            mac = vm.get_mac_address(vlan)
 | 
| +            mac = self.get_mac_address(vlan)
 | 
|              qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac,
 | 
| -                                netdev_id, nic_params.get("nic_extra_params"))
 | 
| +                                self.netdev_id[vlan],
 | 
| +                                nic_params.get("nic_extra_params"))
 | 
|              # Handle the '-net tap' or '-net user' part
 | 
|              script = nic_params.get("nic_script")
 | 
|              downscript = nic_params.get("nic_downscript")
 | 
| @@ -435,10 +419,11 @@ class VM:
 | 
|              if tftp:
 | 
|                  tftp = kvm_utils.get_path(root_dir, tftp)
 | 
|              qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"),
 | 
| -                                vm.get_ifname(vlan),
 | 
| +                                self.get_ifname(vlan),
 | 
|                                  script, downscript, tftp,
 | 
| -                                nic_params.get("bootp"), redirs, netdev_id,
 | 
| -                                nic_params.get("netdev_extra_params"))
 | 
| +                                nic_params.get("bootp"), redirs,
 | 
| +                                self.netdev_id[vlan],
 | 
| +                                nic_params.get("vhost")=="yes")
 | 
|              # Proceed to next NIC
 | 
|              vlan += 1
 | 
|  
 | 
| @@ -450,8 +435,9 @@ class VM:
 | 
|          if smp:
 | 
|              qemu_cmd += add_smp(help, smp)
 | 
|  
 | 
| -        for cdrom in params.objects("cdroms"):
 | 
| -            cdrom_params = params.object_params(cdrom)
 | 
| +        cdroms = kvm_utils.get_sub_dict_names(params, "cdroms")
 | 
| +        for cdrom in cdroms:
 | 
| +            cdrom_params = kvm_utils.get_sub_dict(params, cdrom)
 | 
|              iso = cdrom_params.get("cdrom")
 | 
|              if iso:
 | 
|                  qemu_cmd += add_cdrom(help, kvm_utils.get_path(root_dir, iso),
 | 
| @@ -491,27 +477,27 @@ class VM:
 | 
|              qemu_cmd += add_tcp_redir(help, host_port, guest_port)
 | 
|  
 | 
|          if params.get("display") == "vnc":
 | 
| -            qemu_cmd += add_vnc(help, vm.vnc_port)
 | 
| +            qemu_cmd += add_vnc(help, self.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, vm.uuid)
 | 
| +            qemu_cmd += add_uuid(help, self.uuid)
 | 
|          elif params.get("uuid"):
 | 
|              qemu_cmd += add_uuid(help, params.get("uuid"))
 | 
|  
 | 
|          if params.get("testdev") == "yes":
 | 
| -            qemu_cmd += add_testdev(help, vm.get_testlog_filename())
 | 
| +            qemu_cmd += add_testdev(help, self.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 vm.pci_assignable:
 | 
| -            for pci_id in vm.pa_pci_ids:
 | 
| +        if self.pci_assignable:
 | 
| +            for pci_id in self.pa_pci_ids:
 | 
|                  qemu_cmd += add_pcidevice(help, pci_id)
 | 
|  
 | 
|          extra_params = params.get("extra_params")
 | 
| @@ -522,7 +508,7 @@ class VM:
 | 
|  
 | 
|  
 | 
|      def create(self, name=None, params=None, root_dir=None, timeout=5.0,
 | 
| -               migration_mode=None, mac_source=None):
 | 
| +               migration_mode=None, migration_exec_cmd=None, mac_source=None):
 | 
|          """
 | 
|          Start the VM by running a qemu command.
 | 
|          All parameters are optional. If name, params or root_dir are not
 | 
| @@ -550,40 +536,38 @@ class VM:
 | 
|          params = self.params
 | 
|          root_dir = self.root_dir
 | 
|  
 | 
| -        # Verify the md5sum of the ISO images
 | 
| -        for cdrom in params.objects("cdroms"):
 | 
| -            cdrom_params = params.object_params(cdrom)
 | 
| -            iso = cdrom_params.get("cdrom")
 | 
| -            if iso:
 | 
| -                iso = kvm_utils.get_path(root_dir, iso)
 | 
| -                if not os.path.exists(iso):
 | 
| -                    logging.error("ISO file not found: %s" % iso)
 | 
| +        # Verify the md5sum of the ISO image
 | 
| +        iso = params.get("cdrom")
 | 
| +        if iso:
 | 
| +            iso = kvm_utils.get_path(root_dir, iso)
 | 
| +            if not os.path.exists(iso):
 | 
| +                logging.error("ISO file not found: %s" % iso)
 | 
| +                return False
 | 
| +            compare = False
 | 
| +            if params.get("md5sum_1m"):
 | 
| +                logging.debug("Comparing expected MD5 sum with MD5 sum of "
 | 
| +                              "first MB of ISO file...")
 | 
| +                actual_hash = utils.hash_file(iso, 1048576, method="md5")
 | 
| +                expected_hash = params.get("md5sum_1m")
 | 
| +                compare = True
 | 
| +            elif params.get("md5sum"):
 | 
| +                logging.debug("Comparing expected MD5 sum with MD5 sum of ISO "
 | 
| +                              "file...")
 | 
| +                actual_hash = utils.hash_file(iso, method="md5")
 | 
| +                expected_hash = params.get("md5sum")
 | 
| +                compare = True
 | 
| +            elif params.get("sha1sum"):
 | 
| +                logging.debug("Comparing expected SHA1 sum with SHA1 sum of "
 | 
| +                              "ISO file...")
 | 
| +                actual_hash = utils.hash_file(iso, method="sha1")
 | 
| +                expected_hash = params.get("sha1sum")
 | 
| +                compare = True
 | 
| +            if compare:
 | 
| +                if actual_hash == expected_hash:
 | 
| +                    logging.debug("Hashes match")
 | 
| +                else:
 | 
| +                    logging.error("Actual hash differs from expected one")
 | 
|                      return False
 | 
| -                compare = False
 | 
| -                if cdrom_params.get("md5sum_1m"):
 | 
| -                    logging.debug("Comparing expected MD5 sum with MD5 sum of "
 | 
| -                                  "first MB of ISO file...")
 | 
| -                    actual_hash = utils.hash_file(iso, 1048576, method="md5")
 | 
| -                    expected_hash = cdrom_params.get("md5sum_1m")
 | 
| -                    compare = True
 | 
| -                elif cdrom_params.get("md5sum"):
 | 
| -                    logging.debug("Comparing expected MD5 sum with MD5 sum of "
 | 
| -                                  "ISO file...")
 | 
| -                    actual_hash = utils.hash_file(iso, method="md5")
 | 
| -                    expected_hash = cdrom_params.get("md5sum")
 | 
| -                    compare = True
 | 
| -                elif cdrom_params.get("sha1sum"):
 | 
| -                    logging.debug("Comparing expected SHA1 sum with SHA1 sum "
 | 
| -                                  "of ISO file...")
 | 
| -                    actual_hash = utils.hash_file(iso, method="sha1")
 | 
| -                    expected_hash = cdrom_params.get("sha1sum")
 | 
| -                    compare = True
 | 
| -                if compare:
 | 
| -                    if actual_hash == expected_hash:
 | 
| -                        logging.debug("Hashes match")
 | 
| -                    else:
 | 
| -                        logging.error("Actual hash differs from expected one")
 | 
| -                        return False
 | 
|  
 | 
|          # Make sure the following code is not executed by more than one thread
 | 
|          # at the same time
 | 
| @@ -592,17 +576,15 @@ class VM:
 | 
|  
 | 
|          try:
 | 
|              # Handle port redirections
 | 
| -            redir_names = params.objects("redirs")
 | 
| +            redir_names = kvm_utils.get_sub_dict_names(params, "redirs")
 | 
|              host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names))
 | 
|              self.redirs = {}
 | 
|              for i in range(len(redir_names)):
 | 
| -                redir_params = params.object_params(redir_names[i])
 | 
| +                redir_params = kvm_utils.get_sub_dict(params, redir_names[i])
 | 
|                  guest_port = int(redir_params.get("guest_port"))
 | 
|                  self.redirs[guest_port] = host_ports[i]
 | 
|  
 | 
| -            # Generate netdev IDs for all NICs
 | 
| -            self.netdev_id = []
 | 
| -            for nic in params.objects("nics"):
 | 
| +            for nic in kvm_utils.get_sub_dict_names(params, "nics"):
 | 
|                  self.netdev_id.append(kvm_utils.generate_random_id())
 | 
|  
 | 
|              # Find available VNC port, if needed
 | 
| @@ -616,19 +598,13 @@ class VM:
 | 
|                  f.close()
 | 
|  
 | 
|              # Generate or copy MAC addresses for all NICs
 | 
| -            num_nics = len(params.objects("nics"))
 | 
| +            num_nics = len(kvm_utils.get_sub_dict_names(params, "nics"))
 | 
|              for vlan in range(num_nics):
 | 
| -                nic_name = params.objects("nics")[vlan]
 | 
| -                nic_params = params.object_params(nic_name)
 | 
| -                if nic_params.get("nic_mac", None):
 | 
| -                    mac = nic_params.get("nic_mac")
 | 
| +                mac = mac_source and mac_source.get_mac_address(vlan)
 | 
| +                if mac:
 | 
|                      kvm_utils.set_mac_address(self.instance, vlan, mac)
 | 
|                  else:
 | 
| -                    mac = mac_source and mac_source.get_mac_address(vlan)
 | 
| -                    if mac:
 | 
| -                        kvm_utils.set_mac_address(self.instance, vlan, mac)
 | 
| -                    else:
 | 
| -                        kvm_utils.generate_mac_address(self.instance, vlan)
 | 
| +                    kvm_utils.generate_mac_address(self.instance, vlan)
 | 
|  
 | 
|              # Assign a PCI assignable device
 | 
|              self.pci_assignable = None
 | 
| @@ -684,9 +660,7 @@ class VM:
 | 
|                  self.migration_file = "/tmp/migration-unix-%s" % self.instance
 | 
|                  qemu_command += " -incoming unix:%s" % self.migration_file
 | 
|              elif migration_mode == "exec":
 | 
| -                self.migration_port = kvm_utils.find_free_port(5200, 6000)
 | 
| -                qemu_command += (' -incoming "exec:nc -l %s"' %
 | 
| -                                 self.migration_port)
 | 
| +                qemu_command += ' -incoming "exec:%s"' % migration_exec_cmd
 | 
|  
 | 
|              logging.debug("Running qemu command:\n%s", qemu_command)
 | 
|              self.process = kvm_subprocess.run_bg(qemu_command, None,
 | 
| @@ -704,8 +678,9 @@ class VM:
 | 
|  
 | 
|              # Establish monitor connections
 | 
|              self.monitors = []
 | 
| -            for monitor_name in params.objects("monitors"):
 | 
| -                monitor_params = params.object_params(monitor_name)
 | 
| +            for monitor_name in kvm_utils.get_sub_dict_names(params,
 | 
| +                                                             "monitors"):
 | 
| +                monitor_params = kvm_utils.get_sub_dict(params, monitor_name)
 | 
|                  # Wait for monitor connection to succeed
 | 
|                  end_time = time.time() + timeout
 | 
|                  while time.time() < end_time:
 | 
| @@ -758,7 +733,7 @@ class VM:
 | 
|  
 | 
|              # Establish a session with the serial console -- requires a version
 | 
|              # of netcat that supports -U
 | 
| -            self.serial_console = kvm_subprocess.ShellSession(
 | 
| +            self.serial_console = kvm_subprocess.kvm_shell_session(
 | 
|                  "nc -U %s" % self.get_serial_console_filename(),
 | 
|                  auto_close=False,
 | 
|                  output_func=kvm_utils.log_line,
 | 
| @@ -851,7 +826,7 @@ class VM:
 | 
|                      os.unlink(self.migration_file)
 | 
|                  except OSError:
 | 
|                      pass
 | 
| -            num_nics = len(self.params.objects("nics"))
 | 
| +            num_nics = len(kvm_utils.get_sub_dict_names(self.params, "nics"))
 | 
|              for vlan in range(num_nics):
 | 
|                  self.free_mac_address(vlan)
 | 
|  
 | 
| @@ -910,7 +885,7 @@ class VM:
 | 
|          params).
 | 
|          """
 | 
|          return [self.get_monitor_filename(m) for m in
 | 
| -                self.params.objects("monitors")]
 | 
| +                kvm_utils.get_sub_dict_names(self.params, "monitors")]
 | 
|  
 | 
|  
 | 
|      def get_serial_console_filename(self):
 | 
| @@ -936,9 +911,9 @@ class VM:
 | 
|  
 | 
|          @param index: Index of the NIC whose address is requested.
 | 
|          """
 | 
| -        nics = self.params.objects("nics")
 | 
| +        nics = kvm_utils.get_sub_dict_names(self.params, "nics")
 | 
|          nic_name = nics[index]
 | 
| -        nic_params = self.params.object_params(nic_name)
 | 
| +        nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
 | 
|          if nic_params.get("nic_mode") == "tap":
 | 
|              mac = self.get_mac_address(index)
 | 
|              if not mac:
 | 
| @@ -971,8 +946,8 @@ class VM:
 | 
|          @return: If port redirection is used, return the host port redirected
 | 
|                  to guest port port. Otherwise return port.
 | 
|          """
 | 
| -        nic_name = self.params.objects("nics")[nic_index]
 | 
| -        nic_params = self.params.object_params(nic_name)
 | 
| +        nic_name = kvm_utils.get_sub_dict_names(self.params, "nics")[nic_index]
 | 
| +        nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
 | 
|          if nic_params.get("nic_mode") == "tap":
 | 
|              return port
 | 
|          else:
 | 
| @@ -988,9 +963,9 @@ class VM:
 | 
|  
 | 
|          @param nic_index: Index of the NIC
 | 
|          """
 | 
| -        nics = self.params.objects("nics")
 | 
| +        nics = kvm_utils.get_sub_dict_names(self.params, "nics")
 | 
|          nic_name = nics[nic_index]
 | 
| -        nic_params = self.params.object_params(nic_name)
 | 
| +        nic_params = kvm_utils.get_sub_dict(self.params, nic_name)
 | 
|          if nic_params.get("nic_ifname"):
 | 
|              return nic_params.get("nic_ifname")
 | 
|          else:
 | 
| @@ -1065,7 +1040,7 @@ class VM:
 | 
|          @param nic_index: The index of the NIC to connect to.
 | 
|          @param timeout: Time (seconds) before giving up logging into the
 | 
|                  guest.
 | 
| -        @return: ShellSession object on success and None on failure.
 | 
| +        @return: kvm_spawn object on success and None on failure.
 | 
|          """
 | 
|          username = self.params.get("username", "")
 | 
|          password = self.params.get("password", "")
 | 
| @@ -1093,7 +1068,7 @@ class VM:
 | 
|  
 | 
|      def copy_files_to(self, local_path, remote_path, nic_index=0, timeout=600):
 | 
|          """
 | 
| -        Transfer files to the remote host(guest).
 | 
| +        Transfer files to the guest.
 | 
|  
 | 
|          @param local_path: Host path
 | 
|          @param remote_path: Guest path
 | 
| @@ -1107,12 +1082,21 @@ class VM:
 | 
|          address = self.get_address(nic_index)
 | 
|          port = self.get_port(int(self.params.get("file_transfer_port")))
 | 
|  
 | 
| -        log_filename = ("transfer-%s-to-%s-%s.log" %
 | 
| -                        (self.name, address,
 | 
| -                        kvm_utils.generate_random_string(4)))
 | 
| -        return kvm_utils.copy_files_to(address, client, username, password,
 | 
| -                                       port, local_path, remote_path,
 | 
| -                                       log_filename, timeout)
 | 
| +        if not address or not port:
 | 
| +            logging.debug("IP address or port unavailable")
 | 
| +            return None
 | 
| +
 | 
| +        if client == "scp":
 | 
| +            log_filename = ("scp-%s-%s.log" %
 | 
| +                            (self.name, kvm_utils.generate_random_string(4)))
 | 
| +            return kvm_utils.scp_to_remote(address, port, username, password,
 | 
| +                                           local_path, remote_path,
 | 
| +                                           log_filename, timeout)
 | 
| +        elif client == "rss":
 | 
| +            c = rss_file_transfer.FileUploadClient(address, port)
 | 
| +            c.upload(local_path, remote_path, timeout)
 | 
| +            c.close()
 | 
| +            return True
 | 
|  
 | 
|  
 | 
|      def copy_files_from(self, remote_path, local_path, nic_index=0, timeout=600):
 | 
| @@ -1131,11 +1115,21 @@ class VM:
 | 
|          address = self.get_address(nic_index)
 | 
|          port = self.get_port(int(self.params.get("file_transfer_port")))
 | 
|  
 | 
| -        log_filename = ("transfer-%s-from-%s-%s.log" %
 | 
| -                        (self.name, address,
 | 
| -                        kvm_utils.generate_random_string(4)))
 | 
| -        return kvm_utils.copy_files_from(address, client, username, password,
 | 
| -                        port, local_path, remote_path, log_filename, timeout)
 | 
| +        if not address or not port:
 | 
| +            logging.debug("IP address or port unavailable")
 | 
| +            return None
 | 
| +
 | 
| +        if client == "scp":
 | 
| +            log_filename = ("scp-%s-%s.log" %
 | 
| +                            (self.name, kvm_utils.generate_random_string(4)))
 | 
| +            return kvm_utils.scp_from_remote(address, port, username, password,
 | 
| +                                             remote_path, local_path,
 | 
| +                                             log_filename, timeout)
 | 
| +        elif client == "rss":
 | 
| +            c = rss_file_transfer.FileDownloadClient(address, port)
 | 
| +            c.download(remote_path, local_path, timeout)
 | 
| +            c.close()
 | 
| +            return True
 | 
|  
 | 
|  
 | 
|      def serial_login(self, timeout=10):
 | 
| @@ -1145,7 +1139,7 @@ class VM:
 | 
|          password prompt or a shell prompt) -- fail.
 | 
|  
 | 
|          @param timeout: Time (seconds) before giving up logging into the guest.
 | 
| -        @return: ShellSession object on success and None on failure.
 | 
| +        @return: kvm_spawn object on success and None on failure.
 | 
|          """
 | 
|          username = self.params.get("username", "")
 | 
|          password = self.params.get("password", "")
 | 
| @@ -1219,7 +1213,11 @@ class VM:
 | 
|          if not session:
 | 
|              return None
 | 
|          try:
 | 
| -            return int(session.cmd(self.params.get("cpu_chk_cmd")))
 | 
| +            cmd = self.params.get("cpu_chk_cmd")
 | 
| +            s, count = session.get_command_status_output(cmd)
 | 
| +            if s == 0:
 | 
| +                return int(count)
 | 
| +            return None
 | 
|          finally:
 | 
|              session.close()
 | 
|  
 | 
| @@ -1237,7 +1235,9 @@ class VM:
 | 
|          try:
 | 
|              if not cmd:
 | 
|                  cmd = self.params.get("mem_chk_cmd")
 | 
| -            mem_str = session.cmd(cmd)
 | 
| +            s, mem_str = session.get_command_status_output(cmd)
 | 
| +            if s != 0:
 | 
| +                return None
 | 
|              mem = re.findall("([0-9]+)", mem_str)
 | 
|              mem_size = 0
 | 
|              for m in mem:
 | 
| @@ -1259,14 +1259,3 @@ class VM:
 | 
|          """
 | 
|          cmd = self.params.get("mem_chk_cur_cmd")
 | 
|          return self.get_memory_size(cmd)
 | 
| -
 | 
| -
 | 
| -    def save_to_file(self, path):
 | 
| -        """
 | 
| -        Save the state of virtual machine to a file through migrate to
 | 
| -        exec
 | 
| -        """
 | 
| -        # Make sure we only get one iteration
 | 
| -        self.monitor.cmd("migrate_set_speed 1000g")
 | 
| -        self.monitor.cmd("migrate_set_downtime 100000000")
 | 
| -        self.monitor.migrate('"exec:cat>%s"' % path)
 | 
| 
 |