diff mbox

Refactoring KVM install test.

Message ID 1243394495-12508-1-git-send-email-lmr@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Meneghel Rodrigues May 27, 2009, 3:21 a.m. UTC
Refactored KVM install test. Recently the source directory layout
for KVM was changed (now the toplevel is the userspace (qemu) code
with a kvm directory) and that was breaking the install test.

While I was working on the install test, I refactored the test:

 * Moved functions that fall into the 'more general utility
functions' to kvm_utils;
 * Made a simple function to detect kvm source code directory
layout, to handle automatically build differences.
 * Made module code removal more robust using as a base the
work made by Mike Burns
 * Apply a patch to fix a build issue on current release tarballs.
 * Made the build process to use all processors available on the
machine, reducing the time needed to build the userspace programs
and the kernel modules.
---
 client/tests/kvm_runtest_2/kvm_install.py |  431 ++++++++++++++---------------
 client/tests/kvm_runtest_2/kvm_utils.py   |   96 +++++++
 2 files changed, 303 insertions(+), 224 deletions(-)
diff mbox

Patch

diff --git a/client/tests/kvm_runtest_2/kvm_install.py b/client/tests/kvm_runtest_2/kvm_install.py
index 8be5a93..c2c79f7 100755
--- a/client/tests/kvm_runtest_2/kvm_install.py
+++ b/client/tests/kvm_runtest_2/kvm_install.py
@@ -4,7 +4,7 @@  import sys
 import urllib
 import re
 import signal
-from datetime import *
+import datetime
 
 from autotest_lib.client.bin import utils, test
 from autotest_lib.client.common_lib import error
@@ -14,19 +14,85 @@  import kvm_utils
 
 
 def run_kvm_install(test, params, env):
-    install_mode = params.get("mode")
-    kvm_log.info("Selected installation mode: %s" % install_mode)
+    """
+    Installs KVM using the selected install mode. Most install methods will
+    take kvm source code, build it and install it to a given location.
 
-    srcdir = params.get("srcdir", test.srcdir)
-    if not os.path.exists(srcdir):
-        os.mkdir(srcdir)
+        @param test: kvm_runtest_2 test object
+        @param params: Dictionary with test parameters
+        @param env: Test environment
+    """
+    known_install_modes = ['noinstall', 'release', 'snapshot', 'git',
+                           'localtar', 'localsrc']
 
-    # do not install
-    if install_mode == "noinstall":
+    install_mode = params.get("mode")
+    srcdir = params.get("srcdir", test.srcdir)
+    params["srcdir"] = srcdir
+
+    if install_mode not in known_install_modes:
+        raise error.TestError("Invalid installation mode" % install_mode)
+
+    if not install_mode == 'noinstall':
+        kvm_log.info("Selected installation mode: %s" % install_mode)
+        build_dir = __get_kvm(params)
+        __build_kvm(build_dir)
+        __install_kvm(build_dir, install_mode, test.bindir)
+        __load_kvm_modules(build_dir)
+        kvm_log.info("Done building and installing KVM")
+    else:
         kvm_log.info("Skipping installation")
 
