| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 """ | 3 """ |
| 4 Auxiliary script used to send data between ports on guests. | 4 Auxiliary script used to send data between ports on guests. |
| 5 | 5 |
| 6 @copyright: 2010 Red Hat, Inc. | 6 @copyright: 2010 Red Hat, Inc. |
| 7 @author: Jiri Zupka (jzupka@redhat.com) | 7 @author: Jiri Zupka (jzupka@redhat.com) |
| 8 @author: Lukas Doktor (ldoktor@redhat.com) | 8 @author: Lukas Doktor (ldoktor@redhat.com) |
| 9 """ | 9 """ |
| 10 import threading | 10 import threading |
| 11 from threading import Thread | 11 from threading import Thread |
| 12 import os, select, re, random, sys, array | 12 import os, select, re, random, sys, array |
| 13 import fcntl, traceback, signal | 13 import fcntl, traceback, signal |
| 14 | 14 |
| 15 DEBUGPATH = "/sys/kernel/debug" | 15 DEBUGPATH = "/sys/kernel/debug" |
| 16 SYSFSPATH = "/sys/class/virtio-ports/" | 16 SYSFSPATH = "/sys/class/virtio-ports/" |
| 17 DEVPATH = "/dev/virtio-ports/" |
| 17 | 18 |
| 18 exiting = False | 19 exiting = False |
| 19 | 20 |
| 20 class VirtioGuest: | 21 class VirtioGuest: |
| 21 """ | 22 """ |
| 22 Test tools of virtio_ports. | 23 Test tools of virtio_ports. |
| 23 """ | 24 """ |
| 24 LOOP_NONE = 0 | 25 LOOP_NONE = 0 |
| 25 LOOP_POLL = 1 | 26 LOOP_POLL = 1 |
| 26 LOOP_SELECT = 2 | 27 LOOP_SELECT = 2 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 46 try: | 47 try: |
| 47 f = open(name, "r") | 48 f = open(name, "r") |
| 48 out = f.read() | 49 out = f.read() |
| 49 f.close() | 50 f.close() |
| 50 except: | 51 except: |
| 51 print "FAIL: Cannot open file %s" % (name) | 52 print "FAIL: Cannot open file %s" % (name) |
| 52 | 53 |
| 53 return out | 54 return out |
| 54 | 55 |
| 55 | 56 |
| 56 def _get_port_status(self): | 57 def _get_port_status(self, in_files=None): |
| 57 """ | 58 """ |
| 58 Get info about ports from kernel debugfs. | 59 Get info about ports from kernel debugfs. |
| 59 | 60 |
| 61 @param in_files: Array of input files. |
| 60 @return: Ports dictionary of port properties | 62 @return: Ports dictionary of port properties |
| 61 """ | 63 """ |
| 62 ports = {} | 64 ports = {} |
| 63 not_present_msg = "FAIL: There's no virtio-ports dir in debugfs" | 65 not_present_msg = "FAIL: There's no virtio-ports dir in debugfs" |
| 64 if (not os.path.ismount(DEBUGPATH)): | 66 if not os.path.ismount(DEBUGPATH): |
| 65 os.system('mount -t debugfs none %s' % (DEBUGPATH)) | 67 os.system('mount -t debugfs none %s' % (DEBUGPATH)) |
| 66 try: | 68 try: |
| 67 if not os.path.isdir('%s/virtio-ports' % (DEBUGPATH)): | 69 if not os.path.isdir('%s/virtio-ports' % (DEBUGPATH)): |
| 68 print not_present_msg | 70 print not_present_msg |
| 69 except: | 71 except: |
| 70 print not_present_msg | 72 print not_present_msg |
| 71 else: | 73 else: |
| 72 viop_names = os.listdir('%s/virtio-ports' % (DEBUGPATH)) | 74 viop_names = os.listdir('%s/virtio-ports' % (DEBUGPATH)) |
| 75 if in_files is not None: |
| 76 dev_names = os.listdir('/dev') |
| 77 rep = re.compile(r"vport[0-9]p[0-9]+") |
| 78 dev_names = filter(lambda x: rep.match(x) is not None, dev_names
) |
| 79 if len(dev_names) != len(in_files): |
| 80 print ("FAIL: Not all ports were successfully initialized " |
| 81 "in /dev, only %d from %d." % (len(dev_names), |
| 82 len(in_files))) |
| 83 return |
| 84 |
| 85 if len(viop_names) != len(in_files): |
| 86 print ("FAIL: Not all ports were successfuly initialized " |
| 87 "in debugfs, only %d from %d." % (len(viop_names), |
| 88 len(in_files))) |
| 89 return |
| 90 |
| 73 for name in viop_names: | 91 for name in viop_names: |
| 74 open_db_file = "%s/virtio-ports/%s" % (DEBUGPATH, name) | 92 open_db_file = "%s/virtio-ports/%s" % (DEBUGPATH, name) |
| 75 f = open(open_db_file, 'r') | 93 f = open(open_db_file, 'r') |
| 76 port = {} | 94 port = {} |
| 77 file = [] | 95 file = [] |
| 78 for line in iter(f): | 96 for line in iter(f): |
| 79 file.append(line) | 97 file.append(line) |
| 80 try: | 98 try: |
| 81 for line in file: | 99 for line in file: |
| 82 m = re.match("(\S+): (\S+)", line) | 100 m = re.match("(\S+): (\S+)", line) |
| 83 port[m.group(1)] = m.group(2) | 101 port[m.group(1)] = m.group(2) |
| 84 | 102 |
| 85 if (port['is_console'] == "yes"): | 103 if port['is_console'] == "yes": |
| 86 port["path"] = "/dev/hvc%s" % (port["console_vtermno"]) | 104 port["path"] = "/dev/hvc%s" % (port["console_vtermno"]) |
| 87 # Console works like a serialport | 105 # Console works like a serialport |
| 88 else: | 106 else: |
| 89 port["path"] = "/dev/%s" % name | 107 port["path"] = "/dev/%s" % name |
| 90 | 108 |
| 91 if (not os.path.exists(port['path'])): | 109 if not os.path.exists(port['path']): |
| 92 print "FAIL: %s not exist" % port['path'] | 110 print "FAIL: %s not exist" % port['path'] |
| 93 | 111 |
| 94 sysfspath = SYSFSPATH + name | 112 sysfspath = SYSFSPATH + name |
| 95 if (not os.path.isdir(sysfspath)): | 113 if not os.path.isdir(sysfspath): |
| 96 print "FAIL: %s not exist" % (sysfspath) | 114 print "FAIL: %s not exist" % (sysfspath) |
| 97 | 115 |
| 98 info_name = sysfspath + "/name" | 116 info_name = sysfspath + "/name" |
| 99 port_name = self._readfile(info_name).strip() | 117 port_name = self._readfile(info_name).strip() |
| 100 if (port_name != port["name"]): | 118 if port_name != port["name"]: |
| 101 print ("FAIL: Port info not match \n%s - %s\n%s - %s" % | 119 print ("FAIL: Port info does not match " |
| 120 "\n%s - %s\n%s - %s" % |
| 102 (info_name , port_name, | 121 (info_name , port_name, |
| 103 "%s/virtio-ports/%s" % (DEBUGPATH, name), | 122 "%s/virtio-ports/%s" % (DEBUGPATH, name), |
| 104 port["name"])) | 123 port["name"])) |
| 124 dev_ppath = DEVPATH + port_name |
| 125 if not os.path.exists(dev_ppath): |
| 126 print "FAIL: Symlink %s does not exist." % dev_ppath |
| 127 if not os.path.realpath(dev_ppath) != "/dev/name": |
| 128 print "FAIL: Symlink %s is not correct." % dev_ppath |
| 105 except AttributeError: | 129 except AttributeError: |
| 106 print ("In file " + open_db_file + | 130 print ("Bad data on file %s:\n%s. " % |
| 107 " are bad data\n"+ "".join(file).strip()) | 131 (open_db_file, "".join(file).strip())) |
| 108 print ("FAIL: Fail file data.") | 132 print "FAIL: Bad data on file %s." % open_db_file |
| 109 return | 133 return |
| 110 | 134 |
| 111 ports[port['name']] = port | 135 ports[port['name']] = port |
| 112 f.close() | 136 f.close() |
| 113 | 137 |
| 114 return ports | 138 return ports |
| 115 | 139 |
| 116 | 140 |
| 141 def check_zero_sym(self): |
| 142 """ |
| 143 Check if port /dev/vport0p0 was created. |
| 144 """ |
| 145 symlink = "/dev/vport0p0" |
| 146 if os.path.exists(symlink): |
| 147 print "PASS: Symlink %s exists." % symlink |
| 148 else: |
| 149 print "FAIL: Symlink %s does not exist." % symlink |
| 150 |
| 151 |
| 117 def init(self, in_files): | 152 def init(self, in_files): |
| 118 """ | 153 """ |
| 119 Init and check port properties. | 154 Init and check port properties. |
| 120 """ | 155 """ |
| 121 self.ports = self._get_port_status() | 156 self.ports = self._get_port_status(in_files) |
| 122 | 157 |
| 123 if self.ports == None: | 158 if self.ports is None: |
| 124 return | 159 return |
| 125 for item in in_files: | 160 for item in in_files: |
| 126 if (item[1] != self.ports[item[0]]["is_console"]): | 161 if (item[1] != self.ports[item[0]]["is_console"]): |
| 127 print self.ports | 162 print self.ports |
| 128 print "FAIL: Host console is not like console on guest side\n" | 163 print "FAIL: Host console is not like console on guest side\n" |
| 164 return |
| 165 |
| 129 print "PASS: Init and check virtioconsole files in system." | 166 print "PASS: Init and check virtioconsole files in system." |
| 130 | 167 |
| 131 | 168 |
| 132 class Switch(Thread): | 169 class Switch(Thread): |
| 133 """ | 170 """ |
| 134 Thread that sends data between ports. | 171 Thread that sends data between ports. |
| 135 """ | 172 """ |
| 136 def __init__ (self, in_files, out_files, event, | 173 def __init__ (self, in_files, out_files, event, |
| 137 cachesize=1024, method=0): | 174 cachesize=1024, method=0): |
| 138 """ | 175 """ |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 def catching_signal(self): | 456 def catching_signal(self): |
| 420 """ | 457 """ |
| 421 return: True if should set catch signal, False if ignore signal and | 458 return: True if should set catch signal, False if ignore signal and |
| 422 none when configuration is not changed. | 459 none when configuration is not changed. |
| 423 """ | 460 """ |
| 424 ret = self.catch_signal | 461 ret = self.catch_signal |
| 425 self.catch_signal = None | 462 self.catch_signal = None |
| 426 return ret | 463 return ret |
| 427 | 464 |
| 428 | 465 |
| 429 def async(self, port, mode=True, exp_val = 0): | 466 def async(self, port, mode=True, exp_val=0): |
| 430 """ | 467 """ |
| 431 Set port function mode async/sync. | 468 Set port function mode async/sync. |
| 432 | 469 |
| 433 @param port: port which should be pooled. | 470 @param port: port which should be pooled. |
| 434 @param mode: False to set sync mode, True for sync mode. | 471 @param mode: False to set sync mode, True for sync mode. |
| 435 @param exp_val: Value which should be pooled. | 472 @param exp_val: Value which should be pooled. |
| 436 """ | 473 """ |
| 437 fd = self._open([port])[0] | 474 fd = self._open([port])[0] |
| 438 | 475 |
| 439 try: | 476 try: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 464 | 501 |
| 465 | 502 |
| 466 def close(self, file): | 503 def close(self, file): |
| 467 """ | 504 """ |
| 468 Close open port. | 505 Close open port. |
| 469 | 506 |
| 470 @param file: File to close. | 507 @param file: File to close. |
| 471 """ | 508 """ |
| 472 descriptor = None | 509 descriptor = None |
| 473 path = self.ports[file]["path"] | 510 path = self.ports[file]["path"] |
| 474 if path != None: | 511 if path is not None: |
| 475 if path in self.files.keys(): | 512 if path in self.files.keys(): |
| 476 descriptor = self.files[path] | 513 descriptor = self.files[path] |
| 477 del self.files[path] | 514 del self.files[path] |
| 478 if descriptor != None: | 515 if descriptor is not None: |
| 479 try: | 516 try: |
| 480 os.close(descriptor) | 517 os.close(descriptor) |
| 481 except Exception, inst: | 518 except Exception, inst: |
| 482 print "FAIL: Closing the file: " + str(inst) | 519 print "FAIL: Closing the file: " + str(inst) |
| 483 return | 520 return |
| 484 print "PASS: Close" | 521 print "PASS: Close" |
| 485 | 522 |
| 486 | 523 |
| 487 def open(self, in_file): | 524 def open(self, in_file): |
| 488 """ | 525 """ |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 | 596 |
| 560 | 597 |
| 561 def send_loop(self): | 598 def send_loop(self): |
| 562 """ | 599 """ |
| 563 Start sender data transfer. Requires senderprepare run first. | 600 Start sender data transfer. Requires senderprepare run first. |
| 564 """ | 601 """ |
| 565 self.threads[0].start() | 602 self.threads[0].start() |
| 566 print "PASS: Sender start" | 603 print "PASS: Sender start" |
| 567 | 604 |
| 568 | 605 |
| 569 def send(self, port, length=1, mode=True): | 606 def send(self, port, length=1, mode=True, is_static=False): |
| 570 """ | 607 """ |
| 571 Send a data of some length | 608 Send a data of some length |
| 572 | 609 |
| 573 @param port: Port to write data | 610 @param port: Port to write data |
| 574 @param length: Length of data | 611 @param length: Length of data |
| 575 @param mode: True = loop mode, False = one shoot mode | 612 @param mode: True = loop mode, False = one shoot mode |
| 576 """ | 613 """ |
| 577 in_f = self._open([port]) | 614 in_f = self._open([port]) |
| 578 | 615 |
| 579 data = "" | 616 data = "" |
| 580 while len(data) < length: | 617 writes = 0 |
| 581 data += "%c" % random.randrange(255) | 618 |
| 582 try: | 619 if not is_static: |
| 583 writes = os.write(in_f[0], data) | 620 while len(data) < length: |
| 584 except Exception, inst: | 621 data += "%c" % random.randrange(255) |
| 585 print inst | 622 try: |
| 586 if not writes: | 623 writes = os.write(in_f[0], data) |
| 587 writes = 0 | 624 except Exception, inst: |
| 625 print inst |
| 626 else: |
| 627 while len(data) < 4096: |
| 628 data += "%c" % random.randrange(255) |
| 588 if mode: | 629 if mode: |
| 589 while (writes < length): | 630 while (writes < length): |
| 590 try: | 631 try: |
| 591 writes += os.write(in_f[0], data) | 632 writes += os.write(in_f[0], data) |
| 592 except Exception, inst: | 633 except Exception, inst: |
| 593 print inst | 634 print inst |
| 594 if writes >= length: | 635 if writes >= length: |
| 595 print "PASS: Send data length %d" % writes | 636 print "PASS: Send data length %d" % writes |
| 596 else: | 637 else: |
| 597 print ("FAIL: Partial send: desired %d, transfered %d" % | 638 print ("FAIL: Partial send: desired %d, transfered %d" % |
| (...skipping 27 matching lines...) Expand all Loading... |
| 625 print ("FAIL: Partial recv: desired %d, transfered %d" % | 666 print ("FAIL: Partial recv: desired %d, transfered %d" % |
| 626 (length, len(recvs))) | 667 (length, len(recvs))) |
| 627 | 668 |
| 628 | 669 |
| 629 def clean_port(self, port, buffer=1024): | 670 def clean_port(self, port, buffer=1024): |
| 630 in_f = self._open([port]) | 671 in_f = self._open([port]) |
| 631 ret = select.select([in_f[0]], [], [], 1.0) | 672 ret = select.select([in_f[0]], [], [], 1.0) |
| 632 buf = "" | 673 buf = "" |
| 633 if ret[0]: | 674 if ret[0]: |
| 634 buf = os.read(in_f[0], buffer) | 675 buf = os.read(in_f[0], buffer) |
| 635 print ("PASS: Rest in socket: ") + str(buf[10]) | 676 print ("PASS: Rest in socket: ") + str(buf[:10]) |
| 636 | 677 |
| 637 | 678 |
| 638 def is_alive(): | 679 def is_alive(): |
| 639 """ | 680 """ |
| 640 Check is only main thread is alive and if guest react. | 681 Check is only main thread is alive and if guest react. |
| 641 """ | 682 """ |
| 642 if threading.activeCount() == 2: | 683 if threading.activeCount() == 2: |
| 643 print ("PASS: Guest is ok no thread alive") | 684 print ("PASS: Guest is ok no thread alive") |
| 644 else: | 685 else: |
| 645 threads = "" | 686 threads = "" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 674 while not exiting: | 715 while not exiting: |
| 675 str = raw_input() | 716 str = raw_input() |
| 676 try: | 717 try: |
| 677 exec str | 718 exec str |
| 678 except: | 719 except: |
| 679 exc_type, exc_value, exc_traceback = sys.exc_info() | 720 exc_type, exc_value, exc_traceback = sys.exc_info() |
| 680 print "On Guest exception from: \n" + "".join( | 721 print "On Guest exception from: \n" + "".join( |
| 681 traceback.format_exception(exc_type, | 722 traceback.format_exception(exc_type, |
| 682 exc_value, | 723 exc_value, |
| 683 exc_traceback)) | 724 exc_traceback)) |
| 725 print "FAIL: Guest command exception." |
| 684 | 726 |
| 685 | 727 |
| 686 def sigusr_handler(sig, frame): | 728 def sigusr_handler(sig, frame): |
| 687 pass | 729 pass |
| 688 | 730 |
| 689 | 731 |
| 690 def main(): | 732 def main(): |
| 691 """ | 733 """ |
| 692 Main function with infinite loop to catch signal from system. | 734 Main function with infinite loop to catch signal from system. |
| 693 """ | 735 """ |
| 694 if (len(sys.argv) > 1) and (sys.argv[1] == "-c"): | 736 if (len(sys.argv) > 1) and (sys.argv[1] == "-c"): |
| 695 compile() | 737 compile() |
| 696 | 738 |
| 697 global exiting | 739 global exiting |
| 698 virt = VirtioGuest() | 740 virt = VirtioGuest() |
| 699 slave = Thread(target=worker, args=(virt, )) | 741 slave = Thread(target=worker, args=(virt, )) |
| 700 slave.start() | 742 slave.start() |
| 701 signal.signal(signal.SIGUSR1, sigusr_handler) | 743 signal.signal(signal.SIGUSR1, sigusr_handler) |
| 702 while not exiting: | 744 while not exiting: |
| 703 signal.pause() | 745 signal.pause() |
| 704 catch = virt.catching_signal() | 746 catch = virt.catching_signal() |
| 705 if catch: | 747 if catch: |
| 706 signal.signal(signal.SIGIO, virt) | 748 signal.signal(signal.SIGIO, virt) |
| 707 elif catch == False: | 749 elif catch is False: |
| 708 signal.signal(signal.SIGIO, signal.SIG_DFL) | 750 signal.signal(signal.SIGIO, signal.SIG_DFL) |
| 709 if (catch != None): | 751 if catch is not None: |
| 710 virt.use_config.set() | 752 virt.use_config.set() |
| 711 print "PASS: guest_exit" | 753 print "PASS: guest_exit" |
| 712 | 754 |
| 713 | 755 |
| 714 if __name__ == "__main__": | 756 if __name__ == "__main__": |
| 715 main() | 757 main() |
| OLD | NEW |