OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 """ | 2 """ |
3 Utility classes and functions to handle Virtual Machine creation using qemu. | 3 Utility classes and functions to handle Virtual Machine creation using qemu. |
4 | 4 |
5 @copyright: 2008-2009 Red Hat Inc. | 5 @copyright: 2008-2009 Red Hat Inc. |
6 """ | 6 """ |
7 | 7 |
8 import time, socket, os, logging, fcntl, re, commands, glob | 8 import time, socket, os, logging, fcntl, re, commands, shelve, glob |
9 import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer | 9 import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer |
10 from autotest_lib.client.common_lib import error | 10 from autotest_lib.client.common_lib import error |
11 from autotest_lib.client.bin import utils | 11 from autotest_lib.client.bin import utils |
12 | 12 |
13 | 13 |
14 def get_image_filename(params, root_dir): | 14 def get_image_filename(params, root_dir): |
15 """ | 15 """ |
16 Generate an image path from params and root_dir. | 16 Generate an image path from params and root_dir. |
17 | 17 |
18 @param params: Dictionary containing the test parameters. | 18 @param params: Dictionary containing the test parameters. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 @param name: The name of the object | 102 @param name: The name of the object |
103 @param params: A dict containing VM params | 103 @param params: A dict containing VM params |
104 (see method make_qemu_command for a full description) | 104 (see method make_qemu_command for a full description) |
105 @param root_dir: Base directory for relative filenames | 105 @param root_dir: Base directory for relative filenames |
106 @param address_cache: A dict that maps MAC addresses to IP addresses | 106 @param address_cache: A dict that maps MAC addresses to IP addresses |
107 """ | 107 """ |
108 self.process = None | 108 self.process = None |
109 self.serial_console = None | 109 self.serial_console = None |
110 self.redirs = {} | 110 self.redirs = {} |
111 self.vnc_port = 5900 | 111 self.vnc_port = 5900 |
112 self.uuid = None | |
113 self.monitors = [] | 112 self.monitors = [] |
114 self.pci_assignable = None | 113 self.pci_assignable = None |
| 114 self.netdev_id = [] |
| 115 self.uuid = None |
115 | 116 |
116 self.name = name | 117 self.name = name |
117 self.params = params | 118 self.params = params |
118 self.root_dir = root_dir | 119 self.root_dir = root_dir |
119 self.address_cache = address_cache | 120 self.address_cache = address_cache |
120 self.netdev_id = [] | |
121 | 121 |
122 # Find a unique identifier for this VM | 122 # Find a unique identifier for this VM |
123 while True: | 123 while True: |
124 self.instance = (time.strftime("%Y%m%d-%H%M%S-") + | 124 self.instance = (time.strftime("%Y%m%d-%H%M%S-") + |
125 kvm_utils.generate_random_string(4)) | 125 kvm_utils.generate_random_string(4)) |
126 if not glob.glob("/tmp/*%s" % self.instance): | 126 if not glob.glob("/tmp/*%s" % self.instance): |
127 break | 127 break |
128 | 128 |
129 | 129 |
130 def clone(self, name=None, params=None, root_dir=None, address_cache=None): | 130 def clone(self, name=None, params=None, root_dir=None, address_cache=None): |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 cmd = " -drive file='%s'" % filename | 227 cmd = " -drive file='%s'" % filename |
228 if index is not None: cmd += ",index=%s" % index | 228 if index is not None: cmd += ",index=%s" % index |
229 if format: cmd += ",if=%s" % format | 229 if format: cmd += ",if=%s" % format |
230 if cache: cmd += ",cache=%s" % cache | 230 if cache: cmd += ",cache=%s" % cache |
231 if werror: cmd += ",werror=%s" % werror | 231 if werror: cmd += ",werror=%s" % werror |
232 if serial: cmd += ",serial='%s'" % serial | 232 if serial: cmd += ",serial='%s'" % serial |
233 if snapshot: cmd += ",snapshot=on" | 233 if snapshot: cmd += ",snapshot=on" |
234 if boot: cmd += ",boot=on" | 234 if boot: cmd += ",boot=on" |
235 return cmd | 235 return cmd |
236 | 236 |
237 def add_nic(help, vlan, model=None, mac=None, netdev_id=None): | 237 def add_nic(help, vlan, model=None, mac=None, netdev_id=None, |
238 if has_option(help, "netdev"): | 238 nic_extra_params=None): |
239 cmd = " -net nic,netdev=%s" % netdev_id | 239 if has_option(help, "device"): |
| 240 if model == "virtio": |
| 241 model="virtio-net-pci" |
| 242 if not model: |
| 243 model= "rtl8139" |
| 244 cmd = " -device %s" % model |
| 245 if mac: |
| 246 cmd += ",mac=%s" % mac |
| 247 if has_option(help, "netdev"): |
| 248 cmd += ",netdev=%s" % netdev_id |
| 249 else: |
| 250 cmd += "vlan=%d," % vlan |
| 251 if nic_extra_params: |
| 252 cmd += ",%s" % nic_extra_params |
240 else: | 253 else: |
241 cmd = " -net nic,vlan=%d" % vlan | 254 if has_option(help, "netdev"): |
242 if model: cmd += ",model=%s" % model | 255 cmd = " -net nic,netdev=%s" % netdev_id |
243 if mac: cmd += ",macaddr='%s'" % mac | 256 else: |
| 257 cmd = " -net nic,vlan=%d" % vlan |
| 258 if model: |
| 259 cmd += ",model=%s" % model |
| 260 if mac: |
| 261 cmd += ",macaddr='%s'" % mac |
244 return cmd | 262 return cmd |
245 | 263 |
246 def add_net(help, vlan, mode, ifname=None, script=None, | 264 def add_net(help, vlan, mode, ifname=None, script=None, |
247 downscript=None, tftp=None, bootfile=None, hostfwd=[], | 265 downscript=None, tftp=None, bootfile=None, hostfwd=[], |
248 netdev_id=None): | 266 netdev_id=None, vhost=False): |
249 if has_option(help, "netdev"): | 267 if has_option(help, "netdev"): |
250 cmd = " -netdev %s,id=%s" % (mode, netdev_id) | 268 cmd = " -netdev %s,id=%s" % (mode, netdev_id) |
| 269 if vhost: |
| 270 cmd +=",vhost=on" |
251 else: | 271 else: |
252 cmd = " -net %s,vlan=%d" % (mode, vlan) | 272 cmd = " -net %s,vlan=%d" % (mode, vlan) |
253 if mode == "tap": | 273 if mode == "tap": |
254 if ifname: cmd += ",ifname='%s'" % ifname | 274 if ifname: cmd += ",ifname='%s'" % ifname |
255 if script: cmd += ",script='%s'" % script | 275 if script: cmd += ",script='%s'" % script |
256 cmd += ",downscript='%s'" % (downscript or "no") | 276 cmd += ",downscript='%s'" % (downscript or "no") |
257 elif mode == "user": | 277 elif mode == "user": |
258 if tftp and "[,tftp=" in help: | 278 if tftp and "[,tftp=" in help: |
259 cmd += ",tftp='%s'" % tftp | 279 cmd += ",tftp='%s'" % tftp |
260 if bootfile and "[,bootfile=" in help: | 280 if bootfile and "[,bootfile=" in help: |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"): | 397 for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"): |
378 redir_params = kvm_utils.get_sub_dict(params, redir_name) | 398 redir_params = kvm_utils.get_sub_dict(params, redir_name) |
379 guest_port = int(redir_params.get("guest_port")) | 399 guest_port = int(redir_params.get("guest_port")) |
380 host_port = self.redirs.get(guest_port) | 400 host_port = self.redirs.get(guest_port) |
381 redirs += [(host_port, guest_port)] | 401 redirs += [(host_port, guest_port)] |
382 | 402 |
383 vlan = 0 | 403 vlan = 0 |
384 for nic_name in kvm_utils.get_sub_dict_names(params, "nics"): | 404 for nic_name in kvm_utils.get_sub_dict_names(params, "nics"): |
385 nic_params = kvm_utils.get_sub_dict(params, nic_name) | 405 nic_params = kvm_utils.get_sub_dict(params, nic_name) |
386 # Handle the '-net nic' part | 406 # Handle the '-net nic' part |
387 mac = None | 407 mac = self.get_mac_address(vlan) |
388 if "address_index" in nic_params: | |
389 mac = kvm_utils.get_mac_ip_pair_from_dict(nic_params)[0] | |
390 qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac, | 408 qemu_cmd += add_nic(help, vlan, nic_params.get("nic_model"), mac, |
391 self.netdev_id[vlan]) | 409 self.netdev_id[vlan], |
| 410 nic_params.get("nic_extra_params")) |
392 # Handle the '-net tap' or '-net user' part | 411 # Handle the '-net tap' or '-net user' part |
393 script = nic_params.get("nic_script") | 412 script = nic_params.get("nic_script") |
394 downscript = nic_params.get("nic_downscript") | 413 downscript = nic_params.get("nic_downscript") |
395 tftp = nic_params.get("tftp") | 414 tftp = nic_params.get("tftp") |
396 if script: | 415 if script: |
397 script = kvm_utils.get_path(root_dir, script) | 416 script = kvm_utils.get_path(root_dir, script) |
398 if downscript: | 417 if downscript: |
399 downscript = kvm_utils.get_path(root_dir, downscript) | 418 downscript = kvm_utils.get_path(root_dir, downscript) |
400 if tftp: | 419 if tftp: |
401 tftp = kvm_utils.get_path(root_dir, tftp) | 420 tftp = kvm_utils.get_path(root_dir, tftp) |
402 qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"), | 421 qemu_cmd += add_net(help, vlan, nic_params.get("nic_mode", "user"), |
403 nic_params.get("nic_ifname"), | 422 self.get_ifname(vlan), |
404 script, downscript, tftp, | 423 script, downscript, tftp, |
405 nic_params.get("bootp"), redirs, | 424 nic_params.get("bootp"), redirs, |
406 self.netdev_id[vlan]) | 425 self.netdev_id[vlan], |
| 426 nic_params.get("vhost")=="yes") |
407 # Proceed to next NIC | 427 # Proceed to next NIC |
408 vlan += 1 | 428 vlan += 1 |
409 | 429 |
410 mem = params.get("mem") | 430 mem = params.get("mem") |
411 if mem: | 431 if mem: |
412 qemu_cmd += add_mem(help, mem) | 432 qemu_cmd += add_mem(help, mem) |
413 | 433 |
414 smp = params.get("smp") | 434 smp = params.get("smp") |
415 if smp: | 435 if smp: |
416 qemu_cmd += add_smp(help, smp) | 436 qemu_cmd += add_smp(help, smp) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 for pci_id in self.pa_pci_ids: | 500 for pci_id in self.pa_pci_ids: |
481 qemu_cmd += add_pcidevice(help, pci_id) | 501 qemu_cmd += add_pcidevice(help, pci_id) |
482 | 502 |
483 extra_params = params.get("extra_params") | 503 extra_params = params.get("extra_params") |
484 if extra_params: | 504 if extra_params: |
485 qemu_cmd += " %s" % extra_params | 505 qemu_cmd += " %s" % extra_params |
486 | 506 |
487 return qemu_cmd | 507 return qemu_cmd |
488 | 508 |
489 | 509 |
490 def create(self, name=None, params=None, root_dir=None, | 510 def create(self, name=None, params=None, root_dir=None, timeout=5.0, |
491 for_migration=False, timeout=5.0, extra_params=None): | 511 migration_mode=None, migration_exec_cmd=None, mac_source=None): |
492 """ | 512 """ |
493 Start the VM by running a qemu command. | 513 Start the VM by running a qemu command. |
494 All parameters are optional. The following applies to all parameters | 514 All parameters are optional. If name, params or root_dir are not |
495 but for_migration: If a parameter is not supplied, the corresponding | 515 supplied, the respective values stored as class attributes are used. |
496 value stored in the class attributes is used, and if it is supplied, | |
497 it is stored for later use. | |
498 | 516 |
499 @param name: The name of the object | 517 @param name: The name of the object |
500 @param params: A dict containing VM params | 518 @param params: A dict containing VM params |
501 @param root_dir: Base directory for relative filenames | 519 @param root_dir: Base directory for relative filenames |
502 @param for_migration: If True, start the VM with the -incoming | 520 @param migration_mode: If supplied, start VM for incoming migration |
503 option | 521 using this protocol (either 'tcp', 'unix' or 'exec') |
504 @param extra_params: extra params for qemu command.e.g -incoming option | 522 @param migration_exec_cmd: Command to embed in '-incoming "exec: ..."' |
505 Please use this parameter instead of for_migration. | 523 (e.g. 'gzip -c -d filename') if migration_mode is 'exec' |
| 524 @param mac_source: A VM object from which to copy MAC addresses. If not |
| 525 specified, new addresses will be generated. |
506 """ | 526 """ |
507 self.destroy() | 527 self.destroy() |
508 | 528 |
509 if name is not None: | 529 if name is not None: |
510 self.name = name | 530 self.name = name |
511 if params is not None: | 531 if params is not None: |
512 self.params = params | 532 self.params = params |
513 if root_dir is not None: | 533 if root_dir is not None: |
514 self.root_dir = root_dir | 534 self.root_dir = root_dir |
515 name = self.name | 535 name = self.name |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 # Find available VNC port, if needed | 590 # Find available VNC port, if needed |
571 if params.get("display") == "vnc": | 591 if params.get("display") == "vnc": |
572 self.vnc_port = kvm_utils.find_free_port(5900, 6100) | 592 self.vnc_port = kvm_utils.find_free_port(5900, 6100) |
573 | 593 |
574 # Find random UUID if specified 'uuid = random' in config file | 594 # Find random UUID if specified 'uuid = random' in config file |
575 if params.get("uuid") == "random": | 595 if params.get("uuid") == "random": |
576 f = open("/proc/sys/kernel/random/uuid") | 596 f = open("/proc/sys/kernel/random/uuid") |
577 self.uuid = f.read().strip() | 597 self.uuid = f.read().strip() |
578 f.close() | 598 f.close() |
579 | 599 |
| 600 # Generate or copy MAC addresses for all NICs |
| 601 num_nics = len(kvm_utils.get_sub_dict_names(params, "nics")) |
| 602 for vlan in range(num_nics): |
| 603 mac = mac_source and mac_source.get_mac_address(vlan) |
| 604 if mac: |
| 605 kvm_utils.set_mac_address(self.instance, vlan, mac) |
| 606 else: |
| 607 kvm_utils.generate_mac_address(self.instance, vlan) |
| 608 |
580 # Assign a PCI assignable device | 609 # Assign a PCI assignable device |
581 self.pci_assignable = None | 610 self.pci_assignable = None |
582 pa_type = params.get("pci_assignable") | 611 pa_type = params.get("pci_assignable") |
583 if pa_type in ["vf", "pf", "mixed"]: | 612 if pa_type in ["vf", "pf", "mixed"]: |
584 pa_devices_requested = params.get("devices_requested") | 613 pa_devices_requested = params.get("devices_requested") |
585 | 614 |
586 # Virtual Functions (VF) assignable devices | 615 # Virtual Functions (VF) assignable devices |
587 if pa_type == "vf": | 616 if pa_type == "vf": |
588 self.pci_assignable = kvm_utils.PciAssignable( | 617 self.pci_assignable = kvm_utils.PciAssignable( |
589 type=pa_type, | 618 type=pa_type, |
(...skipping 26 matching lines...) Expand all Loading... |
616 "on your config file. Aborting VM creation.", | 645 "on your config file. Aborting VM creation.", |
617 pa_type) | 646 pa_type) |
618 return False | 647 return False |
619 | 648 |
620 elif pa_type and pa_type != "no": | 649 elif pa_type and pa_type != "no": |
621 logging.warn("Unsupported pci_assignable type: %s", pa_type) | 650 logging.warn("Unsupported pci_assignable type: %s", pa_type) |
622 | 651 |
623 # Make qemu command | 652 # Make qemu command |
624 qemu_command = self.make_qemu_command() | 653 qemu_command = self.make_qemu_command() |
625 | 654 |
626 # Enable migration support for VM by adding extra_params. | 655 # Add migration parameters if required |
627 if extra_params is not None: | 656 if migration_mode == "tcp": |
628 if " -incoming tcp:0:%d" == extra_params: | 657 self.migration_port = kvm_utils.find_free_port(5200, 6000) |
629 self.migration_port = kvm_utils.find_free_port(5200, 6000) | 658 qemu_command += " -incoming tcp:0:%d" % self.migration_port |
630 qemu_command += extra_params % self.migration_port | 659 elif migration_mode == "unix": |
631 elif " -incoming unix:%s" == extra_params: | 660 self.migration_file = "/tmp/migration-unix-%s" % self.instance |
632 self.migration_file = os.path.join("/tmp/", "unix-" + | 661 qemu_command += " -incoming unix:%s" % self.migration_file |
633 time.strftime("%Y%m%d-%H%M%S")) | 662 elif migration_mode == "exec": |
634 qemu_command += extra_params % self.migration_file | 663 qemu_command += ' -incoming "exec:%s"' % migration_exec_cmd |
635 else: | |
636 qemu_command += extra_params | |
637 | 664 |
638 logging.debug("Running qemu command:\n%s", qemu_command) | 665 logging.debug("Running qemu command:\n%s", qemu_command) |
639 self.process = kvm_subprocess.run_bg(qemu_command, None, | 666 self.process = kvm_subprocess.run_bg(qemu_command, None, |
640 logging.debug, "(qemu) ") | 667 logging.debug, "(qemu) ") |
641 | 668 |
642 # Make sure the process was started successfully | 669 # Make sure the process was started successfully |
643 if not self.process.is_alive(): | 670 if not self.process.is_alive(): |
644 logging.error("VM could not be created; " | 671 logging.error("VM could not be created; " |
645 "qemu command failed:\n%s" % qemu_command) | 672 "qemu command failed:\n%s" % qemu_command) |
646 logging.error("Status: %s" % self.process.get_status()) | 673 logging.error("Status: %s" % self.process.get_status()) |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 # Try to destroy with shell command | 770 # Try to destroy with shell command |
744 logging.debug("Trying to shutdown VM with shell command...") | 771 logging.debug("Trying to shutdown VM with shell command...") |
745 session = self.remote_login() | 772 session = self.remote_login() |
746 if session: | 773 if session: |
747 try: | 774 try: |
748 # Send the shutdown command | 775 # Send the shutdown command |
749 session.sendline(self.params.get("shutdown_command")) | 776 session.sendline(self.params.get("shutdown_command")) |
750 logging.debug("Shutdown command sent; waiting for VM " | 777 logging.debug("Shutdown command sent; waiting for VM " |
751 "to go down...") | 778 "to go down...") |
752 if kvm_utils.wait_for(self.is_dead, 60, 1, 1): | 779 if kvm_utils.wait_for(self.is_dead, 60, 1, 1): |
753 logging.debug("VM is down") | 780 logging.debug("VM is down, freeing mac address.") |
754 return | 781 return |
755 finally: | 782 finally: |
756 session.close() | 783 session.close() |
757 | 784 |
758 if self.monitor: | 785 if self.monitor: |
759 # Try to destroy with a monitor command | 786 # Try to destroy with a monitor command |
760 logging.debug("Trying to kill VM with monitor command...") | 787 logging.debug("Trying to kill VM with monitor command...") |
761 try: | 788 try: |
762 self.monitor.quit() | 789 self.monitor.quit() |
763 except kvm_monitor.MonitorError, e: | 790 except kvm_monitor.MonitorError, e: |
(...skipping 23 matching lines...) Expand all Loading... |
787 self.process.close() | 814 self.process.close() |
788 if self.serial_console: | 815 if self.serial_console: |
789 self.serial_console.close() | 816 self.serial_console.close() |
790 for f in ([self.get_testlog_filename(), | 817 for f in ([self.get_testlog_filename(), |
791 self.get_serial_console_filename()] + | 818 self.get_serial_console_filename()] + |
792 self.get_monitor_filenames()): | 819 self.get_monitor_filenames()): |
793 try: | 820 try: |
794 os.unlink(f) | 821 os.unlink(f) |
795 except OSError: | 822 except OSError: |
796 pass | 823 pass |
| 824 if hasattr(self, "migration_file"): |
| 825 try: |
| 826 os.unlink(self.migration_file) |
| 827 except OSError: |
| 828 pass |
| 829 num_nics = len(kvm_utils.get_sub_dict_names(self.params, "nics")) |
| 830 for vlan in range(num_nics): |
| 831 self.free_mac_address(vlan) |
797 | 832 |
798 | 833 |
799 @property | 834 @property |
800 def monitor(self): | 835 def monitor(self): |
801 """ | 836 """ |
802 Return the main monitor object, selected by the parameter main_monitor. | 837 Return the main monitor object, selected by the parameter main_monitor. |
803 If main_monitor isn't defined, return the first monitor. | 838 If main_monitor isn't defined, return the first monitor. |
804 If no monitors exist, or if main_monitor refers to a nonexistent | 839 If no monitors exist, or if main_monitor refers to a nonexistent |
805 monitor, return None. | 840 monitor, return None. |
806 """ | 841 """ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 | 908 |
874 If port redirection is used, return 'localhost' (the NIC has no IP | 909 If port redirection is used, return 'localhost' (the NIC has no IP |
875 address of its own). Otherwise return the NIC's IP address. | 910 address of its own). Otherwise return the NIC's IP address. |
876 | 911 |
877 @param index: Index of the NIC whose address is requested. | 912 @param index: Index of the NIC whose address is requested. |
878 """ | 913 """ |
879 nics = kvm_utils.get_sub_dict_names(self.params, "nics") | 914 nics = kvm_utils.get_sub_dict_names(self.params, "nics") |
880 nic_name = nics[index] | 915 nic_name = nics[index] |
881 nic_params = kvm_utils.get_sub_dict(self.params, nic_name) | 916 nic_params = kvm_utils.get_sub_dict(self.params, nic_name) |
882 if nic_params.get("nic_mode") == "tap": | 917 if nic_params.get("nic_mode") == "tap": |
883 mac, ip = kvm_utils.get_mac_ip_pair_from_dict(nic_params) | 918 mac = self.get_mac_address(index) |
884 if not mac: | 919 if not mac: |
885 logging.debug("MAC address unavailable") | 920 logging.debug("MAC address unavailable") |
886 return None | 921 return None |
887 if not ip or nic_params.get("always_use_tcpdump") == "yes": | 922 mac = mac.lower() |
888 # Get the IP address from the cache | 923 # Get the IP address from the cache |
889 ip = self.address_cache.get(mac) | 924 ip = self.address_cache.get(mac) |
890 if not ip: | 925 if not ip: |
891 logging.debug("Could not find IP address for MAC address: " | 926 logging.debug("Could not find IP address for MAC address: %s" % |
892 "%s" % mac) | 927 mac) |
893 return None | 928 return None |
894 # Make sure the IP address is assigned to this guest | 929 # Make sure the IP address is assigned to this guest |
895 nic_dicts = [kvm_utils.get_sub_dict(self.params, nic) | 930 macs = [self.get_mac_address(i) for i in range(len(nics))] |
896 for nic in nics] | 931 if not kvm_utils.verify_ip_address_ownership(ip, macs): |
897 macs = [kvm_utils.get_mac_ip_pair_from_dict(dict)[0] | 932 logging.debug("Could not verify MAC-IP address mapping: " |
898 for dict in nic_dicts] | 933 "%s ---> %s" % (mac, ip)) |
899 if not kvm_utils.verify_ip_address_ownership(ip, macs): | 934 return None |
900 logging.debug("Could not verify MAC-IP address mapping: " | |
901 "%s ---> %s" % (mac, ip)) | |
902 return None | |
903 return ip | 935 return ip |
904 else: | 936 else: |
905 return "localhost" | 937 return "localhost" |
906 | 938 |
907 | 939 |
908 def get_port(self, port, nic_index=0): | 940 def get_port(self, port, nic_index=0): |
909 """ | 941 """ |
910 Return the port in host space corresponding to port in guest space. | 942 Return the port in host space corresponding to port in guest space. |
911 | 943 |
912 @param port: Port number in host space. | 944 @param port: Port number in host space. |
913 @param nic_index: Index of the NIC. | 945 @param nic_index: Index of the NIC. |
914 @return: If port redirection is used, return the host port redirected | 946 @return: If port redirection is used, return the host port redirected |
915 to guest port port. Otherwise return port. | 947 to guest port port. Otherwise return port. |
916 """ | 948 """ |
917 nic_name = kvm_utils.get_sub_dict_names(self.params, "nics")[nic_index] | 949 nic_name = kvm_utils.get_sub_dict_names(self.params, "nics")[nic_index] |
918 nic_params = kvm_utils.get_sub_dict(self.params, nic_name) | 950 nic_params = kvm_utils.get_sub_dict(self.params, nic_name) |
919 if nic_params.get("nic_mode") == "tap": | 951 if nic_params.get("nic_mode") == "tap": |
920 return port | 952 return port |
921 else: | 953 else: |
922 if not self.redirs.has_key(port): | 954 if not self.redirs.has_key(port): |
923 logging.warn("Warning: guest port %s requested but not " | 955 logging.warn("Warning: guest port %s requested but not " |
924 "redirected" % port) | 956 "redirected" % port) |
925 return self.redirs.get(port) | 957 return self.redirs.get(port) |
926 | 958 |
927 | 959 |
| 960 def get_ifname(self, nic_index=0): |
| 961 """ |
| 962 Return the ifname of a tap device associated with a NIC. |
| 963 |
| 964 @param nic_index: Index of the NIC |
| 965 """ |
| 966 nics = kvm_utils.get_sub_dict_names(self.params, "nics") |
| 967 nic_name = nics[nic_index] |
| 968 nic_params = kvm_utils.get_sub_dict(self.params, nic_name) |
| 969 if nic_params.get("nic_ifname"): |
| 970 return nic_params.get("nic_ifname") |
| 971 else: |
| 972 return "t%d-%s" % (nic_index, self.instance[-11:]) |
| 973 |
| 974 |
| 975 def get_mac_address(self, nic_index=0): |
| 976 """ |
| 977 Return the MAC address of a NIC. |
| 978 |
| 979 @param nic_index: Index of the NIC |
| 980 """ |
| 981 return kvm_utils.get_mac_address(self.instance, nic_index) |
| 982 |
| 983 |
| 984 def free_mac_address(self, nic_index=0): |
| 985 """ |
| 986 Free a NIC's MAC address. |
| 987 |
| 988 @param nic_index: Index of the NIC |
| 989 """ |
| 990 kvm_utils.free_mac_address(self.instance, nic_index) |
| 991 |
| 992 |
928 def get_pid(self): | 993 def get_pid(self): |
929 """ | 994 """ |
930 Return the VM's PID. If the VM is dead return None. | 995 Return the VM's PID. If the VM is dead return None. |
931 | 996 |
932 @note: This works under the assumption that self.process.get_pid() | 997 @note: This works under the assumption that self.process.get_pid() |
933 returns the PID of the parent shell process. | 998 returns the PID of the parent shell process. |
934 """ | 999 """ |
935 try: | 1000 try: |
936 children = commands.getoutput("ps --ppid=%d -o pid=" % | 1001 children = commands.getoutput("ps --ppid=%d -o pid=" % |
937 self.process.get_pid()).split() | 1002 self.process.get_pid()).split() |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 finally: | 1252 finally: |
1188 session.close() | 1253 session.close() |
1189 | 1254 |
1190 | 1255 |
1191 def get_current_memory_size(self): | 1256 def get_current_memory_size(self): |
1192 """ | 1257 """ |
1193 Get current memory size of the VM, rather than bootup memory. | 1258 Get current memory size of the VM, rather than bootup memory. |
1194 """ | 1259 """ |
1195 cmd = self.params.get("mem_chk_cur_cmd") | 1260 cmd = self.params.get("mem_chk_cur_cmd") |
1196 return self.get_memory_size(cmd) | 1261 return self.get_memory_size(cmd) |
OLD | NEW |