__author__ = """Copyright Martin J. Bligh, 2006,
Copyright IBM Corp. 2006, Ryan Harper <ryanh@us.ibm.com>"""
import os, shutil, copy, pickle, re, glob
from autotest_lib.client.bin import kernel, kernel_config, os_dep, test
from autotest_lib.client.bin import utils
class xen(kernel.kernel):
def log(self, msg):
print msg
self.logfile.write('%s\n' % msg)
def __init__(self, job, base_tree, results_dir, tmp_dir, build_dir,
leave = False, kjob = None):
# call base-class
kernel.kernel.__init__(self, job, base_tree, results_dir,
tmp_dir, build_dir, leave)
self.kjob = kjob
def config(self, config_file, config_list = None):
raise NotImplementedError('config() not implemented for xen')
def build(self, make_opts = '', logfile = '', extraversion='autotest'):
"""build xen
make_opts
additional options to make, if any
"""
self.log('running build')
os_dep.commands('gcc', 'make')
# build xen with extraversion flag
os.environ['XEN_EXTRAVERSION'] = '-unstable-%s'% extraversion
if logfile == '':
logfile = os.path.join(self.log_dir, 'xen_build')
os.chdir(self.build_dir)
self.log('log_dir: %s ' % self.log_dir)
self.job.logging.tee_redirect_debug_dir(self.log_dir, log_name=logfile)
# build xen hypervisor and user-space tools
targets = ['xen', 'tools']
threads = 2 * utils.count_cpus()
for t in targets:
build_string = 'make -j %d %s %s' % (threads, make_opts, t)
self.log('build_string: %s' % build_string)
utils.system(build_string)
# make a kernel job out of the kernel from the xen src if one isn't provided
if self.kjob is None:
# get xen kernel tree ready
self.log("prep-ing xen'ified kernel source tree")
utils.system('make prep-kernels')
v = self.get_xen_kernel_build_ver()
self.log('building xen kernel version: %s' % v)
# build xen-ified kernel in xen tree
kernel_base_tree = os.path.join(self.build_dir, \
'linux-%s' % self.get_xen_kernel_build_ver())
self.log('kernel_base_tree = %s' % kernel_base_tree)
# fix up XENGUEST value in EXTRAVERSION; we can't have
# files with '$(XENGEUST)' in the name, =(
self.fix_up_xen_kernel_makefile(kernel_base_tree)
# make the kernel job
self.kjob = self.job.kernel(kernel_base_tree)
# hardcoding dom0 config (no modules for testing, yay!)
# FIXME: probe host to determine which config to pick
c = self.build_dir + '/buildconfigs/linux-defconfig_xen0_x86_32'
self.log('using kernel config: %s ' % c)
self.kjob.config(c)
# Xen's kernel tree sucks; doesn't use bzImage, but vmlinux
self.kjob.set_build_target('vmlinuz')
# also, the vmlinuz is not out in arch/*/boot, ARGH! more hackery
self.kjob.set_build_image(self.job.tmpdir + '/build/linux/vmlinuz')
self.kjob.build()
self.job.logging.restore()
xen_version = self.get_xen_build_ver()
self.log('BUILD VERSION: Xen: %s Kernel:%s' % \
(xen_version, self.kjob.get_kernel_build_ver()))
def build_timed(self, *args, **kwds):
raise NotImplementedError('build_timed() not implemented')
def install(self, tag='', prefix = '/', extraversion='autotest'):
"""make install in the kernel tree"""
self.log('Installing ...')
os.chdir(self.build_dir)
if not os.path.isdir(prefix):
os.mkdir(prefix)
self.boot_dir = os.path.join(prefix, 'boot')
if not os.path.isdir(self.boot_dir):
os.mkdir(self.boot_dir)
# remember what we are going to install
xen_version = '%s-%s' % (self.get_xen_build_ver(), extraversion)
self.xen_image = self.boot_dir + '/xen-' + xen_version + '.gz'
self.xen_syms = self.boot_dir + '/xen-syms-' + xen_version
self.log('Installing Xen ...')
os.environ['XEN_EXTRAVERSION'] = '-unstable-%s'% extraversion
# install xen
utils.system('make DESTDIR=%s -C xen install' % prefix)
# install tools
utils.system('make DESTDIR=%s -C tools install' % prefix)
# install kernel
ktag = self.kjob.get_kernel_build_ver()
kprefix = prefix
self.kjob.install(tag=ktag, prefix=kprefix)
def add_to_bootloader(self, tag='autotest', args=''):
""" add this kernel to bootloader, taking an
optional parameter of space separated parameters
e.g.: kernel.add_to_bootloader('mykernel', 'ro acpi=off')
"""
# turn on xen mode
self.job.bootloader.enable_xen_mode()
# remove existing entry if present
self.job.bootloader.remove_kernel(tag)
# add xen and xen kernel
self.job.bootloader.add_kernel(
self.kjob.image, tag, initrd=self.kjob.initrd,
xen_hypervisor=self.xen_image)
# if no args passed, populate from /proc/cmdline
if not args:
args = open('/proc/cmdline', 'r').readline().strip()
# add args to entry one at a time
for a in args.split(' '):
self.job.bootloader.add_args(tag, a)
# turn off xen mode
self.job.bootloader.disable_xen_mode()
def get_xen_kernel_build_ver(self):
"""Check xen buildconfig for current kernel version"""
version = patchlevel = sublevel = ''
extraversion = localversion = ''
version_file = self.build_dir + '/buildconfigs/mk.linux-2.6-xen'
for line in open(version_file, 'r').readlines():
if line.startswith('LINUX_VER'):
start = line.index('=') + 1
version = line[start:].strip() + "-xen"
break
return version
def fix_up_xen_kernel_makefile(self, kernel_dir):
"""Fix up broken EXTRAVERSION in xen-ified Linux kernel Makefile"""
xenguest = ''
makefile = kernel_dir + '/Makefile'
for line in open(makefile, 'r').readlines():
if line.startswith('XENGUEST'):
start = line.index('=') + 1
xenguest = line[start:].strip()
break;
# change out $XENGUEST in EXTRAVERSION line
utils.system('sed -i.old "s,\$(XENGUEST),%s," %s' % (xenguest,
makefile))
def get_xen_build_ver(self):
"""Check Makefile and .config to return kernel version"""
version = patchlevel = sublevel = ''
extraversion = localversion = ''
for line in open(self.build_dir + '/xen/Makefile', 'r').readlines():
if line.startswith('export XEN_VERSION'):
start = line.index('=') + 1
version = line[start:].strip()
if line.startswith('export XEN_SUBVERSION'):
start = line.index('=') + 1
sublevel = line[start:].strip()
if line.startswith('export XEN_EXTRAVERSION'):
start = line.index('=') + 1
extraversion = line[start:].strip()
return "%s.%s%s" % (version, sublevel, extraversion)