-    # install from git
-    elif install_mode == "git":
+
+def __get_kvm(params):
+    """
+    Get KVM and returns a source code directory path.
+
+        @param params: Dictionary with all parameters passed to the
+        install test.
+    """
+    install_mode = params.get("mode")
+    srcdir = params.get("srcdir")
+    if not os.path.isdir(srcdir):
+        os.makedirs(srcdir)
+
+    if install_mode in ['release', 'snapshot', 'localtar']:
+        if install_mode == 'release':
+            release_tag = params.get("release_tag")
+            release_dir = params.get("release_dir")
+            kvm_log.info("Installing KVM from release tarball")
+            if not release_tag:
+                release_tag = kvm_utils.get_latest_kvm_release_tag(release_dir)
+            tarball = os.path.join(release_dir, "kvm-%s.tar.gz" % release_tag)
+            kvm_log.info("Retrieving release kvm-%s" % release_tag)
+            tarball = utils.unmap_url("/", tarball, "/tmp")
+        elif install_mode == 'snapshot':
+            kvm_log.info("Installing KVM from snapshot")
+            snapshot_date = params.get("snapshot_date")
+            snapshot_dir = params.get("snapshot_dir")
+            if not snapshot_date:
+                # Take yesterday's snapshot
+                d = (datetime.date.today() - 
+                     datetime.timedelta(1)).strftime("%Y%m%d")
+            else:
+                d = snapshot_date
+            tarball = os.path.join(snapshot_dir, "kvm-snapshot-%s.tar.gz" % d)
+            kvm_log.info("Retrieving kvm-snapshot-%s" % d)
+            tarball = utils.unmap_url("/", tarball, "/tmp")
+        elif install_mode == 'localtar':
+            tarball = params.get("tarball")
+            if not tarball:
+                raise error.TestError("KVM Tarball install specified but no"
+                                      " tarball provided on control file.")
+            kvm_log.info("Installing KVM from a local tarball")
+            kvm_log.info("Using tarball %s")
+            tarball = utils.unmap_url("/", params.get("tarball"), "/tmp")
+        os.chdir(srcdir)
+        return os.path.join(srcdir, utils.extract_tarball(tarball))
+
+    elif install_mode == 'localsrc':
+        return params.get('srcdir')
+
+    elif install_mode == 'git':
         repo = params.get("git_repo")
         user_repo = params.get("user_git_repo")
         branch = params.get("git_branch", "master")
@@ -36,248 +102,165 @@  def run_kvm_install(test, params, env):
         if not repo:
             message = "KVM git repository path not specified"
             kvm_log.error(message)
-            raise error.TestError, message
+            raise error.TestError(message)
         if not user_repo:
             message = "KVM user git repository path not specified"
             kvm_log.error(message)
-            raise error.TestError, message
-        __install_kvm_from_git(test, srcdir, repo, user_repo, branch, tag,
-                               user_tag, lbranch)
-
-    # install from release
-    elif install_mode == "release":
-        release_dir = params.get("release_dir")
-        release_tag = params.get("release_tag")
-        if not release_dir:
-            message = "Release dir not specified"
-            kvm_log.error(message)
-            raise error.TestError, message
-        __install_kvm_release(test, srcdir, release_dir, release_tag)
-
-    # install from snapshot
-    elif install_mode == "snapshot":
-        snapshot_dir = params.get("snapshot_dir")
-        snapshot_date = params.get("snapshot_date")
-        if not snapshot_dir:
-            message = "Snapshot dir not specified"
-            kvm_log.error(message)
-            raise error.TestError, message
-        __install_kvm_from_snapshot(test, srcdir, snapshot_dir, snapshot_date)
-
-    # install from tarball
-    elif install_mode == "localtar":
-        tarball = params.get("tarball")
-        if not tarball:
-            message = "Local tarball filename not specified"
-            kvm_log.error(message)
-            raise error.TestError, message
-        __install_kvm_from_local_tarball(test, srcdir, tarball)
-
-    # install from local sources
-    elif install_mode == "localsrc":
-        __install_kvm(test, srcdir)
+            raise error.TestError(message)
 
-    # invalid installation mode
-    else:
-        message = "Invalid installation mode: '%s'" % install_mode
-        kvm_log.error(message)
-        raise error.TestError, message
+        local_git_srcdir = os.path.join(srcdir, "kvm")
+        if not os.path.exists(local_git_srcdir):
+            os.mkdir(local_git_srcdir)
+        local_user_git_srcdir = os.path.join(srcdir, "kvmuser")
+        if not os.path.exists(local_user_git_srcdir):
+            os.mkdir(local_user_git_srcdir)
 
