Index: client/tests/kvm/scripts/virtio_guest.py |
diff --git a/client/tests/kvm/scripts/virtio_guest.py b/client/tests/kvm/scripts/virtio_guest.py |
old mode 100755 |
new mode 100644 |
index 0038f48f1885ffcffe1d166282dcee51fb5a4074..4862ef2b920674e3ca4de6af2ceda036efc810ae |
--- a/client/tests/kvm/scripts/virtio_guest.py |
+++ b/client/tests/kvm/scripts/virtio_guest.py |
@@ -3,23 +3,35 @@ |
""" |
Auxiliary script used to send data between ports on guests. |
-@copyright: 2010 Red Hat, Inc. |
+@copyright: 2008-2009 Red Hat Inc. |
@author: Jiri Zupka (jzupka@redhat.com) |
@author: Lukas Doktor (ldoktor@redhat.com) |
""" |
+#from _pydev_SimpleXMLRPCServer import fcntl |
+ |
+""" |
+TODO: |
+virt.init([consoles]) # sysfs, udev, OK |
+virt.open(name) |
+virt.close(name) |
+virt.poll(name, eventmask, timeout) # poll.register(), poll.poll(), |
+return event |
+virt.send(name, length) # host disconnected |
+virt.recv(name, length) # host disconnected |
+virt.blocking(name, true) # true = blocking, false = nonblocking |
+virt.loopback(in_names, out_names, type="None") # use select/poll |
+""" |
+ |
import threading |
from threading import Thread |
-import os, time, select, re, random, sys, array |
-import fcntl, array, subprocess, traceback, signal |
+import os, time, select, re, random, sys, array, fcntl, array, subprocess |
DEBUGPATH = "/sys/kernel/debug" |
SYSFSPATH = "/sys/class/virtio-ports/" |
-class VirtioGuest: |
- """ |
- Test tools of virtio_ports. |
- """ |
+class virtio_guest(): |
+ |
LOOP_NONE = 0 |
LOOP_POLL = 1 |
LOOP_SELECT = 2 |
@@ -29,9 +41,6 @@ class VirtioGuest: |
self.exit_thread = threading.Event() |
self.threads = [] |
self.ports = {} |
- self.poll_fds = {} |
- self.catch_signal = None |
- self.use_config = threading.Event() |
def _readfile(self, name): |
@@ -116,7 +125,7 @@ class VirtioGuest: |
print "PASS: Init and check virtioconsole files in system." |
- class Switch(Thread): |
+ class switch(Thread): |
""" |
Thread that sends data between ports. |
""" |
@@ -128,7 +137,7 @@ class VirtioGuest: |
@param method: Method of read/write access. |
@param cachesize: Block to receive and send. |
""" |
- Thread.__init__(self, name="Switch") |
+ Thread.__init__(self) |
self.in_files = in_files |
self.out_files = out_files |
@@ -202,15 +211,15 @@ class VirtioGuest: |
def run(self): |
- if (self.method == VirtioGuest.LOOP_POLL): |
+ if (self.method == virtio_guest.LOOP_POLL): |
self._poll_mode() |
- elif (self.method == VirtioGuest.LOOP_SELECT): |
+ elif (self.method == virtio_guest.LOOP_SELECT): |
self._select_mode() |
else: |
self._none_mode() |
- class Sender(Thread): |
+ class sender(Thread): |
""" |
Creates a thread which sends random blocks of data to dst port. |
""" |
@@ -219,7 +228,7 @@ class VirtioGuest: |
@param port: Destination port |
@param length: Length of the random data block |
""" |
- Thread.__init__(self, name="Sender") |
+ Thread.__init__(self) |
self.port = port |
self.exit_thread = event |
self.data = array.array('L') |
@@ -251,33 +260,11 @@ class VirtioGuest: |
print os.system("stty -F %s raw -echo" % (name)) |
print os.system("stty -F %s -a" % (name)) |
f.append(self.files[name]) |
- except Exception, inst: |
+ except Exception as inst: |
print "FAIL: Failed to open file %s" % (name) |
raise inst |
return f |
- @staticmethod |
- def pollmask_to_str(mask): |
- """ |
- Conver pool mast to string |
- |
- @param mask: poll return mask |
- """ |
- str = "" |
- if (mask & select.POLLIN): |
- str += "IN " |
- if (mask & select.POLLPRI): |
- str += "PRI IN " |
- if (mask & select.POLLOUT): |
- str += "OUT " |
- if (mask & select.POLLERR): |
- str += "ERR " |
- if (mask & select.POLLHUP): |
- str += "HUP " |
- if (mask & select.POLLMSG): |
- str += "MSG " |
- return str |
- |
def poll(self, port, expected, timeout=500): |
""" |
@@ -292,35 +279,24 @@ class VirtioGuest: |
mask = p.poll(timeout) |
- maskstr = VirtioGuest.pollmask_to_str(mask[0][1]) |
- if (mask[0][1] & expected) == expected: |
- print "PASS: Events: " + maskstr |
- else: |
- emaskstr = VirtioGuest.pollmask_to_str(expected) |
- print "FAIL: Events: " + maskstr + " Expected: " + emaskstr |
- |
- |
- def lseek(self, port, pos, how): |
- """ |
- Use lseek on the device. The device is unseekable so PASS is returned |
- when lseek command fails and vice versa. |
- |
- @param port: Name of the port |
- @param pos: Offset |
- @param how: Relativ offset os.SEEK_{SET,CUR,END} |
- """ |
- fd = self._open([port])[0] |
+ str = "" |
+ if (mask[0][1] & select.POLLIN): |
+ str += "IN " |
+ if (mask[0][1] & select.POLLPRI): |
+ str += "PRI IN " |
+ if (mask[0][1] & select.POLLOUT): |
+ str += "OUT " |
+ if (mask[0][1] & select.POLLERR): |
+ str += "ERR " |
+ if (mask[0][1] & select.POLLHUP): |
+ str += "HUP " |
+ if (mask[0][1] & select.POLLMSG): |
+ str += "MSG " |
- try: |
- os.lseek(fd, pos, how) |
- except Exception, inst: |
- if inst.errno == 29: |
- print "PASS: the lseek failed as expected" |
- else: |
- print inst |
- print "FAIL: unknown error" |
+ if (mask[0][1] & expected) == expected: |
+ print "PASS: Events: " + str |
else: |
- print "FAIL: the lseek unexpectedly passed" |
+ print "FAIL: Events: " + str |
def blocking(self, port, mode=False): |
@@ -330,7 +306,8 @@ class VirtioGuest: |
@param port: port to set mode |
@param mode: False to set nonblock mode, True for block mode |
""" |
- fd = self._open([port])[0] |
+ path = self.ports[port]["path"] |
+ fd = self.files[path] |
try: |
fl = fcntl.fcntl(fd, fcntl.F_GETFL) |
@@ -339,115 +316,12 @@ class VirtioGuest: |
else: |
fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_NONBLOCK) |
- except Exception, inst: |
+ except Exception as inst: |
print "FAIL: Setting (non)blocking mode: " + str(inst) |
return |
- if mode: |
- print "PASS: set to blocking mode" |
- else: |
- print "PASS: set to nonblocking mode" |
- |
- |
- def __call__(self, sig, frame): |
- """ |
- Call function. Used for signal handle. |
- """ |
- if (sig == signal.SIGIO): |
- self.sigio_handler(sig, frame) |
- |
- |
- def sigio_handler(self, sig, frame): |
- """ |
- Handler for sigio operation. |
- |
- @param sig: signal which call handler. |
- @param frame: frame of caller |
- """ |
- if self.poll_fds: |
- p = select.poll() |
- map(p.register, self.poll_fds.keys()) |
- |
- masks = p.poll(1) |
- print masks |
- for mask in masks: |
- self.poll_fds[mask[0]][1] |= mask[1] |
- |
- |
- def get_sigio_poll_return(self, port): |
- """ |
- Return PASS, FAIL and poll walue in string format. |
- |
- @param port: Port to check poll information. |
- """ |
- fd = self._open([port])[0] |
- |
- maskstr = VirtioGuest.pollmask_to_str(self.poll_fds[fd][1]) |
- if (self.poll_fds[fd][0] ^ self.poll_fds[fd][1]): |
- emaskstr = VirtioGuest.pollmask_to_str(self.poll_fds[fd][0]) |
- print "FAIL: Events: " + maskstr + " Expected: " + emaskstr |
- else: |
- print "PASS: Events: " + maskstr |
- self.poll_fds[fd][1] = 0 |
- |
- |
- def set_pool_want_return(self, port, poll_value): |
- """ |
- Set value to static variable. |
- |
- @param port: Port which should be set excepted mask |
- @param poll_value: Value to check sigio signal. |
- """ |
- fd = self._open([port])[0] |
- self.poll_fds[fd] = [poll_value, 0] |
- print "PASS: Events: " + VirtioGuest.pollmask_to_str(poll_value) |
- |
- |
- def catching_signal(self): |
- """ |
- return: True if should set catch signal, False if ignore signal and |
- none when configuration is not changed. |
- """ |
- ret = self.catch_signal |
- self.catch_signal = None |
- return ret |
- |
- |
- def async(self, port, mode=True, exp_val = 0): |
- """ |
- Set port function mode async/sync. |
- |
- @param port: port which should be pooled. |
- @param mode: False to set sync mode, True for sync mode. |
- @param exp_val: Value which should be pooled. |
- """ |
- fd = self._open([port])[0] |
- |
- try: |
- fcntl.fcntl(fd, fcntl.F_SETOWN, os.getpid()) |
- fl = fcntl.fcntl(fd, fcntl.F_GETFL) |
- |
- self.use_config.clear() |
- if mode: |
- fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_ASYNC) |
- self.poll_fds[fd] = [exp_val, 0] |
- self.catch_signal = True |
- else: |
- del self.poll_fds[fd] |
- fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_ASYNC) |
- self.catch_signal = False |
- |
- os.kill(os.getpid(), signal.SIGUSR1) |
- self.use_config.wait() |
- |
- except Exception, inst: |
- print "FAIL: Setting (a)sync mode: " + str(inst) |
- return |
- |
- if mode: |
- print "PASS: Set to async mode" |
- else: |
- print "PASS: Set to sync mode" |
+ print ("PASS: set blocking mode to %s mode" % |
+ ("blocking" if mode else "nonblocking")) |
def close(self, file): |
@@ -462,29 +336,26 @@ class VirtioGuest: |
if path in self.files.keys(): |
descriptor = self.files[path] |
del self.files[path] |
- if descriptor != None: |
- try: |
- os.close(descriptor) |
- except Exception, inst: |
- print "FAIL: Closing the file: " + str(inst) |
- return |
+ try: |
+ os.close(descriptor) |
+ except Exception as inst: |
+ print "FAIL: Closing the file: " + str(inst) |
+ return |
print "PASS: Close" |
- def open(self, in_file): |
+ def open(self, in_files): |
""" |
Direct open devices. |
- @param in_file: Array of files. |
+ @param in_files: Array of files. |
@return: Array of descriptors. |
""" |
- name = self.ports[in_file]["path"] |
+ name = self.ports[in_files]["path"] |
try: |
self.files[name] = os.open(name, os.O_RDWR) |
- if (self.ports[in_file]["is_console"] == "yes"): |
- print os.system("stty -F %s raw -echo" % (name)) |
print "PASS: Open all filles correctly." |
- except Exception, inst: |
+ except Exception as inst: |
print "%s\nFAIL: Failed open file %s" % (str(inst), name) |
@@ -503,7 +374,7 @@ class VirtioGuest: |
in_f = self._open(in_files) |
out_f = self._open(out_files) |
- s = self.Switch(in_f, out_f, self.exit_thread, cachesize, mode) |
+ s = self.switch(in_f, out_f, self.exit_thread, cachesize, mode) |
s.start() |
self.threads.append(s) |
print "PASS: Start switch" |
@@ -541,7 +412,7 @@ class VirtioGuest: |
self.ports = self._get_port_status() |
in_f = self._open([port]) |
- self.threads.append(self.Sender(in_f[0], self.exit_thread, length)) |
+ self.threads.append(self.sender(in_f[0], self.exit_thread, length)) |
print "PASS: Sender prepare" |
@@ -568,7 +439,7 @@ class VirtioGuest: |
data += "%c" % random.randrange(255) |
try: |
writes = os.write(in_f[0], data) |
- except Exception, inst: |
+ except Exception as inst: |
print inst |
if not writes: |
writes = 0 |
@@ -576,7 +447,7 @@ class VirtioGuest: |
while (writes < length): |
try: |
writes += os.write(in_f[0], data) |
- except Exception, inst: |
+ except Exception as inst: |
print inst |
if writes >= length: |
print "PASS: Send data length %d" % writes |
@@ -598,13 +469,13 @@ class VirtioGuest: |
recvs = "" |
try: |
recvs = os.read(in_f[0], buffer) |
- except Exception, inst: |
+ except Exception as inst: |
print inst |
if mode: |
while (len(recvs) < length): |
try: |
recvs += os.read(in_f[0], buffer) |
- except Exception, inst: |
+ except Exception as inst: |
print inst |
if len(recvs) >= length: |
print "PASS: Recv data length %d" % len(recvs) |
@@ -613,28 +484,6 @@ class VirtioGuest: |
(length, len(recvs))) |
- def clean_port(self, port, buffer=1024): |
- in_f = self._open([port]) |
- ret = select.select([in_f[0]], [], [], 1.0) |
- buf = "" |
- if ret[0]: |
- buf = os.read(in_f[0], buffer) |
- print ("PASS: Rest in socket: " + buf) |
- |
- |
-def is_alive(): |
- """ |
- Check is only main thread is alive and if guest react. |
- """ |
- if threading.activeCount() == 2: |
- print ("PASS: Guest is ok no thread alive") |
- else: |
- threads = "" |
- for thread in threading.enumerate(): |
- threads += thread.name + ", " |
- print ("FAIL: On guest run thread. Active thread:" + threads) |
- |
- |
def compile(): |
""" |
Compile virtio_guest.py to speed up. |
@@ -642,52 +491,22 @@ def compile(): |
import py_compile |
py_compile.compile(sys.path[0] + "/virtio_guest.py") |
print "PASS: compile" |
- sys.exit() |
- |
- |
-def worker(virt): |
- """ |
- Worker thread (infinite) loop of virtio_guest. |
- """ |
- print "PASS: Start" |
- |
- while True: |
- str = raw_input() |
- try: |
- exec str |
- except: |
- exc_type, exc_value, exc_traceback = sys.exc_info() |
- print "On Guest exception from: \n" + "".join( |
- traceback.format_exception(exc_type, |
- exc_value, |
- exc_traceback)) |
- sys.exit(0) |
- |
- |
-def sigusr_handler(sig, frame): |
- pass |
+ exit(0) |
def main(): |
""" |
- Main function with infinite loop to catch signal from system. |
+ Main (infinite) loop of virtio_guest. |
""" |
if (len(sys.argv) > 1) and (sys.argv[1] == "-c"): |
compile() |
- virt = VirtioGuest() |
- slave = Thread(target=worker, args=(virt, )) |
- slave.start() |
- signal.signal(signal.SIGUSR1, sigusr_handler) |
+ virt = virtio_guest() |
+ print "PASS: Start" |
+ |
while True: |
- signal.pause() |
- catch = virt.catching_signal() |
- if catch: |
- signal.signal(signal.SIGIO, virt) |
- elif catch == False: |
- signal.signal(signal.SIGIO, signal.SIG_DFL) |
- if (catch != None): |
- virt.use_config.set() |
+ str = raw_input() |
+ exec str |
if __name__ == "__main__": |