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__":