dh-kpatches-0.99.36+nmu1/0000755000000000000000000000000010251672526011645 5ustar dh-kpatches-0.99.36+nmu1/Makefile0000644000000000000000000000271507762204674013322 0ustar DESTDIR = prefix = /usr bindir = ${prefix}/bin datadir = ${prefix}/share/debhelper/dh-kpatches docdir = ${prefix}/share/doc/dh-kpatches mandir = ${prefix}/share/man man1dir = ${mandir}/man1 DHSCRIPT = dh_installkpatches OTHERSCRIPTS = lskpatches TEMPLATES = apply.tmpl unpatch.tmpl register-patch VERSION = $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2) NOWEBSRC = dh-kpatches.nw NOWEBOUTSRC = $(shell noroots ${NOWEBSRC} | sed 's/<<\(.*\)>>/\1/') all: ${DHSCRIPT} ${TEMPLATES} make -C doc all ${DHSCRIPT}: ${DHSCRIPT}.in sed -e s=@TMPLDIR@=${datadir}= -e s=@DHKPVERS@=${VERSION}=<$< >$@ chmod 755 $@ internals: ${NOWEBSRC:.nw=.ps} ${NOWEBSRC:.nw=.html} ${NOWEBOUTSRC}: % : ${NOWEBSRC} notangle -R$@ $< | cpif $@ %.html: %.nw noweave -html -delay \ -filter "noweb/guesslang ${NOWEBOUTSRC} | noweb/inheritlang" \ -filter "noweb/htmltoc | noweb/enscript-html --color" \ -x \ $< > $@ %.ps: dh-kpatches.book %.html htmldoc --batch $< || test $$? = 4 clean: rm -f ${DHSCRIPT} ${NOWEBOUTSRC} rm -rf ${NOWEBSRC:.nw=-html} rm -f *.aux *.log *.dvi *.ps *.latex make -C doc clean install: all install -m755 -d ${DESTDIR}${datadir} ${DESTDIR}${bindir} install -m755 ${DHSCRIPT} ${OTHERSCRIPTS} ${DESTDIR}${bindir} install -m644 ${TEMPLATES} ${DESTDIR}${datadir} make -C doc install uninstall: rm -f ${DESTDIR}${bindir}/${DHSCRIPT} -cd ${DESTDIR}${bindir} && rm -f ${OTHERSCRIPTS} rm -rf ${DESTDIR}${datadir} make -C doc uninstall dh-kpatches-0.99.36+nmu1/dh-kpatches.prj0000644000000000000000000001272510251672506014562 0ustar ;; -*- Prcs -*- (Created-By-Prcs-Version 1 3 3) (Project-Description "") (Project-Version dh-kpatches v0-maint 59) (Parent-Version dh-kpatches v0-maint 58) (Version-Log "typo in previous checkin ignore stderr lines from dpkg-gencontrol (#263617) ") (New-Version-Log "") (Checkin-Time "Thu, 09 Jun 2005 00:46:30 +0200") (Checkin-Login dwitch) (Populate-Ignore ("RCS/.*,v$" "^debian/tmp" "^debian/dh-kpatches/" "^debian/kernel-patch-scripts" ".*-stamp$" "^debian/.*substvars$" "^debian/.*.debhelper$" "^dh_installkpatches.in$" "^doc/dh-kpatches.log$" "^dh_installkpatches$" "^doc/lskpatches.1$" "^doc/dh-kpatches.html$" "^doc/manpage.refs$" "^doc/manpage.links$" "^doc/dh-kpatches.out$" "^debian/files$" "^doc/dh-kpatches.jtex$" "^doc/dh-kpatches.aux$" "^doc/dh-kpatches.pdf$" "^doc/dh_installkpatches.1$" "^dh-kpatches-html/" "^dh-kpatches.html" "^dh-kpatches.latex$" "^dh-kpatches.ps$" "^dh-kpatches.dvi$" "^dh-kpatches.aux$" "^dh-kpatches.log$" )) (Project-Keywords) (Files ;; This is a comment. Fill in files here. ;; For example: (prcs/checkout.cc ()) ;; Files added by populate at Sat, 15 Feb 2003 20:44:20 +0100, ;; to version 0.0(w), by dwitch: (examples/kernel-patch-kdb.kpatches.arch (dh-kpatches/0_kdb-1.6.kp 1.2 644)) (doc/dh_installkpatches.refentry-contents.sgml (dh-kpatches/1_dh_install 1.9 644)) (doc/kpatch-policy.debiandoc.sgml (dh-kpatches/2_kpatch-pol 1.2 444)) (Makefile (dh-kpatches/3_Makefile 1.17 644)) (dh-kpatches.nw (dh-kpatches/4_dh_install 1.17.1.4.1.24.1.9 644)) (doc/dh-kpatches.docbook.sgml (dh-kpatches/5_kpatches-s 1.14 644)) (debian/rules (dh-kpatches/8_rules 1.8 755)) (debian/control (dh-kpatches/9_control 1.14 644)) (debian/copyright (dh-kpatches/12_copyright 1.2 644)) (debian/changelog (dh-kpatches/13_changelog 1.25.1.23.1.11.1.8 644)) ;; Files deleted by populate at Sat, 15 Feb 2003 20:48:01 +0100, ;; from version release-0.1(w), by dwitch: ; (debian/README.Debian ()) ;; Files added by populate at Sat, 15 Feb 2003 23:36:32 +0100, ;; to version release-0.3(w), by dwitch: (TODO (dh-kpatches/14_TODO 1.18 644)) ;; Files added by populate at Sat, 15 Feb 2003 23:38:41 +0100, ;; to version release-0.6(w), by dwitch: (debian/dh-kpatches.overrides (dh-kpatches/15_overrides 1.1 644)) ;; Files added by populate at Sat, 15 Feb 2003 23:45:55 +0100, ;; to version release-0.7(w), by dwitch: (examples/kernel-patch-kdb.kpatches.common (dh-kpatches/17_kernel-pat 1.1 644)) (debian/README-kernelpatch (dh-kpatches/18_README-ker 1.3 644)) ;; Files added by populate at Sat, 15 Feb 2003 23:57:04 +0100, ;; to version release-0.99.4(w), by dwitch: (doc/dh_installkpatches.refentry.sgml (dh-kpatches/19_dh_install 1.1 644)) (doc/Makefile (dh-kpatches/20_Makefile 1.8 644)) (debian/dh-kpatches.doc-base.dh-kpatches (dh-kpatches/21_dh-kpatche 1.2 644)) ;; Files deleted by populate at Sat, 15 Feb 2003 23:57:04 +0100, ;; from version release-0.99.4(w), by dwitch: ; (dh_installkpatches.xml ()) ;; Files added by populate at Sun, 16 Feb 2003 00:02:01 +0100, ;; to version release-0.99.10(w), by dwitch: (lskpatches (dh-kpatches/23_lskpatches 1.3 755)) (doc/lskpatches.refentry.sgml (dh-kpatches/24_lskpatches 1.1 644)) (doc/jadetex.cfg (dh-kpatches/25_jadetex.cf 1.1 644)) (debian/dh-kpatches.files (dh-kpatches/26_dh-kpatche 1.2 644)) (debian/kernel-patch-scripts.files (dh-kpatches/27_kernel-pat 1.3 644)) (debian/compat (dh-kpatches/28_compat 1.1 644)) ;; Files added by populate at Sun, 16 Feb 2003 00:03:31 +0100, ;; to version release-0.99.11(w), by dwitch: (examples-v1/kernel-patch-lkcd-alt-expanded.kpatches (dh-kpatches/29_kernel-pat 1.1 644)) (examples-v1/kernel-patch-lkcd-alt.kpatches (dh-kpatches/30_kernel-pat 1.1 644)) (examples-v1/kernel-patch-lkcd.kpatches (dh-kpatches/31_kernel-pat 1.1 644)) (examples-v1/kernel-patch-ltt.kpatches (dh-kpatches/32_kernel-pat 1.1 644)) ;; Files deleted by populate at Sun, 16 Feb 2003 00:03:31 +0100, ;; from version release-0.99.11(w), by dwitch: ; (dh-kpatches.prj.bak ()) ;; Files added by populate at Sun, 16 Feb 2003 00:04:40 +0100, ;; to version release-0.99.12(w), by dwitch: (register-patch (dh-kpatches/33_register-p 1.4 644)) ;; Files added by populate at Sun, 16 Feb 2003 00:07:40 +0100, ;; to version release-0.99.13(w), by dwitch: (examples-v1/kernel-patch-lkcd-alt3.kpatches (dh-kpatches/34_kernel-pat 1.1 644)) (debian/kernel-patch-scripts.overrides (dh-kpatches/35_kernel-pat 1.1 644)) ;; Files deleted by depopulate at Wed, 26 Feb 2003 00:16:09 +0100, ;; from version v0-maint.6(w), by dwitch: ; (debian/dh-kpatches.doc-base.kpatch-policy ()) ;; Files added by populate at Sun, 16 Nov 2003 00:45:42 +0100, ;; to version v0-dev-noweb.9(w), by dwitch: (noweb.css (dh-kpatches/40_noweb.css 1.5 644)) (dh-kpatches.book (dh-kpatches/41_dh-kpatche 1.1 644)) ;; Files added by populate at Sat, 22 Nov 2003 22:35:55 +0100, ;; to version v0-maint.33(w), by dwitch: (debian/README (dh-kpatches/42_README 1.1 644)) ;; Files deleted by depopulate at Sat, 29 Nov 2003 22:00:33 +0100, ;; from version v0-maint.40(w), by dwitch: ; (apply.tmpl ()) ; (unpatch.tmpl ()) ) (Merge-Parents) (New-Merge-Parents) dh-kpatches-0.99.36+nmu1/.dh-kpatches.prcs_aux0000644000000000000000000000441110251672506015662 0ustar ;; This file is automatically generated, editing may cause PRCS to do ;; REALLY bad things. (Created-By-Prcs-Version 1 3 3) (dh-kpatches.nw 32942 1118270411 4_dh_install 1.17.1.4.1.24.1.9) (debian/README-kernelpatch 1389 1069373161 18_README-ker 1.3) (debian/dh-kpatches.doc-base.dh-kpatches 399 1046215474 21_dh-kpatche 1.2) (debian/rules 1448 1069007602 8_rules 1.8) (examples-v1/kernel-patch-lkcd-alt.kpatches 304 1045350233 30_kernel-pat 1.1) (doc/kpatch-policy.debiandoc.sgml 10386 1045349200 2_kpatch-pol 1.2) (debian/dh-kpatches.files 230 1045350291 26_dh-kpatche 1.2) (dh-kpatches.book 522 1068939313 41_dh-kpatche 1.1) (examples-v1/kernel-patch-ltt.kpatches 433 1045350233 32_kernel-pat 1.1) (debian/copyright 1010 1045338681 12_copyright 1.2) (doc/jadetex.cfg 81 1045350141 25_jadetex.cf 1.1) (debian/compat 2 1045350141 28_compat 1.1) (examples-v1/kernel-patch-lkcd.kpatches 378 1045350233 31_kernel-pat 1.1) (Makefile 1485 1070139836 3_Makefile 1.17) (TODO 2755 1070146340 14_TODO 1.18) (doc/dh_installkpatches.refentry-contents.sgml 3264 1045350573 1_dh_install 1.9) (lskpatches 1755 1046216789 23_lskpatches 1.3) (debian/kernel-patch-scripts.files 147 1045350475 27_kernel-pat 1.3) (debian/changelog 20381 1118270743 13_changelog 1.25.1.23.1.11.1.8) (debian/dh-kpatches.overrides 162 1045348736 15_overrides 1.1) (debian/kernel-patch-scripts.overrides 93 1045350475 35_kernel-pat 1.1) (doc/dh_installkpatches.refentry.sgml 275 1045349845 19_dh_install 1.1) (debian/README 418 1069536855 42_README 1.1) (apply.tmpl 6267 1063837106 7_apply.tmpl 1.30) (examples/kernel-patch-kdb.kpatches.arch 331 1045349200 0_kdb-1.6.kp 1.2) (register-patch 313 1045356505 33_register-p 1.4) (dh_installkpatches.in 12383 1057179526 4_dh_install 1.17.1.4) (doc/dh-kpatches.docbook.sgml 24488 1049493420 5_kpatches-s 1.14) (examples/kernel-patch-kdb.kpatches.common 175 1045349200 17_kernel-pat 1.1) (doc/Makefile 1355 1056491344 20_Makefile 1.8) (examples-v1/kernel-patch-lkcd-alt3.kpatches 330 1045350475 34_kernel-pat 1.1) (noweb.css 1240 1071004911 40_noweb.css 1.5) (unpatch.tmpl 2484 1069374331 6_unpatch.tm 1.16) (doc/lskpatches.refentry.sgml 2071 1045350141 24_lskpatches 1.1) (debian/control 1299 1069007582 9_control 1.14) (examples-v1/kernel-patch-lkcd-alt-expanded.kpatches 326 1045350233 29_kernel-pat 1.1) dh-kpatches-0.99.36+nmu1/TODO0000644000000000000000000000530307762221444012340 0ustar TODO list for 1.0 target ======================== Those will be implemented in 0.100.x, and 0.99.x will not see any new developments, only bugfixes. * dependency handling - when a patch version is selected through the environment, propagate it to dependencies to be applied (unless env was used for the dep), and maybe check deps that were already applied. * core v1 functionality - complete transition of internal data structures to v1: - modularisation of operations - generalize apply/unpatch scripts and put them in kernel-patch-scripts package, for space-saving and to allow collaborating packages (see #118122), so that kpatch packages need only install symlinks to them. But above all, this is on one of the path to v1 implementation, so ... - rewrite apply/unpatch in perl, since the code of those will be mixed with the current dh_installkpatches script, to reach the above point. - support other operations than "diff application", esp. combined diff+cp (#118232, #129459) - be careful on unpatch (see description of "revision 1" format in the doc). - support kernel flavours (see description of "revision 1" format in the doc). * sanity stuff - review the kpatches-specs and kpatch-policy documents, and manpage. - maybe make dh_inst check build-deps versionning - make dh_installkpatches validate the fields in the kpatches file, so that wished features do not get reported as bugs :) (possibly) post-1.0 TODO list ============================= - generate a ${Kernel:versions} substvar, to make it possible to automagically maintain a useful package description. - provide a way to hide patches that are not meant to be used directly, but only depended upon (eg. kdbcore, evms-*), so that they do not uselessly cripple lskpatches output by default (possibly applies to the contents of applied-patches list as well). - provide a make-kpatch-pkg tool to help users in building Q&D kpatch packages for their internal use (I was not sure it was worth doing it, but at least one make-kpkg user requested the feature) - provide a dh_make template for helping to build official patch packages - tarfile support may require pax(1) to get Path-strip-level support - support for use of make-kpkg's versionning (eg. Version-sensitive: yes) ? - support for open kversion ranges, and enumerated. Something like: Kernel-version: 2.4.15 - (meaning: all 2.4 kernels starting at .15) Kernel-version: 2.2.10 -, 2.4.5 - Kernel-version: 2.4 (meaning: all versions in the 2.4 era) That will require sophisticated version-comparison rules, to accomodate well-known EXTRAVERSION prefixes (yes, upsteam-shipped EXTRAVERSION is the prefix of the suffix ;), ie. "test" and "pre" (-ac, -aa, -dj and such are better seen as flavours) dh-kpatches-0.99.36+nmu1/examples/0000755000000000000000000000000007747262756013503 5ustar dh-kpatches-0.99.36+nmu1/examples/kernel-patch-kdb.kpatches.arch0000644000000000000000000000051307623541520021233 0ustar Patch-name: Kernel debugger Patch-id: kdb Path-strip-level: 1 Patch-file: kdb-v1.5-2.2.18 Architecture: i386 Kernel-version: 2.2.18 Patch-file: kdb-v2.1-2.4.17-i386-1 Architecture: i386 Kernel-version: 2.4.17 Depends: kdbcore Patch-file: kdb-v2.1-2.4.17-ia64-011226-1 Architecture: ia64 Kernel-version: 2.4.17 Depends: kdbcore dh-kpatches-0.99.36+nmu1/examples/kernel-patch-kdb.kpatches.common0000644000000000000000000000025707623541520021613 0ustar Patch-name: Kernel debugger architecture-independant core Patch-id: kdbcore Path-strip-level: 1 Patch-file: kdb-v2.1-2.4.17-common-1 Architecture: all Kernel-version: 2.4.17 dh-kpatches-0.99.36+nmu1/noweb.css0000644000000000000000000000233007765436357013507 0ustar # Stylesheet for noweb-generated HTML. # Disclaimers: # - I'm not a CSS expert, any visual improvements are welcome # - This stylesheet was only tested on galeon 1.2.5 and mozilla-firebird 0.7 # - The generated contents (*:before) is completely untested, ignored # by all tested browsers body { background-color: white; color: black } div.title { text-align: center; font-weight: bold; font-size: xx-large; text-decoration: underline } pre { background-color: lightgray; border-style: groove; font-size: larger; margin-left: 2ex; margin-top: 1ex } dfn { font-weight: bolder; background-color: lightyellow; font-size: larger; border-style: ridge; border-style: ridge; border-color: lightyellow; margin-left: -2ex; margin-top: -1ex; text-decoration: none } h2:before { content: counter(h2) ". "; counter-increment: h2; counter-reset: h3; } h3:before { content: counter(h2) "." counter(h3) ". "; counter-increment: h3; counter-reset: h4; } h4:before { content: counter(h2) "." counter(h3) "." counter(h4) ". "; counter-increment: h4; counter-reset: h5; } dh-kpatches-0.99.36+nmu1/lskpatches0000755000000000000000000000333307627000125013727 0ustar #! /bin/bash set -e KPATCHDIR=/usr/src/kernel-patches FORMAT='%-20s%-10s%-10s%-12s%s\n' ARCH=$(dpkg-architecture -qDEB_HOST_ARCH) DIRS_ALL_ALL=$(ls -d ${KPATCHDIR}/all/apply 2>/dev/null || true) DIRS_ARCH_ALL=$(ls -d ${KPATCHDIR}/*/apply 2>/dev/null | grep -v "^${KPATCHDIR}/all/" || true) DIRS_ALL_VERS=$(ls -d ${KPATCHDIR}/all/*/apply 2>/dev/null || true) DIRS_ARCH_VERS=$(ls -d ${KPATCHDIR}/*/*/apply 2>/dev/null | grep -v "^${KPATCHDIR}/all/" || true) # Note: additional "echo $()" calls used to strip spurious spaces dhkp_kversions() { echo $(grep ^KVERSIONS $1 | sed 's/^.*(\(.*\))$/\1/') } dhkp_version() { local rcs=$(echo $(grep -F 'apply.tmpl $''Revision:' $1 | cut -d'$' -f2 | cut -d: -f2)) local dhkp=$(grep ^DHPKPATCHES_VERSION= $1 | cut -d= -f2) if [ -n "${dhkp}" ] then # post-woody echo ${dhkp} elif [ -n "${rcs}" ] then # woody era echo "RCS ${rcs}" else echo '' fi } format() { printf ${FORMAT} "$1" "$2" "$3" "$(dhkp_version $1)" "$(dhkp_kversions $1)" } # Header printf ${FORMAT} PatchID Arch KVers dhkpVers dhkp-KVers for dir in ${DIRS_ALL_ALL} do ( cd ${dir} for kp in $(ls) do format ${kp} 'all' 'all' done ) done for dir in ${DIRS_ARCH_ALL} do ( arch=$(basename $(dirname ${dir})) cd ${dir} for kp in $(ls) do format ${kp} ${arch} 'all' done ) done for dir in ${DIRS_ALL_VERS} do ( vers=$(basename $(dirname ${dir})) cd ${dir} for kp in $(ls) do format ${kp} 'all' ${vers} done ) done for dir in ${DIRS_ARCH_VERS} do ( vers=$(basename $(dirname ${dir})) arch=$(basename $(dirname $(dirname ${dir}))) cd ${dir} for kp in $(ls) do format ${kp} ${arch} ${vers} done ) done dh-kpatches-0.99.36+nmu1/register-patch0000644000000000000000000000047107623557731014524 0ustar #!/bin/sh # This scripts documents the @PATCHNAME@ kernel patch into the # kernel-image package, as being applied to the kernel. docdir=${IMAGE_TOP}/usr/share/doc/kernel-image-${version} mkdir -p ${docdir} echo @PATCHNAME@ '(@PATCHID@), from package @PKGNAME@, version @PKGVERS@' >> ${docdir}/applied-patches dh-kpatches-0.99.36+nmu1/doc/0000755000000000000000000000000011623732653012414 5ustar dh-kpatches-0.99.36+nmu1/doc/Makefile0000644000000000000000000000247411623732653014063 0ustar DESTDIR = prefix = /usr docdir = ${prefix}/share/doc/dh-kpatches mandir = ${prefix}/share/man man1dir = ${mandir}/man1 MANPAGES = dh_installkpatches.1 lskpatches.1 POLICY = kpatch-policy.sgml PROCESSEDPOLICIES = ${POLICY:.sgml=.txt} ${POLICY:.sgml=.html} # debiandoc2* attempts to do something nasty with locale set export LC_ALL=C all: ${MANPAGES} dh-kpatches policy: ${PROCESSEDPOLICIES} dh-kpatches: dh-kpatches.pdf dh-kpatches.html dh-kpatches.pdf dh-kpatches.html: dh_installkpatches.refentry-contents.sgml clean: rm -f ${MANPAGES} ${POLICY:.sgml=.txt} \ manpage.refs manpage.links \ *.jtex *.fot *.aux *.log *.out *.ps *.pdf rm -rf *.html install: all install -m755 -d ${DESTDIR}${man1dir} install -m644 ${MANPAGES} ${DESTDIR}${man1dir} install -m755 -d ${DESTDIR}${docdir} install -m644 dh-kpatches.pdf dh-kpatches.html ${DESTDIR}${docdir} uninstall: rm -rf ${DESTDIR}${docdir} cd ${DESTDIR}${man1dir} && rm -f ${MANPAGES} %.txt: %.debiandoc.sgml debiandoc2text $< mv ${<:.sgml=.txt} $@ %.html: %.debiandoc.sgml debiandoc2html $< mv ${<:.sgml=.html} $@ %.1: %.refentry.sgml docbook2man $< %.html: %.docbook.sgml docbook-2-html --dssslproc openjade1.3 -s gtk -O -Vnochunks -O -Vonechunk $< >$@ rmdir -p $*-html %.pdf: %.docbook.sgml docbook-2-pdf --dssslproc openjade1.3 $< .DELETE_ON_ERROR: dh-kpatches-0.99.36+nmu1/doc/dh_installkpatches.refentry.sgml0000644000000000000000000000042307623542725021004 0ustar ]> &contents; dh-kpatches-0.99.36+nmu1/doc/lskpatches.refentry.sgml0000644000000000000000000000402707623543375017307 0ustar lskpatches 1 lskpatches list installed kernel patches lskpatches Description Prints on standard output a list of kernel patches installed for kernel-package. These patches are eligible for the Along with the IDs for those patches, it lists various information, such as the architecture and kernel version on which make-kpkg will attempt to apply them, and, for patches packaged using dh-kpatches, it lists the version of dh-kpatches used to build the package, and the kernel versions for which the package declares to provide a patch. See also make-kpkg1, dh_installkpatches1. Author This tool and manual page were written by Yann Dirson dirson@debian.org. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license can be found under /usr/share/common-licenses/FDL. dh-kpatches-0.99.36+nmu1/doc/jadetex.cfg0000644000000000000000000000012107623543375014521 0ustar \hypersetup{ bookmarks=true, pdfstartview=FitH, pdfproducer=sgml2x converter} dh-kpatches-0.99.36+nmu1/doc/dh-kpatches.docbook.sgml0000644000000000000000000005765007643377654017144 0ustar ]>
Packaging Linux kernel patches for Debian Yann Dirson Debian
dirson@debian.org
$Revision: 1.14 $ This document describes a debhelper add-on mechanism that allows consistent packaging of various kinds of Linux kernel patches. 1.1 2000-06-10 Initial plain-text revision 1.4 2001-05-14 New "Depends" field 1.8 2002-02-08 New syntax "Kernel-version: all" 2002-02-10 Moved to DocBook, made it more of a real manual 1.9 2002-02-14 Kernel-version ranges 1.10 2002-02-18 First description of "revision 1" format 1.12 2002-07-16 Integrated feedback from maintainers of kpatch-packages. Default fields. Renamed operations. Miscellaneous updates and additions. 1.13 2003-04-04 New field "Debian-patch-file"
Features Current features robustness of patch application support for variable parameters on patch1 command line (eg. allows to apply a version of a patch that was originally targetted at another version handles (un-)application of patch dependencies records in kernel packages build with this patch applied the name and version of the package which shipped the patch. Features to come with version 1.0 application of multi-part patches support for file copying and archive unpacking as patch operation, in addition to diff application support for patch variants for different flavours of a kernel, both to support heavy patches, and to help dealing with otherwise overlaping patches
The <command>dh_installkpatches</> debhelper add-on &DhtoolRefentry;
Description of the <filename>kpatches</> file format The syntax of kpatches files is inspired by the syntax of Debian control-files. A kpatches file contains sections, which are separated by one or more empty lines. Each section is made of Key: value lines.
Revision 0 kpatches files This is the currently supported format for kpatches files. It is to be superceded shortly with a new revision, more general, described later in this document. The file starts with a section for generic patch information, and then has one for each patchfile, allowing versions of the patch for many kernel versions to be specified in one file.
The generic part
Mandatory fields Patch-name a short descriptive name for the patch Patch-name's cannot contain "pipe" (|) and "double quote" (") characters, for purely implementation reasons. Patch-name's that contain "slash" (/) characters would not be allowed before dh-kpatches 0.99.3. Examples Patch-name: Kernel debugger Patch-name: Tracing toolkit Patch-name: Kernel crash dump Patch-id a short identifier for the patch Examples Patch-id: kdb Patch-id: ltt Patch-id: lkcd
Optional fields Path-strip-level default value for the per-patchfile field of the same name (see below). Architecture default value for the per-patchfile field of the same name (see below). Depends default value for the per-patchfile field of the same name (see below).
The patchfile-specific parts
Mandatory fields Patch-file The name of the patch file. It may optionally be compressed with gzip. This should be the first field of each patchfile-specific section. Kernel-version The version (or range of versions) of the kernel this patch is designed for. Other optional fields may be introduced in the future to document other versions which are known to work, and versions known not to work. Version ranges are specified as ver1 - ver2, where both versions must belong to the same "kernel branch" (eg. 2.2, or 2.4), and must be mentionned in increasing order. Kernel versions used in ranges should show an empty EXTRAVERSION field. This is because no special comparision scheme has been implemented to handle the special meaning associated with EXTRAVERSION values like pre2 or test5. As a special case, the value "all" is allowed, for patches that don't depend on a specific version (eg. if they just add a set of files).
Optional fields The optional fields, when not provided, all take hopefully reasonable default values Architecture a comma-separated list of the debian identifiers for archs supported by this patch. Default is "all". Path-strip-level the value to pass as argument to the patch1 Default is 1. Depends a comma-separated list of Patch-Id's of patches this one depends on. Default is no dependency. Debian-patch-file A special version of Patch-file, specifying that a version of the patch file that only applies to a Debian-patched kernel from a kernel-source-version package, in case the vanilla patch does not fit.
Examples of revision 0 <filename>kpatches</> files
kdb These are the 2 kpatches files for the kernel-debugger patch. This patch was monolithic for 2.2 kernels, and has been split for recent 2.4 kernels into an architecture-independant part and one architecture-dependant part per supported architecture. The architecture-independant kdb patch The architecture-dependant kdb patches
Revision 1 kpatches files This will be the next supported format for kpatches files. It has not been implemented yet. It is described here for public review. There are 3 levels of information in this file. A kernel-patch (1st level) is a set of patch alternatives (2nd level), each of which is made of a sequence of patch operations (3rd level). The file starts with a section for generic patch information, and then, for each alternative, has an alternative-specific section followed by one section for each patch operation. An alternative section is syntactically distinguished from an operation section by their mandatory constituent fields.
The generic part
Mandatory fields. Kpatch-format-version the version of the kpatches spec this files complies with. For this version, it should be 1. Patch-name a short descriptive name for the patch Patch-name's cannot contain "pipe" (|) and "double quote" (") characters, for purely implementation reasons. Patch-name's that contain "slash" (/) characters would not be allowed before dh-kpatches 0.99.3. Examples Patch-name: Kernel debugger Patch-name: Tracing toolkit Patch-name: Kernel crash dump OS-kernel The identifier of the kernel the patch is meant for. Current possible values include linux, hurd, netbsd, and there is a default value of linux. Patch-id a short identifier for the patch Examples Patch-id: kdb Patch-id: ltt Patch-id: lkcd
Optional fields For various fields in the alternative-specific and operation-specific parts it can be useful to provide default values. These are defined using fields named by prepending Default- to those fields names. Examples include Default-Path-strip-level and Default-Architecture.
The alternative-specific parts A number of alternative-specific fields are used as conditions for this alternative to be considered. This allows not only to specify in the same file versions of the patch for many kernel versions, but also to specify versions of the patch for different kernel flavours. For example, the LTT patch comes for 2 kernel flavours: plain kernel, and RTAI-patched kernel. The order of alternative sections is significant: the 1st alternative for which all conditions are fullfilled is selected, and all further alternatives are ignored.
Mandatory fields Kernel-version This field is a condition. The version (or range of versions) of the kernel this patch is designed for. Other optional fields may be introduced in the future to document other versions which are known to work, and versions known not to work. Version ranges are specified as ver1 - ver2, where both versions must belong to the same "kernel branch" (eg. 2.2, or 2.4), and must be mentionned in increasing order. As a special case, the value "all" is allowed, for patches that don't depend on a specific version (eg. if they just add a set of files).
Optional fields The optional fields, when not provided, all take hopefully reasonable default values Kernel-flavour This field is a condition for this alternative to be considered - a test to check whether a patch is applied. It is not to be confused with Depends, which will pull others patches first if they are not applied yet. a comma-separated list of Patch-Id's of patches that need to be applied for this one to be considered for application. It may be necessary to add support for flavour versionning (if a patch is disruptive enough to warrant being qualified as a flavour, it is likely that some of its evolution will be disruptive as well). It may be useful to add flavour negations, this has to be investigated at some point. Default is "" (plain/vanilla kernel). Architecture This field is a condition. a comma-separated list of the debian identifiers for archs supported by this patch. Default is "all". Depends This field is NOT a condition. a comma-separated list of Patch-Id's of patches this one depends on. Patches in this list, as opposed to those in the Kernel-flavour list, are such that this patch cannot be applied without them. Default is "" (no dependency).
The operation-specific parts
Mandatory fields I have not firmly decided yet how to formalise these parts, and I'm looking for opinions here. I had originally elected to put the emphasis on operations; this is fine with "copy" and "unpack", but "diff" usually refer to the inverse operation (building the data), and "patch", despite being used for this purpose for quite some time now, is already being used here with a broader meaning. Another problem with "unpack" is that it is broad enough so that the data (ie. archive) may potentially be provided in several formats (eg. tar.gz, tar.bz2, zip, etc.) - that will require some (unnecessary) intelligence within the tool, and will impair modularity (ie. adding support for more archive formats using plugin modules). Another alternative would be to put the emphasis on the data. That would mean replacing Operation fields with something like Format fields, which would have values like "tree", "file", "diff", "tar.gz", "tar", etc. A careful object-oriented implementation would take care of the similarities between those. Another one was suggested by Baruch Even - see below for an example and some discussion. Operation The identifier for a type of patch operation. Valid operations may include "diff", "copy", "unpack", possibly depending on installed plugins. Other fields in the section will depend on the value of this field.
Types of operation diff The application of a diff file (aka. patch file) to the kernel tree. copy The copy of a file, or of a directory tree into the kernel tree. unpack The unpacking of a tarball (or other archive ?) into the kernel tree.
Per-operation-type fields
Fields for the <emphasis>diff</> operation
Mandatory fields File The name of the diff file.
Optional fields Path-strip-level the value to pass as argument to the patch1 Default is 1.
Fields for the <emphasis>unpack</> operation
Mandatory fields File The name of the archive file.
Optional fields Path-strip-level Similar to the option of the same name for the diff operation: strips the N first path components of each member the archive. Default is 0. For tarballs, this option will probably require pax 1 to be applicable.
Fields for the <emphasis>copy</> operation
Mandatory fields From The path of the file or directory to copy. To The directory in which to copy it.
Examples of revision 1 <filename>kpatches</> files
ltt The Linux trace toolkit provides kernel patches both for vanilla kernels and for RTAI kernels. Although there's not yet a packaged version of the RTAI patch, here is what it would look like. The LTT patch
lkcd The kernel crash dump patch requires that a script be copied into the debian part of the kernel tree. Currently this is done by a creating a new patch (named kerntypes) with hand-written apply script, not taking advantage of the dh-kpatches mechanism. Here is how it would look like in revision 1: The LKCD patch Baruch Even baruch@debian.org suggested a syntax that may be simpler. Here is the same example rewritten to use such a syntax, with some interpolations from myself. The LKCD patch (alternate version) The description is more concise, but I fear it would be too losely structured (much more of the information gets stored in left-hand parts of statement), possibly leading to strange-looking stanzas, and possibly impairing extensibility. Here is what the expanded version of the last sample (without default fields) would look like: The LKCD patch (second alternate version) In the same spirit, but datatype-driven instead of operation-driven. This one lies somewhere in between Baruch's proposal and my original one. The LKCD patch (third alternate version)
dh-kpatches-0.99.36+nmu1/doc/dh_installkpatches.refentry-contents.sgml0000644000000000000000000000630007623544255022637 0ustar dh_installkpatches 1 dh_installkpatches install kernel patch into package build directories dh_installkpatches Description dh_installkpatches is a debhelper script that reads debian/package.kpatches or debian/package.kpatches.something files describing one or several revisions of a single kernel patch, and installs them into the package build directory with customized apply and unpatch scripts. It also sets the kpatch:Depends substitution variable, that you should use in your control file to ensure that generated material in your package get all their dependencies. The use of kpatch:Depends requires a build-dependency on version 0.99.3 or later of the dh-kpatches package. Using this variable is now required, since 0.99.16 (mostly because too many people forgot to set it). Options This program does not take any particular option in addition to the standard debhelper1 ones. See also debhelper1, make-kpkg1. /usr/share/doc/dh-kpatches/dh-kpatches.html or /usr/share/doc/dh-kpatches/dh-kpatches.pdf.gz. Author This tool and manual page were written by Yann Dirson dirson@debian.org. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license can be found under /usr/share/common-licenses/FDL. dh-kpatches-0.99.36+nmu1/doc/kpatch-policy.debiandoc.sgml0000644000000000000000000002422207623541520017754 0ustar Kernel-patch sub-policy draft document Yann Dirson dirson@debian.org $Revision: 1.2 $ This document is an attempt to gather current Best Practice(tm) in providing kernel-patches for easy use with kernel-package (see ). It comes from the various issues that stopped me while I started to package kernel patches, and is targetted at maintainers of kernel-patch packages, to gain in consistency, functionality, and smooth system integration. The intention is that at least part of it gets some day blessed into Policy, and most of the remaining into Packaging Manual. This document is covered by the GNU GPL. Big picture summary

This section is meant to give a brief overview of how make-kpkg works with respect to patch handling. For more details please refer to the manpage. Using make-kpkg to build patched kernels

The default configuration of make-kpkg is to ignore any available patches and build a package with whatever kernel source is in the current directory. You can tell it to use patches from under /usr/src/kernel-patches/, either by setting the PATCH_THE_KERNEL environment variable to YES You may also set the patch_the_kernel variable in /etc/kernel-pkg.conf, but I discourage this, you may well forget you have this set one day..

When asked to apply patches, make-kpkg will apply all patches it finds for the current architecture and version for the kernel being built. You may want to only select some of them using the --added_patches option. How make-kpkg applies patches

It looks for apply scripts in the following subdirectories of /usr/src/kernel-patches/:

$ARCH/$VERSION/apply/

$ARCH/apply/

all/$VERSION/apply/

all/apply/

At the time it will want to remove those patches, it will then look into similar directories with name unpatch.

Typically the main job of these scripts is to apply a diff, but well, they are scripts after all, and more complex tasks in need of something more smart than patch may make use of this power. Patch scope

This section should describe possible scopes for a patch in terms of kernel architecture and versions, and what actions to take depending on effective scope.

As you may infer from the previous chapter, some patches are fully generic, whereas others only apply to specific kernel versions and/or specific architectures. Architecture

Some patches do not include support for some achitectures, in which case all they can bring to other architectures is to break them in one way or another. Then they need to be restricted into architecture-dependant directories. In the case where a patch applies to several architectures, shared files should be hard-linked to avoid wasting disk space.

Only patches with (at least theoretical) support for all architectures, and non-architecture-dependant patches, belong to the all category. Version

Usually patches are made of a diff file. These diff files are usually built by comparing a specific kernel-source tree and a modified tree. Although those diffs are guaranted to apply on a tree identical to the one which served as reference when the diff was built, they may also apply (in the mechanical meaning defined by patch returning success) to a number of kernel revisions (or kernels with other patches already applied), if the areas touched by the patch are similar enough to those in the reference tree. This means that a patch against revision x.y.z may also apply to x.y.(z-2) or x.y.(z+5) without patch complaining.

However, this mechanical meaning of a patch applying is not enough in some cases, where changes in one area may interfere with changes in another. Such interferences will range from kernel not being able to compile (eg. because of struct members renamed or previously exported functions marked static) to kernels behaving in really strange unforeseen ways, possibly causing data corruption or all other types of behaviour you usually want to run away from.

For these reasons, depending on how tricky a patch is, one may want to limit the range of kernel versions on which it is to be applied. For this the version-specific subdirectories of /usr/src/kernel-patches/ have been created. But beware not to be too limitative, a patch against the latest stable kernel may well be useful with the next yet-unreleased one, and you may not want to be totalitarian with your package's users. Up to you to make a "good choice", whatever that means. Scripts naming and behaviour

This section is meant to give guidelines for writing the apply and unpatch in a way that will work securely (ie. doesn't break the current kernel-source tree), and will integrate smoothly with the remaining of the system.

This is where currently packaged patches tend to behave in unwanted ways. Naming

Unless specific patches are requested, scripts in the apply and unpatch dirs are executed via run-parts, which runs them in lexical sort order.

It may be nice at some time to allow the names of applied patches to make their way to the EXTRAVERSION field in the kernel revision, so that we get kernel versions like "2.2.17+ide+ltt+int", that would automagically provide at the same time instant information for what patches were applied, and the ability of also installing at the same time plain "2.2.17" as well as "2.2.17+kdb+reiserfs" (no offense to reiserfs meant ;). It may be nice at this time to have patches provide such a short name to make-kpkg. Behaviour

Most of the scripts share a number of behaviours that help them to acomplish the task that justifies their existence. However, probably for lack of such a document, they are currently built on an ad-hoc basis, starting with a copy of existing scripts. I'll try here to list those behaviours and give guidelines so that they indeed do not interfere with each other.

As of now, I don't think a single patch package (including mines) behaves correctly in all these areas. I have started a debhelper-like script to help in this area and to provide a couple additional functionalities. Those interested will find it at apply telling unpatch the patch was applied

This is usually done by creating a file named debian-patches/APPLIED_patchname, which unpatch checks to know whether it has something to do, and which apply also checks to not try to re-apply itself.

Some patches create this file in the debian/ subdirectory, and some other patches create it at the top-level of the kernel sources. The former causes interferences between make-kpkg clean operation and patches applied by running apply scripts by hand; the latter causes problems because some apply scripts remove empty files after patching. Further more, these files are debian-specific, so they may be better in debian-specific subdir anyway. Removing empty files after patching

This is mostly done to cleanup the source tree in cases where files were suppressed or moved. Most package just run find on the whole source tree to find them, then remove them, and create an empty APPLIED_whatever as described above... which gets happily removed by the next apply script that gets run.

For good interaction between those 2 behaviours, no empty files should be removed from the debian/ subdirectory - anyway no file there should be removed by any patch I can think of, as this dir is not part of an official kernel tree. This will allow APPLIED_whatever scripts conforming to the previous point to survive to play their role in the whole picture. Checking whether to apply the patch

apply scripts, when they determine with whatever means that they should not attempt to apply, should not return an error code. This allows unversionned patches to be applied as long as patch can do the job, without preventing other patches to apply on versions of the kernel on which they don't themselves apply. Not breaking the source tree

The scripts should make sure they won't break the user's tree, by using patch --dry-run before they really apply the patch. Not only does this allow unversionned patches to exist at all without enforcing version tests in the scripts, but it also allows the user to experiment with stacking patches without having to restart from unpacking the source at each failure. Packaging issues whether to include several patches per package how to name patch packages dh-kpatches-0.99.36+nmu1/noweb0000777000000000000000000000000007756241224017534 2../../litprog/noweb/ydirsonustar dh-kpatches-0.99.36+nmu1/dh-kpatches.html0000644000000000000000000022640610251655232014733 0ustar dh-kpatches implementation

dh-kpatches implementation

The two Parts

The dh-kpatches system is made of two parts. The first one takes patch descriptions, and produces kernel-patch packages; the second one is (currently) contained in those patch packages, and handles application of the patches to a kernel source tree, as well as their removal.

The application/removal scripts are (currently) generated from templates by the dh_installkpatches script for each kernel-patch package.

Currently, the patch descriptions are completely parsed by dh_installkpatches, and the apply/unpatch scripts are specific to each package, and can only act on the patches dh_installkpatches taught them about.

Packaging-time work

The dh_installkpatches helper

This is the debhelper-based script that will cause our packages to install patches in the One True Way. Its base structure is that of a standard debhelper script.

<dh_installkpatches.in>=
#!/usr/bin/perl -w
#
# dh_installkpatches $Revision: 1.17.1.4.1.24.1.5 $
#
# Reads debian/$package.kpatches[.foo], installs all files necessary
# to have make-kpkg use the kernel patches described in there.
#
# (c) 2000-2003 Yann Dirson <dirson@debian.org>
# Some parts based on code from Adam Di Carlo and Joey Hess

use strict;
use Debian::Debhelper::Dh_Lib;
init();

<definitions for the core kpatch system>

PACKAGE: foreach my $package (@{$dh{DOPACKAGES}}) {
  my $tmp = tmpdir($package);
  my $ext = pkgext($package);

  # There are two filename formats, the usual
  # plus an extended format (debian/package.*).

  opendir(DEB,"debian/") || error("can't read debian directory: $!");
  # If this is the main package, we need to handle unprefixed filenames.
  # For all packages, we must support both the usual filename format plus
  # that format with a period an something appended.
  my $regexp="\Q$package\E\.";
  if ($package eq $dh{MAINPACKAGE}) {
    $regexp="(|$regexp)";
  }
  my @files = grep { /^${regexp}kpatches(\..*)?$/ } readdir(DEB);
  closedir(DEB);

  # next package if there are no patches in there
  next PACKAGE if $#files < 0;

  <process binary package $package>
}

Patch processing

For each binary package, all kpatches files are processed to generate one apply script with a single diff operation (and its corresponding unpatch script).

<process binary package $package>= (<-U)
<assert kpatch:depends is referenced in control file>

foreach my $file (@files) {
  my %patchinfo = read_control_file ("debian/$file");

  #   use Data::Dumper;
  #   print Dumper (%patchinfo);

  my $patchid = $patchinfo{general}->{'patch-id'};

  # transformation of the ID to be acceptable as part of an envvar's name
  $patchinfo{general}->{'clean-patch-id'} = $patchinfo{general}->{'patch-id'};
  $patchinfo{general}->{'clean-patch-id'} =~ s/-/_/g;

  # protect pipes and dquotes for sed command-line
  $patchinfo{general}->{'patch-name'} =~ s,([|\"]),\\$1,g;

  <generate apply/unpatch scripts for given $package and kpatches $file>
}

<set kpatch:Depends substvar>

kpatch:depends substvar

A number of packages are needed by kernel-patch packages:

bash 2.x or better
because apply scripts use arrays
patch
because we (currently) only apply patches made of diff files
grep-dctrl
is used to register the version of the kernel-patch package into the kernel-image package
<definitions for the core kpatch system>= (<-U) [D->]
my $pkgdeps = "bash (>= 2.0), patch, grep-dctrl";

The substvar code was derived from similar functionnality in dh_perl v3.4.1. For idempotency, we first remove anything this program might have previously added to the substvars file.

<set kpatch:Depends substvar>= (<-U)
if (-e "debian/${ext}substvars") {
  complex_doit("grep -v ^kpatch:Depends= debian/${ext}substvars > debian/${ext}substvars.new || true");
  doit("mv", "debian/${ext}substvars.new","debian/${ext}substvars");
}

complex_doit("echo 'kpatch:Depends=$pkgdeps' >> debian/${ext}substvars");

We also make sure the package uses our substvar, and abort if not.

<assert kpatch:depends is referenced in control file>= (<-U)
die 'debian/control must make package ' . $package . ' depend on ${kpatch:Depends}'
  if system ("dpkg-gencontrol -p$package -Pdebian -O -T/dev/null -Vkpatch:Depends=KPATCHISUSED |"
           . "grep -q '^Depends: .*KPATCHISUSED'") != 0;

Kernel-build-time work

For each v0 kpatches file, we produce an apply and an unpatch script, necessary to work properly with make-kpkg. Those are currently produced from templates.

Apply script

<apply.tmpl>=
#! /bin/bash
set -e

<Assert this is a kernel tree>
<Apply.tmpl constants>

DEPENDS=(#DEPENDS#)

KVERSIONS=(#KVERSIONS#)
PATCHFILES=(#PATCHFILES#)
DEBPATCHFILES=(#DEBPATCHFILES#)
STRIPLEVELS=(#STRIPLEVELS#)

<Make apply idempotent>
<Get current kernel version>
<Select alternative to apply, as $IDX>

echo >&2 "START applying #PATCHID# patch (#PATCHNAME#)"

<Handle dependencies>

<Assert patch applies, using dry-run>
<Apply the patch>

<Store necessary info for unpatching>
<Create script to have this patch registered in doc-dir>

echo >&2 "END applying #PATCHID# patch"
<Get current kernel version>= (<-U)
VERSION=$(grep ^VERSION Makefile 2>/dev/null | \
        sed -e 's/[^0-9]*\([0-9]*\)/\1/')
PATCHLEVEL=$( grep ^PATCHLEVEL Makefile 2>/dev/null | \
        sed -e 's/[^0-9]*\([0-9]*\)/\1/')
SUBLEVEL=$(grep ^SUBLEVEL Makefile 2>/dev/null | \
        sed -e 's/[^0-9]*\([0-9]*\)/\1/')
EXTRAVERSION=$(grep ^EXTRAVERSION Makefile | head -1 2>/dev/null | \
        sed -e 's/EXTRAVERSION =[       ]*\([^  ]*\)$/\1/')
KERNELBRANCHLET=${VERSION}.${PATCHLEVEL}.${SUBLEVEL}
KERNELRELEASE=${KERNELBRANCHLET}${EXTRAVERSION}

The candidates patch version for application to our kernel (eg. 2.6.11.11) is the first of:

  1. the version passed through the KPATCH_* mechanism
  2. the version exactly matching the kernel (eg. 2.6.11.11)
  3. the version of the "branchlet" used for short stable branches in the 2.6 branch (eg. 2.6.11)
  4. the all version
<Select alternative to apply, as $IDX>= (<-U)
IDX=

declare -i i=${#PATCHFILES[*]}-1
while [ $i -ge 0 ]
do
    v=${KVERSIONS[$i]}
    if [ -n "$KPATCH_#CLEANPATCHID#" -a "$v" = "$KPATCH_#CLEANPATCHID#" \
         -o "$v" = "$KERNELRELEASE"
         -o "$v" = "$KERNELBRANCHLET"
         -o "$v" = all ]
    then
        IDX=$i
    fi
    i=i-1
done

<Assert we have an alternative to apply>
<Record parameters for applying alternative $IDX>

If the KPATCH_* mechanism was used, we have a special error message listing the requested version.

<Assert we have an alternative to apply>= (<-U)
if [ -n "$KPATCH_#CLEANPATCHID#" -a ${KVERSIONS[$IDX]} != "$KPATCH_#CLEANPATCHID#" ]
then
    echo >&2 "Requested kernel version \`$KPATCH_#CLEANPATCHID#' not found for patch #PATCHID#"
    exit 1
elif [ -z "$IDX" ]
then
    echo >&2 "No \"#PATCHNAME#\" patch found for kernel version $KERNELRELEASE"
    exit 1
fi

Of special notice is the "debian" pseudo-flavour. Before the kernel-patch-debian era, we had to check for README.Debian. Now we must check for version.Debian.

<Record parameters for applying alternative $IDX>= (<-U)
KVERSION=${KVERSIONS[$IDX]}
STRIPLEVEL=${STRIPLEVELS[$IDX]}

if [ "${DEBPATCHFILES[$IDX]}" != '' -a \
    \( -r version.Debian -o -r README.Debian \) ]
then
    PATCHFILE=${DEBPATCHFILES[$IDX]}
else
    PATCHFILE=${PATCHFILES[$IDX]}
fi
<Handle dependencies>= (<-U)
<Check for dependencies>
<Apply dependencies>
<Check for dependencies>= (<-U)
NEEDED_DEPS=
for dep in ${DEPENDS[$IDX]}
do
    if [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/${KERNELBRANCHLET}/apply/$dep ]
    then
        NEEDED_DEPS="${ARCHITECTURE}/${KERNELBRANCHLET}/apply/$dep $NEEDED_DEPS"
    elif [ -x ${TOPPATCHDIR}/all/${KERNELBRANCHLET}/apply/$dep ]
    then
        NEEDED_DEPS="all/${KERNELBRANCHLET}/apply/$dep $NEEDED_DEPS"
    elif [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/apply/$dep ]
    then
        NEEDED_DEPS="${ARCHITECTURE}/apply/$dep $NEEDED_DEPS"
    elif [ -x ${TOPPATCHDIR}/all/apply/$dep ]
    then
        NEEDED_DEPS="all/apply/$dep $NEEDED_DEPS"
    else
        echo >&2 "ERROR: Patch dependency \`$dep' not found - aborting"
        echo >&2 "END applying #PATCHID# patch"
        exit 1
    fi
done
<Apply dependencies>= (<-U)
if [ "$NEEDED_DEPS" ]
then
    echo >&2 "Ensuring the following patches are applied first: $NEEDED_DEPS"
    for apply in ${NEEDED_DEPS}
    do
        dep=$(basename $apply)
        ${TOPPATCHDIR}/$apply

        # check something was applied
        if [ ! -f debian/APPLIED_${ARCHITECTURE}_$dep -a \
             ! -f debian/APPLIED_all_$dep ]
        then
            echo >&2 "ERROR: patch dependency did not left a patch stamp (version mismatch ?) - aborting"
            echo >&2 "END applying #PATCHID# patch"
            exit 1
        fi
    done
    UNPATCHDEPS=$(echo ${NEEDED_DEPS} | sed s,/apply/,/unpatch/,g)
fi
<Assert patch applies, using dry-run>= (<-U)
echo >&2 "Testing whether \"#PATCHNAME#\" patch for $KVERSION applies (dry run):"
if ! [ -r $PATCHFILE ]
then
    echo >&2 "\"#PATCHNAME#\" patch for $KVERSION not found"
    exit 1
elif ! $DECOMPRESSOR $PATCHFILE |
        patch --force --dry-run $PATCH_OPTIONS -p$STRIPLEVEL
then
    echo >&2 "\"#PATCHNAME#\" patch for $KVERSION does not apply cleanly"
    exit 1
fi

We do not use --force on second run, there should be no need for it. If something requires interaction, it is likely there is a bug somewhere, better catch it.

After applying the diff, we remove any empty files, so that files "removed" by the diff are really removed. We make an exception for ./debian/ contents, and for files named APPLIED*, or else some (buggy) stamp files may be caught too.

<Apply the patch>= (<-U)
if ! $DECOMPRESSOR $PATCHFILE |
        patch $PATCH_OPTIONS -p$STRIPLEVEL
then
    # This should never happen, thanks to the dry-run
    echo >&2 "ASSERTION FAILED - \"#PATCHNAME#\" patch for $KVERSION failed"
    echo >&2 "END applying #PATCHID# patch"
    exit 1
fi
echo >&2 "\"#PATCHNAME#\" patch for $KVERSION succeeded"

<Remove empty files>

All information necessary for unpatching is stored in a debian/APPLIED_* file, for use by the unpatch script.

<Store necessary info for unpatching>= (<-U)
mkdir -p debian
cat > 'debian/APPLIED_#PATCHARCH#_#PATCHID#' <<EOF
PATCHFILE='$PATCHFILE'
STRIPLEVEL='$STRIPLEVEL'
DEPENDS='$UNPATCHDEPS'
EOF
<Create script to have this patch registered in doc-dir>= (<-U)
mkdir -p debian/image.d
PKGNAME=`dpkg -S $PATCHFILE | cut -d: -f1`
PKGVERS=`grep-dctrl -n -P $PKGNAME -s Version -X /var/lib/dpkg/status`
cat > 'debian/image.d/register-#PATCHID#' <<EOF
#!/bin/sh

# This scripts documents the "#PATCHNAME#" kernel patch into the
# kernel-image package, as being applied to the kernel.

docdir=\${IMAGE_TOP}/usr/share/doc/kernel-image-\${version}

mkdir -p \${docdir}

(
    printf '#PATCHNAME# (#PATCHID#)${KPATCH_#CLEANPATCHID#:+ for kernel ${KPATCH_#CLEANPATCHID#}},'
    echo ' from package $PKGNAME, version $PKGVERS'
) >> \${docdir}/applied-patches
EOF
chmod +x 'debian/image.d/register-#PATCHID#'

Generated by GNU enscript 1.6.4.
<Apply.tmpl constants>= (<-U)
TOPPATCHDIR=/usr/src/kernel-patches
ARCHITECTURE=`dpkg --print-installation-architecture`
DECOMPRESSOR="zcat -f"
PATCH_OPTIONS="--ignore-whitespace --silent"
# This is informational only, used by lskpatches
DHPKPATCHES_VERSION=#DHKPVERS#

Generated by GNU enscript 1.6.4.

We consider it a success if the patch is already applied.

FIXME: we should make sure that the currently-applied patch is the one that would have been applied.

<Make apply idempotent>= (<-U)
[ -f debian/APPLIED_${ARCHITECTURE}_#PATCHID# -o \
  -f debian/APPLIED_all_#PATCHID# ] && exit 0

Generated by GNU enscript 1.6.4.

Unpatch script

<unpatch.tmpl>=
#! /bin/bash
set -e

# This "unpatch" script was automatically generated by
# dh_installkpatches from unpatch.tmpl $Revision: 1.17.1.4.1.24.1.5 $

<Assert this is a kernel tree>

ARCHITECTURE=`dpkg --print-installation-architecture`
PATCHID=#PATCHID#
PATCHARCH=#PATCHARCH#

TOPPATCHDIR=/usr/src/kernel-patches
DECOMPRESSOR="zcat -f"

STAMP=debian/APPLIED_${PATCHARCH}_$PATCHID

PATCH_OPTIONS="--ignore-whitespace --silent"

[ -f $STAMP ] || exit 0

<Assert stamp file is not empty>
<Read contents from stamp file>
<Assert diff file is still there>
<Do not unpatch if there are still dependants>

<Remove the patch>

<Assert stamp file is not empty>= (<-U)
if [ ! -s $STAMP ]
then
    cat >&2 <<EOF
ERROR: "#PATCHNAME#" patch was applied using old mechanism.
The relevant patch file may even not be on your system any more.
I strongly suggest you remove this kernel tree and unpack a clean one.
EOF
    exit 1
fi

<Read contents from stamp file>= (<-U)
if [ $(echo $(wc -l < $STAMP) ) != 1 ]
then
    . $STAMP
else
    # old format
    APPLY_INFO=$(cat $STAMP)
    PATCHFILE=$(echo ${APPLY_INFO} | cut -d# -f1)
    STRIPLEVEL=$(echo ${APPLY_INFO} | cut -d# -f2)
fi

<Assert diff file is still there>= (<-U)
if [ ! -r $PATCHFILE ]
then
    cat >&2 <<EOF
ERROR: applied "#PATCHNAME#" patch file could not be found.
Presumably the package containing it was removed or upgraded.
I strongly suggest you remove this kernel tree and unpack a clean one.
EOF
    exit 1
fi

<Remove those patches we depended on>= (U->)
if [ -n "$DEPENDS" ]
then
    echo >&2 "Also un-applying the following patches: $DEPENDS"
    for dep in $DEPENDS
    do
        if [ -x ${TOPPATCHDIR}/$dep ]
        then
            ${TOPPATCHDIR}/$dep
        else
            echo >&2 "Could not unpatch dependency: $dep - stopping here."
            echo >&2 "END unpatching #PATCHID# patch"
            exit 1
        fi
    done
fi

<Do not unpatch if there are still dependants>= (<-U)
if grep -l "^DEPENDS=.*[' ]#PATCHARCH#/unpatch/#PATCHID#[' ]" debian/APPLIED_* >/dev/null 2>/dev/null
then
    # There are patches depending on this one, to be removed before.
    # the dep will be removed by the last of those other patches.
    echo >&2 "NOT unpatching \"#PATCHNAME#\" since other patches still rely on it"
    exit 0
fi

<Remove the patch>= (<-U)
echo >&2 "START unpatching #PATCHID# patch (#PATCHNAME#)"

$DECOMPRESSOR $PATCHFILE | patch -R -p$STRIPLEVEL $PATCH_OPTIONS
rm -f debian/APPLIED_${PATCHARCH}_$PATCHID debian/image.d/register-#PATCHID#

<Remove those patches we depended on>
<Remove empty files>
rmdir -p debian/image.d || true

echo >&2 "END unpatching #PATCHID# patch"

Common stuff

<Assert this is a kernel tree>= (<-U <-U)
if ! [ -d kernel -a -d Documentation ]
then
    echo >&2 "Not in kernel top level directory. Exiting"
    exit 1
fi
<Remove empty files>= (<-U <-U)
echo >&2 "Removing empty files:"
# make an exception for ./debian, or else the stamp files will go too.
find . -path ./debian -prune -o \
       -type f -size 0 ! -name 'APPLIED*' -exec rm {} \; -print
echo >&2 "Done."

Reading a kpatches control file

When reading a kpatches control file, we store its contents according a data model suitable for the most recent file-format, and will map data extracted from old file-formats into the modern one.

Generic (v1) data structures

The v1 data structures are a hash of general fields taken from the initial stance (eg. PatchName), a hash of default values also taken from the initial stance, and a sequence of alternative versions of the patch, each of which containing a sequence of operations to apply to the kernel tree:

<initialise %patchinfo with skeleton structure>= (U->)
my %patchinfo = ('general' => {},
                 'defaults' => {},
                 'alternatives' => []);

We provide a single entry-point to the controlfile reader, which will act in different ways according to the format-version.

If we have a v0 header, we migrate the relevant contents of the v0 header into the default-values section ot the %patchinfo structure, before going on reading.

<definitions for the core kpatch system>+= (<-U) [<-D->]

# RE pattern matching any kernel version (marks branch as $1 and version as $2)
my $kversion_pattern = qr/^(\d+\.\d+)\.(\d+(?:\.\d+)?)$/;

# Irregular kernel versions by branch, and their predecessor and successors.
# (Key is the predecessor, value is an array ref;
#  contains the irregular version itself and the successor.)
my %irregular_kversions = (
  # "2.6" => {
  #   "8" => [ "8.1", "9" ]
  # }
);

# Gives back an array containing all the kernel versions
# from $branch.".".$start to $branch.".".$end (inclusive).
# Handles some irregular versions correctly, but depends on
# the monotonic numeric relation of successive versions.
sub iterate_over_kversions {
  my ($branch, $start, $end) = @_;
  my @ret;

  my $v = $start;
  while ($v <= $end) {
    push @ret, $branch . "." . $v;
    if (exists $irregular_kversions{$branch}->{$v}) {
      if ($irregular_kversions{$branch}->{$v}[0] <= $end) {
        push @ret, $branch . "." . $irregular_kversions{$branch}->{$v}[0];
        $v = $irregular_kversions{$branch}->{$v}[1];
      } else {
        last;
      }
    } else {
      $v++;
    }
  }

  return @ret;
}
<definitions for the core kpatch system>+= (<-U) [<-D->]
sub read_control_file {
  my ($file) = @_;

  <initialise %patchinfo with skeleton structure>

  open (IN, $file) or die "cannot open $file: $!";

  # read control-file header
  read_control_file_section ($patchinfo{general});

  if ((!defined $patchinfo{general}->{'kpatch-format-version'}) or
      ($patchinfo{general}->{'kpatch-format-version'} == 0)) {
    $patchinfo{defaults} = control_file_v0_header_to_v1_defaults ($patchinfo{general});
    <read v0 file content>

    # } elsif ($patchinfo{general}->{'kpatch-format-version'} == 1) {
    # Revision 1
    # Eh, not yet :)
  } else {
    die "Unsupported Kpatch-format-version: \`" .
      $patchinfo{general}->{'kpatch-format-version'} . "'";
  }

  close IN;

  validate (\%patchinfo);
  return %patchinfo;
}

Once a %patchinfo structure has been filled, we can run some checks on it, to make as sure as possible that it is correct.

FIXME: this should do much more tests !

<definitions for the core kpatch system>+= (<-U) [<-D->]
sub validate {
  my ($patchinfo) = @_;

  die "Patch-Id can only contain alphanumerics, hyphens, and underscores"
    if $patchinfo->{general}->{'patch-id'} =~ /[^\w-]/;

  foreach my $alternative (@{$patchinfo->{alternatives}}) {
    foreach my $operation (@{$alternative->{operations}}) {
      die "Diff file does not exist: " . $operation->{'diff-file'}
        if ($operation->{format} eq 'diff') and ! -r $operation->{'diff-file'};
      die "Diff file changes EXTRAVERSION: " . $operation->{'diff-file'}
        if 0 == system ('grep -q "^-EXTRAVERSION\>" ' . $operation->{'diff-file'});
    }
  }
}

Reading a control-file section is something quite generic. Maybe there is a generic API for doing that now ?

This function slightly adapted from code in install-docs from Adam Di Carlo, and this is the main reason why it is not split into chunks.

<definitions for the core kpatch system>+= (<-U) [<-D->]
sub read_control_file_section {
  my ($pfields) = @_;

  my $alreadyreadsomething = 0;
  my ($key,$value);
  while (<IN>) {
    chomp;

    # empty line?
    if (/^\s*$/o) {
      if ($alreadyreadsomething) {
        last;
      } else {
        next;
      }
    }

    $alreadyreadsomething = 1;

    if (/^(\S+)\s*:\s*(.*)$/) {
      # first line of a new field

      ($key,$value) = (lc $1,$2);
      #print STDERR "$key -> $value\n";
      if (exists $pfields->{$key}) {
        warn "warning: $key: overwriting previous setting of control field";
      }
      $pfields->{$key} = $value;

    } elsif (/^\s+(\S.*)$/) {
      # additional line in a multi-line field
      $value = $1;
      defined($key) or die "syntax error in control file: no field specified";
      #print STDERR "$key -> $value (continued)\n";
      $pfields->{$key} .= "\n$value";

    } else {
      die "syntax error in control file: $_";
    }
  }

  return $alreadyreadsomething;
}

Handling v0 definitions

A v0 kpatches file is just a list of alternatives, each composed of only one diff operation. We have to convert them into proper structures so that the v1-based processing works as expected.

<read v0 file content>= (<-U)
my $cfs = {};
while (read_control_file_section ($cfs)) {
  push (@{$patchinfo{alternatives}},
        control_file_v0_section_to_alternative($cfs));
  $cfs = {};
}

The function that does the conversion simply maps known fields into their final location.

<definitions for the core kpatch system>+= (<-U) [<-D->]
sub control_file_v0_section_to_alternative {
  my ($cfs) = @_;

  # FIXME: should also process general section, and convert default
  # values - probably in a similar function

  return {
          conditions => {
                         'kernel-version' => $cfs->{'kernel-version'},
                         'architecture' => $cfs->{architecture},
                        },
          depends => $cfs->{depends},
          defaults => {},
          operations => [
                         {
                          'format' => 'diff',
                          'diff-file' => $cfs->{'patch-file'},
                          'debian-diff-file' => $cfs->{'debian-patch-file'},
                          'path-strip-level' => $cfs->{'path-strip-level'},
                         }
                        ],
         };
}

The v0 header differs from the v1 header, in that "default" entries are implicit, and for a small well-defined set of fields. When reading a v0 header, we have to explicit them, and strip them from the general fields.

<definitions for the core kpatch system>+= (<-U) [<-D->]
sub control_file_v0_header_to_v1_defaults {
  my ($header) = @_;
  my %defaults;

  foreach my $key (keys %{$header}) {
    if (! grep { $key eq $_ } ('patch-name', 'patch-id')) {
      $defaults{$key} = $header->{$key};
      delete $header->{$key};
    }
  }

  return \%defaults;
}

Fields of kpatch files

There are 2 types of fields, denoted by constants defined the fields library. Some are mandatory, some are optional. The optional ones can all be given a default value, but mandatory ones cannot use this inheritance mechanism -- hence the $FIELD_INHERITS name.

Due to this inheritance mechanism, the final value of a field has to be computed according to given rules for inheritance and defaulting.

From text fields to data structures

Generic alternative fields

We record all archs mentionned in the kpatches file, so that we know for which archs we have to generate the apply/unpatch scripts.

<compute and split 'architecture' field>= (U->)
{
 my @archfield =
 split (/, */, field_value ($patchinfo{general}, $alternative->{conditions},
                            'architecture', $FIELD_INHERITS, 'all',
                            \%patchinfo));
 $alternative->{conditions}->{architecture} = \@archfield;

 foreach my $arch (@archfield) {
   push @archs, $arch unless grep { $_ eq $arch } @archs;
 }
}

The kernel version can be specified either as a single version or as a range.

FIXME: how a is value "all" handled ? It seems filtered out by the test below...

<compute 'kernel-version' value or range>= (U->)
{
  my $kversion = field_value ($patchinfo{general}, $alternative->{conditions},
                              'kernel-version', $FIELD_MANDATORY);
  # parse "2.4.5 - 2.4.7" and "2.5.4 -" syntaxes

  my @kv = split (/\s+/, $kversion);
  if ($#kv > 0) {
    # FIXME: validity check is really too strict, but we need a
    # good kversion comparison algorithm to attempt any better
    # (ie. "-pre" and "-test" at least are special)
    $kv[0] =~ $kversion_pattern or die "Malformed kernel version: `$kv[0]'";

    my ($branch, $first) = ($1, $2);
    die "Malformed kernel-version range \`$kversion'"
      unless ($kv[1] eq '-') && ($#kv <= 2);
    if ($#kv == 1) {
      die "Unbounded ranges not supported yet: \`$kversion'";
      $kversion = [ $branch, $first ];
    } else {
      $kv[2] =~ $kversion_pattern or die "Malformed kernel version: `$kv[2]'";
      die "Cross-branch ranges are not allowed: `$kversion'"
        unless $1 == $branch;
      die "Reverse-ordered range: `$kversion'" if $2 < $first;
      $kversion = [ $branch, $first, $2 ];
    }
  } else {
    $kv[0] =~ $kversion_pattern or die "Malformed kernel version: `$kv[0]'";
  }

  $alternative->{conditions}->{'kernel-version'} = $kversion;
}

Depends is a comma- and space-separated list, and will be used in the bash apply script to initialize an array, so must be made space-separated only.

<compute 'depends' field>= (U->)
$alternative->{depends} = field_value ($patchinfo{general}, $alternative,
                                       'depends', $FIELD_INHERITS, "",
                                       \%patchinfo);
$alternative->{depends} =~ s/, */ /g;

Per-operation fields

This is simplest of all fields, nothing special is done apart from memorizing it.

<compute 'path-strip-level' field for $op>= (U->)
$op->{'path-strip-level'} = field_value ($patchinfo{general}, $op,
                                         'path-strip-level', $FIELD_INHERITS, 1,
                                         $alternative, \%patchinfo);

Since the diff files may be compressed, we are only recording here their location in the source tree, and we are delaying the recording of their final filename until they are installed and maybe compressed. This will be done as we <install the diff files>.

<compute (debian-)diff-file fields for $op>= (U->)
$op->{'diff-file'} = field_value ($patchinfo{general}, $op,
                                  'diff-file', $FIELD_MANDATORY);
$op->{'debian-diff-file'} = field_value ($patchinfo{general}, $op,
                                         'debian-diff-file', $FIELD_INHERITS);

Field-handling library

Field inheritance

<definitions for the core kpatch system>+= (<-U) [<-D->]
my $FIELD_MANDATORY = 0;
my $FIELD_INHERITS = 1;

$inherits should have one of the values defined above. $default can be undef when there is no default value for the field.

<definitions for the core kpatch system>+= (<-U) [<-D->]
sub field_value {
  my ($general, $hash, $name, $inherits, $default, @defaultlists) = @_;

  my $value = $hash->{$name};
  if ($inherits == $FIELD_MANDATORY) {
    die "Patchfile info lacks $name field" unless defined $value;
  }
  # first go through explicit default values
  foreach my $defaultlist (@defaultlists) {
    $value = $defaultlist->{defaults}->{$name} unless defined $value;
  }
  # then use hardcoded default as a fallback
  if (defined $default) {
    $value = $default unless defined $value;
  }

  return $value;
}

Recording a patchfile field for later use

We use hashes to store sequences of values for each arch. These sequences of values will be directly used to produce the apply/unpatch scripts from their templates.

<definitions for the core kpatch system>+= (<-U) [<-D]
# records a field value for a given patchfile on a given arch
sub record_patchfile_field {
  my ($hash, $arch, $value) = @_;

  if (defined $hash->{$arch}) {
    $hash->{$arch} .= " $value";
  } else {
    $hash->{$arch} = "$value";
  }
}

Patch processing

In a single apply script, all alternatives are handled, and the one to use will be determined at runtime.

We currently support only one operation per alternative (v0 format), and a great deal of this restriction lies in this part, so I will not spend to much time structuring this part, until things are properly implemented.

To get proper v1 support we will put everything including kpatches file parsing into a generic apply script, and have patch packages only symlink to this one.

<generate apply/unpatch scripts for given $package and kpatches $file>= (<-U)
my %kversions=();
my %patchfiles=();
my %debpatchfiles=();
my %striplevels=();
my %depends=();
my @archs=();

# put the right files in the right places
foreach my $alternative (@{$patchinfo{alternatives}}) {
  my $op = $alternative->{operations}->[0];
  <compute values for $alternative>
  <install the diff files>
  <record the $alternative and single $op>
}
<output apply/unpatch scripts>

For each alternative, we compute the value to use for each field, possibly using a default value if none was provided, and in some cases splitting into an array. The final value is stored in the place of the original one.

Diff files thus identified are then installed, and entries for the diff files are then recorded for use when generating the apply/unpatch scripts for each of the named architectures.

There is no particular ordering required between the computation of the various fields, but to help moving towards v1 format, we group them by first handling those specific to the alternative itself, and then those specific to the single diff operation in this alternative.

<compute values for $alternative>= (<-U)
<compute 'depends' field>
<compute and split 'architecture' field>
<compute 'kernel-version' value or range>

<compute 'path-strip-level' field for $op>
<compute (debian-)diff-file fields for $op>

All diff files are now located under a single /usr/src/kernel-patches/diffs/ tree.

<install the diff files>= (<-U)
my $srcdir = "/usr/src/kernel-patches/diffs/$patchid";
doit ("mkdir",  "-p", "$tmp$srcdir") unless -d "$tmp$srcdir";

$op->{'installed-diff-file'} = "$srcdir/" . basename($op->{'diff-file'});
doit ("cp", $op->{'diff-file'}, "$tmp$op->{'installed-diff-file'}");
doit ("gzip", "-9fq", "$tmp$op->{'installed-diff-file'}");
$op->{'installed-diff-file'} = "$op->{'installed-diff-file'}.gz"
  if -r "$tmp$op->{'installed-diff-file'}.gz";

if (defined $op->{'debian-diff-file'}) {
  $op->{'installed-debian-diff-file'} = "$srcdir/" . basename($op->{'debian-diff-file'});
  doit ("cp", $op->{'debian-diff-file'}, "$tmp$op->{'installed-debian-diff-file'}");
  doit ("gzip", "-9fq", "$tmp$op->{'installed-debian-diff-file'}");
  $op->{'installed-debian-diff-file'} = "$op->{'installed-debian-diff-file'}.gz"
    if -r "$tmp$op->{'installed-debian-diff-file'}.gz";
} else {
  $op->{'installed-debian-diff-file'} = '';
}

Version ranges are currently emulated, by duplicating the entry for each integer kernel revision in the range.

This is a temporary behaviour, which does not allow pre-release kernel versions to be seen as part of the range. Adequate version-comparison function and data-structures will be used instead, when time permits.

<record the $alternative and single $op>= (<-U)
foreach my $arch (@{$alternative->{conditions}->{architecture}}) {
  if ((ref $alternative->{conditions}->{'kernel-version'}) eq 'ARRAY') {
    my @kernel_version = @{$alternative->{conditions}->{'kernel-version'}};
    foreach my $version (iterate_over_kversions($kernel_version[0], $kernel_version[1], $kernel_version[2])) {
      record_patchfile_field (\%kversions, $arch, $version);
      record_patchfile_field (\%striplevels, $arch, $op->{'path-strip-level'});
      record_patchfile_field (\%depends, $arch, '"' . $alternative->{depends} . '"');
      record_patchfile_field (\%patchfiles, $arch, '"' . $op->{'installed-diff-file'} . '"');
      record_patchfile_field (\%debpatchfiles, $arch, '"' . $op->{'installed-debian-diff-file'} . '"');
    }
  } else {
    record_patchfile_field (\%kversions, $arch, 
                            $alternative->{conditions}->{'kernel-version'});
    record_patchfile_field (\%striplevels, $arch, $op->{'path-strip-level'});
    record_patchfile_field (\%depends, $arch, '"' . $alternative->{depends} . '"');
    record_patchfile_field (\%patchfiles, $arch, '"' . $op->{'installed-diff-file'} . '"');
    record_patchfile_field (\%debpatchfiles, $arch, '"' . $op->{'installed-debian-diff-file'} . '"');
  }
}

apply and unpatch are currently generated from templates, by substituting in there the values computed from the patch definition expressed in the kpatches file.

<output apply/unpatch scripts>= (<-U)
foreach my $arch (@archs) {
  my $pdir = "/usr/src/kernel-patches/$arch";
  foreach my $script ('apply', 'unpatch') {
    doit ("mkdir", "-p", "$tmp$pdir/$script");
    complex_doit ('sed < @TMPLDIR@/' . "$script.tmpl >$tmp$pdir/$script/$patchid" .
                  ' -e \'s/#PATCHID#/' . $patchinfo{general}->{'patch-id'} . '/g\'' .
                  ' -e \'s/#CLEANPATCHID#/' . $patchinfo{general}->{'clean-patch-id'} . '/g\'' .
                  ' -e \'s|#PATCHNAME#|' . $patchinfo{general}->{'patch-name'} . '|g\'' .
                  " -e 's/#DHKPVERS#/@DHKPVERS@/g'" .
                  " -e 's,#TMPLDIR#,@TMPLDIR@,g'" .
                  " -e 's/#DEPENDS#/$depends{$arch}/g'" .
                  " -e 's/#KVERSIONS#/$kversions{$arch}/g'" .
                  " -e 's|#PATCHFILES#|$patchfiles{$arch}|g'" .
                  " -e 's|#DEBPATCHFILES#|$debpatchfiles{$arch}|g'" .
                  " -e 's/#PATCHARCH#/$arch/g'" .
                  " -e 's/#STRIPLEVELS#/$striplevels{$arch}/g'"
                 );
    doit ("chmod", "0755", "$tmp$pdir/$script/$patchid");

    doit ("mkdir", "-p", "$tmp/usr/share/doc/$package");
    doit ('cp',
          '@TMPLDIR@/README-kernelpatch.Debian',
          "$tmp/usr/share/doc/$package/");
  }
}

Index of chunks

* dh-kpatches-0.99.36+nmu1/dh-kpatches.book0000644000000000000000000000101207755534061014714 0ustar #HTMLDOC 1.8.23 -t ps2 -f dh-kpatches.ps --book --toclevels 3 --numbered --toctitle "Table of Contents" --title --linkstyle underline --size A4 --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header t.h --footer D.1 --nup 1 --tocheader t.h --tocfooter D.i --portrait --color --no-pscommands --no-xrxcomments --compression=1 --jpeg=0 --fontsize 11.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Times --headfootsize 11.0 --headfootfont Helvetica --charset iso-8859-1 --browserwidth 680 dh-kpatches.html dh-kpatches-0.99.36+nmu1/debian/0000755000000000000000000000000011623732756013075 5ustar dh-kpatches-0.99.36+nmu1/debian/kernel-patch-scripts.files0000644000000000000000000000022307623544113020151 0ustar usr/bin/lskpatches usr/share/man/man1/lskpatches.* usr/share/debhelper/dh-kpatches/register-patch usr/share/lintian/overrides/kernel-patch-scripts dh-kpatches-0.99.36+nmu1/debian/compat0000644000000000000000000000000207623543375014275 0ustar 4 dh-kpatches-0.99.36+nmu1/debian/dh-kpatches.files0000644000000000000000000000034607623543623016315 0ustar usr/bin/dh_installkpatches usr/share/debhelper/dh-kpatches/*.tmpl usr/share/debhelper/dh-kpatches/README-kernelpatch.Debian usr/share/doc/dh-kpatches usr/share/man/man1/dh_installkpatches.* usr/share/lintian/overrides/dh-kpatches dh-kpatches-0.99.36+nmu1/debian/README-kernelpatch0000644000000000000000000000255507757253351016264 0ustar This package contains a kernel patch, which was packaged using dh-kpatches @VERSION@. Here is a generic description the behaviour of such patches. For generic instructions on using those patches, see make-kpkg(8), its --added-patches option, and its PATCH_THE_KERNEL environment variable. - its application will by default only be attempted if the declared kernel version for the patch matches the current kernel's version (unlike patches produced with early versions of this package, which attempted to do things the best they can, possibly producing some confusion). - if this patch depends on other patches, those will be applied in an unspecified order, and will be removed after this one will have been removed. It is not necessary any more to ask for explicit application of these dependencies, but it is not an error to do so. - for each patch you can set the KPATCH_ environment variable to a specific kernel version, if you want to apply a patch that is not declared to work on the current kernel. This can be useful if you want to test a patch on a brand new kernel release that was not published at the time of patch packaging. If the requested version is not found, this patch application will fail. If the patchid you're refering to contains characters invalid for an environment variable name (currently only '-'), you should replace them with underscores. dh-kpatches-0.99.36+nmu1/debian/kernel-patch-scripts.overrides0000644000000000000000000000013507623544113021053 0ustar kernel-patch-scripts: script-not-executable ./usr/share/debhelper/dh-kpatches/register-patch dh-kpatches-0.99.36+nmu1/debian/rules0000755000000000000000000000265007755741362014164 0ustar #!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. PACKAGE=dh-kpatches VERSION=$(shell dpkg-parsechangelog | grep ^Version: | sed 's/Version: *//') topdir=$(shell pwd) debdir=${topdir}/debian tmpdir=${debdir}/tmp tmpldir=${tmpdir}/usr/share/debhelper/dh-kpatches/ build: build-stamp build-stamp: dh_testdir $(MAKE) touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp -$(MAKE) clean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) install DESTDIR=${tmpdir} mkdir -p ${tmpdir}/usr/share/lintian/overrides cp -p debian/dh-kpatches.overrides ${tmpdir}/usr/share/lintian/overrides/dh-kpatches cp -p debian/kernel-patch-scripts.overrides ${tmpdir}/usr/share/lintian/overrides/kernel-patch-scripts mkdir -p ${tmpldir} sed s/@VERSION@/${VERSION}/g ${tmpldir}/README-kernelpatch.Debian dh_movefiles test -z `find debian/tmp -not -type d | tee /dev/stderr` binary-arch: build install # We have nothing to do by default. binary-indep: build install # dh_testversion dh_testdir dh_testroot dh_installdocs TODO dh_buildinfo dh_installexamples examples/* dh_installchangelogs dh_compress dh_fixperms dh_installdeb dh_perl dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure dh-kpatches-0.99.36+nmu1/debian/dh-kpatches.doc-base.dh-kpatches0000644000000000000000000000061707626775462021076 0ustar Document: dh-kpatches Title: Packaging Linux kernel patches for Debian with dh-kpatches Author: Yann Dirson Abstract: This document describes a debhelper add-on mechanism that allows consistent packaging of various kinds of Linux kernel patches. Section: devel Format: HTML Index: /usr/share/doc/dh-kpatches/dh-kpatches.html Files: /usr/share/doc/dh-kpatches/dh-kpatches.html dh-kpatches-0.99.36+nmu1/debian/control0000644000000000000000000000240211623732667014477 0ustar Source: dh-kpatches Section: devel Priority: extra Maintainer: Yann Dirson Build-Depends-Indep: debhelper (>> 4), docbook-utils, docbook, debiandoc-sgml, sgml2x (>= 1.0.0), openjade1.3, gtk-doc-tools, nowebm, dh-buildinfo Standards-Version: 3.5.10 Package: dh-kpatches Architecture: all Depends: ${perl:Depends}, debhelper (>= 2.0.14) Suggests: kernel-package Enhances: debhelper Description: Debhelper script to help packaging kernel patches The dh_installkpatches script produces the "apply" and "unpatch" scripts that kernel-package uses to automatically handle kernel patches. It provides a number of useful features like: * does its best to never break your kernel source tree * allows you to select any provided version of a patch * handle patch inter-dependencies . Patches are described in a Debian-standard control-file-like format. Package: kernel-patch-scripts Architecture: all Priority: optional Recommends: kernel-package Enhances: kernel-package Description: Scripts to help dealing with packaged kernel patches This package contains scripts useful to people making use of the various kernel-patch packages. It currently contains: . * lskpatches: a tool that lists installed patches, and gives useful information about them. dh-kpatches-0.99.36+nmu1/debian/README0000644000000000000000000000064207757753127013767 0ustar There are less and less comments in the scripts themselves as the code is migrated to noweb. The implementation document (noweave HTML output) is currently not in this package because the necessary formatting filters for noweb are not available yet in Debian, but current snapshot can be found at http://ydirson.free.fr/en/software/noweb/dh-kpatches.html in the meantime (serving as demonstration for those filters). dh-kpatches-0.99.36+nmu1/debian/dh-kpatches.overrides0000644000000000000000000000024207623540600017200 0ustar dh-kpatches: script-not-executable ./usr/share/debhelper/dh-kpatches/apply.tmpl dh-kpatches: script-not-executable ./usr/share/debhelper/dh-kpatches/unpatch.tmpl dh-kpatches-0.99.36+nmu1/debian/changelog0000644000000000000000000005016511623732756014756 0ustar dh-kpatches (0.99.36+nmu1) unstable; urgency=low * Non-maintainer upload. * No longer use alcovebook-sgml features (Closes: #638637). -- Luca Falavigna Sat, 20 Aug 2011 15:25:13 +0200 dh-kpatches (0.99.36) unstable; urgency=low * Have kernels in the short stable 4-numbers "branchlets" (eg. 2.6.11.x) of the 2.6 line default to using a patch with matching 3-numbers version if a 4-numbers one is not found (Closes: #309147). This is not 100% accurate since EXTRAVERSION is used for many things, but well, it looks like we'll have to live with this way of numbering the kernels. * Removed special handling of 2.6.8.1 as an "irregular version", since it falls in the above case. The "irregular version" mechanism is kept, in case we have to find a quick solution to another kernel versionning change. * Revert abusive merging of regexp from 0.99.35: we do not need to be as strict on single versions are we need to be on ranged ones (Closes: #281801). * Avoid spurious warning messages from dpkg-gencontrol (Closes: #263617). -- Yann Dirson Thu, 9 Jun 2005 00:45:43 +0200 dh-kpatches (0.99.35) unstable; urgency=low * Added support for single irregular kernel versions like 2.6.8.1 (patch from Norbert Buchmuller, closes: #274410). -- Yann Dirson Sun, 24 Oct 2004 17:16:12 +0200 dh-kpatches (0.99.34) unstable; urgency=low * Updated EXTRAVERSION extraction for 2.6.5-3 and later kernel-patch-debian (See: #165505 - thanks to Dann Frazier). -- Yann Dirson Wed, 5 May 2004 09:41:29 +0200 dh-kpatches (0.99.33) unstable; urgency=low * Fixed gzip invocation not to abort on already-compressed patches (Closes: #241257). -- Yann Dirson Wed, 31 Mar 2004 18:00:23 +0200 dh-kpatches (0.99.32) unstable; urgency=low * Fixed checking of applied dependencies in apply script (bug detected by perl in 0.100 branch). * Improved START/END traces by telling PatchId in addition to PatchName. -- Yann Dirson Thu, 8 Jan 2004 23:43:15 +0100 dh-kpatches (0.99.31) unstable; urgency=low * Implement multi-valued Architecture fields, as advertised in the doc (Closes: #216238): * Dirs containing diff files are not stored any more under per-arch directories since this has no meaning any more. Instead they're put in /usr/src/kernel-patches/diffs/. * Now that patch application does not depend any more on old/deprecated PATCH_THE_KERNEL=YES, we can finally cause apply to fail when no alternative is found our kernel (Closes: #217138). In practice, that will make "PATCH_THE_KERNEL=YES" even obsolete :) * Fixed README-kernelpatch note on the order in which sibling dependencies are applies and removed. Removal ordering as documented there was plain wrong, and none of these orderings should be relied upon, since people should explicit inter-dependencies instead. * Added to README-kernelpatch how to handle chars in patchid's not allowed in environment variables. * Slightly clarified the message on unpatch of dependencies. * Internals doc: much work supposed to improve the internals' doc, so that v1 implementation gets easier. * Moved apply.tmpl and unpatch.tmpl into dh-kpatches.nw. * Reworked structure of apply.tmpl to use assertions where possible, instead of nesting if's. -- Yann Dirson Sat, 6 Dec 2003 18:24:28 +0100 dh-kpatches (0.99.30) unstable; urgency=low * Transition of noweb doc chunks from LaTeX to HTML, for compatibility with upcoming code pretty-printing via enscript. * Added missing build-deb on nowebm (CLoses: #221032). * Use dh-buildinfo. -- Yann Dirson Sun, 16 Nov 2003 19:32:55 +0100 dh-kpatches (0.99.29) unstable; urgency=low * The "literate programming is good for you" release. * Use noweb for main dh_installkpatches code. This will help to make the structural changes the code still needs to implement v1 file-format. * Transitionning to noweb must be done by reading the code first, and that helped to find some problems: * Abort when a config file asked to be read cannot be openned, instead of silently ignoring the error. * Don't include kernel-patch-scripts any more in kpatch:Depends, since that was only needed because of the register-patch scriptlet, not used any more since 0.99.24. * Kpatches file were only closed when they were read as v0 files - er, wait, we _only_ support v0 files :) -- Yann Dirson Mon, 3 Nov 2003 20:55:32 +0100 dh-kpatches (0.99.28) unstable; urgency=low * Removed misleading "first" in unpatch output (Closes: #204119). * Ensure all messages on apply/unpatch are written to stderr. * Bracket apply and unpatch operations with START and END messages, to ease debugging complex dependencies. * Ensure that a patch depended on by several patches does not get unpatched until all of its dependants have been unpatched (Closes: #204160). -- Yann Dirson Thu, 18 Sep 2003 00:10:31 +0200 dh-kpatches (0.99.27) unstable; urgency=low * Now check for version.Debian as well when trying to identify a Debian-patched kernel, to reflect changes in how debian kernels are now handled (Closes: #201075). -- Yann Dirson Mon, 14 Jul 2003 13:32:52 +0200 dh-kpatches (0.99.26) unstable; urgency=low * Changed priority of kernel-patch-scripts to optional (Closes: #197612). -- Yann Dirson Sat, 5 Jul 2003 10:02:10 +0200 dh-kpatches (0.99.25) unstable; urgency=low * Fixed unclean quoting of #PATCHNAME# which caused breakage because of changes in 0.99.24 for some patch names (Closes: #199447). -- Yann Dirson Wed, 2 Jul 2003 22:56:50 +0200 dh-kpatches (0.99.24) unstable; urgency=low * Incorporated the contents of the register-patch template into apply script to make it more easy to add features there. Still ship the template so that patches depending on it still apply when upgrading kpatch-scripts. * Register the kernel version the patch was for, when making use of the KPATCH_ mechanism to select an alternate one (Close: #198063). * Call docbook-2-* with --dssslproc instead of obsolete --jade flag; build-dep on 1.0.0 or newer. * Bumped Standards-Version to 3.5.10, no change. -- Yann Dirson Tue, 24 Jun 2003 23:48:27 +0200 dh-kpatches (0.99.23) unstable; urgency=low * Have apply scripts print a warning when no version of a requested patch was found for the kernel to be built. Not yet the full functionality I'd like to have here, but closes: #193016. -- Yann Dirson Fri, 30 May 2003 00:06:01 +0200 dh-kpatches (0.99.22) unstable; urgency=low * Fixed the build process to use openjade1.3 instead of jade, and wrap raw calls to the latter with runjade to catch errors if any. * Finally, also use sgml2x to generate the HTML, after fixing the commented-out invocation - that way, no need to fix the path to the stylesheet when it changes (Closes: #190883). * Build-depend on gtk-doc-tools to get the stylesheet, now that it is not shipped by sgml2x. -- Yann Dirson Sun, 27 Apr 2003 09:48:45 +0200 dh-kpatches (0.99.21) unstable; urgency=low * Typo in package description (Closes: #186989). * Hacked a Debian-patch-file construct as a temporary alternative to a proper "flavour" mechanism - well that'd have to be a magic flavour unless something is changed in the packaging of the kernel, anyway. See #172826 for details. -- Yann Dirson Sun, 6 Apr 2003 14:53:23 +0200 dh-kpatches (0.99.20) unstable; urgency=low * Call grep-dctrl, not grep-status (Closes: #183611). -- Yann Dirson Thu, 13 Mar 2003 21:22:11 +0100 dh-kpatches (0.99.19) unstable; urgency=low * Ensure lskpatches is not corrupted by prcs keyword substitution. -- Yann Dirson Wed, 26 Feb 2003 00:46:03 +0100 dh-kpatches (0.99.18) unstable; urgency=low * Fixed thinko where no error would be issued if fed a kpatches file with format-version greater than 1 - should not have bitten anyone ;) * Be sure apply scripts ask grep-status to do an exact match (Closes: #167344). * Fixed typos in register-patch script, which prevented correct info to be substituted. * Improved way to substitute PATCHNAME into apply/unpatch script, to avoid unexpected failures when patch name contains shell special chars (Closes: #177217). Still far from perfect, but I don't want to make this too complicated, as this will end up being rewritten in perl someday. * Make sure old jade gets used to format docs. * Fixed display of error messages in unpatch scripts. * Cause apply scripts to exit with non-zero status when dry-run fails (Closes: #174213). This is justified by the recent new default of PATCH_THE_KERNEL=AUTO in make-kpkg, which IMHO effectively makes old PATCH_THE_KERNEL=YES behaviour (in which the "exit 0" behaviour was useful) obsolete. There are risks that this behaviour would not be so friendly, though, because we cause interruption of make-kpkg then. Time will tell. Maybe I'll have to revert this. * Don't install kpatch-policy document - most material here is obsolete, and the remainder would be better placed in kernel-package documentation. * Fixed docbase id for dh-kpatches document. Cut'n'paste obviously rulez :) -- Yann Dirson Wed, 26 Feb 2003 00:23:46 +0100 dh-kpatches (0.99.17) unstable; urgency=low * Use -p when calling dpkg-gencontrol to check for kpatch:Depends (Closes: #160511). * Use -Pdebian as well, as debian/tmp may not exist, and we can't suppose the use of any DH_COMPAT level, and anyway it's only used for things that are not related to what's of interest to the script. -- Yann Dirson Wed, 11 Sep 2002 23:08:49 +0200 dh-kpatches (0.99.16) unstable; urgency=low * Switched handling of default values to v1 data structures. * Allowed Depends field to be have a global default value. * Removed support for non-inheriting optional parameters, as "depends" was the only one of this kind. * dh_installkpatches now aborts if the kpatch:Depends substvar is not used in the control-file Depends entry for a package providing a kernel patch through dh-kpatches. -- Yann Dirson Tue, 10 Sep 2002 02:04:16 +0200 dh-kpatches (0.99.15) unstable; urgency=low * More detailed outline in the doc. * Robustness patch from Ola Lundqvist (Closes: #159585). * Changed sed delimiters for PATCHNAME substitution in apply.tmpl to match those in dh_installkpatches (Addresses: #159352). * Refuse to proceed when diff file touches EXTRAVERSION (Addresses: #159319). * Fail if a dependency does not create a stamp file, because it means no version was found. -- Yann Dirson Wed, 4 Sep 2002 22:57:25 +0200 dh-kpatches (0.99.14) unstable; urgency=low * Have the patch register its package name and version, together with its own name. Added grep-dctrl to kpatch:Depends. * Made unpatch scripts remove the debian/image.d/ script, and the directory when necessary. * Started to reorganize internal data structures the v1 way, when still reading from v0 files, and processing them in v0 way. * Added to the doc one more example of what v1 file-format may look like. * Moved v1 examples to examples-v1, so that they do not get installed yet. * Moved a couple of non-essential things down in TODO list, as being post-1.0. * Noticed a couple of issues with dependent patches, listed them in debian/TODO. * Added a lintian override to kernel-patch-scripts for script template not being executable. -- Yann Dirson Mon, 26 Aug 2002 00:02:36 +0200 dh-kpatches (0.99.13) unstable; urgency=low * Register the patch in /usr/share/doc/ in the built kernel. This is done by having the apply script copy a script from the kernel-patch-scripts package into debian/image.d/, which will do the job. Thus, kernel patches will now depend on kernel-patch-scripts (which they would have anyway be the case later, to avoid duplication of apply/unpatch scripts). This will only be honored by kernel-package 8.002 and later; I'm still not 100% convinced we mush have kpatch pakages depend on it, but well, maybe one day I'll have to do that to ensure the kpatch packages get used correctly. * Updated reference to /usr/share/doc/ material in documentation (Closes: #152333). * Removed spurious error messages for lskpatches (patch from Chung-chieh Shan, Closes: #154187). -- Yann Dirson Mon, 29 Jul 2002 22:24:46 +0200 dh-kpatches (0.99.12) unstable; urgency=low * Install TODO file. * Updated draft description of revision-1 file-format from user feedback, and from additional thoughts. -- Yann Dirson Wed, 17 Jul 2002 00:32:44 +0200 dh-kpatches (0.99.11) unstable; urgency=low * New lskpatches script, to list available patches on system, in new kernel-patch-scripts package. * Insert dh-kpatches version in apply script, so that lskpatches can give more useful info. * Switch to debhelper 4. -- Yann Dirson Sat, 22 Jun 2002 23:12:07 +0200 dh-kpatches (0.99.10) unstable; urgency=low * Allow non-range kernel-version specification in kpatches files to have a non-empty EXTRAVERSION (Closes: #141427). * Document that those are not allowed (yet) in kversion ranges. -- Yann Dirson Tue, 9 Apr 2002 00:49:59 +0200 dh-kpatches (0.99.9) unstable; urgency=low * Updated documentation. Described the future "revision 1" kpatches format in details. * Updated README-kernelpatch for new Depends behaviour. -- Yann Dirson Tue, 19 Feb 2002 08:00:42 +0100 dh-kpatches (0.99.8) unstable; urgency=low * Restructured APPLIED files with a controlfile-like format, for more extensibility. * Automatically apply and remove patches declared as dependencies, on apply and unpatch (Closes: #122330). * Reworked plans for 1.0 - still 2 major features possible to implement without rewriting apply/unpatch in perl. -- Yann Dirson Mon, 18 Feb 2002 06:56:51 +0100 dh-kpatches (0.99.7) unstable; urgency=low * Implemented kernel-version ranges, using suggestion from Matt Zimmerman (Addresses: #122330). -- Yann Dirson Thu, 14 Feb 2002 07:51:38 +0100 dh-kpatches (0.99.6) unstable; urgency=low * Reverted silly change in apply scripts wrt dependant patchid's containing hyphens (re-fixes #132710 - thanks to Olaf Meeuwissen). -- Yann Dirson Wed, 13 Feb 2002 07:23:47 +0100 dh-kpatches (0.99.5) unstable; urgency=low * Fixed handling of Depends: field, now correctly working on a per-patchfile basis. * Moved docs in their own source directory. * Some cleanup in dh_installkpatches. * Moved doc from plain-text to docbook. Use bookarticle style (from alcovebook-sgml) for pdf output. Had to split the contents of the manpage away from their DTD, into their own file, to allow including them in the new doc as well - sigh. -- Yann Dirson Mon, 11 Feb 2002 02:52:33 +0100 dh-kpatches (0.99.4) unstable; urgency=low * Added support for "Kernel-version: all" in kpatches files (patch by Olaf Meeuwissen, Closes: #132709). * Fixed check for patch dependencies containing hyphens (Closes: #132710). * Otherwise fixed support for hyphens in patch IDs, accidently broken in 0.99.2. -- Yann Dirson Fri, 8 Feb 2002 06:38:49 +0100 dh-kpatches (0.99.3) unstable; urgency=low * Added support for kpatch:Depends substitution. Currently Expands to "bash (>=2.0)" for array variable support, and "patch" - you guess why. * Fixed 0.99.1 entry for kdb bug ref (thanks to P.M. Hahn). * Remove docbook2man aux files on clean. * Updated manpage, put it under FDL. * Allowed / in Patch-name (use | instead as sed separator), and documented restriction in usable chars here (| and " not allowed). -- Yann Dirson Thu, 7 Feb 2002 09:03:46 +0100 dh-kpatches (0.99.2) unstable; urgency=low * Cope with hyphens in patch IDs - something I removed accidentally from 0.99.1 (Closes: #131159). -- Yann Dirson Sun, 27 Jan 2002 22:22:22 +0100 dh-kpatches (0.99.1) unstable; urgency=medium * WARNING: this release changes the behaviour of the apply scripts, so that patches whose version only approximately matches will by default not be applied. This is a safety measure, to make the mechanism conform to the "least surprise" principle. Environmnent variable are used to select exactly what release of which patch to apply. * Largely updated TODO file, heading for 1.0 release. * Fixed a bug with patches for several arches, where all patches were added to each arch (see kdb #130371). Medium urgency since patch packages are broken when this occurs. * Updated example from kernel-patch-kdb 2.1, for an example of multi-patch package making use of patch dependancies. * Use "g" flag to sed, so that substitutions are all correctly done when creating apply/unpatch from templates. * Use "patch --force" instead of "patch --batch", so that already-applied patches do not get tested reversed on dry-run. * Install in patch packages a README-kernelpatch.Debian file, describing what to expect, and how to control the patch behaviour. * Selectively applied David Kimdon's patch for typos and english correctness (Closes: #126112). * Switch manpage generation to docbook-utils. * Update extended description for package. * Fixed 0.2 changelog entry below for the syntax of multiple kpatches files. * Use Build-Depends-Indep, not Build-Depends. * Updated Standards-Version to 3.5.6. -- Yann Dirson Sun, 27 Jan 2002 16:07:36 +0100 dh-kpatches (0.7) unstable; urgency=low * Escape slashes in a patch name, so that sed does not fail (Closes: #110493). * Added lintian overrides for script templates reported non-executable. -- Yann Dirson Mon, 10 Sep 2001 23:12:34 +0200 dh-kpatches (0.6) unstable; urgency=low * Simple handling of inter-patch dependencies: refuse to install a patch if deps are not OK. * Fixed substitution of PATCHARCH into scripts. -- Yann Dirson Mon, 14 May 2001 16:25:34 +0200 dh-kpatches (0.5) unstable; urgency=medium * Do not cause make-kpkg to fail on unpatch if debian/ dir cannot be removed - thanks to Ard van Breemen (Closes: #96751). * Removed local vars from changelog - now useless. -- Yann Dirson Wed, 9 May 2001 22:40:15 +0200 dh-kpatches (0.4) unstable; urgency=medium * Declare that we enhance debhelper. * Refuse patch-ids with invalid characters (Closes: #94635). * Added missing build-dep on docbook-to-man and debiandoc-sgml. -- Yann Dirson Tue, 1 May 2001 22:43:13 +0200 dh-kpatches (0.3) unstable; urgency=low * Be kind with patch packages that create their (empty) APPLIED stamp outside debian/, by not removing such files. -- Yann Dirson Fri, 23 Mar 2001 01:11:08 +0100 dh-kpatches (0.2) unstable; urgency=low * Support multiple patch-definitions files per package (debian/.kpatches.*). * Fixed support for multiple archs in a single kpatches file. * Removed multiarch knowledge from apply/unpatch scripts, as this is already handled by make-kpkg. * Added Alcove to the list of copyright holders. -- Yann Dirson Tue, 13 Mar 2001 16:29:27 +0100 dh-kpatches (0.1.1) unstable; urgency=low * Removed template README.Debian (Closes: #84190). -- Yann Dirson Sun, 4 Feb 2001 22:24:02 +0100 dh-kpatches (0.1) unstable; urgency=low * Initial Release (Closes: #70858). -- Yann Dirson Mon, 11 Dec 2000 21:02:51 +0100 dh-kpatches-0.99.36+nmu1/debian/copyright0000644000000000000000000000176207623515071015030 0ustar This is dh-kpatches, written and maintained by Yann Dirson on Mon, 11 Dec 2000 21:02:51 +0100. The original source can always be found at: ftp://ftp.debian.org/dists/unstable/main/source/ Copyright (C) 2000-2001 Yann Dirson Copyright (C) 2001 Alcove This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License with the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dh-kpatches-0.99.36+nmu1/examples-v1/0000755000000000000000000000000007747262757014030 5ustar dh-kpatches-0.99.36+nmu1/examples-v1/kernel-patch-ltt.kpatches0000644000000000000000000000066107623543531020716 0ustar Patch-name: Linux Trace Toolkit OS-kernel: linux Patch-id: ltt Kernel-version: 2.4.16 - 2.4.17 Architecture: all Operation: diff File: Patches/patch-ltt-linux-2.4.16-vanilla-020415-1.14 Kernel-version: 2.5.7 Architecture: all Operation: diff File: Patches/patch-ltt-linux-2.5.7-vanilla-020415-1.14 Kernel-version: 2.4.16 Kernel-flavour: rtai Architecture: all Operation: diff File: Patches/patch-ltt-rtai-24.1.8-020317-1.14 dh-kpatches-0.99.36+nmu1/examples-v1/kernel-patch-lkcd-alt-expanded.kpatches0000644000000000000000000000050607623543531023372 0ustar Patch-name: Linux Kernel Crash Dump Patch-id: lkcd Kernel-version: 2.4.17 Architecture: all cp: debian/image.d/kerntypes debian/image.d/ patch: lkcd-4.1-1.patch Path-strip-level: 1 Kernel-version: 2.4.18 Architecture: all cp: debian/image.d/kerntypes debian/image.d/ patch: lkcd-4.1-1-2.4.18.patch Path-strip-level: 1 dh-kpatches-0.99.36+nmu1/examples-v1/kernel-patch-lkcd.kpatches0000644000000000000000000000057207623543531021031 0ustar Patch-name: Linux Kernel Crash Dump Patch-id: lkcd Default-Path-strip-level: 1 Default-Architecture: all Kernel-version: 2.4.17 Operation: copy From: debian/image.d/kerntypes To: debian/image.d/ Operation: diff File: lkcd-4.1-1.patch Kernel-version: 2.4.18 Operation: copy From: debian/image.d/kerntypes To: debian/image.d/ Operation: diff File: lkcd-4.1-1-2.4.18.patch dh-kpatches-0.99.36+nmu1/examples-v1/kernel-patch-lkcd-alt3.kpatches0000644000000000000000000000051207623544113021661 0ustar Patch-name: Linux Kernel Crash Dump Patch-id: lkcd Default-Path-strip-level: 1 Default-Architecture: all Kernel-version: 2.4.17 File: debian/image.d/kerntypes Target-dir: debian/image.d/ Diff: lkcd-4.1-1.patch Kernel-version: 2.4.18 File: debian/image.d/kerntypes Target-dir: debian/image.d/ Diff: lkcd-4.1-1-2.4.18.patch dh-kpatches-0.99.36+nmu1/examples-v1/kernel-patch-lkcd-alt.kpatches0000644000000000000000000000046007623543531021603 0ustar Patch-name: Linux Kernel Crash Dump Patch-id: lkcd Default-Path-strip-level: 1 Default-Architecture: all Kernel-version: 2.4.17 cp: debian/image.d/kerntypes debian/image.d/ patch: lkcd-4.1-1.patch Kernel-version: 2.4.18 cp: debian/image.d/kerntypes debian/image.d/ patch: lkcd-4.1-1-2.4.18.patch dh-kpatches-0.99.36+nmu1/dh-kpatches.nw0000644000000000000000000010025610251671713014407 0ustar dh-kpatches implementation
dh-kpatches implementation
@

The two Parts

The dh-kpatches system is made of two parts. The first one takes patch descriptions, and produces kernel-patch packages; the second one is (currently) contained in those patch packages, and handles application of the patches to a kernel source tree, as well as their removal.

The application/removal scripts are (currently) generated from templates by the dh_installkpatches script for each kernel-patch package.

Currently, the patch descriptions are completely parsed by dh_installkpatches, and the apply/unpatch scripts are specific to each package, and can only act on the patches dh_installkpatches taught them about.

Packaging-time work

The dh_installkpatches helper

This is the debhelper-based script that will cause our packages to install patches in the One True Way. Its base structure is that of a standard debhelper script. <>= #!/usr/bin/perl -w # # dh_installkpatches $Revision: 1.17.1.4.1.24.1.5 $ # # Reads debian/$package.kpatches[.foo], installs all files necessary # to have make-kpkg use the kernel patches described in there. # # (c) 2000-2003 Yann Dirson # Some parts based on code from Adam Di Carlo and Joey Hess use strict; use Debian::Debhelper::Dh_Lib; init(); <> PACKAGE: foreach my $package (@{$dh{DOPACKAGES}}) { my $tmp = tmpdir($package); my $ext = pkgext($package); # There are two filename formats, the usual # plus an extended format (debian/package.*). opendir(DEB,"debian/") || error("can't read debian directory: $!"); # If this is the main package, we need to handle unprefixed filenames. # For all packages, we must support both the usual filename format plus # that format with a period an something appended. my $regexp="\Q$package\E\."; if ($package eq $dh{MAINPACKAGE}) { $regexp="(|$regexp)"; } my @files = grep { /^${regexp}kpatches(\..*)?$/ } readdir(DEB); closedir(DEB); # next package if there are no patches in there next PACKAGE if $#files < 0; <> } @

Patch processing

For each binary package, all kpatches files are processed to generate one apply script with a single diff operation (and its corresponding unpatch script). <>= <> foreach my $file (@files) { my %patchinfo = read_control_file ("debian/$file"); # use Data::Dumper; # print Dumper (%patchinfo); my $patchid = $patchinfo{general}->{'patch-id'}; # transformation of the ID to be acceptable as part of an envvar's name $patchinfo{general}->{'clean-patch-id'} = $patchinfo{general}->{'patch-id'}; $patchinfo{general}->{'clean-patch-id'} =~ s/-/_/g; # protect pipes and dquotes for sed command-line $patchinfo{general}->{'patch-name'} =~ s,([|\"]),\\$1,g; <> } <> @

kpatch:depends substvar

A number of packages are needed by kernel-patch packages:

bash 2.x or better
because apply scripts use arrays
patch
because we (currently) only apply patches made of diff files
grep-dctrl
is used to register the version of the kernel-patch package into the kernel-image package
<>= my $pkgdeps = "bash (>= 2.0), patch, grep-dctrl"; @

The substvar code was derived from similar functionnality in dh_perl v3.4.1. For idempotency, we first remove anything this program might have previously added to the substvars file. <>= if (-e "debian/${ext}substvars") { complex_doit("grep -v ^kpatch:Depends= debian/${ext}substvars > debian/${ext}substvars.new || true"); doit("mv", "debian/${ext}substvars.new","debian/${ext}substvars"); } complex_doit("echo 'kpatch:Depends=$pkgdeps' >> debian/${ext}substvars"); @

We also make sure the package uses our substvar, and abort if not. <>= die 'debian/control must make package ' . $package . ' depend on ${kpatch:Depends}' if system ("dpkg-gencontrol -p$package -Pdebian -O -T/dev/null -Vkpatch:Depends=KPATCHISUSED 2>/dev/null |" . "grep -q '^Depends: .*KPATCHISUSED'") != 0; @

Kernel-build-time work

For each v0 kpatches file, we produce an apply and an unpatch script, necessary to work properly with make-kpkg. Those are currently produced from templates.

Apply script

<>= #! /bin/bash set -e <> <> DEPENDS=(#DEPENDS#) KVERSIONS=(#KVERSIONS#) PATCHFILES=(#PATCHFILES#) DEBPATCHFILES=(#DEBPATCHFILES#) STRIPLEVELS=(#STRIPLEVELS#) <> <> <>= IDX= declare -i i=${#PATCHFILES[*]}-1 while [ $i -ge 0 ] do v=${KVERSIONS[$i]} if [ -n "$KPATCH_#CLEANPATCHID#" -a "$v" = "$KPATCH_#CLEANPATCHID#" \ -o "$v" = "$KERNELRELEASE" \ -o "$v" = "$KERNELBRANCHLET" \ -o "$v" = all ] then IDX=$i fi i=i-1 done <> <> @

If the KPATCH_* mechanism was used, we have a special error message listing the requested version. <>= if [ -n "$KPATCH_#CLEANPATCHID#" -a ${KVERSIONS[$IDX]} != "$KPATCH_#CLEANPATCHID#" ] then echo >&2 "Requested kernel version \`$KPATCH_#CLEANPATCHID#' not found for patch #PATCHID#" exit 1 elif [ -z "$IDX" ] then echo >&2 "No \"#PATCHNAME#\" patch found for kernel version $KERNELRELEASE" exit 1 fi @

Of special notice is the "debian" pseudo-flavour. Before the kernel-patch-debian era, we had to check for README.Debian. Now we must check for version.Debian. <>= KVERSION=${KVERSIONS[$IDX]} STRIPLEVEL=${STRIPLEVELS[$IDX]} if [ "${DEBPATCHFILES[$IDX]}" != '' -a \ \( -r version.Debian -o -r README.Debian \) ] then PATCHFILE=${DEBPATCHFILES[$IDX]} else PATCHFILE=${PATCHFILES[$IDX]} fi <>= <> <> <>= NEEDED_DEPS= for dep in ${DEPENDS[$IDX]} do if [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/${KERNELBRANCHLET}/apply/$dep ] then NEEDED_DEPS="${ARCHITECTURE}/${KERNELBRANCHLET}/apply/$dep $NEEDED_DEPS" elif [ -x ${TOPPATCHDIR}/all/${KERNELBRANCHLET}/apply/$dep ] then NEEDED_DEPS="all/${KERNELBRANCHLET}/apply/$dep $NEEDED_DEPS" elif [ -x ${TOPPATCHDIR}/${ARCHITECTURE}/apply/$dep ] then NEEDED_DEPS="${ARCHITECTURE}/apply/$dep $NEEDED_DEPS" elif [ -x ${TOPPATCHDIR}/all/apply/$dep ] then NEEDED_DEPS="all/apply/$dep $NEEDED_DEPS" else echo >&2 "ERROR: Patch dependency \`$dep' not found - aborting" echo >&2 "END applying #PATCHID# patch" exit 1 fi done <>= if [ "$NEEDED_DEPS" ] then echo >&2 "Ensuring the following patches are applied first: $NEEDED_DEPS" for apply in ${NEEDED_DEPS} do dep=$(basename $apply) ${TOPPATCHDIR}/$apply # check something was applied if [ ! -f debian/APPLIED_${ARCHITECTURE}_$dep -a \ ! -f debian/APPLIED_all_$dep ] then echo >&2 "ERROR: patch dependency did not left a patch stamp (version mismatch ?) - aborting" echo >&2 "END applying #PATCHID# patch" exit 1 fi done UNPATCHDEPS=$(echo ${NEEDED_DEPS} | sed s,/apply/,/unpatch/,g) fi <>= echo >&2 "Testing whether \"#PATCHNAME#\" patch for $KVERSION applies (dry run):" if ! [ -r $PATCHFILE ] then echo >&2 "\"#PATCHNAME#\" patch for $KVERSION not found" exit 1 elif ! $DECOMPRESSOR $PATCHFILE | patch --force --dry-run $PATCH_OPTIONS -p$STRIPLEVEL then echo >&2 "\"#PATCHNAME#\" patch for $KVERSION does not apply cleanly" exit 1 fi @

We do not use --force on second run, there should be no need for it. If something requires interaction, it is likely there is a bug somewhere, better catch it.

After applying the diff, we remove any empty files, so that files "removed" by the diff are really removed. We make an exception for ./debian/ contents, and for files named APPLIED*, or else some (buggy) stamp files may be caught too. <>= if ! $DECOMPRESSOR $PATCHFILE | patch $PATCH_OPTIONS -p$STRIPLEVEL then # This should never happen, thanks to the dry-run echo >&2 "ASSERTION FAILED - \"#PATCHNAME#\" patch for $KVERSION failed" echo >&2 "END applying #PATCHID# patch" exit 1 fi echo >&2 "\"#PATCHNAME#\" patch for $KVERSION succeeded" <> @

All information necessary for unpatching is stored in a debian/APPLIED_* file, for use by the unpatch script. <>= mkdir -p debian cat > 'debian/APPLIED_#PATCHARCH#_#PATCHID#' <>= mkdir -p debian/image.d PKGNAME=`dpkg -S $PATCHFILE | cut -d: -f1` PKGVERS=`grep-dctrl -n -P $PKGNAME -s Version -X /var/lib/dpkg/status` cat > 'debian/image.d/register-#PATCHID#' <> \${docdir}/applied-patches EOF chmod +x 'debian/image.d/register-#PATCHID#' <>= TOPPATCHDIR=/usr/src/kernel-patches ARCHITECTURE=`dpkg --print-installation-architecture` DECOMPRESSOR="zcat -f" PATCH_OPTIONS="--ignore-whitespace --silent" # This is informational only, used by lskpatches DHPKPATCHES_VERSION=#DHKPVERS# @

We consider it a success if the patch is already applied.

FIXME: we should make sure that the currently-applied patch is the one that would have been applied. <>= [ -f debian/APPLIED_${ARCHITECTURE}_#PATCHID# -o \ -f debian/APPLIED_all_#PATCHID# ] && exit 0 @

Unpatch script

<>= #! /bin/bash set -e # This "unpatch" script was automatically generated by # dh_installkpatches from unpatch.tmpl $Revision: 1.17.1.4.1.24.1.5 $ <> ARCHITECTURE=`dpkg --print-installation-architecture` PATCHID=#PATCHID# PATCHARCH=#PATCHARCH# TOPPATCHDIR=/usr/src/kernel-patches DECOMPRESSOR="zcat -f" STAMP=debian/APPLIED_${PATCHARCH}_$PATCHID PATCH_OPTIONS="--ignore-whitespace --silent" [ -f $STAMP ] || exit 0 <> <> <> <> <> @ <>= if [ ! -s $STAMP ] then cat >&2 <>= if [ $(echo $(wc -l < $STAMP) ) != 1 ] then . $STAMP else # old format APPLY_INFO=$(cat $STAMP) PATCHFILE=$(echo ${APPLY_INFO} | cut -d# -f1) STRIPLEVEL=$(echo ${APPLY_INFO} | cut -d# -f2) fi @ <>= if [ ! -r $PATCHFILE ] then cat >&2 <>= if [ -n "$DEPENDS" ] then echo >&2 "Also un-applying the following patches: $DEPENDS" for dep in $DEPENDS do if [ -x ${TOPPATCHDIR}/$dep ] then ${TOPPATCHDIR}/$dep else echo >&2 "Could not unpatch dependency: $dep - stopping here." echo >&2 "END unpatching #PATCHID# patch" exit 1 fi done fi @ <>= if grep -l "^DEPENDS=.*[' ]#PATCHARCH#/unpatch/#PATCHID#[' ]" debian/APPLIED_* >/dev/null 2>/dev/null then # There are patches depending on this one, to be removed before. # the dep will be removed by the last of those other patches. echo >&2 "NOT unpatching \"#PATCHNAME#\" since other patches still rely on it" exit 0 fi @ <>= echo >&2 "START unpatching #PATCHID# patch (#PATCHNAME#)" $DECOMPRESSOR $PATCHFILE | patch -R -p$STRIPLEVEL $PATCH_OPTIONS rm -f debian/APPLIED_${PATCHARCH}_$PATCHID debian/image.d/register-#PATCHID# <> <> rmdir -p debian/image.d || true echo >&2 "END unpatching #PATCHID# patch" @

Common stuff

<>= if ! [ -d kernel -a -d Documentation ] then echo >&2 "Not in kernel top level directory. Exiting" exit 1 fi <>= echo >&2 "Removing empty files:" # make an exception for ./debian, or else the stamp files will go too. find . -path ./debian -prune -o \ -type f -size 0 ! -name 'APPLIED*' -exec rm {} \; -print echo >&2 "Done." @

Reading a kpatches control file

When reading a kpatches control file, we store its contents according a data model suitable for the most recent file-format, and will map data extracted from old file-formats into the modern one.

Generic (v1) data structures

The v1 data structures are a hash of general fields taken from the initial stance (eg. PatchName), a hash of default values also taken from the initial stance, and a sequence of alternative versions of the patch, each of which containing a sequence of operations to apply to the kernel tree: <>= my %patchinfo = ('general' => {}, 'defaults' => {}, 'alternatives' => []); @

We provide a single entry-point to the controlfile reader, which will act in different ways according to the format-version.

If we have a v0 header, we migrate the relevant contents of the v0 header into the default-values section ot the [[%patchinfo]] structure, before going on reading. @ <>= # Irregular kernel versions by branch, and their predecessor and successors. # (Key is the predecessor, value is an array ref; # contains the irregular version itself and the successor.) my %irregular_kversions = ( # "2.6" => { # "8" => [ "8.1", "9" ] # } ); # Gives back an array containing all the kernel versions # from $branch.".".$start to $branch.".".$end (inclusive). # Handles some irregular versions correctly, but depends on # the monotonic numeric relation of successive versions. sub iterate_over_kversions { my ($branch, $start, $end) = @_; my @ret; my $v = $start; while ($v <= $end) { push @ret, $branch . "." . $v; if (exists $irregular_kversions{$branch}->{$v}) { if ($irregular_kversions{$branch}->{$v}[0] <= $end) { push @ret, $branch . "." . $irregular_kversions{$branch}->{$v}[0]; $v = $irregular_kversions{$branch}->{$v}[1]; } else { last; } } else { $v++; } } return @ret; } <>= sub read_control_file { my ($file) = @_; <> open (IN, $file) or die "cannot open $file: $!"; # read control-file header read_control_file_section ($patchinfo{general}); if ((!defined $patchinfo{general}->{'kpatch-format-version'}) or ($patchinfo{general}->{'kpatch-format-version'} == 0)) { $patchinfo{defaults} = control_file_v0_header_to_v1_defaults ($patchinfo{general}); <> # } elsif ($patchinfo{general}->{'kpatch-format-version'} == 1) { # Revision 1 # Eh, not yet :) } else { die "Unsupported Kpatch-format-version: \`" . $patchinfo{general}->{'kpatch-format-version'} . "'"; } close IN; validate (\%patchinfo); return %patchinfo; } @

Once a [[%patchinfo]] structure has been filled, we can run some checks on it, to make as sure as possible that it is correct.

FIXME: this should do much more tests ! <>= sub validate { my ($patchinfo) = @_; die "Patch-Id can only contain alphanumerics, hyphens, and underscores" if $patchinfo->{general}->{'patch-id'} =~ /[^\w-]/; foreach my $alternative (@{$patchinfo->{alternatives}}) { foreach my $operation (@{$alternative->{operations}}) { die "Diff file does not exist: " . $operation->{'diff-file'} if ($operation->{format} eq 'diff') and ! -r $operation->{'diff-file'}; die "Diff file changes EXTRAVERSION: " . $operation->{'diff-file'} if 0 == system ('grep -q "^-EXTRAVERSION\>" ' . $operation->{'diff-file'}); } } } @

Reading a control-file section is something quite generic. Maybe there is a generic API for doing that now ?

This function slightly adapted from code in install-docs from Adam Di Carlo, and this is the main reason why it is not split into chunks. <>= sub read_control_file_section { my ($pfields) = @_; my $alreadyreadsomething = 0; my ($key,$value); while () { chomp; # empty line? if (/^\s*$/o) { if ($alreadyreadsomething) { last; } else { next; } } $alreadyreadsomething = 1; if (/^(\S+)\s*:\s*(.*)$/) { # first line of a new field ($key,$value) = (lc $1,$2); #print STDERR "$key -> $value\n"; if (exists $pfields->{$key}) { warn "warning: $key: overwriting previous setting of control field"; } $pfields->{$key} = $value; } elsif (/^\s+(\S.*)$/) { # additional line in a multi-line field $value = $1; defined($key) or die "syntax error in control file: no field specified"; #print STDERR "$key -> $value (continued)\n"; $pfields->{$key} .= "\n$value"; } else { die "syntax error in control file: $_"; } } return $alreadyreadsomething; } @

Handling v0 definitions

A v0 kpatches file is just a list of alternatives, each composed of only one diff operation. We have to convert them into proper structures so that the v1-based processing works as expected. <>= my $cfs = {}; while (read_control_file_section ($cfs)) { push (@{$patchinfo{alternatives}}, control_file_v0_section_to_alternative($cfs)); $cfs = {}; } @

The function that does the conversion simply maps known fields into their final location. <>= sub control_file_v0_section_to_alternative { my ($cfs) = @_; # FIXME: should also process general section, and convert default # values - probably in a similar function return { conditions => { 'kernel-version' => $cfs->{'kernel-version'}, 'architecture' => $cfs->{architecture}, }, depends => $cfs->{depends}, defaults => {}, operations => [ { 'format' => 'diff', 'diff-file' => $cfs->{'patch-file'}, 'debian-diff-file' => $cfs->{'debian-patch-file'}, 'path-strip-level' => $cfs->{'path-strip-level'}, } ], }; } @

The v0 header differs from the v1 header, in that "default" entries are implicit, and for a small well-defined set of fields. When reading a v0 header, we have to explicit them, and strip them from the general fields. <>= sub control_file_v0_header_to_v1_defaults { my ($header) = @_; my %defaults; foreach my $key (keys %{$header}) { if (! grep { $key eq $_ } ('patch-name', 'patch-id')) { $defaults{$key} = $header->{$key}; delete $header->{$key}; } } return \%defaults; } @

Fields of kpatch files

There are 2 types of fields, denoted by constants defined the fields library. Some are mandatory, some are optional. The optional ones can all be given a default value, but mandatory ones cannot use this inheritance mechanism -- hence the [[$FIELD_INHERITS]] name.

Due to this inheritance mechanism, the final value of a field has to be computed according to given rules for inheritance and defaulting.

From text fields to data structures

Generic alternative fields

We record all archs mentionned in the kpatches file, so that we know for which archs we have to generate the apply/unpatch scripts. <>= { my @archfield = split (/, */, field_value ($patchinfo{general}, $alternative->{conditions}, 'architecture', $FIELD_INHERITS, 'all', \%patchinfo)); $alternative->{conditions}->{architecture} = \@archfield; foreach my $arch (@archfield) { push @archs, $arch unless grep { $_ eq $arch } @archs; } } @

The kernel version can be specified either as a single version or as a range.

FIXME: how a is value "all" handled ? It seems filtered out by the test below... <>= { # pattern matching any kernel version (marks branch as $1 and version as $2) my $ranged_kversion_pattern = qr/^(\d+\.\d+)\.(\d+(?:\.\d+)?)$/; my $minimal_kversion_pattern = qr/^(\d+\.\d+)\.(\d+(?:\.\d+)?)/; my $kversion = field_value ($patchinfo{general}, $alternative->{conditions}, 'kernel-version', $FIELD_MANDATORY); # parse "2.4.5 - 2.4.7" and "2.5.4 -" syntaxes my @kv = split (/\s+/, $kversion); if ($#kv > 0) { # FIXME: validity check is really too strict, but we need a # good kversion comparison algorithm to attempt any better # (ie. "-pre" and "-test" at least are special) $kv[0] =~ $ranged_kversion_pattern or die "Malformed kernel version: `$kv[0]'"; my ($branch, $first) = ($1, $2); die "Malformed kernel-version range \`$kversion'" unless ($kv[1] eq '-') && ($#kv <= 2); if ($#kv == 1) { die "Unbounded ranges not supported yet: \`$kversion'"; $kversion = [ $branch, $first ]; } else { $kv[2] =~ $ranged_kversion_pattern or die "Malformed kernel version: `$kv[2]'"; die "Cross-branch ranges are not allowed: `$kversion'" unless $1 == $branch; die "Reverse-ordered range: `$kversion'" if $2 < $first; $kversion = [ $branch, $first, $2 ]; } } else { $kv[0] =~ $minimal_kversion_pattern or die "Malformed kernel version: `$kv[0]'"; } $alternative->{conditions}->{'kernel-version'} = $kversion; } @ Depends is a comma- and space-separated list, and will be used in the bash apply script to initialize an array, so must be made space-separated only. <>= $alternative->{depends} = field_value ($patchinfo{general}, $alternative, 'depends', $FIELD_INHERITS, "", \%patchinfo); $alternative->{depends} =~ s/, */ /g; @

Per-operation fields

This is simplest of all fields, nothing special is done apart from memorizing it. <>= $op->{'path-strip-level'} = field_value ($patchinfo{general}, $op, 'path-strip-level', $FIELD_INHERITS, 1, $alternative, \%patchinfo); @ Since the diff files may be compressed, we are only recording here their location in the source tree, and we are delaying the recording of their final filename until they are installed and maybe compressed. This will be done as we [[<>]]. <>= $op->{'diff-file'} = field_value ($patchinfo{general}, $op, 'diff-file', $FIELD_MANDATORY); $op->{'debian-diff-file'} = field_value ($patchinfo{general}, $op, 'debian-diff-file', $FIELD_INHERITS); @

Field-handling library

Field inheritance

<>= my $FIELD_MANDATORY = 0; my $FIELD_INHERITS = 1; @

[[$inherits]] should have one of the values defined above. [[$default]] can be [[undef]] when there is no default value for the field. <>= sub field_value { my ($general, $hash, $name, $inherits, $default, @defaultlists) = @_; my $value = $hash->{$name}; if ($inherits == $FIELD_MANDATORY) { die "Patchfile info lacks $name field" unless defined $value; } # first go through explicit default values foreach my $defaultlist (@defaultlists) { $value = $defaultlist->{defaults}->{$name} unless defined $value; } # then use hardcoded default as a fallback if (defined $default) { $value = $default unless defined $value; } return $value; } @

Recording a patchfile field for later use

We use hashes to store sequences of values for each arch. These sequences of values will be directly used to produce the apply/unpatch scripts from their templates. <>= # records a field value for a given patchfile on a given arch sub record_patchfile_field { my ($hash, $arch, $value) = @_; if (defined $hash->{$arch}) { $hash->{$arch} .= " $value"; } else { $hash->{$arch} = "$value"; } } @

Patch processing

In a single apply script, all alternatives are handled, and the one to use will be determined at runtime.

We currently support only one operation per alternative (v0 format), and a great deal of this restriction lies in this part, so I will not spend to much time structuring this part, until things are properly implemented.

To get proper v1 support we will put everything including kpatches file parsing into a generic apply script, and have patch packages only symlink to this one. <>= my %kversions=(); my %patchfiles=(); my %debpatchfiles=(); my %striplevels=(); my %depends=(); my @archs=(); # put the right files in the right places foreach my $alternative (@{$patchinfo{alternatives}}) { my $op = $alternative->{operations}->[0]; <> <> <> } <> @

For each alternative, we compute the value to use for each field, possibly using a default value if none was provided, and in some cases splitting into an array. The final value is stored in the place of the original one.

Diff files thus identified are then installed, and entries for the diff files are then recorded for use when generating the apply/unpatch scripts for each of the named architectures.

There is no particular ordering required between the computation of the various fields, but to help moving towards v1 format, we group them by first handling those specific to the alternative itself, and then those specific to the single diff operation in this alternative. <>= <> <> <> <> <> @

All diff files are now located under a single /usr/src/kernel-patches/diffs/ tree. <>= my $srcdir = "/usr/src/kernel-patches/diffs/$patchid"; doit ("mkdir", "-p", "$tmp$srcdir") unless -d "$tmp$srcdir"; $op->{'installed-diff-file'} = "$srcdir/" . basename($op->{'diff-file'}); doit ("cp", $op->{'diff-file'}, "$tmp$op->{'installed-diff-file'}"); doit ("gzip", "-9fq", "$tmp$op->{'installed-diff-file'}"); $op->{'installed-diff-file'} = "$op->{'installed-diff-file'}.gz" if -r "$tmp$op->{'installed-diff-file'}.gz"; if (defined $op->{'debian-diff-file'}) { $op->{'installed-debian-diff-file'} = "$srcdir/" . basename($op->{'debian-diff-file'}); doit ("cp", $op->{'debian-diff-file'}, "$tmp$op->{'installed-debian-diff-file'}"); doit ("gzip", "-9fq", "$tmp$op->{'installed-debian-diff-file'}"); $op->{'installed-debian-diff-file'} = "$op->{'installed-debian-diff-file'}.gz" if -r "$tmp$op->{'installed-debian-diff-file'}.gz"; } else { $op->{'installed-debian-diff-file'} = ''; } @

Version ranges are currently emulated, by duplicating the entry for each integer kernel revision in the range.

This is a temporary behaviour, which does not allow pre-release kernel versions to be seen as part of the range. Adequate version-comparison function and data-structures will be used instead, when time permits. <>= foreach my $arch (@{$alternative->{conditions}->{architecture}}) { if ((ref $alternative->{conditions}->{'kernel-version'}) eq 'ARRAY') { my @kernel_version = @{$alternative->{conditions}->{'kernel-version'}}; foreach my $version (iterate_over_kversions($kernel_version[0], $kernel_version[1], $kernel_version[2])) { record_patchfile_field (\%kversions, $arch, $version); record_patchfile_field (\%striplevels, $arch, $op->{'path-strip-level'}); record_patchfile_field (\%depends, $arch, '"' . $alternative->{depends} . '"'); record_patchfile_field (\%patchfiles, $arch, '"' . $op->{'installed-diff-file'} . '"'); record_patchfile_field (\%debpatchfiles, $arch, '"' . $op->{'installed-debian-diff-file'} . '"'); } } else { record_patchfile_field (\%kversions, $arch, $alternative->{conditions}->{'kernel-version'}); record_patchfile_field (\%striplevels, $arch, $op->{'path-strip-level'}); record_patchfile_field (\%depends, $arch, '"' . $alternative->{depends} . '"'); record_patchfile_field (\%patchfiles, $arch, '"' . $op->{'installed-diff-file'} . '"'); record_patchfile_field (\%debpatchfiles, $arch, '"' . $op->{'installed-debian-diff-file'} . '"'); } } @

apply and unpatch are currently generated from templates, by substituting in there the values computed from the patch definition expressed in the kpatches file. <>= foreach my $arch (@archs) { my $pdir = "/usr/src/kernel-patches/$arch"; foreach my $script ('apply', 'unpatch') { doit ("mkdir", "-p", "$tmp$pdir/$script"); complex_doit ('sed < @TMPLDIR@/' . "$script.tmpl >$tmp$pdir/$script/$patchid" . ' -e \'s/#PATCHID#/' . $patchinfo{general}->{'patch-id'} . '/g\'' . ' -e \'s/#CLEANPATCHID#/' . $patchinfo{general}->{'clean-patch-id'} . '/g\'' . ' -e \'s|#PATCHNAME#|' . $patchinfo{general}->{'patch-name'} . '|g\'' . " -e 's/#DHKPVERS#/@DHKPVERS@/g'" . " -e 's,#TMPLDIR#,@TMPLDIR@,g'" . " -e 's/#DEPENDS#/$depends{$arch}/g'" . " -e 's/#KVERSIONS#/$kversions{$arch}/g'" . " -e 's|#PATCHFILES#|$patchfiles{$arch}|g'" . " -e 's|#DEBPATCHFILES#|$debpatchfiles{$arch}|g'" . " -e 's/#PATCHARCH#/$arch/g'" . " -e 's/#STRIPLEVELS#/$striplevels{$arch}/g'" ); doit ("chmod", "0755", "$tmp$pdir/$script/$patchid"); doit ("mkdir", "-p", "$tmp/usr/share/doc/$package"); doit ('cp', '@TMPLDIR@/README-kernelpatch.Debian', "$tmp/usr/share/doc/$package/"); } } @

Index of chunks

@