-    # load kvm modules (unless requested not to)
-    if params.get('load_modules', "yes") == "yes":
-        __load_kvm_modules()
-    else:
-        kvm_log.info("user requested not to load kvm modules")
+        kvm_utils.get_git_branch(repo, branch, local_git_srcdir, tag, lbranch)
+        kvm_utils.get_git_branch(user_repo, branch, local_user_git_srcdir, 
+                                 user_tag, lbranch)
 
-def __cleanup_dir(dir):
-    # only alerts if src directory is not empty
-    for root, dirs, files in os.walk(dir):
-        if dirs or files:
-            message = "Directory \'%s\' is not empty" % dir
-            kvm_log.error(message)
-            raise error.TestError, message
-
-def __install_kvm_release(test, srcdir, release_dir, release_tag):
-    if not release_tag:
-        try:
-            # look for the latest release in the web
-            page_url = os.path.join(release_dir, "showfiles.php")
-            local_web_page = utils.unmap_url("/", page_url, "/tmp")
-            f = open(local_web_page, "r")
-            data = f.read()
-            f.close()
-            rx = re.compile("package_id=(\d+).*\>kvm\<", re.IGNORECASE)
-            matches = rx.findall(data)
-            package_id = matches[0]
-            #package_id = 209008
-            rx = re.compile("package_id=%s.*release_id=\d+\">(\d+)" % package_id, re.IGNORECASE)
-            matches = rx.findall(data)
-            release_tag = matches[0] # the first match contains the latest release tag
-        except Exception, e:
-            message = "Could not fetch latest KVM release tag (%s)" % str(e)
-            kvm_log.error(message)
-            raise error.TestError(message)
+        ## TODO: Needs to see how we are syncing up the directories
+        return local_user_git_srcdir
 
-    kvm_log.info("Installing release %s (kvm-%s)" % (release_tag, release_tag))
-    tarball = os.path.join(release_dir, "kvm-%s.tar.gz" % release_tag)
-    tarball = utils.unmap_url("/", tarball, "/tmp")
-    __install_kvm_from_local_tarball(test, srcdir, tarball)
-
-
-def __install_kvm_from_git(test, srcdir, repo, user_repo, branch, tag,
-                           user_tag, lbranch):
-    local_git_srcdir = os.path.join(srcdir, "kvm")
-    if not os.path.exists(local_git_srcdir):
-        os.mkdir(local_git_srcdir)
-    local_user_git_srcdir = os.path.join(srcdir, "kvmuser")
-    if not os.path.exists(local_user_git_srcdir):
-        os.mkdir(local_user_git_srcdir)
-
-    __get_git_branch(repo, branch, local_git_srcdir, tag, lbranch)
-    __get_git_branch(user_repo, branch, local_user_git_srcdir, user_tag, lbranch)
-    utils.system("cd %s && ./configure &&  make -C kernel LINUX=%s sync" % (local_user_git_srcdir, local_git_srcdir))
-    __install_kvm(test, local_user_git_srcdir)
-
-
-def __get_git_branch(repository, branch, srcdir, commit=None, lbranch=None):
-    kvm_log.info("Getting sources from git <REP=%s BRANCH=%s TAG=%s> to local directory <%s>" % (repository, branch, commit, srcdir))
-    pwd = os.getcwd()
-    os.chdir(srcdir)
-    if os.path.exists(".git"):
-        utils.system("git reset --hard")
     else:
-        utils.system("git init")
+        return None
 
-    if not lbranch:
-        lbranch = branch
 
-    utils.system("git fetch -q -f -u -t %s %s:%s" %
-                 (repository, branch, lbranch))
-    utils.system("git checkout %s" % lbranch)
-    if commit:
-        utils.system("git checkout %s" % commit)
+def __build_kvm(build_dir, buildsteps=None):
+    """
+    Builds KVM, given a path to the project source code.
 
-    h = utils.system_output('git log --pretty=format:"%H" -1')
-    desc = utils.system_output("git describe")
-    kvm_log.info("Commit hash for %s is %s (%s)" % (repository, h.strip(), desc))
-    os.chdir(pwd)
+        @param build_dir: Path to KVM source code (toplevel)
+        @param buildsteps: Optional parameter. Alternative sequence of build
+        steps.
+    """
+    if not build_dir:
+        return
 
