From patchwork Tue Mar 23 15:52:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Goldish X-Patchwork-Id: 87669 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2NFrLpu021829 for ; Tue, 23 Mar 2010 15:53:21 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754823Ab0CWPxT (ORCPT ); Tue, 23 Mar 2010 11:53:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:26281 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754133Ab0CWPxS (ORCPT ); Tue, 23 Mar 2010 11:53:18 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2NFrHhO013012 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 23 Mar 2010 11:53:17 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2NFrGBc030461; Tue, 23 Mar 2010 11:53:16 -0400 Received: from localhost.localdomain (dhcp-1-188.tlv.redhat.com [10.35.1.188]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o2NFrEgH025734; Tue, 23 Mar 2010 11:53:15 -0400 From: Michael Goldish To: autotest@test.kernel.org, kvm@vger.kernel.org Cc: Michael Goldish Subject: [KVM-AUTOTEST PATCH v3] KVM test: take frequent screendumps during all tests Date: Tue, 23 Mar 2010 17:52:12 +0200 Message-Id: <1269359532-7139-1-git-send-email-mgoldish@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 23 Mar 2010 15:53:21 +0000 (UTC) diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py index a92282a..b3fef9d 100644 --- a/client/tests/kvm/kvm_preprocessing.py +++ b/client/tests/kvm/kvm_preprocessing.py @@ -1,4 +1,4 @@ -import sys, os, time, commands, re, logging, signal, glob +import sys, os, time, commands, re, logging, signal, glob, threading, shutil from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils @@ -11,6 +11,10 @@ except ImportError: 'distro.') +_screendump_thread = None +_screendump_thread_termination_event = None + + def preprocess_image(test, params): """ Preprocess a single QEMU image according to the instructions in params. @@ -254,6 +258,15 @@ def preprocess(test, params, env): # Preprocess all VMs and images process(test, params, env, preprocess_image, preprocess_vm) + # Start the screendump thread + if params.get("take_regular_screendumps") == "yes": + logging.debug("Starting screendump thread") + global _screendump_thread, _screendump_thread_termination_event + _screendump_thread_termination_event = threading.Event() + _screendump_thread = threading.Thread(target=_take_screendumps, + args=(test, params, env)) + _screendump_thread.start() + def postprocess(test, params, env): """ @@ -263,8 +276,16 @@ def postprocess(test, params, env): @param params: Dict containing all VM and image parameters. @param env: The environment (a dict-like object). """ + # Postprocess all VMs and images process(test, params, env, postprocess_image, postprocess_vm) + # Terminate the screendump thread + global _screendump_thread, _screendump_thread_termination_event + if _screendump_thread: + logging.debug("Terminating screendump thread...") + _screendump_thread_termination_event.set() + _screendump_thread.join(10) + # Warn about corrupt PPM files for f in glob.glob(os.path.join(test.debugdir, "*.ppm")): if not ppm_utils.image_verify_ppm_file(f): @@ -290,11 +311,13 @@ def postprocess(test, params, env): for f in glob.glob(os.path.join(test.debugdir, '*.ppm')): os.unlink(f) - # Execute any post_commands - if params.get("post_command"): - process_command(test, params, env, params.get("post_command"), - int(params.get("post_command_timeout", "600")), - params.get("post_command_noncritical") == "yes") + # Should we keep the screendump dirs? + if params.get("keep_screendumps") != "yes": + logging.debug("'keep_screendumps' not specified; removing screendump " + "dirs...") + for d in glob.glob(os.path.join(test.debugdir, "screendumps_*")): + if os.path.isdir(d) and not os.path.islink(d): + shutil.rmtree(d, ignore_errors=True) # Kill all unresponsive VMs if params.get("kill_unresponsive_vms") == "yes": @@ -318,6 +341,12 @@ def postprocess(test, params, env): env["tcpdump"].close() del env["tcpdump"] + # Execute any post_commands + if params.get("post_command"): + process_command(test, params, env, params.get("post_command"), + int(params.get("post_command_timeout", "600")), + params.get("post_command_noncritical") == "yes") + def postprocess_on_error(test, params, env): """ @@ -343,3 +372,60 @@ def _update_address_cache(address_cache, line): mac_address, address_cache.get("last_seen")) address_cache[mac_address] = address_cache.get("last_seen") del address_cache["last_seen"] + + +def _take_screendumps(test, params, env): + global _screendump_thread_termination_event + temp_dir = test.debugdir + if params.get("screendump_temp_dir"): + temp_dir = kvm_utils.get_path(test.bindir, + params.get("screendump_temp_dir")) + try: + os.makedirs(temp_dir) + except OSError: + pass + temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" % + kvm_utils.generate_random_string(6)) + delay = float(params.get("screendump_delay", 5)) + quality = int(params.get("screendump_quality", 30)) + + cache = {} + + while True: + for vm in kvm_utils.env_get_all_vms(env): + if vm.is_dead(): + continue + vm.send_monitor_cmd("screendump %s" % temp_filename) + if not os.path.exists(temp_filename): + logging.warn("VM '%s' failed to produce a screendump", vm.name) + continue + if not ppm_utils.image_verify_ppm_file(temp_filename): + logging.warn("VM '%s' produced an invalid screendump", vm.name) + os.unlink(temp_filename) + continue + screendump_dir = os.path.join(test.debugdir, + "screendumps_%s" % vm.name) + try: + os.makedirs(screendump_dir) + except OSError: + pass + screendump_filename = os.path.join(screendump_dir, + "%s_%s.jpg" % (vm.name, + time.strftime("%Y-%m-%d_%H-%M-%S"))) + hash = utils.hash_file(temp_filename) + if hash in cache: + try: + os.link(cache[hash], screendump_filename) + except OSError: + pass + else: + try: + image = PIL.Image.open(temp_filename) + image.save(screendump_filename, format="JPEG", quality=quality) + cache[hash] = screendump_filename + except NameError: + pass + os.unlink(temp_filename) + if _screendump_thread_termination_event.isSet(): + break + _screendump_thread_termination_event.wait(delay) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index b13aec4..2a36687 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -10,13 +10,20 @@ main_vm = vm1 # Some preprocessor/postprocessor params start_vm = yes -convert_ppm_files_to_png_on_error = yes -#keep_ppm_files = yes -#keep_ppm_files_on_error = yes kill_vm = no kill_vm_gracefully = yes kill_unresponsive_vms = yes +# Screendump specific stuff +convert_ppm_files_to_png_on_error = yes +#keep_ppm_files = yes +#keep_ppm_files_on_error = yes +take_regular_screendumps = yes +keep_screendumps_on_error = yes +screendump_delay = 5 +screendump_quality = 30 +screendump_temp_dir = /dev/shm + # Some default VM params qemu_binary = qemu qemu_img_binary = qemu-img