<!doctype debiandoc PUBLIC "-//DebianDoc//DTD DebianDoc//EN" [
]>

<debiandoc>
  <book>
    <titlepag>
      <title>Kernel-patch sub-policy draft document</title>
      <author>
	<name>Yann Dirson</name>
	<email>dirson@debian.org</email>
      </author>
      <version>$Revision: 1.2 $</version>
      <abstract>This document is an attempt to gather current Best
Practice(tm) in providing kernel-patches for easy use with
<package>kernel-package</package> (see <manref name="make-kpkg"
section="1">).  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.</abstract>
      <copyright>
	<copyrightsummary>This document is covered by the GNU
GPL.</copyrightsummary>
      </copyright>
    </titlepag>
    <toc>
    <chapt>
      <heading>Big picture summary</heading>
      <p>This section is meant to give a brief overview of how
<prgn>make-kpkg</prgn> works with respect to patch handling.  For more
details please refer to the <manref name="make-kpkg" section="1">
manpage.

      <sect>
	<heading>Using <prgn>make-kpkg</prgn> to build patched kernels</heading>

	<p>The default configuration of <prgn>make-kpkg</prgn> 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 <file>/usr/src/kernel-patches/</file>, either by setting
the <tt>PATCH_THE_KERNEL</tt> environment variable to <tt>YES</tt>
<footnote>You may also set the <tt>patch_the_kernel</tt> variable in
<file>/etc/kernel-pkg.conf</file>, but I discourage this, you may well
forget you have this set one day.</footnote>.

      <p>When asked to apply patches, <prgn>make-kpkg</prgn> 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 <tt>--added_patches</tt> option.

      <sect>
	<heading>How <prgn>make-kpkg</prgn> applies patches</heading>

	<p>It looks for <file>apply</file> scripts in the
following subdirectories of <file>/usr/src/kernel-patches/</file>:
<enumlist compact>
	    <item>
	      <p><file>$ARCH/$VERSION/apply/</file>
	    </item>
	    <item>
	      <p><file>$ARCH/apply/</file>
	    </item>
	    <item>
	      <p><file>all/$VERSION/apply/</file>
	    </item>
	    <item>
	      <p><file>all/apply/</file>
	    </item>
	  </enumlist>

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

	<p>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 <prgn>patch</prgn> may make use of this
power.
    </chapt>

    <chapt>
      <heading>Patch scope</heading>
      <p>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.

      <p>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.

      <sect>
	<heading>Architecture</heading>

	<p>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.

	<p>Only patches with (at least theoretical) support for all
architectures, and non-architecture-dependant patches, belong to the
<tt>all</tt> category.

      <sect>
	<heading>Version</heading>

	<p>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
<prgn>patch</prgn> 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 <tt>x.y.z</tt> may also apply to
<tt>x.y.(z-2)</tt> or <tt>x.y.(z+5)</tt> without <prgn>patch</prgn>
complaining.

	<p>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.

	<p>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
<file>/usr/src/kernel-patches/</file> 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
&quot;good choice&quot;, whatever that means.
    </chapt>

    <chapt>
      <heading>Scripts naming and behaviour</heading>
      <p>This section is meant to give guidelines for writing the
<file>apply</file> and <file>unpatch</file> 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.

      <p>This is where currently packaged patches tend to behave in
unwanted ways.

      <sect>
	<heading>Naming</heading>

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

	<p>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 <prgn>make-kpkg</prgn>.

      <sect>
	<heading>Behaviour</heading>

	<p>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.

	<p>As of now, I don't think a single patch package (including
mines) behaves correctly in all these areas.  I have started a
<package>debhelper</package>-like script to help in this area and to
provide a couple additional functionalities.  Those interested will
find it at <url id="http://people.debian.org/~dirson/kpatches/">

	<sect1>
	  <heading><file>apply</file> telling <file>unpatch</file> the
patch was applied</heading>

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

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

	<sect1>
	  <heading>Removing empty files after patching</heading>

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

	  <p>For good interaction between those 2 behaviours, no empty
files should be removed from the <file>debian/</file> 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
<file>APPLIED_<var>whatever</var></file> scripts conforming to the
previous point to survive to play their role in the whole picture.

	<sect1>
	  <heading>Checking whether to apply the patch</heading>

	  <p><file>apply</file> 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 <prgn>patch</prgn> can do the job, without preventing other
patches to apply on versions of the kernel on which they don't
themselves apply.

	<sect1>
	  <heading>Not breaking the source tree</heading>

	  <p>The scripts should make sure they won't break the user's
tree, by using <prgn>patch --dry-run</prgn> 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.

    </chapt>

    <chapt>
      <heading>Packaging issues</heading>

      <sect>
	<heading>whether to include several patches per package</heading>
      </sect>

      <sect>
	<heading>how to name patch packages</heading>
      </sect>
    </chapt>

  </book>

</debiandoc>