+    print build_dir
+    os.chdir(build_dir)
 
-def __install_kvm_from_snapshot(test, srcdir, snapshot_dir ,snapshot_date):
-    kvm_log.info("Source snapshot dir: %s" % snaphost_dir)
-    kvm_log.info("Source snapshot date: %s" % snapshot_date)
+    kvm_log.info("Applying patch to fix a small problem on KVM module build")
+    utils.system("patch -p0 < ../../adding_kvm_trace_support_qemu.patch")
 
-    if not snapshot_date:
-        d = (date.today() - timedelta(1)).strftime("%Y%m%d") # takes yesterday's snapshot
-    else:
-        d = snapshot_date
+    kvm_build_dir = os.path.join(build_dir, '..', '..', 'build')
+    kvm_build_dir = os.path.abspath(kvm_build_dir)
 
-    tarball = os.path.join(snaphost_dir, "kvm-snapshot-%s.tar.gz" % d)
-    kvm_log.info("Tarball url: %s" % tarball)
-    tarball = utils.unmap_url("/", tarball, "/tmp")
-    __install_kvm_from_local_tarball(test, srcdir, tarball)
+    if not os.path.exists(kvm_build_dir):
+        os.mkdir(kvm_build_dir)
 
+    if not buildsteps:
+        repository_type = kvm_utils.check_kvm_source_dir(build_dir)
+        if repository_type == 1:
+            buildsteps = ["./configure --prefix=%s" % kvm_build_dir,
+                          "make clean",
+                          "make -j %s" % utils.count_cpus()]
+            if not os.path.exists('qemu/pc-bios/bios.bin'):
+                buildsteps.append("make -C bios")
+                buildsteps.append("make -C extboot")
+                buildsteps.append("cp -f bios/BIOS-bochs-latest"
+                                  " qemu/pc-bios/bios.bin")
+                buildsteps.append("cp -f vgabios/VGABIOS-lgpl-latest.bin"
+                                  " qemu/pc-bios/vgabios.bin")
+                buildsteps.append("cp -f vgabios/VGABIOS-lgpl-latest.cirrus.bin"
+                                  " qemu/pc-bios/vgabios-cirrus.bin")
+                buildsteps.append("cp -f extboot/extboot.bin"
+                                  " qemu/pc-bios/extboot.bin")
+        elif repository_type == 2:
+            buildsteps = ["./configure --prefix=%s"
+                          " --with-kvm-trace" % kvm_build_dir,
+                          "make clean",
+                          "make -j %s" % utils.count_cpus()]
+
+    kvm_log.info("Building KVM")
+    os.chdir(build_dir)
+    for step in buildsteps:
+        utils.system(step)
+
+
+def __install_kvm(build_dir, install_mode, test_bindir):
+    """
+    Installs KVM depending on the installation method and creates
+    appropriate symbolic links on the kvm test directory.
+
+        @param build_dir: KVM source directory
+        @param install_mode: Type of KVM installation
+        @param test_bindir: Path of the KVM test directory
+    """
+    prefix = None
+    if install_mode in ['release', 'snapshot', 'git', 'localtar', 'localsrc']:
+        os.chdir(build_dir)
+        repository_type = kvm_utils.check_kvm_source_dir(build_dir)
+        if repository_type == 1:
+            utils.system("make -C qemu install")
+        if repository_type == 2:
+            utils.system("make install")
+
+        kvm_build_dir = os.path.join(test_bindir, 'build')
+        prefix = os.path.abspath(kvm_build_dir)
+
+    if not prefix:
+        raise error.TestError("Can't determine KVM userspace install prefix")
 
