An interesting thread on the DCLUG mailling list. The thread started with a reply from Meg Larko:
On Tue, Jun 24, 2003 at 01:07:22PM -0400, mp3t wrote:
> Hey all!
> I've been digging for an answer to this for some time. The HOWTOs on
> patching for the most part are either esoteric or assume that patching is a
> skill mastered long ago, and only include the syntax which hasn't worked
> for me.
> The way I understand it, a patch describes the difference between an
> original file and a new one, all generated by diff. When you apply a patch
> to the old version, you get the new version. A patch will be successfully
> applied if and only if the version you are patching is identical to the
> original version of the file against which the patch was created.
> Now for a real world example:
> I have kernel version 2.4.20. I want kernel version 2.5.73, and I want to
> patch, not just download the full kernel. I need a patch that was built for
> 2.5.73 against 2.4.20, not just any old version. In other words, I'm
> looking for a patch whose source version is 2.4.20 and target version is
> 2.5.73, right? The initial state of the file being patched must be
> identical to the original file against which the patch was created, because
> diff can only find the differences between exactly two files, not more. All
> this makes logical sense to me. So why, when I grab a patch from
> kernel.org, does it not indicate the assumed initial state of the patch?
> With 2.4.20 in /usr/src/linux, when I run patch -p1 < patch-2.5.73, I get a
> whole bunch of errors, asking for the "File to patch:". The only
> explanation I can come up with is that the initial state against which the
> patch was built is some version other than 2.4.20. How am I to go about
> resolving this ?
You would need to apply the patch for each and every version between 2.4.20
and 2.5.73. That can be alot. My usual solution is to take the .config
file I created for my 2.4.20 kernel and copy that into the /usr/src/linux-2.5.72
dir as orig.config (or some such similar). Then run "make xconfig" or
"make config"--whatever be your preference and load the orig.config file.
That will provide the same base as your 2.4.20 in the 2.5.73. I would
strongly suggest that you just click through and see that nothing too
significant has changed (or take advantage of new things). Finally you
save and exit from xconfig and rebuild the kernel as usual (make dep; make
clean; make bzImage; make modules; make modules_install). Copy the
appropriate files into /boot partition as per usual and go.
Here's my first reply:
On Tue, 24 Jun 2003, Meg Larko wrote:
> On Tue, Jun 24, 2003 at 01:07:22PM -0400, email@example.com wrote:
> > The way I understand it, a patch describes the difference between an
> > original file and a new one, all generated by diff. When you apply a patch
> > to the old version, you get the new version. A patch will be successfully
> > applied if and only if the version you are patching is identical to the
> > original version of the file against which the patch was created.
> Basically yes.
Let's imagine we have a file. Let's call it one. One looks like:
We then edit one so it looks like:
And take a universal diff of the change (which is the prefered diff format
for the kernel). The diff looks like:
--- one Wed Jun 25 18:41:53 2003
+++ two Wed Jun 25 18:42:12 2003
@@ -1,5 +1,8 @@
The added lines have a leading plus. Now edit one so it looks like:
And apply the patch that we made earlier:
mikal@wayne demo]$ patch < one.patch
patching file `one'
Hunk #1 succeeded at 4 with fuzz 1 (offset 3 lines).
We still get as a file version of one:
Sorry for the long winded example, but this is why contextual diffs are so
cool, and therefore used in the kernel. The underlying file is allowed to
change, but you'll only get merge failures if you really need to.
This was followed up with this subsequent email.
On Wed, 25 Jun 2003, firstname.lastname@example.org wrote:
> Thanks for your reply. I understand your analogy, and thanks for
> providing me with an example. However, I fail to see why this is a method
> oft used in the kernel. Suppose 'one' is c code. What if the code which is
> the second change to 'one' conflicts with the first change to 'one'? Then
> applying the said patch would create a conflict.
Perhaps, although it is considered uncool to change the inner workings of
a function in a way which breaks the callers without going and changing
all of those calls. Let's look at the possible scenarios:
- a different function (body) is changed. They're good people, and don't
change the interface that the callers use (arguements, return code, side
effects). It doesn't matter to our patch to another bit of the file, as
the interface is unchangeed.
- they change a function, and are uncool and change the inner workings of
the function. They audit all callers. Our patch no longer applies, because
some of the code we overwrote will have changed. I must now manually fix
- they change a function, and it's interface, and audit all callers, but
magically miss the new call I'm inserting. My patched code will no longer
compile, and I therefore know to fix it.
- they change a function, are uncool and don't audit or change the
interface. We might have a bug, but the patch making the uncool change is
much less likely to get accepted into the kernel in the first place, as it
On the why is it done front -- there are literally thousands of kernel
coders. From newbies like me writing silly little return code checking
patches, to people like Rusty changing the way modules work cause he can.
If we insisted that the underlying file couldn't have changed before patch
application, then Rusty's important module patch would fail because of my
little return code check patch. This would cost developers heaps of time,
whereas bugs because of this stuff are rare.
[ Sidenote. This patches on top of patches system is pretty much how CVS
works (by default). M$' VSS on the other hand locks files, and only lets
one change through at a time. This is why big development teams hate VSS.
> A previous reply to the post noted that a patch, let's say 'patch-2.5.73',
> is meant to upgrade kernel version 2.5.72 and 2.5.72 only, up to 2.5.73. If
> we were to apply this patch to a kernel of version other than that which
> the patch was created against, we would have a problem, would we not?
> Directory structures may have changed, or worse yet, it would insert
> conflicting or redundant code.
For sure, this is the case with these mega patches, but most patches are
very small. For instance Greg KH (the usb dude) issues a bunch of USB
patches every now and then. He'll usually send about 70, most with less
than 10 lines of change. They're all meant to be independant of each
That's done to minimise the chance of one big mega patch causing pain.
> Likewise, I understand that a patch like '2.4.21-preempt' is only to be
> applied to kernel 2.4.21, to add the preemption option. It wouldn't add
> such an option to any other version.
Well, it might. The reason for the name is because they have made
assumptions about the shape of the underlying code. If the underlying
subsystems haven't changed, then the same patch _will_ work for 2.5... The
version number is just to let people know that's the platform it is known
to work on.
This is often how backporting is done. A new cool feature is added to 2.5.
Someone wants it in 2.4. They take the 2.5 patch, apply it, and then hand
audit the changes to make sure that they're sane in 2.4 as well.
Does that clarify?
PS: This is basically now a discussion of optomistic locking versus
pessimistic locking me thinks.