요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
언제 게시할 것인가
5.Posting.rst:17-32간단한 patch는 완성 뒤 게시해도 되지만 복잡한 작업은 완성 전에 feedback을 받는 이점이 크다. 진행 중 code나 git tree를 공개해 관심 있는 개발자가 계속 따라오게 할 수 있다.
아직 merge 준비가 되지 않았다면 게시물에서 명확히 말하고 남은 큰 작업과 알려진 문제를 적는다. 독자는 적어질 수 있지만 review하는 사람은 방향을 함께 고치는 관점으로 접근할 수 있다.
Patch를 만들기 전 확인
5.Posting.rst:34-58- 가능한 범위까지 test하고 kernel debug 도구를 사용한다.
- 합리적인 Kconfig 조합에서 build하고 다른 architecture용 cross compile도 수행한다.
- Kernel coding style을 준수한다.
- 성능 영향이 있으면 benchmark하고 결과 요약을 patch와 함께 제공한다.
- Code를 공개할 권리가 있는지 확인한다. 고용 관계에서 만든 code라면 회사가 GPL 공개에 동의해야 할 수 있다.
Logical patch series 만들기
5.Posting.rst:60-129Patch는 특정 kernel version을 기준으로 만들어야 한다. 일반적으로 Linus git tree의 현재 mainline을 기반으로 하되 임의 commit보다 stable 또는 -rc 같은 잘 알려진 release point에서 branch한다. 넓은 test가 필요하면 -mm, linux-next, subsystem tree를 기준으로 할 수 있다.
아주 단순한 변경만 single patch로 만들고 나머지는 논리적인 series로 나눈다. 실제 작업 중 만들어진 commit 순서를 그대로 보내는 것이 아니라 완성 형태를 기준으로 독립적으로 review 가능한 단위로 재구성한다.
- 각 patch는 하나의 논리적으로 독립된 변경이고 한 줄로 설명할 수 있어야 한다.
- Security fix, structure 재배치, formatting처럼 종류가 다른 변경을 한 patch에 섞지 않는다.
- Series 중간 어느 지점에서도 kernel이 build되고 동작해야 git bisect가 가능하다.
- 지나치게 잘게 쪼개지 않는다. 한 file 변경을 500개 patch로 보내는 것은 review를 어렵게 한다.
- 새 infrastructure를 추가하고 마지막 patch에서만 사용하지 않는다. 가능하면 code를 추가한 patch가 즉시 활성화되어 bisection이 실제 bug 위치를 가리키게 한다.
Patch 형식과 changelog
5.Posting.rst:131-221각 patch message는 optional From line, 한 줄 summary, blank line 뒤의 상세 설명, tag line, unified diff로 구성된다. 다른 사람의 patch를 전달한다면 From으로 실제 author를 보존한다.
gpio: fix build on CONFIG_GPIO_SYSFS=n
문제가 무엇인지, patch가 무엇을 바꾸는지,
왜 mainline에 적용해야 하는지 설명한다.
Signed-off-by: Full Name <[email protected]>
한 줄 summary는 context 없이도 범위를 알 수 있어야 하고 short changelog에 그대로 나온다. 보통 subsystem 이름 뒤에 변경 목적을 쓴다.
상세 설명은 maintainer와 reviewer, backport를 판단하는 distributor, regression을 추적하는 bug hunter, 변경 내용을 보는 사용자 모두에게 필요한 정보를 직접적이고 간결하게 제공해야 한다.
- Bug를 만든 commit을 알면 commit ID와 제목을 함께 적는다.
- 관련 log나 compiler output을 포함해 같은 문제를 검색하는 사람이 찾게 한다.
- 뒤 patch를 지원하는 준비 변경이면 그 관계를 설명한다.
- Internal API를 바꾸면 다른 개발자가 어떻게 대응해야 하는지 적는다.
- Changelog text를 revision-control commit message에도 그대로 사용한다.
- Diff는 unified -u format을 사용하고 -p로 function context를 붙인다.
Fixes, Link, Closes와 참여자 tag
5.Posting.rst:222-279Fixes: 1f2e3d4c5b6a ("commit title")
Link: https://example.com/background
Closes: https://example.com/issues/1234
Fixes는 문제를 도입한 이전 commit을 가리킨다. Link는 commit message에 없는 유용한 background나 specification을 연결할 때만 쓴다. Public bug report를 실제로 고치는 patch라면 Closes를 사용한다. Private tracker와 invalid URL은 쓸 수 없다.
| Tag | 의미 |
|---|---|
| Signed-off-by | Developer's Certificate of Origin에 따라 제출 권리를 인증한다. 없으면 merge할 수 없다. |
| Co-developed-by | 공동 저자를 기록하며 바로 뒤에 그 사람의 Signed-off-by가 와야 한다. |
| Acked-by | 관련 개발자나 maintainer가 merge에 동의한다. |
| Tested-by | 표시된 사람이 patch를 test해 동작을 확인했다. |
| Reviewed-by | 표시된 사람이 correctness 관점에서 review했다. |
| Reported-by | 고친 문제를 보고한 사용자에게 credit을 주며 가능한 경우 Closes가 뒤따른다. |
| Suggested-by | Patch idea를 제안한 사람에게 credit을 준다. |
| Cc | 표시된 사람이 patch 사본을 받아 comment할 기회가 있었다. |
Cc, Reported-by, Suggested-by를 제외한 tag는 이름이 들어가는 사람의 명시적 허가가 필요하다. 예외 세 tag도 공개 기록에서 해당 이름과 email로 kernel에 기여했고 report나 suggestion이 공개된 경우에만 묵시적 허가를 인정한다. Public Bugzilla에 적힌 email 자체는 private이므로 이전 공개 기여에서 사용되지 않았다면 노출하지 않는다.
Mail로 patch 보내기
5.Posting.rst:281-364Mailer가 whitespace를 바꾸거나 line wrap해 patch를 손상시키지 않는지 자신에게 먼저 보내 확인한다. scripts/checkpatch.pl을 실행하고 complaint를 검토하되, checkpatch를 만족시키려고 code를 더 나쁘게 만들지는 않는다.
Patch는 attachment가 아니라 plain text message body로 보내 reviewer가 필요한 부분을 inline quote할 수 있게 한다.
- 영향받는 subsystem maintainer
- 같은 code 영역에서 최근 작업한 developer
- bug report나 feature request의 original poster
- 관련 subsystem mailing list, 없으면 linux-kernel
- Stable 후보 bug fix라면 [email protected]와 commit tag의 Cc: [email protected]
최종적으로 누가 patch를 받아 상위 tree로 올릴지 생각해 recipient를 고른다. 보통 Linus에게 직접 보내지 않고 subsystem maintainer를 거치며 명확한 maintainer가 없을 때 Andrew Morton이 마지막 경로가 될 수 있다.
[PATCH nn/mm] subsys: one-line description
[PATCH 0/5] subsys: series introduction
nn/mm은 series 안의 순서와 전체 개수이며 single patch면 생략한다. 큰 series는 0번 cover letter를 보낼 수 있지만 cover letter 내용은 kernel changelog에 들어가지 않으므로 각 patch의 changelog는 독립적으로 완전해야 한다.
Multi-part series의 2번 이후 patch는 첫 message에 reply해 하나의 thread로 묶는다. Git과 quilt 도구가 threading을 지원한다. 긴 git series에서는 지나치게 깊은 nesting을 만드는 --chain-reply-to를 피한다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. _development_posting:
Posting patches
===============
Sooner or later, the time comes when your work is ready to be presented to
the community for review and, eventually, inclusion into the mainline
kernel. Unsurprisingly, the kernel development community has evolved a set
of conventions and procedures which are used in the posting of patches;
following them will make life much easier for everybody involved. This
document will attempt to cover these expectations in reasonable detail;
more information can also be found in the files
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
and :ref:`Documentation/process/submit-checklist.rst <submitchecklist>`.
When to post
------------
There is a constant temptation to avoid posting patches before they are
completely "ready." For simple patches, that is not a problem. If the
work being done is complex, though, there is a lot to be gained by getting
feedback from the community before the work is complete. So you should
consider posting in-progress work, or even making a git tree available so
that interested developers can catch up with your work at any time.
When posting code which is not yet considered ready for inclusion, it is a
good idea to say so in the posting itself. Also mention any major work
which remains to be done and any known problems. Fewer people will look at
patches which are known to be half-baked, but those who do will come in
with the idea that they can help you drive the work in the right direction.
Before creating patches
-----------------------
There are a number of things which should be done before you consider
sending patches to the development community. These include:
- Test the code to the extent that you can. Make use of the kernel's
debugging tools, ensure that the kernel will build with all reasonable
combinations of configuration options, use cross-compilers to build for
different architectures, etc.
- Make sure your code is compliant with the kernel coding style
guidelines.
- Does your change have performance implications? If so, you should run
benchmarks showing what the impact (or benefit) of your change is; a
summary of the results should be included with the patch.
- Be sure that you have the right to post the code. If this work was done
for an employer, the employer likely has a right to the work and must be
agreeable with its release under the GPL.
As a general rule, putting in some extra thought before posting code almost
always pays back the effort in short order.
Patch preparation
-----------------
The preparation of patches for posting can be a surprising amount of work,
but, once again, attempting to save time here is not generally advisable
even in the short term.
Patches must be prepared against a specific version of the kernel. As a
general rule, a patch should be based on the current mainline as found in
Linus's git tree. When basing on mainline, start with a well-known release
point - a stable or -rc release - rather than branching off the mainline at
an arbitrary spot.
It may become necessary to make versions against -mm, linux-next, or a
subsystem tree, though, to facilitate wider testing and review. Depending
on the area of your patch and what is going on elsewhere, basing a patch
against these other trees can require a significant amount of work
resolving conflicts and dealing with API changes.
Only the most simple changes should be formatted as a single patch;
everything else should be made as a logical series of changes. Splitting
up patches is a bit of an art; some developers spend a long time figuring
out how to do it in the way that the community expects. There are a few
rules of thumb, however, which can help considerably:
- The patch series you post will almost certainly not be the series of
changes found in your working revision control system. Instead, the
changes you have made need to be considered in their final form, then
split apart in ways which make sense. The developers are interested in
discrete, self-contained changes, not the path you took to get to those
changes.
- Each logically independent change should be formatted as a separate
patch. These changes can be small ("add a field to this structure") or
large (adding a significant new driver, for example), but they should be
conceptually small and amenable to a one-line description. Each patch
should make a specific change which can be reviewed on its own and
verified to do what it says it does.
- As a way of restating the guideline above: do not mix different types of
changes in the same patch. If a single patch fixes a critical security
bug, rearranges a few structures, and reformats the code, there is a
good chance that it will be passed over and the important fix will be
lost.
- Each patch should yield a kernel which builds and runs properly; if your
patch series is interrupted in the middle, the result should still be a
working kernel. Partial application of a patch series is a common
scenario when the "git bisect" tool is used to find regressions; if the
result is a broken kernel, you will make life harder for developers and
users who are engaging in the noble work of tracking down problems.
- Do not overdo it, though. One developer once posted a set of edits
to a single file as 500 separate patches - an act which did not make him
the most popular person on the kernel mailing list. A single patch can
be reasonably large as long as it still contains a single *logical*
change.
- It can be tempting to add a whole new infrastructure with a series of
patches, but to leave that infrastructure unused until the final patch
in the series enables the whole thing. This temptation should be
avoided if possible; if that series adds regressions, bisection will
finger the last patch as the one which caused the problem, even though
the real bug is elsewhere. Whenever possible, a patch which adds new
code should make that code active immediately.
Working to create the perfect patch series can be a frustrating process
which takes quite a bit of time and thought after the "real work" has been
done. When done properly, though, it is time well spent.
Patch formatting and changelogs
-------------------------------
So now you have a perfect series of patches for posting, but the work is
not done quite yet. Each patch needs to be formatted into a message which
quickly and clearly communicates its purpose to the rest of the world. To
that end, each patch will be composed of the following:
- An optional "From" line naming the author of the patch. This line is
only necessary if you are passing on somebody else's patch via email,
but it never hurts to add it when in doubt.
- A one-line description of what the patch does. This message should be
enough for a reader who sees it with no other context to figure out the
scope of the patch; it is the line that will show up in the "short form"
changelogs. This message is usually formatted with the relevant
subsystem name first, followed by the purpose of the patch. For
example:
::
gpio: fix build on CONFIG_GPIO_SYSFS=n
- A blank line followed by a detailed description of the contents of the
patch. This description can be as long as is required; it should say
what the patch does and why it should be applied to the kernel.
- One or more tag lines, with, at a minimum, one Signed-off-by: line from
the author of the patch. Tags will be described in more detail below.
The items above, together, form the changelog for the patch. Writing good
changelogs is a crucial but often-neglected art; it's worth spending
another moment discussing this issue. When writing a changelog, you should
bear in mind that a number of different people will be reading your words.
These include subsystem maintainers and reviewers who need to decide
whether the patch should be included, distributors and other maintainers
trying to decide whether a patch should be backported to other kernels, bug
hunters wondering whether the patch is responsible for a problem they are
chasing, users who want to know how the kernel has changed, and more. A
good changelog conveys the needed information to all of these people in the
most direct and concise way possible.
To that end, the summary line should describe the effects of and motivation
for the change as well as possible given the one-line constraint. The
detailed description can then amplify on those topics and provide any
needed additional information. If the patch fixes a bug, cite the commit
which introduced the bug if possible (and please provide both the commit ID
and the title when citing commits). If a problem is associated with
specific log or compiler output, include that output to help others
searching for a solution to the same problem. If the change is meant to
support other changes coming in later patch, say so. If internal APIs are
changed, detail those changes and how other developers should respond. In
general, the more you can put yourself into the shoes of everybody who will
be reading your changelog, the better that changelog (and the kernel as a
whole) will be.
Needless to say, the changelog should be the text used when committing the
change to a revision control system. It will be followed by:
- The patch itself, in the unified ("-u") patch format. Using the "-p"
option to diff will associate function names with changes, making the
resulting patch easier for others to read.
The tags already briefly mentioned above are used to provide insights how
the patch came into being. They are described in detail in the
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
document; what follows here is a brief summary.
One tag is used to refer to earlier commits which introduced problems fixed by
the patch::
Fixes: 1f2e3d4c5b6a ("The first line of the commit specified by the first 12 characters of its SHA-1 ID")
Another tag is used for linking web pages with additional backgrounds or
details, for example an earlier discussion which leads to the patch or a
document with a specification implemented by the patch::
Link: https://example.com/somewhere.html optional-other-stuff
As per guidance from the Chief Penguin, a Link: tag should only be added to
a commit if it leads to useful information that is not found in the commit
itself.
If the URL points to a public bug report being fixed by the patch, use the
"Closes:" tag instead::
Closes: https://example.com/issues/1234 optional-other-stuff
Some bug trackers have the ability to close issues automatically when a
commit with such a tag is applied. Some bots monitoring mailing lists can
also track such tags and take certain actions. Private bug trackers and
invalid URLs are forbidden.
Another kind of tag is used to document who was involved in the development of
the patch. Each of these uses this format::
tag: Full Name <email address> optional-other-stuff
The tags in common use are:
- Signed-off-by: this is a developer's certification that he or she has
the right to submit the patch for inclusion into the kernel. It is an
agreement to the Developer's Certificate of Origin, the full text of
which can be found in :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
Code without a proper signoff cannot be merged into the mainline.
- Co-developed-by: states that the patch was co-created by several developers;
it is a used to give attribution to co-authors (in addition to the author
attributed by the From: tag) when multiple people work on a single patch.
Every Co-developed-by: must be immediately followed by a Signed-off-by: of
the associated co-author. Details and examples can be found in
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`.
- Acked-by: indicates an agreement by another developer (often a
maintainer of the relevant code) that the patch is appropriate for
inclusion into the kernel.
- Tested-by: states that the named person has tested the patch and found
it to work.
- Reviewed-by: the named developer has reviewed the patch for correctness;
see the reviewer's statement in :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
for more detail.
- Reported-by: names a user who reported a problem which is fixed by this
patch; this tag is used to give credit to the (often underappreciated)
people who test our code and let us know when things do not work
correctly. Note, this tag should be followed by a Closes: tag pointing to
the report, unless the report is not available on the web. The Link: tag
can be used instead of Closes: if the patch fixes a part of the issue(s)
being reported.
- A Suggested-by: tag indicates that the patch idea is suggested by the person
named and ensures credit to the person for the idea. This will, hopefully,
inspire them to help us again in the future.
- Cc: the named person received a copy of the patch and had the
opportunity to comment on it.
Be careful in the addition of the aforementioned tags to your patches, as all
except for Cc:, Reported-by:, and Suggested-by: need explicit permission of the
person named. For those three implicit permission is sufficient if the person
contributed to the Linux kernel using that name and email address according
to the lore archives or the commit history -- and in case of Reported-by:
and Suggested-by: did the reporting or suggestion in public. Note,
bugzilla.kernel.org is a public place in this sense, but email addresses
used there are private; so do not expose them in tags, unless the person
used them in earlier contributions.
Sending the patch
-----------------
Before you mail your patches, there are a couple of other things you should
take care of:
- Are you sure that your mailer will not corrupt the patches? Patches
which have had gratuitous white-space changes or line wrapping performed
by the mail client will not apply at the other end, and often will not
be examined in any detail. If there is any doubt at all, mail the patch
to yourself and convince yourself that it shows up intact.
:ref:`Documentation/process/email-clients.rst <email_clients>` has some
helpful hints on making specific mail clients work for sending patches.
- Are you sure your patch is free of silly mistakes? You should always
run patches through scripts/checkpatch.pl and address the complaints it
comes up with. Please bear in mind that checkpatch.pl, while being the
embodiment of a fair amount of thought about what kernel patches should
look like, is not smarter than you. If fixing a checkpatch.pl complaint
would make the code worse, don't do it.
Patches should always be sent as plain text. Please do not send them as
attachments; that makes it much harder for reviewers to quote sections of
the patch in their replies. Instead, just put the patch directly into your
message.
When mailing patches, it is important to send copies to anybody who might
be interested in it. Unlike some other projects, the kernel encourages
people to err on the side of sending too many copies; don't assume that the
relevant people will see your posting on the mailing lists. In particular,
copies should go to:
- The maintainer(s) of the affected subsystem(s). As described earlier,
the MAINTAINERS file is the first place to look for these people.
- Other developers who have been working in the same area - especially
those who might be working there now. Using git to see who else has
modified the files you are working on can be helpful.
- If you are responding to a bug report or a feature request, copy the
original poster as well.
- Send a copy to the relevant mailing list, or, if nothing else applies,
the linux-kernel list.
- If you are fixing a bug, think about whether the fix should go into the
next stable update. If so, [email protected] should get a copy of
the patch. Also add a "Cc: [email protected]" to the tags within
the patch itself; that will cause the stable team to get a notification
when your fix goes into the mainline.
When selecting recipients for a patch, it is good to have an idea of who
you think will eventually accept the patch and get it merged. While it
is possible to send patches directly to Linus Torvalds and have him merge
them, things are not normally done that way. Linus is busy, and there are
subsystem maintainers who watch over specific parts of the kernel. Usually
you will be wanting that maintainer to merge your patches. If there is no
obvious maintainer, Andrew Morton is often the patch target of last resort.
Patches need good subject lines. The canonical format for a patch line is
something like:
::
[PATCH nn/mm] subsys: one-line description of the patch
where "nn" is the ordinal number of the patch, "mm" is the total number of
patches in the series, and "subsys" is the name of the affected subsystem.
Clearly, nn/mm can be omitted for a single, standalone patch.
If you have a significant series of patches, it is customary to send an
introductory description as part zero. This convention is not universally
followed though; if you use it, remember that information in the
introduction does not make it into the kernel changelogs. So please ensure
that the patches, themselves, have complete changelog information.
In general, the second and following parts of a multi-part patch should be
sent as a reply to the first part so that they all thread together at the
receiving end. Tools like git and quilt have commands to mail out a set of
patches with the proper threading. If you have a long series, though, and
are using git, please stay away from the --chain-reply-to option to avoid
creating exceptionally deep nesting.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
언제 patch를 공개할 것인가
1-31작업이 community review를 받고 최종적으로 mainline kernel에 포함될 준비가 되는 시점이 온다. Kernel development community에는 patch 게시를 위한 관례와 절차가 있으며 이를 따르면 모든 참여자의 작업이 쉬워진다. 추가 정보는 Documentation/process/submitting-patches.rst와 Documentation/process/submit-checklist.rst에 있다.
Patch가 완전히 준비되기 전에는 공개하지 않으려는 유혹이 있다. 단순한 patch라면 문제가 없지만 복잡한 작업은 완료 전에 community feedback을 받는 이점이 크다. 진행 중인 작업을 게시하거나 관심 있는 개발자가 언제든 따라올 수 있도록 git tree를 공개하는 방법을 고려한다.
아직 merge할 준비가 되지 않은 code를 게시할 때에는 그 사실을 message에 분명히 적는다. 남은 주요 작업과 알려진 문제도 설명한다. 완성도가 낮다고 알려진 patch를 보는 사람은 줄겠지만, review하는 사람은 작업을 올바른 방향으로 이끄는 데 도움을 줄 수 있다는 전제로 참여한다.
Patch를 만들기 전에 확인할 사항
34-57- 가능한 범위까지 code를 시험한다. Kernel debugging tool을 사용하고 합리적인 configuration option 조합에서 build되는지 확인하며 cross-compiler로 여러 architecture를 build한다.
- Kernel coding style guideline을 준수하는지 확인한다.
- 성능에 영향이 있다면 변화의 영향 또는 이점을 보여 주는 benchmark를 실행하고 결과 요약을 patch에 포함한다.
- Code를 게시할 권리가 있는지 확인한다. 고용주를 위해 수행한 작업이라면 고용주가 권리를 가질 가능성이 높고 GPL에 따른 공개에 동의해야 한다.
일반적으로 code를 게시하기 전에 조금 더 생각하는 데 쓴 시간은 곧 보상받는다.
Patch가 기준으로 삼을 tree와 release point
60-77게시할 patch를 준비하는 데 예상보다 많은 작업이 들 수 있지만 여기서 시간을 아끼려는 시도는 단기적으로도 좋지 않다.
Patch는 특정 kernel version을 기준으로 만들어야 한다. 일반적으로 Linus의 git tree에 있는 현재 mainline을 기준으로 하되 mainline의 임의 지점에서 branch하지 말고 stable release 또는 -rc release처럼 널리 알려진 release point에서 시작한다.
더 넓은 test와 review를 위해 -mm, linux-next 또는 subsystem tree를 기준으로 version을 만들어야 할 때도 있다. Patch 영역과 다른 개발 상황에 따라 이런 tree를 기준으로 하면 conflict 해결과 API change 대응에 상당한 작업이 필요할 수 있다.
논리적인 patch series로 나누기
79-128아주 단순한 변경만 single patch로 만들고 나머지는 논리적인 change series로 구성한다. Patch 분할은 경험이 필요한 작업이지만 다음 원칙이 도움이 된다.
- 게시하는 series는 working revision control system에 기록된 개발 과정과 거의 확실히 다르다. Community가 원하는 것은 최종 change를 이해하기 좋게 나눈 discrete하고 self-contained한 단위이지 개발자가 그 결과에 도달한 경로가 아니다.
- 논리적으로 독립된 change마다 별도 patch를 만든다. Structure field 하나 추가처럼 작거나 큰 driver 추가처럼 실제 code 양이 많을 수 있지만 개념적으로 작고 한 줄로 설명할 수 있어야 한다. 각 patch는 독립적으로 review하고 설명대로 동작하는지 검증할 수 있는 구체적인 change를 수행해야 한다.
- 서로 다른 종류의 change를 한 patch에 섞지 않는다. Critical security bug fix, structure 재배치, code formatting을 한 patch에 넣으면 review에서 지나쳐 중요한 fix까지 잃을 수 있다.
- 각 patch를 적용한 뒤 kernel이 build되고 정상 동작해야 한다. git bisect로 regression을 찾을 때 series 중간까지만 적용되는 경우가 흔하다. 중간 kernel이 깨지면 문제를 찾는 개발자와 user의 작업이 어려워진다.
- 지나치게 잘게 나누지도 않는다. 한 개발자가 file 하나의 edit를 500개 patch로 보낸 사례처럼 분할 자체가 review를 방해할 수 있다. 하나의 logical change라면 single patch가 상당히 커도 괜찮다.
- 새 infrastructure를 여러 patch로 추가한 뒤 마지막 patch에서야 전부 활성화하는 구성을 가능하면 피한다. Regression이 생기면 bisect는 실제 bug가 앞 patch에 있어도 마지막 enable patch를 원인으로 지목한다. 새 code를 추가하는 patch는 가능한 한 즉시 그 code를 활성화해야 한다.
완벽한 patch series를 만드는 과정은 실제 기능 구현이 끝난 뒤에도 많은 시간과 사고를 요구해 답답할 수 있지만 올바르게 수행하면 가치 있는 작업이다.
Patch message와 changelog 구성
131-192각 patch는 목적을 빠르고 명확하게 전달하는 message로 format해야 한다.
- 선택적인 From line: 다른 사람의 patch를 email로 전달할 때 author를 나타낸다. 확신이 없을 때 추가해도 해가 없다.
- Patch가 하는 일을 설명하는 한 줄 summary: 다른 맥락 없이 읽어도 범위를 알 수 있어야 하며 short-form changelog에 나타난다. 보통 subsystem 이름을 먼저 쓰고 patch 목적을 적는다.
- Blank line 뒤의 상세 설명: 필요한 만큼 길게 작성하며 patch가 무엇을 하고 왜 kernel에 적용해야 하는지 설명한다.
- 하나 이상의 tag line: 최소한 patch author의 Signed-off-by 한 줄이 필요하다.
gpio: fix build on CONFIG_GPIO_SYSFS=n
이 요소를 합쳐 patch changelog를 만든다. Changelog는 subsystem maintainer와 reviewer, 다른 kernel로 backport할지 판단하는 distributor와 maintainer, bug 원인을 찾는 사람, kernel 변화가 궁금한 user 등 다양한 독자가 읽는다. 필요한 정보를 직접적이고 간결하게 전달해야 한다.
Summary line은 한 줄 제한 안에서 change의 효과와 동기를 최대한 잘 설명한다. 상세 설명은 이를 확장하고 필요한 추가 정보를 제공한다. Bug fix라면 가능할 때 bug를 만든 commit의 ID와 title을 함께 적는다. 특정 log 또는 compiler output과 관련된 문제면 같은 문제를 검색하는 사람을 위해 output을 포함한다.
뒤 patch의 change를 지원하기 위한 patch라면 그 사실을 말한다. Internal API를 바꾼다면 change와 다른 developer가 대응할 방법을 자세히 적는다. Changelog를 읽을 모든 사람의 입장을 고려할수록 changelog와 kernel 전체가 좋아진다.
Changelog는 revision control system에 commit할 때도 같은 text를 사용해야 한다. 그 뒤 unified(-u) format의 patch 본문이 온다. diff의 -p option을 사용하면 change에 function 이름이 연결되어 읽기 쉬워진다.
Fixes, Link, Closes tag
194-222Tag는 patch가 만들어진 배경을 기록한다. 자세한 규칙은 Documentation/process/submitting-patches.rst에 있고 여기서는 핵심을 요약한다.
Fixes는 현재 patch가 수정하는 문제를 도입한 이전 commit을 가리킨다.
Fixes: 1f2e3d4c5b6a ("The first line of the commit specified by the first 12 characters of its SHA-1 ID")
Link는 patch로 이어진 이전 discussion이나 구현한 specification처럼 추가 배경과 상세 정보가 있는 web page를 연결한다.
Link: https://example.com/somewhere.html optional-other-stuff
Chief Penguin의 지침에 따라 commit 자체에 없는 유용한 정보로 연결될 때만 Link를 추가한다. URL이 patch로 수정하는 public bug report라면 Closes를 사용한다.
Closes: https://example.com/issues/1234 optional-other-stuff
일부 bug tracker는 해당 tag가 있는 commit이 적용되면 issue를 자동으로 닫는다. Mailing list를 감시하는 bot도 tag를 추적해 동작할 수 있다. Private bug tracker와 유효하지 않은 URL은 사용할 수 없다.
개발 참여자를 기록하는 tag
224-278tag: Full Name <email address> optional-other-stuff
| tag | 의미와 조건 |
|---|---|
| Signed-off-by | Developer가 patch를 kernel에 제출할 권리가 있음을 인증하고 Developer's Certificate of Origin에 동의한다. 올바른 sign-off가 없는 code는 mainline에 merge할 수 없다. |
| Co-developed-by | 여러 developer가 patch를 공동 작성했음을 나타내고 From에 적힌 author 외 co-author에게도 credit을 준다. 각 Co-developed-by 바로 뒤에는 해당 co-author의 Signed-off-by가 와야 한다. |
| Acked-by | 다른 developer, 흔히 관련 code maintainer가 kernel inclusion에 적합하다고 동의했음을 뜻한다. |
| Tested-by | 기재된 사람이 patch를 시험하여 동작함을 확인했다. |
| Reviewed-by | 기재된 developer가 patch의 정확성을 review했다. |
| Reported-by | Patch가 고치는 문제를 신고한 user에게 credit을 준다. Web report가 없다면 예외지만 보통 report의 Closes가 뒤따라야 한다. 신고 issue 일부만 고치면 Closes 대신 Link를 쓸 수 있다. |
| Suggested-by | Patch idea를 제안한 사람에게 credit을 주며 향후 기여를 장려한다. |
| Cc | 기재된 사람이 patch 사본을 받아 comment할 기회가 있었음을 뜻한다. |
Cc, Reported-by, Suggested-by를 제외한 tag에는 기재되는 사람의 명시적 허락이 필요하다. 세 tag는 lore archive 또는 commit history에서 그 사람이 같은 이름과 email로 Linux kernel에 기여했고, Reported-by와 Suggested-by의 경우 public에서 신고 또는 제안했다면 묵시적 허락으로 충분하다.
bugzilla.kernel.org는 이 의미에서 public place지만 그곳에 쓴 email address는 private다. 그 사람이 이전 기여에서 같은 address를 사용하지 않았다면 tag로 공개해서는 안 된다.
전송 직전 patch 무결성과 checkpatch 확인
281-306Mailer가 patch를 손상하지 않는지 확인한다. Client가 불필요한 whitespace change나 line wrapping을 적용하면 수신 측에서 patch가 적용되지 않고 상세 review도 받지 못할 가능성이 높다. 조금이라도 의심되면 자신에게 보내서 원형 그대로 도착하는지 확인한다. Client별 설정은 Documentation/process/email-clients.rst를 참조한다.
Patch를 scripts/checkpatch.pl로 검사하고 지적 사항을 검토한다. checkpatch.pl에는 kernel patch 형태에 관한 많은 경험이 반영되어 있지만 사람보다 현명한 것은 아니다. Warning을 고치는 것이 code를 더 나쁘게 만든다면 그대로 따르지 않는다.
scripts/checkpatch.pl <patch-file>
Patch는 항상 plain text로 보내고 attachment로 보내지 않는다. Reviewer가 reply에서 patch 일부를 quote하기 어렵기 때문이다. Patch를 message body에 직접 넣는다.
Patch recipient 선택
308-339Patch에 관심을 가질 수 있는 사람에게 모두 사본을 보내는 것이 중요하다. 다른 project와 달리 kernel은 너무 적게 보내는 것보다 다소 많이 보내는 쪽을 권장한다. 관련자가 mailing list에서 알아서 볼 것이라고 가정하지 않는다.
- 영향받는 subsystem의 maintainer. MAINTAINERS file에서 먼저 찾는다.
- 같은 영역에서 작업했거나 현재 작업 중일 수 있는 다른 developer. git history로 대상 file을 수정한 사람을 확인할 수 있다.
- Bug report 또는 feature request에 대한 응답이면 original poster.
- 관련 mailing list. 해당 list가 없다면 linux-kernel list.
- Bug fix가 다음 stable update에 들어가야 한다면 [email protected]에도 보내고 patch tag에 Cc: [email protected]를 추가한다. Mainline merge 시 stable team이 notification을 받는다.
Recipient를 고를 때 최종적으로 누가 patch를 받아 merge할 것인지 생각해야 한다. Linus Torvalds에게 직접 보내 merge를 요청할 수는 있지만 일반적인 경로는 아니다. Linus는 매우 바쁘고 각 영역은 subsystem maintainer가 관리한다. 보통 그 maintainer가 patch를 merge하게 해야 한다. 명확한 maintainer가 없다면 Andrew Morton이 최후의 patch target이 되는 경우가 많다.
Subject 형식, cover letter, thread
341-363Patch에는 좋은 subject line이 필요하다. 표준적인 형식은 다음과 같다.
[PATCH nn/mm] subsys: one-line description of the patch
nn은 series 안의 patch 순번, mm은 전체 patch 수, subsys는 영향받는 subsystem 이름이다. 독립된 single patch라면 nn/mm을 생략할 수 있다.
큰 patch series에는 part zero로 소개 설명을 보내는 관례가 있다. 항상 지켜지는 것은 아니며 cover letter의 정보는 kernel changelog에 들어가지 않는다. 각 patch 자체에 완전한 changelog가 있어야 한다.
Multi-part patch의 두 번째 이후 message는 일반적으로 첫 part에 reply하여 수신 측에서 같은 thread로 묶이게 한다. git과 quilt에는 올바른 threading으로 series를 보내는 command가 있다. 긴 series를 git으로 보낼 때에는 지나치게 깊은 nesting을 만들지 않도록 --chain-reply-to option을 피한다.
Patch 게시 관행
5.Posting.rst:3-15작업이 review와 mainline 포함을 논의할 수준이 되면 kernel community의 patch 게시 관행을 따라야 한다. 이 관행은 형식 자체가 목적이 아니라 reviewer가 많은 변경을 빠르게 분류·이해·적용하게 하기 위한 것이다.