-def __install_kvm_from_local_tarball(test, srcdir, tarball):
-    pwd = os.getcwd()
-    os.chdir(srcdir)
-    newdir = utils.extract_tarball(tarball)
-    if newdir:
-        srcdir = os.path.join(srcdir, newdir)
-    os.chdir(pwd)
-    __install_kvm(test, srcdir)
+    # create symlinks
+    qemu_path = os.path.join(test_bindir, "qemu")
+    qemu_img_path = os.path.join(test_bindir, "qemu-img")
+    if os.path.lexists(qemu_path):
+        os.unlink(qemu_path)
+    if os.path.lexists(qemu_img_path):
+        os.unlink(qemu_img_path)
+    kvm_qemu = os.path.join(prefix, "bin", "qemu-system-x86_64")
+    if not os.path.isfile(kvm_qemu):
+        raise error.TestError('Invalid qemu path')
+    kvm_qemu_img = os.path.join(prefix, "bin", "qemu-img")
+    if not os.path.isfile(kvm_qemu_img):
+        raise error.TestError('Invalid qemu-img path')
+    os.symlink(kvm_qemu, qemu_path)
+    os.symlink(kvm_qemu_img, qemu_img_path)
 
 
-def __load_kvm_modules():
-    kvm_log.info("Detecting CPU vendor...")
+def __load_kvm_modules(build_dir):
     vendor = "intel"
     if os.system("grep vmx /proc/cpuinfo 1>/dev/null") != 0:
         vendor = "amd"
     kvm_log.info("Detected CPU vendor as '%s'" %(vendor))
 
-    #if self.config.load_modules == "yes":
-    # remove existing in kernel kvm modules
-    kvm_log.info("Unloading loaded KVM modules (if present)...")
-    #utils.system("pkill qemu 1>/dev/null 2>&1", ignore_status=True)
+    kvm_log.info("Killing any qemu processes that might be left behind")
     utils.system("pkill qemu", ignore_status=True)
-    #if utils.system("grep kvm_%s /proc/modules 1>/dev/null" % vendor, ignore_status=True) == 0:
-    utils.system("/sbin/rmmod kvm_%s" % vendor, ignore_status=True)
-    #if utils.system("grep kvm /proc/modules 1>/dev/null", ignore_status=True) == 0:
-    utils.system("/sbin/rmmod kvm", ignore_status=True)
 
-    if utils.system("grep kvm /proc/modules 1>/dev/null", ignore_status=True) == 0:
+    kvm_log.info("Unloading previously loaded KVM modules")
+    kvm_utils.unload_module("kvm")
+    if utils.module_is_loaded("kvm"):
         message = "Failed to remove old KVM modules"
         kvm_log.error(message)
-        raise error.TestError, message
+        raise error.TestError(message)
 
     kvm_log.info("Loading new KVM modules...")
