--- /dev/null
+#
+# Assemble a blktap source package with DKMS.
+#
+
+PATH := $(CURDIR)/bin:$(PATH)
+KERN_REPO := git://xenbits.xensource.com/people/dstodden/linux.git
+GIT := git
+BRANCH_PREFIX := xenbits/blktap/next-
+
+export PATH
+export GIT
+
+-include rev.mk
+
+PKG_NAME = blktap
+PKG_VERSION = $(shell echo $(REV:v%=%) | tr - +)
+SRCDIR = src
+DEB = $(PKG_NAME)-dkms_$(PKG_VERSION)_all.deb
+
+BRANCH_SOURCES = \
+ drivers/block/blktap \
+ include/linux/blktap.h
+
+SUDO = sudo
+DKMS = dkms -m $(PKG_NAME) -v $(DKMS_VERSION)
+DKMS_VERSION = $(PKG_VERSION)
+DKMS_SRCDIR = /usr/src/$(PKG_NAME)-$(DKMS_VERSION)
+DKMS_DSCDIR = /var/lib/dkms/$(PKG_NAME)/$(DKMS_VERSION)/dsc
+DKMS_DEBDIR = /var/lib/dkms/$(PKG_NAME)/$(DKMS_VERSION)/deb
+DKMS_TPLDIR = $(DKMS_SRCDIR)/$(PKG_NAME)-dkms-mkdeb
+DKMS_DEB = $(DKMS_DEBDIR)/$(DEB)
+
+DKMS_FRAGS = \
+ dkms.head.conf \
+ dkms.backports.conf \
+ dkms.extras.conf
+
+BACKPORTDIR = $(SRCDIR)/patches/backports
+EXTRASDIR = $(SRCDIR)/patches/extras
+
+.PHONY: checkout \
+ backports \
+ dkms \
+ extras \
+ source \
+ install
+
+.DELETE_ON_ERROR: \
+ rev.mk \
+ kernelbranches.out
+
+all: .stamp-source
+
+source: .stamp-checkout .stamp-backports .stamp-extras \
+ $(SRCDIR)/dkms.conf $(SRCDIR)/Makefile
+
+rev.mk: kernelbranches.out
+ > $@
+ (echo -n "KVER = "; head -n1 | cut -d: -f2;) < $< >> $@
+ (echo -n "REV = "; head -n1 | cut -d: -f3;) < $< >> $@
+
+kernelbranches.out:
+ kernelbranches $(KERN_REPO) $(BRANCH_PREFIX) > $@
+
+nexti = read i 2>/dev/null < $(1) || i=0; echo $$i; echo $$((i+1)) > $(1)
+
+.stamp-checkout:
+ $(GIT) archive --remote=$(KERN_REPO) --format=tar \
+ --prefix=$(SRCDIR)/ $(REV) $(BRANCH_SOURCES) | \
+ tar xf -
+ touch $@
+
+.stamp-backports:
+ rm -rf dkms.backports.conf $(BACKPORTDIR)
+ mkdir -p $(BACKPORTDIR)
+ cd $(BACKPORTDIR); \
+ backports $(KERN_REPO) $(BRANCH_PREFIX) $(BRANCH_SOURCES) | \
+ while read file pattern; do \
+ n=$$($(call nexti,patchno)); \
+ echo "PATCH[$$n]='backports/$$file'"; \
+ echo "PATCH_MATCH[$$n]='$$pattern'"; \
+ done >> $(CURDIR)/dkms.backports.conf;
+ touch $@
+
+.stamp-extras:
+ rm -rf dkms.extras.conf $(EXTRASDIR)
+ mkdir -p $(EXTRASDIR)
+ find patches/extras -name \*.diff | \
+ while read patch; do \
+ cp $$patch $(EXTRASDIR); \
+ n=$$($(call nexti,patchno)); \
+ echo "PATCH[$$n]=extras/$$(basename $$patch)"; \
+ done >> dkms.extras.conf
+ touch .stamp-$@
+
+$(SRCDIR)/Makefile:
+ > $@
+ echo 'export CONFIG_BLK_DEV_TAP = m' >> $@
+ echo 'obj-$$(CONFIG_BLK_DEV_TAP) := drivers/block/blktap/' >> $@
+ echo 'KBUILD_CPPFLAGS += -I$$(src)/include' >> $@
+
+dkms.head.conf: dkms.head.conf.in .stamp-checkout
+ sed -e's/@PKG_NAME@/$(PKG_NAME)/' \
+ -e's/@PKG_VERSION@/$(PKG_VERSION)/' \
+ < $< > $@
+
+$(SRCDIR)/dkms.conf: .stamp-backports .stamp-extras $(DKMS_FRAGS)
+ cat $(DKMS_FRAGS) > $@
+
+install: .stamp-source sudo-dkms-install
+
+sudo-%:
+ $(SUDO) $(MAKE) $*
+
+dkms-install:
+ rm -rf $(DKMS_SRCDIR)
+ ln -s $(CURDIR)/$(SRCDIR) $(DKMS_SRCDIR)
+ $(DKMS) add
+ touch .stamp-$@
+
+dkms-build:
+ $(DKMS) build
+ touch .stamp-$@
+
+dkms-deb:
+ $(DKMS) mkdeb --source-only
+ touch .stamp-$@
+
+$(DKMS_TPLDIR):
+ mkdir -p $(DKMS_TPLDIR)
+ cp -r template/debian $(DKMS_TPLDIR)/
+
+dkms-template: $(DKMS_TPLDIR)
+
+dkms-clean:
+ [ -z "$$($(DKMS) status)" ] || $(DKMS) remove --all
+ rm -rf $(DKMS_SRCDIR)
+ rm -f .stamp-dkms-*
+
+$(DKMS_DEB): sudo-dkms-deb
+
+$(DEB): $(DKMS_DEB)
+ cp $(DKMS_DEB) $(DEB)
+
+deb: $(DEB)
+
+clean: sudo-dkms-clean
+ rm -rf src
+ rm -f .stamp-checkout .stamp-backports .stamp-extras patchno
+ rm -f $(DKMS_FRAGS)
--- /dev/null
+#!/usr/bin/python
+
+import re
+
+class Trie(object):
+
+ def __init__(self, parent = None, item = None):
+ self.parent = parent
+ self.item = None
+ self.children = {}
+
+ def insert(self, key, item):
+ if not key:
+ self.item = item
+
+ else:
+ head = key[0]
+ tail = key[1:]
+
+ child = self.children.get(head)
+
+ if child is None:
+ child = self.__class__(self)
+ self.children[head] = child
+
+ child.insert(tail, item)
+
+ def delete(self, key):
+ if not key:
+ self.item = None
+
+ else:
+
+ head = key[0]
+ tail = key[1:]
+ child = self.children.get(head)
+ if child:
+ if child.delete(tail):
+ del self.children[head]
+
+ return not len(self.children)
+
+ def __setitem__(self, key, item):
+ self.insert(key, item)
+
+ def __delitem__(self, key):
+ self.delete(key)
+
+ def __repr__(self):
+ return "(%r, {%s})" % \
+ (self.item,
+ ", ".join(map(lambda (key, child):
+ "'%s': %s" % (key, repr(child)),
+ self.children.items())))
+
+ SPECIAL = "()|."
+
+ @classmethod
+ def __escape(cls, key):
+ if key in cls.SPECIAL:
+ return "\\%s" % key
+ return key
+
+ def regex(self):
+
+ children = []
+
+ for key, child in self.children.iteritems():
+ children.append(self.__escape(key) + child.regex())
+
+ if not children:
+ return ""
+
+ if len(children) == 1:
+ return str(children[0])
+
+ children.sort()
+ return "(%s)" % "|".join(children)
+
+class KernelVersion(object):
+
+ PATTERN = re.compile("^(\d+).(\d+).(\d+)(.*)$")
+
+ def __init__(self, ver, pat, sub, ext = ""):
+ self.ver = int(ver)
+ assert self.ver <= 0xFF
+
+ self.pat = int(pat)
+ assert self.pat <= 0xFF
+
+ self.sub = int(sub)
+ assert self.sub <= 0xFF
+
+ self.ext = ext
+
+ __FIRST = [2, 4, 0]
+
+ __DISCONT = { 2: { 4: ( 37, [2, 5, 0] ),
+ 5: ( 75, [2, 6, 0] ),
+ 6: ( 39, [3, 0, 0] ) },
+ 3: { 0: ( 99, [3, 1, 0] ) } }
+
+ class InvalidVersion(Exception):
+
+ def __init__(self, kv):
+ self.version = version
+
+ def __str__(self, kv):
+ raise "Nonexistent %r" % repr(self.version)
+
+ @classmethod
+ def first(cls):
+ return cls(*cls.__FIRST)
+
+ def next(self):
+ try:
+ _max, next = self.__DISCONT[self.ver][self.pat]
+ except KeyError:
+ raise self.InvalidVersion(self)
+
+ if self.sub < _max:
+ return self.__class__(self.ver, self.pat, self.sub + 1)
+
+ elif self.sub == _max:
+ return self.__class__(*next)
+
+ else:
+ raise self.InvalidVersion(self)
+
+ def __repr__(self):
+ return "%s(%r, %r, %r, %r)" % \
+ (self.__class__.__name__,
+ self.ver, self.pat, self.sub, self.ext)
+
+ def __str__(self):
+ return "%d.%d.%d%s" % \
+ (self.ver, self.pat, self.sub, self.ext)
+
+ @classmethod
+ def from_string(cls, s):
+ match = cls.PATTERN.search(s)
+ if not match:
+ raise Exception("Not a kernel version: %s" % s)
+
+ kv = cls(*match.groups())
+ assert str(kv) == s
+
+ return kv
+
+ @classmethod
+ def from_int(cls, val):
+ ver = (val >> 16) & 0xFF
+ pat = (val >> 8) & 0xFF
+ sub = (val ) & 0xFF
+
+ kv = cls(ver, pat, sub)
+ assert int(kv) == val
+
+ def __int__(self):
+ return \
+ (self.ver << 16) + \
+ (self.pat << 8) + \
+ (self.sub )
+
+ def __lt__(self, other):
+ return int(self) < int(other)
+
+ def __le__(self, other):
+ return int(self) <= int(other)
+
+ def __ge__(self, other):
+ return int(self) >= int(other)
+
+ def __gt__(self, other):
+ return int(self) > int(other)
+
+class VersionRange(object):
+
+ def __init__(self, start, until):
+ self.start = start
+ self.until = until
+
+ @classmethod
+ def from_strings(cls, start, until):
+ return cls(KernelVersion.from_string(start),
+ KernelVersion.from_string(until))
+
+ def __iter__(self):
+ kv = self.start
+
+ while kv < self.until:
+ yield kv
+ kv = kv.next()
+
+ def regex(self):
+ t = Trie()
+
+ for i in self:
+ t[str(i)] = None
+
+ return t.regex()
+
+if __name__ == '__main__':
+ from sys import argv, stdin, stderr
+ import os
+
+ prog = os.path.basename(argv[0])
+
+ def usage(ostream):
+ print >>ostream, "Usage: %s [<cmd>] [<args>]" % prog
+ print >>ostream
+ print >>ostream, " regex <start> <until>"
+ print >>ostream, " list <start> <until>"
+ print >>ostream, " sort [rev]"
+
+ def fail():
+ usage(stderr)
+ exit(1)
+
+ try:
+ cmd = argv[1]
+ except IndexError:
+ fail()
+
+ if cmd in ('regex', 'list'):
+ try:
+ start, until = argv[2:4]
+ except ValueError:
+ fail()
+
+ if cmd == 'regex':
+ kvs = VersionRange.from_strings(start, until)
+ print "^%s([^0-9]|$)" % kvs.regex()
+
+ elif cmd == 'list':
+ kvs = VersionRange.from_strings(start, until)
+ for kv in kvs:
+ print kv
+
+ elif cmd == 'sort':
+ try:
+ rev = argv[2] == 'rev'
+ except IndexError:
+ rev = False
+
+ kvs = []
+
+ for line in stdin:
+ line = line.strip()
+ for s in line.strip().split():
+ kv = KernelVersion.from_string(s)
+ kvs.append(kv)
+
+ kvs.sort()
+ if rev:
+ kvs.reverse()
+
+ for kv in kvs:
+ print kv
+
+ else:
+ fail()