# HG changeset patch # User Bryan O'Sullivan # Date 1161453951 25200 # Node ID ecacb6b4c9fd9d12ef08b3103ed3996fcfa4ef11 # Parent 32bf9a5f22c0e90f3ce5bbf98847f7dc9fc31421 Grouping patches in the series file. diff -r 32bf9a5f22c0 -r ecacb6b4c9fd en/mq-collab.tex --- a/en/mq-collab.tex Fri Oct 20 16:56:20 2006 -0700 +++ b/en/mq-collab.tex Sat Oct 21 11:05:51 2006 -0700 @@ -5,11 +5,11 @@ capabilities makes it possible to work in complicated development environments. -In this chapter, I will discuss a technique I have developed to manage -the development of an Infiniband device driver for the Linux kernel. -The driver in question is large (at least as drivers go), with 25,000 -lines of code spread across 35 source files. It is maintained by a -small team of developers. +In this chapter, I will use as an example a technique I have used to +manage the development of an Infiniband device driver for the Linux +kernel. The driver in question is large (at least as drivers go), +with 25,000 lines of code spread across 35 source files. It is +maintained by a small team of developers. While much of the material in this chapter is specific to Linux, the same principles apply to any code base for which you're not the @@ -33,7 +33,10 @@ subsystems. \item We also maintain a number of ``backports'' to older versions of the Linux kernel, to support the needs of customers who are running - older Linux distributions that do not incorporate our drivers. + older Linux distributions that do not incorporate our drivers. (To + \emph{backport} a piece of code is to modify it to work in an older + version of its target environment than the version it was developed + for.) \item Finally, we make software releases on a schedule that is necessarily not aligned with those used by Linux distributors and kernel developers, so that we can deliver new features to customers @@ -79,7 +82,8 @@ case, MQ contains a few added features that make the job more pleasant. -\section{Conditionally applying patches with guards} +\section{Conditionally applying patches with + guards} Perhaps the best way to maintain sanity with so many targets is to be able to choose specific patches to apply for a given situation. MQ @@ -150,14 +154,106 @@ \interaction{mq.guards.qselect.qpush} A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}'' -character. +character. The name of a guard must start with an alphabetic +character (upper or lower case) or an underscore. The rest of the +guard's name can contain any of these characters, or a digit. These +rules are similar to those used for variable naming in most popular +programming languages. If you try to use a guard with an invalid +name, MQ will complain: \interaction{mq.guards.qselect.error} Changing the selected guards changes the patches that are applied. \interaction{mq.guards.qselect.quux} -You can see here that negative guards take precedence over positive -guards. +You can see in the example below that negative guards take precedence +over positive guards. \interaction{mq.guards.qselect.foobar} +\section{MQ's rules for applying patches} + +The rules that MQ uses when deciding whether to apply a patch +are as follows. +\begin{itemize} +\item A patch that has no guards is always applied. +\item If the patch has any negative guard that matches any currently + selected guard, the patch is skipped. +\item If the patch has any positive guard that matches any currently + selected guard, the patch is applied. +\item If the patch has positive or negative guards, but none matches + any currently selected guard, the patch is skipped. +\end{itemize} + +\section{Trimming the work environment} + +In working on the device driver I mentioned earlier, I don't apply the +patches to a normal Linux kernel tree. Instead, I use a repository +that contains only a snapshot of the source files and headers that are +relevant to Infiniband development. This repository is~1\% the size +of a kernel repository, so it's easier to work with. + +I then choose a ``base'' version on top of which the patches are +applied. This is a snapshot of the Linux kernel tree as of a revision +of my choosing. When I take the snapshot, I record the changeset ID +from the kernel repository in the commit message. Since the snapshot +preserves the ``shape'' and content of the relevant parts of the +kernel tree, I can apply my patches on top of either my tiny +repository or a normal kernel tree. + +Normally, the base tree atop which the patches apply should be a +snapshot of a very recent upstream tree. This best facilitates the +development of patches that can easily be submitted upstream with few +or no modifications. + +\section{Dividing up the \sfilename{series} file} + +I categorise the patches in the \sfilename{series} file into a number +of logical groups. Each section of like patches begins with a block +of comments that describes the purpose of the patches that follow. + +The sequence of patch groups that I maintain follows. The ordering of +these groups is important; I'll describe why after I introduce the +groups. +\begin{itemize} +\item The ``accepted'' group. Patches that the development team has + submitted to the maintainer of the Infiniband subsystem, and which + he has accepted, but which are not present in the snapshot that the + tiny repository is based on. These are ``read only'' patches, + present only to transform the tree into a similar state as it is in + the upstream maintainer's repository. +\item The ``rework'' group. Patches that I have submitted, but that + the upstream maintainer has requested modifications to before he + will accept them. +\item The ``pending'' group. Patches that I have not yet submitted to + the upstream maintainer, but which we have finished working on. + These will be ``read only'' for a while. If the upstream maintainer + accepts them upon submission, I'll move them to the end of the + ``accepted'' group. If he requests that I modify any, I'll move + them to the beginning of the ``rework'' group. +\item The ``in progress'' group. Patches that are actively being + developed, and should not be submitted anywhere yet. +\item The ``backport'' group. Patches that adapt the source tree to + older versions of the kernel tree. +\item The ``do not ship'' group. Patches that for some reason should + never be submitted upstream. For example, one such patch might + change embedded driver identification strings to make it easier to + distinguish, in the field, between an out-of-tree version of the + driver and a version shipped by a distribution vendor. +\end{itemize} + +Now to return to the reasons for ordering groups of patches in this +way. We would like the lowest patches in the stack to be as stable as +possible, so that we will not need to rework higher patches due to +changes in context. Putting patches that will never be changed first +in the \sfilename{series} file serves this purpose. + +We would also like the patches that we know we'll need to modify to be +applied on top of a source tree that resembles the upstream tree as +closely as possible. This is why we keep accepted patches around for +a while. + +The ``backport'' and ``do not ship'' patches float at the end of the +\sfilename{series} file in part because they'll never be shipped +upstream. Additionally, the backport patches must be applied on top +of all other patches. + %%% Local Variables: %%% mode: latex %%% TeX-master: "00book"