1 __author__ = """Copyright Martin J. Bligh, 2006, 2 Copyright IBM Corp. 2006, Ryan Harper <ryanh (at] us.ibm.com>""" 3 4 import os, shutil, copy, pickle, re, glob 5 from autotest_lib.client.bin import kernel, kernel_config, os_dep, test 6 from autotest_lib.client.bin import utils 7 8 9 class xen(kernel.kernel): 10 11 def log(self, msg): 12 print msg 13 self.logfile.write('%s\n' % msg) 14 15 16 def __init__(self, job, base_tree, results_dir, tmp_dir, build_dir, 17 leave = False, kjob = None): 18 # call base-class 19 kernel.kernel.__init__(self, job, base_tree, results_dir, 20 tmp_dir, build_dir, leave) 21 self.kjob = kjob 22 23 24 def config(self, config_file, config_list = None): 25 raise NotImplementedError('config() not implemented for xen') 26 27 28 def build(self, make_opts = '', logfile = '', extraversion='autotest'): 29 """build xen 30 31 make_opts 32 additional options to make, if any 33 """ 34 self.log('running build') 35 os_dep.commands('gcc', 'make') 36 # build xen with extraversion flag 37 os.environ['XEN_EXTRAVERSION'] = '-unstable-%s'% extraversion 38 if logfile == '': 39 logfile = os.path.join(self.log_dir, 'xen_build') 40 os.chdir(self.build_dir) 41 self.log('log_dir: %s ' % self.log_dir) 42 self.job.logging.tee_redirect_debug_dir(self.log_dir, log_name=logfile) 43 44 # build xen hypervisor and user-space tools 45 targets = ['xen', 'tools'] 46 threads = 2 * utils.count_cpus() 47 for t in targets: 48 build_string = 'make -j %d %s %s' % (threads, make_opts, t) 49 self.log('build_string: %s' % build_string) 50 utils.system(build_string) 51 52 # make a kernel job out of the kernel from the xen src if one isn't provided 53 if self.kjob is None: 54 # get xen kernel tree ready 55 self.log("prep-ing xen'ified kernel source tree") 56 utils.system('make prep-kernels') 57 58 v = self.get_xen_kernel_build_ver() 59 self.log('building xen kernel version: %s' % v) 60 61 # build xen-ified kernel in xen tree 62 kernel_base_tree = os.path.join(self.build_dir, \ 63 'linux-%s' % self.get_xen_kernel_build_ver()) 64 65 self.log('kernel_base_tree = %s' % kernel_base_tree) 66 # fix up XENGUEST value in EXTRAVERSION; we can't have 67 # files with '$(XENGEUST)' in the name, =( 68 self.fix_up_xen_kernel_makefile(kernel_base_tree) 69 70 # make the kernel job 71 self.kjob = self.job.kernel(kernel_base_tree) 72 73 # hardcoding dom0 config (no modules for testing, yay!) 74 # FIXME: probe host to determine which config to pick 75 c = self.build_dir + '/buildconfigs/linux-defconfig_xen0_x86_32' 76 self.log('using kernel config: %s ' % c) 77 self.kjob.config(c) 78 79 # Xen's kernel tree sucks; doesn't use bzImage, but vmlinux 80 self.kjob.set_build_target('vmlinuz') 81 82 # also, the vmlinuz is not out in arch/*/boot, ARGH! more hackery 83 self.kjob.set_build_image(self.job.tmpdir + '/build/linux/vmlinuz') 84 85 self.kjob.build() 86 87 self.job.logging.restore() 88 89 xen_version = self.get_xen_build_ver() 90 self.log('BUILD VERSION: Xen: %s Kernel:%s' % \ 91 (xen_version, self.kjob.get_kernel_build_ver())) 92 93 94 def build_timed(self, *args, **kwds): 95 raise NotImplementedError('build_timed() not implemented') 96 97 98 def install(self, tag='', prefix = '/', extraversion='autotest'): 99 """make install in the kernel tree""" 100 self.log('Installing ...') 101 102 os.chdir(self.build_dir) 103 104 if not os.path.isdir(prefix): 105 os.mkdir(prefix) 106 self.boot_dir = os.path.join(prefix, 'boot') 107 if not os.path.isdir(self.boot_dir): 108 os.mkdir(self.boot_dir) 109 110 # remember what we are going to install 111 xen_version = '%s-%s' % (self.get_xen_build_ver(), extraversion) 112 self.xen_image = self.boot_dir + '/xen-' + xen_version + '.gz' 113 self.xen_syms = self.boot_dir + '/xen-syms-' + xen_version 114 115 self.log('Installing Xen ...') 116 os.environ['XEN_EXTRAVERSION'] = '-unstable-%s'% extraversion 117 118 # install xen 119 utils.system('make DESTDIR=%s -C xen install' % prefix) 120 121 # install tools 122 utils.system('make DESTDIR=%s -C tools install' % prefix) 123 124 # install kernel 125 ktag = self.kjob.get_kernel_build_ver() 126 kprefix = prefix 127 self.kjob.install(tag=ktag, prefix=kprefix) 128 129 130 def add_to_bootloader(self, tag='autotest', args=''): 131 """ add this kernel to bootloader, taking an 132 optional parameter of space separated parameters 133 e.g.: kernel.add_to_bootloader('mykernel', 'ro acpi=off') 134 """ 135 136 # turn on xen mode 137 self.job.bootloader.enable_xen_mode() 138 139 # remove existing entry if present 140 self.job.bootloader.remove_kernel(tag) 141 142 # add xen and xen kernel 143 self.job.bootloader.add_kernel( 144 self.kjob.image, tag, initrd=self.kjob.initrd, 145 xen_hypervisor=self.xen_image) 146 147 # if no args passed, populate from /proc/cmdline 148 if not args: 149 args = open('/proc/cmdline', 'r').readline().strip() 150 151 # add args to entry one at a time 152 for a in args.split(' '): 153 self.job.bootloader.add_args(tag, a) 154 155 # turn off xen mode 156 self.job.bootloader.disable_xen_mode() 157 158 159 def get_xen_kernel_build_ver(self): 160 """Check xen buildconfig for current kernel version""" 161 version = patchlevel = sublevel = '' 162 extraversion = localversion = '' 163 164 version_file = self.build_dir + '/buildconfigs/mk.linux-2.6-xen' 165 166 for line in open(version_file, 'r').readlines(): 167 if line.startswith('LINUX_VER'): 168 start = line.index('=') + 1 169 version = line[start:].strip() + "-xen" 170 break 171 172 return version 173 174 175 def fix_up_xen_kernel_makefile(self, kernel_dir): 176 """Fix up broken EXTRAVERSION in xen-ified Linux kernel Makefile""" 177 xenguest = '' 178 makefile = kernel_dir + '/Makefile' 179 180 for line in open(makefile, 'r').readlines(): 181 if line.startswith('XENGUEST'): 182 start = line.index('=') + 1 183 xenguest = line[start:].strip() 184 break; 185 186 # change out $XENGUEST in EXTRAVERSION line 187 utils.system('sed -i.old "s,\$(XENGUEST),%s," %s' % (xenguest, 188 makefile)) 189 190 191 def get_xen_build_ver(self): 192 """Check Makefile and .config to return kernel version""" 193 version = patchlevel = sublevel = '' 194 extraversion = localversion = '' 195 196 for line in open(self.build_dir + '/xen/Makefile', 'r').readlines(): 197 if line.startswith('export XEN_VERSION'): 198 start = line.index('=') + 1 199 version = line[start:].strip() 200 if line.startswith('export XEN_SUBVERSION'): 201 start = line.index('=') + 1 202 sublevel = line[start:].strip() 203 if line.startswith('export XEN_EXTRAVERSION'): 204 start = line.index('=') + 1 205 extraversion = line[start:].strip() 206 207 return "%s.%s%s" % (version, sublevel, extraversion) 208