1import logging, os
2from autotest_lib.client.common_lib import error
3
4
5@error.context_aware
6def run_usb(test, params, env):
7    """
8    Test usb device of guest
9
10    1) create a image file by qemu-img
11    2) boot up a guest add this file as a usb device
12    3) check usb device information by execute monitor/guest command
13
14    @param test: kvm test object
15    @param params: Dictionary with the test parameters
16    @param env: Dictionary with test environment.
17    """
18    vm = env.get_vm(params["main_vm"])
19    vm.create()
20
21    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
22
23    output = vm.monitor.cmd("info usb")
24    if "Product QEMU USB MSD" not in output:
25        logging.debug(output)
26        raise error.TestFail("Could not find mass storage device")
27
28    output = session.cmd("lsusb -v")
29    # No bus specified, default using "usb.0" for "usb-storage"
30    for i in ["ID 0000:0000", "Mass Storage", "SCSI", "QEMU USB HARDDRIVE"]:
31        if i not in output:
32            logging.debug(output)
33            raise error.TestFail("No '%s' in the output of 'lsusb -v'" % i)
34
35    output = session.cmd("fdisk -l")
36    if params.get("fdisk_string") not in output:
37        for line in output.splitlines():
38            logging.debug(line)
39        raise error.TestFail("Could not detect the usb device on fdisk output")
40
41    error.context("Formatting USB disk")
42    devname = session.cmd("ls /dev/disk/by-path/* | grep usb").strip()
43    session.cmd("yes | mkfs %s" % devname,
44                timeout=int(params.get("format_timeout")))
45
46    error.context("Mounting USB disk")
47    session.cmd("mount %s /mnt" % devname)
48
49    error.context("Creating comparison file")
50    c_file = '/tmp/usbfile'
51    session.cmd("dd if=/dev/random of=%s bs=1M count=1" % c_file)
52
53    error.context("Copying %s to USB disk" % c_file)
54    session.cmd("cp %s /mnt" % c_file)
55
56    error.context("Unmounting USB disk before file comparison")
57    session.cmd("umount %s" % devname)
58
59    error.context("Mounting USB disk for file comparison")
60    session.cmd("mount %s /mnt" % devname)
61
62    error.context("Determining md5sum for file on root fs and in USB disk")
63    md5_root = session.cmd("md5sum %s" % c_file).strip()
64    md5_usb = session.cmd("md5sum /mnt/%s" % os.path.basename(c_file)).strip()
65    md5_root = md5_root.split()[0]
66    md5_usb = md5_usb.split()[0]
67
68    error.context("")
69    if md5_root != md5_usb:
70        raise error.TestError("MD5 mismatch between file on root fs and on "
71                              "USB disk")
72
73    error.context("Unmounting USB disk after file comparison")
74    session.cmd("umount %s" % devname)
75
76    error.context("Checking if there are I/O error messages in dmesg")
77    output = session.get_command_output("dmesg")
78    io_error_msg = []
79    for line in output.splitlines():
80        if "Buffer I/O error" in line:
81            io_error_msg.append(line)
82
83    if io_error_msg:
84        e_msg = "IO error found on guest's dmesg when formatting USB device"
85        logging.error(e_msg)
86        for line in io_error_msg:
87            logging.error(line)
88        raise error.TestFail(e_msg)
89
90    session.close()
91