|
Michal Marek |
7276a4 |
#!/usr/bin/env python
|
|
Michal Marek |
7276a4 |
"""
|
|
Michal Marek |
7276a4 |
xen-port-patches.py [git dir]
|
|
Michal Marek |
7276a4 |
Create custom patches for xen from custom patches that affect x86.
|
|
Michal Marek |
7276a4 |
Turned out to be a little functional programming exercise for the author.
|
|
Michal Marek |
7276a4 |
(c) 2005-04-06, Kurt Garloff <garloff@suse.de>
|
|
Michal Marek |
7276a4 |
"""
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
import re, glob, sys, os, filecmp
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
# List of replacement rules
|
|
Michal Marek |
7276a4 |
replrules = [(r"(.*)-xen(\.[^/\s])", r"\1\2"),
|
|
Michal Marek |
7276a4 |
(r"include/asm-([^/\s]+86[^/\s]*)/mach-xen/asm/", r"include/asm-\1/"),
|
|
Michal Marek |
7276a4 |
(r"arch/([^/\s]+86[^/\s]*)/include/mach-xen/asm/", r"arch/\1/include/asm/")]
|
|
Michal Marek |
7276a4 |
# List of compiled rules (speed reasons)
|
|
Michal Marek |
7276a4 |
#comprules = map(lambda(x): (x[0], x[1], re.compile(x[0])), replrules)
|
|
Michal Marek |
7276a4 |
comprules = [ (x[0], x[1], re.compile(x[0])) for x in replrules ]
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def applCorrFwd(path):
|
|
Michal Marek |
7276a4 |
"Try to apply replrules, return void elem if none applied, otherwise \
|
|
Michal Marek |
7276a4 |
corresponding old and new name"
|
|
Michal Marek |
7276a4 |
# Maximal functional programming obfusc^W elegance
|
|
Michal Marek |
7276a4 |
# Drop element 2 from each tupel
|
|
Michal Marek |
7276a4 |
return map(lambda(x): (x[0], x[1]), \
|
|
Michal Marek |
7276a4 |
# Filter out non-matched path combinations
|
|
Michal Marek |
7276a4 |
filter(lambda(x): x[2], \
|
|
Michal Marek |
7276a4 |
# Try all replacement rules
|
|
Michal Marek |
7276a4 |
map(lambda(x): (path,
|
|
Michal Marek |
7276a4 |
re.sub(x[0], x[1], path), x[2].search(path)),
|
|
Michal Marek |
7276a4 |
comprules)))
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def createReplList(patch):
|
|
Michal Marek |
7276a4 |
"Creates a list of files to watch and their corresp xen file names"
|
|
Michal Marek |
7276a4 |
pfile = open(patch, "r")
|
|
Michal Marek |
7276a4 |
srch = re.compile(r"^\+\+\+ [^/\s]+/([\S]*)")
|
|
Michal Marek |
7276a4 |
# Again illegi^W beautiful functional programming
|
|
Michal Marek |
7276a4 |
# return matched string no 1
|
|
Michal Marek |
7276a4 |
matches = map(lambda(m): m.group(1), \
|
|
Michal Marek |
7276a4 |
# filter out non-matches
|
|
Michal Marek |
7276a4 |
filter(lambda(m): m, \
|
|
Michal Marek |
7276a4 |
# find matches
|
|
Michal Marek |
7276a4 |
map(lambda(line): srch.search(line), pfile)))
|
|
Michal Marek |
7276a4 |
pfile.close()
|
|
Michal Marek |
7276a4 |
#print matches
|
|
Michal Marek |
7276a4 |
# Try path replacements, drop empty elements and one nesting level
|
|
Michal Marek |
7276a4 |
return map(lambda(x): (x[0][0], x[0][1]), \
|
|
Michal Marek |
7276a4 |
filter(lambda(x): x, map(applCorrFwd, matches)))
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def findPatchFiles(kgit):
|
|
Michal Marek |
7276a4 |
"Returns a list of all files in patches.*/ on below kgit"
|
|
Michal Marek |
7276a4 |
list = glob.glob(kgit + "/patches.*/*")
|
|
Michal Marek |
7276a4 |
# Avoid patches in patches.xen, backup files
|
|
Michal Marek |
7276a4 |
filterout = re.compile("(patches\.xen|~$|\.#)")
|
|
Michal Marek |
7276a4 |
return filter(lambda(x): not filterout.search(x), list)
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def writePatch(fname, hdr, body):
|
|
Michal Marek |
7276a4 |
"Create xen patch corresponding to other patch"
|
|
Michal Marek |
7276a4 |
xenrepl = re.compile(r"^.*\/([^\/]*)$")
|
|
Michal Marek |
7276a4 |
xenfname = re.sub(xenrepl, r"xen3-\1", fname)
|
|
Michal Marek |
7276a4 |
shortrepl = re.compile(r"^.*\/([^\/]*\/[^\/]*)$")
|
|
Michal Marek |
7276a4 |
shortname = re.sub(shortrepl, r"\1", fname)
|
|
Michal Marek |
7276a4 |
origname = ".".join([xenfname, "orig"])
|
|
Michal Marek |
7276a4 |
print "%s -> %s" % (shortname, xenfname)
|
|
Michal Marek |
7276a4 |
if os.access(xenfname, os.F_OK):
|
|
Michal Marek |
7276a4 |
os.rename(xenfname, origname)
|
|
Michal Marek |
7276a4 |
pfile = open(xenfname, "w")
|
|
Michal Marek |
7276a4 |
pfile.write(hdr)
|
|
Michal Marek |
7276a4 |
pfile.write("Automatically created from \"%s\" by " \
|
|
Michal Marek |
7276a4 |
"xen-port-patches.py\n\n" % shortname)
|
|
Michal Marek |
7276a4 |
pfile.write(body)
|
|
Michal Marek |
7276a4 |
pfile.close()
|
|
Michal Marek |
7276a4 |
if os.access(origname, os.F_OK):
|
|
Michal Marek |
7276a4 |
if filecmp.cmp(xenfname, origname):
|
|
Michal Marek |
7276a4 |
os.remove(xenfname)
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
ser = open("xen3-series.conf", "a")
|
|
Michal Marek |
7276a4 |
ser.write("\t\t%s\n" % xenfname)
|
|
Michal Marek |
7276a4 |
ser.close()
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
f771f0 |
def decorateSubject(subject):
|
|
Michal Marek |
f771f0 |
m = re.search(r"^(Subject:\s*(?:\[.*\])?\s*)(.*)", subject);
|
|
Michal Marek |
f771f0 |
if not m:
|
|
Michal Marek |
f771f0 |
return subject
|
|
Michal Marek |
f771f0 |
if re.search(r"^[^\s]*:[^:]*$", m.group(2)):
|
|
Michal Marek |
f771f0 |
# subsystem: text -> xen/subsystem: text
|
|
Michal Marek |
f771f0 |
tag = "xen/"
|
|
Michal Marek |
f771f0 |
else:
|
|
Michal Marek |
f771f0 |
# text -> xen: text
|
|
Michal Marek |
f771f0 |
tag = "xen: "
|
|
Michal Marek |
f771f0 |
return m.group(1) + tag + m.group(2) + "\n"
|
|
Michal Marek |
f771f0 |
|
|
Michal Marek |
7276a4 |
def mayCreatePatch(fname, repls):
|
|
Michal Marek |
7276a4 |
"Try to apply the replacement rules to fname"
|
|
Michal Marek |
7276a4 |
if fname.endswith(".gz"):
|
|
Michal Marek |
7276a4 |
decomp ="gzip"
|
|
Michal Marek |
7276a4 |
elif fname.endswith(".bz2"):
|
|
Michal Marek |
7276a4 |
decomp = "bzip2"
|
|
Michal Marek |
7276a4 |
elif fname.endswith(".xz"):
|
|
Michal Marek |
7276a4 |
decomp = "xz"
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
decomp = ""
|
|
Michal Marek |
7276a4 |
if decomp == "":
|
|
Michal Marek |
7276a4 |
pfile = open(fname, "r")
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
pfile = os.popen(" ".join([decomp, "-dc", fname]), "r")
|
|
Michal Marek |
7276a4 |
parts = fname.split(".")
|
|
Michal Marek |
7276a4 |
del parts[-1]
|
|
Michal Marek |
7276a4 |
fname = ".".join(parts)
|
|
Michal Marek |
7276a4 |
# Again an unelegant loop with an ugly state machine
|
|
Michal Marek |
7276a4 |
active = 0; header = 0
|
|
Michal Marek |
7276a4 |
patch = ""; rule = ()
|
|
Michal Marek |
7276a4 |
patchheader = ""; pheaderactive = 1
|
|
Michal Marek |
7276a4 |
endmarker = re.compile(r"^(Index|diff|CVS|RCS|\-\-\-|\+\+\+|===)")
|
|
Michal Marek |
f771f0 |
subj = re.compile(r"^Subject:\s")
|
|
Michal Marek |
34eaba |
commit = re.compile(r"^Git-[Cc]ommit:\s")
|
|
Michal Marek |
34eaba |
mainline = re.compile(r"^Patch-[Mm]ainline:\s")
|
|
Michal Marek |
7276a4 |
for line in pfile:
|
|
Michal Marek |
7276a4 |
hmark = endmarker.search(line)
|
|
Michal Marek |
7276a4 |
if pheaderactive:
|
|
Michal Marek |
7276a4 |
if hmark:
|
|
Michal Marek |
7276a4 |
pheaderactive = 0
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
f771f0 |
if subj and subj.search(line):
|
|
Michal Marek |
f771f0 |
subj = None
|
|
Michal Marek |
f771f0 |
line = decorateSubject(line)
|
|
Michal Marek |
34eaba |
elif commit.search(line):
|
|
Michal Marek |
34eaba |
continue
|
|
Michal Marek |
34eaba |
elif mainline.search(line):
|
|
Michal Marek |
34eaba |
line = "Patch-mainline: Never, SUSE-Xen specific\n"
|
|
Michal Marek |
7276a4 |
patchheader += line
|
|
Michal Marek |
7276a4 |
continue
|
|
Michal Marek |
7276a4 |
# If we get here, we're past the patch file header
|
|
Michal Marek |
7276a4 |
if active:
|
|
Michal Marek |
7276a4 |
if header:
|
|
Michal Marek |
7276a4 |
if not hmark:
|
|
Michal Marek |
7276a4 |
header = 0
|
|
Michal Marek |
7276a4 |
#else:
|
|
Michal Marek |
7276a4 |
patch += re.sub(rule[1], rule[0], line)
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
if hmark:
|
|
Michal Marek |
7276a4 |
active = 0
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
patch += line
|
|
Michal Marek |
7276a4 |
# else is no good, need to test again
|
|
Michal Marek |
7276a4 |
if not active and hmark:
|
|
Michal Marek |
7276a4 |
matches = filter(lambda(x): x[2],
|
|
Michal Marek |
7276a4 |
map(lambda(x): (x[0], x[1], x[2].search(line)), repls))
|
|
Michal Marek |
7276a4 |
if matches:
|
|
Michal Marek |
7276a4 |
active = 1; header = 1
|
|
Michal Marek |
7276a4 |
# There should never be more than one match ...
|
|
Michal Marek |
7276a4 |
rule = (matches[0][0], matches[0][1])
|
|
Michal Marek |
7276a4 |
patch += re.sub(rule[1], rule[0], line)
|
|
Michal Marek |
7276a4 |
pfile.close()
|
|
Michal Marek |
7276a4 |
if patch:
|
|
Michal Marek |
7276a4 |
writePatch(fname, patchheader, patch)
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def createXenPatches(filelist, repls):
|
|
Michal Marek |
7276a4 |
"For each file in the list, find hunks that may be needed for Xen"
|
|
Michal Marek |
7276a4 |
# We could do this again with functional programming, but the
|
|
Michal Marek |
7276a4 |
# memory requirements may be significant, so let's create a
|
|
Michal Marek |
7276a4 |
# loop on the per patchfile level.
|
|
Michal Marek |
7276a4 |
for pfile in filelist:
|
|
Michal Marek |
7276a4 |
mayCreatePatch(pfile, repls)
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
def main(args):
|
|
Michal Marek |
7276a4 |
"Main program"
|
|
Michal Marek |
7276a4 |
# Allow overriding kernel git dir
|
|
Michal Marek |
7276a4 |
if len(args) > 1 and args[1] != ".":
|
|
Michal Marek |
7276a4 |
kerngit = args[1]
|
|
Michal Marek |
7276a4 |
else:
|
|
Michal Marek |
7276a4 |
kerngit = re.sub(r"^(.*)/[^/]+/[^/]+$", r"\1", os.path.abspath(args[0]))
|
|
Michal Marek |
7276a4 |
print "Using kernel git at '%s'" % (kerngit)
|
|
Michal Marek |
7276a4 |
# Create list of replacements
|
|
Michal Marek |
7276a4 |
repllist = createReplList(kerngit + "/patches.xen/xen3-auto-xen-arch.diff")
|
|
Michal Marek |
7276a4 |
#print repllist
|
|
Michal Marek |
7276a4 |
# ... and compile
|
|
Michal Marek |
7276a4 |
complrepl = map(lambda(x): (x[0], x[1], re.compile(x[1])), repllist)
|
|
Michal Marek |
7276a4 |
# Create a list of patch files
|
|
Michal Marek |
7276a4 |
patchfiles = findPatchFiles(kerngit)
|
|
Michal Marek |
7276a4 |
#print patchfiles
|
|
Michal Marek |
7276a4 |
createXenPatches(patchfiles + args[2:], complrepl)
|
|
Michal Marek |
7276a4 |
|
|
Michal Marek |
7276a4 |
# Entry point
|
|
Michal Marek |
7276a4 |
if __name__ == '__main__':
|
|
Michal Marek |
7276a4 |
main(sys.argv)
|
|
Michal Marek |
7276a4 |
|