Kernel Hacking Lesson #9: Creating, Applying, and Submitting Patches
As a kernel developer, you'll spend a lot of time creating, applying,
and submitting patches. Creating and applying patches can be tricky -
a lot of conventions must be learned and a lot of common mistakes
avoided. Submitting a patch also takes some work.
At first, submitting patches might seem like the easiest part of
kernel development. After all, it can't be as hard as fixing an
ethernet driver bug, right? Well, often it's easier to fix a kernel
bug than to get a kernel patch accepted into the mainline kernel.
Part of the reason is the sheer limitations of one person - the kernel
maintainer can only read and accept so many patches per release. But
other reasons why patches are hard to get accepted are controversial
changes, territoriality, personality conflicts, and apathy. And
finally, whenever you submit a patch, you are putting your reputation
and ego on the line and that's more than a little scary.
That being said, submitting a patch can be a lot of fun and very
encouraging. Some kernel developers had parties to celebrate the
first patch they wrote that was accepted into the mainline kernel.
Knowing that you wrote some code that other people thought was good
enough to include in the Linux kernel is a great feeling! So, let's
learn how to apply, create, and submit patches.
How patches work
A "patch" is a file that describes the differences between two
versions of a file. The program diff compares the original file and
the new file line-by-line and prints the differences to standard out
in a specific format. The program patch can read the output of
diff and apply those changes to another copy of the original file.
(Note that the word "patch" refers both to the output of the diff
command and to the command that applies the patch.) For example:
val@evilcat <~>$ cat old/file.txt
This
is
a
simple
file.
val@evilcat <~>$ cat new/file.txt
This
is
a
slightly more complex
file.
val@evilcat <~>$ diff -uNr old new
diff -uNr old/file.txt new/file.txt
--- old/file.txt Tue May 28 23:00:21 2002
+++ new/file.txt Tue May 28 23:01:01 2002
@@ -1,5 +1,5 @@
This
is
a
-simple
+slightly more complex
file.
As you can see, the two files differ in only one line. The line from
the first file listed on the command line is shown with a "-" in front
of it, followed by the line from the second file on the command line
is shown with a "+" in front of it. Intuitively, you are
"subtracting" the line from the old file and "adding" the line from
the new file. Remember, the old files always come first and the newer
files come second.
Now, lets apply the patch we just created. A patch updates the older
version of the file to the newer version of the file, so we want to
apply the patch to the older version of the file.
val@evilcat <~>$ diff -uNr old new > patchfile
val@evilcat <~>$ cd old
val@evilcat <~/old>$ patch -p1 < ../patchfile
patching file file.txt
val@evilcat <~/old>$ cat file.txt
This
is
a
slightly more complex
file.
After applying the output of the diff command
using patch, the "old"
file is now the same as the "new" file.
Applying patches
Next, we'll learn how to apply patches. One of the common reasons
you'll need to apply a patch is in order to get a particular kernel
version which isn't available as one big tarball downloadable from
ftp.kernel.org, or else to get an incremental patch so you don't have
to download an entire new kernel when most of the kernel files are
still the same.
The kernel patch naming and creation standards are not particularly
simple. Say that you want to get the kernel 2.6.9-rc4 for some
reason, and you currently have the full kernel source for version
2.6.7. You'll need to download the following patches to get from
2.6.7 to 2.6.10-rc1:
2.6.7 to 2.6.8
2.6.8 to 2.6.9-rc4
Each prepatch (the patches that come between the major releases and
are named patch-2.6.x-rcN, usually found in a directory on the ftp
site called testing) is created by diffing against the previous
major release. A common mistake is to download kernel version 2.6.9
and then attempt to apply the 2.6.9-rc4 prepatch. If you want
kernel version 2.6.9-rc4, you should download
kernel 2.6.8 and then
apply the 2.6.9-rc4 prepatch. This is because
2.6.9-rc4 is a predecessor of
2.6.9, not the other way around. NOTE: The naming convention and
location of kernel prepatches tends to change frequently. You may
have to read the linux-kernel mailing list to find out where the very
latest patches are being kept and what they are being named.
The official kernel patches are all made so that you can simply do:
cd <your linux source tree>
patch -p1 < ../patchfile
What the -p1 option to the patch command says is "Strip the part of
the pathname up through the first forward slash and then try to apply
the patch to the file with the stripped down pathname."
If all this seems incredibly complex and annoying, you might want to
try using BitKeeper. See the end of this lesson for a brief
introduction to BitKeeper.
Creating a patch
The first thing to remember is to always keep an untouched, pristine
version of the kernel source somewhere. Don't compile in it, don't
edit any files in it, don't do anything to it - just copy it to make
your working copy of the source tree. The original kernel source
should be in a directory named linux.vanilla or
linux.orig, and
your working directory should be in the same directory as the original
source. For example, if your pristine source is in
/usr/src/linux.vanilla, your working source should be in
/usr/src/ also.
After you make your changes to your working copy, you'll create a
patch using diff. Assuming that your working tree is named
linux.new, you would run this command:
val@evilcat <~>$ diff -uNr linux.vanilla linux.new > patchfile
All the differences between the original kernel source and your new
kernel source are now in patchfile. NOTE: Do not ever create a
patch with uneven directories, for example (DON'T do this):
val@evilcat <~>$ diff -uNr linux.vanilla working/usb/thing1/linux > patchfile
This will not create a patch in the standard patch format and no one
will bother trying out your patch since it's hard to apply.
Now that you've created a patch - read it! It's almost guaranteed
that your patch includes files that you don't want as part of your
patch, such as old editor backup files, object files, or random cruft
you created during development. To get rid of these files, you can
tell diff to ignore certain files, you can delete the files, or you
can hand-edit the diff. Be sure you understand the patch format
before you hand-edit a patch, or you can easily create a patch that
won't apply. One useful command for getting rid of most of the extra
files created during a kernel build is:
make mrproper
But remember, this deletes your .config file and forces you to do a
complete recompile of your kernel.
Also, make sure that your patch goes in the correct direction. Are
your new lines the ones with "+"'s in front of them? And, make sure
those are the changes you wanted to send. It's surprisingly easy to
make a diff against the wrong source tree entirely.
After you think you've got a final version of the patch, apply it to a
a copy of your pristine source tree (don't ruin your only copy of the
pristine source tree). If it doesn't apply without any errors, redo
the patch.
Once again, if this seems awfully complex, you may want to try
BitKeeper, described at the end of this lesson.
Submitting a patch
After you've created a patch, you'll hopefully want to share it with
other people. Ideally, you'll test the patch yourself, get other
people to test it too, and have other people read the patch itself.
In summary, you want your patch to be bug-free, well-written, and
easy to apply.
Testing
Always compile and test your patches yourself. You'll see people
posting "totally untested" patches to linux-kernel, but don't fall for
it - a totally untested patch is likely to be a useless patch. Kernel
maintainers have more than once released a kernel which doesn't
compile at all. No one is perfect - always test your patches.
Coding style
Be sure that your code fits in with the code around it and follows the
kernel coding style conventions. See the file
Documentation/CodingStyle for specific directions, although looking
at other source files is often the best way to figure out what the
current conventions are.
Easy to apply
If it's difficult to apply your patch, it almost certainly won't be
accepted. In addition to creating the patch with the proper level of
directories, you need to create it against the kernel that is
identical (or nearly so) to the kernel that other people will be
applying your patch to. So, if you want person XYZ to apply your
patch, find out what version of the kernel person XYZ is using and try
to get something as close to that as possible. Usually this is the
latest vanilla kernel released by the kernel maintainer. For example,
if you have a patch against 2.6.9-rc2, and
2.6.9-rc4 is the latest
version released, then you should recreate your patch against
2.6.9-rc4. The easiest way to do this is to apply your patch from
2.6.9-rc2 to 2.6.9-rc4 and fix up any
changes that occurred
between the two versions, then rediff against 2.6.9-rc4.
Who to submit your patch to
The answer to "Who should I submit this patch to?" is "It depends."
Subscribe to linux-kernel and any list which is more specific to the
area you are working on, and you will begin to get an idea of who the
appropriate person is. Some general rules of thumb:
Try to find the person most specifically involved in maintaining the
part of the kernel you are changing. If you make a change to the foo
driver in the bar subsystem, and the foo driver has a maintainer, you
should probably submit your patch to the foo maintainer, and only to
the bar subsystem maintainer if the foo maintainer is ignoring you.
The file in the toplevel kernel source directory, MAINTAINERS, is
frequently out of date, but often helpful anyway. No one will fault
you if you send your patch to the person listed in the MAINTAINERS
file and CC linux-kernel. When in doubt, this is always the safest
route to take.
And finally, ask a friend! Send mail to the linuxchix lists asking
for advice on who to submit a patch to. We can help.
Distributing your patch
Most patches are small enough to be included in an email. While some
maintainers refuse to accept patches in attachments, and some refuse
MIME encoded attachments, all maintainers will accept a patch that is
included in the body of a text-only email. Make sure your mail client
isn't mangling your patch - if you aren't sure, email your patch to
yourself and apply it to make sure other people will be able to apply
it to. Most Linux mailing lists like patches with a meaningful English-language
subject, prefixed with the string [PATCH]
so that it's easy to find and read patches.
If your patch is too big to send by email (around 20K or larger), put
it on a web page or ftp site where other people can download it, and
put the URL in your email.
Political considerations
If all that mattered is that your patch was well-formed, correct, and
fixed a bug, submitting a patch would be a lot simpler. Instead, your
patch needs to be tasteful, timely, interesting, and considerate of
the maintainer's ego. Most of the time, a simple bugfix will be
immediately accepted. Occasionally though, you'll run into bigger
problems. The important thing to remember is that you can't work
around the Linux maintainer system, you have to work through it. Read
a few threads on linux-kernel in which people tried to wheedle their
patch into the kernel (I've tried - and failed). If your patch isn't
accepted, listen to what other people are saying about it and try to
fix the problems with it. The most often rejected patch is the
feature patch - adding a new feature that is considered tasteless by
the other maintainers. Don't waste your time trying to get that patch
accepted, just maintain it separately. If enough people find the
patch useful, you'll gain a reputation as being a useful kernel hacker
among all the people who download and use your patch.
Sometimes, a maintainer just can't accept a patch because of his or
her ego. When this happens, the only option is to maintain a better
version of the code independently of the main kernel. Often,
externally maintained code that proves to be better will replace the
in-kernel code after a while, which is one way to become a maintainer.
The alternative to diff and patch - BitKeeper
BitKeeper is currently being used by many kernel developers as a
replacement for diff and patch. It simplifies a lot of kernel
development tasks, such as updating to the latest version, creating
patches, and applying patches. For more information, see the
BitKeeper website:
http://www.bitkeeper.com
Or "BitKeeper for Kernel Developers"
http://www.nmt.edu/~val/ols/bk.ps.gz
|