-    os.chdir("kernel")
-    if os.path.exists("x86"):
-        os.chdir("x86")
-    utils.system("/sbin/insmod ./kvm.ko && sleep 1 && /sbin/insmod ./kvm-%s.ko" % vendor)
-
-    #elif self.config.load_modules == "no":
-        #kvm_log.info("user requested not to load kvm modules")
-
-    ### no matter if new kvm modules are to be loaded or not
-    ### make sure there are kvm modules installed.
-    if utils.system("grep kvm_%s /proc/modules 1>/dev/null" %(vendor), ignore_status=True) != 0:
-        message = "Failed to load KVM modules"
-        kvm_log.error(message)
-        raise error.TestError, message
-
-def __install_kvm(test, srcdir):
-    # create destination dir
-
-    kvm_build_dir = os.path.join(srcdir, '..', '..', 'build')
-    kvm_build_dir = os.path.abspath(kvm_build_dir)
-
-    if not os.path.exists(kvm_build_dir):
-        os.mkdir(kvm_build_dir)
-
-    # change to source dir
-    os.chdir(srcdir)
-
-    # start working...
-    kvm_log.info("Building KVM...")
-
-    def run(cmd, title, timeout):
-        (status, pid, output) = kvm_utils.run_bg(cmd, None, kvm_log.info,
-                                                 '(%s)' % title, timeout=timeout)
-        if status != 0:
-            kvm_utils.safe_kill(pid, signal.SIGTERM)
-            raise error.TestFail, "'%s' failed" % cmd
-
-    # configure + make
-    run("./configure --prefix=%s" % kvm_build_dir, "configure", 30)
-    run("make clean", "make clean", 30)
-    run("make", "make", 1200)
-
-    # make bios binaries if missing
-    if not os.path.exists('qemu/pc-bios/bios.bin'):
-        run("make -C bios", "make bios", 60)
-        run("make -C vgabios", "make vgabios", 60)
-        run("make -C extboot", "make extboot", 60)
-        cp1 = "cp -f bios/BIOS-bochs-latest qemu/pc-bios/bios.bin"
-        cp2 = "cp -f vgabios/VGABIOS-lgpl-latest.bin qemu/pc-bios/vgabios.bin"
-        cp3 = "cp -f vgabios/VGABIOS-lgpl-latest.cirrus.bin qemu/pc-bios/vgabios-cirrus.bin"
-        cp4 = "cp -f extboot/extboot.bin qemu/pc-bios/extboot.bin"
-        cmd = "&& ".join([cp1, cp2, cp3, cp4])
-        run(cmd, "copy bios binaries", 30)
-
-    # install from qemu directory
-    run("make -C qemu install", "(make install) ", 120)
-
-    # create symlinks
-    qemu_path = os.path.join(test.bindir, "qemu")
-    qemu_img_path = os.path.join(test.bindir, "qemu-img")
-    if os.path.lexists(qemu_path):
-        os.unlink(qemu_path)
-    if os.path.lexists(qemu_img_path):
-        os.unlink(qemu_img_path)
-    kvm_qemu = os.path.join(kvm_build_dir, "bin", "qemu-system-x86_64")
-    kvm_qemu_img = os.path.join(kvm_build_dir, "bin", "qemu-img")
-    os.symlink(kvm_qemu, qemu_path)
-    os.symlink(kvm_qemu_img, qemu_img_path)
 
-    kvm_log.info("Done building and installing KVM")
+    kvm_module_path = None
+    kvm_vendor_module_path = None
+    for folder, subdirs, files in os.walk(build_dir):
+        if "kvm.ko" in files:
+            kvm_module_path = os.path.join(folder, "kvm.ko")
+            kvm_vendor_module_path = os.path.join(folder, "kvm-%s.ko" % vendor)
+
+    abort = False
+    if not kvm_module_path:
+        kvm_log.error("Could not find KVM module that was supposed to be"
+                      " built on the source dir")
+        abort = True
+    elif not kvm_vendor_module_path:
+        kvm_log.error("Could not find KVM (%s) module that was supposed to be"
+                      " built on the source dir" % vendor)
+        abort = True
+    if abort:
+        raise error.TestError("Could not load KVM modules.")
+
+    utils.system("/sbin/insmod %s" % kvm_module_path)
+    time.sleep(1)
+    utils.system("/sbin/insmod %s" % kvm_vendor_module_path)
+
+    if not utils.module_is_loaded("kvm"):
+        message = "Failed to load the KVM modules built for the test"
+        kvm_log.error(message)
+        raise error.TestError(message)
diff --git a/client/tests/kvm_runtest_2/kvm_utils.py b/client/tests/kvm_runtest_2/kvm_utils.py
index be8ad95..eb6afb4 100644
--- a/client/tests/kvm_runtest_2/kvm_utils.py
+++ b/client/tests/kvm_runtest_2/kvm_utils.py
@@ -15,6 +15,8 @@  import re
 
 import kvm_log
 
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
 
 # Functions for working with dicts obtained from the test config file
 
