summaryrefslogtreecommitdiff
path: root/debian/bin
diff options
context:
space:
mode:
Diffstat (limited to 'debian/bin')
-rw-r--r--debian/bin/abiupdate.py184
-rw-r--r--debian/bin/buildcheck.py225
-rw-r--r--debian/bin/check-patches.sh13
-rwxr-xr-xdebian/bin/gencontrol.py358
-rw-r--r--debian/bin/genorig.py136
-rw-r--r--debian/bin/kconfig.py37
-rw-r--r--debian/bin/patch.apply227
-rw-r--r--debian/bin/perf11
-rw-r--r--debian/bin/test-patches81
9 files changed, 1272 insertions, 0 deletions
diff --git a/debian/bin/abiupdate.py b/debian/bin/abiupdate.py
new file mode 100644
index 00000000..c0b21b5a
--- /dev/null
+++ b/debian/bin/abiupdate.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append(sys.path[0] + "/../lib/python")
+
+import optparse, os, shutil, tempfile, urllib2
+from debian_linux.abi import Symbols
+from debian_linux.config import *
+from debian_linux.debian import *
+
+default_url_base = "http://ftp.de.debian.org/debian/"
+default_url_base_incoming = "http://incoming.debian.org/"
+
+class url_debian_flat(object):
+ def __init__(self, base):
+ self.base = base
+
+ def __call__(self, source, filename):
+ return self.base + filename
+
+class url_debian_pool(object):
+ def __init__(self, base):
+ self.base = base
+
+ def __call__(self, source, filename):
+ return self.base + "pool/main/" + source[0] + "/" + source + "/" + filename
+
+class main(object):
+ dir = None
+
+ def __init__(self, url, url_config = None, arch = None, featureset = None, flavour = None):
+ self.log = sys.stdout.write
+
+ self.url = self.url_config = url
+ if url_config is not None:
+ self.url_config = url_config
+ self.override_arch = arch
+ self.override_featureset = featureset
+ self.override_flavour = flavour
+
+ changelog = Changelog(version = VersionLinux)
+ while changelog[0].distribution == 'UNRELEASED':
+ changelog.pop(0)
+ changelog = changelog[0]
+
+ self.source = changelog.source
+ self.version = changelog.version.linux_version
+ self.version_source = changelog.version.complete
+
+ local_config = ConfigCoreDump(fp = file("debian/config.defines.dump"))
+
+ self.version_abi = self.version + '-' + local_config['abi',]['abiname']
+
+ def __call__(self):
+ self.dir = tempfile.mkdtemp(prefix = 'abiupdate')
+ try:
+ self.log("Retreive config\n")
+ config = self.get_config()
+ if self.override_arch:
+ arches = [self.override_arch]
+ else:
+ arches = config[('base',)]['arches']
+ for arch in arches:
+ self.update_arch(config, arch)
+ finally:
+ shutil.rmtree(self.dir)
+
+ def extract_package(self, filename, base):
+ base_out = self.dir + "/" + base
+ os.mkdir(base_out)
+ os.system("dpkg-deb --extract %s %s" % (filename, base_out))
+ return base_out
+
+ def get_abi(self, arch, prefix):
+ filename = "linux-headers-%s-%s_%s_%s.deb" % (self.version_abi, prefix, self.version_source, arch)
+ f = self.retrieve_package(self.url, filename)
+ d = self.extract_package(f, "linux-headers-%s_%s" % (prefix, arch))
+ f1 = d + "/usr/src/linux-headers-%s-%s/Module.symvers" % (self.version_abi, prefix)
+ s = Symbols(open(f1))
+ shutil.rmtree(d)
+ return s
+
+ def get_config(self):
+ filename = "linux-support-%s_%s_all.deb" % (self.version_abi, self.version_source)
+ f = self.retrieve_package(self.url_config, filename)
+ d = self.extract_package(f, "linux-support")
+ c = d + "/usr/src/linux-support-" + self.version_abi + "/config.defines.dump"
+ config = ConfigCoreDump(fp = file(c))
+ shutil.rmtree(d)
+ return config
+
+ def retrieve_package(self, url, filename):
+ u = url(self.source, filename)
+ filename_out = self.dir + "/" + filename
+
+ f_in = urllib2.urlopen(u)
+ f_out = file(filename_out, 'w')
+ while 1:
+ r = f_in.read()
+ if not r:
+ break
+ f_out.write(r)
+ return filename_out
+
+ def save_abi(self, symbols, arch, featureset, flavour):
+ dir = "debian/abi/%s" % self.version_abi
+ if not os.path.exists(dir):
+ os.makedirs(dir)
+ out = "%s/%s_%s_%s" % (dir, arch, featureset, flavour)
+ symbols.write(open(out, 'w'))
+
+ def update_arch(self, config, arch):
+ if self.override_featureset:
+ featuresets = [self.override_featureset]
+ else:
+ featuresets = config[('base', arch)]['featuresets']
+ for featureset in featuresets:
+ self.update_featureset(config, arch, featureset)
+
+ def update_featureset(self, config, arch, featureset):
+ config_base = config.merge('base', arch, featureset)
+
+ if not config_base.get('enabled', True):
+ return
+
+ if self.override_flavour:
+ flavours = [self.override_flavour]
+ else:
+ flavours = config_base['flavours']
+ for flavour in flavours:
+ self.update_flavour(config, arch, featureset, flavour)
+
+ def update_flavour(self, config, arch, featureset, flavour):
+ config_base = config.merge('base', arch, featureset, flavour)
+
+ if not config_base.get('modules', True):
+ return
+
+ self.log("Updating ABI for arch %s, featureset %s, flavour %s: " % (arch, featureset, flavour))
+ try:
+ if featureset == 'none':
+ localversion = flavour
+ else:
+ localversion = featureset + '-' + flavour
+
+ abi = self.get_abi(arch, localversion)
+ self.save_abi(abi, arch, featureset, flavour)
+ self.log("Ok.\n")
+ except urllib2.HTTPError, e:
+ self.log("Failed to retrieve %s: %s\n" % (e.filename, e))
+ except StandardError, e:
+ self.log("FAILED!\n")
+ import traceback
+ traceback.print_exc(None, sys.stdout)
+
+if __name__ == '__main__':
+ options = optparse.OptionParser()
+ options.add_option("-i", "--incoming", action = "store_true", dest = "incoming")
+ options.add_option("--incoming-config", action = "store_true", dest = "incoming_config")
+ options.add_option("-u", "--url-base", dest = "url_base", default = default_url_base)
+ options.add_option("--url-base-incoming", dest = "url_base_incoming", default = default_url_base_incoming)
+
+ opts, args = options.parse_args()
+
+ kw = {}
+ if len(args) >= 1:
+ kw['arch'] =args[0]
+ if len(args) >= 2:
+ kw['featureset'] =args[1]
+ if len(args) >= 3:
+ kw['flavour'] =args[2]
+
+ url_base = url_debian_pool(opts.url_base)
+ url_base_incoming = url_debian_flat(opts.url_base_incoming)
+ if opts.incoming_config:
+ url = url_config = url_base_incoming
+ else:
+ url_config = url_base
+ if opts.incoming:
+ url = url_base_incoming
+ else:
+ url = url_base
+
+ main(url, url_config, **kw)()
diff --git a/debian/bin/buildcheck.py b/debian/bin/buildcheck.py
new file mode 100644
index 00000000..3297ba24
--- /dev/null
+++ b/debian/bin/buildcheck.py
@@ -0,0 +1,225 @@
+#!/usr/bin/python
+
+import sys
+sys.path.append('debian/lib/python')
+
+import fnmatch
+import stat
+
+from debian_linux.abi import Symbols
+from debian_linux.config import ConfigCoreDump
+from debian_linux.debian import *
+
+
+class CheckAbi(object):
+ class SymbolInfo(object):
+ def __init__(self, symbol, symbol_ref=None):
+ self.symbol = symbol
+ self.symbol_ref = symbol_ref or symbol
+
+ @property
+ def module(self):
+ return self.symbol.module
+
+ @property
+ def name(self):
+ return self.symbol.name
+
+ def write(self, out, ignored):
+ info = []
+ if ignored:
+ info.append("ignored")
+ for name in ('module', 'version', 'export'):
+ data = getattr(self.symbol, name)
+ data_ref = getattr(self.symbol_ref, name)
+ if data != data_ref:
+ info.append("%s: %s -> %s" % (name, data_ref, data))
+ else:
+ info.append("%s: %s" % (name, data))
+ out.write("%-48s %s\n" % (self.symbol.name, ", ".join(info)))
+
+ def __init__(self, config, dir, arch, featureset, flavour):
+ self.config = config
+ self.arch, self.featureset, self.flavour = arch, featureset, flavour
+
+ self.filename_new = "%s/Module.symvers" % dir
+
+ changelog = Changelog(version=VersionLinux)[0]
+ version = changelog.version.linux_version
+ abiname = self.config['abi',]['abiname']
+ self.filename_ref = "debian/abi/%s-%s/%s_%s_%s" % (version, abiname, arch, featureset, flavour)
+
+ def __call__(self, out):
+ ret = 0
+
+ new = Symbols(open(self.filename_new))
+ try:
+ ref = Symbols(open(self.filename_ref))
+ except IOError:
+ out.write("Can't read ABI reference. ABI not checked! Continuing.\n")
+ return 0
+
+ symbols, add, change, remove = self._cmp(ref, new)
+
+ ignore = self._ignore(symbols)
+
+ add_effective = add - ignore
+ change_effective = change - ignore
+ remove_effective = remove - ignore
+
+ if change_effective or remove_effective:
+ out.write("ABI has changed! Refusing to continue.\n")
+ ret = 1
+ elif change or remove:
+ out.write("ABI has changed but all changes have been ignored. Continuing.\n")
+ elif add_effective:
+ out.write("New symbols have been added. Continuing.\n")
+ elif add:
+ out.write("New symbols have been added but have been ignored. Continuing.\n")
+ else:
+ out.write("No ABI changes.\n")
+
+ if add:
+ out.write("\nAdded symbols:\n")
+ for name in sorted(add):
+ symbols[name].write(out, name in ignore)
+
+ if change:
+ out.write("\nChanged symbols:\n")
+ for name in sorted(change):
+ symbols[name].write(out, name in ignore)
+
+ if remove:
+ out.write("\nRemoved symbols:\n")
+ for name in sorted(remove):
+ symbols[name].write(out, name in ignore)
+
+ return ret
+
+ def _cmp(self, ref, new):
+ ref_names = set(ref.keys())
+ new_names = set(new.keys())
+
+ add = set()
+ change = set()
+ remove = set()
+
+ symbols = {}
+
+ for name in new_names - ref_names:
+ add.add(name)
+ symbols[name] = self.SymbolInfo(new[name])
+
+ for name in ref_names.intersection(new_names):
+ s_ref = ref[name]
+ s_new = new[name]
+
+ if s_ref != s_new:
+ change.add(name)
+ symbols[name] = self.SymbolInfo(s_new, s_ref)
+
+ for name in ref_names - new_names:
+ remove.add(name)
+ symbols[name] = self.SymbolInfo(ref[name])
+
+ return symbols, add, change, remove
+
+ def _ignore_pattern(self, pattern):
+ ret = []
+ for i in re.split(r'(\*\*?)', pattern):
+ if i == '*':
+ ret.append(r'[^!]+')
+ elif i == '**':
+ ret.append(r'.+')
+ elif i:
+ ret.append(re.escape(i))
+ return re.compile('^' + ''.join(ret) + '$')
+
+ def _ignore(self, symbols):
+ # TODO: let config merge this lists
+ configs = []
+ configs.append(self.config.get(('abi', self.arch, self.featureset, self.flavour), {}))
+ configs.append(self.config.get(('abi', self.arch, None, self.flavour), {}))
+ configs.append(self.config.get(('abi', self.arch, self.featureset), {}))
+ configs.append(self.config.get(('abi', self.arch), {}))
+ configs.append(self.config.get(('abi', None, self.featureset), {}))
+ configs.append(self.config.get(('abi',), {}))
+
+ ignores = set()
+ for config in configs:
+ ignores.update(config.get('ignore-changes', []))
+
+ filtered = set()
+ for ignore in ignores:
+ type = 'name'
+ if ':' in ignore:
+ type, ignore = ignore.split(':')
+ if type in ('name', 'module'):
+ p = self._ignore_pattern(ignore)
+ for symbol in symbols.itervalues():
+ if p.match(getattr(symbol, type)):
+ filtered.add(symbol.name)
+ else:
+ raise NotImplementedError
+
+ return filtered
+
+
+class CheckImage(object):
+ def __init__(self, config, dir, arch, featureset, flavour):
+ self.dir = dir
+ self.arch, self.featureset, self.flavour = arch, featureset, flavour
+
+ self.config_entry_build = config.merge('build', arch, featureset, flavour)
+ self.config_entry_image = config.merge('image', arch, featureset, flavour)
+
+ def __call__(self, out):
+ image = self.config_entry_build.get('image-file')
+
+ if not image:
+ # TODO: Bail out
+ return 0
+
+ image = os.path.join(self.dir, image)
+
+ fail = 0
+
+ fail |= self.check_size(out, image)
+
+ return fail
+
+ def check_size(self, out, image):
+ value = self.config_entry_image.get('check-size')
+
+ if not value:
+ return 0
+
+ value = int(value)
+
+ size = os.stat(image)[stat.ST_SIZE]
+
+ if size > value:
+ out.write('Image too large (%d > %d)! Refusing to continue.\n' % (size, value))
+ return 1
+
+ out.write('Image fits (%d <= %d). Continuing.\n' % (size, value))
+ return 0
+
+
+class Main(object):
+ def __init__(self, dir, arch, featureset, flavour):
+ self.args = dir, arch, featureset, flavour
+
+ self.config = ConfigCoreDump(fp=file("debian/config.defines.dump"))
+
+ def __call__(self):
+ fail = 0
+
+ for c in CheckAbi, CheckImage:
+ fail |= c(self.config, *self.args)(sys.stdout)
+
+ return fail
+
+
+if __name__ == '__main__':
+ sys.exit(Main(*sys.argv[1:])())
diff --git a/debian/bin/check-patches.sh b/debian/bin/check-patches.sh
new file mode 100644
index 00000000..3a733fae
--- /dev/null
+++ b/debian/bin/check-patches.sh
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+
+TMPDIR=$(mktemp -d)
+trap "rm -rf $TMPDIR" EXIT
+grep -v "^#" debian/patches/series/* | awk '{if (NF >= 2) print "debian/patches/" $2}' | sort -u > $TMPDIR/used
+find debian/patches ! -path '*/series*' -type f -name "*.diff" -o -name "*.patch" -printf "%p\n" | sort > $TMPDIR/avail
+echo "Used patches"
+echo "=============="
+cat $TMPDIR/used
+echo
+echo "Unused patches"
+echo "=============="
+fgrep -v -f $TMPDIR/used $TMPDIR/avail
diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py
new file mode 100755
index 00000000..bcf0215e
--- /dev/null
+++ b/debian/bin/gencontrol.py
@@ -0,0 +1,358 @@
+#!/usr/bin/env python
+
+import os, sys
+sys.path.append("debian/lib/python")
+
+from debian_linux.config import ConfigCoreHierarchy
+from debian_linux.debian import *
+from debian_linux.gencontrol import Gencontrol as Base
+from debian_linux.utils import Templates
+
+class Gencontrol(Base):
+ def __init__(self, config_dirs = ["debian/config"], template_dirs = ["debian/templates"]):
+ super(Gencontrol, self).__init__(ConfigCoreHierarchy(config_dirs), Templates(template_dirs), VersionLinux)
+ self.process_changelog()
+ self.config_dirs = config_dirs
+
+ def _setup_makeflags(self, names, makeflags, data):
+ for src, dst, optional in names:
+ if src in data or not optional:
+ makeflags[dst] = data[src]
+
+ def do_main_setup(self, vars, makeflags, extra):
+ super(Gencontrol, self).do_main_setup(vars, makeflags, extra)
+ makeflags.update({
+ 'MAJOR': self.version.linux_major,
+ 'VERSION': self.version.linux_version,
+ 'UPSTREAMVERSION': self.version.linux_upstream,
+ 'ABINAME': self.abiname,
+ 'SOURCEVERSION': self.version.complete,
+ })
+
+ def do_main_packages(self, packages, vars, makeflags, extra):
+ packages.extend(self.process_packages(self.templates["control.main"], self.vars))
+
+ arch_makeflags = (
+ ('kernel-arch', 'KERNEL_ARCH', False),
+ )
+
+ def do_arch_setup(self, vars, makeflags, arch, extra):
+ config_base = self.config.merge('base', arch)
+ self._setup_makeflags(self.arch_makeflags, makeflags, config_base)
+
+ def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra):
+ headers_arch = self.templates["control.headers.arch"]
+ packages_headers_arch = self.process_packages(headers_arch, vars)
+
+ libc_dev = self.templates["control.libc-dev"]
+ packages_headers_arch[0:0] = self.process_packages(libc_dev, {})
+
+ packages_headers_arch[-1]['Depends'].extend(PackageRelation())
+ extra['headers_arch_depends'] = packages_headers_arch[-1]['Depends']
+
+ self.merge_packages(packages, packages_headers_arch, arch)
+
+ cmds_binary_arch = ["$(MAKE) -f debian/rules.real binary-arch-arch %s" % makeflags]
+ cmds_source = ["$(MAKE) -f debian/rules.real source-arch %s" % makeflags]
+ makefile.add('binary-arch_%s_real' % arch, cmds = cmds_binary_arch)
+ makefile.add('source_%s_real' % arch, cmds = cmds_source)
+
+ def do_featureset_setup(self, vars, makeflags, arch, featureset, extra):
+ config_base = self.config.merge('base', arch, featureset)
+ makeflags['LOCALVERSION_HEADERS'] = vars['localversion_headers'] = vars['localversion']
+
+ def do_featureset_packages(self, packages, makefile, arch, featureset, vars, makeflags, extra):
+ headers_featureset = self.templates["control.headers.featureset"]
+ package_headers = self.process_package(headers_featureset[0], vars)
+
+ self.merge_packages(packages, (package_headers,), arch)
+
+ cmds_binary_arch = ["$(MAKE) -f debian/rules.real binary-arch-featureset %s" % makeflags]
+ cmds_source = ["$(MAKE) -f debian/rules.real source-featureset %s" % makeflags]
+ makefile.add('binary-arch_%s_%s_real' % (arch, featureset), cmds = cmds_binary_arch)
+ makefile.add('source_%s_%s_real' % (arch, featureset), cmds = cmds_source)
+
+ flavour_makeflags_base = (
+ ('compiler', 'COMPILER', False),
+ ('kernel-arch', 'KERNEL_ARCH', False),
+ ('cflags', 'CFLAGS_KERNEL', True),
+ ('override-host-type', 'OVERRIDE_HOST_TYPE', True),
+ )
+
+ flavour_makeflags_image = (
+ ('type', 'TYPE', False),
+ ('initramfs', 'INITRAMFS', True),
+ )
+
+ flavour_makeflags_other = (
+ ('localversion', 'LOCALVERSION', False),
+ ('localversion-image', 'LOCALVERSION_IMAGE', True),
+ )
+
+ def do_flavour_setup(self, vars, makeflags, arch, featureset, flavour, extra):
+ config_base = self.config.merge('base', arch, featureset, flavour)
+ config_description = self.config.merge('description', arch, featureset, flavour)
+ config_image = self.config.merge('image', arch, featureset, flavour)
+
+ vars['class'] = config_description['hardware']
+ vars['longclass'] = config_description.get('hardware-long') or vars['class']
+
+ vars['localversion-image'] = vars['localversion']
+ override_localversion = config_image.get('override-localversion', None)
+ if override_localversion is not None:
+ vars['localversion-image'] = vars['localversion_headers'] + '-' + override_localversion
+
+ self._setup_makeflags(self.flavour_makeflags_base, makeflags, config_base)
+ self._setup_makeflags(self.flavour_makeflags_image, makeflags, config_image)
+ self._setup_makeflags(self.flavour_makeflags_other, makeflags, vars)
+
+ def do_flavour_packages(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra):
+ headers = self.templates["control.headers"]
+
+ config_entry_base = self.config.merge('base', arch, featureset, flavour)
+ config_entry_description = self.config.merge('description', arch, featureset, flavour)
+ config_entry_image = self.config.merge('image', arch, featureset, flavour)
+ config_entry_image_dbg = self.config.merge('image-dbg', arch, featureset, flavour)
+ config_entry_relations = self.config.merge('relations', arch, featureset, flavour)
+
+ compiler = config_entry_base.get('compiler', 'gcc')
+ relations_compiler = PackageRelation(config_entry_relations[compiler])
+ relations_compiler_build_dep = PackageRelation(config_entry_relations[compiler])
+ for group in relations_compiler_build_dep:
+ for item in group:
+ item.arches = [arch]
+ packages['source']['Build-Depends'].extend(relations_compiler_build_dep)
+
+ image_fields = {'Description': PackageDescription()}
+ for field in 'Depends', 'Provides', 'Suggests', 'Recommends', 'Conflicts':
+ image_fields[field] = PackageRelation(config_entry_image.get(field.lower(), None), override_arches=(arch,))
+
+ if config_entry_image.get('initramfs', True):
+ generators = config_entry_image['initramfs-generators']
+ config_entry_commands_initramfs = self.config.merge('commands-image-initramfs-generators', arch, featureset, flavour)
+ commands = [config_entry_commands_initramfs[i] for i in generators if config_entry_commands_initramfs.has_key(i)]
+ makeflags['INITRD_CMD'] = ' '.join(commands)
+ l_depends = PackageRelationGroup()
+ for i in generators:
+ i = config_entry_relations.get(i, i)
+ l_depends.append(i)
+ a = PackageRelationEntry(i)
+ if a.operator is not None:
+ a.operator = -a.operator
+ image_fields['Conflicts'].append(PackageRelationGroup([a]))
+ image_fields['Depends'].append(l_depends)
+
+ desc_parts = self.config.get_merge('description', arch, featureset, flavour, 'parts')
+ if desc_parts:
+ # XXX: Workaround, we need to support multiple entries of the same name
+ parts = list(set(desc_parts))
+ parts.sort()
+ desc = image_fields['Description']
+ for part in parts:
+ desc.append(config_entry_description['part-long-' + part])
+ desc.append_short(config_entry_description.get('part-short-' + part, ''))
+
+ packages_dummy = []
+ packages_own = []
+
+ if config_entry_image['type'] == 'plain-s390-tape':
+ image = self.templates["control.image.type-standalone"]
+ build_modules = False
+ elif config_entry_image['type'] == 'plain-xen':
+ raise RuntimeError
+ image = self.templates["control.image.type-modulesextra"]
+ build_modules = True
+ config_entry_xen = self.config.merge('xen', arch, featureset, flavour)
+ if config_entry_xen.get('dom0-support', True):
+ p = self.process_packages(self.templates['control.xen-linux-system'], vars)
+ l = PackageRelationGroup()
+ xen_versions = []
+ for xen_flavour in config_entry_xen['flavours']:
+ for version in config_entry_xen['versions']:
+ l.append("xen-hypervisor-%s-%s" % (version, xen_flavour))
+ xen_versions.append('%s-%s' % (version, xen_flavour))
+ makeflags['XEN_VERSIONS'] = ' '.join(xen_versions)
+ p[0]['Depends'].append(l)
+ packages_dummy.extend(p)
+ else:
+ build_modules = True
+ image = self.templates["control.image.type-%s" % config_entry_image['type']]
+ #image = self.templates["control.image.type-modulesinline"]
+
+ config_entry_xen = self.config.merge('xen', arch, featureset, flavour)
+ if config_entry_xen.get('dom0-support', False):
+ p = self.process_packages(self.templates['control.xen-linux-system'], vars)
+ l = PackageRelationGroup()
+ for xen_flavour in config_entry_xen['flavours']:
+ l.append("xen-hypervisor-%s" % xen_flavour)
+ p[0]['Depends'].append(l)
+ packages_dummy.extend(p)
+
+ vars.setdefault('desc', None)
+
+ packages_own.append(self.process_real_image(image[0], image_fields, vars))
+ packages_own.extend(self.process_packages(image[1:], vars))
+
+ if build_modules:
+ makeflags['MODULES'] = True
+ package_headers = self.process_package(headers[0], vars)
+ package_headers['Depends'].extend(relations_compiler)
+ packages_own.append(package_headers)
+ extra['headers_arch_depends'].append('%s (= ${binary:Version})' % packages_own[-1]['Package'])
+
+ build_debug = config_entry_image_dbg.get('enabled')
+ if build_debug:
+ makeflags['DEBUG'] = True
+ packages_own.extend(self.process_packages(self.templates['control.image-dbg'], vars))
+
+ self.merge_packages(packages, packages_own + packages_dummy, arch)
+
+ if config_entry_image['type'] == 'plain-xen':
+ for i in ('postinst', 'postrm', 'prerm'):
+ j = self.substitute(self.templates["image.xen.%s" % i], vars)
+ file("debian/%s.%s" % (packages_own[0]['Package'], i), 'w').write(j)
+
+ def get_config(*entry_name):
+ entry_real = ('image',) + entry_name
+ entry = self.config.get(entry_real, None)
+ if entry is None:
+ return None
+ return entry.get('configs', None)
+
+ def check_config_default(fail, f):
+ for d in self.config_dirs[::-1]:
+ f1 = d + '/' + f
+ if os.path.exists(f1):
+ return [f1]
+ if fail:
+ raise RuntimeError("%s unavailable" % f)
+ return []
+
+ def check_config_files(files):
+ ret = []
+ for f in files:
+ for d in self.config_dirs[::-1]:
+ f1 = d + '/' + f
+ if os.path.exists(f1):
+ ret.append(f1)
+ break
+ else:
+ raise RuntimeError("%s unavailable" % f)
+ return ret
+
+ def check_config(default, fail, *entry_name):
+ configs = get_config(*entry_name)
+ if configs is None:
+ return check_config_default(fail, default)
+ return check_config_files(configs)
+
+ kconfig = check_config('config', True)
+ kconfig.extend(check_config("%s/config" % arch, True, arch))
+ kconfig.extend(check_config("%s/config.%s" % (arch, flavour), False, arch, None, flavour))
+ kconfig.extend(check_config("featureset-%s/config" % featureset, False, None, featureset))
+ kconfig.extend(check_config("%s/%s/config" % (arch, featureset), False, arch, featureset))
+ kconfig.extend(check_config("%s/%s/config.%s" % (arch, featureset, flavour), False, arch, featureset, flavour))
+ makeflags['KCONFIG'] = ' '.join(kconfig)
+ if build_debug:
+ makeflags['KCONFIG_OPTIONS'] = '-o DEBUG_INFO=y'
+
+ cmds_binary_arch = ["$(MAKE) -f debian/rules.real binary-arch-flavour %s" % makeflags]
+ if packages_dummy:
+ cmds_binary_arch.append("$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='%s' %s" % (' '.join(["-p%s" % i['Package'] for i in packages_dummy]), makeflags))
+ cmds_build = ["$(MAKE) -f debian/rules.real build %s" % makeflags]
+ cmds_setup = ["$(MAKE) -f debian/rules.real setup-flavour %s" % makeflags]
+ makefile.add('binary-arch_%s_%s_%s_real' % (arch, featureset, flavour), cmds = cmds_binary_arch)
+ makefile.add('build_%s_%s_%s_real' % (arch, featureset, flavour), cmds = cmds_build)
+ makefile.add('setup_%s_%s_%s_real' % (arch, featureset, flavour), cmds = cmds_setup)
+
+ def do_extra(self, packages, makefile):
+ apply = self.templates['patch.apply']
+
+ vars = {
+ 'revisions': 'orig base ' + ' '.join([i.revision for i in self.versions[::-1]]),
+ 'upstream': self.version.upstream,
+ 'linux_upstream': self.version.linux_upstream,
+ 'abiname': self.abiname,
+ }
+
+ apply = self.substitute(apply, vars)
+
+ file('debian/bin/patch.apply', 'w').write(apply)
+
+ def merge_packages(self, packages, new, arch):
+ for new_package in new:
+ name = new_package['Package']
+ if name in packages:
+ package = packages.get(name)
+ package['Architecture'].append(arch)
+
+ for field in 'Depends', 'Provides', 'Suggests', 'Recommends', 'Conflicts':
+ if field in new_package:
+ if field in package:
+ v = package[field]
+ v.extend(new_package[field])
+ else:
+ package[field] = new_package[field]
+
+ else:
+ new_package['Architecture'] = [arch]
+ packages.append(new_package)
+
+ def process_changelog(self):
+ act_upstream = self.changelog[0].version.linux_upstream
+ versions = []
+ for i in self.changelog:
+ if i.version.linux_upstream != act_upstream:
+ break
+ versions.append(i.version)
+ self.versions = versions
+ version = self.version = self.changelog[0].version
+ if self.version.linux_modifier is not None:
+ self.abiname = ''
+ else:
+ self.abiname = '-%s' % self.config['abi',]['abiname']
+ self.vars = {
+ 'upstreamversion': self.version.linux_upstream,
+ 'version': self.version.linux_version,
+ 'source_upstream': self.version.upstream,
+ 'major': self.version.linux_major,
+ 'abiname': self.abiname,
+ }
+ self.config['version',] = {'source': self.version.complete, 'abiname': self.abiname}
+
+ distribution = self.changelog[0].distribution
+
+# Skip version/distribution checks for SLP
+ distribution = 'SLP'
+
+ if distribution in ('unstable', ):
+ if (version.linux_revision_experimental or
+ version.linux_revision_other):
+ raise RuntimeError("Can't upload to %s with a version of %s" %
+ (distribution, version))
+ if distribution in ('experimental', ):
+ if not version.linux_revision_experimental:
+ raise RuntimeError("Can't upload to %s with a version of %s" %
+ (distribution, version))
+
+ def process_real_image(self, entry, fields, vars):
+ entry = self.process_package(entry, vars)
+ for key, value in fields.iteritems():
+ if key in entry:
+ real = entry[key]
+ real.extend(value)
+ elif value:
+ entry[key] = value
+ return entry
+
+ def write(self, packages, makefile):
+ self.write_config()
+ super(Gencontrol, self).write(packages, makefile)
+
+ def write_config(self):
+ f = file("debian/config.defines.dump", 'w')
+ self.config.dump(f)
+ f.close()
+
+if __name__ == '__main__':
+ Gencontrol()()
diff --git a/debian/bin/genorig.py b/debian/bin/genorig.py
new file mode 100644
index 00000000..8a0979d1
--- /dev/null
+++ b/debian/bin/genorig.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append("debian/lib/python")
+
+import os
+import os.path
+import re
+import shutil
+import subprocess
+
+from debian_linux.debian import Changelog, VersionLinux
+from debian_linux.patches import PatchSeries
+
+class Main(object):
+ def __init__(self, input_files, override_version):
+ self.log = sys.stdout.write
+
+ self.input_files = input_files
+
+ changelog = Changelog(version = VersionLinux)[0]
+ source = changelog.source
+ version = changelog.version
+
+ if override_version:
+ version = VersionLinux('%s-undef' % override_version)
+
+ self.version_dfsg = version.linux_dfsg
+ if self.version_dfsg is None:
+ self.version_dfsg = '0'
+
+ self.log('Using source name %s, version %s, dfsg %s\n' % (source, version.upstream, self.version_dfsg))
+
+ self.orig = '%s-%s' % (source, version.upstream)
+ self.orig_tar = '%s_%s.orig.tar.gz' % (source, version.upstream)
+ self.tag = 'v' + version.upstream.replace('~', '-')
+
+ def __call__(self):
+ import tempfile
+ self.dir = tempfile.mkdtemp(prefix = 'genorig', dir = 'debian')
+ try:
+ if os.path.isdir(self.input_files[0]):
+ self.upstream_export(self.input_files[0])
+ else:
+ self.upstream_extract(self.input_files[0])
+ if len(self.input_files) > 1:
+ self.upstream_patch(self.input_files[1])
+ self.debian_patch()
+ self.tar()
+ finally:
+ shutil.rmtree(self.dir)
+
+ def upstream_export(self, input_repo):
+ self.log("Exporting %s from %s\n" % (self.tag, input_repo))
+
+ archive_proc = subprocess.Popen(['git', 'archive', '--format=tar',
+ '--prefix=%s/' % self.orig, self.tag],
+ cwd=input_repo,
+ stdout=subprocess.PIPE)
+ extract_proc = subprocess.Popen(['tar', '-xf', '-'], cwd=self.dir,
+ stdin=archive_proc.stdout)
+
+ if extract_proc.wait():
+ raise RuntimeError("Can't extract tarball")
+
+ def upstream_extract(self, input_tar):
+ self.log("Extracting tarball %s\n" % input_tar)
+ match = re.match(r'(^|.*/)(?P<dir>linux-\d+\.\d+\.\d+(-\S+)?)\.tar(\.(?P<extension>(bz2|gz)))?$', input_tar)
+ if not match:
+ raise RuntimeError("Can't identify name of tarball")
+
+ cmdline = ['tar', '-xf', input_tar, '-C', self.dir]
+ if match.group('extension') == 'bz2':
+ cmdline.append('-j')
+ elif match.group('extension') == 'gz':
+ cmdline.append('-z')
+
+ if subprocess.Popen(cmdline).wait():
+ raise RuntimeError("Can't extract tarball")
+
+ os.rename(os.path.join(self.dir, match.group('dir')), os.path.join(self.dir, self.orig))
+
+ def upstream_patch(self, input_patch):
+ self.log("Patching source with %s\n" % input_patch)
+ match = re.match(r'(^|.*/)patch-\d+\.\d+\.\d+(-\S+?)?(\.(?P<extension>(bz2|gz)))?$', input_patch)
+ if not match:
+ raise RuntimeError("Can't identify name of patch")
+ cmdline = []
+ if match.group('extension') == 'bz2':
+ cmdline.append('bzcat')
+ elif match.group('extension') == 'gz':
+ cmdline.append('zcat')
+ else:
+ cmdline.append('cat')
+ cmdline.append(input_patch)
+ cmdline.append('| (cd %s; patch -p1 -f -s -t --no-backup-if-mismatch)' % os.path.join(self.dir, self.orig))
+ if os.spawnv(os.P_WAIT, '/bin/sh', ['sh', '-c', ' '.join(cmdline)]):
+ raise RuntimeError("Can't patch source")
+
+ def debian_patch(self):
+ name = "orig-" + self.version_dfsg
+ self.log("Patching source with debian patch (series %s)\n" % name)
+ fp = file("debian/patches/series/" + name)
+ series = PatchSeries(name, "debian/patches", fp)
+ series(dir = os.path.join(self.dir, self.orig))
+
+ def tar(self):
+ out = os.path.join("../orig", self.orig_tar)
+ try:
+ os.mkdir("../orig")
+ except OSError: pass
+ try:
+ os.stat(out)
+ raise RuntimeError("Destination already exists")
+ except OSError: pass
+ self.log("Generate tarball %s\n" % out)
+ cmdline = ['tar -czf', out, '-C', self.dir, self.orig]
+ try:
+ if os.spawnv(os.P_WAIT, '/bin/sh', ['sh', '-c', ' '.join(cmdline)]):
+ raise RuntimeError("Can't patch source")
+ os.chmod(out, 0644)
+ except:
+ try:
+ os.unlink(out)
+ except OSError:
+ pass
+ raise
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+ parser = OptionParser(usage = "%prog [OPTION]... {TAR [PATCH] | REPO}")
+ parser.add_option("-V", "--override-version", dest = "override_version", help = "Override version", metavar = "VERSION")
+ options, args = parser.parse_args()
+
+ assert 1 <= len(args) <= 2
+ Main(args, options.override_version)()
diff --git a/debian/bin/kconfig.py b/debian/bin/kconfig.py
new file mode 100644
index 00000000..d5df64f1
--- /dev/null
+++ b/debian/bin/kconfig.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+import optparse
+import os.path
+import re
+import sys
+
+from debian_linux.kconfig import *
+
+def merge(output, configs, overrides):
+ kconfig = KconfigFile()
+ for c in configs:
+ kconfig.read(file(c))
+ for key, value in overrides.iteritems():
+ kconfig.set(key, value)
+ file(output, "w").write(str(kconfig))
+
+def opt_callback_dict(option, opt, value, parser):
+ match = re.match('^\s*(\S+)=(\S+)\s*$', value)
+ if not match:
+ raise optparse.OptionValueError('not key=value')
+ dest = option.dest
+ data = getattr(parser.values, dest)
+ data[match.group(1)] = match.group(2)
+
+if __name__ == '__main__':
+ parser = optparse.OptionParser(usage = "%prog [OPTION]... FILE...")
+ parser.add_option('-o', '--override',
+ action='callback',
+ callback=opt_callback_dict,
+ default={},
+ dest='overrides',
+ help="Override option",
+ type='string')
+ options, args = parser.parse_args()
+
+ merge(args[0], args[1:], options.overrides)
diff --git a/debian/bin/patch.apply b/debian/bin/patch.apply
new file mode 100644
index 00000000..a4130b93
--- /dev/null
+++ b/debian/bin/patch.apply
@@ -0,0 +1,227 @@
+#!/usr/bin/env python
+
+import os, os.path, re, sys
+from warnings import warn
+
+sys.path.append("/usr/share/linux-support-2.6.36-trunk/lib/python")
+
+from debian_linux.patches import PatchSeries, PatchSeriesList
+
+_default_home = "/usr/src/kernel-patches/all/2.6.36/debian"
+revisions = "orig base 1~experimental.1 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11".split()
+upstream = "2.6.36"
+
+class MatchExtra(object):
+ def __init__(self, arch, featureset):
+ self.arch, self.featureset = arch, featureset
+
+ self.matched_arch = self.matched_featureset = False
+
+ def __call__(self, obj):
+ if not self:
+ return False
+
+ data = obj.data
+
+ match_arch = []
+ match_featureset = []
+ for i in data:
+ if i.startswith("arch="):
+ match_arch.append(i[5:])
+ elif i.startswith("featureset="):
+ match_featureset.append(i[11:])
+ else:
+ raise RuntimeError('Ignored unknown modifier: %s' % i)
+
+ ret_arch = ret_featureset = False
+
+ if match_arch:
+ if self.arch is not None:
+ if self.arch in match_arch:
+ self.matched_arch = True
+ ret_arch = True
+
+ else:
+ ret_arch = True
+
+ if match_featureset:
+ if self.featureset is not None:
+ if self.featureset in match_featureset:
+ self.matched_featureset = True
+ ret_featureset = True
+
+ else:
+ ret_featureset = True
+
+ return ret_arch and ret_featureset
+
+ def __nonzero__(self):
+ return self.arch is not None or self.featureset is not None
+
+ def info(self):
+ ret = []
+ if self.matched_arch:
+ ret.append("arch=%s" % self.arch)
+ if self.matched_featureset:
+ ret.append("featureset=%s" % self.featureset)
+ return ret
+
+_marker = object()
+
+class version_file(object):
+ _file = 'version.Debian'
+ extra = None
+ in_progress = False
+
+ def __init__(self, upstream = None):
+ if os.path.exists(self._file):
+ s = file(self._file).readline().strip()
+ self._read(s)
+ elif upstream:
+ warn('No %s file, assuming Debian Linux %s' % (self._file, upstream))
+ self.upstream = upstream
+ self.revision = 'orig'
+ else:
+ raise RuntimeError, "Not possible to determine version"
+
+ def __str__(self):
+ if self.in_progress:
+ return "unstable"
+ ret = [self.upstream, self.revision]
+ if self.extra is not None:
+ ret.extend(self.extra.info())
+ return ' '.join(ret)
+
+ def _read(self, s):
+ if s == 'unstable':
+ raise RuntimeError("Tree is in an unstable condition. Can't continue!")
+ list = s.split()
+ self.upstream, self.revision = list[0:2]
+
+ arch = featureset = None
+ for i in list[2:]:
+ if i.startswith("arch="):
+ arch = i[5:]
+ elif i.startswith("featureset="):
+ featureset = i[11:]
+ else:
+ raise RuntimeError("Can't parse extra information")
+ self.extra = MatchExtra(arch, featureset)
+
+ def _write(self):
+ if os.path.lexists(self._file):
+ os.unlink(self._file)
+ file(self._file, 'w').write('%s\n' % self)
+
+ def begin(self):
+ self.in_progress = True
+ self._write()
+
+ def commit(self, revision, extra = _marker):
+ self.in_progress = False
+ self.revision = revision
+ if extra is not _marker:
+ self.extra = extra
+ self._write()
+
+def main():
+ options, args = parse_options()
+
+ if len(args) > 1:
+ print "Too much arguments"
+ return
+
+ home = options.home
+
+ vfile = version_file(upstream)
+ current_revision = vfile.revision
+ current_extra = vfile.extra
+
+ if len(args) == 1:
+ target_revision = args[0]
+ else:
+ target_revision = revisions[-1]
+ target_extra = MatchExtra(options.arch, options.featureset)
+
+ if vfile.upstream != upstream:
+ raise RuntimeError("Upstream version differs between tree (%s) and package (%s)" % (vfile.upstream, upstream))
+ if current_revision not in revisions:
+ raise RuntimeError, "Current revision is not in our list of revisions"
+ if target_revision not in revisions:
+ raise RuntimeError, "Target revision is not in our list of revisions"
+
+ if current_revision == target_revision and current_extra == target_extra:
+ print "Nothing to do"
+ return
+
+ current_index = revisions.index(current_revision)
+ target_index = revisions.index(target_revision)
+
+ if current_extra:
+ if current_revision != revisions[-1]:
+ raise RuntimeError, "Can't patch from %s with options %s" % (current, ' '.join(current_extra))
+ consider = ['%s-extra' % i for i in revisions[1:current_index + 1]]
+ s = PatchSeriesList.read(home, consider)
+ vfile.begin()
+ s(cond = current_extra, reverse = True)
+ vfile.commit(current_revision, None)
+
+ if current_index < target_index:
+ consider = revisions[current_index + 1:target_index + 1]
+ s = PatchSeriesList.read(home, consider)
+ vfile.begin()
+ s()
+ vfile.commit(target_revision)
+ elif current_index > target_index:
+ consider = revisions[target_index + 1:current_index + 1]
+ s = PatchSeriesList.read(home, consider)
+ vfile.begin()
+ s(reverse = True)
+ vfile.commit(target_revision)
+
+ if target_extra:
+ consider = ['%s-extra' % i for i in revisions[1:target_index + 1]]
+ s = PatchSeriesList.read(home, consider)
+ vfile.begin()
+ s(cond = target_extra)
+ vfile.commit(target_revision, target_extra)
+
+def parse_options():
+ from optparse import OptionParser
+ parser = OptionParser(
+ usage = "%prog [OPTION]... [TARGET]",
+ )
+ parser.add_option(
+ '-a', '--arch',
+ dest = 'arch',
+ help = "arch",
+ )
+ parser.add_option(
+ '-f', '--featureset',
+ dest = 'featureset',
+ help = "featureset",
+ )
+ parser.add_option(
+ '-H', '--overwrite-home',
+ default = _default_home, dest = 'home',
+ help = "overwrite home [default: %default]",
+ )
+
+ options, args = parser.parse_args()
+
+ if options.arch is None and options.featureset is not None:
+ raise RuntimeError('You specified a featureset without an arch, this is not really working')
+
+ return options, args
+
+if __name__ == '__main__':
+ def showwarning(message, category, filename, lineno):
+ sys.stderr.write("Warning: %s\n" % message)
+ import warnings
+ warnings.showwarning = showwarning
+ try:
+ main()
+ except RuntimeError, e:
+ sys.stderr.write("Error: %s\n" % e)
+ raise SystemExit, 1
+
diff --git a/debian/bin/perf b/debian/bin/perf
new file mode 100644
index 00000000..fc2c0797
--- /dev/null
+++ b/debian/bin/perf
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Execute the right version of perf for the current kernel.
+version="$(uname -r)"
+version="${version%%-*}"
+shopt -s execfail
+exec "perf_$version" "$@"
+
+# Not found? Tell the user which package to install.
+echo >&2 "E: linux-tools-$version is not installed."
+exit 1
diff --git a/debian/bin/test-patches b/debian/bin/test-patches
new file mode 100644
index 00000000..fdcff209
--- /dev/null
+++ b/debian/bin/test-patches
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+set -e
+shopt -s extglob
+
+# Set defaults from the running kernel
+arch="$(dpkg --print-architecture)"
+kernelabi="$(uname -r)"
+ff="${kernelabi#+([^-])-@(trunk|+([0-9]))-}"
+if [ "x$ff" != "x$kernelabi" ]; then
+ flavour="${ff#@(openvz|vserver|xen)-}"
+ if [ "x$flavour" != "x$ff" ]; then
+ featureset="${ff%-$flavour}"
+ else
+ featureset=none
+ fi
+else
+ flavour=
+ featureset=none
+fi
+
+eval "set -- $(getopt -n "$0" -- "f:j:s:" "$@")"
+while true; do
+ case "$1" in
+ -f) flavour="$2"; shift 2 ;;
+ -j) export DEBIAN_KERNEL_JOBS="$2"; shift 2 ;;
+ -s) featureset="$2"; shift 2 ;;
+ --) shift 1; break ;;
+ esac
+done
+
+if [ $# -lt 1 ]; then
+ echo >&2 "Usage: $0 [<options>] <patch>..."
+ cat >&2 <<EOF
+Options:
+ -f <flavour> specify the 'flavour' of kernel to build, e.g. 686
+ -j <jobs> specify number of compiler jobs to run in parallel
+ -s <featureset> specify an optional featureset to apply, e.g. xen
+EOF
+ exit 2
+fi
+
+if [ -z "$flavour" ]; then
+ echo >&2 "You must specify a flavour to build with the -f option"
+ exit 2
+fi
+
+dpkg-checkbuilddeps -B
+
+# Append 'a~test' to Debian version; this should be less than any official
+# successor and easily recognisable
+version="$(dpkg-parsechangelog | sed 's/^Version: //; t; d')"
+if [ "${version%a~test}" = "$version" ]; then
+ version="$version"a~test
+ dch -v "$version" --distribution UNRELEASED "Testing patches $*"
+fi
+debversion="${version##*-}"
+
+# Copy all patches into a new directory
+rm -rf debian/patches/test/
+mkdir debian/patches/test
+cp -t debian/patches/test/ "$@"
+
+# Generate patch series for the new version
+>debian/patches/series/"$debversion"
+for patch in "$@"; do
+ echo "+ test/$(basename "$patch")" >>debian/patches/series/"$debversion"
+done
+
+# Regenerate control and included rules
+rm debian/control debian/rules.gen
+debian/rules debian/control-real && exit 1 || true
+test -f debian/control
+test -f debian/rules.gen
+
+# Clean and patch source
+debian/rules clean
+debian/rules source
+
+# Build selected binaries
+fakeroot make -f debian/rules.gen binary-arch_"$arch"_"$featureset"_"$flavour"