1import logging, os, signal, re, time
2from autotest_lib.client.common_lib import error
3from autotest_lib.client.bin import utils
4from autotest_lib.client.virt import aexpect, virt_utils
5
6
7def run_netstress_kill_guest(test, params, env):
8    """
9    Try stop network interface in VM when other VM try to communicate.
10
11    @param test: kvm test object
12    @param params: Dictionary with the test parameters
13    @param env: Dictionary with test environment.
14    """
15    def get_corespond_ip(ip):
16        """
17        Get local ip address which is used for contact ip.
18
19        @param ip: Remote ip
20        @return: Local corespond IP.
21        """
22        result = utils.run("ip route get %s" % (ip)).stdout
23        ip = re.search("src (.+)", result)
24        if ip is not None:
25            ip = ip.groups()[0]
26        return ip
27
28
29    def get_ethernet_driver(session):
30        """
31        Get driver of network cards.
32
33        @param session: session to machine
34        """
35        modules = []
36        out = session.cmd("ls -l --color=never "
37                          "/sys/class/net/*/device/driver/module")
38        for module in out.split("\n"):
39            modules.append(module.split("/")[-1])
40        modules.remove("")
41        return set(modules)
42
43
44    def kill_and_check(vm):
45        vm_pid = vm.get_pid()
46        vm.destroy(gracefully=False)
47        time.sleep(2)
48        try:
49            os.kill(vm_pid, 0)
50            logging.error("VM is not dead")
51            raise error.TestFail("VM is not dead after sending signal 0 to it")
52        except OSError:
53            logging.info("VM is dead")
54
55
56    def netload_kill_problem(session_serial):
57        netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
58        setup_cmd = params.get("setup_cmd")
59        clean_cmd = params.get("clean_cmd")
60        firewall_flush = "iptables -F"
61
62        try:
63            utils.run(firewall_flush)
64        except:
65            logging.warning("Could not flush firewall rules on guest")
66
67        try:
68            session_serial.cmd(firewall_flush)
69        except aexpect.ShellError:
70            logging.warning("Could not flush firewall rules on guest")
71
72        for i in params.get("netperf_files").split():
73            vm.copy_files_to(os.path.join(netperf_dir, i), "/tmp")
74
75        guest_ip = vm.get_address(0)
76        server_ip = get_corespond_ip(guest_ip)
77
78        logging.info("Setup and run netperf on host and guest")
79        session_serial.cmd(setup_cmd % "/tmp", timeout=200)
80        utils.run(setup_cmd % netperf_dir)
81
82        try:
83            session_serial.cmd(clean_cmd)
84        except:
85            pass
86        session_serial.cmd(params.get("netserver_cmd") % "/tmp")
87
88        utils.run(clean_cmd, ignore_status=True)
89        utils.run(params.get("netserver_cmd") % netperf_dir)
90
91        server_netperf_cmd = params.get("netperf_cmd") % (netperf_dir, "TCP_STREAM",
92                                        guest_ip, params.get("packet_size", "1500"))
93        quest_netperf_cmd = params.get("netperf_cmd") % ("/tmp", "TCP_STREAM",
94                                       server_ip, params.get("packet_size", "1500"))
95
96        tcpdump = env.get("tcpdump")
97        pid = None
98        if tcpdump:
99            # Stop the background tcpdump process
100            try:
101                pid = int(utils.system_output("pidof tcpdump"))
102                logging.debug("Stopping the background tcpdump")
103                os.kill(pid, signal.SIGSTOP)
104            except:
105                pass
106
107        try:
108            logging.info("Start heavy network load host <=> guest.")
109            session_serial.sendline(quest_netperf_cmd)
110            utils.BgJob(server_netperf_cmd)
111
112            #Wait for create big network usage.
113            time.sleep(10)
114            kill_and_check(vm)
115
116        finally:
117            utils.run(clean_cmd, ignore_status=True)
118            if tcpdump and pid:
119                logging.debug("Resuming the background tcpdump")
120                logging.info("pid is %s" % pid)
121                os.kill(pid, signal.SIGCONT)
122
123
124    def netdriver_kill_problem(session_serial):
125        modules = get_ethernet_driver(session_serial)
126        logging.debug(modules)
127        for _ in range(50):
128            for module in modules:
129                session_serial.cmd("rmmod %s" % (module))
130                time.sleep(0.2)
131            for module in modules:
132                session_serial.cmd("modprobe %s" % (module))
133                time.sleep(0.2)
134        kill_and_check(vm)
135
136
137    vm = env.get_vm(params["main_vm"])
138    vm.verify_alive()
139    login_timeout = int(params.get("login_timeout", 360))
140    session = vm.wait_for_login(timeout=login_timeout)
141    session.close()
142    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
143
144    mode = params.get("mode")
145    if mode == "driver":
146        netdriver_kill_problem(session_serial)
147    elif mode == "load":
148        netload_kill_problem(session_serial)
149