@@ -99,6 +101,100 @@  def safe_kill(pid, signal):
         return False
 
 
+def get_latest_kvm_release_tag(release_dir):
+    try:
+        page_url = os.path.join(release_dir, "showfiles.php")
+        local_web_page = utils.unmap_url("/", page_url, "/tmp")
+        f = open(local_web_page, "r")
+        data = f.read()
+        f.close()
+        rx = re.compile("package_id=(\d+).*\>kvm\<", re.IGNORECASE)
+        matches = rx.findall(data)
+        package_id = matches[0]
+        #package_id = 209008
+        rx = re.compile("package_id=%s.*release_id=\d+\">(\d+)" % package_id, 
+                        re.IGNORECASE)
+        matches = rx.findall(data)
+        return matches[0] # the first match contains the latest release tag
+    except Exception, e:
+        message = "Could not fetch latest KVM release tag (%s)" % str(e)
+        kvm_log.error(message)
+        raise error.TestError(message)
+
+
+def get_git_branch(repository, branch, srcdir, commit=None, lbranch=None):
+    """
+    Retrieves a given git code repository.
+
+        @param repository: Git repository URL
+    """
+    kvm_log.info("Getting sources from git <REP=%s BRANCH=%s TAG=%s>"
+                 " to local directory <%s>" % (repository, branch, commit, 
+                                               srcdir))
+    pwd = os.getcwd()
+    os.chdir(srcdir)
+    if os.path.exists(".git"):
+        utils.system("git reset --hard")
+    else:
+        utils.system("git init")
+
+    if not lbranch:
+        lbranch = branch
+
+    utils.system("git fetch -q -f -u -t %s %s:%s" %
+                 (repository, branch, lbranch))
+    utils.system("git checkout %s" % lbranch)
+    if commit:
+        utils.system("git checkout %s" % commit)
+
+    h = utils.system_output('git log --pretty=format:"%H" -1')
+    desc = utils.system_output("git describe")
+    kvm_log.info("Commit hash for %s is %s (%s)" % (repository, h.strip(),
+                                                    desc))
+    os.chdir(pwd)
+
+
+def unload_module(module_name):
+    """
+    Removes a module. Handles dependencies. If even then it's not possible
+    to remove one of the modules, it will trhow an error.CmdError exception.
+
+        @param module_name: Name of the module we want to remove
+    """
+    l_raw = utils.system_output("/sbin/lsmod").splitlines()
+    lsmod = [x for x in l_raw if x.split()[0] == module_name]
+    if len(lsmod) > 0:
+        line_parts = lsmod[0].split()
+        if len(line_parts) == 4:
+            submodules = line_parts[3].split(",")
+            for submodule in submodules:
+                unload_module(submodule)
+        utils.system("/sbin/modprobe -r %s" % module_name)
+        kvm_log.info("Module %s unloaded" % module_name)
+    else:
+        kvm_log.info("Module %s is already unloaded" % module_name)
+
+
+def check_kvm_source_dir(source_dir):
+    """
+    Inspects the kvm source directory and verifies its disposition. In some
+    occasions build may be dependant on the source directory disposition.
+
+        @param source_dir: Source code path that will be inspected.
+    """
+    os.chdir(source_dir)
+    has_qemu_dir = os.path.isdir('qemu')
+    has_kvm_dir = os.path.isdir('kvm')
+    if has_qemu_dir and not has_kvm_dir:
+        kvm_log.info("qemu directory detected, source dir layout 1")
+        return 1
+    if has_kvm_dir and not has_qemu_dir:
+        kvm_log.info("kvm directory detected, source dir layout 2")
+        return 2
+    else:
+        raise error.TestError("Unknown source dir layout, cannot proceed.")
+
+
 # The following are a class and functions used for SSH, SCP and Telnet communication with guests.
 
 class kvm_spawn: