Merge remote branch 'cros/upstream' into autotest-rebase
Merged to upstream trunk@5066, from trunk@4749.
There is no way I could enlist each individual CL from the upstream here since it will blow up the changelist description field.
BUG=
TEST=
Had patched this CL into a fresh cut client to avoid any side effect.
run_remote_test bvt from both emerged location and third_party/autotest/file.
Both test passed!
We should also keep any eye on this to see how it gets propagated into cautotest server.
TBR=dalecurtis
Change-Id: I72f2bc7a9de530178484aea1bfb5ace68bcad029
diff --git a/client/tests/kvm/scripts/allocator.py b/client/tests/kvm/scripts/allocator.py
index 227745a..09dc004 100755
--- a/client/tests/kvm/scripts/allocator.py
+++ b/client/tests/kvm/scripts/allocator.py
@@ -12,7 +12,7 @@
PAGE_SIZE = 4096 # machine page size
-TMPFS_OVERHEAD = 0.0022 # overhead on 1MB of write data
+TMPFS_OVERHEAD = 0.0022 # overhead on 1MB of write data
class MemFill(object):
@@ -34,7 +34,7 @@
self.tmpdp = tempfile.mkdtemp()
ret_code = os.system("mount -o size=%dM tmpfs %s -t tmpfs" %
- ((mem+math.ceil(mem*TMPFS_OVERHEAD)),
+ ((mem+math.ceil(mem*TMPFS_OVERHEAD)),
self.tmpdp))
if ret_code != 0:
if os.getuid() != 0:
diff --git a/client/tests/kvm/scripts/bonding_setup.py b/client/tests/kvm/scripts/bonding_setup.py
new file mode 100644
index 0000000..f2d4be9
--- /dev/null
+++ b/client/tests/kvm/scripts/bonding_setup.py
@@ -0,0 +1,37 @@
+import os, re, commands, sys
+"""This script is used to setup bonding, macaddr of bond0 should be assigned by
+argv1"""
+
+if len(sys.argv) != 2:
+ sys.exit(1)
+mac = sys.argv[1]
+eth_nums = 0
+ifconfig_output = commands.getoutput("ifconfig")
+re_eth = "eth[0-9]*"
+for ename in re.findall(re_eth, ifconfig_output):
+ eth_config_file = "/etc/sysconfig/network-scripts/ifcfg-%s" % ename
+ eth_config = """DEVICE=%s
+USERCTL=no
+ONBOOT=yes
+MASTER=bond0
+SLAVE=yes
+BOOTPROTO=none
+""" % ename
+ f = file(eth_config_file,'w')
+ f.write(eth_config)
+ f.close()
+
+bonding_config_file = "/etc/sysconfig/network-scripts/ifcfg-bond0"
+bond_config = """DEVICE=bond0
+BOOTPROTO=dhcp
+NETWORKING_IPV6=no
+ONBOOT=yes
+USERCTL=no
+MACADDR=%s
+""" % mac
+f = file(bonding_config_file, "w")
+f.write(bond_config)
+f.close()
+os.system("modprobe bonding")
+os.system("service NetworkManager stop")
+os.system("service network restart")
diff --git a/client/tests/kvm/scripts/join_mcast.py b/client/tests/kvm/scripts/join_mcast.py
old mode 100644
new mode 100755
diff --git a/client/tests/kvm/scripts/qemu-ifup-ipv6 b/client/tests/kvm/scripts/qemu-ifup-ipv6
old mode 100644
new mode 100755
diff --git a/client/tests/kvm/scripts/unattended.py b/client/tests/kvm/scripts/unattended.py
index 1029d1e..e9e4751 100755
--- a/client/tests/kvm/scripts/unattended.py
+++ b/client/tests/kvm/scripts/unattended.py
@@ -242,9 +242,8 @@
class UnattendedInstall(object):
"""
Creates a floppy disk image that will contain a config file for unattended
- OS install. Optionally, sets up a PXE install server using qemu built in
- TFTP and DHCP servers to install a particular operating system. The
- parameters to the script are retrieved from environment variables.
+ OS install. The parameters to the script are retrieved from environment
+ variables.
"""
def __init__(self):
"""
@@ -256,9 +255,9 @@
attributes = ['kernel_args', 'finish_program', 'cdrom_cd1',
'unattended_file', 'medium', 'url', 'kernel', 'initrd',
- 'nfs_server', 'nfs_dir', 'pxe_dir', 'pxe_image',
- 'pxe_initrd', 'install_virtio', 'tftp',
- 'floppy', 'cdrom_unattended']
+ 'nfs_server', 'nfs_dir', 'install_virtio', 'floppy',
+ 'cdrom_unattended', 'boot_path', 'extra_params']
+
for a in attributes:
self._setattr(a)
@@ -269,13 +268,6 @@
for va in v_attributes:
self._setattr(va)
- # Silly attribution just to calm pylint down...
- self.tftp = self.tftp
- if self.tftp:
- self.tftp = os.path.join(KVM_TEST_DIR, self.tftp)
- if not os.path.isdir(self.tftp):
- os.makedirs(self.tftp)
-
if self.cdrom_cd1:
self.cdrom_cd1 = os.path.join(KVM_TEST_DIR, self.cdrom_cd1)
self.cdrom_cd1_mount = tempfile.mkdtemp(prefix='cdrom_cd1_', dir='/tmp')
@@ -287,9 +279,7 @@
if not os.path.isdir(os.path.dirname(self.floppy)):
os.makedirs(os.path.dirname(self.floppy))
- self.image_path = KVM_TEST_DIR
- self.kernel_path = os.path.join(self.image_path, self.kernel)
- self.initrd_path = os.path.join(self.image_path, self.initrd)
+ self.image_path = os.path.dirname(self.kernel)
def _setattr(self, key):
@@ -408,7 +398,7 @@
boot_disk.setup_answer_file(dest_fname, answer_contents)
elif self.unattended_file.endswith('.xml'):
- if self.tftp:
+ if "autoyast" in self.extra_params:
# SUSE autoyast install
dest_fname = "autoinst.xml"
if self.cdrom_unattended:
@@ -436,87 +426,44 @@
boot_disk.close()
- def setup_pxe_boot(self):
+ def setup_cdrom(self):
"""
- Sets up a PXE boot environment using the built in qemu TFTP server.
- Copies the PXE Linux bootloader pxelinux.0 from the host (needs the
- pxelinux package or equivalent for your distro), and vmlinuz and
- initrd.img files from the CD to a directory that qemu will serve trough
- TFTP to the VM.
+ Mount cdrom and copy vmlinuz and initrd.img.
"""
- print "Setting up PXE boot using TFTP root %s" % self.tftp
-
- pxe_file = None
- pxe_paths = ['/usr/lib/syslinux/pxelinux.0',
- '/usr/share/syslinux/pxelinux.0']
- for path in pxe_paths:
- if os.path.isfile(path):
- pxe_file = path
- break
-
- if not pxe_file:
- raise SetupError('Cannot find PXE boot loader pxelinux.0. Make '
- 'sure pxelinux or equivalent package for your '
- 'distro is installed.')
-
- pxe_dest = os.path.join(self.tftp, 'pxelinux.0')
- shutil.copyfile(pxe_file, pxe_dest)
+ print "Copying vmlinuz and initrd.img from cdrom"
+ m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' %
+ (self.cdrom_cd1, self.cdrom_cd1_mount))
+ run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1)
try:
- m_cmd = ('mount -t iso9660 -v -o loop,ro %s %s' %
- (self.cdrom_cd1, self.cdrom_cd1_mount))
- run(m_cmd, info='Could not mount CD image %s.' % self.cdrom_cd1)
-
- pxe_dir = os.path.join(self.cdrom_cd1_mount, self.pxe_dir)
- pxe_image = os.path.join(pxe_dir, self.pxe_image)
- pxe_initrd = os.path.join(pxe_dir, self.pxe_initrd)
-
- if not os.path.isdir(pxe_dir):
- raise SetupError('The ISO image does not have a %s dir. The '
- 'script assumes that the cd has a %s dir '
- 'where to search for the vmlinuz image.' %
- (self.pxe_dir, self.pxe_dir))
-
- if not os.path.isfile(pxe_image) or not os.path.isfile(pxe_initrd):
- raise SetupError('The location %s is lacking either a vmlinuz '
- 'or a initrd.img file. Cannot find a PXE '
- 'image to proceed.' % self.pxe_dir)
-
- tftp_image = os.path.join(self.tftp, 'vmlinuz')
- tftp_initrd = os.path.join(self.tftp, 'initrd.img')
- shutil.copyfile(pxe_image, tftp_image)
- shutil.copyfile(pxe_initrd, tftp_initrd)
-
+ img_path_cmd = ("mkdir -p %s" % self.image_path)
+ run(img_path_cmd, info=("Could not create image path dir %s" %
+ self.image_path))
+ kernel_fetch_cmd = ("cp %s/%s/%s %s" %
+ (self.cdrom_cd1_mount, self.boot_path,
+ os.path.basename(self.kernel), self.kernel))
+ run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" %
+ self.cdrom_cd1_mount))
+ initrd_fetch_cmd = ("cp %s/%s/%s %s" %
+ (self.cdrom_cd1_mount, self.boot_path,
+ os.path.basename(self.initrd), self.initrd))
+ run(initrd_fetch_cmd, info=("Could not copy the initrd.img from "
+ "%s" % self.cdrom_cd1_mount))
finally:
cleanup(self.cdrom_cd1_mount)
- pxe_config_dir = os.path.join(self.tftp, 'pxelinux.cfg')
- if not os.path.isdir(pxe_config_dir):
- os.makedirs(pxe_config_dir)
- pxe_config_path = os.path.join(pxe_config_dir, 'default')
-
- pxe_config = open(pxe_config_path, 'w')
- pxe_config.write('DEFAULT pxeboot\n')
- pxe_config.write('TIMEOUT 20\n')
- pxe_config.write('PROMPT 0\n')
- pxe_config.write('LABEL pxeboot\n')
- pxe_config.write(' KERNEL vmlinuz\n')
- pxe_config.write(' APPEND initrd=initrd.img %s\n' %
- self.kernel_args)
- pxe_config.close()
-
- print "PXE boot successfuly set"
-
def setup_url(self):
"""
Download the vmlinuz and initrd.img from URL.
"""
- print "Downloading the vmlinuz and initrd.img"
+ print "Downloading vmlinuz and initrd.img from URL"
os.chdir(self.image_path)
- kernel_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.kernel)
- initrd_fetch_cmd = "wget -q %s/isolinux/%s" % (self.url, self.initrd)
+ kernel_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path,
+ os.path.basename(self.kernel))
+ initrd_fetch_cmd = "wget -q %s/%s/%s" % (self.url, self.boot_path,
+ os.path.basename(self.initrd))
if os.path.exists(self.kernel):
os.unlink(self.kernel)
@@ -526,7 +473,6 @@
run(kernel_fetch_cmd, info="Could not fetch vmlinuz from %s" % self.url)
run(initrd_fetch_cmd, info=("Could not fetch initrd.img from %s" %
self.url))
- print "Download of vmlinuz and initrd.img finished"
def setup_nfs(self):
@@ -540,12 +486,14 @@
run(m_cmd, info='Could not mount nfs server')
try:
- kernel_fetch_cmd = ("cp %s/isolinux/%s %s" %
- (self.nfs_mount, self.kernel, self.image_path))
+ kernel_fetch_cmd = ("cp %s/%s/%s %s" %
+ (self.nfs_mount, self.boot_path,
+ os.path.basename(self.kernel), self.image_path))
run(kernel_fetch_cmd, info=("Could not copy the vmlinuz from %s" %
self.nfs_mount))
- initrd_fetch_cmd = ("cp %s/isolinux/%s %s" %
- (self.nfs_mount, self.initrd, self.image_path))
+ initrd_fetch_cmd = ("cp %s/%s/%s %s" %
+ (self.nfs_mount, self.boot_path,
+ os.path.basename(self.initrd), self.image_path))
run(initrd_fetch_cmd, info=("Could not copy the initrd.img from "
"%s" % self.nfs_mount))
finally:
@@ -572,8 +520,8 @@
if self.unattended_file and (self.floppy or self.cdrom_unattended):
self.setup_boot_disk()
if self.medium == "cdrom":
- if self.tftp:
- self.setup_pxe_boot()
+ if self.kernel and self.initrd:
+ self.setup_cdrom()
elif self.medium == "url":
self.setup_url()
elif self.medium == "nfs":
diff --git a/client/tests/kvm/scripts/virtio_guest.py b/client/tests/kvm/scripts/virtio_guest.py
old mode 100644
new mode 100755
index 4862ef2..0038f48
--- a/client/tests/kvm/scripts/virtio_guest.py
+++ b/client/tests/kvm/scripts/virtio_guest.py
@@ -3,35 +3,23 @@
"""
Auxiliary script used to send data between ports on guests.
-@copyright: 2008-2009 Red Hat Inc.
+@copyright: 2010 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, fcntl, array, subprocess
+import os, time, select, re, random, sys, array
+import fcntl, array, subprocess, traceback, signal
DEBUGPATH = "/sys/kernel/debug"
SYSFSPATH = "/sys/class/virtio-ports/"
-class virtio_guest():
-
+class VirtioGuest:
+ """
+ Test tools of virtio_ports.
+ """
LOOP_NONE = 0
LOOP_POLL = 1
LOOP_SELECT = 2
@@ -41,6 +29,9 @@
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):
@@ -125,7 +116,7 @@
print "PASS: Init and check virtioconsole files in system."
- class switch(Thread):
+ class Switch(Thread):
"""
Thread that sends data between ports.
"""
@@ -137,7 +128,7 @@
@param method: Method of read/write access.
@param cachesize: Block to receive and send.
"""
- Thread.__init__(self)
+ Thread.__init__(self, name="Switch")
self.in_files = in_files
self.out_files = out_files
@@ -211,15 +202,15 @@
def run(self):
- if (self.method == virtio_guest.LOOP_POLL):
+ if (self.method == VirtioGuest.LOOP_POLL):
self._poll_mode()
- elif (self.method == virtio_guest.LOOP_SELECT):
+ elif (self.method == VirtioGuest.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.
"""
@@ -228,7 +219,7 @@
@param port: Destination port
@param length: Length of the random data block
"""
- Thread.__init__(self)
+ Thread.__init__(self, name="Sender")
self.port = port
self.exit_thread = event
self.data = array.array('L')
@@ -260,11 +251,33 @@
print os.system("stty -F %s raw -echo" % (name))
print os.system("stty -F %s -a" % (name))
f.append(self.files[name])
- except Exception as inst:
+ except Exception, 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):
"""
@@ -279,24 +292,35 @@
mask = p.poll(timeout)
- 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 "
-
+ maskstr = VirtioGuest.pollmask_to_str(mask[0][1])
if (mask[0][1] & expected) == expected:
- print "PASS: Events: " + str
+ print "PASS: Events: " + maskstr
else:
- print "FAIL: Events: " + str
+ 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]
+
+ 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"
+ else:
+ print "FAIL: the lseek unexpectedly passed"
def blocking(self, port, mode=False):
@@ -306,8 +330,7 @@
@param port: port to set mode
@param mode: False to set nonblock mode, True for block mode
"""
- path = self.ports[port]["path"]
- fd = self.files[path]
+ fd = self._open([port])[0]
try:
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
@@ -316,12 +339,115 @@
else:
fcntl.fcntl(fd, fcntl.F_SETFL, fl & ~os.O_NONBLOCK)
- except Exception as inst:
+ except Exception, inst:
print "FAIL: Setting (non)blocking mode: " + str(inst)
return
- print ("PASS: set blocking mode to %s mode" %
- ("blocking" if mode else "nonblocking"))
+ 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"
def close(self, file):
@@ -336,26 +462,29 @@
if path in self.files.keys():
descriptor = self.files[path]
del self.files[path]
- try:
- os.close(descriptor)
- except Exception as inst:
- print "FAIL: Closing the file: " + str(inst)
- return
+ if descriptor != None:
+ try:
+ os.close(descriptor)
+ except Exception, inst:
+ print "FAIL: Closing the file: " + str(inst)
+ return
print "PASS: Close"
- def open(self, in_files):
+ def open(self, in_file):
"""
Direct open devices.
- @param in_files: Array of files.
+ @param in_file: Array of files.
@return: Array of descriptors.
"""
- name = self.ports[in_files]["path"]
+ name = self.ports[in_file]["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 as inst:
+ except Exception, inst:
print "%s\nFAIL: Failed open file %s" % (str(inst), name)
@@ -374,7 +503,7 @@
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"
@@ -412,7 +541,7 @@
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"
@@ -439,7 +568,7 @@
data += "%c" % random.randrange(255)
try:
writes = os.write(in_f[0], data)
- except Exception as inst:
+ except Exception, inst:
print inst
if not writes:
writes = 0
@@ -447,7 +576,7 @@
while (writes < length):
try:
writes += os.write(in_f[0], data)
- except Exception as inst:
+ except Exception, inst:
print inst
if writes >= length:
print "PASS: Send data length %d" % writes
@@ -469,13 +598,13 @@
recvs = ""
try:
recvs = os.read(in_f[0], buffer)
- except Exception as inst:
+ except Exception, inst:
print inst
if mode:
while (len(recvs) < length):
try:
recvs += os.read(in_f[0], buffer)
- except Exception as inst:
+ except Exception, inst:
print inst
if len(recvs) >= length:
print "PASS: Recv data length %d" % len(recvs)
@@ -484,6 +613,28 @@
(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.
@@ -491,22 +642,52 @@
import py_compile
py_compile.compile(sys.path[0] + "/virtio_guest.py")
print "PASS: compile"
- exit(0)
+ sys.exit()
-def main():
+def worker(virt):
"""
- Main (infinite) loop of virtio_guest.
+ Worker thread (infinite) loop of virtio_guest.
"""
- if (len(sys.argv) > 1) and (sys.argv[1] == "-c"):
- compile()
-
- virt = virtio_guest()
print "PASS: Start"
while True:
str = raw_input()
- exec str
+ 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
+
+
+def main():
+ """
+ Main function with infinite loop to catch signal from system.
+ """
+ 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)
+ 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()
if __name__ == "__main__":