Simple System for Managing Patches

This is the way Trond showed us to maintain patches against the linux kernel. It's simple to use and seems to work well. There are some small scripts in simple_patch_mgmt-02.tar.gz that automate things a little.

Start with a plain vanilla kernel source directory,


me@mybox$ cd ~/my_linux_trees/
me@mybox$ wget http://www.kernel.org/pub/linux/kernel/v2.5/linux-2.5.55.tar.gz
me@mybox$ tar -xzvf linux-2.5.55.tar.gz

and then create a new directory to work in and populate it with symlinks to linux-2.5.55 using lndir:


me@mybox$ mkdir linux-2.5.55-foo/
me@mybox$ cd linux-2.5.55-foo/
me@mybox$ lndir -silent ../linux-2.5.55
me@mybox$ cd ..; ls
linux-2.5.55  linux-2.5.55-foo  linux-2.5.55.tar.gz

Now say you want to edit fs/nfs/inode.c. Currently linux-2.5.55-foo/fs/inode.c is just a symlink to linux-2.5.55/fs/inode.c; first you want to replace it with a copy of itself. The provided delink script does this for you:


me@mybox$ cd linux-2.5.55-foo/fs/nfs/
me@mybox$ ls -l inode.c
lrwxrwxrwx    1 me  me  36    Feb  5 12:02 inode.c -> ../../../linux-2.5.55/fs/nfs/inode.c
me@mybox$ delink inode.c; ls -l inode.c
-rw-r--r--    1 me  me  42424 Feb  5 12:02 inode.c

Now edit inode.c normally. When you're done, you want to distribute a patch against linux-2.5.55 that implements your cool new feature:


me@mybox$ cd ~/my_linux_trees/
me@mybox$ diff -urN linux-2.5.55 linux-2.5.55-foo >linux-2.5.55-foo.diff

Now inspect the resulting diff to make sure it looks reasonable. If you did a make in one of those directories while testing your change, you may find that it contains a lot of .o files and other garbage. Oops! Big mistake. Never build a kernel inside one of those source trees. Instead, use lndir to create a build directory and build the kernel there:


me@mybox$ mkdir build-linux-2.5.55-foo
me@mybox$ cd build-linux-2.5.55-foo
me@mybox$ lndir -silent ../linux-2.5.55-foo
me@mybox$ make menuconfig && make bzImage && etc.....

This way you can build as many different kernels you want without disturbing the pristine source trees.

If you later decide to try applying linux-2.5.55-foo.diff to another kernel tree, you can use patch:


me@mybox$ ls
linux-2.5.59  linux-2.5.55-foo.diff
me@mybox$ mkdir linux-2.5.59-foo
me@mybox$ cd linux-2.5.59-foo
me@mybox$ patch -p1 <../linux-2.5.59-foo.diff

As a consequence of the way patch works, it will do the right thing with the symlinks: when it modifies a file, it will replace it with a copy first rather than modifying the linked file.

The other two provided tools, make_diffs and apply_patches, automate the tasks of, respectively, making diffs between a series of such trees, and applying a series of patches to a single tree. To use make_diffs:


me@mybox$ make_diffs linux-2.5.55 linux-2.5.55-1 linux-2.5.55-2 ....

this will create a diff between linux 2.5.55 and linux-2.5.55-1, another diff between linux-2.5.55-1 and linux-2.5.55-2, etc. To apply a series of patches:


me@mybox$ apply_patches --source=linux-2.5.55 ~/my_diffs/linux-2.5.55-1.diff ~/my_diffs/linux-2.5.55-2.diff ....

and a bunch of new trees will be created, named after the corresponding patches. Note that the patches must be given by absolute pathnames. This is all made easier if you stick to some naming convention that ensures that the patches and trees all have names which sort in the order they're meant to be applied in. One convention is to name them as in this example:


me@mybox$ ls my_diffs
linux-2.5.55-01-auth2.diff	   linux-2.5.55-06-krb5.diff
linux-2.5.55-02-rpc_encode.diff    linux-2.5.55-07-rpc_svcgss.diff
linux-2.5.55-03-rpc_gss.diff	   linux-2.5.55-08-rpc_integ.diff
linux-2.5.55-04-auth_upcall.diff   linux-2.5.55-09-rpc_priv.diff
linux-2.5.55-05-auth_upcall2.diff  linux-2.5.55-10-idmap.diff

The entire series of patches above can be applied in the correct order just by doing:


me@mybox$ apply_patches --source=linux-2.5.55 ~/my_diffs/*.diff

This isn't a really a replacement for using a revision control system, but it works a lot better than trying to import huge linux trees into cvs. The patches that you end up with should be small enough that you can keep lots of old versions around. Patches are also relatively easy for humans to read, and tend to port to different versions, and apply on top of other people's patches, fairly well.

That's it. Mail me corrections or comments at bfields@umich.edu