Home | History | Annotate | Download | only in bin
      1 # TODO: need a function to get the newest config file older than us from
      2 # the repo.
      3 
      4 import shutil, os
      5 from autotest_lib.client.bin import utils
      6 from autotest_lib.client.common_lib import error, kernel_versions
      7 
      8 def apply_overrides(orig_file, changes_file, output_file):
      9     override = dict()
     10 
     11     # First suck all the changes into a dictionary.
     12     input = file(changes_file, 'r')
     13     for line in input.readlines():
     14         if line.startswith('CONFIG_'):
     15             key = line.split('=')[0]
     16             override[key] = line;
     17         elif line.startswith('# CONFIG_'):
     18             key = line.split(' ')[1]
     19             override[key] = line;
     20     input.close()
     21 
     22     # Now go through the input file, overriding lines where need be
     23     input = file(orig_file, 'r')
     24     output = file(output_file, 'w')
     25     for line in input.readlines():
     26         if line.startswith('CONFIG_'):
     27             key = line.split('=')[0]
     28         elif line.startswith('# CONFIG_'):
     29             key = line.split(' ')[1]
     30         else:
     31             key = None
     32         if key and key in override:
     33             output.write(override[key])
     34         else:
     35             output.write(line)
     36     input.close()
     37     output.close()
     38 
     39 
     40 def diff_configs(old, new):
     41     utils.system('diff -u %s %s > %s' % (old, new, new + '.diff'),
     42                  ignore_status=True)
     43 
     44 
     45 
     46 def modules_needed(config):
     47     return (utils.grep('CONFIG_MODULES=y', config) and utils.grep('=m', config))
     48 
     49 
     50 def config_by_name(name, set):
     51     version = kernel_versions.version_choose_config(name, set[1:])
     52     if version:
     53         return set[0] + version
     54     return None
     55 
     56 
     57 class kernel_config(object):
     58     # Build directory must be ready before init'ing config.
     59     #
     60     # Stages:
     61     #       1. Get original config file
     62     #       2. Apply overrides
     63     #       3. Do 'make oldconfig' to update it to current source code
     64     #                  (gets done implicitly during the process)
     65     #
     66     # You may specifiy the a defconfig within the tree to build,
     67     # or a custom config file you want, or None, to get machine's
     68     # default config file from the repo.
     69 
     70     build_dir = ''          # the directory we're building in
     71     config_dir = ''         # local repository for config_file data
     72 
     73     build_config = ''       # the config file in the build directory
     74     orig_config = ''        # the original config file
     75     over_config = ''        # config file + overrides
     76 
     77 
     78     def __init__(self, job, build_dir, config_dir, orig_file,
     79                             overrides, defconfig = False, name = None, make = None):
     80         self.build_dir = build_dir
     81         self.config_dir = config_dir
     82 
     83         #       1. Get original config file
     84         self.build_config = build_dir + '/.config'
     85         if (orig_file == '' and not defconfig and not make):    # use user default
     86             set = job.config_get("kernel.default_config_set")
     87             defconf = None
     88             if set and name:
     89                 defconf = config_by_name(name, set)
     90             if not defconf:
     91                 defconf = job.config_get("kernel.default_config")
     92             if defconf:
     93                 orig_file = defconf
     94         if (orig_file == '' and not make and defconfig):        # use defconfig
     95             make = 'defconfig'
     96         if (orig_file == '' and make): # use the config command
     97             print "kernel_config: using " + make + " to configure kernel"
     98             os.chdir(build_dir)
     99             make_return = utils.system('make %s > /dev/null' % make)
    100             self.config_record(make)
    101             if (make_return):
    102                 raise error.TestError('make % failed' % make)
    103         else:
    104             print "kernel_config: using " + orig_file + \
    105                                             " to configure kernel"
    106             self.orig_config = config_dir + '/config.orig'
    107             utils.get_file(orig_file, self.orig_config)
    108             self.update_config(self.orig_config, self.orig_config+'.new')
    109             diff_configs(self.orig_config, self.orig_config+'.new')
    110 
    111 
    112         #       2. Apply overrides
    113         if overrides:
    114             print "kernel_config: using " + overrides + \
    115                                             " to re-configure kernel"
    116             self.over_config = config_dir + '/config.over'
    117             overrides_local = self.over_config + '.changes'
    118             utils.get_file(overrides, overrides_local)
    119             apply_overrides(self.build_config, overrides_local, self.over_config)
    120             self.update_config(self.over_config, self.over_config+'.new')
    121             diff_configs(self.over_config, self.over_config+'.new')
    122         else:
    123             self.over_config = self.orig_config
    124 
    125 
    126     def update_config(self, old_config, new_config = 'None'):
    127         os.chdir(self.build_dir)
    128         shutil.copyfile(old_config, self.build_config)
    129         utils.system('yes "" | make oldconfig > /dev/null')
    130         if new_config:
    131             shutil.copyfile(self.build_config, new_config)
    132 
    133     def config_record(self, name):
    134         #Copy the current .config file to the config.<name>[.<n>]
    135         i = 1
    136         to = self.config_dir + '/config.%s' % name
    137         while os.path.exists(to):
    138             i += 1
    139             to = self.config_dir + '/config.%s.%d' % (name,i)
    140         shutil.copyfile(self.build_dir + '/.config', to)
    141