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 |