diff options
58 files changed, 5498 insertions, 328 deletions
diff --git a/Documentation/ABI/README b/Documentation/ABI/README index 315fffe1f831..27c962e6a872 100644 --- a/Documentation/ABI/README +++ b/Documentation/ABI/README @@ -62,7 +62,7 @@ Users: All users of this interface who wish to be notified when Note: - The fields should be use a simple notation, compatible with ReST markup. + The fields should use a simple notation, compatible with ReST markup. Also, the file **should not** have a top-level index, like:: === diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 67b74c50355f..35a170dcb8f2 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1614,10 +1614,17 @@ Kernel parameters on all PCI bridges while in the EFI boot stub efi_no_storage_paranoia [EFI,X86,EARLY] - Using this parameter you can use more than 50% of - your efi variable storage. Use this parameter only if - you are really sure that your UEFI does sane gc and - fulfills the spec otherwise your board may brick. + The kernel reserves 5KB of EFI variable storage for + safety, because some UEFI implementation may fail to + boot if there's insufficient space in the EFI variable + storage. + + Using this parameter, you can use the 5KB reservation + in the EFI variable storage. + + However, Use this parameter only if you are really + sure that your UEFI does sane gc and fulfills the spec + otherwise your board may brick. efivar_ssdt= [EFI; X86] Name of an EFI variable that contains an SSDT that is to be dynamically loaded by Linux. If there are @@ -6422,9 +6429,9 @@ Kernel parameters reboot= [KNL] Format (x86 or x86_64): [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] | d[efault] \ - [[,]s[mp]#### \ + [[,]s[mp]####] \ [[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \ - [[,]f[orce] + [[,]f[orce]] Where reboot_mode is one of warm (soft) or cold (hard) or gpio (prefix with 'panic_' to set mode for panic reboot only), @@ -6884,7 +6891,7 @@ Kernel parameters xtime_lock contention on larger systems, and/or RCU lock contention on all systems with CONFIG_MAXSMP set. Format: { "0" | "1" } - 0 -- disable. (may be 1 via CONFIG_CMDLINE="skew_tick=1" + 0 -- disable. (may be 1 via CONFIG_CMDLINE="skew_tick=1") 1 -- enable. Note: increases power consumption, thus should only be enabled if running jitter sensitive (HPC/RT) workloads. @@ -6925,7 +6932,7 @@ Kernel parameters apic=verbose is specified. Example: apic=debug show_lapic=all - slab_debug[=options[,slabs][;[options[,slabs]]...] [MM] + slab_debug[=options[,slabs][;[options[,slabs]]...]] [MM] Enabling slab_debug allows one to determine the culprit if slab objects become corrupted. Enabling slab_debug can create guard zones around objects and diff --git a/Documentation/admin-guide/media/bttv.rst b/Documentation/admin-guide/media/bttv.rst index 58cbaf6df694..78c3e560b806 100644 --- a/Documentation/admin-guide/media/bttv.rst +++ b/Documentation/admin-guide/media/bttv.rst @@ -1239,7 +1239,7 @@ Models: - Galaxis DVB Card C CI - Galaxis DVB Card S - Galaxis DVB Card C -- Galaxis plug.in S [neuer Name: Galaxis DVB Card S CI +- Galaxis plug.in S [new Name: Galaxis DVB Card S CI] Hauppauge ~~~~~~~~~ diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst index ffa690a171c8..77447c454632 100644 --- a/Documentation/admin-guide/mm/pagemap.rst +++ b/Documentation/admin-guide/mm/pagemap.rst @@ -70,7 +70,7 @@ number of times a page is mapped. * ``/proc/kpageflags``. This file contains a 64-bit set of flags for each page, indexed by PFN. - The flags are (from ``fs/proc/page.c``, above kpageflags_read): + The flags are (from ``include/uapi/linux/kernel-page-flags.h``): 0. LOCKED 1. ERROR @@ -271,7 +271,7 @@ The ``struct pm_scan_arg`` is used as the argument of the IOCTL. provided or not. 3. The range is specified through ``start`` and ``end``. 4. The walk can abort before visiting the complete range such as the user buffer - can get full etc. The walk ending address is specified in``end_walk``. + can get full etc. The walk ending address is specified in ``walk_end``. 5. The output buffer of ``struct page_region`` array and size is specified in ``vec`` and ``vec_len``. 6. The optional maximum requested pages are specified in the ``max_pages``. @@ -282,7 +282,7 @@ Find pages which have been written and WP them as well:: struct pm_scan_arg arg = { .size = sizeof(arg), - .flags = PM_SCAN_CHECK_WPASYNC | PM_SCAN_CHECK_WPASYNC, + .flags = PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC, .. .category_mask = PAGE_IS_WRITTEN, .return_mask = PAGE_IS_WRITTEN, @@ -295,7 +295,7 @@ present or huge:: .size = sizeof(arg), .flags = 0, .. - .category_mask = PAGE_IS_WRITTEN | PAGE_IS_SWAPPED, + .category_mask = PAGE_IS_WRITTEN | PAGE_IS_FILE, .category_inverted = PAGE_IS_SWAPPED, .category_anyof_mask = PAGE_IS_PRESENT | PAGE_IS_HUGE, .return_mask = PAGE_IS_WRITTEN | PAGE_IS_SWAPPED | diff --git a/Documentation/conf.py b/Documentation/conf.py index 9b822ab470d9..3f82cfbff778 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -61,12 +61,12 @@ manpages_url = 'https://man7.org/linux/man-pages/man{section}/{page}.{section}.h def config_init(app, config): """ - Initialize path-dependent variabled + Initialize path-dependent variables On Sphinx, all directories are relative to what it is passed as SOURCEDIR parameter for sphinx-build. Due to that, all patterns that have directory names on it need to be dynamically set, after - converting them to a relative patch. + converting them to a relative path. As Sphinx doesn't include any patterns outside SOURCEDIR, we should exclude relative patterns that start with "../". diff --git a/Documentation/core-api/SMP.rst b/Documentation/core-api/SMP.rst new file mode 100644 index 000000000000..0265a9835f23 --- /dev/null +++ b/Documentation/core-api/SMP.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +============== +SMP primitives +============== + +.. kernel-doc:: include/linux/smp.h + :internal: + +.. kernel-doc:: kernel/smp.c + :export: diff --git a/Documentation/core-api/dma-api.rst b/Documentation/core-api/dma-api.rst index ca75b3541679..ba23a472f794 100644 --- a/Documentation/core-api/dma-api.rst +++ b/Documentation/core-api/dma-api.rst @@ -508,7 +508,7 @@ call to dma_iova_try_alloc. This can be useful in the unmap path. Is used to link ranges to the IOVA previously allocated. The start of all but the first call to dma_iova_link for a given state must be aligned -to the DMA merge boundary returned by ``dma_get_merge_boundary())``, and +to the DMA merge boundary returned by ``dma_get_merge_boundary()``, and the size of all but the last range must be aligned to the DMA merge boundary as well. diff --git a/Documentation/core-api/errseq.rst b/Documentation/core-api/errseq.rst index ff332e272405..d298d4cd2f60 100644 --- a/Documentation/core-api/errseq.rst +++ b/Documentation/core-api/errseq.rst @@ -143,7 +143,7 @@ Because of this, it's often advantageous to first do an errseq_check to see if anything has changed, and only later do an errseq_check_and_advance after taking the lock. e.g.:: - if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err)) { + if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err))) { /* su.s_wd_err is protected by s_wd_err_lock */ spin_lock(&su.s_wd_err_lock); err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index 13769d5c40bf..92f91c6a0d79 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -81,6 +81,7 @@ Documentation/locking/index.rst for more related documentation. padata ../RCU/index wrappers/memory-barriers.rst + SMP Low-level hardware management ============================= diff --git a/Documentation/core-api/list.rst b/Documentation/core-api/list.rst index 479aa91cc395..df8b078bb366 100644 --- a/Documentation/core-api/list.rst +++ b/Documentation/core-api/list.rst @@ -458,7 +458,7 @@ The list_move() and list_move_tail() functions can be used to move an entry from one list to another, to either the start or end respectively. In the following example, we'll assume we start with two lists ("clowns" and -"sidewalk" in the following initial state "State 0":: +"sidewalk") in the following initial state "State 0":: .----------------------------------------------------------------. v | diff --git a/Documentation/core-api/min_heap.rst b/Documentation/core-api/min_heap.rst index 9f57766581df..919dcf1bdec7 100644 --- a/Documentation/core-api/min_heap.rst +++ b/Documentation/core-api/min_heap.rst @@ -240,19 +240,6 @@ This macro returns `true` if the heap is full, otherwise `false`. **Inline Version:** min_heap_full_inline(heap) -- **min_heap_empty(heap)**: Checks whether the heap is empty. - Complexity: **O(1)**. - -.. code-block:: c - - bool empty = min_heap_empty(heap); - -- `heap`: A pointer to the min-heap to check. - -This macro returns `true` if the heap is empty, otherwise `false`. - -**Inline Version:** min_heap_empty_inline(heap) - Example Usage ============= diff --git a/Documentation/core-api/packing.rst b/Documentation/core-api/packing.rst index f68f1e08fef9..cff1a262efce 100644 --- a/Documentation/core-api/packing.rst +++ b/Documentation/core-api/packing.rst @@ -330,7 +330,7 @@ Here is an example of how to use the fields APIs: void unpack_your_data(const packed_buf_t *buf, struct data *unpacked) { - BUILD_BUG_ON(sizeof(*buf) != SIZE; + BUILD_BUG_ON(sizeof(*buf) != SIZE); unpack_fields(buf, sizeof(*buf), unpacked, fields, QUIRK_LITTLE_ENDIAN); @@ -338,7 +338,7 @@ Here is an example of how to use the fields APIs: void pack_your_data(const struct data *unpacked, packed_buf_t *buf) { - BUILD_BUG_ON(sizeof(*buf) != SIZE; + BUILD_BUG_ON(sizeof(*buf) != SIZE); pack_fields(buf, sizeof(*buf), unpacked, fields, QUIRK_LITTLE_ENDIAN); diff --git a/Documentation/dev-tools/container.rst b/Documentation/dev-tools/container.rst index 452415b64662..9e23f79d5ae1 100644 --- a/Documentation/dev-tools/container.rst +++ b/Documentation/dev-tools/container.rst @@ -40,7 +40,7 @@ Available options: ``-r, --runtime RUNTIME`` - Container runtime name. Supported runtimes: ``docker``, ``podman``. + Container runtime name. Supported runtimes: ``podman``, ``docker``. If not specified, the first one found on the system will be used i.e. Podman if present, otherwise Docker. @@ -75,8 +75,8 @@ working directory and adjust the user and group id as needed. The container image which would typically include a compiler toolchain is provided by the user and selected via the ``-i`` option. The container runtime -can be selected with the ``-r`` option, which can be either ``docker`` or -``podman``. If none is specified, the first one found on the system will be +can be selected with the ``-r`` option, which can be either ``podman`` or +``docker``. If none is specified, the first one found on the system will be used while giving priority to Podman. Support for other runtimes may be added later depending on their popularity among users. diff --git a/Documentation/driver-api/usb/writing_usb_driver.rst b/Documentation/driver-api/usb/writing_usb_driver.rst index 95c4f5d14052..6f024e1647cd 100644 --- a/Documentation/driver-api/usb/writing_usb_driver.rst +++ b/Documentation/driver-api/usb/writing_usb_driver.rst @@ -322,7 +322,4 @@ http://linux-hotplug.sourceforge.net/ linux-usb Mailing List Archives: https://lore.kernel.org/linux-usb/ -Programming Guide for Linux USB Device Drivers: -https://lmu.web.psi.ch/docu/manuals/software_manuals/linux_sl/usb_linux_programming_guide.pdf - USB Home Page: https://www.usb.org diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 1a29a5afabd7..16c35b491dad 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -123,8 +123,7 @@ At mount time, the two directories given as mount options "lowerdir" and mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\ workdir=/work /merged -The "workdir" needs to be an empty directory on the same filesystem -as upperdir. +The "workdir" needs to be a directory on the same filesystem as upperdir. Then whenever a lookup is requested in such a merged directory, the lookup is performed in each actual directory and the combined result diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 27189f6e004e..c102b62023cd 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -513,7 +513,7 @@ In some kernel configurations, the semantics of pages part of a larger allocation (e.g., THP) can differ: a page is accounted as "private" if all pages part of the corresponding large allocation are *certainly* mapped in the same process, even if the page is mapped multiple times in that process. A -page is accounted as "shared" if any page page of the larger allocation +page is accounted as "shared" if any page of the larger allocation is *maybe* mapped in a different process. In some cases, a large allocation might be treated as "maybe mapped by multiple processes" even though this is no longer the case. diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst index c969c76ef7cb..23fd393c8193 100644 --- a/Documentation/kernel-hacking/locking.rst +++ b/Documentation/kernel-hacking/locking.rst @@ -471,7 +471,7 @@ to protect the cache and all the objects within it. Here's the code:: obj = __cache_find(id); if (obj) { ret = 0; - strcpy(name, obj->name); + strscpy(name, obj->name); } mutex_unlock(&cache_lock); return ret; @@ -553,7 +553,7 @@ which are taken away, and the ``+`` are lines which are added. obj = __cache_find(id); if (obj) { ret = 0; - strcpy(name, obj->name); + strscpy(name, obj->name); } - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); @@ -676,7 +676,7 @@ Here is the code:: obj = __cache_find(id); - if (obj) { - ret = 0; - - strcpy(name, obj->name); + - strscpy(name, obj->name); - } + if (obj) + __object_get(obj); @@ -1317,7 +1317,7 @@ from user context, and can sleep. - put_user() -- kmalloc(GP_KERNEL) <kmalloc>` +- kmalloc(GFP_KERNEL) <kmalloc> - mutex_lock_interruptible() and mutex_lock() diff --git a/Documentation/process/coding-assistants.rst b/Documentation/process/coding-assistants.rst index 899f4459c52d..6125ee4914c5 100644 --- a/Documentation/process/coding-assistants.rst +++ b/Documentation/process/coding-assistants.rst @@ -15,6 +15,10 @@ kernel development process: * Documentation/process/coding-style.rst * Documentation/process/submitting-patches.rst +For guidelines on content generated by AI coding assistants see: + +* Documentation/process/generated-content.rst + Licensing and Legal Requirements ================================ diff --git a/Documentation/process/generated-content.rst b/Documentation/process/generated-content.rst index 08621e50a462..aad2caad9f8b 100644 --- a/Documentation/process/generated-content.rst +++ b/Documentation/process/generated-content.rst @@ -107,3 +107,10 @@ the resulting changes. If you do so anyway, maintainers are entitled to reject your series without detailed review. + +References +========== + +For specific guidelines on AI coding assistants, see: + +* Documentation/process/coding-assistants.rst diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index cc6a1f73d7f2..7ae79452e1b4 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -404,12 +404,11 @@ patches that are being emailed around. The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you -can certify the below: +can certify the below:: -Developer's Certificate of Origin 1.1 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Developer's Certificate of Origin 1.1 -By making a contribution to this project, I certify that: + By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license @@ -554,12 +553,11 @@ some testing has been performed, provides a means to locate testers for future patches, and ensures credit for the testers. Reviewed-by:, instead, indicates that the patch has been reviewed and found -acceptable according to the Reviewer's Statement: +acceptable according to the Reviewer's Statement:: -Reviewer's statement of oversight -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Reviewer's statement of oversight -By offering my Reviewed-by: tag, I state that: + By offering my Reviewed-by: tag, I state that: (a) I have carried out a technical review of this patch to evaluate its appropriateness and readiness for inclusion into diff --git a/Documentation/scheduler/sched-energy.rst b/Documentation/scheduler/sched-energy.rst index 4e47aaf103eb..83bac0da4869 100644 --- a/Documentation/scheduler/sched-energy.rst +++ b/Documentation/scheduler/sched-energy.rst @@ -141,7 +141,7 @@ in its previous activation. find_energy_efficient_cpu() uses compute_energy() to estimate what will be the energy consumed by the system if the waking task was migrated. compute_energy() looks at the current utilization landscape of the CPUs and adjusts it to -'simulate' the task migration. The EM framework provides the em_pd_energy() API +'simulate' the task migration. The EM framework provides the em_cpu_energy() API which computes the expected energy consumption of each performance domain for the given utilization landscape. diff --git a/Documentation/scheduler/sched-pelt.c b/Documentation/scheduler/sched-pelt.c index 7238b355919c..38ff53dcf352 100644 --- a/Documentation/scheduler/sched-pelt.c +++ b/Documentation/scheduler/sched-pelt.c @@ -25,7 +25,8 @@ void calc_runnable_avg_yN_inv(void) for (i = 0; i < HALFLIFE; i++) { x = ((1UL<<32)-1)*pow(y, i); - if (i % 6 == 0) printf("\n\t"); + if (i % 6 == 0) + printf("\n\t"); printf("0x%8x, ", x); } printf("\n};\n\n"); diff --git a/Documentation/sphinx-static/custom.css b/Documentation/sphinx-static/custom.css index 5aa0a1ed9864..be33d9ed1280 100644 --- a/Documentation/sphinx-static/custom.css +++ b/Documentation/sphinx-static/custom.css @@ -3,6 +3,8 @@ * CSS tweaks for the Alabaster theme */ +div.body { max-width: 120em; } + /* Shrink the headers a bit */ div.body h1 { font-size: 180%; } div.body h2 { font-size: 150%; } @@ -156,15 +158,6 @@ div.language-selection ul li:hover { background: #dddddd; } -/* - * Let long inline literals in paragraph text wrap as needed to prevent - * overflow. - */ -code.docutils.literal span.pre { - white-space: normal; - overflow-wrap: anywhere; -} - /* Let rendered reference links in tables wrap when needed. */ div.body table.docutils a.reference { overflow-wrap: anywhere; diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index dc9f9e188ffa..7ffe19b5ed58 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -161,7 +161,7 @@ class MaintainersParser: html = KERNELDOC_URL + ename + ".html" entries[entry] = f'`{ename} <{html}>`_' else: - entries[entry] = f':doc:`{ename} </{entry}>`' + entries[entry] = f'/{entry}' return entries @@ -345,7 +345,10 @@ class MaintainersProfile(Include): output += f"- {name}: {entry}\n" self.warning(f"{profile}: Invalid 'P' tag: {entry}\n") else: - output += f"- {entry}\n" + if not name: + name = entry + + output += f"- :doc:`{name} <{entry}>`\n" # # Create a hidden TOC table with all profiles. That allows adding diff --git a/Documentation/translations/ja_JP/process/submitting-patches.rst b/Documentation/translations/ja_JP/process/submitting-patches.rst index d31d469909e4..22d54b663051 100644 --- a/Documentation/translations/ja_JP/process/submitting-patches.rst +++ b/Documentation/translations/ja_JP/process/submitting-patches.rst @@ -182,7 +182,7 @@ URL は禁止です。 変更を分割する -------------- -各 **論理的な変更** は、個別のパッチに分けてください。 +それぞれの\ **論理的な変更**\ は、個別のパッチに分けてください。 たとえば、単一のドライバに対する変更にバグ修正と性能改善の 両方が含まれるなら、それらは 2 つ以上のパッチに分けてください。 @@ -208,7 +208,7 @@ URL は禁止です。 ことがあります。途中でバグを持ち込めば、彼らに感謝されることは ないでしょう。 -パッチセットをこれ以上小さくできないなら、一度に投稿するのは +パッチセットをそれ以上小さくできないなら、一度に投稿するのは 15 個程度までにして、レビューと統合を待ってください。 @@ -220,18 +220,17 @@ Documentation/process/coding-style.rst を参照してください。 これを怠ると、単にレビューアの時間を無駄にするだけでなく、 パッチはおそらく読まれもせずに却下されます。 -大きな例外が 1 つあります。コードをあるファイルから別の -ファイルへ移動する場合です。このときは、コードを移動する -その同じパッチの中で、移動したコードを一切変更してはいけません。 -そうすることで、コードの移動という行為と、あなたの変更とを -明確に区別できます。これは実際の差分のレビューを大いに助け、 -ツールがコード自体の履歴をより適切に追跡できるようにします。 +一つの重要な例外は、コードをあるファイルから別のファイルへ移動する場合です。 +その際は、コードを移動するその同じパッチの中で、一切コードを変更しては +いけません。これにより、コードの移動という行為と、コードの変更とが +明確に区別されます。これは実際の差分のレビューを大いに助け、また、ツールを +使ったコード変更の履歴の追跡を容易にします。 提出前に、パッチスタイルチェッカー (``scripts/checkpatch.pl``) でパッチを確認してください。 -ただし、スタイルチェッカーは指針として見るべきであり、 +ただし、スタイルチェッカーは指針にすぎず、 人間の判断に取って代わるものではないことに注意してください。 -違反があっても、その方がコードの見栄えがよいなら、 +違反が指摘されるままのコードの方が見栄えがよいなら、おそらく そのままにしておくのが最善でしょう。 チェッカーは 3 つのレベルで報告します: @@ -240,8 +239,7 @@ Documentation/process/coding-style.rst を参照してください。 - WARNING: 慎重なレビューを要するもの - CHECK: 検討を要するもの -パッチに残した違反については、すべて理由を説明できなければ -なりません。 +パッチに違反を残す場合は、そのすべてを正当化できなければなりません。 パッチの宛先を選択する @@ -256,8 +254,8 @@ Documentation/process/coding-style.rst を参照してください。 サブシステムのメンテナが見つからない場合は、Andrew Morton (akpm@linux-foundation.org) が最後の手段となるメンテナです。 -すべてのパッチでは、デフォルトで linux-kernel@vger.kernel.org を -使うべきですが、このリストの流量が多いため、目を通さなくなった +すべてのパッチは、デフォルトで linux-kernel@vger.kernel.org にも +送られるべきですが、このリストは流量が多く、目を通さなくなった 開発者も少なくありません。とはいえ、無関係なメーリングリストや 無関係な人々にスパムを送らないでください。 @@ -268,103 +266,104 @@ Documentation/process/coding-style.rst を参照してください。 Linux カーネルに採用されるすべての変更の最終的な裁定者は Linus Torvalds です。彼のメールアドレスは <torvalds@linux-foundation.org> です。Linus は大量のメールを -受け取っており、現時点では彼に直接届くパッチはごくわずかなので、 -通常は彼にメールを送ることを極力避けてください。 +受け取っており、現時点では直接彼を経由するパッチはごくわずかなので、 +通常は彼にメールを送ることを極力\ **避けて**\ ください。 -悪用可能なセキュリティバグを修正するパッチがあるなら、 -そのパッチを security@kernel.org に送ってください。深刻なバグに +悪用可能なセキュリティバグを修正するパッチの場合は、 +それを security@kernel.org に送ってください。深刻なバグに ついては、ディストリビュータがユーザーにパッチを配布できるよう、 -短期間の embargo が検討される場合があります。そのような場合、 -そのパッチを公開メーリングリストに送るべきではありません。 +短期間の秘匿措置 (訳註: embargo) が検討される可能性があります。 +ですので、その種のパッチを公開メーリングリストに送らないでください。 Documentation/process/security-bugs.rst も参照してください。 リリース済みカーネルの深刻なバグを修正するパッチは、次のような行を -パッチの sign-off 欄に入れることで、stable メンテナへ向けてください:: +パッチの sign-off 欄に入れることで、stable メンテナに知らせてください。 +(メールの宛先ではないことに注意。) :: Cc: stable@vger.kernel.org -これはメールの受信者ではないことに注意してください。また、 -この文書に加えて Documentation/process/stable-kernel-rules.rst も -読んでください。 +また、この文書に加えて Documentation/process/stable-kernel-rules.rst +も読んでください。 変更がユーザーランドとカーネルのインターフェースに影響する場合は、 MAINTAINERS ファイルに記載されている MAN-PAGES メンテナに -man-pages パッチ、少なくとも変更の通知を送って、情報が -マニュアルページに反映されるようにしてください。ユーザー空間 API の +マニュアルページのパッチ、もしくは少なくとも変更の通知を送って、情報が +そちらにも反映されるようにしてください。ユーザー空間 API の 変更は、linux-api@vger.kernel.org にも Cc してください。 MIME・リンク・圧縮・添付なし、プレーンテキストのみ ---------------------------------------------------- Linus や他のカーネル開発者は、あなたが投稿する変更を読み、 -コメントできる必要があります。カーネル開発者が標準的な -メールツールを使ってあなたの変更を「引用」し、コードの特定の -箇所についてコメントできることが重要です。 +コメントできる必要があります。カーネル開発者にとって、コードの特定の +箇所について、標準的なメールツールを使ってあなたの変更を「引用」し、 +コメントできることが重要です。 -このため、すべてのパッチはメール本文中に ``inline`` で投稿すべきです。 +このため、すべてのパッチはメール本文中に「インライン」で投稿すべきです。 これを行う最も簡単な方法は ``git send-email`` を使うことであり、 強く推奨されます。``git send-email`` の対話型チュートリアルは -https://git-send-email.io で利用できます。 +https://git-send-email.io にあります。 -``git send-email`` を使わないことを選ぶ場合: +``git send-email`` を使わない場合: .. warning:: - パッチをコピー&ペーストする場合は、エディタの word-wrap によって - パッチが壊れないよう注意してください。 + パッチをコピー&ペーストする際に、エディタによる自動改行で + パッチが壊されないよう注意してください。 圧縮の有無にかかわらず、パッチを MIME 添付ファイルとして添付しては -いけません。多くの一般的なメールアプリケーションは、MIME 添付 -ファイルを常にプレーンテキストとして送信するとは限らず、あなたの -コードにコメントできなくなります。MIME 添付ファイルは Linus が -処理するのにも少し余分な時間がかかるため、MIME 添付された変更が -受け入れられる可能性を下げます。 +いけません。よく使われるメールアプリケーションの多くは、MIME 添付 +ファイルをプレーンテキストとして送信するとは限らず、あなたのコードに +対するコメントを妨げます。MIME 添付ファイルは Linus (訳補: をはじめ +とする開発者)が処理するのに余分な手間がかかるため、MIME 添付すると +その変更が受け入れられる可能性を下げることになります。 -例外: メーラがパッチを壊してしまう場合は、誰かから MIME を使って -再送するよう求められることがあります。 +例外: パッチがメーラーによって壊されている場合に、MIME による再送 +を求められることがあります。 -パッチを変更せずに送信するようメールクライアントを設定するための -ヒントについては、Documentation/process/email-clients.rst を参照してください。 +改変なしにパッチを送信するためのメールクライアント設定のヒントは、 +Documentation/process/email-clients.rst を参照してください。 -レビューコメントに返答する +レビューコメントに応答する -------------------------- -あなたのパッチには、ほぼ確実に、パッチを改善する方法について -レビューアからコメントが付きます。それは、あなたのメールへの返信という -形で届きます。それらのコメントには必ず返答してください。レビューアを -無視することは、こちらも無視されるためのよい方法です。コメントに -答えるには、単にそのメールへ返信すれば構いません。コード変更に +あなたのパッチには、ほぼ確実に、その改善に向けてレビューアから +コメントが付きます。それは、あなたのメールへの返信という +形で届きます。それらのコメントには必ず応答してください。レビューアを +無視することは、あなたが無視されることにつながります。コメントに +答えるには、単にそのメールへ返信すればよいです。コード変更に つながらないレビューコメントや質問であっても、次のレビューアが状況を -よりよく理解できるように、ほぼ確実にコメントまたは changelog エントリに -反映すべきです。 - -どのような変更を行うのかをレビューアに必ず伝え、時間を割いてくれた -ことに感謝してください。コードレビューは疲れる、時間のかかる作業であり、 -レビューアが不機嫌になることもあります。そのような場合であっても、 -丁寧に返答し、指摘された問題に対応してください。次の版を送るときは、 -cover letter または個々のパッチに ``patch changelog`` を追加し、前回の +よりよく理解できるよう、多くの場合、コメントまたは changelog エントリ +として残すべきです。 + +どのような変更を行うのかを忘れずにレビューアに伝えてください。そして +時間を割いてくれることへの感謝を忘れないでください。 +コードレビューは疲れる、時間のかかる作業であり、 +ときにはレビューアが機嫌を損ねることもあります。そのような場合でも、 +丁寧に応答し、指摘された問題に対応してください。次の版を送る際には、 +カバーレターまたは個々のパッチに ``patch changelog`` を追加し、前回の 投稿との差分を説明してください。詳細は原文の該当節 ("The canonical patch format") を参照してください。 .. TODO: Convert to file-local cross-reference when the destination is translated. -あなたのパッチにコメントした人には、パッチの Cc リストに追加して、 -新しい版を知らせてください。 +あなたのパッチにコメントしてくれた人たちは、パッチの Cc リストに追加して +新しい版について知らせてください。 メールクライアントとメーリングリストでの作法についての推奨事項は、 Documentation/process/email-clients.rst を参照してください。 -メール議論では不要な引用を削った interleaved replies を使う ------------------------------------------------------------- +要点に絞ったインライン返信での議論 +--------------------------------------- -Linux カーネル開発の議論では、top-posting は強く非推奨とされています。 -Interleaved replies、または ``inline`` replies を使うと、会話の流れを -ずっと追いやすくなります。詳細は次を参照してください: +Linux カーネル開発の議論では、全文引用 (訳註: top-posting) は強く非推奨です。 +インライン返信 (訳註: interleaved reples or "inline" replies) を使うと、 +会話の流れをずっと追いやすくなります。詳細は次を参照してください: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style -メーリングリストでは、よく次のように引用されます:: +これについて、メーリングリストでは、次の引用をしばしば目にします:: A: http://en.wikipedia.org/wiki/Top_post Q: Where do I find info about this thing called top-posting? @@ -381,24 +380,102 @@ https://en.wikipedia.org/wiki/Posting_style#Interleaved_style Q: Should I include quotations after my reply? -落胆しない、そして急がない --------------------------- +落胆しない - いらいらしない +--------------------------- 変更を投稿した後は、辛抱強く待ってください。レビューアは忙しい人たちであり、 -あなたのパッチをすぐに見られるとは限りません。 +あなたのパッチにすぐに取りかかれるとは限りません。 かつては、パッチが何のコメントもなく虚空へ消えていくこともありましたが、 現在の開発プロセスはそれよりも円滑に機能しています。数週間以内、 通常は 2〜3 週間以内にコメントを受け取るはずです。そうならない場合は、 パッチを正しい場所へ送ったか確認してください。再投稿したりレビューアに -ping したりする前に、少なくとも 1 週間は待ってください。merge window の -ような忙しい時期には、さらに長く待つ方がよい場合もあります。 +ping したりする前に、少なくとも 1 週間は待ってください。マージ期間 +(訳註: merge window) のような忙しい時期には、さらに長く待ちましょう。 -数週間後に、subject line に "RESEND" を追加して、パッチまたは -パッチシリーズを再送しても構いません:: +数週間後に、件名に "RESEND" を追加したパッチまたはパッチシリーズを +再送することは構いません:: [PATCH Vx RESEND] sub/sys: Condensed patch summary -パッチまたはパッチシリーズの修正版を投稿する場合は、"RESEND" を -追加しないでください。"RESEND" は、前回の投稿から一切変更していない -パッチまたはパッチシリーズを再送する場合にのみ使います。 +ただし、パッチまたはパッチシリーズの修正版を投稿する際には "RESEND" +を追加しないでください。 +"RESEND" は、前回の投稿から一切変更のないパッチまたはパッチシリーズの +再送だけに当てはまります。 + + +件名に PATCH を含める +--------------------- + +Linus と linux-kernel メーリングリストには大量のメールが届くため、 +件名の先頭に ``[PATCH]`` を付けることが一般的な慣例となっています。 +これにより、Linus や他のカーネル開発者は、パッチとその他の議論を +容易に区別できます。 + +``git send-email`` は、この指定を自動的に行います。 + + +作業への署名 - Developer's Certificate of Origin +-------------------------------------------------- + +誰が何を行ったのかを追跡しやすくするため、特にパッチが複数階層の +メンテナーを経由して最終的にカーネルへ取り込まれる場合に備えて、 +メールでやり取りされるパッチには sign-off の手続きが導入されています。 + +sign-off は、パッチの説明の末尾に追加する単純な一行です。これは、 +そのパッチを自分で作成したか、オープンソースのパッチとして提出する +権利を持っていることを証明します。 + +.. note:: 【訳註】 + + ``Signed-off-by`` によって同意する対象は、翻訳文ではなく、 + 以下に示す英語原文の Developer's Certificate of Origin 1.1 です。 + DCO は法的な性質を持つ文書であるため、本文は翻訳せず、原文のまま + 掲載します。内容を確認する場合は、必ず英語原文を参照してください。 + +規則は単純で、以下を証明できる場合です:: + + Developer's Certificate of Origin 1.1 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + +上記を証明できる場合は、次のような行を追加します:: + + Signed-off-by: Random J Developer <random@developer.example.org> + +既知の身元を使用してください。匿名での貢献は認められません。 +``git commit -s`` を使用すると、この行を自動的に追加できます。 + +revert にも ``Signed-off-by:`` を含める必要があります。 +``git revert -s`` を使用すると、自動的に追加できます。 + +末尾に追加のタグを付ける人もいます。現時点では無視されますが、 +社内手続きを示したり、sign-off に関する特記事項を記録したりするために +使用できます。 + +作者の SoB に続く追加の SoB(``Signed-off-by:``)は、パッチの開発には +関与せず、その取り扱いや転送を行った人によるものです。SoB の連鎖は、 +パッチがメンテナーを経て最終的に Linus へ届いた実際の経路を反映する +必要があります。最初の SoB は、単独の主要作者であることを示します。 diff --git a/Documentation/translations/pt_BR/index.rst b/Documentation/translations/pt_BR/index.rst index 7a488f662a1e..232d18f7cfce 100644 --- a/Documentation/translations/pt_BR/index.rst +++ b/Documentation/translations/pt_BR/index.rst @@ -68,13 +68,24 @@ kernel e sobre como ver seu trabalho integrado. Introdução <process/1.Intro> Guia do Processo de Desenvolvimento <process/development-process> + Como aplicar patches <process/applying-patches> + Backporting e resolução de conflitos <process/backporting> + Como não Deixar as ioctls malfeitas <process/botching-up-ioctls> Index de documentos do Kernel <process/kernel-docs> Regras de licenciamento <process/license-rules> Como começar <process/howto> Requisitos mínimos <process/changes> Conclave (Continuidade do projeto) <process/conclave> + Modelos de Maturidade para Contribuição no Kernel Linux <process/contribution-maturity-model.rst> Manuais dos mantenedores <process/maintainer-handbooks> Processo do subsistema de rede (netdev) <process/maintainer-netdev> Processo do subsistema SoC <process/maintainer-soc> Conformidade de DTS para SoC <process/maintainer-soc-clean-dts> Processo do subsistema KVM x86 <process/maintainer-kvm-x86> + Adicionando uma nova chamada de Sistema <process/adding-syscalls> + Declaração sobre Drivers do Kernel <process/kernel-driver-statement> + Lista de verificação para submissão de patches do kernel Linux <process/submit-checklist> + Interpretação do Código de Conduta do Kernel Linux <process/code-of-conduct-interpretation> + Código de Conduta de Compromisso do Colaborador <process/code-of-conduct> + Interfaces, recursos de linguagem, atributos e convenções obsoletos <process/deprecated> + diff --git a/Documentation/translations/pt_BR/process/4.Coding.rst b/Documentation/translations/pt_BR/process/4.Coding.rst new file mode 100644 index 000000000000..ca4c74774a91 --- /dev/null +++ b/Documentation/translations/pt_BR/process/4.Coding.rst @@ -0,0 +1,440 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Escrever o código corretamente +============================== + +Embora haja muito o que se dizer sobre um processo de design sólido e orientado +à comunidade, a prova de qualquer projeto de desenvolvimento de kernel está no +código resultante. É o código que será examinado por outros desenvolvedores e +mesclado (ou não) na árvore principal (*mainline*). Portanto, é a qualidade +deste código que determinará o sucesso final do projeto. + +Esta seção examinará o processo de codificação. Começaremos analisando uma série +de maneiras pelas quais os desenvolvedores de kernel podem errar. Em seguida, o +foco mudará para como fazer as coisas do jeito certo e as ferramentas que podem +ajudar nessa busca. + + +Armadilhas +---------- + +Estilo de Codificação +********************* + +O kernel há muito possui um estilo de codificação padrão, descrito em +:ref:`Documentation/process/coding-style.rst <codingstyle>`. Por grande parte +desse tempo, as políticas descritas naquele arquivo eram consideradas, no +máximo, como recomendações. Como resultado, há uma quantidade substancial +de código no kernel que não cumpre as diretrizes de estilo de codificação. +A presença desse código leva a dois riscos independentes para os +desenvolvedores do kernel. + +O primeiro deles é acreditar que os padrões de codificação do kernel não importam +e não são exigidos. A verdade é que adicionar novo código ao kernel é muito +difícil se esse código não estiver escrito de acordo com o padrão; muitos +desenvolvedores solicitarão que o código seja reformatado antes mesmo de +revisá-lo. Uma base de código tão grande quanto a do kernel exige certa +uniformidade para tornar possível que os desenvolvedores entendam rapidamente +qualquer parte dela. Portanto, não há mais espaço para códigos com formatações +estranhas. + +Ocasionalmente, o estilo de codificação do kernel entrará em conflito com o +estilo exigido por um empregador. Nesses casos, o estilo do kernel terá que +vencer para que o código possa ser mesclado. Colocar código no kernel significa +abrir mão de um certo grau de controle de várias maneiras — incluindo o controle +sobre como o código é formatado. + +A outra armadilha é presumir que o código já presente no kernel necessita +urgentemente de correções de estilo de codificação. Os desenvolvedores podem +começar a gerar patches de reformatação como uma forma de ganhar familiaridade +com o processo, ou como um meio de incluir seus nomes nos logs de alterações +(*changelogs*) do kernel ou ambos. No entanto, patches puramente de estilo de +codificação são vistos como ruído pela comunidade de desenvolvimento; eles tendem +a receber uma recepção fria. Portanto, é melhor evitar esse tipo de patch. É +natural corrigir o estilo de um trecho de código ao trabalhar nele por outros +motivos, mas mudanças de estilo de codificação não devem ser feitas apenas por +fazer. + +O documento de estilo de codificação também não deve ser lido como uma lei +absoluta que nunca pode ser transgredida. Se houver um bom motivo para ir contra +o estilo (uma linha que se torna muito menos legível se for dividida para caber +no limite de 80 colunas, por exemplo), simplesmente faça isso. + +Note que você também pode usar a ferramenta ``clang-format`` para ajudá-lo com +essas regras, para reformatar rapidamente partes do seu código de forma automática +e para revisar arquivos completos a fim de identificar erros de estilo de +codificação, erros de digitação e possíveis melhorias. Ela também é útil para +ordenar ``#includes``, alinhar variáveis/macros, reajustar o fluxo de textos e +outras tarefas semelhantes. Veja o arquivo +:ref:`Documentation/dev-tools/clang-format.rst <clangformat>` para mais detalhes. + +Algumas configurações básicas do editor, como indentação e fins de linha, +serão definidas automaticamente se você estiver usando um editor compatível +com o EditorConfig. Consulte o site oficial do EditorConfig para obter mais +informações: https://editorconfig.org/ + +Camadas de Abstração +******************** + +Os professores de Ciência da Computação ensinam os alunos a fazerem uso +extensivo de camadas de abstração em nome da flexibilidade e da ocultação de +informações. Certamente o kernel faz uso extensivo de abstração; nenhum +projeto que envolva vários milhões de linhas de código poderia fazer o +contrário e sobreviver. No entanto, a experiência tem mostrado que a +abstração excessiva ou prematura pode ser tão prejudicial quanto a otimização +prematura. A abstração deve ser usada até o nível necessário e não além. + +Em um nível simples, considere uma função que possui um argumento que é +sempre passado como zero por todos os chamadores. Alguém poderia manter esse +argumento caso alguém eventualmente precise usar a flexibilidade extra que ele +oferece. A essa altura, no entanto, as chances são grandes de que o código que +implementa esse argumento extra tenha sido quebrado de alguma forma sutil que +nunca foi percebida — porque ele nunca foi usado. Ou, quando surge a +necessidade de flexibilidade extra, ela não ocorre de uma forma que corresponda +à expectativa inicial do programador. Os desenvolvedores do kernel enviam +patches rotineiramente para remover argumentos não utilizados; eles não devem, +em geral, ser adicionados em primeiro lugar. + +Camadas de abstração que ocultam o acesso ao hardware — frequentemente para +permitir que a maior parte de um driver seja usada com múltiplos sistemas +operacionais — são especialmente malvistas. Essas camadas obscurecem o código +e podem impor uma penalidade de desempenho; elas não pertencem ao kernel +Linux. + +Por outro lado, se você se pegar copiando quantidades significativas de código +de outro subsistema do kernel, é hora de perguntar se faria sentido, de fato, +extrair parte desse código em uma biblioteca separada ou implementar essa +funcionalidade em um nível superior. Não há valor em duplicar o mesmo código +por todo o kernel. + + +Uso de #ifdef e do pré-processador em geral +******************************************* + +O pré-processador C parece apresentar uma forte tentação para alguns +programadores C, que o veem como uma forma de codificar eficientemente uma grande +quantidade de flexibilidade em um arquivo-fonte. No entanto, o pré-processador +não é C, e o uso pesado dele resulta em um código muito mais difícil de ser lido +por outros e mais difícil para o compilador verificar a correção. O uso pesado +do pré-processador é quase sempre um sinal de código que precisa de algum +trabalho de limpeza. + +A compilação condicional com #ifdef é, de fato, um recurso poderoso, e é +utilizada dentro do kernel. Mas há pouco desejo de ver um código que seja +salpicado liberalmente com blocos #ifdef. Como regra geral, o uso de #ifdef +deve ser confinado a arquivos de cabeçalho (headers) sempre que possível. O +código compilado condicionalmente pode ser confinado a funções que, se o código +não estiver presente, simplesmente se tornam vazias. O compilador irá então, +silenciosamente, otimizar e remover a chamada para a função vazia. O resultado +é um código muito mais limpo e fácil de acompanhar. + +As macros do pré-processador C apresentam uma série de riscos, incluindo a +possível avaliação múltipla de expressões com efeitos colaterais e a falta de +segurança de tipos. Se você se sentir tentado a definir uma macro, considere a +criação de uma função inline em seu lugar. O código resultante será o mesmo, +mas as funções inline são mais fáceis de ler, não avaliam seus argumentos +múltiplas vezes e permitem que o compilador realize a checagem de tipos nos +argumentos e no valor de retorno. + + +Funções Inline +************** + +No entanto, as funções inline apresentam um perigo próprio. Os programadores +podem ficar encantados com a eficiência percebida inerente a evitar uma chamada +de função e encher um arquivo de código-fonte com funções inline. Essas +funções, contudo, podem na verdade reduzir o desempenho. Como seu código é +replicado em cada local de chamada, elas acabam inflando o tamanho do kernel +compilado. Isso, por sua vez, cria pressão nos caches de memória do +processador, o que pode desacelerar a execução drasticamente. As funções +inline, como regra, devem ser bastante pequenas e relativamente raras. O custo +de uma chamada de função, afinal de contas, não é tão alto; a criação de um +grande número de funções inline é um exemplo clássico de otimização prematura. + +Em geral, os programadores de kernel ignoram os efeitos de cache por sua própria +conta e risco. O clássico compromisso entre tempo e espaço (tradeoff) ensinado +nas aulas introdutórias de estruturas de dados frequentemente não se aplica ao +hardware contemporâneo. Espaço *é* tempo, no sentido de que um programa maior +será executado mais lentamente do que um que seja mais compacto. + +Compiladores mais recentes desempenham um papel cada vez mais ativo em decidir +se uma determinada função deve ou não ser realmente inline. Portanto, a inserção +liberal da palavra-chave "inline" pode não apenas ser excessiva; ela também pode +ser irrelevante. + + +Mecanismo de Trava +****************** + +Em maio de 2006, a pilha de rede "Devicescape" foi, com grande alarde, lançada +sob a GPL e disponibilizada para inclusão no kernel mainline. Essa doação foi uma +notícia bem-vinda; o suporte para redes sem fio no Linux era considerado abaixo do +padrão, na melhor das hipóteses, e a pilha da Devicescape oferecia a promessa de +corrigir essa situação. No entanto, esse código só entrou de fato no mainline em +junho de 2007 (2.6.22). O que aconteceu? + +Esse código mostrava vários sinais de ter sido desenvolvido a portas fechadas em +ambiente corporativo. Mas um grande problema em particular era que ele não havia +sido projetado para funcionar em sistemas multiprocessados. Antes que essa pilha +de rede (agora chamada de mac80211) pudesse ser integrada, um esquema de locking +(bloqueio) precisou ser adaptado a ela. + +Era uma vez uma época em que o código do kernel Linux podia ser desenvolvido sem +pensar nos problemas de concorrência apresentados por sistemas multiprocessados. +Hoje, no entanto, este documento está sendo escrito em um laptop dual-core. +Mesmo em sistemas com um único processador, o trabalho feito para melhorar a +capacidade de resposta aumentará o nível de concorrência dentro do kernel. Os +dias em que o código do kernel podia ser escrito sem pensar em locking ficaram +há muito tempo no passado. + +Qualquer recurso (estruturas de dados, registradores de hardware, etc.) que +possa ser acessado concorrentemente por mais de uma linha de execução deve ser +protegido por uma trava (lock). O novo código deve ser escrito com esse +requisito em mente; adaptar o locking após o fato é uma tarefa consideravelmente +mais difícil. Os desenvolvedores do kernel devem dedicar um tempo para +compreender as primitivas de locking disponíveis bem o suficiente para escolher +a ferramenta certa para o trabalho. Códigos que mostrem falta de atenção à +concorrência terão um caminho difícil para entrar no mainline. + + +Regressions +*********** + +Um perigo final que vale a pena mencionar é este: pode ser tentador fazer uma +alteração (que pode trazer grandes melhorias) que faça algo quebrar para os +usuários existentes. Esse tipo de alteração é chamado de "regressão", e as +regressões tornaram-se totalmente indesejadas no kernel mainline. Com poucas +exceções, as alterações que causarem regressões serão revertidas se a regressão +não puder ser corrigida em tempo hábil. É muito melhor evitar a regressão em +primeiro lugar. + +Muitas vezes argumenta-se que uma regressão pode ser justificada se ela fizer as +coisas funcionarem para mais pessoas do que os problemas que ela cria. Por que +não fazer uma alteração se ela trouxer uma nova funcionalidade para dez sistemas +para cada um que ela quebrar? A melhor resposta para essa pergunta foi expressa +por Linus em julho de 2007: + +:: + + Portanto, nós não corrigimos bugs introduzindo novos problemas. Esse caminho + leva à loucura, e ninguém nunca sabe se você está realmente fazendo algum + progresso real. São dois passos para frente, um passo para trás, ou um passo + para frente e dois passos para trás? + +(https://lwn.net/Articles/243460/). + +Um tipo de regressão especialmente indesejado é qualquer tipo de alteração na +ABI do espaço do usuário (user-space ABI). Uma vez que uma interface tenha sido +exportada para o espaço do usuário, ela deve receber suporte indefinidamente. +Esse fato torna a criação de interfaces de espaço do usuário particularmente +desafiadora: já que elas não podem ser alteradas de maneiras incompatíveis, elas +devem ser feitas corretamente na primeira vez. Por essa razão, exige-se sempre +muita reflexão, documentação clara e uma ampla revisão para as interfaces do +espaço do usuário. + + +Ferramentas de verificação de código +------------------------------------ + +Por enquanto, pelo menos, a escrita de código livre de erros continua sendo um +ideal que poucos de nós conseguem alcançar. O que podemos esperar fazer, no +entanto, é capturar e corrigir o máximo possível desses erros antes que nosso +código entre no kernel mainline. Para esse fim, os desenvolvedores do kernel +reuniram um conjunto impressionante de ferramentas que podem capturar uma ampla +variedade de problemas obscuros de forma automatizada. Qualquer problema +capturado pelo computador é um problema que não afligirá um usuário mais tarde, +portanto, é lógico que as ferramentas automatizadas devem ser usadas sempre que +possível. + +O primeiro passo é simplesmente prestar atenção aos avisos (warnings) produzidos +com o compilador. As versões contemporâneas do gcc podem detectar (e alertar +sobre) um grande número de erros potenciais. Com bastante frequência, esses +avisos apontam para problemas reais. O código enviado para revisão deve, como +regra, não produzir nenhum aviso do compilador. Ao silenciar os avisos, tome o +cuidado de entender a real causa e tente evitar "correções" que façam o aviso +desaparecer sem resolver a sua origem. + +Note que nem todos os avisos do compilador ficam ativados por padrão. Compile o +kernel com "make KCFLAGS=-W" para obter o conjunto completo. + +O kernel fornece várias opções de configuração que ativam recursos de +depuração; a maioria delas é encontrada no submanu "kernel hacking". Várias +dessas opções devem ser ativadas para qualquer kernel usado para fins de +desenvolvimento ou teste. Em particular, você deve ativar: + + - FRAME_WARN para obter avisos sobre quadros de pilha (stack frames) maiores + que um determinado valor. A saída gerada pode ser volumosa, mas não é + necessário se preocupar com os avisos de outras partes do kernel. + + - DEBUG_OBJECTS adicionará código para rastrear o tempo de vida de vários + objetos criados pelo kernel e alertará quando as ações forem feitas fora de + ordem. Se você estiver adicionando um subsistema que cria (e exporta) seus + próprios objetos complexos, considere adicionar suporte à infraestrutura de + depuração de objetos. + + - DEBUG_SLAB pode encontrar uma variedade de erros de alocação e uso de + memória; ele deve ser usado na maioria dos kernels de desenvolvimento. + + - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP e DEBUG_MUTEXES encontrarão uma série de + erros comuns de locking (bloqueio). + +Existem várias outras opções de depuração, algumas das quais serão discutidas +abaixo. Algumas delas têm um impacto significativo no desempenho e não devem ser +usadas o tempo todo. Mas um tempo gasto aprendendo as opções disponíveis +provavelmente se pagará muitas vezes em pouco tempo. + +Uma das ferramentas de depuração mais pesadas é o verificador de locking, ou +"lockdep". Esta ferramenta rastreará a aquisição e a liberação de cada trava +(spinlock ou mutex) no sistema, a ordem em que as travas são adquiridas umas em +relação às outras, o ambiente de interrupção atual e muito mais. Ela pode, +então, garantir que as travas sejam sempre adquiridas na mesma ordem, que as +mesmas suposições de interrupção se apliquem em todas as situações e assim por +diante. Em outras palavras, o lockdep pode encontrar uma série de cenários nos +quais o sistema poderia, em raras ocasiões, entrar em deadlock. Esse tipo de +problema pode ser doloroso (tanto para desenvolvedores quanto para usuários) em +um sistema implantado; o lockdep permite que eles sejam encontrados de maneira +automatizada e antecipada. Códigos com qualquer tipo de locking não trivial +devem ser executados com o lockdep ativado antes de serem enviados para inclusão. + +Como um programador de kernel diligente, você irá, sem dúvida, verificar o +status de retorno de qualquer operação (como uma alocação de memória) que possa +falhar. O fato, porém, é que os caminhos de recuperação de falha resultantes +estão, provavelmente, completamente não testados. Código não testado tende a ser +código quebrado; você poderia estar muito mais confiante em seu código se todos +esses caminhos de tratamento de erros tivessem sido exercitados algumas vezes. + +O kernel fornece um framework de injeção de falhas (fault injection) que pode +fazer exatamente isso, especialmente onde alocações de memória estão +envolvidas. Com a injeção de falhas ativada, uma porcentagem configurável das +alocações de memória será forçada a falhar; essas falhas podem ser restritas a +um intervalo específico de código. Executar o código com a injeção de falhas +ativada permite ao programador ver como o código responde quando as coisas vão +mal. Veja Documentation/fault-injection/fault-injection.rst para mais +informações sobre como usar esse recurso. + +Outros tipos de erros podem ser encontrados com a ferramenta de análise estática +"sparse". Com o sparse, o programador pode ser alertado sobre confusões entre +endereços do espaço do usuário e do espaço do kernel, mistura de quantidades +big-endian e small-endian, a passagem de valores inteiros onde um conjunto de +sinalizadores de bits (bit flags) é esperado, e assim por diante. O sparse deve +ser instalado separadamente (ele pode ser encontrado em +https://sparse.wiki.kernel.org/index.php/Main_Page se a sua distribuição não o +incluir como pacote); ele pode então ser executado no código adicionando "C=1" +ao seu comando make. + +A ferramenta "Coccinelle" (http://coccinelle.lip6.fr/) é capaz de encontrar uma +ampla variedade de potenciais problemas de codificação; ela também pode propor +correções para esses problemas. Uma quantidade considerável de "patches +semânticos" para o kernel foi empacotada sob o diretório scripts/coccinelle; +executar "make coccicheck" passará por esses patches semânticos e relatará +quaisquer problemas encontrados. Veja +:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>` +para mais informações. + +Outros tipos de erros de portabilidade são encontrados mais facilmente ao +compilar seu código para outras arquiteturas. Se você por acaso não tiver um +sistema S/390 ou uma placa de desenvolvimento Blackfin à mão, ainda assim poderá +realizar a etapa de compilação. Um grande conjunto de compiladores cruzados +(cross-compilers) para sistemas x86 pode ser encontrado em: + + https://www.kernel.org/pub/tools/crosstool/ + +Um tempo gasto instalando e usando esses compiladores ajudará a evitar +constrangimentos mais tarde. + + +Documentação +------------- + +A documentação frequentemente tem sido mais a exceção do que a regra no +desenvolvimento do kernel. Mesmo assim, uma documentação adequada ajudará a +facilitar a integração de novos códigos ao kernel, tornará a vida mais fácil para +outros desenvolvedores e será útil para os seus usuários. Em muitos casos, a +adição de documentação tornou-se essencialmente obrigatória. + +A primeira parte da documentação de qualquer patch é o seu log de alterações +(changelog) associado. As entradas do log devem descrever o problema que está +sendo resolvido, a forma da solução, as pessoas que trabalharam no patch, +quaisquer efeitos relevantes no desempenho e qualquer outra coisa que possa ser +necessária para entender o patch. Certifique-se de que o changelog diga o +*porquê* de o patch valer a pena ser aplicado; um número surpreendente de +desenvolvedores falha em fornecer essa informação. + +Qualquer código que adicione uma nova interface de espaço do usuário — incluindo +novos arquivos sysfs ou /proc — deve incluir a documentação dessa interface, de +modo a permitir que os desenvolvedores do espaço do usuário saibam com o que +estão trabalhando. Veja Documentation/ABI/README para uma descrição de como essa +documentação deve ser formatada e quais informações precisam ser fornecidas. + +O arquivo :ref:`Documentation/admin-guide/kernel-parameters.rst +<kernelparameters>` descreve todos os parâmetros de boot do kernel. Qualquer +patch que adicione novos parâmetros deve adicionar as entradas apropriadas a +este arquivo. + +Quaisquer novas opções de configuração devem ser acompanhadas por um texto de +ajuda que explique claramente as opções e quando o usuário pode querer +selecioná-las. + +As informações de API interna de muitos subsistemas são documentadas por meio de +comentários com formatação especial; esses comentários podem ser extraídos e +formatados de várias maneiras pelo script "kernel-doc". Se você estiver +trabalhando em um subsistema que possui comentários kerneldoc, você deve +mantê-los e adicioná-los, conforme apropriado, para funções disponíveis +externamente. Mesmo em áreas que não tenham sido documentadas dessa forma, não há +mal nenhum em adicionar comentários kerneldoc para o futuro; de fato, esta pode +ser uma atividade útil para desenvolvedores iniciantes de kernel. O formato +desses comentários, junto com algumas informações sobre como criar modelos de +kerneldoc, pode ser encontrado em :ref:`Documentation/doc-guide/ <doc_guide>`. + +Qualquer pessoa que leia uma quantidade significativa de código existente do +kernel notará que, frequentemente, os comentários chamam a atenção por sua +ausência. Mais uma vez, as expectativas para códigos novos são mais altas do que +eram no passado; integrar código sem comentários será mais difícil. Dito isso, +há pouco interesse em códigos comentados de forma prolixa. O código deve, por si +só, ser legível, com os comentários explicando os aspectos mais sutis. + +Certas coisas devem sempre ser comentadas. O uso de barreiras de memória +(memory barriers) deve ser acompanhado por uma linha explicando por que a +barreira é necessária. As regras de locking (bloqueio) para estruturas de dados +geralmente precisam ser explicadas em algum lugar. Grandes estruturas de dados +precisam de uma documentação abrangente em geral. Dependências não óbvias entre +trechos distintos de código devem ser apontadas. Qualquer coisa que possa tentar +um "faxineiro de código" (code janitor) a fazer uma "limpeza" incorreta precisa +de um comentário dizendo por que foi feita daquela maneira. E assim por diante. + + +Alterações de API interna +------------------------- + +A interface binária fornecida pelo kernel para o espaço do usuário não pode ser +quebrada, exceto sob as circunstâncias mais graves. Por outro lado, as +interfaces de programação internas do kernel são altamente fluidas e podem ser +alteradas quando surgir a necessidade. Se você se encontrar tendo que criar uma +gambiarra para contornar uma API do kernel, ou simplesmente deixando de usar uma +funcionalidade específica porque ela não atende às suas necessidades, isso pode +ser um sinal de que a API precisa mudar. Como desenvolvedor de kernel, você tem +o poder de fazer tais alterações. + +Existem, é claro, algumas pegadinhas. Alterações de API podem ser feitas, mas +precisam ser bem justificadas. Portanto, qualquer patch que faça uma alteração de +API interna deve ser acompanhado por uma descrição do que é a mudança e do porquê +ela é necessária. Esse tipo de alteração também deve ser separado em um patch +independente, em vez de ser enterrado dentro de um patch maior. + +A outra pegadinha é que o desenvolvedor que altera uma API interna é geralmente +encarregado da tarefa de corrigir qualquer código dentro da árvore do kernel que +tenha sido quebrado pela mudança. Para uma função amplamente utilizada, esse +dever pode levar a literalmente centenas ou milhares de alterações — muitas das +quais provavelmente entrarão em conflito com o trabalho que está sendo feito por +outros desenvolvedores. Desnecessário dizer que isso pode ser um grande +trabalho, então é melhor ter certeza de que a justificativa é sólida. Note que +a ferramenta Coccinelle pode ajudar com alterações de API de amplo alcance. + +Ao fazer uma alteração incompatível de API, deve-se, sempre que possível, +garantir que o código que não foi atualizado seja capturado pelo compilador. +Isso ajudará você a ter certeza de que encontrou todos os usos dessa interface +dentro da árvore (in-tree). Isso também alertará os desenvolvedores de códigos +fora da árvore (out-of-tree) de que há uma mudança à qual eles precisam +responder. Dar suporte a código fora da árvore não é algo com que os +desenvolvedores do kernel precisem se preocupar, mas também não temos que +tornar a vida dos desenvolvedores fora da árvore mais difícil do que precisa ser. diff --git a/Documentation/translations/pt_BR/process/5.Posting.rst b/Documentation/translations/pt_BR/process/5.Posting.rst new file mode 100644 index 000000000000..820a56b661db --- /dev/null +++ b/Documentation/translations/pt_BR/process/5.Posting.rst @@ -0,0 +1,376 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Enviando patches +================ + +Cedo ou tarde, chega o momento em que seu trabalho está pronto para ser +apresentado à comunidade para revisão e, eventualmente, inclusão no kernel +mainline. Sem surpresa, a comunidade de desenvolvimento do kernel evoluiu um +conjunto de convenções e procedimentos que são usados no envio de patches; +segui-los tornará a vida muito mais fácil para todos os envolvidos. Este +documento tentará cobrir essas expectativas em detalhes razoáveis; mais +informações também podem ser encontradas nos arquivos +:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` +e :ref:`Documentation/process/submit-checklist.rst <submitchecklist>`. + + +Quando enviar +------------- + +Existe uma tentação constante de evitar o envio de patches antes que eles +estejam completamente "prontos". Para patches simples, isso não é um problema. +No entanto, se o trabalho que está sendo feito for complexo, há muito a se +ganhar obtendo feedback da comunidade antes que o trabalho esteja concluído. +Portanto, você deve considerar o envio de trabalhos em andamento, ou até mesmo +disponibilizar uma árvore git para que os desenvolvedores interessados possam +acompanhar o seu trabalho a qualquer momento. + +Ao enviar um código que ainda não é considerado pronto para inclusão, é uma boa +ideia dizer isso no próprio envio. Mencione também qualquer trabalho importante +que ainda precise ser feito e quaisquer problemas conhecidos. Menos pessoas vão +olhar para patches que sabidamente estão "meio cozidos" (half-baked), mas aqueles +que o fizerem virão com a ideia de que podem ajudá-lo a conduzir o trabalho na +direção certa. + + +Antes de criar patches +---------------------- + +Há uma série de coisas que devem ser feitas antes de você considerar o envio +de patches para la comunidade de desenvolvimento. Elas incluem: + + - Teste o código tanto quanto puder. Faça uso das ferramentas de depuração + do kernel, garanta que o kernel seja compilado com todas as combinações + razoáveis de opções de configuração, use compiladores cruzados (cross- + compilers) para compilar para diferentes arquiteturas, etc. Adicione testes, + provavelmente usando um framework de testes existente como o KUnit, e + inclua-os como um membro separado da sua série (veja a próxima seção para + mais informações sobre séries de patches). Note que isso pode ser + obrigatório ao afetar alguns subsistemas. Por exemplo, funções de biblioteca + (localizadas sob lib/) são amplamente utilizadas em quase todos os lugares e + espera-se que sejam testadas adequadamente. + + - Certifique-se de que seu código esteja em conformidade com as diretrizes de + estilo de codificação do kernel. + + - Sua alteração tem implicações no desempenho? Se sim, você deve executar + benchmarks mostrando qual é o impacto (ou benefício) da sua mudança; um + resumo dos resultados deve ser incluído junto ao patch. + + - Tenha certeza de que você tem o direito de enviar o código. Se este + trabalho foi feito para um empregador, o empregador provavelmente tem direito + sobre o trabalho e deve estar de acordo com a sua liberação sob a GPL. + +Como regra geral, dedicar um pouco de reflexão extra antes de enviar o código +quase sempre compensa o esforço em pouco tempo. + + +Preparação de patches +--------------------- + +A preparação de patches para envio pode dar uma quantidade surpreendente de +trabalho, mas, mais uma vez, tentar economizar tempo aqui geralmente não é +aconselhável, mesmo a curto prazo. + +Os patches devem ser preparados contra uma versão específica do kernel. Como +regra geral, um patch deve ser baseado no mainline atual encontrado na árvore +git do Linus. Ao basear-se no mainline, comece a partir de um ponto de +lançamento bem conhecido — um release estável ou -rc —, em vez de criar uma +bifurcação (branch) a partir do mainline em um ponto arbitrário. + +No entanto, pode tornar-se necessário criar versões contra a árvore -mm, +linux-next ou a árvore de um subsistema, para facilitar testes e revisões mais +amplos. Dependendo da área do seu patch e do que está acontecendo em outros +lugares, basear um patch contra essas outras árvores pode exigir uma quantidade +significativa de trabalho para resolver conflitos e lidar com mudanças de API. + +Apenas as alterações mais simples devem ser formatadas como um único patch; tudo +o mais deve ser feito como uma série lógica de mudanças. Dividir patches é uma +arte; alguns desenvolvedores passam muito tempo descobrindo como fazer isso da +maneira que a comunidade espera. Existem algumas regras práticas, no entanto, +que podem ajudar consideravelmente: + + - A série de patches que você envia quase certamente não será a série de + alterações encontrada no seu sistema de controle de versão de trabalho. Em + vez disso, as mudanças que você fez precisam ser consideradas em sua forma + final e, então, divididas de maneiras que façam sentido. Os desenvolvedores + estão interessados em alterações discretas e autocontidas, não no caminho + que você percorreu para chegar a essas alterações. + + - Cada alteração logicamente independente deve ser formatada como um patch separado. + Essas alterações podem ser pequenas ("adicionar um campo a esta estrutura") ou + grandes (adicionar um driver totalmente novo, por exemplo), mas devem ser + conceitualmente pequenas e passíveis de uma descrição de uma única linha. Cada + patch deve fazer uma alteração específica que possa ser revisada por si só e + verificada para garantir que faz o que diz fazer. + + - Como uma forma de reafirmar a diretriz acima: não misture diferentes tipos de + alterações no mesmo patch. Se um único patch corrige uma falha crítica de + segurança, reorganiza algumas estruturas e reformatará o código, há uma grande + chance de que ele seja ignorado e a correção importante seja perdida. + + - Cada patch deve resultar em um kernel que compile e funcione corretamente; se + sua série de patches for interrompida no meio, o resultado ainda deve ser um + kernel funcional. A aplicação parcial de uma série de patches é um cenário + comum quando a ferramenta "git bisect" é usada para encontrar regressões; se o + resultado for um kernel quebrado, você tornará a vida mais difícil para os + desenvolvedores e usuários que estão engajados no nobre trabalho de rastrear + problemas. + + - No entanto, não exagere. Certa vez, um desenvolvedor enviou um conjunto de + edições em um único arquivo como 500 patches separados — um ato que não o + tornou a pessoa mais popular na lista de discussão do kernel. Um único patch + pode ser razoavelmente grande, desde que ainda contenha uma única alteração + *lógica*. + + - Pode ser tentador adicionar toda uma nova infraestrutura com uma série de + patches, mas deixar essa infraestrutura sem uso até que o patch final da série + ative tudo. Essa tentação deve ser evitada, se possível; se essa série + adicionar regressões, a bisseção (bisection) apontará o último patch como aquele + que causou o problema, mesmo que o bug real esteja em outro lugar. Sempre que + possível, um patch que adiciona código novo deve tornar esse código ativo + imediatamente. + +Trabalhar para criar a série de patches perfeita pode ser um processo +frustrante, que exige bastante tempo e reflexão após o "trabalho real" ter sido +concluído. Quando feito corretamente, no entanto, é um tempo bem gasto. + + +Formatação de patches e logs de alterações +------------------------------------------ + +Então agora você tem uma série perfeita de patches para enviar, mas o trabalho +ainda não terminou. Cada patch precisa ser formatado em uma mensagem que comunique +de forma rápida e clara o seu propósito para o resto do mundo. Para esse fim, +cada patch será composto pelo seguinte: + + - Uma linha "From" opcional que nomeia o autor do patch. Esta linha só é + necessária se você estiver repassando o patch de outra pessoa via e-mail, + mas nunca é demais adicioná-la em caso de dúvida. + + - Uma descrição de uma única linha sobre o que o patch faz. Esta mensagem deve + ser suficiente para que um leitor que a veja sem outro contexto consiga + compreender o escopo do patch; esta é a linha que aparecerá nos logs de + alterações (changelogs) de "forma curta". Esta mensagem geralmente é formatada + com o nome do subsistema relevante primeiro, seguido pelo propósito do patch. + Por exemplo: + + :: + + gpio: fix build on CONFIG_GPIO_SYSFS=n + + - Uma linha em branco seguida por uma descrição detalhada do conteúdo do + patch. Esta descrição pode ser tão longa quanto necessário; ela deve dizer + o que o patch faz e por que ele deve ser aplicado ao kernel. + + - Uma ou mais linhas de marcadores (tags) com, no mínimo, uma linha + "Signed-off-by:" do autor do patch. Os marcadores serão descritos em mais + detalhes abaixo. + +Os itens acima, juntos, formam o log de alterações (changelog) do patch. Escrever +bons changelogs é uma arte crucial, mas frequentemente negligenciada; vale a +pena dedicar mais um momento para discutir esse assunto. Ao escrever um +changelog, você deve ter em mente que várias pessoas diferentes lerão suas +palavras. Elas incluem mantenedores de subsistemas e revisores que precisam +decidir se o patch deve ser incluído, distribuidores e outros mantenedores +tentando decidir se um patch deve ser retroportado (backported) para outros +kernels, caçadores de bugs se perguntando se o patch é responsável por um +problema que estão perseguindo, usuários que querem saber como o kernel mudou e +muito mais. Um bom changelog transmite a informação necessária para todas essas +pessoas da maneira mais direta e concisa possível. + +Para esse fim, a linha de resumo deve descrever os efeitos e a motivação da +alteração o melhor possível, dada a restrição de uma única linha. A descrição +detalhada pode então ampliar esses tópicos e fornecer qualquer informação +adicional necessária. Se o patch corrige um bug, cite o commit que introduziu o +bug, se possível (e, por favor, forneça tanto o ID do commit quanto o título ao +citar commits). Se um problema estiver associado a uma saída específica de log +ou do compilador, inclua essa saída para ajudar outras pessoas que buscam uma +solução para o mesmo problema. Se a mudança tem o objetivo de dar suporte a +outras alterações que virão em um patch posterior, informe isso. Se as APIs +internas forem alteradas, detalhe essas mudanças e como outros desenvolvedores +devem reagir. Em geral, quanto mais você puder se colocar no lugar de todos que +lerão seu changelog, melhor será esse changelog (e o kernel como um todo). + +Desnecessário dizer que o changelog deve ser o texto usado ao submeter (commit) +a alteração em um sistema de controle de versão. Ele será seguido por: + + - O patch em si, no formato de patch unificado ("-u"). O uso da opção "-p" no + diff associará os nomes das funções às alterações, tornando o patch resultante + mais fácil de ser lido por outras pessoas. + +As tags já mencionadas brevemente acima são usados para fornecer +informações sobre como o patch surgiu. Eles são descritos em detalhes no +documento :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`; +o que se segue aqui é um breve resumo. + +Um marcador é usado para se referir a commits anteriores que introduziram os +problemas corrigidos pelo patch:: + + Fixes: 1f2e3d4c5b6a ("The first line of the commit specified by the first 12 characters of its SHA-1 ID") + +Outro marcador é usado para vincular páginas da web com contextos ou detalhes +adicionais, por exemplo, uma discussão anterior que levou ao patch ou um +documento com uma especificação implementada pelo patch:: + + Link: https://example.com/somewhere.html optional-other-stuff + +De acordo com as orientações do Pinguim-Chefe, um marcador Link +só deve ser adicionado a um commit se ele levar a informações úteis que não +são encontradas no próprio commit. + +Se a URL apontar para um relatório de bug público que está sendo corrigido pelo +patch, use o marcador "Closes:" em seu lugar:: + + Closes: https://example.com/issues/1234 optional-other-stuff + +Alguns rastreadores de bugs têm a capacidade de fechar problemas de forma +automática quando um commit com tal marcador é aplicado. Alguns bots que +monitoram listas de discussão também podem rastrear esses marcadores e tomar certas +ações. Rastreadores de bugs privados e URLs inválidas são proibidos. + +Outro tipo de marcador é usado para documentar quem esteve envolvido no +desenvolvimento do patch. Cada um deles usa este formato:: + + tag: Full Name <email address> optional-other-stuff + +Os marcadores de uso comum são: + + - Signed-off-by: esta é uma certificação do desenvolvedor de que ele ou ela + tem o direito de enviar o patch para inclusão no kernel. É um acordo com o + Developer's Certificate of Origin (Certificado de Origem do Desenvolvedor), + cujo texto completo pode ser encontrado em + :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`. + Códigos sem um signoff adequado não podem ser mesclados (merged) no mainline. + + - Co-developed-by: afirma que o patch foi criado em coautoria por vários + desenvolvedores; é usado para dar atribuição aos coautores (além do autor + atribuído pelo marcador From:) quando várias pessoas trabalham em um único + patch. Cada Co-developed-by: deve ser imediatamente seguido por um + Signed-off-by: do coautor associado. Detalhes e exemplos podem ser encontrados + em :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`. + + - Acked-by: indica o acordo de outro desenvolvedor (frequentemente um + mantenedor do código relevante) de que o patch é apropriado para inclusão + no kernel. + + - Tested-by: afirma que a pessoa nomeada testou o patch e verificou que ele + funciona. + + - Reviewed-by: o desenvolvedor nomeado revisou o patch para verificar sua + correção; veja a declaração do revisor em + :ref:`Documentation/process/submitting-patches.rst <submittingpatches>` + para mais detalhes. + + - Reported-by: nomeia um usuário que relatou o problema que é corrigido por este + patch; este marcador é usado para dar crédito às pessoas (frequentemente sub- + valorizadas) que testam nosso código e nos informam quando as coisas não + funcionam corretamente. Nota: este marcador deve ser seguido por um marcador + Closes: apontando para o relato, a menos que o relato não esteja disponível na + web. O marcador Link: pode ser usado em vez de Closes: se o patch corrigir + apenas uma parte do(s) problema(s) relatado(s). + + - A Suggested-by: este marcador indica que a ideia do patch foi sugerida pela + pessoa nomeada e garante o crédito a ela pela ideia. Isso, espera-se, irá + inspirá-la a nos ajudar novamente no futuro. + + - Cc: a pessoa nomeada recebeu uma cópia do patch e teve a oportunidade de + comentar sobre ele. + +Tenha cuidado ao adicionar os marcadores mencionados acima aos seus patches, pois +todos, exceto Cc:, Reported-by: e Suggested-by:, precisam de permissão explícita +fontes da pessoa nomeada. Para esses três, a permissão implícita é suficiente se +a pessoa contribuiu para o kernel Linux usando esse nome e endereço de e-mail de +acordo com os arquivos do lore ou o histórico de commits — e, no caso de +Reported-by: e Suggested-by:, se fizeram o relato ou a sugestão publicamente. +Nota: o bugzilla.kernel.org é um local público nesse sentido, mas os endereços +de e-mail usados lá são privados; portanto, não os exponha em marcadores, a menos +que a pessoa os tenha usado em contribuições anteriores. + + +Enviando o patch +----------------- + +Antes de enviar seus patches por e-mail, há algumas outras coisas com as quais +você deve se preocupar: + + - Você tem certeza de que seu cliente de e-mail não vai corromper os patches? + Patches que sofreram alterações desnecessárias de espaço em branco ou quebra + de linha causadas pelo cliente de e-mail não serão aplicados na outra ponta + e, frequentemente, não serão examinados em detalhes. Se houver qualquer + dúvida, envie o patch para você mesmo e certifique-se de que ele chegue intacto. + + O documento :ref:`Documentation/process/email-clients.rst <email_clients>` + possui algumas dicas úteis sobre como fazer clientes de e-mail específicos + funcionarem para o envio de patches. + + - Você tem certeza de que seu patch está livre de erros bobos? Você deve sempre + passar os patches pelo scripts/checkpatch.pl e corrigir as reclamações que + ele apresentar. Por favor, tenha em mente que o checkpatch.pl, embora seja a + personificação de uma quantidade razoável de reflexão sobre como os patches do + kernel devem parecer, não é mais inteligente que você. Se corrigir uma + reclamação do checkpatch.pl piorar o código, não o faça. + +Os patches devem sempre ser enviados como texto simples (plain text). Por favor, +não os envie como anexos; isso torna muito mais difícil para os revisores citarem +trechos do patch em suas respostas. Em vez disso, coloque o patch diretamente no +corpo da sua mensagem. + +Ao enviar patches por e-mail, é importante enviar cópias para qualquer pessoa +que possa estar interessada neles. Ao contrário de alguns outros projetos, o +kernel incentiva as pessoas a pecarem pelo excesso, enviando cópias demais; não +assuma que as pessoas relevantes verão sua publicação nas listas de discussão. Em +particular, as cópias devem ir para: + +- O(s) mantenedor(es) do(s) subsistema(s) afetado(s). Como descrito antes, o + arquivo MAINTAINERS é o primeiro lugar para procurar por essas pessoas. + + - Outros desenvolvedores que estiveram trabalhando na mesma área — especialmente + aqueles que possam estar trabalhando lá agora. Usar o git para ver quem mais + modificou os arquivos nos quais você está trabalhando pode ser útil. + + - Se você estiver respondendo a um relato de bug ou a uma solicitação de recurso + (feature request), envie uma cópia também para o autor original. + + - Envie uma cópia para a lista de discussão relevante ou, se nada mais se + aplicar, para a lista linux-kernel. + + - Se você estiver corrigindo um bug, pense se a correção deve ir para a próxima + atualização estável (stable update). Se sim, stable@vger.kernel.org deve + receber uma cópia do patch. Adicione também um "Cc: stable@vger.kernel.org" + aos marcadores (tags) dentro do próprio patch; isso fará com que a equipe do + stable receba uma notificação quando sua correção for integrada ao mainline. + +Ao selecionar os destinatários para um patch, é bom ter uma ideia de quem você +acha que eventualmente aceitará o patch e fará a mesclagem (merge). Embora seja +possível enviar patches diretamente para Linus Torvalds e fazer com que ele os +mescle, as coisas normalmente não são feitas dessa forma. Linus está ocupado, e +existem mantenedores de subsistemas que vigiam partes específicas do kernel. Em +geral, você desejará que esse mantenedor mescle seus patches. Se não houver um +mantenedor óbvio, Andrew Morton costuma ser o destino de patch de último recurso. + +Os patches precisam de boas linhas de assunto (subject lines). O formato canônico +para a linha de um patch é algo como: + +:: + + + [PATCH nn/mm] subsys: descrição de uma linha do patch + +onde "nn" é o número ordinal do patch, "mm" é o número total de patches na +série, e "subsys" é o nome do subsistema afetado. Claramente, nn/mm pode ser +omitido no caso de um patch único e isolado (standalone). + +Se você tiver uma série significativa de patches, é costumeiro enviar uma +descrição introdutória como a parte zero. Essa convenção não é seguida +universalmente, no entanto; se você a utilizar, lembre-se de que as informações +da introdução não entram nos changelogs do kernel. Portanto, certifique-se de +que os patches, em si, possuam informações completas em seus changelogs. + +Em geral, a segunda parte e as subsequentes de um patch de múltiplas partes devem +ser enviadas como uma resposta à primeira parte, de modo que todas formem uma +única linha de discussão (thread) na ponta receptora. Ferramentas como o git e o +quilt possuem comandos para enviar por e-mail um conjunto de patches com o +encadeamento correto. Se você tiver uma série longa, contudo, e estiver usando o +git, por favor, evite a opção --chain-reply-to para não criar um aninhamento +excepcionalmente profundo. diff --git a/Documentation/translations/pt_BR/process/6.Followthrough.rst b/Documentation/translations/pt_BR/process/6.Followthrough.rst new file mode 100644 index 000000000000..d6bdaa2cb8a4 --- /dev/null +++ b/Documentation/translations/pt_BR/process/6.Followthrough.rst @@ -0,0 +1,220 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Acompanhamento +============== + +Neste ponto, você seguiu as diretrizes apresentadas até aqui e, com a +adição de suas próprias habilidades de engenharia, enviou uma série perfeita +de patches. Um dos maiores erros que até mesmo desenvolvedores experientes +do kernel podem cometer é concluir que o seu trabalho agora está concluído. +Na verdade, o envio de patches indica uma transição para a próxima etapa +do processo, possivelmente com uma quantidade considerável de trabalho +ainda por fazer. + +É raro um patch ser tão bom em seu primeiro envio que não haja margem para +melhorias. O processo de desenvolvimento do kernel reconhece esse fato e, +como resultado, é fortemente orientado para o aprimoramento do código +enviado. Espera-se que você, como autor desse código, trabalhe junto à +comunidade do kernel para garantir que seu código esteja de acordo com os +padrões de qualidade do kernel. A falha em participar desse processo muito +provavelmente impedirá a inclusão de seus patches na árvore principal +(*mainline*). + + +Trabalhando com revisores +------------------------- + +Um patch de qualquer relevância resultará em uma série de comentários de outros +desenvolvedores à medida que eles revisam o código. Trabalhar com revisores +pode ser, para muitos desenvolvedores, a parte mais intimidadora do processo +de desenvolvimento do kernel. No entanto, a vida pode se tornar muito mais +fácil se você mantiver algumas coisas em mente: + +* Se você explicou bem o seu patch, os revisores entenderão o seu valor + e o porquê de você ter tido o trabalho de escrevê-lo. Contudo, esse valor + não os impedirá de fazer uma pergunta fundamental: como será manter um + kernel com este código inserido nele daqui a cinco ou dez anos? Muitas das + mudanças que podem lhe pedir para fazer — desde ajustes de estilo de código + até reescritas substanciais — vêm do entendimento de que o Linux ainda estará + por aqui e sob desenvolvimento daqui a uma década. + +* A revisão de código é um trabalho árduo e uma ocupação relativamente + ingrata; as pessoas lembram quem escreveu o código do kernel, mas há pouca + fama duradoura para aqueles que o revisaram. Portanto, os revisores podem + ficar ranzinzas, especialmente quando veem os mesmos erros sendo cometidos + repetidamente. Se você receber uma revisão que pareça irritada, insultuosa + ou abertamente ofensiva, resista ao impulso de responder à altura. A revisão + de código diz respeito ao código, não às pessoas, e os revisores de código + não estão atacando você pessoalmente. + +* Da mesma forma, os revisores de código não estão tentando promover os + interesses de seus empregadores em detrimento dos seus. Os desenvolvedores + do kernel geralmente esperam continuar trabalhando no kernel daqui a muitos + anos, mas entendem que seu empregador pode mudar. Quase sem exceção, eles + estão verdadeiramente trabalhando em prol da criação do melhor kernel possível; + eles não estão tentando causar desconforto aos concorrentes de seus empregadores. + +* Esteja preparado para solicitações aparentemente tolas de mudanças no estilo + de codificação e pedidos para refatorar parte do seu código em seções + compartilhadas do kernel. Uma das funções dos mantenedores é manter as coisas + com a mesma aparência. Às vezes, isso significa que aquele truque inteligente + (*clever hack*) em seu driver para contornar um problema + +Note que você não precisa concordar com todas as mudanças sugeridas pelos +revisores. Se você acredita que o revisor entendeu mal o seu código, explique +o que realmente está acontecendo. Se tiver uma objeção técnica a uma mudança +sugerida, descreva-a e justifique a sua solução para o problema. Se as suas +explicações fizerem sentido, o revisor as aceitará. Contudo, caso a sua +explicação não seja persuasiva — especialmente se outros começarem a concordar +com o revisor —, reserve um tempo para repensar as coisas. Pode ser fácil ficar +ceguificado por sua própria solução para um problema, a ponto de não perceber +que algo está fundamentalmente errado ou que, talvez, você não esteja sequer +resolvendo o problema certo. + +Andrew Morton sugeriu que todo comentário de revisão que não resulte em uma +alteração de código deveria, em vez disso, resultar em um comentário adicional +no próprio código; isso pode ajudar os futuros revisores a evitar as dúvidas +que surgiram da primeira vez. + +Um erro fatal é ignorar os comentários de revisão na esperança de que eles +desapareçam. Eles não vão desaparecer. Se você reenviar o código sem ter +respondido aos comentários que recebeu da vez anterior, é provável que descubra +que os seus patches não vão a lugar nenhum. + +Por falar em reenviar código: tenha em mente que os revisores não vão se +lembrar de todos os detalhes do código que você enviou da última vez. Portanto, +é sempre uma boa ideia lembrar os revisores dos problemas levantados +anteriormente e de como você lidou com eles; o registro de alterações +(*changelog*) do patch é um bom lugar para esse tipo de informação. Os revisores +não deveriam ter que vasculhar os arquivos das listas de discussão para se +familiarizarem com o que foi dito na última vez; se você ajudá-los a começar +com o pé direito, eles estarão de melhor humor quando revisitarem o seu código. + +E se você tentou fazer tudo certo e as coisas ainda não estão avançando? A +maioria das divergências técnicas pode ser resolvida por meio de discussão, +mas há momentos em que alguém simplesmente precisa tomar uma decisão. Se você +acredita genuinamente que essa decisão está indo contra você de forma errada, +você sempre pode tentar recorrer a uma instância superior. Até o momento em +que este texto foi escrito, essa instância superior costuma ser Andrew Morton. +Andrew goza de um enorme respeito na comunidade de desenvolvimento do kernel; +ele frequentemente consegue destravar uma situação que parece desesperadoramente +bloqueada. Recorrer a Andrew, no entanto, não deve ser feito de ânimo leve e nem +antes que todas as outras alternativas tenham sido esgotadas. E tenha em mente, +é claro, que ele também pode não concordar com você. + +O que acontece a seguir +----------------------- + +Se um patch for considerado algo bom para ser adicionado ao kernel, e assim +que a maioria dos problemas de revisão tiver sido resolvida, o próximo passo +geralmente é a entrada na árvore de um mantenedor de subsistema. Como isso +funciona varia de um subsistema para o outro; cada mantenedor tem sua própria +maneira de fazer as coisas. Em particular, pode haver mais de uma árvore — uma, +talvez, dedicada a patches planejados para a próxima janela de mesclagem +(*merge window*), e outra para trabalhos de longo prazo. + +Para patches que se aplicam a áreas para quais não há uma árvore de subsistema +óbvia (patches de gerenciamento de memória, por exemplo), a árvore padrão +geralmente acaba sendo a *-mm*. Patches que afetam múltiplos subsistemas +também podem acabar passando pela árvore *-mm*. + +A inclusão em uma árvore de subsistema pode trazer um nível mais alto de +visibilidade para um patch. Agora, outros desenvolvedores que trabalham com +aquela árvore receberão o patch por padrão. As árvores de subsistemas tipicamente +alimentam a *linux-next* também, tornando seus conteúdos visíveis para a +comunidade de desenvolvimento como um todo. Neste ponto, há uma boa chance de +você receber mais comentários de um novo conjunto de revisores; esses +comentários precisam ser respondidos da mesma forma que na rodada anterior. + +O que também pode acontecer neste ponto, dependendo da natureza do seu patch, +é surgirem conflitos com o trabalho que está sendo feito por outros. No pior +dos casos, conflitos pesados de patches podem fazer com que alguns trabalhos +sejam deixados em segundo plano, para que os patches restantes possam ser +ajustados e mesclados. Outras vezes, a resolução de conflitos envolverá trabalhar +junto a outros desenvolvedores e, possivelmente, mover alguns patches entre +árvores para garantir que tudo se aplique de forma limpa. Este trabalho pode ser +árduo, mas console-se com uma vantagem: antes do surgimento da árvore *linux-next*, +esses conflitos frequentemente só apareciam durante a janela de mesclagem e +tinham que ser resolvidos às pressas. Agora eles podem ser resolvidos com calma, +antes que a janela de mesclagem se abra. + +Um belo dia, se tudo correr bem, você fará login e verá que o seu patch foi +mesclado ao kernel principal (*mainline*). Parabéns! No entanto, assim que a +comemoração terminar (e você tiver se adicionado ao arquivo MAINTAINERS), vale +a pena lembrar de um pequeno fato importante: o trabalho ainda não acabou. A +mesclagem na árvore principal traz os seus próprios desafios. + +Para começar, a visibilidade do seu patch aumentou ainda mais. Pode haver +uma nova rodada de comentários de desenvolvedores que não estavam cientes do +patch antes. Pode ser tentador ignorá-los, já que não há mais nenhuma dúvida +sobre a mesclagem do seu código. No entanto, resista a essa tentação; você +ainda precisa ser receptivo aos desenvolvedores que tiverem dúvidas ou +sugestões. + +Mais importante ainda: a inclusão na árvore principal coloca o seu código +nas mãos de um grupo muito maior de testadores. Mesmo que você tenha contribuído +com um driver para um hardware que ainda não está disponível, você se +surpreenderá com a quantidade de pessoas que compilarão seu código em seus +próprios kernels. E, logicamente, onde há testadores, haverá relatórios de +erros (*bug reports*). + +O pior tipo de relatório de erro são as regressões (*regressions*). Se o seu +patch causar uma regressão, você descobrirá uma quantidade desconfortável de +olhos voltados para você; as regressões precisam ser corrigidas o mais rápido +possível. Se você não estiver disposto ou for incapaz de corrigir a regressão +(e ninguém mais fizer isso por você), seu patch quase certamente será removido +durante o período de estabilização. Além de anular todo o trabalho que você teve +para colocar seu patch na árvore principal, ter um patch removido como resultado +da falha em corrigir uma regressão pode muito bem tornar mais difícil para você +mesclar trabalhos no futuro. + +Depois que todas as regressões tiverem sido tratadas, pode haver outros erros +comuns com os quais lidar. O período de estabilização é a sua melhor oportunidade +para corrigir esses problemas e garantir que a estreia do seu código em um +lançamento do kernel principal seja o mais sólida possível. Portanto, por favor, +responda aos relatórios de erros e corrija os problemas, se for viável. É para +isso que serve o período de estabilização; você pode começar a criar novos +patches fantásticos assim que quaisquer problemas com os antigos tiverem sido +resolvidos. + +E não se esqueça de que existem outros marcos que também podem gerar relatórios +de erros: o próximo lançamento estável da árvore principal, o momento em que +distribuidores proeminentes adotarem uma versão do kernel que contenha o seu +patch, etc. Continuar respondendo a esses relatórios é uma questão de orgulho +básico pelo seu trabalho. Se isso não for motivação suficiente, contudo, também +vale a pena considerar que a comunidade de desenvolvimento se lembra dos +desenvolvedores que perdem o interesse em seu próprio código após a mesclagem. +A próxima vez que você enviar um patch, eles o avaliarão sob a suposição de +que você não estará por perto para mantê-lo depois. + + +Outras coisas que podem acontecer +--------------------------------- + +Um dia, você poderá abrir o seu cliente de e-mail e ver que alguém lhe enviou +um patch para o seu código. Afinal, essa é uma das vantagens de ter o seu +código disponível publicamente. Se você concordar com o patch, poderá encaminhá-lo +para o mantenedor do subsistema (certifique-se de incluir uma linha ``From:`` +adequada para que a atribuição de autoria esteja correta e adicione a sua +própria assinatura — *signoff*) ou enviar uma resposta com um ``Acked-by:`` +e deixar que o remetente original o envie para cima. + +Se você não concordar com o patch, envie uma resposta educada explicando o +motivo. Se possível, diga ao autor quais alterações precisam ser feitas para +que o patch seja aceitável para você. Existe uma certa resistência em mesclar +patches que sofrem oposição do autor e mantenedor do código, mas isso tem limite. +Se você for visto como alguém que está bloqueando um bom trabalho sem necessidade, +esses patches eventualmente seguirão outro fluxo ao seu redor e entrarão na +árvore principal de qualquer maneira. No kernel do Linux, ninguém tem poder de +veto absoluto sobre nenhum código. Exceto, talvez, o Linus. + +Em ocasiões muito raras, você poderá ver algo completamente diferente: outro +desenvolvedor envia uma solução diferente para o seu problema. Nesse ponto, +as chances são de que um dos dois patches não seja mesclado, e o argumento +"o meu chegou primeiro" não é considerado um argumento técnico convincente. +Se o patch de outra pessoa deslocar o seu e entrar na árvore principal, existe +realmente apenas uma maneira de responder: fique satisfeito pelo fato de o seu +problema ter sido resolvido e siga adiante com o seu trabalho. Ter o próprio +trabalho deixado de lado dessa maneira pode ser doloroso e desanimador, mas a +comunidade se lembrará da sua reação muito depois de terem esquecido de quem +foi o patch que realmente foi mesclado. diff --git a/Documentation/translations/pt_BR/process/7.AdvancedTopics.rst b/Documentation/translations/pt_BR/process/7.AdvancedTopics.rst new file mode 100644 index 000000000000..97466fad1994 --- /dev/null +++ b/Documentation/translations/pt_BR/process/7.AdvancedTopics.rst @@ -0,0 +1,201 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Tópicos avançados +================= + +Neste ponto, esperamos que você já tenha uma boa noção de como funciona o +processo de desenvolvimento. No entanto, ainda há mais a aprender! Esta seção +cobrirá uma série de tópicos que podem ser úteis para desenvolvedores que +desejam se tornar parte regular do processo de desenvolvimento do kernel Linux. + +Gerenciamento de patches com o git +---------------------------------- + +O uso de controle de versão distribuído para o kernel começou no início de +2002, quando Linus começou a testar o aplicativo proprietário BitKeeper. +Embora o BitKeeper fosse controverso, a abordagem de gerenciamento de versão +de software que ele incorporava certamente não era. O controle de versão +distribuído permitiu uma aceleração imediata do projeto de desenvolvimento do +kernel. Atualmente, existem várias alternativas gratuitas ao BitKeeper. Para o +bem ou para o mal, o projeto do kernel adotou o git como sua ferramenta de +escolha. + +Gerenciar patches com o git pode facilitar muito a vida do desenvolvedor, +especialmente à medida que o volume desses patches cresce. O git também tem suas +pontas soltas e apresenta certos riscos; é uma ferramenta jovem e poderosa que +ainda está sendo refinada por seus desenvolvedores. Este documento não tentará +ensinar o leitor a usar o git; isso seria material suficiente para um documento +longo por si só. Em vez disso, o foco aqui será em como o git se encaixa +especificamente no processo de desenvolvimento do kernel. Os desenvolvedores +que desejam se atualizar com o git encontrarão mais informações em: + + https://git-scm.com/ + + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + +e em vários tutoriais encontrados na web. + +A primeira ordem do dia é ler os sites acima e obter uma compreensão sólida de +como o git funciona antes de tentar usá-lo para disponibilizar patches para +outros. Um desenvolvedor que utiliza o git deve ser capaz de obter uma cópia do +repositório principal, explorar o histórico de revisões, comitar alterações na +árvore, usar branches, etc. A compreensão das ferramentas do git para a +reescrita de histórico (como o rebase) também é útil. O git vem com sua própria +terminologia e conceitos; um novo usuário do git deve saber sobre refs, remote +branches, o index, fast-forward merges, pushes e pulls, detached HEADs, etc. +Tudo isso pode ser um pouco intimidante no início, mas os conceitos não são tão +difíceis de entender com um pouco de estudo. + +Usar o git para gerar patches para submissão por e-mail pode ser um bom exercício +enquanto você se atualiza. + +Quando estiver pronto para começar a disponibilizar árvores git para que outros +possam examinar, você, logicamente, precisará de um servidor a partir do qual um +pull possa ser feito. Configurar um servidor desse tipo com o git-daemon é +relativamente simples se você tiver um sistema acessível à internet. Caso +contrário, sites de hospedagem públicos e gratuitos (o GitHub, por exemplo) +estão começando a surgir na rede. Desenvolvedores estabelecidos podem obter uma +conta no kernel.org, mas estas não são fáceis de conseguir; consulte +https://kernel.org/faq/ para mais informações. + +O fluxo de trabalho normal do git envolve o uso de muitas branches. Cada linha +de desenvolvimento pode ser separada em uma "topic branch" distinta e mantida de +forma independente. Branches no git são baratas, não há razão para não fazer um +uso livre delas. E, em qualquer caso, você não deve fazer o seu desenvolvimento +em nenhuma branch a partir da qual pretenda pedir para que outros deem pull. +Branches disponíveis publicamente devem ser criadas com cuidado; mescle patches +de branches de desenvolvimento quando eles estiverem em sua forma final e prontos +para seguir em frente — não antes. + +O git fornece algumas ferramentas poderosas que podem permitir que você +reescreva o seu histórico de desenvolvimento. Um patch inconveniente (um que +quebre o bisection, por exemplo, ou que tenha algum outro tipo de bug óbvio) +pode ser corrigido localmente ou feito desaparecer completamente do histórico. +Uma série de patches pode ser reescrita como se tivesse sido escrita no topo da +linha principal de hoje, mesmo que você esteja trabalhando nela há meses. As +alterações podem ser movidas de forma transparente de uma branch para outra. E +assim por diante. O uso criterioso da capacidade do git de revisar o histórico +pode ajudar na criação de conjuntos de patches limpos e com menos problemas. + +O uso excessivo dessa capacidade pode levar a outros problemas, no entanto, além +de uma simples obsessão pela criação do histórico de projeto perfeito. Reescrever +o histórico reescreverá as alterações contidas nele, transformando uma árvore do +kernel testada (assim se espera) em uma não testada. Mas, além disso, os +desenvolvedores não podem colaborar facilmente se não tiverem uma visão +compartilhada do histórico do projeto; se você reescrever o histórico que outros +desenvolvedores já deram pull em seus repositórios, tornará a vida deles muito +mais difícil. Portanto, uma regra prática simples se aplica aqui: o histórico +que foi exportado para terceiros deve ser visto geralmente como imutável dali em +diante. + +Sendo assim, uma vez que você faz o push de um conjunto de alterações para o seu +servidor disponível publicamente, essas alterações não devem ser reescritas. O +git tentará aplicar essa regra se você tentar dar push em alterações que não +resultem em um fast-forward merge (ou seja, alterações que não compartilham o +mesmo histórico). É possível anular essa verificação, e pode haver momentos em +que seja necessário reescrever uma árvore exportada. Mover changesets entre +árvores para evitar conflitos na linux-next é um exemplo. No entanto, tais ações +devem ser raras. Esta é uma das razões pelas quais o desenvolvimento deve ser +feito em branches privadas (que podem ser reescritas, se necessário) e apenas +movido para branches públicas quando estiver em um estado razoavelmente avançado. + +À medida que a linha principal (ou outra árvore na qual um conjunto de +alterações se baseia) avança, é tentador fazer o merge com essa árvore para +permanecer na vanguarda. Para uma branch privada, o rebasing pode ser uma maneira +fácil de acompanhar outra árvore, mas o rebasing não é uma opção uma vez que uma +árvore é exportada para o mundo. Quando isso acontece, um merge completo deve +ser feito. Fazer merges ocasionalmente faz todo o sentido, mas merges excessivamente +frequentes podem poluir o histórico desnecessariamente. A técnica sugerida neste +caso é fazer merges raramente, e geralmente apenas em release points específicos +(como um lançamento -rc da linha principal). Se você estiver inseguro sobre +mudanças específicas, sempre poderá realizar merges de teste em uma branch +privada. A ferramenta "rerere" do git pode ser útil nessas situações; ela se +lembra de como os conflitos de merge foram resolvidos para que você não precise +fazer o mesmo trabalho duas vezes. + +Uma das maiores reclamações recorrentes sobre ferramentas como o git é esta: o +movimento em massa de patches de um repositório para outro torna fácil a +inclusão de mudanças desaconselháveis que entram na linha principal abaixo do +radar de revisão. Os desenvolvedores do kernel costumam ficar descontentes quando +veem esse tipo de coisa acontecer; disponibilizar uma árvore git com patches não +revisados ou fora do tópico pode afetar a sua capacidade de ter suas árvores +puxadas no futuro. Citando Linus: + +:: + + Você pode me enviar patches, mas para eu puxar um patch git de você, eu + preciso saber que você sabe o que está fazendo, e preciso ser capaz de + confiar nas coisas *sem* ter que ir lá e verificar cada mudança + individualmente à mão. + +(https://lwn.net/Articles/224135/). + +Para evitar esse tipo de situação, certifique-se de que todos os patches +dentro de uma determinada branch permaneçam estritamente alinhados ao tópico +associado; uma branch de "correções de drivers" não deveria fazer alterações no +código central de gerenciamento de memória. E, acima de tudo, não use uma árvore +git para burlar o processo de revisão. Publique ocasionalmente um resumo da +árvore na lista de discussão relevante e, quando for o momento certo, solicite +que a árvore seja incluída na linux-next. + +Se e quando outros começarem a enviar patches para inclusão em sua árvore, não +se esqueça de revisá-los. Certifique-se também de manter as informações corretas +de autoria; a ferramenta "am" do git faz o melhor que pode a esse respeito, mas +você pode ter que adicionar uma linha "From:" ao patch se ele tiver sido +retransmitido a você por terceiros. + +Ao solicitar um pull, certifique-se de fornecer todas as informações +relevantes: onde está a sua árvore, qual branch deve ser puxada e quais +alterações resultarão do pull. O comando git request-pull pode ser útil a esse +respeito; ele formatará a solicitação da maneira que outros desenvolvedores +esperam e também verificará se você se lembrou de dar push nessas alterações +para o servidor público. + + +Revisão de patches +------------------ + +Alguns leitores certamente objetarão a inclusão desta seção em "tópicos +avançados" sob o argumento de que mesmo desenvolvedores iniciantes do kernel +deveriam estar revisando patches. É certamente verdade que não há melhor maneira +de aprender a programar no ambiente do kernel do que examinando o código +postado por outros. Além disso, revisores estão sempre em falta; ao examinar o +código, você pode fazer uma contribuição significativa para o processo como um +todo. + +Revisar código pode ser uma perspectiva intimidadora, especialmente para um novo +desenvolvedor do kernel que pode se sentir nervoso em questionar — em público — +um código que foi postado por aqueles com mais experiência. No entanto, mesmo o +código escrito pelos desenvolvedores mais experientes pode ser aprimorado. Talvez +o melhor conselho para revisores (todos os revisores) seja este: formule os +comentários de revisão como perguntas em vez de críticas. Perguntar "como o lock +é liberado neste caminho?" sempre funcionará melhor do que afirmar "o bloqueio +aqui está errado." + +Outra técnica útil em caso de desacordo é pedir que outros se manifestem. Se uma +discussão chegar a um impasse após algumas trocas de mensagens, peça a opinião +de outros revisores ou mantenedores. Frequentemente, aqueles que concordam com +um revisor permanecem em silêncio, a menos que sejam solicitados. A opinião de +múltiplas pessoas carrega exponencialmente mais peso. + +Diferentes desenvolvedores revisarão o código sob diferentes pontos de vista. +Alguns estão preocupados principalmente com o estilo de codificação e se as +linhas de código possuem espaços em branco no final (trailing white space). +Outros se concentrarão principalmente em saber se a alteração implementada pelo +patch como um todo é algo bom para o kernel ou não. Ainda assim, outros buscarão +por bloqueios problemáticos, uso excessivo de pilha (stack usage), possíveis +problemas de segurança, duplicação de código encontrado em outros lugares, +documentação adequada, efeitos adversos no desempenho, alterações na ABI do +espaço do usuário (user-space ABI), etc. Todos os tipos de revisão, se levarem a +um código melhor entrando no kernel, são bem-vindos e valem a pena. + +Não há exigência estrita para o uso de tags específicas como ``Reviewed-by``. Na +verdade, revisões em texto simples são mais informativas e incentivadas mesmo +quando uma tag é fornecida, por exemplo: "Analisei os aspectos A, B e C deste +envio e tudo me parece correto." Alguma forma de mensagem de revisão ou resposta +é obviamente necessária, caso contrário, os mantenedores não saberão que o +revisor sequer examinou o patch! + +Por último, mas não menos importante, a revisão de patches pode se tornar um +processo negativo, focado em apontar problemas. Por favor, reserve um elogio de +vez em quando, particularmente para os novatos! diff --git a/Documentation/translations/pt_BR/process/8.Conclusion.rst b/Documentation/translations/pt_BR/process/8.Conclusion.rst new file mode 100644 index 000000000000..d5af31e7c4d9 --- /dev/null +++ b/Documentation/translations/pt_BR/process/8.Conclusion.rst @@ -0,0 +1,73 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Para mais informações +===================== + +Há inúmeras fontes de informação sobre o desenvolvimento do kernel Linux e +tópicos relacionados. A primeira delas sempre será o diretório Documentation +encontrado na distribuição do código-fonte do kernel. Comece com o arquivo de +nível superior :ref:`process/howto.rst <process_howto>`; leia também +:ref:`process/submitting-patches.rst <submittingpatches>`. Muitas APIs internas +do kernel são documentadas usando o mecanismo kerneldoc; "make htmldocs" ou +"make pdfdocs" podem ser usados para gerar esses documentos em formato HTML ou +PDF (embora a versão do TeX fornecida por algumas distribuições esbarre em +limites internos e falhe em processar os documentos corretamente). + +Vários sites discutem o desenvolvimento do kernel em todos os níveis de +detalhes. O autor gostaria de sugerir humildemente o https://lwn.net/ como uma +fonte; informações sobre muitos tópicos específicos do kernel podem ser +encontradas através do índice do kernel do LWN em: + + https://lwn.net/Kernel/Index/ + +Além disso, um recurso valioso para os desenvolvedores do kernel é: + https://kernelnewbies.org/ + +E, claro, não se deve esquecer o https://kernel.org/, o local definitivo +para informações sobre os lançamentos do kernel. + +Há uma série de livros sobre o desenvolvimento do kernel: + + Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro + Rubini, and Greg Kroah-Hartman). Online at + https://lwn.net/Kernel/LDD3/. + + Linux Kernel Development (Robert Love). + + Understanding the Linux Kernel (Daniel Bovet and Marco Cesati). + +Todos esses livros, no entanto, sofrem de um defeito comum: eles tendem a estar +um pouco obsoletos quando chegam às prateleiras, e já estão nelas há algum +tempo. Ainda assim, há uma boa quantidade de informações úteis a serem +encontradas ali. + +A documentação para o git pode ser encontrada em: + + https://www.kernel.org/pub/software/scm/git/docs/ + + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + + +Conclusão +========= + +Parabéns a qualquer pessoa que tenha chegado ao fim deste documento longo e +detalhado. Esperamos que ele tenha fornecido uma compreensão útil de como o +kernel Linux é desenvolvido e de como você pode participar desse processo. + +No fim das contas, é a participação que importa. Qualquer projeto de software +de código aberto não é nada mais do que a soma do que seus colaboradores +dedicam a ele. O kernel Linux progrediu tão rápido e tão bem porque foi ajudado +por um grupo impressionantemente grande de desenvolvedores, todos trabalhando +para torná-lo melhor. O kernel é um exemplo primordial do que pode ser feito +quando milhares de pessoas trabalham juntas em direção a um objetivo comum. + +O kernel, no entanto, sempre pode se beneficiar de uma base maior de +desenvolvedores. Há sempre mais trabalho a fazer. Mas, de forma igualmente +importante, a maioria dos outros participantes do ecossistema Linux pode se +beneficiar ao contribuir para o kernel. Colocar o código na linha principal +(mainline) é a chave para uma maior qualidade de código, menores custos de +manutenção e distribuição, um nível mais alto de influência sobre a direção do +desenvolvimento do kernel e muito mais. É uma situação em que todos os +envolvidos ganham. Abra o seu editor e venha se juntar a nós; você será mais do +que bem-vindo. diff --git a/Documentation/translations/pt_BR/process/adding-syscalls.rst b/Documentation/translations/pt_BR/process/adding-syscalls.rst new file mode 100644 index 000000000000..cdf8b5033765 --- /dev/null +++ b/Documentation/translations/pt_BR/process/adding-syscalls.rst @@ -0,0 +1,700 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================================= +Adicionando uma Nova Chamada de Sistema +======================================= + +Este documento descreve o que está envolvido na adição de uma nova chamada de +sistema (system call) ao kernel Linux, indo além dos conselhos normais de +submissão em +:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`. + + +Alternativas às Chamadas de Sistema +----------------------------------- + +A primeira coisa a se considerar ao adicionar uma nova chamada de sistema é se +uma das alternativas poderia ser mais adequada. Embora as chamadas de sistema +sejam os pontos de interação mais tradicionais e óbvios entre o espaço do +usuário (userspace) e o kernel, existem outras possibilidades -- escolha o que +melhor se adapta à sua interface. + + - Se as operações envolvidas puderem ser moldadas para se parecerem com um + objeto do tipo arquivo, pode fazer mais sentido criar um novo sistema de + arquivos ou dispositivo. Isso também torna mais fácil encapsular a nova + funcionalidade em um módulo de kernel, em vez de exigir que ela seja + incorporada ao kernel principal. + + - Se a nova funcionalidade envolver operações em que o kernel notifica o + espaço do usuário de que algo aconteceu, retornar um novo descritor de + arquivo (file descriptor) para o objeto relevante permite que o espaço + do usuário use ``poll``/``select``/``epoll`` para receber essa + notificação. + - No entanto, as operações que não se mapeiam para operações do tipo + :manpage:`read(2)`/:manpage:`write(2)` precisam ser implementadas como + requisições :manpage:`ioctl(2)`, o que pode levar a uma API um tanto + quanto opaca. + + - Se você estiver apenas expondo informações do sistema em tempo de execução, + um novo nó no sysfs (veja ``Documentation/filesystems/sysfs.rst``) ou no + sistema de arquivos ``/proc`` pode ser mais apropriado. No entanto, o acesso + a esses mecanismos exige que o sistema de arquivos relevante esteja montado, + o que pode não ser sempre o caso (por exemplo, em um ambiente com namespaces, + sandboxed ou chrooted). Evite adicionar qualquer API ao debugfs, pois este + não é considerado uma interface de "produção" para o espaço do usuário. + - Se a operação for específica para um arquivo ou descritor de arquivo de um + determinado objeto, então uma opção de comando adicional para :manpage:`fcntl(2)` + pode ser mais adequada. Contudo, o :manpage:`fcntl(2)` é uma chamada de sistema + de multiplexação que oculta muita complexidade, portanto, esta opção é melhor + para quando a nova função for intimamente análoga à funcionalidade existente + do :manpage:`fcntl(2)`, ou se a nova funcionalidade for muito simples (por + exemplo, obter/definir uma flag simples relacionada a um descritor de arquivo). + - Se a operação for específica para uma tarefa (task) ou processo específico, + então uma opção de comando adicional para :manpage:`prctl(2)` pode ser mais + apropriada. Assim como no caso do :manpage:`fcntl(2)`, esta chamada de sistema + é um multiplexador complicado, sendo melhor reservá-la para análogos próximos + de comandos ``prctl()`` existentes ou para obter/definir uma flag simples + relacionada a um processo. + + +Projetando a API: Planejando a Extensibilidade +---------------------------------------------- + +Uma nova chamada de sistema faz parte da API do kernel e deve ser suportada +indefinidamente. Sendo assim, é uma excelente ideia discutir explicitamente a +interface na lista de discussão do kernel (LKML), e é crucial planejar extensões +futuras para essa interface. + +(A tabela de chamadas de sistema está repleta de exemplos históricos onde isso +não foi feito, juntamente com as respectivas chamadas de sistema de acompanhamento +-- ``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``, +``pipe``/``pipe2``, ``renameat``/``renameat2`` -- portanto, aprenda com a história +do kernel e planeje as extensões desde o início.) + +Para chamadas de sistema mais simples que recebem apenas alguns argumentos, a +maneira preferencial de permitir extensibilidade futura é incluir um argumento de +flags na chamada de sistema. Para garantir que os programas do espaço do usuário +possam usar flags de forma segura entre diferentes versões do kernel, verifique +se o valor de flags contém qualquer flag desconhecida e rejeite a chamada de +sistema (com ``EINVAL``) se contiver:: + + if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3)) + return -EINVAL; + +(Se nenhum valor de flag for utilizado ainda, verifique se o argumento de flags +é zero.) + +Para chamadas de sistema mais sofisticadas que envolvem um número maior de +argumentos, prefere-se encapsular a maioria dos argumentos em uma estrutura +(struct) que é passada por meio de um ponteiro. Esse tipo de estrutura pode +lidar com extensões futuras incluindo um argumento de tamanho (size) na própria +estrutura:: + + struct xyzzy_params { + u32 size; /* o espaço do usuário define p->size = sizeof(struct xyzzy_params) */ + u32 param_1; + u64 param_2; + u64 param_3; + }; + +Desde que qualquer campo adicionado subsequentemente, digamos ``param_4``, seja +projetado de forma que um valor zero mantenha o comportamento anterior, isso +permitirá lidar com a divergência de versões em ambas as direções: + + - Para lidar com um programa de espaço do usuário mais novo chamando um kernel + mais antigo, o código do kernel deve verificar se qualquer memória além do + tamanho da estrutura que ele espera está zerada (efetivamente verificando + se ``param_4 == 0``). + - Para lidar com um programa de espaço do usuário mais antigo chamando um kernel + mais novo, o código do kernel pode preencher com zero (zero-extend) a + instância menor da estrutura (efetivamente definindo ``param_4 = 0``). + +Veja :manpage:`perf_event_open(2)` e a função ``perf_copy_attr()`` (em +``kernel/events/core.c``) para um exemplo desta abordagem. + + +Projetando a API: Outras Considerações +-------------------------------------- + +Se a sua nova chamada de sistema permitir que o espaço do usuário se refira a +um objeto do kernel, ela deve usar um descritor de arquivo (file descriptor) +como o handle (identificador) para esse objeto -- não invente um novo tipo de +handle de objeto para o espaço do usuário quando o kernel já possui mecanismos +e semânticas bem definidas para o uso de descritores de arquivo. + +Se a sua nova chamada de sistema (2) de fato retornar un novo descritor de +arquivo, então o argumento de flags deve incluir um valor que seja equivalente +a definir ``O_CLOEXEC`` no novo FD. Isso torna possível para o espaço do usuário +fechar a janela de tempo entre a chamada ``()`` e a execução de +``fcntl(fd, F_SETFD, FD_CLOEXEC)``, onde um ``fork()`` e ``execve()`` inesperados +em outra thread poderiam vazar um descritor para o programa executado. (Contudo, +resista à tentação de reutilizar o valor real da constante ``O_CLOEXEC``, pois +ela é específica de cada arquitetura e faz parte de um espaço de numeração de +flags ``O_*`` que está bastante cheio.) + +Se a sua chamada de sistema retornar um novo descritor de arquivo, você também +deve considerar o que significa usar a família de chamadas de sistema +:manpage:`poll(2)` nesse descritor de arquivo. Tornar um descritor de arquivo +pronto para leitura ou escrita é a maneira normal de o kernel indicar ao espaço +do usuário que um evento ocorreu no objeto correspondente do kernel. + +Se a sua nova chamada de sistema (2) envolver um argumento de nome de arquivo +(filename):: + + int sys_xyzzy(const char __user *path, ..., unsigned int flags); + +você também deve considerar se uma versão xyzzyat(2) seria mais apropriada:: + + int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags); + +Isso permite maior flexibilidade para a forma como o espaço do usuário especifica +o arquivo em questão; em particular, permite que o espaço do usuário solicite a +funcionalidade para um descritor de arquivo já aberto usando a flag +``AT_EMPTY_PATH``, fornecendo efetivamente uma operação fxyzzy(3) de graça:: + + - xyzzyat(AT_FDCWD, path, ..., 0) é equivalente a (path,...) + - xyzzyat(fd, "", ..., AT_EMPTY_PATH) é equivalente a fxyzzy(fd, ...) + +(Para mais detalhes sobre a justificativa das chamadas \*at(), veja a página de +manual :manpage:`openat(2)`; para um exemplo de AT_EMPTY_PATH, veja a página de +manual :manpage:`fstatat(2)`.) + +Se a sua nova chamada de sistema (2) envolver um parâmetro que descreve um +deslocamento (offset) dentro de um arquivo, mude o seu tipo para ``loff_t`` para +que offsets de 64 bits possam ser suportados mesmo em arquiteturas de 32 bits. + +Se a sua nova chamada de sistema (2) envolver funcionalidades privilegiadas, +ela precisa ser governada pelo bit de capacidade (capability) do Linux apropriado +(verificado com uma chamada a ``capable()``), conforme descrito na página de +manual :manpage:`capabilities(7)`. Escolha um bit de capacidade existente que governe +funcionalidades relacionadas, mas tente evitar combinar muitas funções que tenham +apenas uma vaga relação sob o mesmo bit, pois isso vai contra o propósito das +capabilities de dividir o poder do root. Em particular, evite adicionar novos +usos para a capacidade ``CAP_SYS_ADMIN``, que já é excessivamente generalista. + +Se a sua nova chamada de sistema (2) manipular um processo diferente do +processo que a chamou, ela deve ser restrita (usando uma chamada a +``ptrace_may_access()``) para que apenas um processo chamador com as mesmas +permissões do processo alvo, ou com as capacidades necessárias, possa manipular +o processo alvo. + +Finalmente, esteja ciente de que algumas arquiteturas não-x86 lidam melhor se os +parâmetros da chamada de sistema que são explicitamente de 64 bits caírem em +argumentos de numeração ímpar (ou seja, parâmetro 1, 3, 5), para permitir o uso +de pares contíguos de registradores de 32 bits. (Esta preocupação não se aplica +se os argumentos fizerem parte de uma estrutura que é passada por meio de um +ponteiro.) + + +Propondo a API +-------------- + +Para tornar as novas chamadas de sistema fáceis de revisar, é melhor dividir o +conjunto de patches (patchset) em blocos separados. Estes devem incluir, pelo +menos, os seguintes itens como commits distintos (cada um dos quais é descrito +mais adiante): + + - A implementação central da chamada de sistema, juntamente com protótipos, + numeração genérica, alterações no Kconfig e a implementação de stub de realinhamento (fallback stub). + - A fiação (wiring up) da nova chamada de sistema para uma arquitetura em + particular, geralmente x86 (incluindo todas as variantes x86_64, x86_32 e x32). + - Uma demonstração do uso da nova chamada de sistema no espaço do usuário por + meio de um selftest em ``tools/testing/selftests/``. + - Um rascunho da página de manual (man-page) para a nova chamada de sistema, + seja como texto simples na carta de apresentação (cover letter) ou como um + patch para o repositório (separado) de man-pages. + +Novas propostas de chamadas de sistema, como qualquer alteração na API do +kernel, devem sempre ser enviadas com cópia (cc'ed) para linux-api@vger.kernel.org. + + +Implementação Genérica de Chamadas de Sistema +--------------------------------------------- + +O ponto de entrada principal para a sua nova chamada de sistema (2) será chamado +de ``sys_xyzzy()``, mas você deve adicionar esse ponto de entrada com a macro +``SYSCALL_DEFINEn()`` apropriada, em vez de fazer isso explicitamente. O 'n' +indica o número de argumentos da chamada de sistema, e a macro recebe o nome da +chamada de sistema seguido pelos pares (tipo, nome) para os parâmetros como +argumentos. O uso dessa macro permite que os metadados sobre a nova chamada de +sistema fiquem disponíveis para outras ferramentas. + +O novo ponto de entrada também precisa de um protótipo de função correspondente +em ``include/linux/syscalls.h``, marcado como asmlinkage para corresponder à +maneira como as chamadas de sistema são invocadas:: + + asmlinkage long sys_xyzzy(...); + +Algumas arquiteturas (por exemplo, x86) possuem suas próprias tabelas de syscall +específicas da arquitetura, mas várias outras arquiteturas compartilham uma tabela +de syscall genérica. Adicione a sua nova chamada de sistema à lista genérica +adicionando uma entrada na lista em ``include/uapi/asm-generic/unistd.h``:: + + #define __NR_xyzzy 292 + __SYSCALL(__NR_xyzzy, sys_xyzzy) + +Atualize também a contagem de __NR_syscalls para refletir a chamada de sistema +adicional, e observe que se múltiplas novas chamadas de sistema forem adicionadas +na mesma janela de mesclagem (merge window), o número da sua nova syscall poderá +ser ajustado para resolver conflitos. + +O arquivo ``kernel/sys_ni.c`` fornece uma implementação de stub de fallback para +cada chamada de sistema, retornando ``-ENOSYS``. Adicione a sua nova chamada de +sistema aqui também:: + + COND_SYSCALL(sys_xyzzy); + +A sua nova funcionalidade de kernel, e a chamada de sistema que a controla, deve +normalmente ser opcional, portanto adicione uma opção ``CONFIG`` (tipicamente em +``init/Kconfig``) para ela. Como de costume para novas opções ``CONFIG``: + + - Inclua uma descrição da nova funcionalidade e da chamada de sistema controlada + pela opção. + - Faça a opção depender de EXPERT se ela deve ser ocultada dos usuários normais. + - Faça com que quaisquer novos arquivos de código-fonte que implementem a função + sejam dependentes da opção CONFIG no Makefile (por exemplo, + ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``). + - Verifique duas vezes se o kernel ainda compila com a nova opção CONFIG desativada. + +Para resumir, você precisa de um commit que inclua: + + - Opção ``CONFIG`` para a nova função, normalmente em ``init/Kconfig`` + - ``SYSCALL_DEFINEn(, ...)`` para o ponto de entrada + - Protótipo correspondente em ``include/linux/syscalls.h`` + - Entrada na tabela genérica em ``include/uapi/asm-generic/unistd.h`` + - Stub de fallback em ``kernel/sys_ni.c`` + + +.. _pt_BR_syscall_generic_6_11: + +Desde a versão 6.11 +~~~~~~~~~~~~~~~~~~~ + +A partir da versão 6.11 do kernel, a implementação de chamadas de sistema +genéricas para as seguintes arquiteturas não requer mais modificações em +``include/uapi/asm-generic/unistd.h``: + + - arc + - arm64 + - csky + - hexagon + - loongarch + - nios2 + - openrisc + - riscv + +Em vez disso, você precisa atualizar ``scripts/syscall.tbl`` e, se aplicável, +ajustar ``arch/*/kernel/Makefile.syscalls``. + +Como o ``scripts/syscall.tbl`` serve como uma tabela de syscall comum para +múltiplas arquiteturas, uma nova entrada é necessária nesta tabela:: + + 468 common sys_xyzzy + +Note que adicionar uma entrada ao ``scripts/syscall.tbl`` com a ABI "common" +também afeta todas as arquiteturas que compartilham essa tabela. Para alterações +mais limitadas ou específicas de uma arquitetura, considere usar uma ABI +específica da arquitetura ou definir uma nova. + +Se uma nova ABI, digamos ``xyz``, for introduzida, as atualizações +correspondentes também devem ser feitas em ``arch/*/kernel/Makefile.syscalls``:: + + syscall_abis_{32,64} += xyz (...) + +Para resumir, você precisa de um commit que inclua: + + - Opção ``CONFIG`` para a nova função, normalmente em ``init/Kconfig`` + - ``SYSCALL_DEFINEn(, ...)`` para o ponto de entrada + - Protótipo correspondente em ``include/linux/syscalls.h`` + - Nova entrada em ``scripts/syscall.tbl`` + - (Se necessário) Atualizações de Makefile em ``arch/*/kernel/Makefile.syscalls`` + - Stub de fallback em ``kernel/sys_ni.c`` + + +Implementação de Chamadas de Sistema em x86 +------------------------------------------- + +Para interligar (wire up) a sua nova chamada de sistema nas plataformas x86, você +precisa atualizar as tabelas mestras de syscall. Assumindo que a sua nova chamada +de sistema não seja especial de alguma forma (veja abaixo), isso envolve uma +entrada "common" (para x86_64 e x32) em +``arch/x86/entry/syscalls/syscall_64.tbl``:: + + 333 common sys_xyzzy + +e uma entrada "i386" em ``arch/x86/entry/syscalls/syscall_32.tbl``:: + + 380 i386 sys_xyzzy + +Novamente, esses números estão sujeitos a alterações caso ocorram conflitos na +janela de mesclagem (merge window) relevante. + +Chamadas de Sistema de Compatibilidade (Genéricas) +-------------------------------------------------- + +Para a maioria das chamadas de sistema, a mesma implementação de 64 bits pode +ser invocada mesmo quando o programa do espaço do usuário é, ele próprio, de 32 +bits; mesmo se os parâmetros da chamada de sistema incluírem um ponteiro +explícito, isso é tratado de forma transparente. + +No entanto, existem algumas situações em que uma camada de compatibilidade +(compatibility layer) é necessária para lidar com as diferenças de tamanho entre +32 bits e 64 bits. + +A primeira é se o kernel de 64 bits também suportar programas de espaço do +usuário de 32 bits e, portanto, precisar analisar áreas de memória +(``__user``) que poderiam conter valores de 32 bits ou 64 bits. Em particular, +isso é necessário sempre que um argumento de chamada de sistema for: + + - um ponteiro para um ponteiro + - um ponteiro para uma struct que contém um ponteiro (por exemplo, + ``struct iovec __user *``) + - um ponteiro para um tipo integral de tamanho variável (``time_t``, + ``off_t``, ``long``, ...) + - um ponteiro para uma struct que contém um tipo integral de tamanho variável. + +A segunda situação que requer uma camada de compatibilidade é se um dos +argumentos da chamada de sistema tiver um tipo que é explicitamente de 64 bits, +mesmo em uma arquitetura de 32 bits, por exemplo, ``loff_t`` ou ``__u64``. Neste +caso, um valor que chega ao kernel de 64 bits vindo de uma aplicação de 32 bits +será dividido em dois valores de 32 bits, que precisarão ser remontados na +camada de compatibilidade. + +(Note que um argumento de chamada de sistema que seja um ponteiro para um tipo +explícito de 64 bits **não** precisa de uma camada de compatibilidade; por +exemplo, os argumentos do :manpage:`splice(2)` do tipo ``loff_t __user *`` não +disparam a necessidade de uma chamada de sistema ``compat_``.) + +A versão de compatibilidade da chamada de sistema é chamada de +``compat_sys_xyzzy()`` e é adicionada com a macro ``COMPAT_SYSCALL_DEFINEn()``, +de forma análoga à macro SYSCALL_DEFINEn. Esta versão da implementação roda como +parte de um kernel de 64 bits, mas espera receber valores de parâmetros de 32 +bits e faz o que for necessário para lidar com eles. (Tipicamente, a versão +``compat_sys_`` converte os valores para versões de 64 bits e chama a versão +``sys_``, ou ambas chamam uma função interna comum de implementação). + +O ponto de entrada compat também precisa de um protótipo de função +correspondente em ``include/linux/compat.h``, marcado como asmlinkage para +corresponder à maneira como as chamadas de sistema são invocadas:: + + asmlinkage long compat_sys_xyzzy(...); + +Se a chamada de sistema envolver uma estrutura cujo layout seja diferente em +sistemas de 32 bits e 64 bits, digamos ``struct xyzzy_args``, então o arquivo de +cabeçalho ``include/linux/compat.h`` também deve incluir uma versão compat da +estrutura (``struct compat_xyzzy_args``), onde cada campo de tamanho variável +tenha o tipo ``compat_`` correspondente ao tipo na ``struct xyzzy_args``. A +rotina ``compat_sys_xyzzy()`` pode então usar essa estrutura ``compat_`` para +analisar os argumentos vindos de uma invocação de 32 bits. + +Por exemplo, se existirem os campos:: + + struct xyzzy_args { + const char __user *ptr; + __kernel_long_t varying_val; + u64 fixed_val; + /* ... */ + }; + +na struct xyzzy_args, então a struct compat_xyzzy_args teria:: + + struct compat_xyzzy_args { + compat_uptr_t ptr; + compat_long_t varying_val; + u64 fixed_val; + /* ... */ + }; + +A lista genérica de chamadas de sistema também precisa de ajustes para permitir +a versão compat; a entrada em ``include/uapi/asm-generic/unistd.h`` deve usar +``__SC_COMP`` em vez de ``__SYSCALL``:: + + #define __NR_xyzzy 292 + __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy) + +Para resumir, você precisa de: + + - uma macro ``COMPAT_SYSCALL_DEFINEn(, ...)`` para o ponto de entrada compat + - protótipo correspondente em ``include/linux/compat.h`` + - (se necessário) struct de mapeamento de 32 bits em ``include/linux/compat.h`` + - instância de ``__SC_COMP``, e não de ``__SYSCALL``, em + ``include/uapi/asm-generic/unistd.h`` + +Desde a versão 6.11 +~~~~~~~~~~~~~~~~~~~ + +Isso se aplica a todas as arquiteturas listadas em +:ref:`Desde a versão 6.11<pt_BR_syscall_generic_6_11>` sob "Implementação Genérica de +Chamadas de Sistema", exceto arm64. Veja +:ref:`Chamadas de Sistema de Compatibilidade (arm64)<pt_BR_compat_arm64>` para mais +informações. + +Você precisa estender a entrada em ``scripts/syscall.tbl`` com uma coluna extra +para indicar que um programa de espaço do usuário de 32 bits rodando em um +kernel de 64 bits deve atingir o ponto de entrada compat:: + + 468 common sys_xyzzy compat_sys_xyzzy + +Para resumir, você precisa de: + + - ``COMPAT_SYSCALL_DEFINEn(, ...)`` para o ponto de entrada compat + - Protótipo correspondente em ``include/linux/compat.h`` + - Modificação da entrada em ``scripts/syscall.tbl`` para incluir uma coluna + "compat" extra + - (Se necessário) Struct de mapeamento de 32 bits em ``include/linux/compat.h`` + + +.. _pt_BR_compat_arm64: + +Chamadas de Sistema de Compatibilidade (arm64) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +No arm64, existe uma tabela de syscall dedicada para chamadas de sistema de +compatibilidade voltadas para o espaço do usuário de 32 bits (AArch32): +``arch/arm64/tools/syscall_32.tbl``. Você precisa adicionar uma linha adicional +a esta tabela especificando o ponto de entrada compat:: + + 468 common sys_xyzzy compat_sys_xyzzy + + +Chamadas de Sistema de Compatibilidade (x86) +-------------------------------------------- + +Para interligar a arquitetura x86 de uma chamada de sistema com uma versão de +compatibilidade, as entradas nas tabelas de syscall precisam ser ajustadas. + +Primeiro, a entrada em ``arch/x86/entry/syscalls/syscall_32.tbl`` ganha uma +coluna extra para indicar que um programa de espaço do usuário de 32 bits rodando +em um kernel de 64 bits deve atingir o ponto de entrada compat:: + + 380 i386 sys_xyzzy __ia32_compat_sys_xyzzy + +Segundo, você precisa definir o que deve acontecer para a versão da ABI x32 da +nova chamada de sistema. Há uma escolha aqui: o layout dos argumentos deve +corresponder à versão de 64 bits ou à versão de 32 bits. + +Se houver um ponteiro para um ponteiro envolvido, a decisão é fácil: x32 é +ILP32 (inteiro, long e ponteiro possuem 32 bits), portanto o layout deve +corresponder à versão de 32 bits, e a entrada em +``arch/x86/entry/syscalls/syscall_64.tbl`` é dividida para que os programas x32 +atinjam o wrapper de compatibilidade:: + + 333 64 sys_xyzzy + ... + 555 x32 __x32_compat_sys_xyzzy + +Se não houver ponteiros envolvidos, então é preferível reutilizar a chamada de +sistema de 64 bits para a ABI x32 (e, consequentemente, a entrada em +``arch/x86/entry/syscalls/syscall_64.tbl`` permanece inalterada). + +Em qualquer um dos casos, você deve verificar se os tipos envolvidos no layout +dos seus argumentos de fato se mapeiam exatamente do x32 (-mx32) para os seus +equivalentes de 32 bits (-m32) ou 64 bits (-m64). + + +Chamadas de Sistema com Retorno para Outro Local +------------------------------------------------ + +Para a maioria das chamadas de sistema (syscalls), assim que a execução é +concluída, o programa do usuário continua exatamente de onde parou -- na +próxima instrução, com a pilha idêntica e a maior parte dos registradores no +mesmo estado de antes da chamada, além do mesmo espaço de memória virtual. + +No entanto, algumas poucas chamadas de sistema agem de forma diferente. Elas +podem retornar para um local distinto (``rt_sigreturn``), alterar o espaço de +memória (``fork``/``vfork``/``clone``) ou até mesmo modificar a arquitetura +(``execve``/``execveat``) do programa. + +Para permitir isso, a implementação da chamada de sistema no kernel pode +precisar salvar e restaurar registradores adicionais na pilha do kernel, +garantindo controle total de onde e como a execução continuará após a syscall. + +Isso é específico de cada arquitetura (arch-specific), mas tipicamente envolve +a definição de pontos de entrada em assembly que salvam/restauram esses +registradores adicionais e invocam o ponto de entrada real da chamada de +sistema. + +Para x86_64, isso é implementado como um ponto de entrada ``stub_xyzzy`` em +``arch/x86/entry/entry_64.S``, e a entrada correspondente na tabela de syscalls +(``arch/x86/entry/syscalls/syscall_64.tbl``) é ajustada para refletir:: + + 333 common stub_xyzzy + +O equivalente para programas de 32 bits executados em um kernel de 64 bits é +normalmente chamado de ``stub32_xyzzy`` e implementado em +``arch/x86/entry/entry_64_compat.S``, com o respectivo ajuste na tabela de +syscalls em ``arch/x86/entry/syscalls/syscall_32.tbl``:: + + 380 i386 sys_xyzzy stub32_xyzzy + +Se a chamada de sistema precisar de uma camada de compatibilidade (como na +seção anterior), a versão ``stub32_`` precisará chamar a versão +``compat_sys_`` da chamada de sistema em vez da versão nativa de 64 bits. Além +disso, se a implementação da ABI x32 não for compartilhada com a versão +x86_64, sua tabela de syscalls também precisará invocar um stub que direcione +para a versão ``compat_sys_``. + +Por questões de integridade, também é recomendado configurar um mapeamento para +que o User-Mode Linux (UML) continue funcionando -- sua tabela de syscalls fará +referência a ``stub_xyzzy``, mas o build do UML não inclui a implementação de +``arch/x86/entry/entry_64.S`` (já que o UML simula registradores, etc.). Corrigir +isso é tão simples quanto adicionar um #define em +``arch/x86/um/sys_call_table_64.c``:: + + #define stub_xyzzy sys_xyzzy + + +Outros Detalhes +--------------- + +A maior parte do kernel trata as chamadas de sistema de maneira genérica, mas +há exceções ocasionais que podem precisar de atualização para a sua chamada +de sistema específica. + +O subsistema de auditoria (audit) é um desses casos especiais; ele inclui +funções (específicas de cada arquitetura) que classificam alguns tipos +especiais de chamada de sistema -- especificamente operações de abertura de +arquivo (``open``/``openat``), execução de programa (``execve``/``exeveat``) ou +multiplexador de socket (``socketcall``). Se a sua nova chamada de sistema for +análoga a uma dessas, o sistema de auditoria deverá ser atualizado. + +De forma mais geral, se existir uma chamada de sistema atual que seja análoga +à sua nova chamada de sistema, vale a pena fazer um grep em todo o kernel pela +chamada existente para verificar se não há outros casos especiais. + + +Testes +------ + +Uma nova chamada de sistema deve, obviamente, ser testada; também é útil +fornecer aos revisores uma demonstração de como os programas do espaço do +usuário (user space) usarão a chamada de sistema. Uma boa maneira de combinar +esses objetivos é incluir um programa simples de autoteste em um novo diretório +sob ``tools/testing/selftests/``. + +Para uma nova chamada de sistema, obviamente não haverá uma função de wrapper +na libc e, portanto, o teste precisará invocá-la usando ``syscall()``; além +disso, se a chamada de sistema envolver uma nova estrutura visível para o +espaço do usuário, o cabeçalho correspondente precisará ser instalado para +compilar o teste. + +Certifique-se de que o autoteste seja executado com sucesso em todas as +arquiteturas suportadas. Por exemplo, verifique se ele funciona quando compitado +como um programa ABI x86_64 (-m64), x86_32 (-m32) e x32 (-mx32). + +Para testes mais extensos e minuciosos de novas funcionalidades, você também +deve considerar a adição de testes ao Linux Test Project ou ao projeto +xfstests para alterações relacionadas + +Página de Manual (Man Page) +--------------------------- + +Todas as novas chamadas de sistema devem vir acompanhadas de uma página de +manual completa, idealmente usando a marcação groff, mas texto simples também +é aceitável. Se o groff for utilizado, é útil incluir uma versão ASCII pré- +renderizada da página de manual no e-mail de apresentação (cover letter) do +conjunto de patches (patchset), para a conveniência dos revisores. + +A página de manual deve ser enviada com cópia (cc) para +linux-man@vger.kernel.org. Para mais detalhes, consulte +https://www.kernel.org/doc/man-pages/patches.html + + +Não invoque Chamadas de Sistema dentro do Kernel +------------------------------------------------ + +As chamadas de sistema são, como mencionado acima, pontos de interação entre o +espaço do usuário (userspace) e o kernel. Portanto, funções de chamada de +sistema como ``sys_xyzzy()`` ou ``compat_sys_xyzzy()`` só devem ser chamadas a +partir do espaço do usuário por meio da tabela de syscalls, e não de outros +lugares do kernel. Se a funcionalidade da syscall for útil para ser utilizada +dentro do kernel, precisar ser compartilhada entre uma syscall antiga e uma +nova, ou precisar ser compartilhada entre uma syscall e sua variante de +compatibilidade, ela deve ser implementada por meio de uma função auxiliadora +("helper", como ``ksys_xyzzy()``). Essa função do kernel poderá então ser +chamada dentro do stub da syscall (``sys_xyzzy()``), do stub da syscall de +compatibilidade (``compat_sys_xyzzy()``) e/ou de outro código do kernel. + +Pelo menos em x86 de 64 bits, será um requisito rígido a partir da versão v4.17 +em diante não chamar funções de chamadas de sistema no kernel. Essa arquitetura +utiliza uma convenção de chamada diferente para chamadas de sistema na qual a +``struct pt_regs`` é decodificada dinamicamente em um wrapper de syscall, que +então repassa o processamento para a função real da syscall. Isso significa que +apenas os parâmetros realmente necessários para uma syscall específica são +passados durante a entrada da syscall, em vez de preencher seis registradores da +CPU com conteúdos aleatórios do espaço do usuário o tempo todo (o que poderia +causar problemas sérios no decorrer da cadeia de chamadas). + +Além disso, as regras sobre como os dados podem ser acessados diferem entre os +dados do kernel e os dados do usuário. Essa é outra razão pela qual chamar +``sys_xyzzy()`` geralmente é uma má ideia. + +Exceções a essa regra são permitidas apenas em substituições (overrides) +específicas de cada arquitetura, wrappers de compatibilidade específicos de cada +arquitetura ou outros códigos dentro do diretório arch/. + +Referências e Fontes +-------------------- + + - Artigo da LWN por Michael Kerrisk sobre o uso do argumento flags em chamadas + de sistema: + https://lwn.net/Articles/585415/ + - Artigo da LWN por Michael Kerrisk sobre como lidar com flags desconhecidas + em uma chamada de sistema: https://lwn.net/Articles/588444/ + - Artigo da LWN por Jake Edge descrevendo restrições em argumentos de chamadas + de sistema de 64 bits: https://lwn.net/Articles/311630/ + - Par de artigos da LWN por David Drysdale que descrevem detalhadamente os + caminhos de implementação de chamadas de sistema para a v3.14: + + - https://lwn.net/Articles/604287/ + - https://lwn.net/Articles/604515/ + + - Os requisitos específicos de arquitetura para chamadas de sistema são + discutidos na página de manual :manpage:`syscall(2)`: + http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES + - E-mails compilados de Linus Torvalds discutindo os problemas com ``ioctl()``: + https://yarchive.net/comp/linux/ioctl.html + - "How to not invent kernel interfaces", Arnd Bergmann, + https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf + - Artigo da LWN por Michael Kerrisk sobre evitar novos usos de CAP_SYS_ADMIN: + https://lwn.net/Articles/486306/ + - Recomendação de Andrew Morton para que todas as informações relacionadas a + uma nova chamada de sistema venham na mesma thread de e-mail: + https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org + - Recomendação de Michael Kerrisk para que uma nova chamada de sistema venha + acompanhada de uma página de manual: + https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com + - Sugestão de Thomas Gleixner para que a vinculação (wire-up) do x86 esteja em + um commit separado: + https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos + - Sugestão de Greg Kroah-Hartman de que é bom que novas chamadas de sistema + venham acompanhadas de uma página de manual e um autoteste: + https://lore.kernel.org/r/20140320025530.GA25469@kroah.com + - Discussão de Michael Kerrisk sobre uma nova chamada de sistema versus a + extensão de :manpage:`prctl(2)`: + https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com + - Sugestão de Ingo Molnar de que as chamadas de sistema que envolvem múltiplos + argumentos devem encapsular esses argumentos em uma struct, a qual inclua um + campo de tamanho (size) para fins de extensibilidade futura: + https://lore.kernel.org/r/20150730083831.GA22182@gmail.com + - Excentricidades de numeração decorrentes do uso (e reuso) de flags do espaço + de numeração O_*: + + - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness + check") + - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc + conflict") + - commit bb458c644a59 ("Safer ABI for O_TMPFILE") + + - Discussão de Matthew Wilcox sobre restrições em argumentos de 64 bits: + https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org + - Recomendação de Greg Kroah-Hartman de que flags desconhecidas devem ser + fiscalizadas/policiadas: + https://lore.kernel.org/r/20140717193330.GB4703@kroah.com + - Recomendação de Linus Torvalds de que as chamadas de sistema x32 devem + preferir a compatibilidade com as versões de 64 bits em vez das versões de + 32 bits: + https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com + - Série de patches revisando a infraestrutura da tabela de chamadas de sistema + para utilizar scripts/syscall.tbl em múltiplas arquiteturas: + https://lore.kernel.org/lkml/20240704143611.2979589-1-arnd@kernel.org diff --git a/Documentation/translations/pt_BR/process/applying-patches.rst b/Documentation/translations/pt_BR/process/applying-patches.rst new file mode 100644 index 000000000000..313401bc2335 --- /dev/null +++ b/Documentation/translations/pt_BR/process/applying-patches.rst @@ -0,0 +1,447 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Aplicando Patches ao Kernel Linux ++++++++++++++++++++++++++++++++++ + +Autor Original: + Jesper Juhl, Agosto de 2005 + +.. note:: + + Este documento está obsoleto. Na maioria dos casos, em vez de usar ``patch`` + manualmente, você quase certamente desejará considerar o uso do Git. + +Uma pergunta feita com frequência na Linux Kernel Mailing List é como aplicar +an patch ao kernel ou, mais especificamente, a qual kernel base um patch para +uma das muitas árvores/branches deve ser aplicado. Esperamos que este documento +explique isso a você. + +Além de explicar como aplicar e reverter patches, uma breve descrição das +diferentes árvores do kernel (e exemplos de como aplicar seus patches +específicos) também é fornecida. + + +O que é um Patch? +================= + +Um patch é um pequeno documento de texto que contém uma diferença (delta) de +alterações entre duas versões diferentes de uma árvore de código-fonte. Os +patches são criados com o programa ``diff``. + +Para aplicar um patch corretamente, você precisa saber de qual base ele foi +gerado e em qual nova versão o patch transformará a árvore de código-fonte. +Ambas as informações devem estar presentes nos metadados do arquivo de patch +ou ser possíveis de deduzir a partir do nome do arquivo. + + +Como eu aplico ou reverto um patch? +=================================== + +Você aplica um patch com o programa ``patch``. O programa patch lê um arquivo +de diff (ou patch) e faz as alterações descritas nele na árvore de +código-fonte. + +Os patches para o kernel Linux são gerados relativamente ao diretório pai que +contém o diretório do código-fonte do kernel. + +Isso significa que os caminhos para os arquivos dentro do arquivo de patch +contêm o nome dos diretórios do código-fonte do kernel contra os quais ele foi +gerado (ou alguns outros nomes de diretório como "a/" e "b/"). + +Como é improvável que isso corresponda ao nome do diretório do código-fonte do +kernel na sua máquina local (mas frequentemente é uma informação útil para ver +contra qual versão um patch sem identificação foi gerado), você deve entrar no +seu diretório de código-fonte do kernel e, em seguida, remover o primeiro +elemento do caminho dos nomes de arquivos no arquivo de patch ao aplicá-lo (o +argumento ``-p1`` para o ``patch`` faz isso). + +Para reverter um patch aplicado anteriormente, use o argumento -R para o patch. +Portanto, se você aplicou um patch desta forma:: + + patch -p1 < ../patch-x.y.z + +Você pode revertê-lo (desfazê-lo) assim:: + + patch -R -p1 < ../patch-x.y.z + + +Como eu passo um arquivo de patch/diff para o ``patch``? +======================================================== + +Isso (como de costume no Linux e em outros sistemas operacionais do tipo UNIX) +pode ser feito de várias maneiras diferentes. + +Em todos os exemplos abaixo, eu passo o arquivo (em formato não compactado) para +o patch via stdin usando a seguinte sintaxe:: + + patch -p1 < path/to/patch-x.y.z + +Se você quer apenas ser capaz de seguir os exemplos abaixo e não deseja +conhecer mais do que uma maneira de usar o patch, então você pode parar a +leitura desta seção aqui. + +O patch também pode receber o nome do arquivo a ser usado através do argumento +-i, desta forma:: + + patch -p1 -i path/to/patch-x.y.z + +Se o seu arquivo de patch estiver compactado com gzip ou xz e você não quiser +descompactá-lo antes de aplicá-lo, você pode passá-lo para o patch desta outra +forma:: + + xzcat path/to/patch-x.y.z.xz | patch -p1 + bzcat path/to/patch-x.y.z.gz | patch -p1 + +Se você deseja descompactar o arquivo de patch manualmente primeiro antes de +aplicá-lo (o que presumo que você tenha feito nos exemplos abaixo), basta +executar gunzip ou xz no arquivo -- desta forma:: + + gunzip patch-x.y.z.gz + xz -d patch-x.y.z.xz + +O que deixará você com um arquivo patch-x.y.z em texto puro que você pode +passar para o patch via stdin ou pelo argumento ``-i``, conforme sua preferência. + +Alguns outros argumentos úteis para o patch são ``-s``, que faz com que o patch +seja silencioso (exceto por erros), o que é bom para evitar que erros sumam da +tela rolando rápido demais; e ``--dry-run``, que faz com que o patch apenas +imprima uma lista do que aconteceria, mas sem realizar nenhuma alteração de +fato. Por fim, ``--verbose`` diz ao patch para imprimir mais informações sobre o +trabalho que está sendo realizado. + + +Erros comuns ao aplicar patches +=============================== + +Quando o patch aplica um arquivo de patch, ele tenta verificar a integridade do +arquivo de diferentes maneiras. + +Verificar se o arquivo parece um arquivo de patch válido e checar se o código ao +redor dos trechos sendo modificados corresponde ao contexto fornecido no patch +são apenas duas das verificações básicas de integridade que o patch faz. + +Se o patch encontrar algo que não pareça totalmente correto, ele tem duas +opções. Ele pode se recusar a aplicar as alterações e abortar, ou pode tentar +encontrar uma maneira de fazer o patch ser aplicado com algumas pequenas +alterações. + +Um exemplo de algo que não está "totalmente correto" e que o patch tentará +corrigir é se todo o contexto coincidir, as linhas sendo alteradas coincidirem, +mas os números das linhas forem diferentes. Isso pode acontecer, por exemplo, se +o patch fizer uma alteração no meio do arquivo, mas, por algum motivo, algumas +linhas tiverem sido adicionadas ou removidas perto do início do arquivo. Nesse +caso, tudo parece correto, apenas mudou um pouco para cima ou para baixo, e o +patch geralmente ajustará os números das linhas e aplicará o patch. + +Sempre que o patch aplicar um patch que ele teve de modificar um pouco para +fazer caber, ele avisará você dizendo que o patch foi aplicado com **fuzz**. +Você deve ser cauteloso com tais alterações porque, embora o patch +provavelmente tenha acertado, ele nem /sempre/ acerta, e o resultado às vezes +será incorreto. + +Quando o patch encontra uma alteração que não consegue corrigir com fuzz, ele a +rejeita imediatamente e deixa um arquivo com a extensão ``.rej`` (um arquivo de +rejeição). Você pode ler esse arquivo para ver exatamente qual alteração não +pôde ser aplicada, para que possa corrigi-la manualmente, se desejar. + +Se você não tem nenhum patch de terceiros aplicado ao seu código-fonte do +kernel, mas apenas patches do kernel.org, e você aplica os patches na ordem +correta, e não fez nenhuma modificação por conta própria nos arquivos de +origem, então você nunca deveria ver uma mensagem de fuzz ou de rejeição (reject) +do patch. Se você ainda assim vir tais mensagens, então há um alto risco de que +sua árvore de código-fonte local ou o arquivo de patch estejam corrompidos de +alguma forma. Nesse caso, você provavelmente deveria tentar baixar o patch +novamente e, se as coisas ainda não estiverem certas, aconselha-se começar com +uma árvore limpa baixada na íntegra do kernel.org. + +Vamos examinar um pouco mais algumas das mensagens que o patch pode produzir. + +Se o patch parar e apresentar um prompt ``File to patch:``, então o patch não +conseguiu encontrar um arquivo para ser modificado. O mais provável é que você +tenha esquecido de especificar -p1 ou esteja no diretório errado. Com menos +frequência, você encontrará patches que precisam ser aplicados com ``-p0`` em +vez de ``-p1`` (a leitura do arquivo de patch deve revelar se este é o caso -- se +for, isso é um erro da pessoa que criou o patch, mas não é fatal). + +Se você receber ``Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines).`` ou +uma mensagem semelhante a essa, significa que o patch teve que ajustar o local +da alteração (neste exemplo, ele precisou se mover 7 linhas de onde esperava +fazer a alteração para fazê-la caber). + +O arquivo resultante pode ou não estar correto, dependendo do motivo pelo qual o +arquivo estava diferente do esperado. + +Isso geralmente acontece se você tentar aplicar un patch que foi gerado contra uma +versão de kernel diferente daquela que você está tentando modificar. + +Se você receber uma mensagem como ``Hunk #3 FAILED at 2387.``, significa que o +patch não pôde ser aplicado corretamente e o programa patch não foi capaz de +encontrar um caminho usando o fuzz. Isso gerará um arquivo ``.rej`` com a +alteração que fez o patch falhar e também um arquivo ``.orig`` mostrando o +conteúdo original que não pôde ser alterado. + +Se você receber ``Reversed (or previously applied) patch detected! Assume -R? [n]`` +então o patch detectou que a alteração contida no patch parece já ter sido feita. + +Se você realmente aplicou este patch anteriormente e apenas o reaplicou por erro, +basta dizer [n]ão (n) e abortar este patch. Se você aplicou este patch +anteriormente e realmente pretendia revertê-lo, mas esqueceu de especificar -R, +você pode dizer [**y**]es (sim) aqui para fazer o patch revertê-lo para você. + +Isso também pode acontecer se o criador do patch inverteu os diretórios de +origem e destino ao criar o patch e, nesse caso, reverter o patch irá, na +verdade, aplicá-lo. + +Uma mensagem semelhante a ``patch: **** unexpected end of file in patch`` ou +``patch unexpectedly ends in middle of line`` significa que o patch não conseguiu +fazer sentido do arquivo que você passou para ele. Ou o seu download está +quebrado, ou você tentou passar para o patch um arquivo de patch compactado sem +descompactá-lo primeiro, ou o arquivo de patch que você está usando foi alterado +por um cliente de e-mail ou agente de transferência de e-mail em algum lugar pelo +caminho, por exemplo, dividindo uma linha longa em duas linhas. Frequentemente, +esses avisos podem ser corrigidos facilmente juntando (concatenando) as duas +linhas que foram divididas. + +Como já mencionei acima, esses erros nunca deveriam acontecer se você aplicar um +patch do kernel.org na versão correta de uma árvore de código-fonte não +modificada. Portanto, se você obtiver esses erros com patches do kernel.org, +você provavelmente deve assumir que o seu arquivo de patch ou a sua árvore está +quebrada, e eu o aconselharia a recomeçar com um download limpo de uma árvore +completa do kernel e do patch que deseja aplicar. + +Existem alternativas ao ``patch``? +================================== + +Sim, existem alternativas. + +Você pode usar o programa ``interdiff`` (http://cyberelk.net/tim/patchutils/) para +gerar um patch que represente as diferenças entre dois patches e, em seguida, +aplicar o resultado. + +Isso permitirá que você passe de algo como 5.7.2 para 5.7.3 em um único +passo. A flag -z do interdiff permite até mesmo passar patches em formato +compactado com gzip ou bzip2 diretamente, sem o uso de zcat, bzcat ou +descompactação manual. + +Aqui está como você passaria de 5.7.2 para 5.7.3 em um único passo:: + + interdiff -z ../patch-5.7.2.gz ../patch-5.7.3.gz | patch -p1 + +Embora o interdiff possa economizar um ou dois passos, geralmente recomenda-se +realizar os passos adicionais, já que o interdiff pode errar em alguns casos. + +Outra alternativa é o ``ketchup``, que é um script em python para download e +aplicação automática de patches (https://www.selenic.com/ketchup/). + +Outras ferramentas úteis são o diffstat, que mostra um resumo das alterações +feitas por um patch; o lsdiff, que exibe uma lista curta dos arquivos afetados +em um arquivo de patch, junto com (opcionalmente) os números das linhas de +início de cada patch; e o grepdiff, que exibe uma lista dos arquivos modificados +por um patch onde o patch contém uma determinada expressão regular. + + +Onde posso baixar os patches? +============================= + +Os patches estão disponíveis em https://kernel.org/ +Os patches mais recentes estão vinculados na página principal, mas eles também +possuem locais específicos. + +Os patches 5.x.y (-stable) e 5.x residem em + + https://www.kernel.org/pub/linux/kernel/v5.x/ + +Os patches incrementais 5.x.y residem em + + https://www.kernel.org/pub/linux/kernel/v5.x/incr/ + +Os patches -rc não são armazenados no servidor web, mas são gerados sob +demanda a partir de tags do git, tais como + + https://git.kernel.org/torvalds/p/v5.1-rc1/v5.0 + +Os patches estáveis -rc residem em + + https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/ + + +Os kernels 5.x +============== + +Estes são os lançamentos estáveis base publicados por Linus. O lançamento com o +número mais alto é o mais recente. + +Se regressões ou outras falhas graves forem encontradas, um patch de correção +-stable será lançado (veja abaixo) sobre esta base. Assim que um novo kernel +base 5.x é lançado, um patch é disponibilizado contendo o delta entre o kernel +5.x anterior e o novo. + +Para aplicar um patch mudando da versão 5.6 para a 5.7, você faria o seguinte +(note que tais patches **NÃO** se aplicam sobre kernels 5.x.y, mas sim sobre o +kernel base 5.x -- se você precisar mudar de 5.x.y para 5.x+1, você deve +primeiro reverter o patch do 5.x.y). + +Aqui estão alguns exemplos:: + + # mudando de 5.6 para 5.7 + + $ cd ~/linux-5.6 # muda para o dir do fonte do kernel + $ patch -p1 < ../patch-5.7 # aplica o patch do 5.7 + $ cd .. + $ mv linux-5.6 linux-5.7 # renomeia o dir do fonte + + # mudando de 5.6.1 para 5.7 + + $ cd ~/linux-5.6.1 # muda para o dir do fonte do kernel + $ patch -p1 -R < ../patch-5.6.1 # reverte o patch do 5.6.1 + # o dir do fonte agora é o 5.6 + $ patch -p1 < ../patch-5.7 # aplica o novo patch do 5.7 + $ cd .. + $ mv linux-5.6.1 linux-5.7 # renomeia o dir do fonte + +Os kernels 5.x.y +================ + +Kernels com versões de 3 dígitos são kernels -stable (estáveis). Eles contêm +correções críticas relativamente pequenas para problemas de segurança ou +regressões significativas descobertas em um determinado kernel 5.x. + +Esta é a ramificação recomendada para usuários que desejam o kernel estável mais +recente e não estão interessados em ajudar a testar versões de desenvolvimento +ou experimentais. + +Se nenhum kernel 5.x.y estiver disponível, então o kernel 5.x com o número mais +alto será o atual kernel estável. + +A equipe -stable fornece patches normais, bem como incrementais. Abaixo está +como aplicar esses patches. + +Patches normais +~~~~~~~~~~~~~~~ + +Estes patches não são incrementais, o que significa que, por exemplo, o patch +5.7.3 não se aplica sobre o código-fonte do kernel 5.7.2, mas sim sobre o +código-fonte do kernel base 5.7. + +Portanto, para aplicar o patch 5.7.3 ao seu código-fonte existente do kernel +5.7.2, você deve primeiro remover o patch 5.7.2 (de modo que reste apenas o +código-fonte do kernel base 5.7) e então aplicar o novo patch 5.7.3. + +Aqui está um pequeno exemplo:: + + $ cd ~/linux-5.7.2 # muda para o dir do fonte do kernel + $ patch -p1 -R < ../patch-5.7.2 # reverte o patch do 5.7.2 + $ patch -p1 < ../patch-5.7.3 # aplica o novo patch do 5.7.3 + $ cd .. + $ mv linux-5.7.2 linux-5.7.3 # renomeia o dir do fonte do kernel + +Patches incrementais +~~~~~~~~~~~~~~~~~~~~ + +Os patches incrementais são diferentes: em vez de serem aplicados sobre o kernel +base 5.x, eles são aplicados sobre o kernel estável anterior (5.x.y-1). + +Aqui está o exemplo para aplicar estes:: + + $ cd ~/linux-5.7.2 # muda para o dir do fonte do kernel + $ patch -p1 < ../patch-5.7.2-3 # aplica o novo patch do 5.7.3 + $ cd .. + $ mv linux-5.7.2 linux-5.7.3 # renomeia o dir do fonte do kernel + + +Os kernels -rc +============== + +Estes são os kernels candidatos a lançamento (release-candidate). São kernels +de desenvolvimento publicados por Linus sempre que ele considera que a árvore +atual do git (a ferramenta de gerenciamento de código-fonte do kernel) está em +um estado razoavelmente íntegro e adequado para testes. + +Estes kernels não são estáveis e você deve esperar quebras ocasionais se pretender +executá-los. Esta é, no entanto, a mais estável das principais ramificações de +desenvolvimento e é também o que eventualmente se tornará o próximo kernel +estável, por isso é importante que seja testado pelo maior número possível de +pessoas. + +Esta é uma boa ramificação para pessoas que querem ajudar a testar kernels de +desenvolvimento, mas não querem executar algumas das coisas realmente +experimentais (essas pessoas devem ver as seções sobre os kernels -next e -mm +abaixo). + +Os patches -rc não são incrementais; eles se aplicam a um kernel base 5.x, assim +como os patches 5.x.y descritos acima. A versão do kernel antes do sufixo -rcN +indica a versão do kernel na qual este kernel -rc eventualmente se tornará. + +Portanto, 5.8-rc5 significa que este é o quinto candidato a lançamento para o +kernel 5.8 e o patch deve ser aplicado sobre o código-fonte do kernel 5.7. + +Aqui estão 3 exemplos de como aplicar esses patches:: + + # primeiro, um exemplo de mudança do 5.7 para o 5.8-rc3 + + $ cd ~/linux-5.7 # muda para o dir do fonte do 5.7 + $ patch -p1 < ../patch-5.8-rc3 # aplica o patch do 5.8-rc3 + $ cd .. + $ mv linux-5.7 linux-5.8-rc3 # renomeia o dir do fonte + + # agora vamos mudar do 5.8-rc3 para o 5.8-rc5 + + $ cd ~/linux-5.8-rc3 # muda para o dir do 5.8-rc3 + $ patch -p1 -R < ../patch-5.8-rc3 # reverte o patch do 5.8-rc3 + $ patch -p1 < ../patch-5.8-rc5 # aplica o novo patch do 5.8-rc5 + $ cd .. + $ mv linux-5.8-rc3 linux-5.8-rc5 # renomeia o dir do fonte + + # por fim, vamos tentar mudar do 5.7.3 para o 5.8-rc5 + + $ cd ~/linux-5.7.3 # muda para o dir do fonte do kernel + $ patch -p1 -R < ../patch-5.7.3 # reverte o patch do 5.7.3 + $ patch -p1 < ../patch-5.8-rc5 # aplica o novo patch do 5.8-rc5 + $ cd .. + $ mv linux-5.7.3 linux-5.8-rc5 # renomeia o dir do fonte do kernel + + +Os patches -mm e a árvore linux-next +==================================== + +Os patches -mm são patches experimentais publicados por Andrew Morton. + +No passado, a árvore -mm também era usada para testar patches de subsistemas, +mas essa função agora é realizada por meio da árvore +`linux-next` (https://www.kernel.org/doc/man-pages/linux-next.html). +Os mantenedores de subsistemas enviam seus patches primeiro para a linux-next e, +durante a janela de mesclagem (merge window), enviam-nos diretamente para Linus. + +Os patches -mm servem como uma espécie de campo de testes para novos recursos e +outros patches experimentais que não são mesclados por meio de uma árvore de +subsistema. Assim que tais patches provam seu valor na -mm por um tempo, Andrew +os envia para Linus para inclusão na linha principal (mainline). + +A árvore linux-next é atualizada diariamente e inclui os patches -mm. Ambas +estão em constante fluxo e contêm muitos recursos experimentais, uma grande +quantidade de patches de depuração (debugging) não apropriados para a linha +principal etc., sendo as mais experimentais das ramificações descritas neste +documento. + +Estes patches não são apropriados para uso em sistemas que devem ser estáveis e +são mais arriscados de executar do que qualquer uma das outras ramificações +(certifique-se de ter backups atualizados -- isso vale para qualquer kernel +experimental, mas ainda mais para patches -mm ou ao usar um kernel da árvore +linux-next). + +O teste dos patches -mm e da linux-next é imensamente apreciado, pois todo o +objetivo deles é eliminar regressões, travamentos (crashes), bugs de corrupção +de dados, quebras de compilação (e qualquer outro bug em geral) antes que as +alterações sejam mescladas na árvore principal do Linus, que é mais estável. + +Mas os testadores da -mm e da linux-next devem estar cientes de que quebras são +mais comuns do que em qualquer outra árvore. + + +Isso conclui esta lista de explicações sobre as várias árvores do kernel. +Espero que agora você tenha clareza sobre como aplicar os vários patches e +ajudar a testar o kernel. + +Agradecimentos a Randy Dunlap, Rolf Eike Beer, Linus Torvalds, Bodo Eggert, +Johannes Stezenbach, Grant Coady, Pavel Machek e outros que posso ter esquecido +por suas revisões e contribuições para este documento.
\ No newline at end of file diff --git a/Documentation/translations/pt_BR/process/backporting.rst b/Documentation/translations/pt_BR/process/backporting.rst new file mode 100644 index 000000000000..ce3f9fb4fc5b --- /dev/null +++ b/Documentation/translations/pt_BR/process/backporting.rst @@ -0,0 +1,598 @@ +.. SPDX-License-Identifier: GPL-2.0 + +==================================== +Backporting e resolução de conflitos +==================================== + +:Autor: Vegard Nossum <vegard.nossum@oracle.com> + +.. contents:: + :local: + :depth: 3 + :backlinks: none + +Introdução +========== + +Alguns desenvolvedores podem nunca precisar lidar de fato com backporting de +patches, mesclagem de ramificações (branches) ou resolução de conflitos em seu +trabalho diário, portanto, quando um conflito de mesclagem aparece, pode ser +assustador. Felizmente, resolver conflitos é uma habilidade como qualquer outra, +e existem muitas técnicas úteis que você pode usar para tornar o processo mais +suave e aumentar sua confiança no resultado. + +Este documento tem como objetivo ser um guia abrangente e passo a passo para +backporting e resolução de conflitos. + +Aplicando o patch a uma árvore +============================== + +Às vezes, o patch que você está fazendo backport já existe como um commit do +git, caso em que você apenas faz o cherry-pick dele diretamente usando +``git cherry-pick``. No entanto, se o patch vier de um e-mail, como costuma +acontecer no caso do kernel Linux, você precisará aplicá-lo a uma árvore usando +``git am``. + +Se você já usou o ``git am``, provavelmente já sabe que ele é bastante exigente +sobre o patch ser aplicado perfeitamente à sua árvore de código-fonte. Na +verdade, você provavelmente já teve pesadelos com arquivos ``.rej`` e tentando +editar o patch para fazê-lo ser aplicado. + +Recomenda-se fortemente, em vez disso, encontrar uma versão base apropriada onde +o patch se aplique de forma limpa e *então* fazer o cherry-pick dele para a sua +árvore de destino, pois isso fará com que o git exiba marcadores de conflito e +permitirá que você resolva os conflitos com a ajuda do git e de quaisquer outras +ferramentas de resolução de conflitos que preferir usar. Por exemplo, se você +quiser aplicar um patch que acabou de chegar na LKML a um kernel estável mais +antigo, você pode aplicá-lo ao kernel principal (mainline) mais recente e, em +seguida, fazer o cherry-pick dele para a sua ramificação estável mais antiga. + +Geralmente é melhor usar exatamente a mesma base a partir da qual o patch foi +gerado, mas isso não importa tanto, desde que ele se aplique de forma limpa e +não esteja muito longe da base original. O único problema ao aplicar o patch na +base "errada" é que isso pode trazer mais alterações não relacionadas no +contexto do diff ao fazer o cherry-pick dele para a ramificação mais antiga. + +Um bom motivo para preferir o ``git cherry-pick`` em vez do ``git am`` é que o +git conhece o histórico preciso de um commit existente, de modo que ele saberá +quando o código foi movido de lugar e teve seus números de linha alterados; isso, +por sua vez, torna menos provável que o patch seja aplicado no lugar errado (o +que pode resultar em erros silenciosos ou conflitos confusos). + +Se você estiver usando o `b4`_. e estiver aplicando o patch diretamente de um +e-mail, você pode usar o ``b4 am`` com as opções ``-g``/``--guess-base`` e +``-3``/``--prep-3way`` para fazer parte disso automaticamente (veja a +`apresentação do b4`_ para mais informações). No entanto, o restante deste +artigo assumirá que você está fazendo um ``git cherry-pick`` simples. + +.. _b4: https://people.kernel.org/monsieuricon/introducing-b4-and-patch-attestation +.. _apresentação do b4: https://youtu.be/mF10hgVIx9o?t=2996 + +Assim que tiver o patch no git, você pode prosseguir e fazer o cherry-pick dele +em sua árvore de código-fonte. Não se esqueça de fazer o cherry-pick com ``-x`` +se quiser um registro por escrito de onde o patch veio! + +Note que, se você estiver enviando um patch para a ramificação estável (stable), +o formato é ligeiramente diferente; a primeira linha após a linha de assunto +precisa ser:: + + commit <upstream commit> upstream + +ou:: + + [ Upstream commit <upstream commit> ] + +Resolvendo conflitos +==================== + +Ih, rapaz; o cherry-pick falhou com uma mensagem vagamente ameaçadora:: + + CONFLICT (content): Merge conflict + +O que fazer agora? + +Em geral, os conflitos aparecem quando o contexto do patch (ou seja, as linhas +que estão sendo alteradas e/ou as linhas que cercam as alterações) não +corresponde ao que está na árvore à qual você está tentando aplicar o patch. + +No caso de backports, o que provavelmente aconteceu foi que a ramificação +(branch) a partir da qual você está fazendo o backport contém patches que não +estão na ramificação para a qual você está fazendo o backport. No entanto, o +inverso também é possível. Em qualquer caso, o resultado é um conflito que +precisa ser resolvido. + +Se a sua tentativa de cherry-pick falhar com um conflito, o git edita os +arquivos automaticamente para incluir os chamados marcadores de conflito, +mostrando onde está o conflito e como as duas ramificações divergiram. Resolver +o conflito normalmente significa editar o resultado final de forma que ele leve +em consideração esses outros commits. + +A resolução do conflito pode ser feita manualmente em um editor de texto comum +ou usando uma ferramenta dedicada de resolução de conflitos. + +Muitas pessoas preferem usar seu editor de texto comum e editar o conflito +diretamente, pois pode ser mais fácil entender o que você está fazendo e +controlar o resultado final. Definitivamente, existem prós e contras em cada +método, e às vezes há valor em usar ambos. + +Não abordaremos o uso de ferramentas de mesclagem (merge tools) dedicadas aqui, +além de fornecer algumas indicações de várias ferramentas que você poderia usar: + +- `Modo Emacs Ediff <https://www.emacswiki.org/emacs/EdiffMode>`__ +- `vimdiff/gvimdiff <https://linux.die.net/man/1/vimdiff>`__ +- `KDiff3 <http://kdiff3.sourceforge.net/>`__ +- `TortoiseMerge <https://tortoisesvn.net/TortoiseMerge.html>`__ +- `Meld <https://meldmerge.org/help/>`__ +- `P4Merge <https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge>`__ +- `Beyond Compare <https://www.scootersoftware.com/>`__ +- `IntelliJ <https://www.jetbrains.com/help/idea/resolve-conflicts.html>`__ +- `VSCode <https://code.visualstudio.com/docs/editor/versioncontrol>`__ + +Para configurar o git para funcionar com elas, veja ``git mergetool --help`` ou +a `documentação oficial do git-mergetool`_. + +.. _documentação oficial do git-mergetool: https://git-scm.com/docs/git-mergetool + +Patches pré-requisitos +---------------------- + +A maioria dos conflitos acontece porque a ramificação para a qual você está +fazendo o backport não possui alguns patches em comparação com a ramificação a +partir da qual você está fazendo o backport. No caso mais geral (como a +mesclagem de duas ramificações independentes), o desenvolvimento poderia ter +ocorrido em qualquer uma das ramificações, ou as ramificações simplesmente +divergiram -- talvez a sua ramificação mais antiga tenha recebido alguns outros +backports que, por si só, precisaram de resoluções de conflitos, causando uma +divergência. + +É importante sempre identificar o commit ou os commits que causaram o conflito, +pois, caso contrário, você não poderá ter confiança na correção da sua +resolução. Como um bônus adicional, especialmente se o patch for em uma área com +a qual você não está muito familiarizado, os registros de alterações (changelogs) +desses commits frequentemente lhe darão o contexto para entender o código e os +problemas ou armadilhas potenciais com a sua resolução de conflito. + +git log +~~~~~~~ + +Um bom primeiro passo é olhar o ``git log`` para o arquivo que possui o +conflito -- isso geralmente é suficiente quando não há muitos patches no +arquivo, mas pode ficar confuso se o arquivo for grande e frequentemente +modificado por patches. Você deve executar o ``git log`` no intervalo de commits +entre a sua ramificação atualmente ativa (``HEAD``) e o pai do patch que você está +escolhendo (``<commit>``), ou seja:: + + git log HEAD..<commit>^ -- <path> + +Melhor ainda, se você quiser restringir essa saída a uma única função (porque é +onde o conflito aparece), você pode usar a seguinte sintaxe:: + + git log -L:'\<function\>':<path> HEAD..<commit>^ + +.. note:: + O ``\<`` e o ``\>`` ao redor do nome da função garantem que as + correspondências fiquem ancoradas em um limite de palavra. Isso é + importante, pois essa parte é na verdade uma regex e o git segue apenas a + primeira correspondência; portanto, se você usar + ``-L:thread_stack:kernel/fork.c``, ele poderá fornecer apenas resultados + para a função ``try_release_thread_stack_to_cache``, embora existam muitas + outras funções naquele arquivo contendo a string ``thread_stack`` em seus + nomes. + +Outra opção útil para o ``git log`` é a ``-G``, que permite filtrar por certas +strings que aparecem nos diffs dos commits que você está listando:: + + git log -G'regex' HEAD..<commit>^ -- <path> + +Esta também pode ser uma maneira prática de encontrar rapidamente quando algo +(por exemplo, uma chamada de função ou uma variável) foi alterado, adicionado +ou removido. A string de busca é uma expressão regular, o que significa que você +pode potencialmente buscar por coisas mais específicas, como atribuições a um +membro específico de uma struct:: + + git log -G'\->index\>.*=' + +git blame +~~~~~~~~~ + +Outra maneira de encontrar commits pré-requisitos (embora apenas o mais recente +para um determinado conflito) é executar o ``git blame``. Neste caso, você +precisa executá-lo no commit pai do patch para o qual está fazendo o +cherry-pick e no arquivo onde o conflito apareceu, ou seja:: + + git blame <commit>^ -- <path> + +Este comando também aceita o argumento ``-L`` (para restringir a saída a uma +única função), mas, neste caso, você especifica o nome do arquivo no final do +comando, como de costume:: + + git blame -L:'\<function\>' <commit>^ -- <path> + +Navegue até o local onde o conflito ocorreu. A primeira coluna da saída do +blame é o ID do commit do patch que adicionou uma determinada linha de código. + +Pode ser uma boa ideia dar um ``git show`` nesses commits e ver se eles se +parecem com a possível origem do conflito. Às vezes, haverá mais de um desses +commits, seja porque múltiplos commits alteraram linhas diferentes da mesma área +de conflito *ou* porque múltiplos patches subsequentes alteraram a mesma linha +(ou linhas) várias vezes. Neste último caso, você pode ter que executar o +``git blame`` novamente e especificar a versão mais antiga do arquivo para +analisar, a fim de cavar mais fundo no histórico do arquivo. + +Patches pré-requisitos vs. incidentais +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tendo encontrado o patch que causou o conflito, você precisa determinar se ele +é um pré-requisito para o patch que você está fazendo o backport ou se é apenas +incidental e pode ser pulado. Um patch incidental seria aquele que toca no mesmo +código que o patch para o qual você está fazendo o backport, mas não altera a +semântica do código de nenhuma forma relevante. Por exemplo, um patch de limpeza +de espaços em branco é completamente incidental -- da mesma forma, um patch que +simplesmente renomeia uma função ou uma variável também seria incidental. Por +outro lado, se a função que está sendo alterada sequer existe na sua ramificação +atual, então isso não seria nada incidental e você precisa considerar com +cuidado se o patch que adiciona a função deve ser aplicado via cherry-pick +primeiro. + +Se você descobrir que há um patch pré-requisito necessário, então você precisa +parar e fazer o cherry-pick dele em vez disso. Se você já resolveu alguns +conflitos em um arquivo diferente e não quer fazer isso de novo, você pode +criar uma cópia temporária daquele arquivo. + +Para abortar o cherry-pick atual, vá em frente e execute +``git cherry-pick --abort`` e, em seguida, reinicie o processo de cherry-pick +com o ID do commit do patch pré-requisito. + +Entendendo os marcadores de conflito +------------------------------------ + +Diffs combinados +~~~~~~~~~~~~~~~~ + +Digamos que você tenha decidido não fazer o cherry-pick (ou o revert) de patches +adicionais e quer apenas resolver o conflito. O Git terá inserido marcadores de +conflito no seu arquivo. Por padrão, isso se parecerá com algo como:: + + <<<<<<< HEAD + this is what's in your current tree before cherry-picking + ======= + this is what the patch wants it to be after cherry-picking + >>>>>>> <commit>... title + +Isso é o que você veria se abrisse o arquivo no seu editor. No entanto, se você +executasse o ``git diff`` sem nenhum argumento, a saída seria algo assim:: + + $ git diff + [...] + ++<<<<<<<< HEAD + +this is what's in your current tree before cherry-picking + ++======== + + this is what the patch wants it to be after cherry-picking + ++>>>>>>>> <commit>... title + +Quando você está resolvendo um conflito, o comportamento do ``git diff`` difere +do seu comportamento normal. Note as duas colunas de marcadores de diff em vez +da coluna única usual; este é o chamado "`diff combinado`_", aqui mostrando o +diff de 3 vias (ou diff-de-diffs) entre: + +#. a ramificação atual (antes do cherry-pick) e o diretório de trabalho atual, e +#. a ramificação atual (antes do cherry-pick) e o arquivo como ele fica após o + patch original ter sido aplicado. + +.. _diff combinado: https://git-scm.com/docs/diff-format#_combined_diff_format + +Diffs melhores +~~~~~~~~~~~~~~ + +Diffs combinados de 3 vias incluem todas as outras alterações que aconteceram +no arquivo entre a sua ramificação atual e a ramificação a partir da qual você +está fazendo o cherry-pick. Embora isso seja útil para detectar outras +alterações que você precisa levar em consideração, também torna a saída do +``git diff`` um tanto intimidadora e difícil de ler. Em vez disso, você pode +preferir executar ``git diff HEAD`` (ou ``git diff --ours``), que mostra apenas +o diff entre a ramificação atual antes do cherry-pick e o diretório de trabalho +atual. Ele se parece com isso:: + + $ git diff HEAD + [...] + +<<<<<<<< HEAD + this is what's in your current tree before cherry-picking + +======== + +this is what the patch wants it to be after cherry-picking + +>>>>>>>> <commit>... title + +Como você pode ver, isso é lido exatamente como qualquer outro diff e deixa claro +quais linhas estão na ramificação atual e quais linhas estão sendo adicionadas +porque fazem parte do conflito de mesclagem ou do patch que está sendo aplicado +via cherry-pick. + +Estilos de mesclagem e diff3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +O estilo padrão de marcador de conflito mostrado acima é conhecido como o estilo +``merge``. Também está disponível um outro estilo, conhecido como o estilo +``diff3``, que se parece com isso:: + + <<<<<<< HEAD + this is what is in your current tree before cherry-picking + ||||||| parent of <commit> (title) + this is what the patch expected to find there + ======= + this is what the patch wants it to be after being applied + >>>>>>> <commit> (title) + +Como você pode ver, isso tem 3 partes em vez de 2, e inclui o que o git +esperava encontrar lá, mas não encontrou. É *altamente recomendável* usar este +estilo de conflito, pois deixa muito mais claro o que o patch realmente alterou; +ou seja, ele permite que você compare as versões de antes e depois do arquivo +para o commit do qual está fazendo o cherry-pick. Isso permite que você tome +melhores decisões sobre como resolver o conflito. + +Para alterar os estilos de marcadores de conflito, você pode usar o seguinte +comando:: + + git config merge.conflictStyle diff3 + +Existe uma terceira opção, ``zdiff3``, introduzida no `Git 2.35`_, que possui as +mesmas 3 seções do ``diff3``, mas onde as linhas comuns foram cortadas, tornando +a área de conflito menor em alguns casos. + +.. _Git 2.35: https://github.blog/2022-01-24-highlights-from-git-2-35/ + +Iterando em resoluções de conflito +---------------------------------- + +O primeiro passo em qualquer processo de resolução de conflito é entender o +patch para o qual você está fazendo o backport. Para o kernel Linux, isso é +especialmente importante, pois uma alteração incorreta pode levar ao travamento +de todo o sistema -- ou pior, a uma vulnerabilidade de segurança não detectada. + +Entender o patch pode ser fácil ou difícil, dependendo do próprio patch, do +registro de alterações (changelog) e da sua familiaridade com o código que está +sendo alterado. No entanto, uma boa pergunta para cada alteração (ou cada bloco/ +hunk do patch) seria: "Por que este hunk está no patch?" As respostas a essas +perguntas orientarão a sua resolução de conflito. + +Processo de resolução +~~~~~~~~~~~~~~~~~~~~~ + +Às vezes, a coisa mais fácil a fazer é apenas remover tudo, exceto a primeira +parteda do conflito, deixando o arquivo essencialmente inalterado, e aplicar +as alterações manualmente. Talvez o patch esteja alterando um argumento de +chamada de função de ``0`` para ``1``, enquanto uma alteração conflitante +adicionou um parâmetro totalmente novo (e insignificante) ao final da lista de +parâmetros; nesse caso, é bastante fácil alterar o argumento de ``0`` para ``1`` +manualmente e deixar o restante dos argumentos como estão. Esta técnica de +aplicar alterações manualmente é mais útil se o conflito tiver trazido muito +contexto não relacionado com o qual você não precisa realmente se preocupar. + +Para conflitos particularmente difíceis com muitos marcadores de conflito, você +pode usar ``git add`` ou ``git add -i`` para indexar (stage) seletivamente as +suas resoluções para tirá-las do caminho; isso também permite que você use +``git diff HEAD`` para ver sempre o que ainda resta a ser resolvido ou +``git diff --cached`` para ver como está o seu patch até o momento. + +Lidando com arquivos renomeados +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Uma das coisas mais irritantes que podem acontecer ao fazer o backport de um +patch é descobrir que um dos arquivos modificados foi renomeado, pois isso +geralmente significa que o git sequer colocará marcadores de conflito, mas +apenas lavará as mãos e dirá (parafraseando): "Caminho não mesclado! Faça você o +trabalho..." + +Geralmente existem algumas maneiras de lidar com isso. Se o patch para o +arquivo renomeado for pequeno, como uma alteração de uma única linha, a coisa +mais fácil é prosseguir, aplicar a alteração manualmente e dar o caso por +encerrado. Por outro lado, se a alteração for grande ou complicada, você +definitivamente não vai querer fazê-la manualmente. + +Como uma primeira tentativa, você pode tentar algo assim, que reduzirá o limite +(threshold) de detecção de renomeação para 30% (por padrão, o git usa 50%, o que +significa que dois arquivos precisam ter pelo menos 50% em comum para que ele +considere um par de adição/remoção como uma renomeação potencial):: + + git cherry-pick -strategy=recursive -Xrename-threshold=30 + +Às vezes, a coisa certa a fazer será fazer o backport também do patch que +realizou a renomeação, mas esse definitivamente não é o caso mais comum. Em vez +disso, o que você pode fazer é renomear temporariamente o arquivo na +ramificação para a qual está fazendo o backport (usando ``git mv`` e commitando +o resultado), reiniciar a tentativa de cherry-pick do patch, renomear o arquivo +de volta (``git mv`` e commitando novamente) e, finalmente, esmagar (squash) o +resultado usando ``git rebase -i`` (veja o `tutorial de rebase`_) para que ele +apareça como um único commit quando você terminar. + +.. _tutorial de rebase: [https://medium.com/@slamflipstrom/a-beginners-guide-to-squashing-commits-with-git-rebase-8185cf6e62ec](https://medium.com/@slamflipstrom/a-beginners-guide-to-squashing-commits-with-git-rebase-8185cf6e62ec) + +Pegadinhas +---------- + +Argumentos de função +~~~~~~~~~~~~~~~~~~~~ + +Preste atenção às alterações em argumentos de função! É fácil deixar passar +detalhes e pensar que duas linhas são iguais quando, na verdade, elas diferem em +algum pequeno detalhe, como qual variável foi passada como argumento +(especialmente se as duas variáveis forem de apenas um caractere e parecerem +iguais, como i e j). + +Tratamento de erros +~~~~~~~~~~~~~~~~~~~ + +Se você fizer o cherry-pick de um patch que inclua uma instrução ``goto`` +(geralmente para tratamento de erros), é absolutamente imperativo verificar em +dobro se o rótulo (label) de destino ainda está correto na ramificação para a +qual você está fazendo o backport. O mesmo vale para instruções ``return``, +``break`` e ``continue`` adicionadas. + +O tratamento de erros geralmente fica localizado no final da função, portanto, +pode não fazer parte do conflito, mesmo que possa ter sido alterado por outros +patches. + +Uma boa maneira de garantir que você revise os caminhos de erro é sempre usar +``git diff -W`` e ``git show -W`` (também conhecido como ``--function-context``) +ao inspecionar suas alterações. Para código em C, isso mostrará toda a função +que está sendo alterada em um patch. Uma das coisas que frequentemente dão +errado durante backports é que algo mais na função mudou em qualquer uma das +ramificações a partir da qual ou para a qual você está fazendo o backport. Ao +incluir a função inteira no diff, você obtém mais contexto e pode identificar +mais facilmente problemas que de outra forma poderiam passar despercebidos. + +Código refatorado +~~~~~~~~~~~~~~~~~ + +Algo que acontece com bastante frequência é o código ser refatorado ao "isolar" +uma sequência ou padrão de código comum em uma função auxiliar. Ao fazer o +backport de patches para uma área onde tal refatoração ocorreu, você efetivamente +precisa fazer o inverso ao realizar o backport: um patch para um único local pode +precisar ser aplicado a múltiplos locais na versão que recebeu o backport. (Um +indicativo para este cenário é que uma função foi renomeada -- mas nem sempre é o +caso.) + +Para evitar backports incompletos, vale a pena tentar descobrir se o patch +corrige um bug que aparece em mais de um lugar. Uma maneira de fazer isso seria +usar o ``git grep``. (Isso, na verdade, é uma boa ideia de se fazer em geral, não +apenas para backports.) Se você descobrir que o mesmo tipo de correção se +aplicaria a outros lugares, também vale a pena ver se esses lugares existem no +upstream -- se não existirem, é provável que o patch precise ser ajustado. O +``git log`` é seu amigo para descobrir o que aconteceu com essas áreas, já que o +``git blame`` não mostrará código que foi removido. + +Se você encontrar outras instâncias do mesmo padrão na árvore do upstream e não +tiver certeza se isso também é um bug, pode valer a pena perguntar ao autor do +patch. Não é incomum encontrar novos bugs durante o processo de backport! + +Verificando o resultado +======================= + +colordiff +--------- + +Tendo commitado um novo patch sem conflitos, você pode agora comparar o seu +patch com o patch original. É altamente recomendável que você use uma +ferramenta como o `colordiff`_ que possa mostrar dois arquivos lado a lado e +colori-los de acordo com as alterações entre eles:: + + colordiff -yw -W 200 <(git diff -W <upstream commit>^-) <(git diff -W HEAD^-) | less -SR + +.. _colordiff: https://www.colordiff.org/ + +Aqui, ``-y`` significa fazer uma comparação lado a lado; ``-w`` ignora +espaços em branco e ``-W 200`` define a largura da saída (caso contrário, ele +usará 130 por padrão, o que costuma ser um pouco pouco). + +A sintaxe ``rev^-`` é um atalho prático para ``rev^..rev``, essencialmente +fornecendo apenas o diff para aquele único commit; veja também a +`documentação oficial do git rev-parse`_. + +.. _documentação oficial do git rev-parse: https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations + +Novamente, note a inclusão de ``-W`` para o ``git diff``; isso garante que você +verá a função completa para qualquer função que tenha mudado. + +Uma coisa incrivelmente importante que o colordiff faz é destacar as linhas que +são diferentes. Por exemplo, se um ``goto`` de tratamento de erros teve seus +rótulos alterados entre o patch original e o que sofreu o backport, o colordiff +irá mostrá-los lado a lado, mas destacados em uma cor diferente. Assim, é fácil +ver que as duas instruções ``goto`` estão saltando para rótulos diferentes. Da +mesma forma, linhas que não foram modificadas por nenhum dos patches, mas que +diferem no contexto, também serão destacadas e, portanto, se destacarão durante +uma inspeção manual. + +Claro, esta é apenas uma inspeção visual; o teste real é compilar e executar o +kernel (ou programa) com o patch aplicado. + +Testes de compilação (Build testing) +------------------------------------ + +Não abordaremos os testes em tempo de execução aqui, mas pode ser uma boa ideia +compilar apenas os arquivos tocados pelo patch como uma verificação rápida de +sanidade. Para o kernel Linux, você pode compilar arquivos únicos assim, +assumindo que você tenha o ``.config`` e o ambiente de compilação configurados +corretamente:: + + make caminho/para/o/arquivo.o + +Note que isso não descobrirá erros de ligação (linker errors), então você ainda +deve fazer uma compilação completa após verificar que o arquivo único compila. +Ao compilar o arquivo único primeiro, você pode evitar ter que esperar por uma +compilação completa *caso* haja erros de compilador em qualquer um dos arquivos +que você alterou. + +Testes em tempo de execução +--------------------------- + +Mesmo um teste de compilação ou de boot bem-sucedido não é necessariamente o +suficiente para descartar uma dependência ausente em algum lugar. Embora as +chances sejam pequenas, pode haver alterações de código onde duas modificações +independentes no mesmo arquivo resultem em nenhum conflito, nenhum erro em tempo +de compilação e erros em tempo de execução apenas em casos excepcionais. + +Um exemplo concreto disso foi um par de patches para o código de entrada de +chamada de sistema (system call entry code), onde o primeiro patch salvava/ +restaurava um registrador e um patch posterior fazia uso do mesmo registrador +em algum lugar no meio dessa sequência. Como não havia sobreposição entre as +alterações, era possível fazer o cherry-pick do segundo patch, não ter conflitos +e acreditar que tudo estava bem, quando na verdade o código estava agora +sobrescrevendo (scribbling over) um registrador não salvo. + +Embora a vasta maioria dos erros seja capturada durante a compilação ou ao +exercitar o código superficialmente, a única maneira de *realmente* verificar um +backport é revisar o patch final com o mesmo nível de escrutínio que você daria +(ou deveria dar) a qualquer outro patch. Ter testes unitários e testes de +regressão ou outros tipos de testes automáticos pode ajudar a aumentar a +confiança na correção de um backport. + +Enviando backports para a árvore estável (stable) +================================================= + +À medida que os mantenedores da árvore estável tentam aplicar correções da linha +principal (mainline) em seus kernels estáveis via cherry-pick, eles podem enviar +e-mails solicitando backports quando encontram conflitos; veja, por exemplo, +<https://lore.kernel.org/stable/2023101528-jawed-shelving-071a@gregkh/>. +Esses e-mails normalmente incluem os passos exatos que você precisa seguir para +fazer o cherry-pick do patch para a árvore correta e enviá-lo. + +Uma coisa a se certificar é que o seu registro de alterações (changelog) esteja +em conformidade com o formato esperado:: + + <original patch title> + + [ Upstream commit <mainline rev> ] + + <rest of the original changelog> + [ <summary of the conflicts and their resolutions> ] + Signed-off-by: <your name and email> + +A linha "Upstream commit" às vezes é ligeiramente diferente dependendo da versão +estável. Versões mais antigas usavam este formato:: + + commit <mainline rev> upstream. + +O mais comum é indicar a versão do kernel à qual o patch se aplica na linha de +assunto do e-mail (usando, por exemplo, +``git send-email --subject-prefix='PATCH 6.1.y'``), mas você também pode +colocá-la na área do Signed-off-by: ou abaixo da linha ``---``. + +Os mantenedores da árvore estável esperam envios separados para cada versão +estável ativa, e cada envio também deve ser testado separadamente. + +Algumas palavras finais de conselho +=================================== + +1) Aborde o processo de backport com humildade. +2) Entenda o patch para o qual você está fazendo o backport; isso significa ler + tanto o registro de alterações (changelog) quanto o código. +3) Seja honesto sobre a sua confiança no resultado ao enviar o patch. +4) Peça aprovações explícitas (acks) aos mantenedores relevantes. + +Exemplos +======== + +O texto acima mostra, de forma geral, o processo idealizado de backport de um +patch. Para um exemplo mais concreto, veja este tutorial em vídeo onde dois +patches são portados da linha principal (mainline) para a estável (stable): +`Backporting Linux Kernel Patches`_. + +.. _Backporting Linux Kernel Patches: https://youtu.be/sBR7R1V2FeA
\ No newline at end of file diff --git a/Documentation/translations/pt_BR/process/botching-up-ioctls.rst b/Documentation/translations/pt_BR/process/botching-up-ioctls.rst new file mode 100644 index 000000000000..193297619ac2 --- /dev/null +++ b/Documentation/translations/pt_BR/process/botching-up-ioctls.rst @@ -0,0 +1,256 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================================ +(Como evitar) Deixar as ioctls malfeitas +============================================ + +De: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html + +Por: Daniel Vetter, Copyright © 2013 Intel Corporation + +Uma percepção clara que os hackers de gráficos do kernel tiveram nos últimos +anos é que tentar criar uma interface unificada para gerenciar as unidades de +execução e a memória em GPUs completamente diferentes é um esforço inútil. +Portanto, hoje em dia, cada driver tem seu próprio conjunto de ioctls para +alocar memória e enviar trabalho para a GPU. O que é bom, já que não há mais a +insanidade na forma de interfaces falsamente genéricas, mas que na verdade só +são usadas uma vez. No entanto, a desvantagem clara é que há muito mais +potencial para estragar as coisas. + +Para evitar repetir todos os mesmos erros novamente, escrevi algumas das lições +aprendidas enquanto fazia um trabalho malfeito para o driver drm/i915. A maioria +delas aborda apenas tecnicalidades e não os problemas macro (big-picture), como +deveria ser exatamente a aparência da ioctl de envio de comando. Aprender essas +lições é provavelmente algo que cada driver de GPU tem que fazer por conta +própria. + + +Pré-requisitos +-------------- + +Primeiro, os pré-requisitos. Sem estes você já falhou, porque precisará +adicionar uma camada de compatibilidade de 32 bits (compat layer): + + * Use apenas inteiros de tamanho fixo. Para evitar conflitos com typedefs no + espaço de usuário (userspace), o kernel possui tipos especiais como __u32 e + __s64. Use-os. + + * Alinhe tudo ao tamanho natural e use preenchimento (padding) explícito. + Plataformas de 32 bits não alinham necessariamente valores de 64 bits a + limites (boundaries) de 64 bits, mas plataformas de 64 bits o fazem. Portanto, + sempre precisamos de padding para o tamanho natural para acertar isso. + + * Preencha a struct inteira para um múltiplo de 64 bits se a estrutura contiver + tipos de 64 bits -- caso contrário, o tamanho da estrutura diferirá entre + 32 bits e 64 bits. Ter um tamanho de estrutura diferente prejudica ao passar + matrizes (arrays) de estruturas para o kernel, ou se o kernel verificar o + tamanho da estrutura, o que o core do drm, por exemplo, faz. + + * Ponteiros são __u64, convertidos de/para um uintptr_t no lado do espaço de + usuário e de/para um void __user * no kernel. Tente de verdade não atrasar + essa conversão ou, pior ainda, manipular o __u64 bruto pelo seu código, pois + isso diminui a verificação que ferramentas como o sparse podem fornecer. A + macro u64_to_user_ptr pode ser usada no kernel para evitar avisos sobre + inteiros e ponteiros de tamanhos diferentes. + + +Conceitos básicos +----------------- + +Evitadas as alegrias de escrever uma camada de compatibilidade (compat layer), +podemos dar uma olhada nos deslizes básicos. Negligenciar estes pontos tornará a +compatibilidade retroativa e futura uma verdadeira dor de cabeça. E, como errar +na primeira tentativa é garantido, você certamente terá uma segunda iteração ou, +pelo menos, uma extensão para qualquer interface fornecida. + + * Tenha uma maneira clara para o espaço de usuário descobrir se a sua nova + ioctl ou extensão de ioctl é suportada em um determinado kernel. Se você não + puder confiar que os kernels antigos rejeitarão as novas flags/modos ou + ioctls (já que fazer isso foi deixado de lado no passado), então você + precisará de uma flag de recurso (feature flag) do driver ou de um número de + revisão em algum lugar. + + * Tenha um plano para estender as ioctls com novas flags ou novos campos no + final da estrutura. O core do drm verifica o tamanho passado para cada + chamada de ioctl e preenche com zero (zero-extends) quaisquer divergências + entre o kernel e o espaço de usuário. Isso ajuda, mas não é uma solução + completa, já que um espaço de usuário mais novo em um kernel mais antigo não + notará que os campos recém-adicionados no final estão sendo ignorados. + Portanto, isso ainda exige novas flags de recurso do driver. + + * Verifique todos os campos e flags não utilizados, além de todo o preenchimento + (padding), para garantir que estejam em 0, e rejeite a ioctl se esse não for + o caso. Caso contrário, seu excelente plano para extensões futuras irá por + água abaixo, pois alguém enviará uma struct de ioctl com lixo de pilha + (stack garbage) aleatório nas partes ainda não utilizadas. O que, então, + consolida na ABI que esses campos nunca poderão ser usados para nada além de + lixo. Esta também é a razão pela qual você deve preencher explicitamente todas + as estruturas, mesmo que nunca as use em uma matriz (array) -- o padding que + o compilador possa inserir poderia conter lixo. + + * Tenha casos de teste simples para tudo o que foi mencionado acima. + + +Diversão com caminhos de erro (Error Paths) +------------------------------------------- + +Hoje em dia, não temos mais nenhuma desculpa para que os drivers drm sejam pequenos +exploits de root disfarçados. Isso significa que precisamos tanto de uma +validação completa de entrada quanto de caminhos sólidos de tratamento de erros +-- as GPUs eventualmente vão parar de funcionar (die) nos casos mais bizarros +de qualquer maneira: + + * A ioctl deve verificar se há estouros de matriz (array overflows). Ela também + precisa verificar estouros superiores/inferiores (over/underflows) e problemas + de limitação (clamping) de valores inteiros em geral. O exemplo usual são os + valores de posicionamento de sprite alimentados diretamente no hardware, onde + o hardware possui apenas 12 bits ou algo assim. Funciona perfeitamente até que + algum servidor de exibição bizarro não se preocupe em fazer o clamping por si + mesmo e o cursor dê a volta (wrap around) na tela. + + * Tenha casos de teste simples para cada caso de falha de validação de entrada + na sua ioctl. Verifique se o código de erro corresponde às suas expectativas. + E, finalmente, certifique-se de testar apenas um único caminho de erro em + cada subteste, enviando dados que, de outra forma, seriam perfeitamente + válidos. Sem isso, uma verificação anterior já poderia rejeitar a ioctl e + ofuscar (shadow) o caminho de código que você realmente deseja testar, + ocultando bugs e regressões. + + * Torne todas as suas ioctls reiniciáveis (restartable). Primeiro, o X (X11) + realmente ama sinais (signals) e, segundo, isso permitirá que você teste 90% + de todos os caminhos de tratamento de erro apenas interrompendo sua suíte de + testes principal constantemente com sinais. Graças ao amor do X por sinais, + você obterá uma excelente cobertura de base de todos os seus caminhos de erro + praticamente de graça para drivers de gráficos. Além disso, seja consistente + na forma como você lida com a reinicialização de ioctls -- por exemplo, o drm + possui um pequeno helper drmIoctl em sua biblioteca de espaço de usuário. O + driver i915 estragou isso com a ioctl set_tiling; agora estamos presos para + sempre com algumas semânticas arcanas tanto no kernel quanto no espaço de + usuário. + + * Se você não puder tornar um determinado caminho de código reiniciável, torne + uma tarefa travada pelo menos finalizável (killable). As GPUs simplesmente + morrem, e seus usuários não vão gostar mais de você se você travar a máquina + inteira deles (por meio de um processo do X impossível de matar). Se a + recuperação de estado ainda for muito complicada, tenha um timeout ou uma + rede de segurança de verificação de travamento (hangcheck) como um esforço de + última hora (last-ditch) caso o hardware enlouqueça (gone bananas). + + * Tenha casos de teste para os cenários mais complexos (corner cases) no seu + código de recuperação de erros -- é fácil demais criar um deadlock entre seu + código de hangcheck e os processos que estão aguardando (waiters). + + +Tempo, Espera e a Perda de Prazos +--------------------------------- + +As GPUs fazem quase tudo de forma assíncrona, portanto, temos a necessidade de +cronometrar operações e aguardar pelas que estão pendentes. Esse é um negócio +realmente complicado; no momento, nenhuma das ioctls suportadas pelo drm/i915 +acerta isso completamente, o que significa que ainda há toneladas de lições para +aprender aqui. + + * Use CLOCK_MONOTONIC como seu tempo de referência, sempre. É o que o alsa, o + drm e o v4l usam por padrão hoje em dia. Mas informe ao espaço de usuário + quais carimbos de data/hora (timestamps) são derivados de domínios de relógio + diferentes, como o relógio principal do seu sistema (fornecido pelo kernel) + ou algum contador de hardware independente em outro lugar. Os relógios vão + divergir se você olhar de perto o suficiente, mas se as ferramentas de + medição de desempenho tiverem essa informação, elas poderão ao menos compensar. + Se o seu espaço de usuário puder obter os valores brutos de alguns relógios + (por exemplo, por meio de instruções de amostragem de contador de desempenho + no fluxo de comandos), considere expor esses também. + + * Use __s64 para segundos mais __u64 para nanossegundos para especificar o + tempo. Não é a especificação de tempo mais conveniente, mas é praticamente o + padrão. + + * Verifique se os valores de tempo de entrada estão normalizados e rejeite-os + caso contrário. Note que a struct nativa do kernel, ktime, possui um inteiro + sinalizado tanto para segundos quanto para nanossegundos, portanto, cuidado + aqui. + + * Para timeouts, use tempos absolutos. Se você for um bom sujeito e tiver + tornado a sua ioctl reiniciável, os timeouts relativos tendem a ser muito + imprecisos (coarse) e podem estender indefinidamente o seu tempo de espera + devido ao arredondamento a cada reinicialização. Especialmente se o seu relógio + de referência for algo realmente lento, como o contador de quadros da tela + (display frame counter). Vestindo o chapéu de advogado de especificações, isso + não é um bug, já que os timeouts sempre podem ser estendidos -- mas os usuários + com certeza vão odiar você se as belas animações deles começarem a gaguejar + (stutter) devido a isso. + + * Considere descartar quaisquer ioctls de espera síncrona com timeouts e apenas + entregue um evento assíncrono em um descritor de arquivo passível de poll + (pollable file descriptor). Isso se encaixa muito melhor no loop principal de + aplicações orientadas a eventos. + + * Tenha casos de teste para cenários complexos (corner-cases), especialmente se + os valores de retorno para eventos já concluídos, esperas bem-sucedidas e + esperas que estouraram o tempo (timed-out) são todos sãos e adequados às suas + necessidades. + + +Evitando o vazamento de recursos (Leaking Resources, Not) +--------------------------------------------------------- + +Um driver drm completo essencialmente implementa um pequeno SO, mas especializado +para as plataformas de GPU fornecidas. Isso significa que um driver precisa +expor toneladas de handles (identificadores) para diferentes objetos e outros +recursos para o espaço de usuário. Fazer isso corretamente traz seu próprio +pequeno conjunto de armadilhas: + + * Sempre vincule o tempo de vida (lifetime) de seus recursos criados + dinamicamente ao tempo de vida de um descritor de arquivo (file descriptor - + fd). Considere usar um mapeamento 1:1 se o seu recurso precisar ser + compartilhado entre processos -- a passagem de fds sobre unix domain sockets + também simplifica o gerenciamento do tempo de vida para o espaço de usuário. + + * Sempre tenha suporte a O_CLOEXEC. + + * Certifique-se de que você tem isolamento suficiente entre os diferentes + clientes. Por padrão, escolha um namespace privado por fd, o que força + qualquer compartilhamento a ser feito de forma explícita. Só adote um + namespace mais global por dispositivo se os objetos forem verdadeiramente + únicos do dispositivo. Um contraexemplo nas interfaces de modeset do drm é + que os objetos de modeset por dispositivo, como conectores, compartilham um + namespace com objetos de framebuffer, que na maioria das vezes não são + compartilhados de forma alguma. Um namespace separado, privado por padrão, + para os framebuffers teria sido mais adequado. + + * Pense sobre os requisitos de unicidade para os handles do espaço de usuário. + Por exemplo, para a maioria dos drivers drm, é um bug do espaço de usuário + enviar o mesmo objeto duas vezes na mesma ioctl de envio de comando. Mas, + se os objetos forem compartilháveis, o espaço de usuário precisa saber se + já viu um objeto importado de outro processo ou não. Eu ainda não tentei isso + sozinho devido à falta de uma nova classe de objetos, mas considere usar + números de inode em seus descritores de arquivo compartilhados como + identificadores únicos -- é assim que arquivos reais também são diferenciados. + Infelizmente, isso requer um sistema de arquivos virtual completo no kernel. + + +Por último, mas não menos importante +------------------------------------ + +Nem todo problema precisa de uma nova ioctl: + + * Pense bem se você realmente quer uma interface privada do driver. Claro que + é muito mais rápido aprovar uma interface privada do driver do que se envolver + em discussões longas por uma solução mais genérica. E, ocasionalmente, criar + uma interface privada para liderar um novo conceito é o que se exige. Mas, + no final, assim que a interface genérica surgir, você acabará mantendo duas + interfaces. Indefinidamente. + + * Considere outras interfaces além de ioctls. Um atributo sysfs é muito melhor + para configurações por dispositivo ou para objetos filhos com tempos de vida + razoavelmente estáticos (como conectores de saída no drm com todos os seus + atributos de sobreposição de detecção). Ou talvez apenas a sua suíte de + testes precise dessa interface e, nesse caso, o debugfs, com seu aviso de + isenção de responsabilidade por não ter uma ABI estável, seria melhor. + +Finalmente, o objetivo principal é acertar na primeira tentativa, pois se o seu +driver se provar popular e suas plataformas de hardware forem duradouras, você +ficará preso a uma determinada ioctl essencialmente para sempre. Você pode +tentar depreciar ioctls horríveis em iterações mais novas do seu hardware, mas +geralmente leva anos para conseguir isso. E depois mais anos até que o último +usuário capaz de reclamar sobre regressões desapareça também.
\ No newline at end of file diff --git a/Documentation/translations/pt_BR/process/code-of-conduct-interpretation.rst b/Documentation/translations/pt_BR/process/code-of-conduct-interpretation.rst new file mode 100644 index 000000000000..866c9f7e7a12 --- /dev/null +++ b/Documentation/translations/pt_BR/process/code-of-conduct-interpretation.rst @@ -0,0 +1,257 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Interpretação do Código de Conduta do Kernel Linux +================================================== + +O :ref:`pt_BR_code_of_conduct` é um documento geral que tem como objetivo +fornecer um conjunto de regras para quase todas as comunidades de código +aberto. Toda comunidade de código aberto é única e o kernel Linux não é +exceção. Por causa disso, este documento descreve como nós, na comunidade +do kernel Linux, o interpretaremos. Nós também não esperamos que esta +interpretação seja estática ao longo do tempo, e a ajustaremos conforme +necessário. + +O esforço de desenvolvimento do kernel Linux é um processo muito pessoal +em comparação com as formas "tradicionais" de desenvolvimento de software. +Suas contribuições e as ideias por trás delas serão cuidadosamente +revisadas, frequentemente resultando em críticas e apontamentos. A +revisão quase sempre exigirá melhorias antes que o material possa ser +incluído no kernel. Saiba que isso acontece porque todos os envolvidos +querem ver a melhor solução possível para o sucesso geral do Linux. Este +processo de desenvolvimento provou criar o kernel de sistema operacional +mais robusto de todos os tempos, e nós não queremos fazer nada que cause +a diminuição da qualidade do envio e do resultado final. + +Mantenedores +------------ + +O Código de Conduta usa o termo "mantenedores" várias vezes. Na +comunidade do kernel, um "mantenedor" é qualquer pessoa responsável por +um subsistema, driver ou arquivo, e que esteja listada no arquivo +MAINTAINERS na árvore de código-fonte do kernel. + +Responsabilidades +----------------- + +O Código de Conduta menciona direitos e responsabilidades para os +mantenedores, e isso precisa de alguns esclarecimentos adicionais. + +Em primeiro lugar e acima de tudo, é uma expectativa razoável que os +mantenedores liderem pelo exemplo. + +Dito isto, nossa comunidade é vasta e ampla, e não há um novo requisito +para que os mantenedores lidem unilateralmente com o comportamento de +outras pessoas nas partes da comunidade onde atuam. Essa responsabilidade +é de todos nós e, em última análise, o Código de Conduta documenta os +caminhos finais de escalonamento em caso de preocupações não resolvidas +em relação a questões de conduta. + +Os mantenedores devem estar dispostos a ajudar quando ocorrerem problemas +e trabalhar com outras pessoas na comunidade quando necessário. Não tenha +medo de entrar em contato com o Conselho Consultivo Técnico (TAB) ou +outros mantenedores se não tiver certeza de como lidar com as situações +que surgirem. Isso não será considerado um relato de violação, a menos +que você queira que seja. Se não tiver certeza sobre como abordar o TAB +ou quaisquer outros mantenedores, entre em contato com nossa mediadora +de conflitos, Joanna Lee <jlee@linuxfoundation.org>. + +No final, "sejam gentis uns com os outros" é realmente o objetivo final +para todos. Sabemos que todos são humanos e que todos falhamos às vezes, +mas o objetivo principal para todos nós deve ser trabalhar em direção a +resoluções amigáveis dos problemas. A aplicação do código de conduta será +apenas uma opção de último recurso. + +Nosso objetivo de criar um sistema operacional robusto e tecnicamente +avançado e a complexidade técnica envolvida exigem naturalmente +conhecimento técnico e tomada de decisões. + +O conhecimento técnico exigido varia dependendo da área de contribuição. +Ele é determinado principalmente pelo contexto e pela complexidade técnica +e apenas secundariamente pelas expectativas de contribuidores e +mantenedores. + +Tanto as expectativas de conhecimento técnico quanto a tomada de decisões +estão sujeitas a discussão, mas no final das contas há uma necessidade +básica de sermos capazes de tomar decisões para progredir. Esta +prerrogativa está nas mãos dos mantenedores e da liderança do projeto e +espera-se que seja usada de boa fé. + +Como consequência, definir expectativas de conhecimento técnico, tomar +decisões e rejeitar contribuições inadequadas não são vistos como uma +violação do Código de Conduta. + +Embora os mantenedores sejam em geral receptivos aos novatos, sua +capacidade de ajudar os contribuidores a superar os obstáculos de entrada +é limitada, portanto, eles devem definir prioridades. Isso, também, não +deve ser visto como uma violação do Código de Conduta. A comunidade do +kernel está ciente disso e fornece programas de nível de entrada de +várias formas, como o kernelnewbies.org. + +Escopo +------ + +A comunidade do kernel Linux interage primariamente em um conjunto de listas +de e-mail públicas distribuídas por vários servidores diferentes controlados +por várias empresas ou indivíduos diferentes. Todas essas listas estão +definidas no arquivo MAINTAINERS na árvore de código-fonte do kernel. +Quaisquer e-mails enviados para essas listas de e-mail são considerados +cobertos pelo Código de Conduta. + +Desenvolvedores que usam o bugzilla do kernel.org e outras ferramentas de +rastreamento de bugs ou bugzilla de subsistemas devem seguir as diretrizes +do Código de Conduta. A comunidade do kernel Linux não possui um endereço +de e-mail de projeto "oficial" ou endereço "oficial" de mídia social. +Qualquer atividade realizada usando uma conta de e-mail do kernel.org deve +seguir o Código de Conduta conforme publicado para o kernel.org, assim como +qualquer indivíduo usando uma conta de e-mail corporativa deve seguir as +regras específicas daquela corporação. + +O Código de Conduta não proíbe que se continue a incluir nomes, endereços de +e-mail e comentários associados em mensagens de listas de discussão, +mensagens de log de alterações (changelog) do kernel ou comentários no +código. + +A interação em outros fóruns é coberta pelas regras que se aplicam a tais +fóruns e, em geral, não é coberta pelo Código de Conduta. Exceções podem +ser consideradas para circunstâncias extremas. + +As contribuições enviadas para o kernel devem usar linguagem apropriada. +O conteúdo já existente que precede o Código de Conduta não será tratado +agora como uma violação. No entanto, a linguagem inapropriada pode ser vista +como um bug; tais bugs serão corrigidos mais rapidamente se quaisquer partes +interessadas enviarem patches com esse propósito. Expressões que atualmente +fazem parte da API de usuário/kernel, ou que refletem a terminologia usada +em padrões ou especificações publicadas, não são consideradas bugs. + +Aplicação +--------- + +O endereço listado no Código de Conduta vai para o Comitê do Código de +Conduta. Os membros exatos que recebem esses e-mails a qualquer momento +estão listados em https://kernel.org/code-of-conduct.html. Os membros não +podem acessar relatos feitos antes de se juntarem ou após terem deixado o +comitê. + +O Comitê do Código de Conduta consiste em membros voluntários da comunidade +nomeados pelo TAB, bem como um mediador profissional agindo como um terceiro +neutro. Os processos que o comitê do Código de Conduta usará para lidar com +os relatos variam e dependerão das circunstâncias individuais; no entanto, +este arquivo serve como documentação para o processo geral utilizado. + +Qualquer membro do comitê, incluindo o mediador, pode ser contatado +diretamente se o relator não desejar incluir todo o comitê em uma +reclamação ou preocupação. + +O Comitê do Código de Conduta revisa os casos de acordo com os processos +(veja acima) e consulta o TAB conforme a necessidade e a conveniência, +por exemplo, para solicitar e receber informações sobre a comunidade do +kernel. + +Quaisquer decisões a respeito de recomendações de aplicação (enforcement) +serão levadas ao TAB para implementação junto aos mantenedores relevantes, +se necessário. Uma vez que o TAB aprove uma ou mais das medidas descritas +no escopo do banimento pelo voto de dois terços dos membros, o Comitê do +Código de Conduta aplicará as medidas aprovadas pelo TAB. Quaisquer membros +do Comitê do Código de Conduta que sirvam no TAB não votarão nas medidas. + +Em intervalos trimestrais, o Comitê do Código de Conduta e o TAB fornecerão +um relatório resumindo os relatos anonimizados que o comitê do Código de +Conduta recebeu e o status deles, bem como os detalhes de quaisquer +decisões aprovadas pelo TAB, incluindo dados completos e identificáveis da +votação. + +Como a maneira pela qual interpretamos e aplicamos o Código de Conduta +evoluirá com o tempo, este documento será atualizado quando necessário para +refletir quaisquer mudanças. + +Aplicação para Violações de Comportamento Inaceitável do Código de Conduta +---------------------------------------------------------------------------- + +O comitê do Código de Conduta trabalha para garantir que nossa comunidade +continue a ser inclusiva e promova discussões e pontos de vista diversos, e +trabalha para melhorar essas características ao longo do tempo. A maioria +dos relatos que o Comitê do Código de Conduta recebe decorre da +compreensão incorreta sobre o processo de desenvolvimento e os papéis, +responsabilidades e o direito dos mantenedores de tomar decisões sobre a +aceitação de código. Estes são resolvidos através do esclarecimento do +processo de desenvolvimento e do escopo do Código de Conduta. + +Comportamentos inaceitáveis podem interromper a colaboração respeitosa por um +curto período de tempo e impactar negativamente a saúde da comunidade a longo +prazo. Comportamentos inaceitáveis frequentemente são resolvidos quando os +indivíduos reconhecem seu comportamento e se retratam por ele no ambiente em +que a violação ocorreu. + +O Comitê do Código de Conduta recebe relatos sobre comportamentos +inaceitáveis quando eles não são resolvidos através de discussões na +comunidade. O comitê do Código de Conduta toma medidas para restaurar a +colaboração produtiva e respeitosa quando um comportamento inaceitável +impactou negativamente esse relacionamento. + +O Comitê do Código de Conduta tem a obrigação de manter os relatos e as +informações dos relatores em sigilo. Os relatos podem vir de partes lesadas +e membros da comunidade que são observadores de comportamentos +inaceitáveis. O Comitê do Código de Conduta tem a responsabilidade de +investigar e resolver esses relatos, trabalhando com todas as partes +envolvidas. + +O Comitê do Código de Conduta trabalha com o indivíduo para promover uma +mudança em sua compreensão sobre a importância de reparar os danos causados +por seu comportamento à parte lesada e o impacto negativo a longo prazo na +comunidade. + +O objetivo é alcançar uma resolução que seja aceitável para todas as partes. +Se trabalhar com o indivíduo não trouxer o resultado desejado, o Comitê do +Código de Conduta avaliará outras medidas, como buscar um pedido de +desculpas público para reparar o dano. + +Buscar retratação pública pela violação +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +O Comitê do Código de Conduta chama a atenção publicamente para o comportamento +no ambiente em que a violação ocorreu, buscando uma retratação pública +pela violação. + +Uma retratação pública pela violação é o primeiro passo para reconstruir a +confiança. A confiança é essencial para o sucesso contínuo e a saúde da +comunidade, que opera com base na confiança e no respeito. + +Medidas corretivas se não houver uma retratação pública pela violação +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +O Comitê do Código de Conduta determina o próximo curso de ação para restaurar +a colaboração saudável, recomendando medida(s) corretiva(s) ao TAB para +aprovação. + +- Banir o infrator de participar do processo de desenvolvimento do kernel por + um período de até um ciclo completo de desenvolvimento do kernel. O Comitê + do Código de Conduta pode exigir uma retratação pública como condição + para suspender o banimento. + +O escopo do banimento por um período de tempo pode incluir: + + a. negar contribuições de patch e pull requests + b. pausar a colaboração com o infrator ignorando suas contribuições e/ou + bloqueando sua(s) conta(s) de e-mail + c. restringir sua capacidade de se comunicar pelas plataformas kernel.org, + como listas de discussão e sites de mídia social + +Uma vez que o TAB aprove uma ou mais das medidas descritas no escopo do +banimento por dois terços dos membros votando a favor das medidas, o Comitê do +Código de Conduta aplicará a(s) medida(s) aprovada(s) pelo TAB em colaboração +com a comunidade, mantenedores, submantenedores e administradores do +kernel.org. Quaisquer membros do Comitê do Código de Conduta atuando no TAB +não votarão nas medidas. + +O Comitê do Código de Conduta está ciente do impacto negativo que buscar uma +retratação pública e instituir um banimento pode ter sobre os indivíduos. +Também está ciente dos danos a longo prazo para a comunidade que podem resultar +da falta de ação quando tais violações públicas graves ocorrem. + +A eficácia da(s) medida(s) corretiva(s) aprovada(s) pelo TAB depende da +confiança e cooperação da comunidade, mantenedores, submantenedores e +administradores do kernel.org na sua aplicação. + +O Comitê do Código de Conduta espera sinceramente que comportamentos +inaceitáveis que exijam a busca de retratações públicas continuem a ser +ocorrências extremamente raras no futuro.
\ No newline at end of file diff --git a/Documentation/translations/pt_BR/process/code-of-conduct.rst b/Documentation/translations/pt_BR/process/code-of-conduct.rst new file mode 100644 index 000000000000..1ab171bf21cf --- /dev/null +++ b/Documentation/translations/pt_BR/process/code-of-conduct.rst @@ -0,0 +1,88 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _pt_BR_code_of_conduct: + +Código de Conduta de Compromisso do Colaborador ++++++++++++++++++++++++++++++++++++++++++++++++ + +Nosso Compromisso +================= + +No interesse de promover um ambiente aberto e acolhedor, nós, como colaboradores +e mantenedores, nos comprometemos a tornar a participação em nosso projeto e em +nossa comunidade uma experiência livre de assédio para todos, independentemente +da idade, tamanho corporal, deficiência, etnia, características sexuais, +identidade e expressão de gênero, nível de experiência, educação, status +socioeconômico, nacionalidade, aparência pessoal, raça, religião ou identidade +e orientação sexual. + +Nossos Padrões +============== + +Exemplos de comportamentos que contribuem para a criação de um ambiente positivo +incluem: + +* Utilizar linguagem acolhedora e inclusiva +* Respeitar pontos de vista e experiências divergentes +* Aceitar críticas construtivas de forma cortês +* Focar no que é melhor para a comunidade +* Demonstrar empatia para com outros membros da comunidade + +Exemplos de comportamentos inaceitáveis por parte dos participantes incluem: + +* O uso de linguagem ou imagens de teor sexual, bem como atenção ou avanços + sexuais indesejados +* Provocações (*trolling*), comentários insultuosos/depreciativos e ataques + pessoais ou políticos +* Assédio público ou privado +* Publicar informações privadas de terceiros, como endereço físico ou eletrônico, + sem permissão explícita +* Qualquer outra conduta que possa ser razoavelmente considerada inadequada em um + ambiente profissional + +Nossas Responsabilidades +======================== + +Os mantenedores são responsáveis por esclarecer os padrões de comportamento +aceitável e devem tomar medidas corretivas apropriadas e justas em resposta a +quaisquer casos de comportamento inaceitável. + +Os mantenedores têm o direito e a responsabilidade de remover, editar ou rejeitar +comentários, commits, código, edições em wiki, issues e outras contribuições que +não estejam alinhadas a este Código de Conduta, ou de banir temporária ou +permanentemente qualquer colaborador por outros comportamentos que considerem +inadequados, ameaçadores, ofensivos ou prejudiciais. + +Escopo +====== + +Este Código de Conduta se aplica tanto dentro dos espaços do projeto quanto em +espaços públicos quando um indivíduo estiver representando o projeto ou sua +comunidade. Exemplos de representação do projeto ou comunidade incluem o uso de um +endereço de e-mail oficial do projeto, publicações por meio de uma conta oficial +em redes sociais ou atuar como um representante nomeado em um evento online ou +presencial. A representação de um projeto pode ser detalhada e esclarecida de forma +adicional pelos mantenedores do projeto. + +Aplicação +========= + +Casos de comportamento abusivo, de assédio ou inaceitável sob qualquer outro aspecto +podem ser relatados entrando em contato com o Comitê do Código de Conduta pelo e-mail +<conduct@kernel.org>. Todas as reclamações serão revisadas e investigadas, resultando +em uma resposta considerada necessária e adequada às circunstâncias. O Comitê do +Código de Conduta é obrigado a manter a confidencialidade em relação ao denunciante +de um incidente. Detalhes adicionais sobre políticas de aplicação específicas podem +ser publicados separadamente. + +Atribuição +========== + +Este Código de Conduta foi adaptado do Contributor Covenant, versão 1.4, +disponível em https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +Interpretação +============= + +Consulte o documento :ref:`code_of_conduct_interpretation` para entender como a +comunidade do kernel Linux interpretará este documento. diff --git a/Documentation/translations/pt_BR/process/contribution-maturity-model.rst b/Documentation/translations/pt_BR/process/contribution-maturity-model.rst new file mode 100644 index 000000000000..bb003c4cd0d9 --- /dev/null +++ b/Documentation/translations/pt_BR/process/contribution-maturity-model.rst @@ -0,0 +1,111 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================================================= +Modelos de Maturidade para Contribuição no Kernel Linux +======================================================= + + +Contexto +======== + +Como parte do Linux Kernel Maintainers’ Summit de 2021, houve uma +`discussão <https://lwn.net/Articles/870581/>`_ sobre os desafios na +contratação de mantenedores do kernel, bem como a sucessão de mantenedores. +Algumas das conclusões daquela discussão incluíram que as empresas que fazem +parte da comunidade do Kernel Linux precisam permitir que os engenheiros atuem +como mantenedores como parte de seu trabalho, para que possam crescer e se +tornar líderes respeitados e, eventualmente, mantenedores do kernel. Para +apoiar um fluxo forte de talentos, os desenvolvedores devem ser autorizados e +incentivados a assumir contribuições no upstream, como revisar os patches de +outras pessoas, refatorar a infraestrutura do kernel e escrever documentação. + +Para tanto, o Conselho Técnico Consultivo (Technical Advisory Board - TAB) da +Linux Foundation propõe este Modelo de Maturidade para Contribuição no Kernel +Linux. Essas expectativas comuns para o engajamento da comunidade upstream visam +aumentar a influência de desenvolvedores individuais, aumentar a colaboração +de organizações e melhorar a saúde geral do ecossistema do Kernel Linux. + +O TAB insta as organizações a avaliarem continuamente seu modelo de maturidade +em Open Source e a se comprometerem com melhorias para se alinharem a este +modelo. Para ser eficaz, essa avaliação deve incorporar o feedback de toda a +organização, incluindo a gerência e os desenvolvedores de todos os níveis de +senioridade. No espírito do Open Source, incentivamos as organizações a +publicarem suas avaliações e planos para melhorar seu engajamento com a +comunidade upstream. + +Nível 0 +======= + +* Engenheiros de Software não têm permissão para contribuir com patches para o + kernel Linux. + + +Nível 1 +======= + +* Engenheiros de Software têm permissão para contribuir com patches para o + kernel Linux, seja como parte de suas responsabilidades de trabalho ou em seu + próprio tempo. + +Nível 2 +======= + +* Espera-se que os Engenheiros de Software contribuam para o Kernel Linux como + parte de suas responsabilidades de trabalho. +* Os Engenheiros de Software receberão apoio para participar de conferências + relacionadas ao Linux como parte de seu trabalho. +* As contribuições de código no upstream de um Engenheiro de Software serão + consideradas em promoções e avaliações de desempenho. + +Nível 3 +======= + +* Espera-se que os Engenheiros de Software revisem patches (incluindo patches + escritos por engenheiros de outras empresas) como parte de suas + responsabilidades de trabalho. +* A contribuição com apresentações ou artigos para conferências acadêmicas ou + relacionadas ao Linux (como as organizadas pela Linux Foundation, Usenix, + ACM, etc.) é considerada parte do trabalho do engenheiro. +* As contribuições comunitárias de um Engenheiro de Software serão consideradas + em promoções e avaliações de desempenho. +* As organizações relatarão regularmente as métricas de suas contribuições em + open source e acompanharão essas métricas ao longo do tempo. Essas métricas + podem ser publicadas apenas internamente na organização ou, a critério da + organização, algumas ou todas podem ser publicadas externamente. As métricas + fortemente sugeridas incluem: + + * O número de contribuições ao kernel no upstream por equipe ou organização + (por exemplo, todas as pessoas que se reportam a um gerente, diretor ou + vice-presidente). + * A porcentagem de desenvolvedores de kernel que fizeram contribuições no + upstream em relação ao total de desenvolvedores de kernel na organização. + * O intervalo de tempo entre os kernels usados nos servidores e/ou produtos + da organização e a data de publicação do kernel upstream no qual o kernel + interno se baseia. + * O número de commits fora da árvore (out-of-tree) presentes nos kernels + internos. + +Nível 4 +======= + +* Os Engenheiros de Software são incentivados a dedicar uma parte do seu tempo + de trabalho focados no Trabalho no Upstream, o qual é definido como a revisão + de patches, atuação em comitês de programa, melhoria da infraestrutura central + do projeto -- como escrita ou manutenção de testes, redução de dívida técnica + no upstream, escrita de documentação, etc. +* Os Engenheiros de Software recebem apoio para ajudar a organizar conferências + relacionadas ao Linux. +* As organizações considerarão o feedback dos membros da comunidade em + avaliações de desempenho oficiais. + +Nível 5 +======= + +* O desenvolvimento de kernel no upstream é considerado um cargo formal, com + pelo menos um terço do tempo do engenheiro dedicado à realização de Trabalho + no Upstream. +* As organizações buscarão ativamente o feedback dos membros da comunidade como + um fator nas avaliações de desempenho oficiais. +* As organizações relatarão internamente e de forma regular a proporção entre o + Trabalho no Upstream e o trabalho focado em atingir diretamente os objetivos + de negócios.
\ No newline at end of file diff --git a/Documentation/translations/pt_BR/process/deprecated.rst b/Documentation/translations/pt_BR/process/deprecated.rst new file mode 100644 index 000000000000..2793a1fc92fe --- /dev/null +++ b/Documentation/translations/pt_BR/process/deprecated.rst @@ -0,0 +1,422 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================================================================== +Interfaces, recursos de linguagem, atributos e convenções obsoletos +======================================================================== + +Em um mundo perfeito, seria possível converter todas as instâncias de alguma +API obsoleta para a nova API e remover completamente a API antiga em um único +ciclo de desenvolvimento. No entanto, devido ao tamanho do kernel, à hierarquia +de manutenção e ao cronograma, nem sempre é viável realizar esse tipo de +conversão de uma só vez. Isso significa que novas instâncias podem acabar +entrando no kernel enquanto as antigas estão sendo removidas, apenas aumentando +o volume de trabalho para remover a API. A fim de instruir os desenvolvedores +sobre o que se tornou obsoleto e o porquê, esta lista foi criada para servir de +referência quando o uso de elementos obsoletos for proposto para inclusão no +kernel. + +__deprecated +------------ +Embora este atributo marque visualmente uma interface como obsoleta, ele `não +gera mais avisos durante as compilações +<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_ porque +um dos objetivos permanentes do kernel é compilar sem avisos (*warnings*), e +ninguém estava de fato agindo para remover essas interfaces obsoletas. Embora o +uso de `__deprecated` seja útil para sinalizar uma API antiga em um arquivo de +cabeçalho (*header file*), não é a solução completa. Tais interfaces devem ser +totalmente removidas do kernel ou adicionadas a este arquivo para desestimular +outros desenvolvedores de usá-las no futuro. + +BBUG() e BUG_ON() +----------------- +Em vez disso, use WARN() e WARN_ON() e trate a condição de erro "impossível" +da forma mais amigável possível. Embora a família de APIs BUG() tenha sido +originalmente projetada para agir como uma asserção de "situação impossível" e +eliminar uma thread do kernel de forma "segura", ela se mostrou arriscada +demais. (Por exemplo: "Em que ordem os bloqueios precisam ser liberados? Os +diversos estados foram restaurados?") Muito frequentemente, o uso de BUG() vai +desestabilizar o sistema ou travá-lo por completo, o que torna impossível +depurar ou até mesmo obter relatórios de travamento (*crash reports*) viáveis. +Linus tem opiniões `muito fortes +<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_ +`sobre isso +<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_. + +Note que a família WARN() só deve ser usada para situações que "espera-se que +sejam inacessíveis". Se você quiser alertar sobre situações que são +"acessíveis, mas indesejáveis", use a família de funções pr_warn(). Os +administradores do sistema podem ter configurado o sysctl *panic_on_warn* para +garantir que seus sistemas não continuem executando diante de condições +"inacessíveis". (Para exemplos, veja commits como `este aqui +<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_.) + +Aritmética explícita em argumentos do alocador +---------------------------------------------- +Cálculos dinâmicos de tamanho (especialmente multiplicação) não devem ser +realizados em argumentos de funções de alocação de memória (ou similares) +devido ao risco de estouro de capacidade (*overflow*). Isso poderia fazer com +que os valores dessem a volta (*wrap around*), resultando em uma alocação menor +do que o esperado pelo chamador. O uso dessas alocações pode levar a estouros +lineares na memória heap e a outros comportamentos incorretos. (Uma exceção a +isso são valores literais onde o compilador pode emitir um aviso se houver +risco de estouro. No entanto, a maneira preferível nesses casos é refatorar o +código conforme sugerido abaixo para evitar a aritmética explícita.) + +Por exemplo, não use ``count * size`` como argumento, como em:: + + foo = kmalloc(count * size, GFP_KERNEL); + +Em vez disso, a forma de dois fatores do alocador deve ser utilizada:: + + foo = kmalloc_array(count, size, GFP_KERNEL); + +Especificamente, kmalloc() pode ser substituído por kmalloc_array(), e +kzalloc() pode ser substituído por kcalloc(). + +Se nenhuma forma de dois fatores estiver disponível, os auxiliares de +saturação em estouro (*saturate-on-overflow*) devem ser usados:: + + bar = dma_alloc_coherent(dev, array_size(count, size), &dma, GFP_KERNEL); + +Outro caso comum a ser evitado é calcular o tamanho de uma estrutura com uma +matriz final de outras estruturas, como em:: + + header = kzalloc(sizeof(*header) + count * sizeof(*header->item), + GFP_KERNEL); + +Em vez disso, use o auxiliar:: + + header = kzalloc(struct_size(header, item, count), GFP_KERNEL); + +.. note:: Se você estiver usando struct_size() em uma estrutura que contém uma + matriz de comprimento zero ou de um único elemento como membro final, + refatore o uso dessa matriz e mude para um `membro de matriz flexível + <#zero-length-and-one-element-arrays>`_ em seu lugar. + +Para outros cálculos, faça a composição usando os auxiliares size_mul(), +size_add() e size_sub(). Por exemplo, no caso de:: + + foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL); + +Em vez disso, use os auxiliares:: + + foo = krealloc(size_add(current_size, + size_mul(chunk_size, + size_sub(count, 3))), GFP_KERNEL); + +Para mais detalhes, veja também array3_size() e flex_array_size(), bem como as +funções relacionadas das famílias check_mul_overflow(), check_add_overflow(), +check_sub_overflow() e check_shl_overflow().\ + +simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull() +---------------------------------------------------------------------- +As funções simple_strtol(), simple_strtoll(), simple_strtoul() e +simple_strtoull() ignoram explicitamente estouros de capacidade (*overflows*), +o que pode levar a resultados inesperados nos chamadores. As respectivas +funções kstrtol(), kstrtoll(), kstrtoul() e kstrtoull() tendem a ser as +substitutas corretas, embora se deva notar que estas exigem que a string seja +terminada em NUL ou em nova linha (*newline*). + +strcpy() +-------- +A função strcpy() não realiza verificação de limites no buffer de destino. +Isso pode resultar em estouros lineares além do final do buffer, levando a todo +tipo de comportamentos incorretos. Embora ``CONFIG_FORTIFY_SOURCE=y`` e várias +opções do compilador ajudem a reduzir o risco de usar esta função, não há uma +boa razão para adicionar novos usos dela. A substituta segura é strscpy(), +embora se deva ter cuidado nos casos em que o valor de retorno de strcpy() era +utilizado, já que strscpy() não retorna um ponteiro para o destino, mas sim a +quantidade de bytes não-NUL copiados (ou um código de erro errno negativo quando +ocorre truncamento). + +strncpy() +--------- +A função strncpy() foi removida do kernel. Todos os chamadores antigos foram +migrados para alternativas mais seguras. + +A função strncpy() não garantia a terminação em NUL do buffer de destino, +levando a estouros de leitura linear e outros comportamentos incorretos. Ela +também preenchia incondicionalmente o destino com NUL, o que representava uma +penalidade de desempenho desnecessária para chamadores que usavam apenas +strings terminadas em NUL. Devido aos seus diversos comportamentos, ela era uma +API ambígua para determinar qual era a real intenção do autor ao realizar a +cópia. + +As substitutas para strncpy() são: + +- strscpy() quando o destino deve ser terminado em NUL. +- strscpy_pad() quando o destino deve ser terminado em NUL e preenchido com + zeros (por exemplo, estruturas que cruzam fronteiras de privilégio). +- memtostr() para destinos terminados em NUL a partir de origens de largura + fixa não terminadas em NUL (com o atributo ``__nonstring`` na origem). +- memtostr_pad() para o mesmo caso anterior, mas com preenchimento de zeros. +- strtomem() para destinos de largura fixa não terminados em NUL, com o + atributo ``__nonstring`` no destino. +- strtomem_pad() para destinos não terminados em NUL que também precisam de + preenchimento com zeros. +- memcpy_and_pad() para cópias limitadas a partir de origens potencialmente não + terminadas, onde o tamanho do destino é um valor definido em tempo de + execução (*runtime*). + +strlcpy() +--------- +A função strlcpy() lê primeiro todo o buffer de origem (já que o valor de +retorno deve corresponder ao de strlen()). Essa leitura pode exceder o limite +de tamanho do destino. Isso é ineficiente e pode levar a estouros de leitura +linear se a string de origem não for terminada em NUL. A substituta segura é +strscpy(), embora se deva ter cuidado nos casos em que o valor de retorno de +strlcpy() é utilizado, já que strscpy() retornará valores negativos de errno +quando houver truncamento. + +Especificador de formato %p +---------------------------- +Tradicionalmente, o uso de "%p" em strings de formatação causava falhas de +exposição de endereços reais no dmesg, proc, sysfs, etc. Em vez de deixar esses +endereços expostos a explorações, todos os usos de "%p" no kernel agora são +exibidos como um valor hash, tornando-os inúteis para fins de endereçamento. +Novos usos de "%p" não devem ser adicionados ao kernel. Para endereços de texto, +usar "%pS" costuma ser melhor, pois exibe o nome do símbolo, que é muito mais +útil. Para quase todo o restante, simplesmente não adicione "%p" de forma +alguma. + +Parafraseando as diretrizes atuais do Linus `guidance +<https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_: + +- Se o valor hash de "%p" é inútil, pergunte a si mesmo se o ponteiro em si é + importante. Talvez ele deva ser removido por completo? +- Se você realmente acredita que o valor real do ponteiro é importante, por que + algum estado do sistema ou nível de privilégio do usuário seria considerado + "especial"? Se você acha que pode justificar isso (em comentários e no log de + commit) de forma sólida o suficiente para resistir ao escrutínio do Linus, + talvez possa usar "%px", certificando-se de aplicar permissões adequadas. + +Se você estiver depurando algo em que a geração de hash de "%p" esteja causando +problemas, é possível inicializar o sistema temporariamente com a opção de +depuração "`no_hash_pointers +<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_". + +Matrizes de Tamanho Variável (VLAs) +----------------------------------- +O uso de VLAs (Variable Length Arrays) na pilha de execução gera um código de +máquina muito pior do que matrizes de tamanho estático na pilha. Embora esses +problemas significativos de `desempenho +<https://git.kernel.org/linus/02361bc77888>`_ sejam motivo suficiente para +eliminar as VLAs, elas também representam um risco de segurança. O crescimento +dinâmico de uma matriz na pilha pode exceder a memória restante no segmento da +pilha. Isso pode levar a um travamento, à possível sobrescrita de dados +sensíveis no final da pilha (quando compilado sem ``CONFIG_THREAD_INFO_IN_TASK=y``) +ou à sobrescrita de posições de memória adjacentes à pilha (quando compilado sem +``CONFIG_VMAP_STACK=y``). + +Passagem direta implícita no switch case (fall-through) +------------------------------------------------------- +A linguagem C permite que o fluxo de execução de um bloco switch passe +diretamente para o próximo caso (fall-through) quando uma instrução "break" +está ausente ao final de um caso. No entanto, isso introduz ambiguidade no +código, pois nem sempre fica claro se o "break" ausente é intencional ou um bug. +Por exemplo, não é óbvio apenas olhando para o código se o ``STATE_ONE`` foi +intencionalmente projetado para passar diretamente para o ``STATE_TWO``:: + + switch (value) { + case STATE_ONE: + do_something(); + case STATE_TWO: + do_other(); + break; + default: + WARN("unknown state"); + } + +Como há uma longa lista de falhas `causadas pela ausência de instruções "break" +<https://cwe.mitre.org/data/definitions/484.html>`_, não permitimos mais a +passagem direta implícita. Para identificar os casos de passagem direta +intencionais, adotamos a macro pseudo-palavra-chave "fallthrough", que se +expande para a extensão do gcc `__attribute__((__fallthrough__)) +<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_. (Quando a +sintaxe ``[[fallthrough]]`` do C17/C18 for suportada de forma mais ampla por +compiladores C, analisadores estáticos e IDEs, poderemos mudar para o uso dessa +sintaxe para a pseudo-palavra-chave da macro.) + +Todos os blocos de switch/case devem terminar com um dos seguintes elementos: + +* break; +* fallthrough; +* continue; +* goto <rótulo>; +* return [expressão]; + +Matrizes de comprimento zero e de um único elemento +---------------------------------------------------- +Há uma necessidade frequente no kernel de fornecer uma maneira de declarar uma +estrutura com um conjunto de elementos finais de tamanho dinâmico. O código do +kernel deve sempre usar `"membros de matriz flexível" +<https://en.wikipedia.org/wiki/Flexible_array_member>`_ para esses casos. O +estilo antigo de matrizes de um único elemento ou de comprimento zero não deve +mais ser utilizado. + +No código C mais antigo, elementos finais de tamanho dinâmico eram declarados +especificando uma matriz de um elemento ao final de uma estrutura:: + + struct something { + size_t count; + struct foo items[1]; + }; + +Isso levava a cálculos de tamanho frágeis via sizeof() (que exigiam a subtração +do tamanho do elemento final único para obter o tamanho correto do "cabeçalho"). +Uma `extensão GNU C <https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ foi +introduzida para permitir matrizes de comprimento zero, a fim de evitar esses +problemas de cálculo de tamanho:: + + struct something { + size_t count; + struct foo items[0]; + }; + +No entanto, isso trouxe outros problemas e não resolveu algumas limitações de +ambos os estilos, como a incapacidade de detectar quando tal matriz é usada +acidentalmente *fora* do final de uma estrutura (o que poderia ocorrer +diretamente, ou quando tal estrutura estava contida em unions, estruturas de +estruturas, etc.). + +O padrão C99 introduziu os "membros de matriz flexível", nos quais a declaração +da matriz simplesmente não possui um tamanho numérico:: + + struct something { + size_t count; + struct foo items[]; + }; + +Esta é a maneira como o kernel espera que elementos finais de tamanho dinâmico +sejam declarados. Isso permite que o compilador gere erros quando a matriz +flexível não for o último elemento da estrutura, o que ajuda a evitar que bugs +de `comportamento indefinido +<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_ sejam +introduzidos inadvertidamente na base de código. Também permite que o +compilador analise corretamente os tamanhos das matrizes (via sizeof(), +``CONFIG_FORTIFY_SOURCE`` e ``CONFIG_UBSAN_BOUNDS``). Por exemplo, não existe um +mecanismo que nos alerte de que a seguinte aplicação do operador sizeof() a uma +matriz de comprimento zero sempre resulta em zero:: + + struct something { + size_t count; + struct foo items[0]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL); + instance->count = count; + + size = sizeof(instance->items) * instance->count; + memcpy(instance->items, source, size); + +Na última linha do código acima, ``size`` acaba sendo ``zero``, quando se +poderia pensar que ele representaria o tamanho total em bytes da memória +dinâmica recentemente alocada para a matriz final ``items``. Aqui estão alguns +exemplos deste problema: `link 1 +<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_, +`link 2 +<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_. +Em vez disso, `membros de matriz flexível têm tipo incompleto e, portanto, o +operador sizeof() não pode ser aplicado +<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, de modo que qualquer +uso incorreto de tais operadores será imediatamente percebido em tempo de +compilação. + +Em relação às matrizes de um único elemento, é preciso estar muito ciente de que +`tais matrizes ocupam pelo menos o mesmo espaço que um único objeto daquele tipo +<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ e, portanto, contribuem +para o tamanho da estrutura que as contém. Isso é propício a erros sempre que se +deseja calcular o tamanho total da memória dinâmica a ser alocada para uma +estrutura que contém uma matriz desse tipo como membro:: + + struct something { + size_t count; + struct foo items[1]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL); + instance->count = count; + + size = sizeof(instance->items) * instance->count; + memcpy(instance->items, source, size); + +No exemplo acima, foi necessário lembrar de calcular ``count - 1`` ao usar o +auxiliar struct_size(); caso contrário, teríamos alocado memória --de forma não +intencional-- para um objeto ``items`` a mais. A maneira mais limpa e menos +sujeita a erros de implementar isso é através do uso de um `membro de matriz +flexível`, em conjunto com os auxiliares struct_size() e flex_array_size():: + + struct something { + size_t count; + struct foo items[]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL); + instance->count = count; + + memcpy(instance->items, source, flex_array_size(instance, items, instance->count)); + +Existem dois casos especiais de substituição nos quais o auxiliar +DECLARE_FLEX_ARRAY() precisa ser utilizado. (Note que ele é nomeado +__DECLARE_FLEX_ARRAY() para uso em cabeçalhos de UAPI.) Esses casos ocorrem +quando a matriz flexível está sozinha em uma estrutura ou faz parte de uma +union. Isso não é permitido pela especificação C99, mas sem justificativa +técnica (como pode ser visto tanto pelo uso existente de tais matrizes nesses +locais quanto pela solução alternativa que DECLARE_FLEX_ARRAY() adota). Por +exemplo, para converter isto:: + + struct something { + ... + union { + struct type1 one[0]; + struct type2 two[0]; + }; + }; + +O auxiliar deve ser utilizado:: + + struct something { + ... + union { + DECLARE_FLEX_ARRAY(struct type1, one); + DECLARE_FLEX_ARRAY(struct type2, two); + }; + }; + +Atribuições diretas de kmalloc para objetos struct +-------------------------------------------------- +Realizar atribuições diretas (*open-coded*) de alocações da família kmalloc() +impede que o kernel (e o compilador) consigam examinar o tipo da variável que +está recebendo a atribuição, o que limita qualquer introspecção relacionada que +possa ajudar com alinhamento, estouros de capacidade (*wrap-around*) ou +proteções adicionais (*hardening*). A família de macros kmalloc_obj() fornece +essa introspecção, que pode ser usada para os padrões de código comuns de +alocações de objetos únicos, de matrizes ou de objetos flexíveis. Por exemplo, +estas atribuições diretas:: + + ptr = kmalloc(sizeof(*ptr), gfp); + ptr = kzalloc(sizeof(*ptr), gfp); + ptr = kmalloc_array(count, sizeof(*ptr), gfp); + ptr = kcalloc(count, sizeof(*ptr), gfp); + ptr = kmalloc(struct_size(ptr, flex_member, count), gfp); + ptr = kmalloc(sizeof(struct foo), gfp); + +tornam-se, respectivamente:: + + ptr = kmalloc_obj(*ptr [, gfp] ); + ptr = kzalloc_obj(*ptr [, gfp] ); + ptr = kmalloc_objs(*ptr, count [, gfp] ); + ptr = kzalloc_objs(*ptr, count [, gfp] ); + ptr = kmalloc_flex(*ptr, flex_member, count [, gfp] ); + __auto_type ptr = kmalloc_obj(struct foo [, gfp] ); + +O argumento gfp é opcional, sendo o valor padrão GFP_KERNEL. Se +``ptr->flex_member`` estiver anotado com __counted_by(), a alocação falhará +automaticamente caso ``count`` seja maior do que o valor máximo representável +que pode ser armazenado no membro contador associado a ``flex_member``. diff --git a/Documentation/translations/pt_BR/process/development-process.rst b/Documentation/translations/pt_BR/process/development-process.rst index 599c34c859be..d303ab92b2d3 100644 --- a/Documentation/translations/pt_BR/process/development-process.rst +++ b/Documentation/translations/pt_BR/process/development-process.rst @@ -20,3 +20,8 @@ conhecimento profundo de programação de kernel para ser compreendida. 1.Intro 2.Process 3.Early-stage + 4.Coding + 5.Posting + 6.Followthrough + 7.AdvancedTopics + 8.Conclusion diff --git a/Documentation/translations/pt_BR/process/kernel-driver-statement.rst b/Documentation/translations/pt_BR/process/kernel-driver-statement.rst new file mode 100644 index 000000000000..5a8a8f41d566 --- /dev/null +++ b/Documentation/translations/pt_BR/process/kernel-driver-statement.rst @@ -0,0 +1,205 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Declaração sobre Drivers do Kernel +---------------------------------- + +Posicionamento sobre os Módulos do Kernel Linux +=============================================== + + +Nós, os desenvolvedores do kernel Linux abaixo assinados, consideramos +qualquer módulo ou driver de código fechado para o kernel Linux +prejudicial e indesejável. Repetidamente, constatamos que eles são +nocivos aos usuários do Linux, às empresas e ao ecossistema Linux como +um todo. Tais módulos negam a abertura, a estabilidade, a flexibilidade +e a manutenibilidade do modelo de desenvolvimento do Linux e privam +seus usuários do conhecimento da comunidade Linux. Fornecedores que +oferecem módulos de kernel de código fechado forçam seus clientes a +abrir mão de vantagens fundamentais do Linux ou a escolher novos +fornecedores. Portanto, para aproveitar plenamente a economia de custos +e os benefícios de suporte compartilhado que o código aberto tem a +oferecer, incentivamos fortemente para que os fornecedores adotem uma +política de dar suporte a seus clientes no Linux com código de kernel +de código aberto. + +Falamos apenas por nós mesmos, e não por qualquer empresa para a qual +possamos trabalhar hoje, tenhamos trabalhado no passado ou venhamos a +trabalhar no futuro. + + - Dave Airlie + - Nick Andrew + - Jens Axboe + - Ralf Baechle + - Felipe Balbi + - Ohad Ben-Cohen + - Muli Ben-Yehuda + - Jiri Benc + - Arnd Bergmann + - Thomas Bogendoerfer + - Vitaly Bordug + - James Bottomley + - Josh Boyer + - Neil Brown + - Mark Brown + - David Brownell + - Michael Buesch + - Franck Bui-Huu + - Adrian Bunk + - François Cami + - Ralph Campbell + - Luiz Fernando N. Capitulino + - Mauro Carvalho Chehab + - Denis Cheng + - Jonathan Corbet + - Glauber Costa + - Alan Cox + - Magnus Damm + - Ahmed S. Darwish + - Robert P. J. Day + - Hans de Goede + - Arnaldo Carvalho de Melo + - Helge Deller + - Jean Delvare + - Mathieu Desnoyers + - Sven-Thorsten Dietrich + - Alexey Dobriyan + - Daniel Drake + - Alex Dubov + - Randy Dunlap + - Michael Ellerman + - Pekka Enberg + - Jan Engelhardt + - Mark Fasheh + - J. Bruce Fields + - Larry Finger + - Jeremy Fitzhardinge + - Mike Frysinger + - Kumar Gala + - Robin Getz + - Liam Girdwood + - Jan-Benedict Glaw + - Thomas Gleixner + - Brice Goglin + - Cyrill Gorcunov + - Andy Gospodarek + - Thomas Graf + - Krzysztof Halasa + - Harvey Harrison + - Stephen Hemminger + - Michael Hennerich + - Tejun Heo + - Benjamin Herrenschmidt + - Kristian Høgsberg + - Henrique de Moraes Holschuh + - Marcel Holtmann + - Mike Isely + - Takashi Iwai + - Olof Johansson + - Dave Jones + - Jesper Juhl + - Matthias Kaehlcke + - Kenji Kaneshige + - Jan Kara + - Jeremy Kerr + - Russell King + - Olaf Kirch + - Roel Kluin + - Hans-Jürgen Koch + - Auke Kok + - Peter Korsgaard + - Jiri Kosina + - Aaro Koskinen + - Mariusz Kozlowski + - Greg Kroah-Hartman + - Michael Krufky + - Aneesh Kumar + - Clemens Ladisch + - Christoph Lameter + - Gunnar Larisch + - Anders Larsen + - Grant Likely + - John W. Linville + - Yinghai Lu + - Tony Luck + - Pavel Machek + - Matt Mackall + - Paul Mackerras + - Roland McGrath + - Patrick McHardy + - Kyle McMartin + - Paul Menage + - Thierry Merle + - Eric Miao + - Akinobu Mita + - Ingo Molnar + - James Morris + - Andrew Morton + - Paul Mundt + - Oleg Nesterov + - Luca Olivetti + - S.Çağlar Onur + - Pierre Ossman + - Keith Owens + - Venkatesh Pallipadi + - Nick Piggin + - Nicolas Pitre + - Evgeniy Polyakov + - Richard Purdie + - Mike Rapoport + - Sam Ravnborg + - Gerrit Renker + - Stefan Richter + - David Rientjes + - Luis R. Rodriguez + - Stefan Roese + - Francois Romieu + - Rami Rosen + - Stephen Rothwell + - Maciej W. Rozycki + - Mark Salyzyn + - Yoshinori Sato + - Deepak Saxena + - Holger Schurig + - Amit Shah + - Yoshihiro Shimoda + - Sergei Shtylyov + - Kay Sievers + - Sebastian Siewior + - Rik Snel + - Jes Sorensen + - Alexey Starikovskiy + - Alan Stern + - Timur Tabi + - Hirokazu Takata + - Eliezer Tamir + - Eugene Teo + - Doug Thompson + - FUJITA Tomonori + - Dmitry Torokhov + - Marcelo Tosatti + - Steven Toth + - Theodore Tso + - Matthias Urlichs + - Geert Uytterhoeven + - Arjan van de Ven + - Ivo van Doorn + - Rik van Riel + - Wim Van Sebroeck + - Hans Verkuil + - Horst H. von Brand + - Dmitri Vorobiev + - Anton Vorontsov + - Daniel Walker + - Johannes Weiner + - Harald Welte + - Matthew Wilcox + - Dan J. Williams + - Darrick J. Wong + - David Woodhouse + - Chris Wright + - Bryan Wu + - Rafael J. Wysocki + - Herbert Xu + - Vlad Yasevich + - Peter Zijlstra + - Bartlomiej Zolnierkiewicz diff --git a/Documentation/translations/pt_BR/process/maintainer-netdev.rst b/Documentation/translations/pt_BR/process/maintainer-netdev.rst index 5de2828041b9..e9bb998c7bfd 100644 --- a/Documentation/translations/pt_BR/process/maintainer-netdev.rst +++ b/Documentation/translations/pt_BR/process/maintainer-netdev.rst @@ -22,11 +22,11 @@ netdev ------ A **netdev** é a lista de discussão para todos os assuntos do Linux relacionados a rede. Isso inclui qualquer item encontrado em ``net/`` (ex: código principal -como IPv6) e em ``drivers/net`` (ex: drivers específicos de hardware) na árvore +como IPv6) e em ``drivers/net`` (ex: drivers específicos de hardware) na árvore de diretórios do Linux. Note que alguns subsistemas (ex: drivers de rede sem fio/wireless), que possuem -um alto volume de tráfego, possuem suas próprias listas de discussão e árvores +um alto volume de tráfego, possuem suas próprias listas de discussão e árvores específicas. Como muitas outras listas de discussão do Linux, a lista netdev é hospedada no @@ -34,7 +34,7 @@ Como muitas outras listas de discussão do Linux, a lista netdev é hospedada no https://lore.kernel.org/netdev/. À exceção dos subsistemas mencionados anteriormente, todo o desenvolvimento de -rede do Linux (ex: RFCs, revisões, comentários, etc.) ocorre na **netdev**. +rede do Linux (ex: RFCs, revisões, comentários, etc.) ocorre na **netdev**. Ciclo de Desenvolvimento ------------------------ @@ -506,8 +506,14 @@ netdevsim O ``netdevsim`` é um driver de teste que pode ser usado para exercitar APIs de configuração de driver sem a necessidade de hardware compatível. Mock-ups e -testes baseados no ``netdevsim`` são fortemente encorajados ao adicionar novas -APIs, mas o ``netdevsim`` em si **não** é considerado um caso de uso/usuário. +testes baseados no ``netdevsim`` são encorajados ao adicionar novas APIs com +lógica complexa na pilha. Os testes devem ser escritos de forma que possam ser +executados tanto contra o ``netdevsim`` quanto contra um dispositivo real +(veja ``tools/testing/selftests/drivers/net/README.rst``). Testes exclusivos +para o ``netdevsim`` devem se concentrar em testar casos extremos e caminhos de +falha no núcleo que são difíceis de exercitar com um driver real. + +``netdevsim`` em si **não** é considerado um caso de uso/usuário. Você também deve implementar as novas APIs em um driver real. Não damos garantias de que o ``netdevsim`` mudará no futuro de uma forma que @@ -577,8 +583,11 @@ independentemente do nível de experiência. Para orientações gerais e dicas É seguro assumir que os mantenedores da netdev conhecem a comunidade e o nível de experiência dos revisores. Os revisores não devem se preocupar com o fato de -seus comentários impedirem ou desviarem o fluxo de patches. Revisores menos -experientes são fortemente incentivados a fazer uma revisão mais aprofundada das +seus comentários impedirem ou desviarem o fluxo de patches. Uma tag Reviewed-by +é entendida como "Eu revisei este código da melhor maneira possível" em vez de +"Posso atestar que este código está correto". + +Revisores são fortemente incentivados a fazer uma revisão mais aprofundada das submissões e não focar exclusivamente em questões triviais ou subjetivas, como formatação de código, tags, etc. diff --git a/Documentation/translations/pt_BR/process/submit-checklist.rst b/Documentation/translations/pt_BR/process/submit-checklist.rst new file mode 100644 index 000000000000..003fc956832d --- /dev/null +++ b/Documentation/translations/pt_BR/process/submit-checklist.rst @@ -0,0 +1,145 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================================================== +Lista de verificação para submissão de patches do kernel Linux +============================================================== + +Aqui estão algumas coisas básicas que os desenvolvedores devem fazer se +quiserem ver suas submissões de patches de kernel aceitas mais rapidamente. + +Estas diretrizes vão além da documentação fornecida em +:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` +e em outros locais sobre o envio de patches para o kernel Linux. + +Revise seu código +================= + +1) Se você usar um recurso, faça o #include do arquivo que define/declara + esse recurso. Não dependa de outros arquivos de cabeçalho que incluam + os que você usa de forma indireta. + +2) Verifique o estilo geral do seu patch conforme detalhado em + :ref:`Documentation//process/coding-style.rst <codingstyle>`. + +3) Todas as barreiras de memória {por exemplo, ``barrier()``, ``rmb()``, + ``wmb()``} precisam de um comentário no código-fonte que explique a + lógica do que estão fazendo e o porquê. + +Revise as alterações do Kconfig +=============================== + +1) Quaisquer novas ou modificadas opções de ``CONFIG`` não bagunçam o + menu de configuração e têm 'desativado' (off) como padrão, a menos que + atendam aos critérios de exceção documentados em + ``Documentation/kbuild/kconfig-language.rst``, atributos de menu: valor + padrão. + +2) Todas as novas opções de ``Kconfig`` possuem texto de ajuda. + +3) Foram cuidadosamente revisadas com relação às combinações relevantes de + ``Kconfig``. Isso é muito difícil de acertar apenas com testes --- exige + capacidade de raciocínio. + pays off here. + +Forneça documentação +==================== + +1) Inclua :ref:`kernel-doc <kernel_doc>` para documentar as APIs globais + do kernel. (Não é obrigatório para funções estáticas, mas também é + aceitável nelas.) + +2) Todas as novas entradas em ``/proc`` devem ser documentadas sob + ``Documentation/``. + +3) Todos os novos parâmetros de inicialização (boot) do kernel devem ser + documentados em ``Documentation/admin-guide/kernel-parameters.rst``. + +4) Todos os novos parâmetros de módulo devem ser documentados com + ``MODULE_PARM_DESC()``. + +5) Todas as novas interfaces com o espaço de usuário (userspace) devem ser + documentadas em ``Documentation/ABI/``. Consulte + ``Documentation/admin-guide/abi.rst`` (ou ``Documentation/ABI/README``) + para obter mais informações. Patches que alteram interfaces de espaço + de usuário devem incluir em cópia (CC) linux-api@vger.kernel.org. + +6) Se quaisquer ioctls forem adicionados pelo patch, atualize também + ``Documentation/userspace-api/ioctl/ioctl-number.rst``. + +Verifique seu código com ferramentas +==================================== + +1) Verifique se há violações triviais com o verificador de estilo de patch + antes do envio (``scripts/checkpatch.pl``). Você deve ser capaz de + justificar todas as violações que permanecerem no seu patch. + +2) Faça uma verificação limpa com o sparse. + +3) Use ``make checkstack`` e corrija quaisquer problemas encontrados por ele. + Observe que o ``checkstack`` não aponta problemas explicitamente, mas + qualquer função individual que utilize mais de 512 bytes na pilha é uma + candidata a alteração. + +Compile seu código +================== + +1) Compila de forma limpa: + + a) com as opções de ``CONFIG`` aplicáveis ou modificadas definidas como + ``=y``, ``=m`` e ``=n``. Sem avisos/erros do ``gcc``, sem avisos/erros do + vinculador (linker). + + b) Passa em ``allnoconfig``, ``allmodconfig`` + + c) Compila com sucesso ao usar ``O=builddir`` + + d) Quaisquer alterações em Documentation/ compilam com sucesso sem novos + avisos/erros. Use ``make htmldocs`` ou ``make pdfdocs`` para verificar + a compilação e corrigir quaisquer problemas. + +2) Compila em múltiplas arquiteturas de CPU usando ferramentas locais de + compilação cruzada (cross-compile) ou alguma outra fazenda de compilação + (build farm). + Observe que testar em arquiteturas de diferentes tamanhos de palavra + (32 e 64 bits) e diferentes endianness (big- e little-endian) é eficaz + para capturar vários problemas de portabilidade decorrentes de falsas + suposições sobre o intervalo de quantidade representável, alinhamento + de dados ou endianness, entre outros. + +3) O novo código adicionado foi compilado com ``gcc -W`` (use + ``make KCFLAGS=-W``). Isso gerará muito ruído, mas é bom para encontrar + bugs como "warning: comparison between signed and unsigned". + +4) Se o seu código-fonte modificado depender ou usar quaisquer APIs ou + recursos do kernel relacionados aos seguintes símbolos do ``Kconfig``, + teste múltiplas compilações com os símbolos relacionados do ``Kconfig`` + desativados e/ou definidos como ``=m`` (se essa opção estiver disponível) + [não todos ao mesmo tempo, apenas combinações variadas/aleatórias deles]: + + ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, + ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``, + ``CONFIG_NET``, ``CONFIG_INET=n`` (mas este último com ``CONFIG_NET=y``). + +Teste seu código +================ + +1) Foi testado com ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``, + ``CONFIG_SLUB_DEBUG``, ``CONFIG_DEBUG_PAGEALLOC``, + ``CONFIG_DEBUG_MUTEXES``, ``CONFIG_DEBUG_SPINLOCK``, + ``CONFIG_DEBUG_ATOMIC_SLEEP``, ``CONFIG_PROVE_RCU`` e + ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` todos habilitados simultaneamente. + +2) Foi testado em tempo de compilação e de execução com e sem ``CONFIG_SMP`` + e ``CONFIG_PREEMPT``. + +3) Todos os caminhos de código foram executados com todos os recursos de + lockdep ativados. + +4) Foi verificado com a injeção de falhas de pelo menos slab e alocação de + páginas. Consulte ``Documentation/fault-injection/``. + Se o novo código for substancial, a adição de injeção de falhas específica + do subsistema pode ser apropriada. + +5) Testado com a tag mais recente do linux-next para garantir que ele ainda + funcione com todos os outros patches enfileirados e com várias alterações + na VM, VFS e outros subsistemas. diff --git a/Documentation/translations/zh_CN/accounting/psi.rst b/Documentation/translations/zh_CN/accounting/psi.rst index a0ddb7bd257c..703bc81ff9be 100644 --- a/Documentation/translations/zh_CN/accounting/psi.rst +++ b/Documentation/translations/zh_CN/accounting/psi.rst @@ -148,7 +148,7 @@ psi接口提供的均值即可。 Cgroup2接口 =========== -对于CONFIG_CGROUP=y及挂载了cgroup2文件系统的系统,能够获取cgroups内任务的psi。 +对于CONFIG_CGROUPS=y及挂载了cgroup2文件系统的系统,能够获取cgroups内任务的psi。 此场景下cgroupfs挂载点的子目录包含cpu.pressure、memory.pressure、io.pressure文件, 内容格式与/proc/pressure/下的文件相同。 diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index 15d9ab5993a7..bd01cf6474c8 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -1,7 +1,13 @@ +.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.rst -:Original: :doc:`../../../admin-guide/index` -:Translator: Alex Shi <alex.shi@linux.alibaba.com> +:Original: Documentation/admin-guide/index.rst + +:翻译: + + 时奎亮 Alex Shi <alex.shi@linux.alibaba.com> + + 朱岩 Yan Zhu <zhuyan2015@qq.com> Linux 内核用户和管理员指南 @@ -11,7 +17,11 @@ Linux 内核用户和管理员指南 整体的顺序或组织 - 这些材料不是一个单一的,连贯的文件!幸运的话,情况会随着 时间的推移而迅速改善。 -这个初始部分包含总体信息,包括描述内核的README, 关于内核参数的文档等。 + +内核管理通用指南 +---------------- + +本节包含总体信息,包括描述内核整体的 README 文件、内核参数文档等。 .. toctree:: :maxdepth: 1 @@ -20,17 +30,54 @@ Linux 内核用户和管理员指南 Todolist: -* kernel-parameters * devices +* features + +内核管理接口的重要组成部分是 /proc 和 sysfs 虚拟文件系统;这些文档描述了如何 +与之交互。 + +.. toctree:: + :maxdepth: 1 + + cputopology + +Todolist: + +* sysfs-rules * sysctl/index +* abi -本节介绍CPU漏洞及其缓解措施。 +安全相关文档: + +.. toctree:: + :maxdepth: 1 Todolist: * hw-vuln/index +* LSM/index +* perf-security + + +内核启动 +-------- + +.. toctree:: + :maxdepth: 1 + + bootconfig + +Todolist: + +* kernel-parameters +* efi-stub +* initrd + -下面的一组文档,针对的是试图跟踪问题和bug的用户。 +追踪和识别问题 +-------------- + +以下是一组面向试图追踪特定问题和 bug 的用户的文档。 .. toctree:: :maxdepth: 1 @@ -39,94 +86,149 @@ Todolist: reporting-regressions bug-hunting bug-bisect - tainted-kernels init + clearing-warn-once + lockup-watchdogs + sysrq Todolist: +* quickly-build-trimmed-linux +* verify-bugs-and-bisect-regressions +* tainted-kernels * ramoops * dynamic-debug-howto * kdump/index * perf/index +* pstore-blk +* kernel-per-CPU-kthreads +* RAS/index + + +核心内核子系统 +-------------- + +这些文档描述了核心内核管理接口,这些接口几乎在任何系统上都值得关注。 + +.. toctree:: + :maxdepth: 1 -这是应用程序开发人员感兴趣的章节的开始。可以在这里找到涵盖内核ABI各个 -方面的文档。 + cpu-load + mm/index + module-signing + numastat Todolist: -* sysfs-rules +* cgroup-v2 +* cgroup-v1/index +* namespaces/index +* pm/index +* syscall-user-dispatch -本手册的其余部分包括各种指南,介绍如何根据您的喜好配置内核的特定行为。 +对非原生二进制格式的支持。请注意,其中一些文档相当 **古老**。 .. toctree:: :maxdepth: 1 - bootconfig - clearing-warn-once - cpu-load - cputopology - lockup-watchdogs - numastat - unicode - sysrq - mm/index +Todolist: + +* binfmt-misc +* java +* mono + + +块设备和文件系统管理 +-------------------- + +.. toctree:: + :maxdepth: 1 Todolist: -* acpi/index -* aoe/index -* auxdisplay/index * bcache * binderfs -* binfmt-misc * blockdev/index -* braille-console -* btmrvl -* cgroup-v1/index -* cgroup-v2 * cifs/index -* dell_rbu * device-mapper/index -* edid -* efi-stub * ext4 +* filesystem-monitoring * nfs/index -* gpio/index -* highuid -* hw_random -* initrd * iostats -* java * jfs -* kernel-per-CPU-kthreads +* md +* ufs +* xfs + + +专用设备指南 +------------ + +如何在 Linux 系统中配置硬件。 + +.. toctree:: + :maxdepth: 1 + +Todolist: + +* acpi/index +* aoe/index +* auxdisplay/index +* braille-console +* btmrvl +* dell_rbu +* edid +* gpio/index +* hw_random * laptops/index * lcd-panel-cgram -* ldm -* LSM/index -* md * media/index -* module-signing -* mono -* namespaces/index +* nvme-multipath * parport -* perf-security -* pm/index * pnp * rapidio -* ras * rtc * serial-console * svga +* thermal/index * thunderbolt -* ufs * vga-softcursor * video-output -* xfs + + +工作负载分析 +------------ + +这是一个章节的开始,其中包含对从事 Linux 内核安全关键性分析的应用程序开发人员 +和系统集成商感兴趣的信息。这里可以找到支持分析内核与应用程序交互以及关键内核 +子系统预期的文档。 + +.. toctree:: + :maxdepth: 1 + +Todolist: + +* workload-tracing + + +其他内容 +-------- + +一些难以分类且通常已过时的文档。 + +.. toctree:: + :maxdepth: 1 + +Todolist: + +* highuid +* ldm +* unicode .. only:: subproject and html - Indices - ======= + 索引 + ==== * :ref:`genindex` diff --git a/Documentation/translations/zh_CN/admin-guide/module-signing.rst b/Documentation/translations/zh_CN/admin-guide/module-signing.rst new file mode 100644 index 000000000000..b5671224f102 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/module-signing.rst @@ -0,0 +1,250 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/admin-guide/module-signing.rst +:翻译: + 朱岩 Yan Zhu <zhuyan2015@qq.com> + + +================ +内核模块签名机制 +================ + +.. 目录 +.. +.. - 概述 +.. - 配置模块签名 +.. - 生成签名密钥 +.. - 内核中的公钥 +.. - 模块手动签名 +.. - 已签名模块和剥离 +.. - 加载已签名模块 +.. - 无效签名和未签名模块 +.. - 管理/保护私钥 + + +概述 +==== + +内核模块签名机制在安装过程中对模块进行加密签名,然后在加载模块时检查签名。这 +通过禁止加载未签名的模块或使用无效密钥签名的模块来提高内核安全性。模块签名通 +过使恶意模块更难加载到内核中来增加安全性。模块签名检查在内核中完成,因此不需 +要受信任的用户空间位。 + +此机制使用 X.509 ITU-T 标准证书对涉及的公钥进行编码。签名本身不以任何工业标准 +类型编码。内置机制目前仅支持 RSA、NIST P-384 ECDSA 和 NIST FIPS-204 ML-DSA +公钥签名标准(尽管它是可插拔的并允许使用其他标准)。对于 RSA 和 ECDSA,可以使 +用的可能的哈希算法是大小为 256、384 和 512 的 SHA-2 和 SHA-3(算法由签名中的 +数据选择);ML-DSA 会自行进行哈希运算,但允许与 SHA512 哈希算法结合用于签名属 +性。 + +配置模块签名 +============ + +通过进入内核配置的 :menuselection:`Enable Loadable Module Support` 菜单并打 +开以下选项来启用模块签名机制:: + + CONFIG_MODULE_SIG "Module signature verification" + +这有多个可用选项: + + (1) :menuselection:`Require modules to be validly signed` + (``CONFIG_MODULE_SIG_FORCE``) + + 这指定了内核应如何处理其密钥未知或未签名的模块。 + + 如果关闭(即"宽松模式"),则允许使用不可用密钥和未签名的模块,但内核将被 + 标记为受污染,并且相关模块将被标记为受污染,显示字符'E'。 + + 如果打开(即"限制模式"),只有具有有效签名且可由内核拥有的公钥验证的模块 + 才会被加载。所有其他模块将生成错误。 + + 无论此处的设置如何,如果模块的签名块无法解析,它将被直接拒绝。 + + + (2) :menuselection:`Automatically sign all modules` + (``CONFIG_MODULE_SIG_ALL``) + + 如果打开此选项,则在构建的 modules_install 阶段期间将自动签名模块。 + 如果关闭,则必须使用以下命令手动签名模块:: + + scripts/sign-file + + + (3) :menuselection:`Which hash algorithm should modules be signed with?` + + 这提供了安装阶段将用于签名模块的哈希算法选择: + + =============================== ========================================== + ``CONFIG_MODULE_SIG_SHA256`` :menuselection:`Sign modules with SHA-256` + ``CONFIG_MODULE_SIG_SHA384`` :menuselection:`Sign modules with SHA-384` + ``CONFIG_MODULE_SIG_SHA512`` :menuselection:`Sign modules with SHA-512` + ``CONFIG_MODULE_SIG_SHA3_256`` :menuselection:`Sign modules with SHA3-256` + ``CONFIG_MODULE_SIG_SHA3_384`` :menuselection:`Sign modules with SHA3-384` + ``CONFIG_MODULE_SIG_SHA3_512`` :menuselection:`Sign modules with SHA3-512` + =============================== ========================================== + + 此处选择的算法也将被构建到内核中(而不是作为模块),以便使用该算法签名的 + 模块可以在不导致循环依赖的情况下检查其签名。 + + + (4) :menuselection:`File name or PKCS#11 URI of module signing key` + (``CONFIG_MODULE_SIG_KEY``) + + 将此选项设置为除默认值 ``certs/signing_key.pem`` 之外的其他值将禁用签名 + 密钥的自动生成,并允许使用您选择的密钥对内核模块进行签名。提供的字符串应 + 标识包含私钥及其对应的 PEM 格式 X.509 证书的文件,或者在 OpenSSL + ENGINE_pkcs11 功能正常的系统上,使用 RFC7512 定义的 PKCS#11 URI。在后一 + 种情况下,PKCS#11 URI 应引用证书和私钥。 + + 如果包含私钥的 PEM 文件已加密,或者 PKCS#11 令牌需要 PIN,可以通过 + ``KBUILD_SIGN_PIN`` 变量在构建时提供。 + + + (5) :menuselection:`Additional X.509 keys for default system keyring` + (``CONFIG_SYSTEM_TRUSTED_KEYS``) + + 此选项可设置为包含附加证书的 PEM 编码文件的文件名,这些证书将默认包含在 + 系统密钥环中。 + +请注意,启用模块签名会为内核构建过程添加对执行签名工具的 OpenSSL 开发包的依赖。 + + +生成签名密钥 +============ + +生成和检查签名需要加密密钥对。私钥用于生成签名,相应的公钥用于检查签名。私钥 +仅在构建期间需要,之后可以删除或安全存储。公钥被构建到内核中,以便在加载模块 +时可以使用它来检查签名。 + +在正常情况下,当 ``CONFIG_MODULE_SIG_KEY`` 保持默认值时,如果文件中不存在密 +钥对,内核构建将使用 openssl 自动生成新的密钥对:: + + certs/signing_key.pem + +在构建 vmlinux 期间(公钥需要构建到 vmlinux 中)使用参数:: + + certs/x509.genkey + +文件(如果尚不存在也会生成)。 + +可以在 RSA(``MODULE_SIG_KEY_TYPE_RSA``)、 +ECDSA(``MODULE_SIG_KEY_TYPE_ECDSA``)和 +ML-DSA(``MODULE_SIG_KEY_TYPE_MLDSA_*``)之间选择生成 RSA 4k、NIST P-384 +密钥对或 ML-DSA 44、65 或 87 密钥对。 + +强烈建议您提供自己的 x509.genkey 文件。 + +最值得注意的是,在 x509.genkey 文件中,req_distinguished_name 部分应从默认值 +更改:: + + [ req_distinguished_name ] + #O = Unspecified company + CN = Build time autogenerated kernel key + #emailAddress = unspecified.user@unspecified.company + +生成的 RSA 密钥大小也可以通过以下方式设置:: + + [ req ] + default_bits = 4096 + +也可以使用位于 Linux 内核源代码树根节点中的 x509.genkey 密钥生成配置文件和 +openssl 命令手动生成公钥/私钥文件。以下是生成公钥/私钥文件的示例:: + + openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \ + -config x509.genkey -outform PEM -out kernel_key.pem \ + -keyout kernel_key.pem + +然后可以将生成的 kernel_key.pem 文件的完整路径名指定在 +``CONFIG_MODULE_SIG_KEY`` 选项中,并且将使用其中的证书和密钥而不是自动生成的 +密钥对。 + + +内核中的公钥 +============ + +内核包含一个可由 root 查看的公钥环。它们在名为 ".builtin_trusted_keys" 的密 +钥环中,可以通过以下方式查看:: + + [root@deneb ~]# cat /proc/keys + ... + 223c7853 I------ 1 perm 1f030000 0 0 keyring .builtin_trusted_keys: 1 + 302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 [] + +除了专门为模块签名生成的公钥外,还可以在 ``CONFIG_SYSTEM_TRUSTED_KEYS`` 配置 +选项引用的 PEM 编码文件中提供其他受信任的证书。 + +此外,架构代码可以从硬件存储中获取公钥并将其添加(例如从 UEFI 密钥数据库)。 + +最后,可以通过以下方式添加其他公钥:: + + keyctl padd asymmetric "" [.builtin_trusted_keys-ID] <[key-file] + +例如:: + + keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509 + +但是,请注意,内核只允许将由已驻留在 ``.builtin_trusted_keys`` 中的密钥有效 +签名的密钥添加到 ``.builtin_trusted_keys``。 + +模块手动签名 +============ + +要手动对模块进行签名,请使用 Linux 内核源代码树中可用的 scripts/sign-file 工 +具。该脚本需要 4 个参数: + + 1. 哈希算法(例如,sha256) + 2. 私钥文件名或 PKCS#11 URI + 3. 公钥文件名 + 4. 要签名的内核模块 + +以下是签名内核模块的示例:: + + scripts/sign-file sha512 kernel-signkey.priv \ + kernel-signkey.x509 module.ko + +使用的哈希算法不必与配置的算法匹配,但如果不同,应确保哈希算法要么内置在内核 +中,要么可以在不需要自身的情况下加载。 + +如果私钥需要密码或 PIN,可以在 $KBUILD_SIGN_PIN 环境变量中提供。 + + +已签名模块和剥离 +================ + +已签名模块在末尾简单地附加了数字签名。模块文件末尾的字符串 +``~Module signature appended~.`` 确认签名存在,但不能确认签名有效! + +已签名模块是脆弱的,因为签名在定义的ELF容器之外。因此,一旦计算并附加签名,就 +不得剥离它们。请注意,整个模块都是签名的有效载荷,包括签名时存在的任何和所有 +调试信息。 + + +加载已签名模块 +============== + +模块通过 insmod、modprobe、 ``init_module()`` 或 ``finit_module()`` 加载, +与未签名模块完全一样,因为在用户空间中不进行任何处理。 +所有签名检查都在内核内完成。 + + +无效签名和未签名模块 +==================== + +如果启用了 ``CONFIG_MODULE_SIG_FORCE`` 或在内核启动命令提供了 +module.sig_enforce=1,内核将仅加载具有有效签名且具有公钥的模块。否则,它还将 +加载未签名的模块。任何具有不匹配签名的模块将不被允许加载。 + +任何具有不可解析签名的模块将被拒绝。 + + +管理/保护私钥 +============== + +由于私钥用于签名模块,病毒和恶意软件可以使用私钥签名模块并危害操作系统。私钥 +必须被销毁或移动到安全位置,而不是保存在内核源代码树的根节点中。 + +如果使用相同的私钥为多个内核配置签名模块,必须确保模块版本信息足以防止将模块 +加载到不同的内核中。要么设置 ``CONFIG_MODVERSIONS=y``,要么通过更改 +``EXTRAVERSION`` 或 ``CONFIG_LOCALVERSION`` 确保每个配置具有不同的内核发布字 +符串。 diff --git a/Documentation/translations/zh_CN/dev-tools/kasan.rst b/Documentation/translations/zh_CN/dev-tools/kasan.rst index fd2e3afbdfad..767b280d8af0 100644 --- a/Documentation/translations/zh_CN/dev-tools/kasan.rst +++ b/Documentation/translations/zh_CN/dev-tools/kasan.rst @@ -79,7 +79,7 @@ KASAN只支持SLUB。 CONFIG_KASAN=y 同时在 ``CONFIG_KASAN_GENERIC`` (启用通用KASAN模式), ``CONFIG_KASAN_SW_TAGS`` -(启用基于硬件标签的KASAN模式),和 ``CONFIG_KASAN_HW_TAGS`` (启用基于硬件标签 +(启用基于软件标签的KASAN模式),和 ``CONFIG_KASAN_HW_TAGS`` (启用基于硬件标签 的KASAN模式)之间进行选择。 对于软件模式,还可以在 ``CONFIG_KASAN_OUTLINE`` 和 ``CONFIG_KASAN_INLINE`` diff --git a/Documentation/translations/zh_CN/how-to.rst b/Documentation/translations/zh_CN/how-to.rst index 7ae5d8765888..9ec2384e1e76 100644 --- a/Documentation/translations/zh_CN/how-to.rst +++ b/Documentation/translations/zh_CN/how-to.rst @@ -13,20 +13,20 @@ Linux 内核中文文档翻译规范 过去几年,在广大社区爱好者的友好合作下,Linux 内核中文文档迎来了蓬勃的发 展。在翻译的早期,一切都是混乱的,社区对译稿只有一个准确翻译的要求,以鼓 励更多的开发者参与进来,这是从 0 到 1 的必然过程,所以早期的中文文档目录 -更加具有多样性,不过好在文档不多,维护上并没有过大的压力。 +呈现出较强的多样性,不过好在文档不多,维护上并没有过大的压力。 然而,世事变幻,不觉有年,现在内核中文文档在前进的道路上越走越远,很多潜 在的问题逐渐浮出水面,而且随着中文文档数量的增加,翻译更多的文档与提高中 文文档可维护性之间的矛盾愈发尖锐。由于文档翻译的特殊性,很多开发者并不会 一直更新文档,如果中文文档落后英文文档太多,文档更新的工作量会远大于重新 翻译。而且邮件列表中陆续有新的面孔出现,他们那股热情,就像燃烧的火焰,能 -瞬间点燃整个空间,可是他们的补丁往往具有个性,这会给审阅带来了很大的困难, +瞬间点燃整个空间,可是他们的补丁往往具有个性,这给审阅带来了很大的困难, reviewer 们只能耐心地指导他们如何与社区更好地合作,但是这项工作具有重复 性,长此以往,会渐渐浇灭 reviewer 审阅的热情。 -虽然内核文档中已经有了类似的贡献指南,但是缺乏专门针对于中文翻译的,尤其 +虽然内核文档中已经有了类似的贡献指南,但是缺乏专门面向中文翻译的,尤其 是对于新手来说,浏览大量的文档反而更加迷惑,该文档就是为了缓解这一问题而 -编写,目的是为提供给新手一个快速翻译指南。 +编写,旨在为新手提供一份快速翻译指南。 详细的贡献指南:Documentation/translations/zh_CN/process/index.rst。 @@ -145,8 +145,8 @@ Git 和邮箱配置 sudo dnf install git-email vim ~/.gitconfig -这里是我的一个配置文件示范,请根据您的邮箱域名服务商提供的手册替换到对 -应的字段。 +这里是我的一个配置文件示范,请根据您的邮箱域名服务商提供的手册替换对应 +的字段。 :: [user] @@ -190,7 +190,7 @@ Git 和邮箱配置 译文格式要求 ------------ - - 每行长度最多不超过 40 个字符 + - 每行长度不超过 40 个字符 - 每行长度请保持一致 - 标题的下划线长度请按照一个英文一个字符、一个中文两个字符与标题对齐 - 其它的修饰符请与英文文档保持一致 @@ -211,7 +211,7 @@ Git 和邮箱配置 -------- 中文文档有每行 40 字符限制,因为一个中文字符等于 2 个英文字符。但是社区并 -没有那么严格,一个诀窍是将您的翻译的内容与英文原文的每行长度对齐即可,这样, +没有那么严格,一个诀窍是将您翻译的内容与英文原文的每行长度对齐,这样, 您也不必总是检查有没有超限。 如果您的英文阅读能力有限,可以考虑使用辅助翻译工具,例如 deepseek。但是您 @@ -257,7 +257,9 @@ Git 和邮箱配置 Update the translation through commit b080e52110ea ("docs: update self-protection __ro_after_init status") - # 请执行 git log --oneline <您翻译的英文文档路径>,并替换上述内容 + # 请执行 git log --no-merges --oneline <您翻译的英文文档路径> + # 并替换上述内容。注意:应引用实际修改文件内容的 commit, + # 而非 merge commit Signed-off-by: Yanteng Si <si.yanteng@linux.dev> # 如果您前面的步骤正确执行,该行会自动显示,否则请检查 gitconfig 文件 @@ -267,13 +269,22 @@ Git 和邮箱配置 **请注意** 以上四行,缺少任何一行,您都将会在第一轮审阅后返工,如果您需要一个 更加明确的示例,请对 zh_CN 目录执行 git log。 -导出补丁和制作封面 ------------------- +导出补丁 +-------- + +这个时候,可以导出补丁,做发送邮件列表最后的准备了。对于单个补丁, +命令行执行:: + + git format-patch -1 + +然后命令行会输出类似下面的内容:: + + 0001-docs-zh_CN-add-xxxxxxxx.patch -这个时候,可以导出补丁,做发送邮件列表最后的准备了。命令行执行:: +如果您有多个补丁,命令行执行:: git format-patch -N - # N 要替换为补丁数量,一般 N 大于等于 1 + # N 要替换为补丁数量,一般 N 大于 1 然后命令行会输出类似下面的内容:: @@ -288,13 +299,12 @@ Git 和邮箱配置 ./scripts/checkpatch.pl *.patch -参考脚本输出,解决掉所有的 error 和 warning,通常情况下,只有下面这个 +参考脚本输出,解决掉所有的 error 和 warning。通常情况下,只有下面这个 warning 不需要解决:: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? -一个简单的解决方法是一次只检查一个补丁,然后打上该补丁,直接对译文进行修改, -然后执行以下命令为补丁追加更改:: +对于单个补丁,解决方案很简单,只需要打上该补丁,直接对译文进行修改,为补丁追加后续更改:: git checkout docs-next git checkout -b test-trans-new @@ -302,15 +312,21 @@ warning 不需要解决:: ./scripts/checkpatch.pl 0001-xxxxx.patch # 直接修改您的翻译 git add . - git am --amend + git commit --amend # 保存退出 - git am 0002-xxxxx.patch - …… -重新导出再次检测,重复这个过程,直到处理完所有的补丁。 +随后,重新导出补丁再次检测,重复这个过程,直到处理完所有 warning 和 +error。 + +如果您有多个补丁,请按补丁集中补丁顺序对每个补丁重复上述流程,一次只处理 +一个,不要一次 git am 多个补丁。全部处理完毕后再重新导出并再次测试。 -最后,如果检测时没有 warning 和 error 需要被处理或者您只有一个补丁,请跳 -过下面这个步骤,否则请重新导出补丁制作封面:: +为补丁集制作封面 +---------------- + +对于单个补丁,请跳过本节。 + +如果您有多个补丁,则需要为补丁集制作一份封面,即 0 号补丁:: git format-patch -N --cover-letter --thread=shallow # N 要替换为补丁数量,一般 N 大于 1 @@ -327,18 +343,14 @@ warning 不需要解决:: vim 0000-cover-letter.patch ... - Subject: [PATCH 0/N] *** SUBJECT HERE *** #修改该字段,概括您的补丁集都做了哪些事情 + Subject: [PATCH 0/N] *** SUBJECT HERE *** # 修改该字段,概括您的补丁集都做了哪些事情 - *** BLURB HERE *** #修改该字段,详细描述您的补丁集做了哪些事情 + *** BLURB HERE *** # 修改该字段,详细描述您的补丁集做了哪些事情 Yanteng Si (1): docs/zh_CN: add xxxxx ... -如果您只有一个补丁,则可以不制作封面,即 0 号补丁,只需要执行:: - - git format-patch -1 - 把补丁提交到邮件列表 ==================== @@ -361,13 +373,13 @@ warning 不需要解决:: git send-email *.patch --to <maintainer email addr> --cc <others addr> # 一个 to 对应一个地址,一个 cc 对应一个地址,有几个就写几个 -执行该命令时,请确保网络通常,邮件发送成功一般会返回 250。 +执行该命令时,请确保网络通畅,邮件发送成功一般会返回 250。 您可以先发送给自己,尝试发出的 patch 是否可以用 'git am' 工具正常打上。 如果检查正常, 您就可以放心的发送到社区评审了。 -如果该步骤被中断,您可以检查一下,继续用上条命令发送失败的补丁,一定不要再 -次发送已经发送成功的补丁。 +如果该步骤被中断,您可以检查一下,然后用上条命令继续发送失败的补丁,一定不 +要再次发送已经发送成功的补丁。 积极参与审阅过程并迭代补丁 ========================== @@ -380,7 +392,7 @@ reviewer 的评论,做到每条都有回复,每个回复都落实到位。 - 请先将您的邮箱客户端信件回复修改为 **纯文本** 格式,并去除所有签名,尤其是 企业邮箱。 - - 然后点击回复按钮,并将要回复的邮件带入, + - 然后点击回复按钮,并引用要回复的邮件, - 在第一条评论行尾换行,输入您的回复 - 在第二条评论行尾换行,输入您的回复 - 直到处理完最后一条评论,换行空两行输入问候语和署名 @@ -390,28 +402,67 @@ reviewer 的评论,做到每条都有回复,每个回复都落实到位。 迭代补丁 -------- -建议您每回复一条评论,就修改一处翻译。然后重新生成补丁,相信您现在已经具 -备了灵活使用 git am --amend 的能力。 +建议您每回复一条评论,就修改一处翻译,然后重新生成补丁,相信您现在 +已经具备了灵活使用 git am 与 git commit --amend 的能力。 -每次迭代一个补丁,不要一次多个:: +对于单个补丁,每回复完评论后修改、追加:: - git am <您要修改的补丁> + git am 0001-xxxxx.patch # 直接对文件进行您的修改 git add . git commit --amend -当您将所有的评论落实到位后,导出第二版补丁,并修改封面:: +当您将所有的评论落实到位后,导出第二版补丁:: - git format-patch -N -v 2 --cover-letter --thread=shallow + git format-patch -1 -v 2 + +命令行会输出 v2-0001-xxxxx.patch。打开该文件,在 --- 分割线下方追加 +changelog。注意,分割线以下的内容不会进入 git 提交历史,仅作为邮件中的 +说明供 reviewer 检查:: + + Subject: [PATCH v2] docs/zh_CN: add xxxxxx translation + + Translate .../xxx.rst into Chinese. + + Signed-off-by: Yanteng Si <si.yanteng@linux.dev> + --- + v1->v2: + - 修正第二节的错别字,Reviewer-A 提出的意见 + - 根据 Reviewer-B 的建议调整段落顺序 -打开 0 号补丁,在 BLURB HERE 处编写相较于上个版本,您做了哪些改动。 + Documentation/translations/zh_CN/xxx.rst | 100 ++++++ + 1 file changed, 100 insertions(+) -然后执行:: +后续迭代 v3、v4 …… 时,新的 changelog 放在最上面,旧的保留在下方,按 +从新到旧的顺序叠加。例如 v3 补丁的 --- 下方:: - git send-email v2* --to <maintainer email addr> --cc <others addr> + --- + v2->v3: + - ...本次相较 v2 的改动... + v1->v2: + - ...上一次相较 v1 的改动... + +然后发送:: + + git send-email v2-0001-*.patch --to <maintainer email addr> --cc <others addr> + +如果您有多个补丁,迭代时请按以下原则:每次只迭代一个补丁,不要一次多个, +每个补丁独立重复上述流程。所有评论落实到位后,导出 v2 时附带封面:: + + git format-patch -N -v 2 --cover-letter --thread=shallow + +打开 0 号补丁,在 BLURB HERE 处写明整组补丁相较 v1 的总体改动,格式 +同上面的单个补丁 changelog 示例。如果某个补丁需要单独说明,可在该 +补丁文件的 --- 分割线下方追加单个补丁的 changelog。最后执行:: + + git send-email v2-*.patch --to <maintainer email addr> --cc <others addr> 这样,新的一版补丁就又发送到邮件列表等待审阅,之后就是重复这个过程。 +此外,如果审阅者或维护者在邮件回复中给出了 Reviewed-by tag,请在下 +一版补丁的 commit 信息中加入该 tag,放在 Signed-off-by 行的下方,以 +便维护者合入时保留您的审阅记录。 + 审阅周期 -------- @@ -425,10 +476,10 @@ reviewer 的评论,做到每条都有回复,每个回复都落实到位。 紧急处理 -------- -如果您发送到邮件列表之后。发现发错了补丁集,尤其是在多个版本迭代的过程中; +如果您发送到邮件列表之后,发现发错了补丁集,尤其是在多个版本迭代的过程中; 自己发现了一些不妥的翻译;发送错了邮件列表…… -git email 默认会抄送给您一份,所以您可以切换为审阅者的角色审查自己的补丁, +git send-email 默认会抄送给您一份,所以您可以切换为审阅者的角色审查自己的补丁, 并留下评论,描述有何不妥,将在下个版本怎么改,并付诸行动,重新提交,但是 注意频率,每天提交的次数不要超过两次。 @@ -437,7 +488,7 @@ git email 默认会抄送给您一份,所以您可以切换为审阅者的角 对于首次参与 Linux 内核中文文档翻译的新手,建议您在 linux 目录中运行以下命令: :: - tools/docs/checktransupdate.py -l zh_CN`` + tools/docs/checktransupdate.py -l zh_CN 该命令会列出需要翻译或更新的英文文档,结果同时保存在 checktransupdate.log 中。 @@ -446,9 +497,9 @@ git email 默认会抄送给您一份,所以您可以切换为审阅者的角 进阶 ---- -希望您不只是单纯的翻译内核文档,在熟悉了一起与社区工作之后,您可以审阅其他 +希望您不只是单纯地翻译内核文档,在熟悉了与社区协作之后,您可以审阅其他 开发者的翻译,或者提出具有建设性的主张。与此同时,与文档对应的代码更加有趣, -而且需要完善的地方还有很多,勇敢地去探索,然后提交你的想法吧。 +而且需要完善的地方还有很多,勇敢地去探索,然后提交您的想法吧。 常见的问题 ========== @@ -467,7 +518,7 @@ Maintainer 回复补丁不能正常 apply ------------------ 大部分情况下,是由于您发送了非纯文本格式的信件,请尽量避免使用 webmail,推荐 -使用邮件客户端,比如 thunderbird,记得在设置中的回信配置那改为纯文本发送。 +使用邮件客户端,比如 thunderbird,记得在设置的回信配置中改为纯文本发送。 -如果超过了 24 小时,您依旧没有在<https://lore.kernel.org/linux-doc/>发现您的 -邮件,请联系您的网络管理员帮忙解决。 +如果超过了 24 小时,您依旧没有在 https://lore.kernel.org/linux-doc/ 上找到您 +的邮件,请联系您的网络管理员帮忙解决。 diff --git a/Documentation/translations/zh_CN/rust/arch-support.rst b/Documentation/translations/zh_CN/rust/arch-support.rst index f5ae44588a57..0ca4be6e1763 100644 --- a/Documentation/translations/zh_CN/rust/arch-support.rst +++ b/Documentation/translations/zh_CN/rust/arch-support.rst @@ -23,6 +23,7 @@ ``arm64`` Maintained 仅小端序。 ``loongarch`` Maintained \- ``riscv`` Maintained 仅 ``riscv64``,且仅限 LLVM/Clang。 +``s390`` Maintained 必须禁用 ``CONFIG_EXPOLINE``。 ``um`` Maintained \- ``x86`` Maintained 仅 ``x86_64``。 ============= ================ ============================================== diff --git a/Documentation/translations/zh_CN/rust/general-information.rst b/Documentation/translations/zh_CN/rust/general-information.rst index 9b5e37e13f38..a8c1a226ed4f 100644 --- a/Documentation/translations/zh_CN/rust/general-information.rst +++ b/Documentation/translations/zh_CN/rust/general-information.rst @@ -13,6 +13,14 @@ 本文档包含了在内核中使用Rust支持时需要了解的有用信息。 +``no_std`` +---------- + +内核中的 Rust 支持只能链接 `core <https://doc.rust-lang.org/core/>`_, +而不能链接 `std <https://doc.rust-lang.org/std/>`_。供内核使用的 crate +必须使用 ``#![no_std]`` 属性选择这种行为。 + + .. _rust_code_documentation_zh_cn: 代码文档 @@ -20,10 +28,18 @@ Rust内核代码使用其内置的文档生成器 ``rustdoc`` 进行记录。 -生成的HTML文档包括集成搜索、链接项(如类型、函数、常量)、源代码等。它们可以在以下地址阅读 -(TODO:当在主线中时链接,与其他文档一起生成): +生成的 HTML 文档包括集成搜索、链接项(如类型、函数、常量)、源代码等。 +它们可以在以下地址阅读: + + https://rust.docs.kernel.org + +对于 linux-next,请参阅: - http://kernel.org/ + https://rust.docs.kernel.org/next/ + +每个主要版本也有对应的标签,例如: + + https://rust.docs.kernel.org/6.10/ 这些文档也可以很容易地在本地生成和阅读。这相当快(与编译代码本身的顺序相同),而且不需要特 殊的工具或环境。这有一个额外的好处,那就是它们将根据所使用的特定内核配置进行定制。要生成它 @@ -62,6 +78,58 @@ Rust内核代码使用其内置的文档生成器 ``rustdoc`` 进行记录。 模块(例如,驱动程序)不应该直接使用C语言的绑定。相反,子系统应该根据需要提供尽可能安 全的抽象。 +.. code-block:: + + rust/bindings/ + (rust/helpers/) + + include/ -----+ <-+ + | | + drivers/ rust/kernel/ +----------+ <-+ | + fs/ | bindgen | | + .../ +-------------------+ +----------+ --+ | + | Abstractions | | | + +---------+ | +------+ +------+ | +----------+ | | + | my_foo | -----> | | foo | | bar | | -------> | Bindings | <-+ | + | driver | Safe | | sub- | | sub- | | Unsafe | | | + +---------+ | |system| |system| | | bindings | <-----+ + | | +------+ +------+ | | crate | | + | | kernel crate | +----------+ | + | +-------------------+ | + | | + +------------------# FORBIDDEN #--------------------------------+ + +主要思想是将所有与内核 C API 的直接交互封装到经过仔细审查和文档化的抽象 +中。这样,只要满足以下条件,这些抽象的用户就不能引入未定义行为 +(undefined behavior,UB): + +#. 抽象是正确的("可靠")。 +#. 任何 ``unsafe`` 块都遵守调用块内操作所需的安全契约。类似地,任何 + ``unsafe impl`` 都遵守实现该特性所需的安全契约。 + +绑定 +~~~~ + +通过从 ``include/`` 中将 C 头文件包含到 +``rust/bindings/bindings_helper.h``, ``bindgen`` 工具将为所包含的子系统 +自动生成绑定。构建后,请查看 ``rust/bindings/`` 目录中的 +``*_generated.rs`` 输出文件。 + +对于 ``bindgen`` 不会自动生成的 C 头文件部分,例如 C ``inline`` 函数或 +非平凡宏,可以在 ``rust/helpers/`` 中添加一个小型包装函数,使其也可供 +Rust 端使用。 + +抽象 +~~~~ + +抽象是绑定和内核内用户之间的层。它们位于 ``rust/kernel/`` 中,其作用是 +将对绑定的不安全访问封装到尽可能安全并暴露给用户的 API 中。抽象的用户 +包括用 Rust 编写的驱动程序或文件系统等。 + +除了安全方面,这些抽象还应该易于使用,也就是说,把 C 接口转换为符合 +Rust 惯例的代码。基本示例包括将 C 的资源获取和释放转换为 Rust 的初始化 +和清理模式,或者将 C 整数错误码转换为 Rust 的 ``Result``。 + 有条件的编译 ------------ @@ -74,3 +142,11 @@ Rust代码可以访问基于内核配置的条件性编译: #[cfg(CONFIG_X="y")] // Enabled as a built-in (`y`) #[cfg(CONFIG_X="m")] // Enabled as a module (`m`) #[cfg(not(CONFIG_X))] // Disabled + +对于 Rust 的 ``cfg`` 不支持的其他条件,例如带有数值比较的表达式,可以 +定义一个新的 Kconfig 符号: + +.. code-block:: kconfig + + config RUSTC_HAS_SPAN_FILE + def_bool RUSTC_VERSION >= 108800 diff --git a/Documentation/translations/zh_CN/rust/quick-start.rst b/Documentation/translations/zh_CN/rust/quick-start.rst index 5f0ece6411f5..0396137f3c19 100644 --- a/Documentation/translations/zh_CN/rust/quick-start.rst +++ b/Documentation/translations/zh_CN/rust/quick-start.rst @@ -59,7 +59,7 @@ Fedora Linux 提供较新的 Rust 版本,因此通常开箱即用,例如:: Gentoo Linux ************ -Gentoo Linux(尤其是 testing 分支)提供较新的 Rust 版本,因此通常开箱即用, +Gentoo Linux 提供较新的 Rust 版本,因此通常开箱即用, 例如:: USE='rust-src rustfmt clippy' emerge dev-lang/rust dev-util/bindgen @@ -70,7 +70,7 @@ Gentoo Linux(尤其是 testing 分支)提供较新的 Rust 版本,因此 Nix *** -Nix(unstable 频道)提供较新的 Rust 版本,因此通常开箱即用,例如:: +Nix 提供较新的 Rust 版本,因此通常开箱即用,例如:: { pkgs ? import <nixpkgs> {} }: pkgs.mkShell { @@ -85,16 +85,14 @@ openSUSE openSUSE Slowroll 和 openSUSE Tumbleweed 提供较新的 Rust 版本,因此通常开箱 即用,例如:: - zypper install rust rust1.79-src rust-bindgen clang + zypper install rust rust-src rust-bindgen clang Ubuntu ****** -25.04 -~~~~~ - -最新的 Ubuntu 版本提供较新的 Rust 版本,因此通常开箱即用,例如:: +Ubuntu 25.10 和 26.04 LTS 提供较新的 Rust 版本,因此通常开箱即用, +例如:: apt install rustc rust-src bindgen rustfmt rust-clippy @@ -111,32 +109,32 @@ Ubuntu 虽然 Ubuntu 24.04 LTS 及更早版本仍然提供较新的 Rust 版本,但它们需要一些额外的配 置,使用带版本号的软件包,例如:: - apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 \ - rust-1.80-clippy - ln -s /usr/lib/rust-1.80/bin/rustfmt /usr/bin/rustfmt-1.80 - ln -s /usr/lib/rust-1.80/bin/clippy-driver /usr/bin/clippy-driver-1.80 + apt install rustc-1.85 rust-1.85-src bindgen-0.71 rustfmt-1.85 \ + rust-1.85-clippy + ln -s /usr/lib/rust-1.85/bin/rustfmt /usr/bin/rustfmt-1.85 + ln -s /usr/lib/rust-1.85/bin/clippy-driver /usr/bin/clippy-driver-1.85 这些软件包都不会将其工具设置为默认值;因此应该显式指定它们,例如:: - make LLVM=1 RUSTC=rustc-1.80 RUSTDOC=rustdoc-1.80 RUSTFMT=rustfmt-1.80 \ - CLIPPY_DRIVER=clippy-driver-1.80 BINDGEN=bindgen-0.65 + make LLVM=1 RUSTC=rustc-1.85 RUSTDOC=rustdoc-1.85 RUSTFMT=rustfmt-1.85 \ + CLIPPY_DRIVER=clippy-driver-1.85 BINDGEN=bindgen-0.71 -或者,修改 ``PATH`` 变量将 Rust 1.80 的二进制文件放在前面,并将 ``bindgen`` 设 +或者,修改 ``PATH`` 变量将 Rust 1.85 的二进制文件放在前面,并将 ``bindgen`` 设 置为默认值,例如:: - PATH=/usr/lib/rust-1.80/bin:$PATH + PATH=/usr/lib/rust-1.85/bin:$PATH update-alternatives --install /usr/bin/bindgen bindgen \ - /usr/bin/bindgen-0.65 100 - update-alternatives --set bindgen /usr/bin/bindgen-0.65 + /usr/bin/bindgen-0.71 100 + update-alternatives --set bindgen /usr/bin/bindgen-0.71 -使用带版本号的软件包时需要设置 ``RUST_LIB_SRC``,例如:: +使用带版本号的软件包时可能需要设置 ``RUST_LIB_SRC``,例如:: - RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library + RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.85 --version | cut -d' ' -f2)/library 为方便起见,可以将 ``RUST_LIB_SRC`` 导出到全局环境中。 -此外, ``bindgen-0.65`` 在较新的版本(24.04 LTS 和 24.10)中可用,但在更早的版 -本(20.04 LTS 和 22.04 LTS)中可能不可用,因此可能需要手动构建 ``bindgen`` +此外, ``bindgen-0.71`` 在较新的版本(24.04 LTS)中可用,但在更早的版本 +(20.04 LTS 和 22.04 LTS)中可能不可用,因此可能需要手动构建 ``bindgen`` (请参见下文)。 @@ -325,11 +323,3 @@ Rust支持(CONFIG_RUST)需要在 ``General setup`` 菜单中启用。在其 要想深入了解,请看 ``samples/rust/`` 下的样例源代码、 ``rust/`` 下的Rust支持代码和 ``Kernel hacking`` 下的 ``Rust hacking`` 菜单。 - -如果使用的是GDB/Binutils,而Rust符号没有被demangled,原因是工具链还不支持Rust的新v0 -mangling方案。有几个办法可以解决: - -- 安装一个较新的版本(GDB >= 10.2, Binutils >= 2.36)。 - -- 一些版本的GDB(例如vanilla GDB 10.1)能够使用嵌入在调试信息(``CONFIG_DEBUG_INFO``) - 中的pre-demangled的名字。 diff --git a/Documentation/translations/zh_CN/rust/testing.rst b/Documentation/translations/zh_CN/rust/testing.rst index ca81f1cef6eb..6747d0012991 100644 --- a/Documentation/translations/zh_CN/rust/testing.rst +++ b/Documentation/translations/zh_CN/rust/testing.rst @@ -128,10 +128,13 @@ Rust 测试中常用的断言宏是来自 Rust 标准库( ``core`` )中的 ` 这些测试通过 ``kunit_tests`` 过程宏引入,该宏将测试套件的名称作为参数。 +每个测试套件都应该由 ``rust/kernel/Kconfig.test`` 中的 Kconfig 选项保护。 + 例如,假设想要测试前面文档测试示例中的函数 ``f``,我们可以在定义该函数的同一文件中编写: .. code-block:: rust + #[cfg(CONFIG_RUST_MYMOD_KUNIT_TEST)] #[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; @@ -158,6 +161,7 @@ Rust 测试中常用的断言宏是来自 Rust 标准库( ``core`` )中的 ` .. code-block:: rust + #[cfg(CONFIG_RUST_MYMOD_KUNIT_TEST)] #[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; diff --git a/Documentation/translations/zh_CN/scheduler/sched-energy.rst b/Documentation/translations/zh_CN/scheduler/sched-energy.rst index fdbf6cfeea93..03dedc69839a 100644 --- a/Documentation/translations/zh_CN/scheduler/sched-energy.rst +++ b/Documentation/translations/zh_CN/scheduler/sched-energy.rst @@ -119,7 +119,7 @@ EAS覆盖了CFS的任务唤醒平衡代码。在唤醒平衡时,它使用平 如果唤醒的任务被迁移,find_energy_efficient_cpu()使用compute_energy()来估算 系统将消耗多少能量。compute_energy()检查各CPU当前的利用率情况,并尝试调整来 -“模拟”任务迁移。EM框架提供了API em_pd_energy()计算每个性能域在给定的利用率条件 +“模拟”任务迁移。EM框架提供了API em_cpu_energy()计算每个性能域在给定的利用率条件 下的预期能量消耗。 下面详细介绍一个优化能量消耗的任务放置决策的例子。 diff --git a/Documentation/translations/zh_CN/security/self-protection.rst b/Documentation/translations/zh_CN/security/self-protection.rst index 93de9cee5c1a..ad96bb4a4995 100644 --- a/Documentation/translations/zh_CN/security/self-protection.rst +++ b/Documentation/translations/zh_CN/security/self-protection.rst @@ -97,7 +97,7 @@ ARCH_OPTIONAL_KERNEL_RWX时的默认设置。 -------------------- 对于64位系统,一种消除许多系统调用最简单的方法是构建时不启用 -CONFIG_CONPAT。然而,这种情况通常不可行。 +CONFIG_COMPAT。然而,这种情况通常不可行。 “seccomp”系统为用户空间提供了一种可选功能,提供了一种减少可供 运行中进程使用内核入口点数量的方法。这限制了可以访问内核代码 diff --git a/Documentation/translations/zh_TW/process/stable-api-nonsense.rst b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst index 4b8597fed5ae..a21daf29da10 100644 --- a/Documentation/translations/zh_TW/process/stable-api-nonsense.rst +++ b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst @@ -14,21 +14,21 @@ 中文版校譯者: 李陽 Li Yang <leoyang.li@nxp.com> 胡皓文 Hu Haowen <2023002089@link.tyut.edu.cn> -Linux 內核驅動接口 +Linux 內核驅動介面 ================== -寫作本文檔的目的,是爲了解釋爲什麼Linux既沒有二進制內核接口,也沒有穩定 -的內核接口。這裏所說的內核接口,是指內核裏的接口,而不是內核和用戶空間 -的接口。內核到用戶空間的接口,是提供給應用程序使用的系統調用,系統調用 +寫作本文檔的目的,是爲了解釋爲什麼Linux既沒有二進制內核介面,也沒有穩定 +的內核介面。這裏所說的內核介面,是指內核裏的介面,而不是內核和用戶空間 +的介面。內核到用戶空間的介面,是提供給應用程序使用的系統調用,系統調用 在歷史上幾乎沒有過變化,將來也不會有變化。我有一些老應用程序是在0.9版本 或者更早版本的內核上編譯的,在使用2.6版本內核的Linux發佈上依然用得很好 -。用戶和應用程序作者可以將這個接口看成是穩定的。 +。用戶和應用程序作者可以將這個介面看成是穩定的。 執行綱要 -------- -你也許以爲自己想要穩定的內核接口,但是你不清楚你要的實際上不是它。你需 +你也許以爲自己想要穩定的內核介面,但是你不清楚你要的實際上不是它。你需 要的其實是穩定的驅動程序,而你只有將驅動程序放到公版內核的源代碼樹裏, 纔有可能達到這個目的。而且這樣做還有很多其它好處,正是因爲這些好處使得 Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選擇Linux的原因。 @@ -37,8 +37,8 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 入門 ----- -只有那些寫驅動程序的“怪人”纔會擔心內核接口的改變,對廣大用戶來說,既 -看不到內核接口,也不需要去關心它。 +只有那些寫驅動程序的“怪人”纔會擔心內核介面的改變,對廣大用戶來說,既 +看不到內核介面,也不需要去關心它。 首先,我不打算討論關於任何非GPL許可的內核驅動的法律問題,這些非GPL許可 的驅動程序包括不公開源代碼,隱藏源代碼,二進制或者是用源代碼包裝,或者 @@ -46,14 +46,14 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 詢律師,我只是一個程序員,所以我只打算探討技術問題(不是小看法律問題, 法律問題很實際,並且需要一直關注)。 -既然只談技術問題,我們就有了下面兩個主題:二進制內核接口和穩定的內核源 -代碼接口。這兩個問題是互相關聯的,讓我們先解決掉二進制接口的問題。 +既然只談技術問題,我們就有了下面兩個主題:二進制內核介面和穩定的內核源 +代碼介面。這兩個問題是互相關聯的,讓我們先解決掉二進制介面的問題。 -二進制內核接口 +二進制內核介面 -------------- -假如我們有一個穩定的內核源代碼接口,那麼自然而然的,我們就擁有了穩定的 -二進制接口,是這樣的嗎?錯。讓我們看看關於Linux內核的幾點事實: +假如我們有一個穩定的內核源代碼介面,那麼自然而然的,我們就擁有了穩定的 +二進制介面,是這樣的嗎?錯。讓我們看看關於Linux內核的幾點事實: - 取決於所用的C編譯器的版本,不同的內核數據結構裏的結構體的對齊方 式會有差別,代碼中不同函數的表現形式也不一樣(函數是不是被inline @@ -84,18 +84,18 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 深刻的教訓... -穩定的內核源代碼接口 +穩定的內核源代碼介面 -------------------- 如果有人不將他的內核驅動程序,放入公版內核的源代碼樹,而又想讓驅動程序 一直保持在最新的內核中可用,那麼這個話題將會變得沒完沒了。 -內核開發是持續而且快節奏的,從來都不會慢下來。內核開發人員在當前接口中 +內核開發是持續而且快節奏的,從來都不會慢下來。內核開發人員在當前介面中 找到bug,或者找到更好的實現方式。一旦發現這些,他們就很快會去修改當前的 -接口。修改接口意味着,函數名可能會改變,結構體可能被擴充或者刪減,函數 -的參數也可能發生改變。一旦接口被修改,內核中使用這些接口的地方需要同時 +介面。修改介面意味着,函數名可能會改變,結構體可能被擴充或者刪減,函數 +的參數也可能發生改變。一旦介面被修改,內核中使用這些介面的地方需要同時 修正,這樣才能保證所有的東西繼續工作。 -舉一個例子,內核的USB驅動程序接口在USB子系統的整個生命週期中,至少經歷 +舉一個例子,內核的USB驅動程序介面在USB子系統的整個生命週期中,至少經歷 了三次重寫。這些重寫解決以下問題: - 把數據流從同步模式改成非同步模式,這個改動減少了一些驅動程序的 @@ -105,22 +105,22 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 需要提供更多的參數給USB核心,以修正了很多已經被記錄在案的死鎖。 這和一些封閉源代碼的操作系統形成鮮明的對比,在那些操作系統上,不得不額 -外的維護舊的USB接口。這導致了一個可能性,新的開發者依然會不小心使用舊的 -接口,以不恰當的方式編寫代碼,進而影響到操作系統的穩定性。 +外的維護舊的USB介面。這導致了一個可能性,新的開發者依然會不小心使用舊的 +介面,以不恰當的方式編寫代碼,進而影響到操作系統的穩定性。 在上面的例子中,所有的開發者都同意這些重要的改動,在這樣的情況下修改代 -價很低。如果Linux保持一個穩定的內核源代碼接口,那麼就得創建一個新的接口 -;舊的,有問題的接口必須一直維護,給Linux USB開發者帶來額外的工作。既然 +價很低。如果Linux保持一個穩定的內核源代碼介面,那麼就得創建一個新的介面 +;舊的,有問題的介面必須一直維護,給Linux USB開發者帶來額外的工作。既然 所有的Linux USB驅動的作者都是利用自己的時間工作,那麼要求他們去做毫無意 義的免費額外工作,是不可能的。 安全問題對Linux來說十分重要。一個安全問題被發現,就會在短時間內得到修 -正。在很多情況下,這將導致Linux內核中的一些接口被重寫,以從根本上避免安 -全問題。一旦接口被重寫,所有使用這些接口的驅動程序,必須同時得到修正, +正。在很多情況下,這將導致Linux內核中的一些介面被重寫,以從根本上避免安 +全問題。一旦介面被重寫,所有使用這些介面的驅動程序,必須同時得到修正, 以確定安全問題已經得到修復並且不可能在未來還有同樣的安全問題。如果內核 -內部接口不允許改變,那麼就不可能修復這樣的安全問題,也不可能確認這樣的 +內部介面不允許改變,那麼就不可能修復這樣的安全問題,也不可能確認這樣的 安全問題以後不會發生。 -開發者一直在清理內核接口。如果一個接口沒有人在使用了,它就會被刪除。這 -樣可以確保內核儘可能的小,而且所有潛在的接口都會得到儘可能完整的測試 -(沒有人使用的接口是不可能得到良好的測試的)。 +開發者一直在清理內核介面。如果一個介面沒有人在使用了,它就會被刪除。這 +樣可以確保內核儘可能的小,而且所有潛在的介面都會得到儘可能完整的測試 +(沒有人使用的介面是不可能得到良好的測試的)。 要做什麼 @@ -128,11 +128,11 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 如果你寫了一個Linux內核驅動,但是它還不在Linux源代碼樹裏,作爲一個開發 者,你應該怎麼做?爲每個發佈的每個版本提供一個二進制驅動,那簡直是一個 -噩夢,要跟上永遠處於變化之中的內核接口,也是一件辛苦活。 +噩夢,要跟上永遠處於變化之中的內核介面,也是一件辛苦活。 很簡單,讓你的驅動進入內核源代碼樹(要記得我們在談論的是以GPL許可發行 的驅動,如果你的代碼不符合GPL,那麼祝你好運,你只能自己解決這個問題了, 你這個吸血鬼<把Andrew和Linus對吸血鬼的定義鏈接到這裏>)。當你的代碼加入 -公版內核源代碼樹之後,如果一個內核接口改變,你的驅動會直接被修改接口的 +公版內核源代碼樹之後,如果一個內核介面改變,你的驅動會直接被修改介面的 那個人修改。保證你的驅動永遠都可以編譯通過,並且一直工作,你幾乎不需要 做什麼事情。 @@ -142,7 +142,7 @@ Linux能成爲強壯,穩定,成熟的操作系統,這也是你最開始選 - 其他人會給驅動添加新特性。 - 其他人會找到驅動中的bug並修復。 - 其他人會在驅動中找到性能優化的機會。 - - 當外部的接口的改變需要修改驅動程序的時候,其他人會修改驅動程序 + - 當外部的介面的改變需要修改驅動程序的時候,其他人會修改驅動程序 - 不需要聯繫任何發行商,這個驅動會自動的隨着所有的Linux發佈一起發 布。 @@ -30,15 +30,15 @@ Who Are You? Find your role below: -* New Kernel Developer - Getting started with kernel development -* Academic Researcher - Studying kernel internals and architecture -* Security Expert - Hardening and vulnerability analysis -* Backport/Maintenance Engineer - Maintaining stable kernels -* System Administrator - Configuring and troubleshooting -* Maintainer - Leading subsystems and reviewing patches -* Hardware Vendor - Writing drivers for new hardware -* Distribution Maintainer - Packaging kernels for distros -* AI Coding Assistant - LLMs and AI-powered development tools +* New Kernel Developer: Getting started with kernel development +* Academic Researcher: Studying kernel internals and architecture +* Security Expert: Hardening and vulnerability analysis +* Backport/Maintenance Engineer: Maintaining stable kernels +* System Administrator: Configuring and troubleshooting +* Maintainer: Leading subsystems and reviewing patches +* Hardware Vendor: Writing drivers for new hardware +* Distribution Maintainer: Packaging kernels for distros +* AI Coding Assistant: LLMs and AI-powered development tools For Specific Users diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/kdoc_output.py index de107ab4a281..618b0d765ef5 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -624,7 +624,7 @@ class ManFormat(OutputFormat): ``manual`` Defaults to ``Kernel API Manual``. - The above controls the output of teh corresponding fields on troff + The above controls the output of the corresponding fields on troff title headers, which will be filled like this:: .TH "{name}" {section} "{date}" "{modulename}" "{manual}" diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/kdoc_parser.py index 2dedda215c22..884f42584667 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -11,6 +11,7 @@ and extract embedded documentation comments from it. import sys import re +import difflib from pprint import pformat from kdoc.c_lex import CTokenizer, tokenizer_set_log @@ -558,6 +559,50 @@ class KernelDoc: self.push_parameter(ln, decl_type, param, dtype, arg, declaration_name) + def get_suggestions_hint(self, decl_name, possible_names): + # For decl name 'flags' or 'flgas', suggests 'substruct.flags' + submember_exact = [] + submember_substrings = [] + submember_suggestions = [] + for possible_name in possible_names: + parts = possible_name.strip().split('.') + if len(parts) < 2: + continue + + final_part = parts[-1] + if decl_name == final_part: + submember_exact.append(possible_name) + elif decl_name in final_part: + submember_substrings.append(possible_name) + elif difflib.get_close_matches(decl_name, [final_part]): + submember_suggestions.append(possible_name) + + # For decl name 'flgas', suggests 'flags' + full_suggestions = difflib.get_close_matches(decl_name, possible_names) + + # For decl name 'member', suggests 'longer_member' + full_substrings = [name for name in possible_names if decl_name in name] + + ordered_lists = [ + submember_exact, + submember_substrings, + submember_suggestions, + full_suggestions, + full_substrings, + ] + + # Deduplicate but maintain order from most to least likely: + unique_suggestions = {} + for suggestion_list in ordered_lists: + for suggestion in suggestion_list: + unique_suggestions[suggestion] = None + + suggestions = list(unique_suggestions.keys()) + if not suggestions: + return "" + + return f"(did you mean one of: '{"', '".join(suggestions)}')" + def check_sections(self, ln, decl_name, decl_type): """ Check for errors inside sections, emitting warnings if not found @@ -566,12 +611,13 @@ class KernelDoc: for section in self.entry.sections: if section not in self.entry.parameterlist and \ not known_sections.search(section): + hint = self.get_suggestions_hint(section, self.entry.parameterlist) if decl_type == 'function': dname = f"{decl_type} parameter" else: dname = f"{decl_type} member" self.emit_msg(ln, - f"Excess {dname} '{section}' description in '{decl_name}'") + f"Excess {dname} '{section}' description in '{decl_name}' {hint}".strip()) # # Check that documented parameter names (from doc comments, including @@ -591,12 +637,13 @@ class KernelDoc: if param_name in self.entry.parameterlist: continue + hint = self.get_suggestions_hint(param_name, self.entry.parameterlist) if decl_type == 'function': dname = f"{decl_type} parameter" else: dname = f"{decl_type} member" self.emit_msg(ln, - f"Excess {dname} '{param_name}' description in '{decl_name}'") + f"Excess {dname} '{param_name}' description in '{decl_name}' {hint}".strip()) def check_return_section(self, ln, declaration_name, return_type): """ |
