mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 21:03:31 -04:00
Merge tag 'docs-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux
Pull documentation updates from Jonathan Corbet:
"It has been a not-too-busy cycle for docs; here's the highlights:
- A (hopefully) consensus change to our LLM-attribution requirements,
removing the specific model name from the Assisted-by tag
- A couple of new realtime documents
- Various docs-build-system fixes
- Ongoing work with the Chinese, Portuguese, and Japanese
translations
...and lots of typo fixes, grammar tweaks, etc"
* tag 'docs-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux: (85 commits)
Doc: admin-guide: pm: Remove unnecessary backticks and fix a spell
Documentation: Extend the real-time hardware bits with some firmware bits
docs: pt_BR: Reorganize process/index.rst to follow english structure
docs: conf.py: fix the 'utf-8' typo
doc tools: fix 'path' typos
Documentation: real-time: Add kernel configuration guide
docs: python: abi_regex: convert adjacent index placeholders
docs: python: abi_regex: catch the right exception for a bad regex
docs: sphinx-build-wrapper: include localversion in kernel version string
Documentation: html: adjust sidebar section titles styling
Documentation: html: show sections in the sidebar
checkpatch.pl: adapt to new Assisted-by: format
MAINTAINERS: update Traditional Chinese documentation maintainers
docs: pt_BR: process: Translate CVE documentation
docs: pt_BR: translate the management-style.rst to Brazilian Portuguese
docs: xforms_lists: support DEFINE_IDTENTRY_IRQ()
coding-assistants: simplify attribution
docs: translations: pt_BR: translate email-clients.rst
docs: pt_BR: process: Translate the security-bugs.rst
doc:it_IT: align doc-guide translation
...
This commit is contained in:
4
CREDITS
4
CREDITS
@@ -1821,6 +1821,10 @@ S: Am Strand 5
|
||||
S: D-19063 Schwerin
|
||||
S: Germany
|
||||
|
||||
N: Haowen Hu
|
||||
E: srcres258@furdevs.cn
|
||||
D: Traditional Chinese (zh_TW) documentation translation and maintenance
|
||||
|
||||
N: Jan Hubicka
|
||||
E: hubicka@freesoft.cz
|
||||
E: hubicka@suse.cz
|
||||
|
||||
@@ -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::
|
||||
|
||||
===
|
||||
|
||||
@@ -160,7 +160,7 @@ Description:
|
||||
in trace events, such as CXL DRAM and CXL general media
|
||||
error records of CXL memory devices.
|
||||
|
||||
When readng back these attributes, it returns the current
|
||||
When reading back these attributes, it returns the current
|
||||
value of memory requested to be repaired.
|
||||
|
||||
bank_group - The bank group of the memory to repair.
|
||||
|
||||
@@ -1618,10 +1618,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
|
||||
@@ -6446,9 +6453,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),
|
||||
@@ -6908,7 +6915,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.
|
||||
@@ -6949,7 +6956,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
|
||||
@@ -7039,17 +7046,6 @@ Kernel parameters
|
||||
take as long as they take. Specifying 300,000
|
||||
for this value provides a 5-minute timeout.
|
||||
|
||||
smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices
|
||||
smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port
|
||||
smsc-ircc2.ircc_sir= [HW] SIR base I/O port
|
||||
smsc-ircc2.ircc_fir= [HW] FIR base I/O port
|
||||
smsc-ircc2.ircc_irq= [HW] IRQ line
|
||||
smsc-ircc2.ircc_dma= [HW] DMA channel
|
||||
smsc-ircc2.ircc_transceiver= [HW] Transceiver type:
|
||||
0: Toshiba Satellite 1800 (GP data pin select)
|
||||
1: Fast pin select (default)
|
||||
2: ATC IRMode
|
||||
|
||||
smt= [KNL,MIPS,S390,EARLY] Set the maximum number of threads
|
||||
(logical CPUs) to use per physical CPU on systems
|
||||
capable of symmetric multithreading (SMT). Will
|
||||
|
||||
@@ -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
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -67,7 +67,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
|
||||
@@ -264,7 +264,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``.
|
||||
@@ -275,7 +275,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,
|
||||
@@ -288,7 +288,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 |
|
||||
|
||||
@@ -471,7 +471,7 @@ update the core ranking and set the cpu's priority.
|
||||
Kernel Parameters
|
||||
-----------------
|
||||
|
||||
``amd-pstate`` peferred core`` has two states: enable and disable.
|
||||
``amd-pstate`` preferred core has two states: enable and disable.
|
||||
Enable/disable states can be chosen by different kernel parameters.
|
||||
Default enable ``amd-pstate`` preferred core.
|
||||
|
||||
|
||||
@@ -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 "../".
|
||||
@@ -287,7 +287,7 @@ author = "The kernel development community"
|
||||
try:
|
||||
makefile_version = None
|
||||
makefile_patchlevel = None
|
||||
with open("../Makefile", encoding="utf=8") as fp:
|
||||
with open("../Makefile", encoding="utf-8") as fp:
|
||||
for line in fp:
|
||||
key, val = [x.strip() for x in line.split("=", 2)]
|
||||
if key == "VERSION":
|
||||
|
||||
11
Documentation/core-api/SMP.rst
Normal file
11
Documentation/core-api/SMP.rst
Normal file
@@ -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:
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -81,6 +81,7 @@ Documentation/locking/index.rst for more related documentation.
|
||||
padata
|
||||
../RCU/index
|
||||
wrappers/memory-barriers.rst
|
||||
SMP
|
||||
|
||||
Low-level hardware management
|
||||
=============================
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
=============
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -130,3 +130,107 @@ https://github.com/Linutronix/RTC-Testbench.
|
||||
The goal of this project is to validate real-time network communication. It can
|
||||
be thought of as a "cyclictest" for networking and also serves as a starting
|
||||
point for application development.
|
||||
|
||||
Firmware
|
||||
--------
|
||||
|
||||
The firmware often plays a significant role in system operation because it can
|
||||
perform tasks that the kernel cannot directly access, and in some cases it can
|
||||
even preempt or intercept the kernel.
|
||||
|
||||
A common example of firmware assisting the kernel is when it provides a generic
|
||||
interface to a resource. Instead of accessing an RTC chip through an I2C host
|
||||
controller, the kernel may query the firmware for the current time, and the
|
||||
firmware then accesses the RTC behind the scenes.
|
||||
|
||||
Firmware can also intercept kernel execution by providing services that
|
||||
temporarily take control of the system. One example is memory scrubbing, where
|
||||
the firmware periodically pauses the kernel, reads back portions of system
|
||||
memory, and then returns control. During this time, the kernel is effectively
|
||||
interrupted.
|
||||
In contrast, some systems provide hardware-based memory scrubbing, which
|
||||
operates independently of firmware or software. See
|
||||
Documentation/edac/scrub.rst for details.
|
||||
|
||||
If the kernel is intercepted for longer periods then these periods can be made
|
||||
visible with the hardware latency detector. See
|
||||
Documentation/trace/hwlat_detector.rst.
|
||||
|
||||
The kernel can also be intercepted in response to specific events, such as
|
||||
overheating. In this case, the firmware may throttle the CPU or shut it down
|
||||
immediately to prevent hardware damage.
|
||||
|
||||
Unless the firmware is well documented, it should be thoroughly tested to
|
||||
uncover any unexpected behaviour.
|
||||
|
||||
EFI
|
||||
~~~~
|
||||
|
||||
EFI provides runtime services that act as a communication interface between the
|
||||
firmware and the operating system. One such service is reading and writing EFI
|
||||
variables, which are used, for example, to determine the boot source.
|
||||
|
||||
Invoking a runtime service may require the architecture to disable kernel
|
||||
preemption or interrupts during the call. This means the duration of a service
|
||||
invocation directly affects the system’s observable latency. There is also
|
||||
nothing that prevents a service call from disabling interrupts internally while
|
||||
it runs.
|
||||
|
||||
For these reasons, EFI runtime services are disabled by default on a PREEMPT_RT
|
||||
kernel. They can still be enabled at boot time or via a Kconfig option if
|
||||
required.
|
||||
The native EFI runtime service implementation (where both the EFI service and
|
||||
the kernel are either 32-bit or 64-bit executables) uses a wrapper mechanism
|
||||
that invokes the service through a dedicated workqueue. This workqueue is named
|
||||
efi_runtime, and it can be restricted to a housekeeping CPU using the
|
||||
``/sys/devices/virtual/workqueue/efi_runtime/cpumask`` sysfs file. Assigning it
|
||||
to a housekeeping CPU ensures that potentially long service invocations do not
|
||||
impact the real-time workload which is restricted to other CPUs.
|
||||
|
||||
It must also be verified that the runtime services behave as expected. Some
|
||||
implementations on the x86 architecture pause all other CPUs while one CPU
|
||||
performs the service call. In such cases, the interruption affects all CPUs,
|
||||
and restricting the workqueue to a single CPU provides no benefit.
|
||||
|
||||
OP-TEE (ARM)
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Execution flows from the normal world (Linux) into the secure world (OP-TEE)
|
||||
through the secure monitor at EL3. The transition is initiated by the `smc`
|
||||
(Secure Monitor Call) opcode or the `hvc` (Hypervisor Call) opcode together
|
||||
with a function identifier. The calling convention defines two types of calls:
|
||||
**yielding calls** and **fast calls**:
|
||||
|
||||
- A **yielding call** unmasks interrupts before handling the requested service,
|
||||
allowing normal world interrupts to occur.
|
||||
- A **fast call** handles the requested service atomically, without allowing
|
||||
interrupts from either the normal world or the secure world.
|
||||
|
||||
In addition, the secure world (EL3 and OP-TEE) can receive interrupts routed to
|
||||
the secure world. While a secure world interrupt is being serviced,
|
||||
normal world interrupts are masked and cannot preempt the operation.
|
||||
|
||||
The transition from normal world to secure monitor to OP-TEE and back introduces
|
||||
additional latency due to world switching and context save/restore. This
|
||||
overhead is typically a few microseconds and usually remains within the noise
|
||||
floor.
|
||||
|
||||
It is worth noting that the normal world cannot mask secure interrupts, while
|
||||
the secure world can mask normal-world interrupts during execution. How OP-TEE
|
||||
affects real-time workloads depends on whether secure interrupts are enabled
|
||||
and which OP-TEE services are invoked.
|
||||
|
||||
A practical concern is any fast call that runs longer than expected, for
|
||||
example a function that occasionally performs a long-running cryptographic
|
||||
computation. Another example that may block in an unexpected way are OP-TEE
|
||||
drivers that issue RPC requests. An OP-TEE service in the secure world (RPMB
|
||||
for instance) may need to issue a request back to the normal world (the Linux
|
||||
driver) in order to complete the operation. While Linux remains preemptible,
|
||||
the thread that issued the request stays blocked until the RPC completes and
|
||||
the secure function call returns.
|
||||
|
||||
The TF-A project provides documentation on interrupt management:
|
||||
https://trustedfirmware-a.readthedocs.io/en/latest/design/interrupt-framework-design.html#interrupt-management-framework
|
||||
|
||||
The OP-TEE project provides documentation on how interrupts are handled:
|
||||
https://optee.readthedocs.io/en/latest/architecture/core.html#interrupt-handling
|
||||
|
||||
@@ -15,3 +15,4 @@ the required changes compared to a non-PREEMPT_RT configuration.
|
||||
differences
|
||||
hardware
|
||||
architecture-porting
|
||||
kernel-configuration
|
||||
|
||||
307
Documentation/core-api/real-time/kernel-configuration.rst
Normal file
307
Documentation/core-api/real-time/kernel-configuration.rst
Normal file
@@ -0,0 +1,307 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==============================
|
||||
Real-Time Kernel configuration
|
||||
==============================
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 3
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document lists the kernel configuration options that might affect a
|
||||
real-time kernel's worst-case latency. It is intended for system integrators.
|
||||
|
||||
Configuration options
|
||||
=====================
|
||||
|
||||
.. Please keep the configuration listings alphabetically ordered
|
||||
|
||||
CPU frequency governors
|
||||
-----------------------
|
||||
|
||||
``CONFIG_CPU_FREQ``
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: *high*
|
||||
|
||||
The CPU frequency scaling subsystem ensures that the processor can operate at
|
||||
its maximum supported frequency. While, in general, bootloaders are tasked
|
||||
with setting the CPU clock to the highest speed on boot, some do not. It is
|
||||
thus desirable to keep this option enabled.
|
||||
|
||||
.. caution::
|
||||
|
||||
A real-time kernel is not about being "as fast as possible", however
|
||||
real-time requirements may demand that the CPU is clocked at a particular
|
||||
speed.
|
||||
|
||||
``CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: *high*
|
||||
|
||||
Real-Time workloads expect a fixed CPU frequency during execution. Using the
|
||||
performance governor is an easy way to achieve that purely from kernel
|
||||
configuration.
|
||||
|
||||
This is not an absolute rule. Some setups might prefer to clock the CPU to
|
||||
lower speeds due to thermal packaging or other requirements. The key is that
|
||||
the CPU frequency remains constant once set.
|
||||
|
||||
Non-performance CPU frequency governors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *medium*
|
||||
|
||||
To ensure reproducible system latency measurements, disable the
|
||||
non-``PERFORMANCE`` CPU frequency governors whenever possible. This avoids
|
||||
the risk of unknown userspace tasks implicitly or explicitly setting a
|
||||
different CPU frequency governor, and thereby changing latency behavior while
|
||||
the system is running.
|
||||
|
||||
If disabling other frequency governors is not an option, use a governor that
|
||||
keeps the CPU frequency fixed. For example,
|
||||
``CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE`` can be enabled when userspace is
|
||||
responsible for setting a *stable* frequency during system initialization.
|
||||
|
||||
If a low CPU frequency is desired, then
|
||||
``CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE`` can be set.
|
||||
|
||||
The ``ONDEMAND`` governor should not be enabled on a real-time system. Its
|
||||
frequency changes depend on workload behavior and can significantly harm
|
||||
determinism.
|
||||
|
||||
For more information, see Documentation/admin-guide/pm/cpufreq.rst
|
||||
|
||||
``CONFIG_CPU_IDLE``
|
||||
-------------------
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: *info*
|
||||
|
||||
CPU idle states (C-states) allow the processor to enter low-power modes during
|
||||
periods of inactivity. Very-low CPU idle states may require flushing the CPU
|
||||
caches and lowering or disabling the clocking. This can lower power
|
||||
consumption, but it also increases the entry and exit latency from such
|
||||
states.
|
||||
|
||||
While disabling this option eliminates cpuidle-related latencies, doing so can
|
||||
significantly impact hardware longevity, warranty, and thermal behavior.
|
||||
Users should cap the maximum C-state to C1 instead. For ACPI platforms, this
|
||||
can be achieved by using the boot parameter [1]_::
|
||||
|
||||
processor.max_cstate=1
|
||||
|
||||
Higher C-states can be acceptable depending on the user workload's latency
|
||||
requirements. For ACPI-based platforms, use the ``cpupower idle-info``
|
||||
command to inspect the available idle states.
|
||||
|
||||
For more information, please see:
|
||||
|
||||
- ``linux/tools/power/cpupower``
|
||||
- Documentation/admin-guide/pm/cpuidle.rst
|
||||
- Documentation/admin-guide/pm/index.rst
|
||||
|
||||
``CONFIG_DRM``
|
||||
--------------
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *info*
|
||||
|
||||
GPU-accelerated workloads can share system resources with the CPU, including
|
||||
last-level cache (LLC) and memory bandwidth. Modern integrated GPUs optimize
|
||||
graphics performance at the expense of CPU determinism.
|
||||
|
||||
Examples of affected platforms:
|
||||
|
||||
- Intel processors with integrated graphics (Gen9 and later)
|
||||
- AMD APUs with Radeon Graphics
|
||||
- Xilinx Zynq UltraScale+ MPSoC EG/EV series
|
||||
|
||||
If graphics workloads must run alongside real-time tasks, users must conduct
|
||||
thorough stress testing using tools like ``glmark2`` while measuring the
|
||||
overall system latency.
|
||||
|
||||
For more information, please check:
|
||||
|
||||
- Documentation/core-api/real-time/hardware.rst ("Regarding hardware" section)
|
||||
- Documentation/filesystems/resctrl.rst
|
||||
- `Real-Time and Graphics: A Contradiction? <https://web.archive.org/web/20221025085614/https://linutronix.de/PDF/Realtime_and_graphics-acontradiction2021.pdf>`_
|
||||
|
||||
``CONFIG_EFI_DISABLE_RUNTIME``
|
||||
------------------------------
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: *medium*
|
||||
|
||||
EFI is the standard boot and firmware interface for multiple architectures.
|
||||
EFI runtime services provide callback functions to be called from the kernel;
|
||||
e.g., as utilized by (``CONFIG_EFI_VARS*``) or (``CONFIG_RTC_DRV_EFI``). For
|
||||
the former, the kernel calls into EFI to update the EFI variables.
|
||||
|
||||
Calling into EFI means invoking firmware callbacks. During such invocations,
|
||||
the system might not be able to react to interrupts and will thus not be able
|
||||
to perform a context switch. This can cause significant latency spikes for
|
||||
the real-time system.
|
||||
|
||||
``CONFIG_PREEMPT_RT`` enables this option by default. If this option is
|
||||
manually disabled at build time, the following boot parameter [1]_ may be used
|
||||
to disable EFI runtime at boot up::
|
||||
|
||||
efi=noruntime
|
||||
|
||||
Alternatively, confine EFI runtime service calls to a housekeeping CPU by
|
||||
restricting the ``efi_runtime`` workqueue CPU affinity. For example, set that
|
||||
workqueue's affinity to CPU #0 and pin your RT tasks to a different CPU range.
|
||||
See Documentation/core-api/workqueue.rst
|
||||
|
||||
``CONFIG_NO_HZ`` / ``CONFIG_NO_HZ_FULL``
|
||||
----------------------------------------
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *medium*
|
||||
|
||||
Tickless operation can increase kernel-to-userspace transition latency due to
|
||||
the extra accounting and state book-keeping.
|
||||
|
||||
*Guidance by real-time workload type:*
|
||||
|
||||
- For periodic workloads; e.g., control loops executing every 100 µs, avoid
|
||||
``NO_HZ`` modes. Consistent kernel ticks are preferable.
|
||||
|
||||
- For computation-intensive workloads; e.g. extended userspace execution,
|
||||
``NO_HZ_FULL`` may be beneficial. In such cases, users should offload the
|
||||
kernel housekeeping to dedicated CPUs and isolate compute cores.
|
||||
|
||||
See also Documentation/timers/no_hz.rst
|
||||
|
||||
``CONFIG_PREEMPT_RT``
|
||||
---------------------
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: **fatal**
|
||||
|
||||
This option must be enabled, or the resulting kernel will not be fully
|
||||
preemptible and real-time capable.
|
||||
|
||||
``CONFIG_TRACING`` (and tracing options)
|
||||
----------------------------------------
|
||||
|
||||
:Expectation: enabled
|
||||
:Severity: *info*
|
||||
|
||||
Shipping kernels with tracing support enabled (but not actively running) is
|
||||
highly recommended. This will allow the users to extract more information if
|
||||
latency problems arise. Nonetheless, some tracers do incur latency overhead
|
||||
just by being enabled.
|
||||
|
||||
.. caution::
|
||||
|
||||
Users should *not* make use of tracers or trace events during production
|
||||
real-time kernel operation as they can add considerable overhead and degrade
|
||||
the system's latency.
|
||||
|
||||
``CONFIG_IRQSOFF_TRACER`` and ``CONFIG_PREEMPT_TRACER``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *high*
|
||||
|
||||
These tracers do incur measurable latency overhead even when tracing is not
|
||||
currently active.
|
||||
|
||||
Kernel Debug Options
|
||||
====================
|
||||
|
||||
Most kernel debug options add runtime overhead that increases the worst-case
|
||||
latency.
|
||||
|
||||
.. caution::
|
||||
|
||||
During development and early testing, users are encouraged to run their
|
||||
real-time workloads and peripherals with lockdep (:ref:`lockdep`) and other
|
||||
kernel debug options enabled, for a considerable amount of time. Such
|
||||
workloads might trigger kernel code paths that were not triggered during the
|
||||
internal Linux real-time kernel development, thus helping to uncover locking
|
||||
and other types of kernel bugs.
|
||||
|
||||
``CONFIG_DEBUG_ATOMIC_SLEEP``
|
||||
-----------------------------
|
||||
|
||||
:Expectation: allowed
|
||||
|
||||
This sanity check catches common kernel programming errors with a tolerable
|
||||
latency cost. It also increases overall scheduling as each ``might_sleep()``
|
||||
can lead to a context switch.
|
||||
|
||||
``CONFIG_DEBUG_BUGVERBOSE`` and ``CONFIG_DEBUG_INFO*``
|
||||
------------------------------------------------------
|
||||
|
||||
:Expectation: allowed
|
||||
|
||||
These options increase the kernel image size but have no latency impact. They
|
||||
are also essential for meaningful BUG logs, crash dumps, and profiling.
|
||||
|
||||
``CONFIG_DEBUG_FS``
|
||||
-------------------
|
||||
|
||||
:Expectation: allowed
|
||||
|
||||
This is safe to include in real-time kernels, *provided that debugfs is not
|
||||
accessed during production runtime*.
|
||||
|
||||
``CONFIG_DEBUG_KERNEL``
|
||||
-----------------------
|
||||
|
||||
:Expectation: allowed
|
||||
|
||||
Meta-option which allows debug features to be enabled. It has no runtime
|
||||
impact, but beware of any debug features that it may have implicitly enabled.
|
||||
|
||||
``CONFIG_LOCKUP_DETECTOR``
|
||||
--------------------------
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *high*
|
||||
|
||||
The lockup detector creates kernel timer callbacks that execute every few
|
||||
seconds, in hard-IRQ context, even on real-time kernels. These periodic
|
||||
interrupts can cause latency spikes.
|
||||
|
||||
Users should use hardware watchdogs instead, which will provide a similar
|
||||
functionality without the software-induced latency.
|
||||
|
||||
.. _lockdep:
|
||||
|
||||
``CONFIG_PROVE_LOCKING``
|
||||
------------------------
|
||||
|
||||
:Expectation: disabled
|
||||
:Severity: *high*
|
||||
|
||||
Proving the correctness of all kernel locking adds substantial overhead and
|
||||
significantly increases worst-case latency.
|
||||
|
||||
Summary
|
||||
=======
|
||||
|
||||
There is no "one size fits all" solution for configuring a real-time Linux
|
||||
system. Beginning with the system real-time requirements, integrators must
|
||||
consider the features and functions of the system's hardware, kernel, and
|
||||
userspace. All such components must be properly configured in order to
|
||||
establish and constrain the system's maximum latency.
|
||||
|
||||
With that in mind, any incorrect real-time kernel configuration could cause a
|
||||
new maximum latency that shows up at the wrong time and is catastrophic for
|
||||
the real-time system's latency.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] See Documentation/admin-guide/kernel-parameters.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.
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ Creating the User
|
||||
To use the message handler, you must first create a user using
|
||||
ipmi_create_user. The interface number specifies which SMI you want
|
||||
to connect to, and you must supply callback functions to be called
|
||||
when data comes in. This also allows to you pass in a piece of data,
|
||||
when data comes in. This also allows you to pass in a piece of data,
|
||||
the handler_data, that will be passed back to you on all calls.
|
||||
|
||||
Once you are done, call ipmi_destroy_user() to get rid of the user.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -21,6 +21,7 @@ community and getting your work upstream.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Working with the development community
|
||||
|
||||
Development process <process/development-process>
|
||||
Submitting patches <process/submitting-patches>
|
||||
@@ -37,6 +38,7 @@ kernel.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Internal API manuals
|
||||
|
||||
Core API <core-api/index>
|
||||
Driver APIs <driver-api/index>
|
||||
@@ -50,6 +52,7 @@ Various other manuals with useful information for all kernel developers.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Development tools and processes
|
||||
|
||||
Licensing rules <process/license-rules>
|
||||
Writing documentation <doc-guide/index>
|
||||
@@ -71,6 +74,7 @@ developers seeking information on the kernel's user-space APIs.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: User-oriented documentation
|
||||
|
||||
Administration <admin-guide/index>
|
||||
Build system <kbuild/index>
|
||||
@@ -88,6 +92,7 @@ platform firmware.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Firmware-related documentation
|
||||
|
||||
Firmware <firmware-guide/index>
|
||||
Firmware and Devicetree <devicetree/index>
|
||||
@@ -98,6 +103,7 @@ Architecture-specific documentation
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Architecture-specific documentation
|
||||
|
||||
CPU architectures <arch/index>
|
||||
|
||||
@@ -111,6 +117,7 @@ to reStructuredText format, or are simply too old.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Other documentation
|
||||
|
||||
Unsorted documentation <staging/index>
|
||||
|
||||
@@ -120,6 +127,7 @@ Translations
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Translations
|
||||
|
||||
Translations <translations/index>
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
================================
|
||||
|
||||
@@ -43,12 +47,8 @@ When AI tools contribute to kernel development, proper attribution
|
||||
helps track the evolving role of AI in the development process.
|
||||
Contributions should include an Assisted-by tag in the following format::
|
||||
|
||||
Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]
|
||||
Assisted-by: LLM [TOOL1] [TOOL2]
|
||||
|
||||
Where:
|
||||
|
||||
* ``AGENT_NAME`` is the name of the AI tool or framework
|
||||
* ``MODEL_VERSION`` is the specific model version used
|
||||
* ``[TOOL1] [TOOL2]`` are optional specialized analysis tools used
|
||||
(e.g., coccinelle, sparse, smatch, clang-tidy)
|
||||
|
||||
@@ -56,7 +56,7 @@ Basic development tools (git, gcc, make, editors) should not be listed.
|
||||
|
||||
Example::
|
||||
|
||||
Assisted-by: Claude:claude-3-opus coccinelle sparse
|
||||
Assisted-by: LLM coccinelle sparse
|
||||
|
||||
Procedure for finding and fixing bugs
|
||||
=====================================
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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%; }
|
||||
@@ -75,6 +77,19 @@ div.kerneltoc li.current ul { margin-left: 0; }
|
||||
div.kerneltoc { background-color: #eeeeee; }
|
||||
div.kerneltoc li.current ul { background-color: white; }
|
||||
|
||||
/*
|
||||
* Hide toctree captions on the welcome page, they should only be shown in the
|
||||
* sidebar.
|
||||
*/
|
||||
section#the-linux-kernel-documentation p.caption { display: none; }
|
||||
|
||||
/*
|
||||
* Make section titles bold in the sidebar, and decrease their bottom margin to
|
||||
* group them with their subsections.
|
||||
*/
|
||||
div.sphinxsidebar p.caption { font-weight: bold; margin-bottom: 0; }
|
||||
div.sphinxsidebar p.caption + ul { margin-top: 0; }
|
||||
|
||||
/*
|
||||
* The CSS magic to toggle the contents on small screens.
|
||||
*/
|
||||
@@ -156,15 +171,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
Verificare la necessità di aggiornare le traduzioni
|
||||
===================================================
|
||||
|
||||
Questo script aiuta a tracciare lo stato delle traduzioni della
|
||||
documentazione nelle diverse lingue, ovvero se la documentazione è
|
||||
allineata con la controparte inglese.
|
||||
|
||||
Come funziona
|
||||
-------------
|
||||
|
||||
Lo script usa il comando ``git log`` per individuare l'ultimo commit in inglese
|
||||
a partire dal commit della traduzione (in ordine di data dell'autore) e gli
|
||||
ultimi commit in inglese a partire da HEAD. Se emergono delle differenze, il
|
||||
file viene considerato non aggiornato, e vengono quindi raccolti e segnalati i
|
||||
commit che necessitano di un aggiornamento.
|
||||
|
||||
Funzionalità implementate
|
||||
|
||||
- verifica di tutti i file in una determinata lingua
|
||||
- verifica di un singolo file o di un insieme di file
|
||||
- opzioni per modificare il formato dell'output
|
||||
- tracciamento dello stato di traduzione dei file che non hanno alcuna
|
||||
traduzione
|
||||
|
||||
Utilizzo
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
tools/docs/checktransupdate.py --help
|
||||
|
||||
Fate riferimento all'output del messaggio d'aiuto per i dettagli sull'utilizzo.
|
||||
|
||||
Esempi
|
||||
|
||||
- ``tools/docs/checktransupdate.py -l zh_CN``
|
||||
Questo stamperà tutti i file che necessitano di un aggiornamento nella
|
||||
lingua zh_CN.
|
||||
- ``tools/docs/checktransupdate.py Documentation/translations/zh_CN/dev-tools/testing-overview.rst``
|
||||
Questo stamperà solamente lo stato del file specificato.
|
||||
|
||||
L'output sarà quindi qualcosa del genere:
|
||||
|
||||
::
|
||||
|
||||
Documentation/dev-tools/kfence.rst
|
||||
No translation in the locale of zh_CN
|
||||
|
||||
Documentation/translations/zh_CN/dev-tools/testing-overview.rst
|
||||
commit 42fb9cfd5b18 ("Documentation: dev-tools: Add link to RV docs")
|
||||
1 commits needs resolving in total
|
||||
|
||||
Funzionalità ancora da implementare
|
||||
|
||||
- specificare cartelle in aggiunta ai singoli file
|
||||
319
Documentation/translations/it_IT/doc-guide/contributing.rst
Normal file
319
Documentation/translations/it_IT/doc-guide/contributing.rst
Normal file
@@ -0,0 +1,319 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
Come contribuire al miglioramento della documentazione del kernel
|
||||
=================================================================
|
||||
|
||||
La documentazione è una parte importante di ogni progetto di sviluppo
|
||||
software. Una buona documentazione aiuta ad attirare nuovi sviluppatori e
|
||||
permette a quelli già presenti di lavorare in modo più efficace. Senza una
|
||||
documentazione di qualità, si spreca molto tempo nel decifrare il codice a
|
||||
ritroso e si commettono errori altrimenti evitabili.
|
||||
|
||||
Sfortunatamente, al momento la documentazione del kernel è ben lontana da
|
||||
quello che dovrebbe essere per sostenere un progetto di queste dimensioni e
|
||||
importanza.
|
||||
|
||||
Questa guida è per chi vuole contribuire a migliorare questa situazione. I
|
||||
miglioramenti alla documentazione del kernel possono essere fatti da
|
||||
sviluppatori con diversi livelli di esperienza; sono un modo relativamente
|
||||
semplice per imparare il processo di sviluppo del kernel in generale e
|
||||
trovare il proprio posto nella comunità. Quello che segue è, per la maggior
|
||||
parte, l'elenco dei compiti che il manutentore della documentazione ritiene
|
||||
più urgenti.
|
||||
|
||||
Le cose da fare nella documentazione
|
||||
------------------------------------
|
||||
|
||||
C'è un elenco infinito di compiti da svolgere per portare la nostra
|
||||
documentazione al livello in cui dovrebbe essere. Questo elenco contiene
|
||||
alcuni punti importanti, ma è lungi dall'essere esaustivo; se trovate un
|
||||
modo diverso per migliorare la documentazione, non esitate!
|
||||
|
||||
Correzione degli avvisi
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Al momento, la generazione della documentazione produce un numero
|
||||
incredibile di avvisi. Quando ce ne sono così tanti, è come se non ce ne
|
||||
fosse nessuno: le persone li ignorano e non si accorgeranno mai quando il
|
||||
loro lavoro ne aggiunge di nuovi. Per questo motivo, eliminare gli avvisi è
|
||||
uno dei compiti a più alta priorità nell'elenco delle cose da fare per la
|
||||
documentazione. Il compito in sé è ragionevolmente semplice, ma va
|
||||
affrontato nel modo giusto per avere successo.
|
||||
|
||||
Gli avvisi emessi da un compilatore per il codice C possono spesso essere
|
||||
scartati come falsi positivi, portando a patch il cui unico scopo è zittire
|
||||
il compilatore. Gli avvisi generati dalla documentazione, invece, indicano
|
||||
quasi sempre un problema reale; farli sparire richiede di comprendere il
|
||||
problema e correggerlo alla radice. Per questo motivo, le patch che
|
||||
correggono avvisi nella documentazione non dovrebbero limitarsi a dire "fix
|
||||
a warning" nel titolo del changelog; dovrebbero invece indicare il problema
|
||||
reale che è stato corretto.
|
||||
|
||||
Un altro punto importante è che gli avvisi nella documentazione sono spesso
|
||||
generati da problemi nei commenti kerneldoc all'interno del codice C. Anche se
|
||||
il manutentore della documentazione apprezza l'essere messo in copia sulle
|
||||
correzioni di questo tipo, in realtà spesso rivolgersi al sottosistema di
|
||||
documentazione non è il modo migliore di apportare queste modifiche; queste
|
||||
dovrebbero invece essere inviate al manutentore del sottosistema in questione.
|
||||
|
||||
Per esempio, in una generazione della documentazione ho preso, quasi a
|
||||
caso, un paio di avvisi::
|
||||
|
||||
./drivers/devfreq/devfreq.c:1818: warning: bad line:
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
./drivers/devfreq/devfreq.c:1854: warning: bad line:
|
||||
- Resource-managed devfreq_unregister_notifier()
|
||||
|
||||
(Le righe sono state divise per essere più leggibili).
|
||||
|
||||
Una rapida occhiata al file sorgente indicato sopra ha rivelato un paio di
|
||||
commenti kerneldoc con questo aspetto::
|
||||
|
||||
/**
|
||||
* devm_devfreq_register_notifier()
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
* @list: DEVFREQ_TRANSITION_NOTIFIER.
|
||||
*/
|
||||
|
||||
Il problema è l'asterisco mancante, che confonde l'idea semplicistica che il
|
||||
sistema di generazione abbia idea di come debba essere fatto un blocco di
|
||||
commento C. Questo problema era presente fin da quando quel commento venne
|
||||
aggiunto nel 2016, quindi da diversi anni. Correggerlo è stata solo questione di
|
||||
aggiungere gli asterischi mancanti. Una rapida occhiata alla cronologia di quel
|
||||
file ha mostrato quale fosse il formato usuale per la riga dell'oggetto, e
|
||||
``scripts/get_maintainer.pl`` mi ha detto chi dovesse riceverla (basta passare
|
||||
il percorso delle vostre patch come argomento a scripts/get_maintainer.pl). La
|
||||
patch risultante era questa::
|
||||
|
||||
[PATCH] PM / devfreq: Fix two malformed kerneldoc comments
|
||||
|
||||
Two kerneldoc comments in devfreq.c fail to adhere to the required format,
|
||||
resulting in these doc-build warnings:
|
||||
|
||||
./drivers/devfreq/devfreq.c:1818: warning: bad line:
|
||||
- Resource-managed devfreq_register_notifier()
|
||||
./drivers/devfreq/devfreq.c:1854: warning: bad line:
|
||||
- Resource-managed devfreq_unregister_notifier()
|
||||
|
||||
Add a couple of missing asterisks and make kerneldoc a little happier.
|
||||
|
||||
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
|
||||
---
|
||||
drivers/devfreq/devfreq.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
|
||||
index 57f6944d65a6..00c9b80b3d33 100644
|
||||
--- a/drivers/devfreq/devfreq.c
|
||||
+++ b/drivers/devfreq/devfreq.c
|
||||
@@ -1814,7 +1814,7 @@ static void devm_devfreq_notifier_release(struct device *dev, void *res)
|
||||
|
||||
/**
|
||||
* devm_devfreq_register_notifier()
|
||||
- - Resource-managed devfreq_register_notifier()
|
||||
+ * - Resource-managed devfreq_register_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
@@ -1850,7 +1850,7 @@ EXPORT_SYMBOL(devm_devfreq_register_notifier);
|
||||
|
||||
/**
|
||||
* devm_devfreq_unregister_notifier()
|
||||
- - Resource-managed devfreq_unregister_notifier()
|
||||
+ * - Resource-managed devfreq_unregister_notifier()
|
||||
* @dev: The devfreq user device. (parent of devfreq)
|
||||
* @devfreq: The devfreq object.
|
||||
* @nb: The notifier block to be unregistered.
|
||||
--
|
||||
2.24.1
|
||||
|
||||
L'intero procedimento ha richiesto solo pochi minuti. Naturalmente, ho poi
|
||||
scoperto che qualcun altro l'aveva già corretto in un altro albero,
|
||||
mettendo in luce un'altra lezione: controllate sempre linux-next per
|
||||
vedere se un problema è già stato risolto prima di mettervici sopra.
|
||||
|
||||
Altre correzioni richiederanno più tempo, specialmente quelle relative ai
|
||||
campi di una struttura o ai parametri di una funzione privi di
|
||||
documentazione. In questi casi, è necessario capire quale sia il ruolo di
|
||||
questi campi o parametri e descriverli correttamente. Nel complesso, questo
|
||||
compito diventa un po' tedioso a volte, ma è molto importante. Se riusciamo
|
||||
davvero ad eliminare gli avvisi dalla generazione della documentazione,
|
||||
allora potremo iniziare a pretendere che gli sviluppatori evitino di
|
||||
aggiungerne di nuovi.
|
||||
|
||||
Oltre ai normali avvisi durante la generazione della documentazione, potete
|
||||
ottenerne di più eseguendo ``make refcheckdocs`` per trovare riferimenti a file
|
||||
di documentazione inesistenti.
|
||||
|
||||
Commenti kerneldoc dimenticati
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gli sviluppatori sono incoraggiati a scrivere commenti kerneldoc per il
|
||||
loro codice, ma molti di questi commenti non vengono mai inclusi nella
|
||||
generazione della documentazione. Questo rende tale informazione più
|
||||
difficile da trovare e, per esempio, impedisce a Sphinx di generare
|
||||
collegamenti verso quella documentazione. Aggiungere le direttive
|
||||
``kernel-doc`` alla documentazione per includere quei commenti può aiutare
|
||||
la comunità a ottenere il pieno valore del lavoro speso per crearli.
|
||||
|
||||
Lo strumento ``tools/docs/find-unused-docs.sh`` può essere usato per
|
||||
trovare questi commenti dimenticati.
|
||||
|
||||
Da notare che il valore maggiore deriva dall'includere la documentazione
|
||||
per le funzioni e le strutture dati esportate. Molti sottosistemi hanno
|
||||
anche commenti kerneldoc per uso interno; questi non dovrebbero essere
|
||||
inclusi nella generazione della documentazione a meno che non vengano
|
||||
posti in un documento specificamente rivolto agli sviluppatori che
|
||||
lavorano all'interno del sottosistema in questione.
|
||||
|
||||
|
||||
Correzione dei refusi
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Correggere errori di battitura o di formattazione nella documentazione è
|
||||
un modo rapido per imparare come creare e inviare patch, ed è un servizio
|
||||
utile. Sono sempre disposto ad accettare questo tipo di patch. Detto
|
||||
questo, una volta che ne avete corretti alcuni, considerate di passare a
|
||||
compiti più avanzati, lasciando qualche refuso per il prossimo principiante
|
||||
che vorrà occuparsene.
|
||||
|
||||
Da notare che alcune cose *non* sono refusi e non dovrebbero essere
|
||||
"corrette":
|
||||
|
||||
- Sia la grafia americana che quella britannica dell'inglese sono
|
||||
ammesse nella documentazione del kernel. Non c'è bisogno di sostituire
|
||||
l'una con l'altra.
|
||||
|
||||
- La questione se un punto debba essere seguito da uno o due spazi non
|
||||
va dibattuta nel contesto della documentazione del kernel. Anche
|
||||
altri argomenti di legittimo disaccordo, come la "virgola di Oxford",
|
||||
non sono pertinenti qui.
|
||||
|
||||
Come per qualsiasi patch a qualsiasi progetto, considerate se la vostra
|
||||
modifica sta davvero migliorando le cose.
|
||||
|
||||
Documentazione datata
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Parte della documentazione del kernel è attuale, mantenuta e utile.
|
||||
Un'altra parte... non lo è. Documentazione impolverata, vecchia e
|
||||
imprecisa può fuorviare i lettori e gettare discredito sulla nostra
|
||||
documentazione nel suo complesso. Qualsiasi cosa si possa fare per
|
||||
affrontare questi problemi è più che benvenuta.
|
||||
|
||||
Ogni volta che lavorate su un documento, considerate se è attuale, se ha
|
||||
bisogno di essere aggiornato, o se forse dovrebbe essere rimosso del
|
||||
tutto. Ci sono alcuni segnali d'allarme a cui potete prestare attenzione:
|
||||
|
||||
- Riferimenti a kernel della serie 2.x
|
||||
- Rimandi a repositori su SourceForge
|
||||
- Nella cronologia, negli ultimi anni, solo correzioni di refusi
|
||||
- Discussioni su modi di lavorare precedenti a Git
|
||||
|
||||
La cosa migliore da fare, ovviamente, sarebbe portare la documentazione a
|
||||
essere attuale, aggiungendo qualsiasi informazione necessaria. Un lavoro
|
||||
simile spesso richiede la collaborazione di sviluppatori che conoscono bene
|
||||
il sottosistema in questione. Gli sviluppatori, quando viene chiesto loro
|
||||
gentilmente, e quando le loro risposte vengono ascoltate e messe in
|
||||
pratica, sono spesso più che disposti a collaborare con chi lavora per
|
||||
migliorare la documentazione.
|
||||
|
||||
Alcuni documenti sono senza speranza; a volte troviamo documenti che fanno
|
||||
riferimento a codice rimosso dal kernel molto tempo fa, per esempio. C'è
|
||||
una sorprendente resistenza a rimuovere la documentazione obsoleta, ma
|
||||
dovremmo farlo comunque. Il materiale superfluo nella nostra documentazione
|
||||
non è d'aiuto a nessuno.
|
||||
|
||||
Nei casi in cui, forse, ci sono informazioni utili in un documento
|
||||
gravemente datato, e non siete in grado di aggiornarlo, la cosa migliore
|
||||
da fare potrebbe essere aggiungere un avviso all'inizio. Si raccomanda il
|
||||
seguente testo::
|
||||
|
||||
.. warning ::
|
||||
This document is outdated and in need of attention. Please use
|
||||
this information with caution, and please consider sending patches
|
||||
to update it.
|
||||
|
||||
In questo modo, almeno i nostri pazientissimi lettori sono stati avvisati
|
||||
che il documento potrebbe portarli fuori strada.
|
||||
|
||||
Coerenza della documentazione
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
I veterani di qui ricorderanno i libri su Linux che comparvero sugli
|
||||
scaffali negli anni '90. Erano semplicemente raccolte di file di
|
||||
documentazione racimolati da varie fonti in rete. I libri sono (per lo
|
||||
più) migliorati da allora, ma la documentazione del kernel è ancora per lo
|
||||
più costruita su quel modello. Sono migliaia di file, quasi ognuno dei
|
||||
quali è stato scritto in isolamento da tutti gli altri. Non abbiamo un
|
||||
corpo coerente di documentazione del kernel; abbiamo migliaia di documenti
|
||||
individuali.
|
||||
|
||||
Abbiamo cercato di migliorare la situazione creando un insieme di "libri"
|
||||
che raggruppano la documentazione per specifici lettori. Questi
|
||||
includono:
|
||||
|
||||
- Documentation/admin-guide/index.rst
|
||||
- Documentation/core-api/index.rst
|
||||
- Documentation/driver-api/index.rst
|
||||
- Documentation/userspace-api/index.rst
|
||||
|
||||
Così come questo libro sulla documentazione stessa.
|
||||
|
||||
Spostare i documenti nei libri appropriati è un compito importante e deve
|
||||
continuare. Ci sono, tuttavia, un paio di sfide associate a questo lavoro.
|
||||
Spostare i file della documentazione, nel breve termine, infastidisce chi vi
|
||||
lavora; comprensibilmente, non sono entusiasti di questi cambiamenti. Di solito
|
||||
li si può convincere a spostarli una volta; tuttavia, non vogliamo continuare a
|
||||
spostarli in giro.
|
||||
|
||||
Anche quando tutti i documenti sono al posto giusto, però, siamo solo
|
||||
riusciti a trasformare un grande cumulo in un gruppo di cumuli più
|
||||
piccoli. Il lavoro di cercare di tessere insieme tutti quei documenti in
|
||||
un unico insieme non è ancora iniziato. Se avete idee brillanti su come
|
||||
potremmo procedere su questo fronte, saremmo più che felici di sentirle.
|
||||
|
||||
Miglioramenti al foglio di stile
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Con l'adozione di Sphinx abbiamo un output HTML dall'aspetto molto più gradevole
|
||||
di quanto avessimo un tempo. Ma è ancora migliorabile; Donald Knuth e Edward
|
||||
Tufte non ne sarebbero impressionati. Questo richiede di modificare i nostri
|
||||
fogli di stile per creare un output tipograficamente più solido, accessibile e
|
||||
leggibile.
|
||||
|
||||
Attenzione: se vi assumete questo compito, vi state addentrando nel
|
||||
classico territorio del "bikeshed". Aspettatevi molte opinioni e
|
||||
discussioni anche per cambiamenti relativamente ovvi. Questa è, ahimè, la
|
||||
natura del mondo in cui viviamo.
|
||||
|
||||
Generazione di PDF senza LaTeX
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Questo è un compito decisamente non banale per qualcuno con molto tempo a
|
||||
disposizione e competenze in Python. La catena di strumenti di Sphinx è
|
||||
relativamente piccola e ben contenuta; è facile da aggiungere a un sistema
|
||||
di sviluppo. Ma generare output in PDF o EPUB richiede l'installazione di
|
||||
LaTeX, che non è affatto piccolo o ben contenuto. Sarebbe una bella cosa
|
||||
da eliminare.
|
||||
|
||||
La speranza originale era di usare lo strumento rst2pdf (https://rst2pdf.org/)
|
||||
per la generazione dei PDF, ma si è scoperto che non era all'altezza del
|
||||
compito. Il lavoro di sviluppo su rst2pdf sembra però essere ripreso di recente,
|
||||
il che è un segno di speranza. Se uno sviluppatore adeguatamente motivato lo
|
||||
migliorasse per far funzionare rst2pdf con la documentazione del kernel, il
|
||||
mondo gli sarebbe eternamente grato.
|
||||
|
||||
Scrivere più documentazione
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Naturalmente, ci sono vaste parti del kernel che sono gravemente prive di
|
||||
documentazione. Se avete la conoscenza per documentare uno specifico
|
||||
sottosistema del kernel e il desiderio di farlo, non esitate a scrivere e
|
||||
inviare il lavoro al kernel. Un numero incalcolabile di
|
||||
sviluppatori e utenti del kernel vi ringrazierà.
|
||||
@@ -1,8 +1,5 @@
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
.. note:: Per leggere la documentazione originale in inglese:
|
||||
:ref:`Documentation/doc-guide/index.rst <doc_guide>`
|
||||
|
||||
.. _it_doc_guide:
|
||||
|
||||
==========================================
|
||||
@@ -15,10 +12,6 @@ Come scrivere la documentazione del kernel
|
||||
sphinx
|
||||
kernel-doc
|
||||
parse-headers
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
contributing
|
||||
maintainer-profile
|
||||
checktransupdate
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
.. note:: Per leggere la documentazione originale in inglese:
|
||||
:ref:`Documentation/doc-guide/index.rst <doc_guide>`
|
||||
|
||||
.. title:: Commenti in kernel-doc
|
||||
|
||||
.. _it_kernel_doc:
|
||||
|
||||
=================================
|
||||
Scrivere i commenti in kernel-doc
|
||||
=================================
|
||||
@@ -82,11 +77,15 @@ che questo produca alcuna documentazione. Per esempio::
|
||||
|
||||
tools/docs/kernel-doc -v -none drivers/foo/bar.c
|
||||
|
||||
Il formato della documentazione è verificato della procedura di generazione
|
||||
del kernel quando viene richiesto di effettuare dei controlli extra con GCC::
|
||||
Il formato della documentazione dei file ``.c`` è verificato anche dalla
|
||||
procedura di generazione del kernel quando viene richiesto di effettuare dei
|
||||
controlli extra con GCC::
|
||||
|
||||
make W=n
|
||||
|
||||
Tuttavia, il comando precedente non verifica i file d'intestazione. Questi
|
||||
devono essere controllati separatamente utilizzando ``kernel-doc``.
|
||||
|
||||
Documentare le funzioni
|
||||
------------------------
|
||||
|
||||
@@ -172,7 +171,7 @@ Valore di ritorno
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome
|
||||
``Return``.
|
||||
``Return`` (o ``Returns``).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -202,7 +201,8 @@ Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome
|
||||
Documentare strutture, unioni ed enumerazioni
|
||||
---------------------------------------------
|
||||
|
||||
Generalmente il formato di un commento kernel-doc per struct, union ed enum è::
|
||||
Generalmente il formato di un commento kernel-doc per ``struct``, ``union``
|
||||
ed ``enum`` è::
|
||||
|
||||
/**
|
||||
* struct struct_name - Brief description.
|
||||
@@ -237,6 +237,10 @@ Le etichette ``private:`` e ``public:`` devono essere messe subito dopo
|
||||
il marcatore di un commento ``/*``. Opzionalmente, possono includere commenti
|
||||
fra ``:`` e il marcatore di fine commento ``*/``.
|
||||
|
||||
Quando ``private:`` viene usata su strutture annidate, si propaga solo alle
|
||||
strutture/unioni interne.
|
||||
|
||||
|
||||
Esempio::
|
||||
|
||||
/**
|
||||
@@ -280,13 +284,15 @@ Strutture ed unioni annidate
|
||||
union {
|
||||
struct {
|
||||
int memb1;
|
||||
/* private: nasconde memb2 dalla documentazione */
|
||||
int memb2;
|
||||
}
|
||||
};
|
||||
/* Qui torna tutto pubblico, l'ambito private è terminato */
|
||||
struct {
|
||||
void *memb3;
|
||||
int memb4;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
int memb1;
|
||||
@@ -366,10 +372,23 @@ Anche i tipi di dato per prototipi di funzione possono essere documentati::
|
||||
* Description of the type.
|
||||
*
|
||||
* Context: Locking context.
|
||||
* Return: Meaning of the return value.
|
||||
* Returns: Meaning of the return value.
|
||||
*/
|
||||
typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2);
|
||||
|
||||
Documentazione delle variabili
|
||||
-------------------------------
|
||||
|
||||
Generalmente il formato di un commento kernel-doc per una variabile è
|
||||
il seguente::
|
||||
|
||||
/**
|
||||
* var var_name - Brief description.
|
||||
*
|
||||
* Description of the var_name variable.
|
||||
*/
|
||||
extern int var_name;
|
||||
|
||||
Documentazione di macro simili a oggetti
|
||||
----------------------------------------
|
||||
|
||||
@@ -433,6 +452,10 @@ del `dominio Sphinx per il C`_.
|
||||
``%CONST``
|
||||
Il nome di una costante (nessun riferimento, solo formattazione)
|
||||
|
||||
Esempi::
|
||||
|
||||
%0 %NULL %-1 %-EFAULT %-EINVAL %-ENOMEM
|
||||
|
||||
````literal````
|
||||
Un blocco di testo che deve essere riportato così com'è. La rappresentazione
|
||||
finale utilizzerà caratteri a ``spaziatura fissa``.
|
||||
@@ -484,15 +507,22 @@ la seguente sintassi::
|
||||
See :c:func:`my custom link text for function foo <foo>`.
|
||||
See :c:type:`my custom link text for struct bar <bar>`.
|
||||
|
||||
Per ulteriori dettagli, consultate la documentazione del `dominio Sphinx per
|
||||
il C`_.
|
||||
|
||||
.. note::
|
||||
Le variabili non vengono automaticamente collegate tramite riferimenti
|
||||
incrociati. Per queste, dovete aggiungere esplicitamente un riferimento
|
||||
incrociato del dominio C.
|
||||
|
||||
Commenti per una documentazione generale
|
||||
----------------------------------------
|
||||
|
||||
Al fine d'avere il codice ed i commenti nello stesso file, potete includere
|
||||
dei blocchi di documentazione kernel-doc con un formato libero invece
|
||||
che nel formato specifico per funzioni, strutture, unioni, enumerati o tipi
|
||||
di dato. Per esempio, questo tipo di commento potrebbe essere usato per la
|
||||
spiegazione delle operazioni di un driver o di una libreria
|
||||
che nel formato specifico per funzioni, strutture, unioni, enumerati, tipi
|
||||
di dato o variabili. Per esempio, questo tipo di commento potrebbe essere
|
||||
usato per la spiegazione delle operazioni di un driver o di una libreria
|
||||
|
||||
Questo s'ottiene utilizzando la parola chiave ``DOC:`` a cui viene associato
|
||||
un titolo.
|
||||
@@ -565,6 +595,8 @@ identifiers: *[ function/type ...]*
|
||||
Include la documentazione per ogni *function* e *type* in *source*.
|
||||
Se non vengono esplicitamente specificate le funzioni da includere, allora
|
||||
verranno incluse tutte quelle disponibili in *source*.
|
||||
*type* può essere un identificatore di tipo ``struct``, ``union``,
|
||||
``enum``, ``typedef`` o ``var``.
|
||||
|
||||
Esempi::
|
||||
|
||||
@@ -601,7 +633,25 @@ dai file sorgenti.
|
||||
Come utilizzare kernel-doc per generare pagine man
|
||||
--------------------------------------------------
|
||||
|
||||
Se volete utilizzare kernel-doc solo per generare delle pagine man, potete
|
||||
farlo direttamente dai sorgenti del kernel::
|
||||
Per generare le pagine man di tutti i file che contengono marcatori
|
||||
kernel-doc, eseguite::
|
||||
|
||||
$ tools/docs/kernel-doc -man $(git grep -l '/\*\*' -- :^Documentation :^tools) | scripts/split-man.pl /tmp/man
|
||||
$ make mandocs
|
||||
|
||||
Oppure, chiamando direttamente ``script-build-wrapper``::
|
||||
|
||||
$ ./tools/docs/sphinx-build-wrapper mandocs
|
||||
|
||||
Il risultato sarà disponibile nella cartella ``/man`` dentro la cartella
|
||||
di output (predefinita: ``Documentation/output``).
|
||||
|
||||
Opzionalmente, è possibile generare un sottoinsieme di pagine man usando
|
||||
SPHINXDIRS:
|
||||
|
||||
$ make SPHINXDIRS=driver-api/media mandocs
|
||||
|
||||
.. note::
|
||||
|
||||
Quando si usa SPHINXDIRS={subdir}, verranno generate le pagine man solo
|
||||
per i file che si trovano esplicitamente all'interno di un file
|
||||
``Documentation/{subdir}/.../*.rst``.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
Profilo del manutentore del sottosistema di documentazione
|
||||
==========================================================
|
||||
|
||||
Il "sottosistema" della documentazione è il punto di coordinamento
|
||||
centrale per la documentazione del kernel e la relativa infrastruttura.
|
||||
Copre la gerarchia sotto Documentation/ (con l'eccezione di
|
||||
Documentation/devicetree), diverse utilità sotto scripts/ e, almeno in
|
||||
parte, LICENSES/.
|
||||
|
||||
Vale la pena notare, però, che i confini di questo sottosistema sono più sfumati
|
||||
del normale. Molti altri manutentori di sottosistemi preferiscono mantenere il
|
||||
controllo di alcune parti di Documentation/, e molti altri ancora vi applicano
|
||||
liberamente delle modifiche quando è conveniente. Oltre a ciò, buona parte della
|
||||
documentazione del kernel si trova nel codice sorgente sotto forma di commenti
|
||||
kerneldoc; questi sono solitamente (ma non sempre) mantenuti dal manutentore del
|
||||
sottosistema pertinente.
|
||||
|
||||
La lista di discussione per la documentazione è linux-doc@vger.kernel.org.
|
||||
Le patch dovrebbero essere inviate contro l'albero docs-next quando
|
||||
possibile.
|
||||
|
||||
Aggiunta alla checklist di invio
|
||||
--------------------------------
|
||||
|
||||
Quando si apportano modifiche alla documentazione, dovreste generare
|
||||
effettivamente la documentazione e assicurarvi che non siano stati
|
||||
introdotti nuovi errori o avvisi. Generare i documenti in HTML e osservare
|
||||
il risultato aiuterà a evitare fraintendimenti spiacevoli su come le cose
|
||||
verranno rappresentate.
|
||||
|
||||
Tutta la nuova documentazione (incluse le aggiunte a documenti esistenti)
|
||||
dovrebbe idealmente giustificare, da qualche parte nel changelog, chi sia
|
||||
il pubblico a cui è destinata; in questo modo, ci assicuriamo che la
|
||||
documentazione finisca nel posto giusto. Alcune categorie possibili
|
||||
sono: sviluppatori del kernel (esperti o principianti), programmatori
|
||||
dello spazio utente, utenti finali e/o amministratori di sistema, e
|
||||
distributori.
|
||||
|
||||
Date chiave del ciclo
|
||||
---------------------
|
||||
|
||||
Le patch possono essere inviate in qualsiasi momento, ma la risposta sarà
|
||||
più lenta del solito durante la finestra d'integrazione. L'albero della
|
||||
documentazione tende a chiudersi tardi, prima dell'apertura della finestra
|
||||
d'integrazione, poiché il rischio di regressioni dovute a patch sulla
|
||||
documentazione è basso.
|
||||
|
||||
Cadenza di revisione
|
||||
--------------------
|
||||
|
||||
Sono (Jonathan Corbet) l'unico manutentore del sottosistema di documentazione, e
|
||||
svolgo questo lavoro nel mio tempo libero, quindi la risposta alle patch sarà a
|
||||
volte lenta. Cerco sempre di inviare una notifica quando una patch viene
|
||||
integrata (o quando decido che non può esserlo). Non esitate a inviare un
|
||||
sollecito se non avete ricevuto risposta entro una settimana dall'invio di una
|
||||
patch.
|
||||
@@ -1,195 +1,195 @@
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
:Original: Documentation/doc-guide/index.rst
|
||||
|
||||
=========================================
|
||||
Includere gli i file di intestazione uAPI
|
||||
=========================================
|
||||
=====================================
|
||||
Includere i file di intestazione uAPI
|
||||
=====================================
|
||||
|
||||
Qualche volta è utile includere dei file di intestazione e degli esempi di codice C
|
||||
al fine di descrivere l'API per lo spazio utente e per generare dei riferimenti
|
||||
fra il codice e la documentazione. Aggiungere i riferimenti ai file dell'API
|
||||
dello spazio utente ha ulteriori vantaggi: Sphinx genererà dei messaggi
|
||||
dello spazio utente ha un ulteriore vantaggio: Sphinx genererà dei messaggi
|
||||
d'avviso se un simbolo non viene trovato nella documentazione. Questo permette
|
||||
di mantenere allineate la documentazione della uAPI (API spazio utente)
|
||||
con le modifiche del kernel.
|
||||
Il programma :ref:`parse_headers.py <it_parse_headers>` genera questi riferimenti.
|
||||
Esso dev'essere invocato attraverso un Makefile, mentre si genera la
|
||||
documentazione. Per avere un esempio su come utilizzarlo all'interno del kernel
|
||||
consultate ``Documentation/userspace-api/media/Makefile``.
|
||||
Il programma :ref:`parse_headers.py <it_parse_headers>` genera questi
|
||||
riferimenti. Esso dev'essere invocato attraverso un Makefile, mentre si genera
|
||||
la documentazione. Per avere un esempio su come utilizzarlo all'interno del
|
||||
kernel consultate ``Documentation/userspace-api/media/Makefile``.
|
||||
|
||||
.. _it_parse_headers:
|
||||
|
||||
parse_headers.py
|
||||
^^^^^^^^^^^^^^^^
|
||||
tools/docs/parse_headers.py
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
NOME
|
||||
****
|
||||
|
||||
parse_headers.py - analizza un file C al fine di identificare funzioni,
|
||||
strutture, enumerati e definizioni, e creare riferimenti per un libro Sphinx.
|
||||
|
||||
parse_headers.py - analizza i file C al fine di identificare funzioni,
|
||||
strutture, enumerati e definizioni, e creare riferimenti per Sphinx
|
||||
USO
|
||||
***
|
||||
|
||||
SINTASSI
|
||||
********
|
||||
parse-headers.py [-h] [-d] [-t] ``FILE_IN`` ``FILE_OUT`` ``FILE_RULES``
|
||||
|
||||
SINOSSI
|
||||
*******
|
||||
|
||||
\ **parse_headers.py**\ [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
|
||||
Converte un file d'intestazione o un file sorgente C ``FILE_IN`` in un testo
|
||||
ReStructured Text incluso mediante il blocco ..parsed-literal con riferimenti
|
||||
alla documentazione che descrive l'API. Accetta opzionalmente un file
|
||||
``FILE_RULES`` che descrive quali elementi debbano essere ignorati o il cui
|
||||
riferimento debba puntare ad un tipo/nome diverso da quello predefinito.
|
||||
|
||||
Dove <options> può essere: --debug, --usage o --help.
|
||||
Il file generato viene scritto in ``FILE_OUT``.
|
||||
|
||||
Il programma è capace di identificare ``define``, ``struct``, ``typedef``,
|
||||
``enum`` e ``symbol`` di un enumerato, creando i riferimenti per ognuno di
|
||||
loro.
|
||||
|
||||
Inoltre, esso è capace di distinguere le ``#define`` utilizzate per
|
||||
specificare le macro specifiche di Linux usate per definire gli ``ioctl``.
|
||||
|
||||
Il file ``FILE_RULES``, opzionale, contiene un insieme di regole come le
|
||||
seguenti::
|
||||
|
||||
ignore ioctl VIDIOC_ENUM_FMT
|
||||
replace ioctl VIDIOC_DQBUF vidioc_qbuf
|
||||
replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
|
||||
|
||||
ARGOMENTI POSIZIONALI
|
||||
*********************
|
||||
|
||||
``FILE_IN``
|
||||
File C d'ingresso
|
||||
|
||||
``FILE_OUT``
|
||||
File RST generato
|
||||
|
||||
``FILE_RULES``
|
||||
File delle eccezioni (opzionale)
|
||||
|
||||
OPZIONI
|
||||
*******
|
||||
|
||||
|
||||
|
||||
\ **--debug**\
|
||||
|
||||
Lo script viene messo in modalità verbosa, utile per il debugging.
|
||||
|
||||
|
||||
\ **--usage**\
|
||||
|
||||
Mostra un messaggio d'aiuto breve e termina.
|
||||
|
||||
|
||||
\ **--help**\
|
||||
|
||||
Mostra un messaggio d'aiuto dettagliato e termina.
|
||||
``-h``, ``--help``
|
||||
mostra un messaggio d'aiuto e termina
|
||||
``-d``, ``--debug``
|
||||
aumenta il livello di debug. Può essere usato più volte
|
||||
``-t``, ``--toc``
|
||||
invece di un blocco letterale, genera nel file RST una tabella
|
||||
dell'indice (TOC)
|
||||
|
||||
|
||||
DESCRIZIONE
|
||||
***********
|
||||
|
||||
Converte un file d'intestazione o un file sorgente C (C_FILE) in un testo
|
||||
reStructuredText incluso mediante il blocco ..parsed-literal
|
||||
con riferimenti alla documentazione che descrive l'API. Opzionalmente,
|
||||
il programma accetta anche un altro file (EXCEPTIONS_FILE) che
|
||||
descrive quali elementi debbano essere ignorati o il cui riferimento
|
||||
deve puntare ad elemento diverso dal predefinito.
|
||||
Crea, a partire da ``FILE_IN``, una versione arricchita di un file
|
||||
d'intestazione del kernel con collegamenti incrociati verso ogni tipo di
|
||||
struttura dati C, formattandola con la notazione reStructuredText, sia
|
||||
come blocco letterale che come tabella dell'indice.
|
||||
|
||||
Il file generato sarà disponibile in (OUT_FILE).
|
||||
Accetta opzionalmente un file ``FILE_RULES`` che descrive quali elementi
|
||||
debbano essere ignorati o il cui riferimento debba puntare ad un valore
|
||||
diverso da quello predefinito, e che può opzionalmente definire lo spazio
|
||||
dei nomi C da utilizzare.
|
||||
|
||||
Il programma è capace di identificare *define*, funzioni, strutture,
|
||||
tipi di dato, enumerati e valori di enumerati, e di creare i riferimenti
|
||||
per ognuno di loro. Inoltre, esso è capace di distinguere le #define
|
||||
utilizzate per specificare i comandi ioctl di Linux.
|
||||
Ha lo scopo di permettere una documentazione più completa, in cui i file
|
||||
d'intestazione della uAPI creino collegamenti incrociati verso il codice.
|
||||
|
||||
Il file EXCEPTIONS_FILE contiene due tipi di dichiarazioni:
|
||||
\ **ignore**\ o \ **replace**\ .
|
||||
Il file generato viene scritto in ``FILE_OUT``.
|
||||
|
||||
La sintassi per ignore è:
|
||||
Il file ``FILE_RULES`` può contenere tre tipi di dichiarazioni:
|
||||
**ignore**, **replace** e **namespace**.
|
||||
|
||||
ignore \ **tipo**\ \ **nome**\
|
||||
Per impostazione predefinita, vengono create regole per tutti i simboli e
|
||||
le definizioni, ma è anche possibile fornire un file di eccezioni. Questo
|
||||
file contiene un insieme di regole che seguono la sintassi descritta di
|
||||
seguito:
|
||||
|
||||
La dichiarazione \ **ignore**\ significa che non verrà generato alcun
|
||||
riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ .
|
||||
1. Regole ignore:
|
||||
|
||||
ignore *tipo* *simbolo*
|
||||
|
||||
La sintassi per replace è:
|
||||
Rimuove il simbolo dalla generazione dei riferimenti.
|
||||
|
||||
replace \ **tipo**\ \ **nome**\ \ **nuovo_valore**\
|
||||
2. Regole replace:
|
||||
|
||||
La dichiarazione \ **replace**\ significa che verrà generato un
|
||||
riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ , ma, invece
|
||||
di utilizzare il valore predefinito, verrà utilizzato il valore
|
||||
\ **nuovo_valore**\ .
|
||||
replace *tipo* *vecchio_simbolo* *nuovo_riferimento*
|
||||
|
||||
Per entrambe le dichiarazioni, il \ **tipo**\ può essere uno dei seguenti:
|
||||
Sostituisce *vecchio_simbolo* con *nuovo_riferimento*.
|
||||
*nuovo_riferimento* può essere:
|
||||
|
||||
- un semplice nome di simbolo;
|
||||
- un riferimento Sphinx completo.
|
||||
|
||||
\ **ioctl**\
|
||||
3. Regole namespace
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata su definizioni di ioctl
|
||||
come la seguente:
|
||||
namespace *spazio_dei_nomi*
|
||||
|
||||
#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
|
||||
Imposta lo *spazio_dei_nomi* C da utilizzare durante la generazione dei
|
||||
riferimenti incrociati. Può essere sovrascritto dalle regole replace.
|
||||
|
||||
Nelle regole ignore e replace, *tipo* può essere:
|
||||
|
||||
- ioctl:
|
||||
per le definizioni della forma ``_IO*``, per esempio le definizioni
|
||||
di ioctl
|
||||
|
||||
\ **define**\
|
||||
- define:
|
||||
per le altre definizioni
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata su una qualsiasi #define
|
||||
trovata in C_FILE.
|
||||
- symbol:
|
||||
per i simboli definiti all'interno di enumerati;
|
||||
|
||||
- typedef:
|
||||
per i typedef;
|
||||
|
||||
- enum:
|
||||
per il nome di un enumerato non anonimo;
|
||||
|
||||
\ **typedef**\
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata ad una dichiarazione typedef
|
||||
in C_FILE.
|
||||
|
||||
|
||||
|
||||
\ **struct**\
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata ai nomi di strutture
|
||||
in C_FILE.
|
||||
|
||||
|
||||
|
||||
\ **enum**\
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata ai nomi di enumerati
|
||||
in C_FILE.
|
||||
|
||||
|
||||
|
||||
\ **symbol**\
|
||||
|
||||
La dichiarazione ignore o replace verrà applicata ai nomi di valori di
|
||||
enumerati in C_FILE.
|
||||
|
||||
Per le dichiarazioni di tipo replace, il campo \ **new_value**\ utilizzerà
|
||||
automaticamente i riferimenti :c:type: per \ **typedef**\ , \ **enum**\ e
|
||||
\ **struct**\. Invece, utilizzerà :ref: per \ **ioctl**\ , \ **define**\ e
|
||||
\ **symbol**\. Il tipo di riferimento può essere definito esplicitamente
|
||||
nella dichiarazione stessa.
|
||||
- struct:
|
||||
per le strutture.
|
||||
|
||||
|
||||
ESEMPI
|
||||
******
|
||||
|
||||
- Ignora una definizione ``_VIDEODEV2_H`` in ``FILE_IN``::
|
||||
|
||||
ignore define _VIDEODEV2_H
|
||||
ignore define _VIDEODEV2_H
|
||||
|
||||
- In una struttura dati come questo enumerato::
|
||||
|
||||
enum foo { BAR1, BAR2, PRIVATE };
|
||||
|
||||
Non genererà alcun riferimento incrociato per ``PRIVATE``::
|
||||
|
||||
ignore symbol PRIVATE
|
||||
|
||||
Nello stesso enumerato, invece di creare un riferimento incrociato per
|
||||
ogni simbolo, si può far si che tutti puntino al tipo C ``enum foo``::
|
||||
|
||||
replace symbol BAR1 :c:type:\`foo\`
|
||||
replace symbol BAR2 :c:type:\`foo\`
|
||||
|
||||
|
||||
Ignora una definizione #define _VIDEODEV2_H nel file C_FILE.
|
||||
|
||||
ignore symbol PRIVATE
|
||||
|
||||
|
||||
In un enumerato come il seguente:
|
||||
|
||||
enum foo { BAR1, BAR2, PRIVATE };
|
||||
|
||||
Non genererà alcun riferimento per \ **PRIVATE**\ .
|
||||
|
||||
replace symbol BAR1 :c:type:\`foo\`
|
||||
replace symbol BAR2 :c:type:\`foo\`
|
||||
|
||||
|
||||
In un enumerato come il seguente:
|
||||
|
||||
enum foo { BAR1, BAR2, PRIVATE };
|
||||
|
||||
Genererà un riferimento ai valori BAR1 e BAR2 dal simbolo foo nel dominio C.
|
||||
- Usa lo spazio dei nomi C ``MC`` per tutti i simboli in ``FILE_IN``::
|
||||
|
||||
namespace MC
|
||||
|
||||
BUGS
|
||||
****
|
||||
|
||||
Riferire ogni malfunzionamento a Mauro Carvalho Chehab <mchehab@s-opensource.com>
|
||||
|
||||
Segnalate qualsiasi malfunzionamento a Mauro Carvalho Chehab
|
||||
<mchehab@kernel.org>
|
||||
|
||||
COPYRIGHT
|
||||
*********
|
||||
|
||||
Copyright (c) 2016, 2025 di Mauro Carvalho Chehab <mchehab+huawei@kernel.org>.
|
||||
|
||||
Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>.
|
||||
|
||||
Licenza GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>.
|
||||
Licenza GPLv2: GNU GPL versione 2 <https://gnu.org/licenses/gpl.html>.
|
||||
|
||||
Questo è software libero: siete liberi di cambiarlo e ridistribuirlo.
|
||||
Non c'è alcuna garanzia, nei limiti permessi dalla legge.
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
.. include:: ../disclaimer-ita.rst
|
||||
|
||||
.. note:: Per leggere la documentazione originale in inglese:
|
||||
:ref:`Documentation/doc-guide/index.rst <doc_guide>`
|
||||
|
||||
.. _it_sphinxdoc:
|
||||
|
||||
=============================================
|
||||
@@ -36,7 +33,7 @@ Installazione Sphinx
|
||||
====================
|
||||
|
||||
I marcatori ReST utilizzati nei file in Documentation/ sono pensati per essere
|
||||
processati da ``Sphinx`` nella versione 1.7 o superiore.
|
||||
processati da ``Sphinx`` nella versione 3.4.3 o superiore.
|
||||
|
||||
Esiste uno script che verifica i requisiti Sphinx. Per ulteriori dettagli
|
||||
consultate :ref:`it_sphinx-pre-install`.
|
||||
@@ -52,24 +49,14 @@ vi raccomandiamo di installare Sphinx dentro ad un ambiente virtuale usando
|
||||
``virtualenv-3`` o ``virtualenv`` a seconda di come Python 3 è stato
|
||||
pacchettizzato dalla vostra distribuzione.
|
||||
|
||||
.. note::
|
||||
Riassumendo, se volete installare l'ultima versione di Sphinx, dovete
|
||||
eseguire::
|
||||
|
||||
#) Viene raccomandato l'uso del tema RTD per la documentazione in HTML.
|
||||
A seconda della versione di Sphinx, potrebbe essere necessaria
|
||||
l'installazione tramite il comando ``pip install sphinx_rtd_theme``.
|
||||
$ virtualenv sphinx_latest
|
||||
$ . sphinx_latest/bin/activate
|
||||
(sphinx_latest) $ pip install -r Documentation/sphinx/requirements.txt
|
||||
|
||||
#) Alcune pagine ReST contengono delle formule matematiche. A causa del
|
||||
modo in cui Sphinx funziona, queste espressioni sono scritte
|
||||
utilizzando LaTeX. Per una corretta interpretazione, è necessario aver
|
||||
installato texlive con i pacchetti amdfonts e amsmath.
|
||||
|
||||
Riassumendo, se volete installare la versione 2.4.4 di Sphinx dovete eseguire::
|
||||
|
||||
$ virtualenv sphinx_2.4.4
|
||||
$ . sphinx_2.4.4/bin/activate
|
||||
(sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt
|
||||
|
||||
Dopo aver eseguito ``. sphinx_2.4.4/bin/activate``, il prompt cambierà per
|
||||
Dopo aver eseguito ``. sphinx_latest/bin/activate``, il prompt cambierà per
|
||||
indicare che state usando il nuovo ambiente. Se aprite un nuova sessione,
|
||||
prima di generare la documentazione, dovrete rieseguire questo comando per
|
||||
rientrare nell'ambiente virtuale.
|
||||
@@ -99,6 +86,27 @@ Per alcune distribuzioni Linux potrebbe essere necessario installare
|
||||
anche una serie di pacchetti ``texlive`` in modo da fornire il supporto
|
||||
minimo per il funzionamento di ``XeLaTeX``.
|
||||
|
||||
Espressioni matematiche in HTML
|
||||
-------------------------------
|
||||
|
||||
Alcune pagine ReST contengono delle formule matematiche. Per come funziona
|
||||
Sphinx, queste espressioni sono scritte utilizzando la notazione LaTeX. Esistono
|
||||
due opzioni per far si che Sphinx rappresenti le espressioni matematiche
|
||||
nell'output HTML. La prima è un'estensione chiamata `imgmath`_ che converte le
|
||||
espressioni matematiche in immagini e le integra nelle pagine HTML. L'altra è
|
||||
un'estensione chiamata `mathjax`_ che delega la rappresentazione delle formule
|
||||
matematiche ai browser web capaci di eseguire JavaScript. La prima era l'unica
|
||||
opzione per la documentazione del kernel precedente alla versione 6.1 e richiede
|
||||
diversi pacchetti texlive, fra cui amsfonts e amsmath.
|
||||
|
||||
A partire dalla versione 6.1 del kernel, le pagine HTML con espressioni
|
||||
matematiche possono essere generate senza dover installare alcun pacchetto
|
||||
texlive. Per maggiori informazioni consultate `Scelta della libreria per le
|
||||
formule matematiche`_.
|
||||
|
||||
.. _imgmath: https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.imgmath
|
||||
.. _mathjax: https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.mathjax
|
||||
|
||||
.. _it_sphinx-pre-install:
|
||||
|
||||
Verificare le dipendenze Sphinx
|
||||
@@ -136,6 +144,30 @@ Questo script ha i seguenti parametri:
|
||||
Utilizza l'ambiente predefinito dal sistema operativo invece che
|
||||
l'ambiente virtuale per Python;
|
||||
|
||||
Installare la versione minima di Sphinx
|
||||
---------------------------------------
|
||||
|
||||
Quando si modifica il sistema di generazione di Sphinx, è importante
|
||||
assicurarsi che la versione minima sia ancora supportata. Al giorno d'oggi,
|
||||
sta diventando sempre più difficile farlo sulle distribuzioni moderne, dato
|
||||
che non è possibile installarla con Python 3.13 e versioni successive.
|
||||
|
||||
Potete verificare la versione minima di Python supportata, così come
|
||||
definita in Documentation/process/changes.rst, creando un venv con quella
|
||||
versione e installando i requisiti minimi con::
|
||||
|
||||
/usr/bin/python3.9 -m venv sphinx_min
|
||||
. sphinx_min/bin/activate
|
||||
pip install -r Documentation/sphinx/min_requirements.txt
|
||||
|
||||
Un test più completo può essere eseguito utilizzando:
|
||||
|
||||
tools/docs/test_doc_build.py
|
||||
|
||||
Questo script crea un venv Python per ogni versione supportata, generando
|
||||
facoltativamente la documentazione per un intervallo di versioni di
|
||||
Sphinx.
|
||||
|
||||
|
||||
Generazione della documentazione Sphinx
|
||||
=======================================
|
||||
@@ -143,39 +175,82 @@ Generazione della documentazione Sphinx
|
||||
Per generare la documentazione in formato HTML o PDF si eseguono i rispettivi
|
||||
comandi ``make htmldocs`` o ``make pdfdocs``. Esistono anche altri formati
|
||||
in cui è possibile generare la documentazione; per maggiori informazioni
|
||||
potere eseguire il comando ``make help``.
|
||||
potete eseguire il comando ``make help``.
|
||||
La documentazione così generata sarà disponibile nella sottocartella
|
||||
``Documentation/output``.
|
||||
|
||||
Ovviamente, per generare la documentazione, Sphinx (``sphinx-build``)
|
||||
dev'essere installato. Se disponibile, il tema *Read the Docs* per Sphinx
|
||||
verrà utilizzato per ottenere una documentazione HTML più gradevole.
|
||||
Per la documentazione in formato PDF, invece, avrete bisogno di ``XeLaTeX`
|
||||
e di ``convert(1)`` disponibile in ImageMagick
|
||||
(https://www.imagemagick.org). \ [#ink]_
|
||||
Tipicamente, tutti questi pacchetti sono disponibili e pacchettizzati nelle
|
||||
distribuzioni Linux.
|
||||
dev'essere installato. Per la documentazione in formato PDF, invece,
|
||||
avrete bisogno di ``XeLaTeX`` e di ``convert(1)`` disponibile in
|
||||
ImageMagick (https://www.imagemagick.org).\ [#ink]_ Tutti questi pacchetti
|
||||
sono ampiamente disponibili e pacchettizzati nelle distribuzioni.
|
||||
|
||||
Per poter passare ulteriori opzioni a Sphinx potete utilizzare la variabile
|
||||
make ``SPHINXOPTS``. Per esempio, se volete che Sphinx sia più verboso durante
|
||||
la generazione potete usare il seguente comando ``make SPHINXOPTS=-v htmldocs``.
|
||||
make ``SPHINXOPTS``. Per esempio, se volete che Sphinx sia più prolisso
|
||||
durante la generazione potete usare il comando
|
||||
``make SPHINXOPTS=-v htmldocs``.
|
||||
|
||||
Potete anche personalizzare l'ouptut html passando un livello aggiuntivo
|
||||
Potete anche personalizzare l'output html passando un livello aggiuntivo
|
||||
DOCS_CSS usando la rispettiva variabile d'ambiente ``DOCS_CSS``.
|
||||
|
||||
La variable make ``SPHINXDIRS`` è utile quando si vuole generare solo una parte
|
||||
della documentazione. Per esempio, si possono generare solo di documenti in
|
||||
``Documentation/doc-guide`` eseguendo ``make SPHINXDIRS=doc-guide htmldocs``. La
|
||||
sezione dedicata alla documentazione di ``make help`` vi mostrerà quali sotto
|
||||
cartelle potete specificare.
|
||||
Il tema di base per generare la documentazione HTML viene è "Alabaster"; questo
|
||||
tema è distribuito assieme a Sphinx e non necessita di un'installazione
|
||||
separata. Il tema di Sphinx può essere sostituito usando la variabile make
|
||||
``DOCS_THEME``.
|
||||
|
||||
.. note::
|
||||
|
||||
Alcuni potrebbero preferire il tema RTD per l'output in HTML. A seconda
|
||||
della versione di Sphinx, dev'essere installato separatamente, con il
|
||||
comando ``pip install sphinx_rtd_theme``.
|
||||
|
||||
Esiste un'altra variabile make, ``SPHINXDIRS``, utile quando si vuole
|
||||
generare, a scopo di test, solo una parte della documentazione. Per
|
||||
esempio, potete generare i documenti in ``Documentation/doc-guide``
|
||||
eseguendo ``make SPHINXDIRS=doc-guide htmldocs``. La sezione dedicata alla
|
||||
documentazione di ``make help`` vi mostrerà l'elenco delle sottocartelle
|
||||
che potete specificare.
|
||||
|
||||
Potete eliminare la documentazione generata tramite il comando
|
||||
``make cleandocs``.
|
||||
|
||||
.. [#ink] Avere installato anche ``inkscape(1)`` dal progetto Inkscape ()
|
||||
potrebbe aumentare la qualità delle immagini che verranno integrate
|
||||
nel documento PDF, specialmente per quando si usando rilasci del
|
||||
kernel uguali o superiori a 5.18
|
||||
.. [#ink] Avere installato anche ``inkscape(1)`` dal progetto Inkscape
|
||||
(https://inkscape.org) potrebbe aumentare la qualità delle
|
||||
immagini integrate nei documenti PDF, specialmente per i rilasci
|
||||
del kernel dalla versione 5.18 in poi.
|
||||
|
||||
Scelta della libreria per le formule matematiche
|
||||
------------------------------------------------
|
||||
|
||||
A partire dalla versione 6.1 del kernel, mathjax funge da libreria di
|
||||
ripiego per le formule matematiche nell'output HTML.\ [#sph1_8]_
|
||||
|
||||
La libreria matematica viene scelta in base ai comandi disponibili, come
|
||||
mostrato di seguito:
|
||||
|
||||
.. table:: Scelta della libreria matematica per l'HTML
|
||||
|
||||
======== ================= ================
|
||||
Libreria Comandi richiesti Formato immagine
|
||||
======== ================= ================
|
||||
imgmath latex, dvipng PNG (raster)
|
||||
mathjax
|
||||
======== ================= ================
|
||||
|
||||
La scelta può essere sovrascritta impostando la variabile d'ambiente
|
||||
``SPHINX_IMGMATH`` come mostrato di seguito:
|
||||
|
||||
.. table:: Effetto dell'impostazione di ``SPHINX_IMGMATH``
|
||||
|
||||
====================== ========
|
||||
Impostazione Libreria
|
||||
====================== ========
|
||||
``SPHINX_IMGMATH=yes`` imgmath
|
||||
``SPHINX_IMGMATH=no`` mathjax
|
||||
====================== ========
|
||||
|
||||
.. [#sph1_8] La libreria di ripiego richiede Sphinx >=1.8.
|
||||
|
||||
|
||||
Scrivere la documentazione
|
||||
==========================
|
||||
@@ -289,8 +364,19 @@ incrociato quando questa ha una voce nell'indice. Se trovate degli usi di
|
||||
``c:func:`` nella documentazione del kernel, sentitevi liberi di rimuoverli.
|
||||
|
||||
|
||||
Tabelle
|
||||
-------
|
||||
|
||||
Il formato reStructuredText offre diverse opzioni per la sintassi delle tabelle.
|
||||
Lo stile del kernel per le tabelle preferisce la sintassi delle *tabelle
|
||||
semplici* o delle *tabelle a griglia*. Per maggiori dettagli consultate il
|
||||
`manuale di riferimento reStructuredText per la sintassi delle tabelle`_.
|
||||
|
||||
.. _manuale di riferimento reStructuredText per la sintassi delle tabelle:
|
||||
https://docutils.sourceforge.io/docs/user/rst/quickref.html#tables
|
||||
|
||||
Tabelle a liste
|
||||
---------------
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Il formato ``list-table`` può essere utile per tutte quelle tabelle che non
|
||||
possono essere facilmente scritte usando il formato ASCII-art di Sphinx. Però,
|
||||
@@ -403,6 +489,16 @@ percorso al documento.
|
||||
|
||||
Per informazioni riguardo ai riferimenti incrociati ai commenti
|
||||
kernel-doc per funzioni o tipi, consultate
|
||||
Documentation/translations/it_IT/doc-guide/kernel-doc.rst.
|
||||
|
||||
Riferimenti ai commit
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
I riferimenti ai commit di git vengono trasformati automaticamente in
|
||||
collegamenti ipertestuali quando sono scritti in uno di questi formati::
|
||||
|
||||
commit 72bf4f1767f0
|
||||
commit 72bf4f1767f0 ("net: do not leave an empty skb in write queue")
|
||||
|
||||
.. _it_sphinx_kfigure:
|
||||
|
||||
|
||||
@@ -23,50 +23,53 @@ Requisiti minimi correnti
|
||||
|
||||
Prima di pensare d'avere trovato un baco, aggiornate i seguenti programmi
|
||||
**almeno** alla versione indicata! Se non siete certi della versione che state
|
||||
usando, il comando indicato dovrebbe dirvelo.
|
||||
usando, il comando indicato dovrebbe dirvelo. Per avere una lista dei programmi
|
||||
sul vostro sistema, incluse le rispettive versioni, eseguite
|
||||
./scripts/ver_linux.
|
||||
|
||||
Questa lista presume che abbiate già un kernel Linux funzionante. In aggiunta,
|
||||
non tutti gli strumenti sono necessari ovunque; ovviamente, se non avete una
|
||||
PC Card, per esempio, probabilmente non dovreste preoccuparvi di pcmciautils.
|
||||
|
||||
====================== ================= ========================================
|
||||
Programma Versione minima Comando per verificare la versione
|
||||
====================== ================= ========================================
|
||||
GNU C 8.1 gcc --version
|
||||
Clang/LLVM (optional) 17.0.1 clang --version
|
||||
Rust (opzionale) 1.78.0 rustc --version
|
||||
bindgen (opzionale) 0.65.1 bindgen --version
|
||||
GNU make 4.0 make --version
|
||||
bash 4.2 bash --version
|
||||
binutils 2.30 ld -v
|
||||
flex 2.5.35 flex --version
|
||||
bison 2.0 bison --version
|
||||
pahole 1.16 pahole --version
|
||||
util-linux 2.10o mount --version
|
||||
kmod 13 depmod -V
|
||||
e2fsprogs 1.41.4 e2fsck -V
|
||||
jfsutils 1.1.3 fsck.jfs -V
|
||||
xfsprogs 2.6.0 xfs_db -V
|
||||
squashfs-tools 4.0 mksquashfs -version
|
||||
btrfs-progs 0.18 btrfsck
|
||||
pcmciautils 004 pccardctl -V
|
||||
quota-tools 3.09 quota -V
|
||||
PPP 2.4.0 pppd --version
|
||||
nfs-utils 1.0.5 showmount --version
|
||||
procps 3.2.0 ps --version
|
||||
udev 081 udevd --version
|
||||
grub 0.93 grub --version || grub-install --version
|
||||
mcelog 0.6 mcelog --version
|
||||
iptables 1.4.2 iptables -V
|
||||
openssl & libcrypto 1.0.0 openssl version
|
||||
bc 1.06.95 bc --version
|
||||
Sphinx\ [#f1]_ 2.4.4 sphinx-build --version
|
||||
cpio any cpio --version
|
||||
GNU tar 1.28 tar --version
|
||||
gtags (opzionale) 6.6.5 gtags --version
|
||||
mkimage (opzionale) 2017.01 mkimage --version
|
||||
Python (opzionale) 3.5.x python3 --version
|
||||
====================== ================= ========================================
|
||||
====================== =============== ========================================
|
||||
Programma Versione minima Comando per verificare la versione
|
||||
====================== =============== ========================================
|
||||
bash 4.2 bash --version
|
||||
bc 1.06.95 bc --version
|
||||
bindgen (opzionale) 0.71.1 bindgen --version
|
||||
binutils 2.30 ld -v
|
||||
bison 2.0 bison --version
|
||||
btrfs-progs 0.18 btrfs --version
|
||||
Clang/LLVM (opzionale) 17.0.1 clang --version
|
||||
e2fsprogs 1.41.4 e2fsck -V
|
||||
flex 2.5.35 flex --version
|
||||
gdb 7.2 gdb --version
|
||||
GNU awk (opzionale) 5.1.0 gawk --version
|
||||
GNU C 8.1 gcc --version
|
||||
GNU make 4.0 make --version
|
||||
GNU tar 1.28 tar --version
|
||||
GRUB 0.93 grub --version || grub-install --version
|
||||
gtags (opzionale) 6.6.5 gtags --version
|
||||
iptables 1.4.2 iptables -V
|
||||
jfsutils 1.1.3 fsck.jfs -V
|
||||
kmod 13 kmod -V
|
||||
mcelog 0.6 mcelog --version
|
||||
mkimage (opzionale) 2017.01 mkimage --version
|
||||
nfs-utils 1.0.5 showmount --version
|
||||
openssl & libcrypto 1.0.0 openssl version
|
||||
pahole 1.26 pahole --version
|
||||
pcmciautils 004 pccardctl -V
|
||||
PPP 2.4.0 pppd --version
|
||||
procps 3.2.0 ps --version
|
||||
Python 3.9.x python3 --version
|
||||
quota-tools 3.09 quota -V
|
||||
Rust (opzionale) 1.85.0 rustc --version
|
||||
Sphinx\ [#f1]_ 3.4.3 sphinx-build --version
|
||||
squashfs-tools 4.0 mksquashfs -version
|
||||
udev 081 udevadm --version
|
||||
util-linux 2.10o mount --version
|
||||
xfsprogs 2.6.0 xfs_db -V
|
||||
====================== =============== ========================================
|
||||
|
||||
.. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel
|
||||
|
||||
@@ -144,7 +147,13 @@ pahole
|
||||
|
||||
Dalla versione 5.2, quando viene impostato CONFIG_DEBUG_INFO_BTF, il sistema di
|
||||
compilazione genera BTF (BPF Type Format) a partire da DWARF per vmlinux. Più
|
||||
tardi anche per i moduli. Questo richiede pahole v1.16 o successivo.
|
||||
tardi anche per i moduli. Questo richiede pahole v1.22 o successivo.
|
||||
|
||||
Dalla versione 7.0, le kfunc annotate con KF_IMPLICIT_ARGS richiedono pahole
|
||||
v1.26 o successivo. Senza questa versione, tali kfunc avranno prototipi BTF
|
||||
errati in vmlinux, causando il fallimento del caricamento dei programmi BPF con
|
||||
l'errore "func_proto incompatible with vmlinux". Molte kfunc in sched_ext sono
|
||||
interessate da questo problema.
|
||||
|
||||
A seconda della distribuzione, lo si può trovare nei pacchetti 'dwarves' o
|
||||
'pahole'. Oppure lo si può trovare qui: https://fedorapeople.org/~acme/dwarves/.
|
||||
@@ -155,6 +164,14 @@ Perl
|
||||
Per compilare il kernel vi servirà perl 5 e i seguenti moduli ``Getopt::Long``,
|
||||
``Getopt::Std``, ``File::Basename``, e ``File::Find``.
|
||||
|
||||
Python
|
||||
------
|
||||
|
||||
Diverse opzioni di configurazione lo richiedono: è necessario per le
|
||||
configurazioni predefinite di arm/arm64, CONFIG_LTO_CLANG, alcune opzioni
|
||||
configurabili del DRM, lo strumento kernel-doc e la generazione della
|
||||
documentazione (Sphinx), e altro ancora.
|
||||
|
||||
BC
|
||||
--
|
||||
|
||||
@@ -193,6 +210,12 @@ pacchetto ``u-boot-tools`` oppure può essere compilato dal codice sorgente di
|
||||
U-Boot. Consultate le istruzioni
|
||||
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
|
||||
|
||||
GNU AWK
|
||||
-------
|
||||
|
||||
GNU AWK è necessario se si vuole che la compilazione del kernel generi dati
|
||||
sugli intervalli di indirizzi per i moduli integrati
|
||||
(CONFIG_BUILTIN_MODULE_RANGES).
|
||||
|
||||
Strumenti di sistema
|
||||
********************
|
||||
@@ -405,6 +428,16 @@ Clang/LLVM
|
||||
|
||||
- :ref:`Getting LLVM <getting_llvm>`.
|
||||
|
||||
Rust
|
||||
----
|
||||
|
||||
- Documentation/rust/quick-start.rst.
|
||||
|
||||
bindgen
|
||||
-------
|
||||
|
||||
- Documentation/rust/quick-start.rst.
|
||||
|
||||
Make
|
||||
----
|
||||
|
||||
@@ -507,11 +540,6 @@ mcelog
|
||||
|
||||
- <https://www.mcelog.org/>
|
||||
|
||||
cpio
|
||||
----
|
||||
|
||||
- <https://www.gnu.org/software/cpio/>
|
||||
|
||||
Rete
|
||||
****
|
||||
|
||||
|
||||
@@ -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 エントリに
|
||||
反映すべきです。
|
||||
よりよく理解できるよう、多くの場合、コメントまたは changelog エントリ
|
||||
として残すべきです。
|
||||
|
||||
どのような変更を行うのかをレビューアに必ず伝え、時間を割いてくれた
|
||||
ことに感謝してください。コードレビューは疲れる、時間のかかる作業であり、
|
||||
レビューアが不機嫌になることもあります。そのような場合であっても、
|
||||
丁寧に返答し、指摘された問題に対応してください。次の版を送るときは、
|
||||
cover letter または個々のパッチに ``patch 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 は、単独の主要作者であることを示します。
|
||||
|
||||
@@ -66,15 +66,4 @@ kernel e sobre como ver seu trabalho integrado.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Introdução <process/1.Intro>
|
||||
Guia do Processo de Desenvolvimento <process/development-process>
|
||||
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>
|
||||
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>
|
||||
process/index
|
||||
|
||||
440
Documentation/translations/pt_BR/process/4.Coding.rst
Normal file
440
Documentation/translations/pt_BR/process/4.Coding.rst
Normal file
@@ -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.
|
||||
376
Documentation/translations/pt_BR/process/5.Posting.rst
Normal file
376
Documentation/translations/pt_BR/process/5.Posting.rst
Normal file
@@ -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.
|
||||
220
Documentation/translations/pt_BR/process/6.Followthrough.rst
Normal file
220
Documentation/translations/pt_BR/process/6.Followthrough.rst
Normal file
@@ -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.
|
||||
201
Documentation/translations/pt_BR/process/7.AdvancedTopics.rst
Normal file
201
Documentation/translations/pt_BR/process/7.AdvancedTopics.rst
Normal file
@@ -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!
|
||||
73
Documentation/translations/pt_BR/process/8.Conclusion.rst
Normal file
73
Documentation/translations/pt_BR/process/8.Conclusion.rst
Normal file
@@ -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.
|
||||
700
Documentation/translations/pt_BR/process/adding-syscalls.rst
Normal file
700
Documentation/translations/pt_BR/process/adding-syscalls.rst
Normal file
@@ -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
|
||||
447
Documentation/translations/pt_BR/process/applying-patches.rst
Normal file
447
Documentation/translations/pt_BR/process/applying-patches.rst
Normal file
@@ -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.
|
||||
598
Documentation/translations/pt_BR/process/backporting.rst
Normal file
598
Documentation/translations/pt_BR/process/backporting.rst
Normal file
@@ -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
|
||||
256
Documentation/translations/pt_BR/process/botching-up-ioctls.rst
Normal file
256
Documentation/translations/pt_BR/process/botching-up-ioctls.rst
Normal file
@@ -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.
|
||||
@@ -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.
|
||||
88
Documentation/translations/pt_BR/process/code-of-conduct.rst
Normal file
88
Documentation/translations/pt_BR/process/code-of-conduct.rst
Normal file
@@ -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.
|
||||
@@ -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.
|
||||
125
Documentation/translations/pt_BR/process/cve.rst
Normal file
125
Documentation/translations/pt_BR/process/cve.rst
Normal file
@@ -0,0 +1,125 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====
|
||||
CVEs
|
||||
====
|
||||
|
||||
Os números Common Vulnerabilities and Exposure (CVE®) foram desenvolvidos
|
||||
como uma forma inequívoca de identificar, definir e catalogar vulnerabilidades
|
||||
de segurança divulgadas publicamente. Com o tempo, sua utilidade diminuiu em
|
||||
relação ao projeto do kernel, e os números CVE foram frequentemente atribuídos
|
||||
de formas inadequadas e por motivos inadequados. Por causa disso, a comunidade
|
||||
de desenvolvimento do kernel tendeu a evitá-los. No entanto, a combinação da
|
||||
pressão contínua para atribuir CVEs e outras formas de identificadores de
|
||||
segurança, e abusos contínuos por indivíduos e empresas de fora da comunidade
|
||||
do kernel, deixou claro que a comunidade do kernel deve controlar
|
||||
essas atribuições.
|
||||
|
||||
A equipe de desenvolvedores do kernel Linux tem a capacidade de atribuir CVEs
|
||||
para possíveis problemas de segurança do kernel Linux. Essa atribuição é
|
||||
independente do processo normal de relato de bugs de segurança do kernel
|
||||
Linux, descrito em :ref:`securitybugs`.
|
||||
|
||||
Uma lista de todos os CVEs atribuídos ao kernel Linux pode ser encontrada nos
|
||||
arquivos da lista de discussão linux-cve, como visto em
|
||||
https://lore.kernel.org/linux-cve-announce/. Para receber notificações sobre
|
||||
os CVEs atribuídos, por favor, `inscreva-se
|
||||
<https://subspace.kernel.org/subscribing.html>`_ nessa lista de discussão.
|
||||
|
||||
Processo
|
||||
========
|
||||
|
||||
Como parte do processo normal de lançamento estável, alterações do kernel que
|
||||
são potencialmente problemas de segurança são identificadas pelos
|
||||
desenvolvedores responsáveis pelas atribuições de números CVE e recebem
|
||||
automaticamente números CVE. Essas atribuições são publicadas na lista de
|
||||
discussão linux-cve-announce como anúncios frequentes.
|
||||
|
||||
Observe que, devido à camada em que o kernel Linux se encontra em um sistema,
|
||||
quase qualquer bug pode ser explorável para comprometer a segurança do kernel,
|
||||
mas a possibilidade de exploração muitas vezes não é evidente quando o bug é
|
||||
corrigido. Por causa disso, a equipe de atribuição de CVEs é excessivamente
|
||||
cautelosa e atribui números CVE a qualquer correção de bug que identificar.
|
||||
Isso explica o número aparentemente grande de CVEs emitidos pela equipe do
|
||||
kernel Linux.
|
||||
|
||||
Se a equipe de atribuição de CVEs deixar passar uma correção específica que
|
||||
qualquer usuário considere que deveria receber um CVE, por favor envie um
|
||||
e-mail para <cve@kernel.org> e a equipe trabalhará com você nisso. Observe
|
||||
que nenhum possível problema de segurança deve ser enviado para esse alias;
|
||||
ele é SOMENTE para atribuição de CVEs a correções que já estejam em árvores de
|
||||
kernel lançadas. Se você acredita ter encontrado um problema de segurança
|
||||
ainda
|
||||
não corrigido, por favor siga o processo normal de relato de bugs de segurança do kernel
|
||||
Linux, descrito em :ref:`securitybugs`.
|
||||
|
||||
Nenhum CVE será atribuído automaticamente para problemas de segurança ainda
|
||||
não corrigidos no kernel Linux; a atribuição só acontecerá automaticamente
|
||||
depois que uma correção estiver disponível e aplicada a uma árvore de kernel
|
||||
estável, e ela será rastreada dessa forma pelo ID do commit git da correção
|
||||
original. Se alguém desejar que um CVE seja atribuído antes que um problema
|
||||
seja resolvido com um commit, por favor entre em contato com a equipe de
|
||||
atribuição de CVEs do kernel em <cve@kernel.org> para obter um identificador
|
||||
atribuído a partir de seu lote de identificadores reservados.
|
||||
|
||||
Nenhum CVE será atribuído para qualquer problema encontrado em uma versão do
|
||||
kernel que atualmente não esteja sendo mantida ativamente pela equipe de kernel
|
||||
Stable/LTS. Uma lista dos ramos de kernel atualmente suportados pode ser
|
||||
encontrada em https://kernel.org/releases.html
|
||||
|
||||
Contestações de CVEs atribuídos
|
||||
===============================
|
||||
|
||||
A autoridade para contestar ou modificar um CVE atribuído a uma alteração
|
||||
específica do kernel pertence exclusivamente aos mantenedores do subsistema
|
||||
relevante afetado. Esse princípio garante um alto grau de precisão e
|
||||
responsabilização no relato de vulnerabilidades. Somente esses indivíduos, com
|
||||
profundo conhecimento técnico e conhecimento íntimo do subsistema, podem
|
||||
avaliar de forma eficaz a validade e o escopo de uma vulnerabilidade relatada e
|
||||
determinar sua designação CVE apropriada. Qualquer tentativa de modificar ou
|
||||
contestar um CVE fora dessa autoridade designada pode levar a confusão, relato
|
||||
impreciso e, em última análise, sistemas comprometidos.
|
||||
|
||||
CVEs inválidos
|
||||
==============
|
||||
|
||||
Se um problema de segurança for encontrado em um kernel Linux que é suportado
|
||||
apenas por uma distribuição Linux devido às alterações feitas por essa
|
||||
distribuição, ou porque a distribuição oferece suporte a uma versão do kernel
|
||||
que não é mais uma das versões suportadas pelo kernel.org, então um CVE não
|
||||
pode ser atribuído pela equipe de CVEs do kernel Linux e deve ser solicitado à
|
||||
própria distribuição Linux.
|
||||
|
||||
Qualquer CVE atribuído ao kernel Linux para uma versão de kernel
|
||||
ativamente suportada, por qualquer grupo que não seja a equipe de atribuição de
|
||||
CVEs do kernel, não deve ser tratado como um CVE válido. Por favor, notifique
|
||||
a equipe de atribuição de CVEs do kernel em <cve@kernel.org> para que ela
|
||||
possa trabalhar para invalidar essas entradas por meio do processo de remediação
|
||||
da CNA.
|
||||
|
||||
Aplicabilidade de CVEs específicos
|
||||
==================================
|
||||
|
||||
Como o kernel Linux pode ser usado de múltiplas maneiras, com diversas
|
||||
formas de acesso por usuários externos, ou sem nenhum acesso, a
|
||||
aplicabilidade de qualquer CVE específico cabe ao usuário do Linux determinar;
|
||||
isso não cabe à equipe de atribuição de CVEs. Por favor, não entre em contato
|
||||
conosco para tentar determinar a aplicabilidade de qualquer CVE específico.
|
||||
|
||||
Além disso, como a árvore de códigos-fonte é muito grande, e cada sistema usa
|
||||
apenas um pequeno subconjunto dessa árvore, o usuário do Linux deve estar
|
||||
ciente de que grandes quantidades de CVEs atribuídos não são relevantes para
|
||||
seus sistemas.
|
||||
|
||||
Em resumo, não conhecemos o seu caso de uso e não sabemos quais partes do
|
||||
kernel você usa, portanto não há como determinarmos se um CVE específico é
|
||||
relevante para o seu sistema.
|
||||
|
||||
Como sempre, o melhor é adotar todas as alterações de kernel lançadas, pois
|
||||
elas são testadas em conjunto como um todo unificado por muitos membros da
|
||||
comunidade, e não como alterações individuais selecionadas. Observe também que,
|
||||
para muitos bugs, a solução do problema geral não é encontrada em uma única
|
||||
alteração, mas pela soma de muitas correções umas sobre as outras. Idealmente,
|
||||
CVEs serão atribuídos a todas as correções de todos os problemas, mas às vezes
|
||||
podemos deixar de perceber algumas correções; portanto, presuma que algumas alterações
|
||||
sem um CVE atribuído podem ser relevantes para adotar.
|
||||
422
Documentation/translations/pt_BR/process/deprecated.rst
Normal file
422
Documentation/translations/pt_BR/process/deprecated.rst
Normal file
@@ -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``.
|
||||
@@ -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
|
||||
|
||||
368
Documentation/translations/pt_BR/process/email-clients.rst
Normal file
368
Documentation/translations/pt_BR/process/email-clients.rst
Normal file
@@ -0,0 +1,368 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Informações sobre clientes de email para Linux
|
||||
==============================================
|
||||
|
||||
Git
|
||||
---
|
||||
|
||||
Hoje em dia a maioria dos desenvolvedores usa ``git send-email`` em vez de
|
||||
clientes de email comuns. A página de manual desse comando é bem útil. No lado
|
||||
de quem recebe, os mantenedores usam ``git am`` para aplicar os patches.
|
||||
|
||||
Se você é novo no ``git``, envie seu primeiro patch para si mesmo. Salve-o
|
||||
como texto bruto, incluindo todos os cabeçalhos. Execute ``git am raw_email.txt``
|
||||
e então revise o changelog com ``git log``. Quando isso funcionar, envie o
|
||||
patch para a(s) lista(s) de discussão apropriada(s).
|
||||
|
||||
Preferências Gerais
|
||||
-------------------
|
||||
|
||||
Os patches para o kernel Linux são enviados por email, preferencialmente como
|
||||
texto inline no corpo da mensagem. Alguns mantenedores aceitam anexos, mas,
|
||||
nesse caso, os anexos devem ter o content-type ``text/plain``. Contudo, anexos
|
||||
são, em geral, desaconselhados porque dificultam citar trechos do patch durante
|
||||
o processo de revisão.
|
||||
|
||||
Também é altamente recomendável que você use plain text no corpo do email, tanto
|
||||
para patches quanto para outras mensagens. https://useplaintext.email pode ser
|
||||
útil para obter informações sobre como configurar seu cliente de email preferido,
|
||||
além de listar clientes de email recomendados caso você ainda não tenha preferência.
|
||||
|
||||
Clientes de email usados para patches do kernel Linux devem enviar o texto do
|
||||
patch sem alterações. Por exemplo, eles não devem modificar ou apagar tabs ou
|
||||
espaços, mesmo no início ou no fim das linhas.
|
||||
|
||||
Não envie patches com ``format=flowed``. Isso pode causar quebras de linha
|
||||
inesperadas e indesejadas.
|
||||
|
||||
Não deixe seu cliente de email fazer quebra automática de linha para você.
|
||||
Isso também pode corromper seu patch.
|
||||
|
||||
Clientes de email não devem modificar a codificação do conjunto de caracteres do
|
||||
texto. Patches enviados por email devem usar apenas codificação ASCII ou UTF-8.
|
||||
Se você configurar seu cliente de email para enviar mensagens com codificação
|
||||
UTF-8, você evita alguns possíveis problemas de charset.
|
||||
|
||||
Clientes de email devem gerar e manter "References:" ou "In-Reply-To:"
|
||||
cabeçalhos para que o encadeamento de mensagens não seja quebrado.
|
||||
|
||||
Copiar e colar (ou recortar e colar) geralmente não funciona para patches
|
||||
porque tabs são convertidos em espaços. Usar xclipboard, xclip e/ou xcutsel
|
||||
pode funcionar, mas é melhor testar isso você mesmo ou simplesmente evitar
|
||||
copiar e colar.
|
||||
|
||||
Não use assinaturas PGP/GPG em emails que contenham patches. Isso quebra muitos
|
||||
scripts que leem e aplicam os patches.
|
||||
(Isso deve ser corrigível.)
|
||||
|
||||
É uma boa ideia enviar um patch para si mesmo, salvar a mensagem recebida e
|
||||
aplicá-la com sucesso com o comando 'patch' antes de enviar patches para as
|
||||
listas de discussão do Linux.
|
||||
|
||||
Algumas dicas de clientes de email (MUA)
|
||||
----------------------------------------
|
||||
|
||||
Aqui estão algumas dicas específicas de configuração de MUA para editar e enviar
|
||||
patches para o kernel Linux. Estas dicas não pretendem ser resumos completos da
|
||||
configuração dos pacotes de software.
|
||||
|
||||
Legenda:
|
||||
|
||||
- TUI = Interface de Usuário Baseada em Texto
|
||||
- GUI = Interface Gráfica de Usuário
|
||||
|
||||
Alpine (TUI)
|
||||
************
|
||||
|
||||
Opções de configuração:
|
||||
|
||||
Na seção :menuselection:`Preferências de Envio`:
|
||||
|
||||
- :menuselection:`Não Envie Texto com Quebra de Linha Automática` deve estar ``habilitado``
|
||||
- :menuselection:`Remover Espaços em Branco Antes de Enviar` deve estar ``desabilitado``
|
||||
|
||||
Ao compor a mensagem, o cursor deve ser posicionado onde o patch deverá aparecer,
|
||||
e então pressionar `CTRL-R` permite especificar o arquivo de patch a ser
|
||||
inserido na mensagem.
|
||||
|
||||
Claws Mail (GUI)
|
||||
****************
|
||||
|
||||
Funciona. Algumas pessoas usam isso com sucesso para patches.
|
||||
|
||||
Para inserir um patch, use :menuselection:`Mensagem-->Inserir Arquivo`(`CTRL-I`)
|
||||
ou um editor externo.
|
||||
|
||||
Se o patch inserido precisar ser editado na janela de composição do
|
||||
Claws, a opção "Quebra automática" em
|
||||
:menuselection:`Configuração-->Preferências-->Escrever-->Quebra de linha`
|
||||
deve estar desabilitada.
|
||||
|
||||
Evolution (GUI)
|
||||
***************
|
||||
|
||||
Algumas pessoas usam isso com sucesso para patches.
|
||||
|
||||
Ao compor o e-mail, selecione: Preformatado
|
||||
em :menuselection:`Formatar-->Estilo de Parágrafo-->Preformatado` (`CTRL-7`)
|
||||
ou na barra de ferramentas
|
||||
|
||||
Depois use:
|
||||
:menuselection:`Inserir-->Arquivo de Texto...` (`ALT-N x`)
|
||||
para inserir o patch.
|
||||
|
||||
Você também pode usar ``diff -Nru old.c new.c | xclip``, selecionar
|
||||
:menuselection:`Preformatado`, depois colar com o botão do meio.
|
||||
|
||||
Kmail (GUI)
|
||||
***********
|
||||
|
||||
Algumas pessoas usam o KMail com sucesso para patches.
|
||||
|
||||
A configuração padrão de não compor em HTML é apropriada; não a habilite.
|
||||
|
||||
Ao compor um email, em opções, desmarque “quebra de linha automática”. A única
|
||||
desvantagem é que qualquer texto que você digitar no email não será quebrado
|
||||
automaticamente, então você terá que quebrar manualmente o texto antes do patch.
|
||||
A maneira mais fácil é compor o email com quebra de linha automática habilitado,
|
||||
depois salvá-lo como rascunho. Depois de abri-lo novamente dos rascunhos, ele
|
||||
estará com quebras de linha rígidas e você poderá desmarcar “quebra de linha
|
||||
automática” sem perder a quebra existente.
|
||||
|
||||
No final do seu email, coloque o delimitador de patch comumente usado antes de
|
||||
inserir o patch: três hífens (``---``).
|
||||
|
||||
Então, no menu :menuselection:`Mensagem`, selecione :menuselection:`inserir arquivo`
|
||||
e escolha o seu patch. Como benefício adicional, você pode personalizar a barra
|
||||
de ferramentas de criação de mensagens e colocar o ícone :menuselection:`inserir arquivo` lá.
|
||||
|
||||
Deixe a janela do compositor larga o suficiente para que nenhuma linha seja
|
||||
quebrada. A partir do KMail 1.13.5 (KDE 4.5.4), o KMail aplica quebra de linha
|
||||
ao enviar o email se as linhas quebrarem na janela do compositor. Ter a quebra de
|
||||
linha desativada no menu Opções não é suficiente. Por isso se o seu patch tiver
|
||||
linhas muito longas, você deve deixar a janela do seu compositor bem larga antes
|
||||
de enviar o email. Veja: https://bugs.kde.org/show_bug.cgi?id=174034
|
||||
|
||||
Você pode assinar anexos com GPG com segurança, mas texto em linha é preferido
|
||||
para patches, então não os assine com GPG. Assinar patches que foram inseridos
|
||||
como texto em linha torna mais difícil extraí-los de sua codificação 7 bits.
|
||||
|
||||
Se você absolutamente precisar enviar patches como anexos em vez de inseri-los
|
||||
como texto, clique com o botão direito no anexo e selecione
|
||||
:menuselection:`propriedades`, e destaque :menuselection:`Sugerir exibição automática`
|
||||
para fazer o anexo ser exibido como texto inserido e ficar mais fácil de
|
||||
visualizar.
|
||||
|
||||
Ao salvar patches enviados como texto inserido, selecione o email que contém o
|
||||
patch no painel da lista de mensagens, clique com o botão direito e selecione
|
||||
:menuselection:`salvar como`. Você pode usar o email inteiro sem alterações como
|
||||
patch se ele tiver sido composto corretamente. Emails são salvos como leitura e
|
||||
escrita apenas para o usuário, então você terá que alterar as permissões para
|
||||
torná-los legíveis por grupo e por todos se copiá-los para outro lugar.
|
||||
|
||||
Lotus Notes (GUI)
|
||||
*****************
|
||||
|
||||
Fuja dele.
|
||||
|
||||
IBM Verse (Web GUI)
|
||||
*******************
|
||||
|
||||
Veja Lotus Notes.
|
||||
|
||||
Mutt (TUI)
|
||||
**********
|
||||
|
||||
Muitos desenvolvedores Linux usam ``mutt``, então deve funcionar muito bem.
|
||||
|
||||
O mutt não vem com editor, então qualquer editor que você use deve ser usado de
|
||||
forma que não haja quebras de linha automáticas. A maioria dos editores tem uma
|
||||
opção :menuselection:`Inserir Arquivo` que insere o conteúdo de um arquivo sem
|
||||
alterações.
|
||||
|
||||
Para usar ``vim`` com o mutt::
|
||||
|
||||
set editor="vi"
|
||||
|
||||
Se estiver usando xclip, digite o comando::
|
||||
|
||||
:set paste
|
||||
|
||||
antes do botão do meio ou shift-insert ou use::
|
||||
|
||||
:r filename
|
||||
|
||||
se você quiser incluir o patch inline.
|
||||
(a)ttach funciona bem sem ``set paste``.
|
||||
|
||||
Você também pode gerar patches com ``git format-patch`` e depois usar o Mutt
|
||||
para enviá-los::
|
||||
|
||||
$ mutt -H 0001-some-bug-fix.patch
|
||||
|
||||
Opções de configuração:
|
||||
|
||||
Deve funcionar com as configurações padrão. No entanto, é uma boa ideia definir
|
||||
o ``send_charset`` como::
|
||||
|
||||
set send_charset="us-ascii:utf-8"
|
||||
|
||||
O Mutt é altamente personalizável. Aqui está uma configuração mínima para
|
||||
começar a usar o Mutt para enviar patches pelo Gmail::
|
||||
|
||||
# .muttrc
|
||||
# ================ IMAP ====================
|
||||
set imap_user = 'seuusuario@gmail.com'
|
||||
set imap_pass = 'suasenha'
|
||||
set spoolfile = imaps://imap.gmail.com/INBOX
|
||||
set folder = imaps://imap.gmail.com/
|
||||
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
|
||||
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
|
||||
set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
|
||||
|
||||
# ================ SMTP ====================
|
||||
set smtp_url = "smtp://usuario@smtp.gmail.com:587/"
|
||||
set smtp_pass = $imap_pass
|
||||
set ssl_force_tls = yes # Exige conexão criptografada
|
||||
|
||||
# ================ Composição ====================
|
||||
set editor = `echo \$EDITOR`
|
||||
set edit_headers = yes # Exibe os cabeçalhos ao editar
|
||||
set charset = UTF-8 # valor de $LANG; também usado como
|
||||
# fallback para send_charset
|
||||
# Remetente, endereço de e-mail e linha de assinatura devem
|
||||
# corresponder
|
||||
unset use_domain # porque joe@localhost é constrangedor
|
||||
set realname = "SEU NOME"
|
||||
set from = "usuario@gmail.com"
|
||||
set use_from = yes
|
||||
|
||||
A documentação do Mutt tem muito mais informações:
|
||||
|
||||
https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail
|
||||
|
||||
http://www.mutt.org/doc/manual/
|
||||
|
||||
Pine (TUI)
|
||||
**********
|
||||
|
||||
O Pine já teve alguns problemas de truncamento de espaços em branco no passado,
|
||||
mas isso deve estar todo corrigido agora.
|
||||
|
||||
Use o alpine (sucessor do pine) se possível.
|
||||
|
||||
Opções de configuração:
|
||||
|
||||
- ``quell-flowed-text`` é necessário para versões recentes
|
||||
- a opção ``no-strip-whitespace-before-send`` é necessária
|
||||
|
||||
|
||||
Sylpheed (GUI)
|
||||
**************
|
||||
|
||||
- Funciona bem para inserir texto inline (ou usando anexos).
|
||||
- Permite o uso de um editor externo.
|
||||
- É lento em pastas grandes.
|
||||
- Não fará autenticação TLS SMTP sobre uma conexão não-SSL.
|
||||
- Tem uma barra de régua útil na janela de composição.
|
||||
- Adicionar endereços ao catálogo de endereços não reconhece corretamente o nome
|
||||
de exibição.
|
||||
|
||||
Thunderbird (GUI)
|
||||
*****************
|
||||
|
||||
O Thunderbird é um clone do Outlook que gosta de bagunçar o texto, mas há formas
|
||||
de convencê-lo a se comportar.
|
||||
|
||||
Depois de fazer as modificações, incluindo a instalação das extensões, você
|
||||
precisa reiniciar o Thunderbird.
|
||||
|
||||
- Permitir o uso de um editor externo:
|
||||
|
||||
A forma mais fácil de trabalhar com patches no Thunderbird é usar extensões
|
||||
que abrem seu editor externo favorito.
|
||||
|
||||
Aqui estão alguns exemplos de extensões capazes de fazer isso.
|
||||
|
||||
- "Editor Externo Reativado"
|
||||
|
||||
https://github.com/Frederick888/external-editor-revived
|
||||
|
||||
https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/
|
||||
|
||||
É necessário instalar um "host de mensagens nativas".
|
||||
Leia a wiki, que pode ser encontrada aqui:
|
||||
https://github.com/Frederick888/external-editor-revived/wiki
|
||||
|
||||
- "Editor Externo"
|
||||
|
||||
https://github.com/exteditor/exteditor
|
||||
|
||||
Para isso, baixe e instale a extensão, depois abra a janela de
|
||||
:menuselection:`compor`, adicione um botão para ela usando
|
||||
:menuselection:`Visualizar-->Barras de Ferramentas-->Personalizar...`
|
||||
e então basta clicar no novo botão quando quiser usar o editor externo.
|
||||
|
||||
Observe que o "Editor Externo" exige que seu editor não faça fork, ou seja,
|
||||
o editor não deve retornar antes de fechar. Pode ser necessário passar flags
|
||||
adicionais ou alterar as configurações do seu editor. Principalmente se você
|
||||
estiver usando o gvim, deve passar a opção -f para o gvim colocando
|
||||
``/usr/bin/gvim --nofork"`` (se o binário estiver em ``/usr/bin``) no campo
|
||||
de editor de texto nas configurações de :menuselection:`editor externo`. Se
|
||||
estiver usando outro editor, consulte seu manual para descobrir como fazer isso.
|
||||
|
||||
Para colocar juízo no editor interno, faça o seguinte:
|
||||
|
||||
- Edite as configurações do Thunderbird para que ele não use ``format=flowed``!
|
||||
Vá até a janela principal e encontre o botão do menu suspenso principal.
|
||||
:menuselection:`Menu Principal-->Preferências-->Geral-->Editor de Configurações...`
|
||||
para abrir o editor de registro do Thunderbird.
|
||||
|
||||
- Defina ``mailnews.send_plaintext_flowed`` como ``false``
|
||||
|
||||
- Altere ``mailnews.wraplength`` de ``72`` para ``0`` **ou** instale a
|
||||
extensão "Toggle Line Wrap"
|
||||
|
||||
https://github.com/jan-kiszka/togglelinewrap
|
||||
|
||||
https://addons.thunderbird.net/thunderbird/addon/toggle-line-wrap
|
||||
|
||||
para controlar esse registro dinamicamente.
|
||||
|
||||
- Não escreva mensagens em HTML! Vá até a janela principal
|
||||
:menuselection:`Menu Principal-->Configurações da Conta-->suaconta@servidor.algo-->Composição e Endereçamento`!
|
||||
Lá você pode desabilitar a opção "Compor mensagens em formato HTML".
|
||||
|
||||
- Abra mensagens apenas como texto simples! Vá até a janela principal
|
||||
:menuselection:`Menu Principal-->Visualizar-->Corpo da Mensagem Como-->Texto Simples`!
|
||||
|
||||
TkRat (GUI)
|
||||
***********
|
||||
|
||||
Funciona. Use "Inserir arquivo..." ou um editor externo.
|
||||
|
||||
Gmail (Web GUI)
|
||||
***************
|
||||
|
||||
Não funciona para enviar patches.
|
||||
|
||||
O cliente web do Gmail converte tabulações em espaços automaticamente.
|
||||
|
||||
Ao mesmo tempo, ele quebra linhas a cada 78 caracteres com quebras de linha no
|
||||
estilo CRLF, embora o problema de tab para espaço possa ser resolvido com um
|
||||
editor externo.
|
||||
|
||||
Outro problema é que o Gmail codifica em base64 qualquer mensagem que tenha um
|
||||
caractere não-ASCII. Isso inclui coisas como nomes europeus.
|
||||
|
||||
HacKerMaiL (TUI)
|
||||
****************
|
||||
|
||||
HacKerMaiL (hkml) é uma ferramenta simples de gerenciamento de e-mails baseada
|
||||
em public-inbox que não exige inscrição em listas de discussão. É desenvolvida
|
||||
e mantida pelo mantenedor do DAMON e visa oferecer suporte a fluxos de trabalho
|
||||
de desenvolvimento simples para o DAMON e para subsistemas gerais do kernel.
|
||||
Consulte o README (https://github.com/sjp38/hackermail/blob/master/README.md)
|
||||
para mais detalhes.
|
||||
|
||||
102
Documentation/translations/pt_BR/process/index.rst
Normal file
102
Documentation/translations/pt_BR/process/index.rst
Normal file
@@ -0,0 +1,102 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\renewcommand\thesection*
|
||||
\renewcommand\thesubsection*
|
||||
|
||||
===============================================
|
||||
Trabalhando com a comunidade de desenvolvimento
|
||||
===============================================
|
||||
|
||||
Então você quer ser um desenvolvedor do kernel Linux? Bem-vindo! Embora haja
|
||||
muito a aprender sobre o kernel em um sentido técnico, também é importante
|
||||
aprender como nossa comunidade funciona. A leitura desses documentos tornará
|
||||
muito mais fácil para você ter suas alterações integradas com um mínimo de
|
||||
problemas.
|
||||
|
||||
Uma introdução sobre como funciona o desenvolvimento do kernel
|
||||
--------------------------------------------------------------
|
||||
|
||||
Leia estes documentos primeiro: entender este material facilitará
|
||||
sua entrada na comunidade do kernel.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Como começar <howto>
|
||||
Guia do Processo de Desenvolvimento <development-process>
|
||||
Lista de verificação para submissão de patches do kernel Linux <submit-checklist>
|
||||
|
||||
Ferramentas e guias técnicos para desenvolvedores do kernel
|
||||
-----------------------------------------------------------
|
||||
|
||||
Esta é uma coleção de material com o qual os desenvolvedores do kernel
|
||||
devem estar familiarizados.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Requisitos mínimos <changes>
|
||||
Informações sobre clientes de email para Linux <email-clients>
|
||||
Como aplicar patches <applying-patches>
|
||||
Backporting e resolução de conflitos <backporting>
|
||||
Adicionando uma nova chamada de Sistema <adding-syscalls>
|
||||
Como não Deixar as ioctls malfeitas <botching-up-ioctls>
|
||||
|
||||
Guias de políticas e declarações de desenvolvedores
|
||||
---------------------------------------------------
|
||||
|
||||
Estas são as regras pelas quais tentamos viver na comunidade do kernel
|
||||
(e além).
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Regras de licenciamento <license-rules>
|
||||
Código de Conduta de Compromisso do Colaborador <code-of-conduct>
|
||||
Interpretação do Código de Conduta do Kernel Linux <code-of-conduct-interpretation>
|
||||
Modelos de Maturidade para Contribuição no Kernel Linux <contribution-maturity-model.rst>
|
||||
Declaração sobre Drivers do Kernel <kernel-driver-statement>
|
||||
Estilo de gerenciamento do kernel Linux <management-style>
|
||||
Conclave (Continuidade do projeto) <conclave>
|
||||
|
||||
Lidando com bugs
|
||||
----------------
|
||||
|
||||
Bugs são uma realidade; é importante lidarmos com eles de forma correta.
|
||||
Os documentos abaixo detalham políticas e conselhos em relação ao
|
||||
gerenciamento de bugs e vulnerabilidades.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Falhas de segurança <security-bugs>
|
||||
CVEs <cve>
|
||||
|
||||
Informações para mantenedores
|
||||
-----------------------------
|
||||
|
||||
Como encontrar as pessoas que aceitarão seus patches e manuais úteis para os
|
||||
mantenedores de subsistemas.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Manuais dos mantenedores <maintainer-handbooks>
|
||||
Processo do subsistema de rede (netdev) <maintainer-netdev>
|
||||
Processo do subsistema SoC <maintainer-soc>
|
||||
Conformidade de DTS para SoC <maintainer-soc-clean-dts>
|
||||
Processo do subsistema KVM x86 <maintainer-kvm-x86>
|
||||
|
||||
Outros materiais
|
||||
----------------
|
||||
|
||||
Aqui estão alguns outros guias para a comunidade que são de interesse para
|
||||
a maioria dos desenvolvedores:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Index de documentos do Kernel <kernel-docs>
|
||||
Interfaces, recursos de linguagem, atributos e convenções obsoletos <deprecated>
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
|
||||
265
Documentation/translations/pt_BR/process/management-style.rst
Normal file
265
Documentation/translations/pt_BR/process/management-style.rst
Normal file
@@ -0,0 +1,265 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Estilo de gerenciamento do kernel Linux
|
||||
=======================================
|
||||
|
||||
Este é um documento curto descrevendo o estilo de gerenciamento preferido (ou
|
||||
inventado, dependendo de quem você perguntar) para o kernel do Linux. Ele se
|
||||
destina a espelhar o documento :ref:`process/coding-style.rst <codingstyle>` em
|
||||
algum grau, e foi escrito principalmente para evitar responder [#f1]_ as mesmas
|
||||
(ou semelhantes) perguntas repetidamente.
|
||||
|
||||
Estilo de gerenciamento é muito pessoal e muito mais difícil de quantificar do
|
||||
que simples regras de estilo de codificação, então este documento pode ou não ter
|
||||
qualquer coisa a ver com a realidade. Começou como uma brincadeira, mas isso não
|
||||
significa que não possa ser verdade. Você terá que decidir por si mesmo.
|
||||
|
||||
A propósito, quando falamos sobre "gerente do kernel", trata-se de pessoas líderes
|
||||
técnicas, e não das pessoas que fazem gerenciamento tradicional dentro das empresas.
|
||||
Se você assina pedidos de compra ou tem alguma ideia sobre o orçamento do seu grupo,
|
||||
você quase certamente não é um gerente do kernel. Essas sugestões podem ou não se
|
||||
aplicar a você.
|
||||
|
||||
Primeiro, eu sugeriria comprar "Os Sete Hábitos das Pessoas Altamente Eficazes"
|
||||
e NÃO lê-lo. Queime-o, é um ótimo gesto simbólico.
|
||||
|
||||
.. [#f1] Este documento faz isso não respondendo tanto à pergunta, mas torna
|
||||
dolorosamente óbvio para o questionador que não temos ideia de qual é a resposta.
|
||||
|
||||
De qualquer maneira, aqui vai:
|
||||
|
||||
.. _decisoes:
|
||||
|
||||
1) Decisões
|
||||
-----------
|
||||
|
||||
Todo mundo pensa que os gerentes tomam decisões, e que a tomada de decisões é
|
||||
importante. Quanto maior e mais dolorosa a decisão, maior deve ser o gerente para
|
||||
tomá-la. Isso é muito profundo e óbvio, mas na verdade não é verdade.
|
||||
|
||||
O nome do jogo é **evitar** ter que tomar uma decisão. Em particular, se alguém
|
||||
lhe disser "escolha (a) ou (b), realmente precisamos que você decida sobre isso",
|
||||
você está em apuros como gerente. As pessoas que você gerencia devem conhecer os
|
||||
detalhes melhor do que você, então se elas vierem até você para uma decisão técnica,
|
||||
você está ferrado. Você claramente não é competente para tomar essa decisão por elas.
|
||||
|
||||
(Consequência: Se as pessoas que você gerencia não conhecem os detalhes melhor
|
||||
do que você, você também está ferrado, embora por um motivo totalmente diferente.
|
||||
Isso significa que você está no trabalho errado, e que **elas** deveriam estar
|
||||
gerenciando sua genialidade em vez disso).
|
||||
|
||||
Então o nome do jogo é **evitar** decisões, pelo menos as grandes e dolorosas.
|
||||
Tomar decisões pequenas e sem consequências é bom, e faz você parecer que sabe
|
||||
o que está fazendo, então o que um gerente do kernel precisa fazer é transformar
|
||||
as grandes e dolorosas em pequenas coisas com as quais ninguém realmente se importa.
|
||||
|
||||
Ajuda a perceber que a diferença fundamental entre uma grande decisão e uma pequena
|
||||
é se você pode consertar sua decisão depois. Qualquer decisão pode ser pequena
|
||||
garantindo sempre que, se você estiver errado (e você **vai** estar errado), você
|
||||
sempre pode desfazer o dano mais tarde voltando atrás. De repente, você demonstra
|
||||
o dobro de capacidade como gerente por tomar **duas** decisões inconsequentes
|
||||
- a errada **e** a certa.
|
||||
|
||||
E as pessoas verão isso como verdadeira liderança (*cof cof* besteira *cof cof*).
|
||||
|
||||
Portanto a chave para evitar grandes decisões torna-se apenas evitar fazer coisas
|
||||
que não podem ser desfeitas. Não se deixe encurralar em um canto do qual você não
|
||||
possa escapar. Um rato encurralado pode ser perigoso - um gerente encurralado é
|
||||
apenas lamentável.
|
||||
|
||||
Como ninguém seria estúpido o suficiente para realmente deixar um gerente do kernel
|
||||
ter uma enorme responsabilidade fiscal **de qualquer maneira**, é geralmente
|
||||
bastante fácil voltar atrás. Como você não vai ser capaz de desperdiçar enormes
|
||||
quantidades de dinheiro que você pode não ser capaz de reembolsar, a única coisa que
|
||||
você pode voltar atrás é uma decisão técnica, e lá o retrocesso é muito fácil:
|
||||
apenas diga a todos que você era um imbecil incompetente, peça desculpas e desfaça
|
||||
todo o trabalho inútil em que você fez as pessoas trabalharem no último ano.
|
||||
De repente, a decisão que você tomou há um ano não era uma grande decisão afinal,
|
||||
já que poderia ser facilmente desfeita.
|
||||
|
||||
Acontece que algumas pessoas têm problemas com essa abordagem, por dois motivos:
|
||||
|
||||
- admitir que você foi um idiota é mais difícil do que parece. Todos nós gostamos
|
||||
de manter as aparências, e sair em público para dizer que você estava errado
|
||||
às vezes é muito difícil mesmo.
|
||||
- ter alguém falando que o que você trabalhou no último ano não valeu a pena
|
||||
depois de tudo pode ser difícil para os pobres engenheiros humildes também,
|
||||
e enquanto o **trabalho** real foi fácil de desfazer apenas excluindo-o, você
|
||||
pode ter perdido irrevogavelmente a confiança desse engenheiro. E lembre-se:
|
||||
"irrevogável" era o que tentamos evitar em primeiro lugar, e sua decisão acabou
|
||||
sendo uma grande decisão afinal.
|
||||
|
||||
Felizmente, ambas essas razões podem ser mitigadas efetivamente apenas admitindo
|
||||
de antemão que você não tem a menor ideia, e dizendo às pessoas antes do fato
|
||||
que sua decisão é puramente preliminar, e pode ser a coisa errada. Você deve
|
||||
sempre reservar o direito de mudar de ideia, e fazer com que as pessoas estejam
|
||||
muito **cientes** disso. E é muito mais fácil admitir que você é estúpido quando
|
||||
você ainda não fez a coisa realmente estúpida.
|
||||
|
||||
Então, quando realmente se revela estúpido, as pessoas apenas reviram os olhos
|
||||
e dizem "Ops, não de novo".
|
||||
|
||||
Essa admissão preventiva de incompetência também pode fazer com que as pessoas
|
||||
que realmente fazem o trabalho também pensem duas vezes sobre se vale a pena ou
|
||||
não. Afinal, se **elas** não têm certeza se é uma boa ideia, você com certeza não
|
||||
deve encorajá-las prometendo que o que elas trabalham será incluído. Faça com que
|
||||
elas pelo menos pensem duas vezes antes de embarcar em um grande empreendimento.
|
||||
|
||||
Lembre-se: eles devem saber mais sobre os detalhes do que você, e geralmente já
|
||||
pensam que têm a resposta para tudo. A melhor coisa que você pode fazer como
|
||||
gerente é não incutir confiança, mas sim uma dose saudável de pensamento crítico
|
||||
sobre o que eles fazem.
|
||||
|
||||
A propósito, um outro jeito de evitar uma decisão é simplesmente choramingar "não
|
||||
podemos fazer os dois?" e parecer patético. Confie em mim, funciona. Se não estiver
|
||||
claro qual abordagem é melhor, eles eventualmente descobrirão. A resposta pode
|
||||
acabar sendo que ambas as equipes ficam tão frustradas com a situação que apenas
|
||||
desistem.
|
||||
|
||||
Isso pode soar como uma falha, mas geralmente é um sinal de que havia algo errado
|
||||
com ambos os projetos, e a razão pela qual as pessoas envolvidas não conseguiram
|
||||
decidir foi que ambas estavam erradas. Você acaba saindo por cima, e evitou mais
|
||||
uma decisão que poderia ter estragado.
|
||||
|
||||
2) Pessoas
|
||||
----------
|
||||
|
||||
A maioria das pessoas é idiota, e ser um gerente significa que você terá que lidar
|
||||
com isso, e talvez mais importante, que **elas** terão que lidar com **você**.
|
||||
|
||||
Aconteceu que enquanto é fácil desfazer erros técnicos, não é tão fácil desfazer
|
||||
distúrbios de personalidade. Você só tem que conviver com os deles - e com os seus.
|
||||
|
||||
Entretanto, para se preparar como gerente do kernel, é melhor lembrar de não queimar
|
||||
nenhuma ponte, bombardear nenhum vilarejo inocente ou alienar muitos desenvolvedores
|
||||
do kernel. Acontece que alienar pessoas é bastante fácil, e reverter esse afastamento
|
||||
é difícil. Assim, "alienar" cai imediatamente sob o título de "não reversível",
|
||||
e se torna um não-não de acordo com :ref:`decisoes`.
|
||||
|
||||
Existem apenas algumas regras simples aqui:
|
||||
|
||||
(1) não chame as pessoas de imbecis (pelo menos não em público)
|
||||
(2) aprenda a pedir desculpas quando você esquecer a regra (1)
|
||||
|
||||
O problema com #1 é que é muito fácil de fazer, já que você pode dizer "você é
|
||||
um imbecil" de milhões de maneiras diferentes [#f2]_, às vezes sem nem perceber,
|
||||
e quase sempre com uma convicção ardente de que você está certo.
|
||||
|
||||
E quanto mais convencido você estiver de que está certo (e vamos encarar, você
|
||||
pode chamar praticamente qualquer pessoa de imbecil, e muitas vezes você **vai**
|
||||
estar certo), mais difícil acaba sendo se desculpar depois.
|
||||
|
||||
Para resolver esse problema, você realmente só tem duas opções:
|
||||
|
||||
- fique muito bom em pedir desculpas
|
||||
- espalhe o "amor" de forma tão uniforme que ninguém realmente acabe se sentindo
|
||||
injustamente alvo. Torne-o inventivo o suficiente, e eles podem até se divertir.
|
||||
|
||||
A opção de ser infalivelmente educado realmente não existe. Ninguém confiará em
|
||||
alguém que está claramente escondendo seu verdadeiro caráter.
|
||||
|
||||
.. [#f2] Paul Simon cantou "Fifty Ways to Leave Your Lover", porque francamente,
|
||||
"A Million Ways to Tell a Developer They're a D*ckhead" não soa tão bem. Mas
|
||||
tenho certeza de que ele pensou sobre isso.
|
||||
|
||||
|
||||
3) Pessoas II - o tipo bom
|
||||
--------------------------
|
||||
|
||||
Embora no final das contas a maioria das pessoas seja idiota, a consequência disso
|
||||
é tristemente que você também é, e que enquanto todos nós podemos nos deleitar na
|
||||
segura convicção de que somos melhores do que a pessoa média (vamos encarar, ninguém
|
||||
nunca acredita que é mediano ou abaixo da média), também devemos admitir que não
|
||||
somos a faca mais afiada por aí, e haverá outras pessoas que são menos idiotas
|
||||
do que você.
|
||||
|
||||
Algumas pessoas reagem mal a pessoas inteligentes. Outras se aproveitam delas.
|
||||
|
||||
Tenha certeza de que você, como mantenedor do kernel, está no segundo grupo.
|
||||
Puxe o saco delas, porque são as pessoas que tornarão seu trabalho mais fácil.
|
||||
Em particular, elas serão capazes de tomar suas decisões por você, que é tudo
|
||||
sobre o jogo.
|
||||
|
||||
Então quando você encontrar alguém mais inteligente do que você, apenas siga o
|
||||
fluxo. Suas responsabilidades de gerenciamento tornam-se em grande parte dizer
|
||||
"Parece uma boa ideia - pode ir fundo", ou "Isso parece bom, mas e quanto a xxx?".
|
||||
A segunda versão, em particular, é uma ótima maneira de aprender algo novo sobre
|
||||
"xxx" ou parecer **extra** gerencial ao apontar algo que a pessoa mais inteligente
|
||||
não havia pensado. Em qualquer caso, você vence.
|
||||
|
||||
Uma coisa a se observar é perceber que a grandeza em uma área não se traduz
|
||||
necessariamente em outras áreas. Então você pode instigar as pessoas em direções
|
||||
específicas, mas vamos encarar, elas podem ser boas no que fazem e péssimas em
|
||||
tudo o mais. A boa notícia é que as pessoas tendem a naturalmente voltar para o
|
||||
que são boas, então não é como se você estivesse fazendo algo irreversível quando
|
||||
você **as** instiga em alguma direção, apenas não pressione demais.
|
||||
|
||||
4) Colocando a culpa
|
||||
--------------------
|
||||
|
||||
As coisas vão dar errado, e as pessoas querem alguém para culpar. Pronto, a culpa
|
||||
é sua.
|
||||
|
||||
Não é realmente tão difícil aceitar a culpa, especialmente se as pessoas perceberem
|
||||
que não foi **toda** a sua culpa. O que nos leva à melhor maneira de assumir a
|
||||
culpa: faça isso por outra pessoa. Você se sentirá bem por assumir a culpa, eles
|
||||
se sentirão bem por não serem culpados, e a pessoa que perdeu toda a coleção de
|
||||
pornografia de 36 GB por causa da sua incompetência vai admitir relutantemente que
|
||||
pelo menos você não tentou se esquivar disso.
|
||||
|
||||
Então faça o desenvolvedor que realmente estragou (se você conseguir encontrá-lo)
|
||||
saber **em particular** que ele estragou. Não apenas para que ele possa evitar isso
|
||||
no futuro, mas para que ele saiba que lhe deve uma. E, talvez ainda mais importante,
|
||||
ele provavelmente é a pessoa que pode consertar. Porque, vamos encarar, com certeza
|
||||
não é você.
|
||||
|
||||
Levar a culpa também é o motivo pelo qual você se torna gerente em primeiro lugar.
|
||||
É parte do que faz as pessoas confiarem em você, e permite a você a glória potencial,
|
||||
porque você é quem pode dizer "Eu estraguei". E se você seguiu as regras anteriores,
|
||||
você será muito bom em dizer isso agora.
|
||||
|
||||
5) Coisas para evitar
|
||||
---------------------
|
||||
|
||||
Tem uma coisa que as pessoas odeiam ainda mais do que ser chamado de "idiota", e
|
||||
isso é ser chamado de "idiota" com uma voz moralista. O primeiro você pode se
|
||||
desculpar, o segundo você realmente não terá a chance. Eles provavelmente não
|
||||
estarão mais ouvindo, mesmo que você faça um bom trabalho de outra forma.
|
||||
|
||||
Todos nós pensamos que somos melhores do que qualquer outra pessoa, o que significa
|
||||
que quando alguém posa de superior, isso realmente nos irrita. Você pode ser moral
|
||||
e intelectualmente superior a todos ao seu redor, mas não tente tornar isso muito
|
||||
óbvio, a menos que você realmente **pretenda** irritar alguém [#f3]_.
|
||||
|
||||
Semelhantemente, não seja muito educado ou sutil sobre as coisas. A educação
|
||||
facilmente acaba indo longe demais e escondendo o problema, e como dizem, "Na
|
||||
internet, ninguém pode ouvir você sendo sutil". Use um grande objeto contundente
|
||||
para martelar o ponto, porque você realmente não pode depender das pessoas
|
||||
entenderem o seu ponto de outra forma.
|
||||
|
||||
Um pouco de humor pode ajudar a amortecer tanto a franqueza quanto a moralização.
|
||||
Ir além do limite a ponto de ser ridículo pode transmitir um ponto sem tornar
|
||||
doloroso para o destinatário, que apenas pensa que você está sendo bobo. Isso pode
|
||||
ajudar a superar o bloqueio mental pessoal que todos nós temos sobre críticas.
|
||||
|
||||
.. [#f3] Dica: grupos de discussão na internet que não estão diretamente relacionados
|
||||
ao seu trabalho são ótimas maneiras de descarregar suas frustrações nos outros.
|
||||
Escreva posts insultuosos com sarcasmo apenas para entrar em uma boa discussão
|
||||
de vez em quando, e você se sentirá aliviado. Só não faça sujeira muito perto
|
||||
de casa (ou seja, não crie problemas onde isso possa afetar sua vida pessoal).
|
||||
|
||||
6) Por que eu?
|
||||
--------------
|
||||
|
||||
Já que a sua maior responsabilidade parece ser assumir a culpa pelos erros de outras
|
||||
pessoas, e tornar dolorosamente óbvio para todos os outros que você é incompetente,
|
||||
a pergunta óbvia se torna: por que fazer isso em primeiro lugar?
|
||||
|
||||
Primeiramente, embora você possa ou não receber adolescentes gritando (meninas ou
|
||||
meninos, não vamos ser preconceituosos ou sexistas aqui) batendo na porta do seu
|
||||
camarim, você **vai** receber uma imensa sensação de realização pessoal por estar
|
||||
"no comando". Não importa o fato de que você realmente está liderando tentando
|
||||
acompanhar todos os outros e correndo atrás deles o mais rápido que puder. Todos
|
||||
ainda vão pensar que você é a pessoa no comando.
|
||||
|
||||
É um ótimo trabalho se você conseguir aguentar.
|
||||
368
Documentation/translations/pt_BR/process/security-bugs.rst
Normal file
368
Documentation/translations/pt_BR/process/security-bugs.rst
Normal file
@@ -0,0 +1,368 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Falhas de segurança
|
||||
===================
|
||||
|
||||
Os desenvolvedores do kernel Linux levam a segurança muito a sério. Como tal,
|
||||
gostaríamos de saber quando uma falha de segurança é encontrada para que ela
|
||||
possa ser corrigida e divulgada o mais rápido possível.
|
||||
|
||||
Preparando seu relatório
|
||||
------------------------
|
||||
|
||||
Como em qualquer relatório de bug, um relatório de falha de segurança exige
|
||||
muito trabalho de análise por parte dos desenvolvedores, portanto, quanto mais
|
||||
informações você puder compartilhar sobre o problema, melhor. Por favor, revise
|
||||
o procedimento descrito em Documentation/admin-guide/reporting-issues.rst se
|
||||
você não tiver certeza sobre quais informações são úteis. As seguintes
|
||||
informações são absolutamente necessárias em **qualquer** relatório de falha de
|
||||
segurança:
|
||||
|
||||
* **versão do kernel afetada**: sem indicação de versão, seu relatório não
|
||||
será processado. Uma parte significativa dos relatórios é de bugs que já
|
||||
foram corrigidos, portanto, é extremamente importante que as
|
||||
vulnerabilidades sejam verificadas em versões recentes (árvore de
|
||||
desenvolvimento ou a versão estável mais recente), pelo menos verificando
|
||||
se o código não mudou desde a versão onde foi detectado.
|
||||
|
||||
* **descrição do problema**: uma descrição detalhada do problema, com rastros
|
||||
mostrando sua manifestação, e por que você considera o comportamento
|
||||
observado como um problema no Kernel, é necessária.
|
||||
|
||||
* **reproduzir**: os desenvolvedores precisarão ser capazes de reproduzir o
|
||||
problema para considerar uma correção como eficaz. Isso inclui tanto uma
|
||||
maneira de acionar o problema quanto uma maneira de confirmar que ele
|
||||
ocorre. Será necessário um reprodutor com dependências de baixa
|
||||
complexidade (código-fonte, script de shell, sequência de instruções,
|
||||
imagem de sistema de arquivos, etc). Executáveis apenas binários não são
|
||||
aceitos. Exploits funcionais são extremamente úteis e não serão divulgados
|
||||
sem o consentimento do relator, a menos que já sejam públicos. Por
|
||||
definição, se um problema não pode ser reproduzido, ele não é explorável,
|
||||
portanto, não é um bug de segurança.
|
||||
|
||||
* **condições**: se o bug depender de certas opções de configuração, sysctls,
|
||||
permissões, temporização, modificações de código, etc., estas devem ser
|
||||
indicadas.
|
||||
|
||||
Além disso, as seguintes informações são altamente desejáveis:
|
||||
|
||||
* **localização suspeita do bug**: os nomes dos arquivos e funções onde
|
||||
se suspeita que o bug esteja presente são muito importantes, pelo menos
|
||||
para ajudar a encaminhar o relatório aos mantenedores apropriados. Quando
|
||||
não for possível (por exemplo, "o sistema trava toda vez que executo este
|
||||
comando"), a equipe de segurança ajudará a identificar a origem do bug.
|
||||
|
||||
* **uma proposta de correção**: os relatores de bugs que analisaram a causa
|
||||
de uma falha no código-fonte quase sempre têm uma ideia precisa de como
|
||||
corrigi-lo, porque passaram muito tempo estudando o problema e suas
|
||||
implicações. Propor uma correção testada poupará muito tempo dos
|
||||
mantenedores, mesmo que a correção acabe não sendo a correta, pois ajuda a
|
||||
entender o bug. Ao propor uma correção testada, por favor, formate-a
|
||||
sempre de uma maneira que possa ser mesclada imediatamente (consulte
|
||||
Documentation/process/submitting-patches.rst). Isso evitará algumas trocas
|
||||
de mensagens caso ela seja aceita, e você receberá o crédito por
|
||||
encontrar e corrigir o problema. Observe que, neste caso, apenas uma tag
|
||||
``Signed-off-by:`` é necessária, sem ``Reported-by:`` quando o relator e
|
||||
o autor forem a mesma pessoa.
|
||||
|
||||
* **mitigações**: com muita frequência, durante a análise de um bug,
|
||||
surgem algumas maneiras de mitigar o problema. É útil compartilhá-las,
|
||||
pois podem ser úteis para manter os usuários finais protegidos durante o
|
||||
tempo que levam para aplicar a correção.
|
||||
|
||||
O que se qualifica como um bug de segurança
|
||||
-------------------------------------------
|
||||
|
||||
É importante que a maioria dos bugs seja tratada publicamente, de modo a
|
||||
envolver o maior público possível e encontrar a melhor solução. Por natureza,
|
||||
bugs que são tratados em discussões fechadas entre um pequeno conjunto de
|
||||
participantes têm menos probabilidade de produzir a melhor correção possível
|
||||
(por exemplo, risco de perder casos de uso válidos, capacidades de testes
|
||||
limitadas).
|
||||
|
||||
Acontece que a maioria dos bugs relatados por meio da equipe de segurança são
|
||||
apenas bugs comuns que foram qualificados incorretamente como bugs de segurança
|
||||
devido à falta de conhecimento do modelo de ameaças do kernel Linux, conforme
|
||||
descrito em Documentation/process/threat-model.rst, e deveriam ter sido
|
||||
enviados através dos canais normais descritos em
|
||||
Documentation/admin-guide/reporting-issues.rst
|
||||
|
||||
A lista de segurança existe para bugs urgentes que concedem a um atacante uma
|
||||
capacidade que ele não deveria ter em um sistema de produção corretamente
|
||||
configurado, e que podem ser facilmente explorados, representando uma ameaça
|
||||
iminente para muitos usuários. Antes de relatar, considere se o problema
|
||||
realmente ultrapassa um limite de confiança em tal sistema.
|
||||
|
||||
**Se você recorreu a assistência de IA para identificar um bug, você deve
|
||||
tratá-lo como público**. Embora você possa ter motivos válidos para acreditar
|
||||
que não seja, a experiência da equipe de segurança mostra que os bugs
|
||||
descobertos desta forma surgem sistematicamente e de forma simultânea entre
|
||||
múltiplos pesquisadores, frequentemente no mesmo dia. Neste caso, não
|
||||
compartilhe publicamente um reprodutor, pois isso poderia causar danos não
|
||||
intencionais; apenas mencione que um está disponível e os mantenedores poderão
|
||||
solicitá-lo privadamente se precisarem.
|
||||
|
||||
Se você não tiver certeza se um problema se qualifica, opte por relatar de
|
||||
forma privada: a equipe de segurança prefere triar um relatório limítrofe
|
||||
a perder uma vulnerabilidade real. Relatar bugs comuns na lista de segurança,
|
||||
no entanto, não faz com que eles andem mais rápido e consome a capacidade de
|
||||
triagem de que outros relatórios precisam.
|
||||
|
||||
Identificando contatos
|
||||
----------------------
|
||||
|
||||
A maneira mais eficaz de relatar um bug de segurança é enviá-lo diretamente
|
||||
aos mantenedores do subsistema afetado e Cc: para a equipe de segurança do
|
||||
kernel Linux. Não o envie para uma lista pública nesta fase, a menos que você
|
||||
tenha bons motivos para considerar o problema como público ou trivial de ser
|
||||
descoberto (por exemplo, resultado de uma ferramenta automatizada de varredura
|
||||
de vulnerabilidades amplamente disponível que possa ser repetida por qualquer
|
||||
pessoa, ou o uso de ferramentas baseadas em IA).
|
||||
|
||||
Se você estiver enviando um relatório de problemas que afetam várias partes no
|
||||
kernel, mesmo que sejam problemas bastante semelhantes, envie mensagens
|
||||
individuais (pense que os mantenedores não trabalharão todos nos problemas ao
|
||||
mesmo tempo). A única exceção é quando um problema diz respeito a partes
|
||||
intimamente relacionadas, mantidas pelo exato mesmo subconjunto de
|
||||
mantenedores, e espera-se que essas partes sejam todas corrigidas de uma só vez
|
||||
pelo mesmo commit; então pode ser aceitável relatá-las de uma vez.
|
||||
|
||||
Uma dificuldade para a maioria dos relatores de primeira viagem é descobrir a
|
||||
lista certa de destinatários para enviar um relatório. No kernel Linux, todos
|
||||
os mantenedores oficiais são confiáveis, portanto as consequências de incluir
|
||||
acidentalmente o mantenedor errado são apenas um pequeno ruído para essa
|
||||
pessoa, ou seja, nada dramático. Sendo assim, um método adequado para descobrir
|
||||
a lista de mantenedores (o qual os oficiais de segurança do kernel usam) é
|
||||
contar com o script get_maintainer.pl, ajustado para relatar apenas
|
||||
mantenedores. Este script, quando recebe um nome de arquivo, procurará por seu
|
||||
caminho no arquivo MAINTAINERS para deduzir uma lista hierárquica de
|
||||
mantenedores relevantes. Chamá-lo pela primeira vez com o nível mais refinado
|
||||
de filtragem retornará, na maioria das vezes, uma lista curta de mantenedores
|
||||
deste arquivo específico::
|
||||
|
||||
$ ./scripts/get_maintainer.pl --no-l --no-r --pattern-depth 1 \
|
||||
drivers/example.c
|
||||
Developer One <dev1@example.com> (maintainer:example driver)
|
||||
Developer Two <dev2@example.org> (maintainer:example driver)
|
||||
|
||||
Estes dois mantenedores devem então receber a mensagem. Se o comando não
|
||||
retornar nada, isso significa que o arquivo afetado faz parte de um subsistema
|
||||
mais amplo, portanto devemos ser menos específicos::
|
||||
|
||||
$ ./scripts/get_maintainer.pl --no-l --no-r drivers/example.c
|
||||
Developer One <dev1@example.com> (maintainer:example subsystem)
|
||||
Developer Two <dev2@example.org> (maintainer:example subsystem)
|
||||
Developer Three <dev3@example.com> (maintainer:example subsystem [GENERAL])
|
||||
Developer Four <dev4@example.org> (maintainer:example subsystem [GENERAL])
|
||||
|
||||
Aqui, escolher os primeiros, mais específicos, é suficiente. Quando a lista for
|
||||
longa, é possível produzir uma lista de endereços de e-mail delimitada por
|
||||
vírgulas em uma única linha adequada para o uso no campo TO: de um cliente de
|
||||
e-mail como este::
|
||||
|
||||
$ ./scripts/get_maintainer.pl --no-tree --no-l --no-r --no-n --m \
|
||||
--no-git-fallback --no-substatus --no-rolestats --no-multiline \
|
||||
--pattern-depth 1 drivers/example.c
|
||||
dev1@example.com, dev2@example.org
|
||||
|
||||
ou este para a lista mais ampla::
|
||||
|
||||
$ ./scripts/get_maintainer.pl --no-tree --no-l --no-r --no-n --m \
|
||||
--no-git-fallback --no-substatus --no-rolestats --no-multiline \
|
||||
drivers/example.c
|
||||
dev1@example.com, dev2@example.org, dev3@example.com, dev4@example.org
|
||||
|
||||
Se a esta altura você ainda estiver enfrentando dificuldades para identificar
|
||||
os mantenedores corretos, e apenas neste caso, é possível enviar seu
|
||||
relatório apenas para a equipe de segurança do kernel Linux. Sua mensagem
|
||||
será triada e você receberá instruções sobre quem contatar, se necessário.
|
||||
Sua mensagem poderá igualmente ser encaminhada como está para os mantenedores
|
||||
relevantes.
|
||||
|
||||
Uso responsável de IA para encontrar bugs
|
||||
-----------------------------------------
|
||||
|
||||
Uma fração significativa dos relatórios de bugs enviados à equipe de segurança
|
||||
é, na verdade, o resultado de revisões de código assistidas por ferramentas de
|
||||
IA. Embora isso possa ser um meio eficiente de encontrar bugs em áreas
|
||||
raramente exploradas, causa uma sobrecarga nos mantenedores, que às vezes são
|
||||
forçados a ignorar tais relatórios devido à sua má qualidade ou precisão. Sendo
|
||||
assim, os relatores devem ter um cuidado especial com vários pontos que tendem
|
||||
a tornar esses relatórios desnecessariamente difíceis de lidar:
|
||||
|
||||
* **Comprimento**: Os relatórios gerados por IA tendem a ser excessivamente
|
||||
longos, contendo várias seções e detalhes em excesso. Isso dificulta a
|
||||
identificação de informações importantes, como arquivos afetados, versões e
|
||||
impacto. Por favor, certifique-se de que um resumo claro do problema e
|
||||
todos os detalhes críticos sejam apresentados primeiro. Não exija que os
|
||||
engenheiros de triagem analisem várias páginas de texto. Configure suas
|
||||
ferramentas para produzir relatórios concisos e em estilo humano.
|
||||
|
||||
* **Formatação**: A maioria dos relatórios gerados por IA está repleta de
|
||||
tags Markdown. Essas decorações complicam a busca por informações
|
||||
importantes e não sobrevivem aos processos de citação envolvidos no
|
||||
encaminhamento ou nas respostas. Por favor, sempre converta seu relatório
|
||||
para texto simples sem quaisquer decorações de formatação antes de
|
||||
enviá-lo.
|
||||
|
||||
* **Avaliação de Impacto**: Muitos relatórios gerados por IA carecem de uma
|
||||
compreensão do modelo de ameaças do kernel (consulte
|
||||
Documentation/process/threat-model.rst) e fazem de tudo para inventar
|
||||
consequências teóricas. Isso adiciona ruído e complica a triagem. Por
|
||||
favor, limite-se a fatos verificáveis (por exemplo, "este bug permite que
|
||||
qualquer usuário obtenha CAP_NET_ADMIN") sem enumerar implicações
|
||||
especulativas. Faça com que sua ferramenta leia esta documentação como
|
||||
parte do processo de avaliação.
|
||||
|
||||
* **Reproduzidor**: As ferramentas baseadas em IA são frequentemente capazes
|
||||
de gerar reproduzidores. Por favor, certifique-se sempre de que sua
|
||||
ferramenta forneça um e teste-o exaustivamente. Se o reproduzidor não
|
||||
funcionar, ou se a ferramenta não puder produzir um, a validade do
|
||||
relatório deve ser seriamente questionada. Observe que, como o relatório
|
||||
será postado em uma lista pública, o reproduzidor só deve ser compartilhado
|
||||
mediante solicitação dos mantenedores.
|
||||
|
||||
* **Propor uma Correção:** muitas ferramentas de IA são na verdade melhores
|
||||
em escrever código do que em avaliá-lo. Por favor, peça à sua ferramenta
|
||||
para propor uma correção e teste-a antes de relatar o problema.
|
||||
Se a correção não puder ser testada porque depende de hardware raro ou de
|
||||
protocolos de rede quase extintos, é provável que o problema não seja um
|
||||
bug de segurança. Em qualquer caso, se uma correção for proposta, ela deve
|
||||
aderir a Documentation/process/submitting-patches.rst e incluir uma tag
|
||||
'Fixes:' designando o commit que introduziu o bug.
|
||||
|
||||
A falha em considerar estes pontos expõe seu relatório ao risco de ser
|
||||
ignorado.
|
||||
|
||||
Use o bom senso ao avaliar o relatório. Se o arquivo afetado não tiver sido
|
||||
alterado por mais de um ano e for mantido por um único indivíduo, é provável
|
||||
que o uso tenha diminuído e os usuários expostos sejam virtualmente
|
||||
inexistentes (por exemplo, drivers para hardware muito antigo, sistemas de
|
||||
arquivos obsoletos). Nesses casos, não há necessidade de consumir o tempo de
|
||||
um mantenedor com um relatório sem importância. Se o problema for claramente
|
||||
trivial e publicamente detectável, você deve relatá-lo diretamente às listas
|
||||
de discussão públicas.
|
||||
|
||||
Enviando o relatório
|
||||
--------------------
|
||||
|
||||
Os relatórios devem ser enviados exclusivamente por e-mail. Por favor, use um
|
||||
endereço de e-mail funcional, de preferência o mesmo que você deseja que
|
||||
apareça nas tags ``Reported-by``, se houver. Se não tiver certeza, envie o seu
|
||||
relatório para você mesmo primeiro.
|
||||
|
||||
A equipe de segurança e os mantenedores quase sempre exigem informações
|
||||
adicionais além das fornecidas inicialmente em um relatório e dependem de uma
|
||||
colaboração ativa e eficiente com o relator para realizar testes adicionais
|
||||
(por exemplo, verificar versões, opções de configuração, mitigações ou
|
||||
patches). Antes de entrar em contato com a equipe de segurança, o relator deve
|
||||
certificar-se de que está disponível para explicar suas descobertas, participar
|
||||
de discussões e executar testes adicionais. Relatórios nos quais o relator não
|
||||
responde prontamente ou não consegue discutir suas descobertas de forma eficaz
|
||||
podem ser abandonados se a comunicação não melhorar rapidamente.
|
||||
|
||||
O relatório deve ser enviado aos mantenedores. Se houver dois ou menos
|
||||
destinatários em sua mensagem, você também deve sempre colocar em Cc: a equipe
|
||||
de segurança do kernel Linux, que garantirá que a mensagem seja entregue às
|
||||
pessoas corretas e poderá auxiliar pequenas equipes de mantenedores com
|
||||
processos com os quais eles possam não estar familiarizados. Para equipes
|
||||
maiores, coloque em Cc: a equipe de segurança do kernel Linux em seus primeiros
|
||||
relatórios ou ao buscar ajuda específica, como ao reenviar uma mensagem que não
|
||||
obteve resposta dentro de uma semana. Assim que você se sentir confortável com
|
||||
o processo após alguns relatórios, não será mais necessário colocar a lista de
|
||||
segurança em Cc: ao enviar para equipes grandes. A equipe de segurança do
|
||||
kernel Linux pode ser contatada por e-mail em security@kernel.org. Esta é uma
|
||||
lista privada de oficiais de segurança que ajudarão a verificar o relatório de
|
||||
bug e auxiliarão os desenvolvedores que trabalham em uma correção. É possível
|
||||
que a equipe de segurança traga ajuda extra de mantenedores da área para
|
||||
entender e corrigir a vulnerabilidade de segurança.
|
||||
|
||||
Por favor, envie e-mails em **texto simples** sem anexos, sempre que possível.
|
||||
É muito mais difícil ter uma discussão com citações de contexto sobre um
|
||||
problema complexo se todos os detalhes estiverem ocultos em anexos. Pense nisso
|
||||
como uma :doc:`regular path submission </../../../process/submitting-patches>`
|
||||
(mesmo que você ainda não tenha um patch): descreva o problema e o impacto,
|
||||
liste as etapas de reprodução e siga com uma proposta de correção, tudo em
|
||||
texto simples. Relatórios formatados em Markdown, HTML e RST são
|
||||
particularmente malvistos, pois são bastante difíceis de ler por humanos e
|
||||
incentivam o uso de visualizadores dedicados, às vezes online, o que por
|
||||
definição não é aceitável para um relatório de segurança confidencial. Note
|
||||
que alguns clientes de e-mail tendem a corromper a formatação de texto simples
|
||||
por padrão; por favor, consulte Documentation/process/email-clients.rst para
|
||||
mais informações.
|
||||
|
||||
Divulgação e informações sob embargo
|
||||
------------------------------------
|
||||
|
||||
A lista de segurança não é um canal de divulgação. Para isso, veja Coordenação
|
||||
abaixo.
|
||||
|
||||
Assim que uma correção robusta for desenvolvida, o processo de lançamento é
|
||||
iniciado. Correções para bugs publicamente conhecidos são lançadas
|
||||
imediatamente.
|
||||
|
||||
Embora nossa preferência seja lançar correções para bugs publicamente não
|
||||
divulgados assim que estiverem disponíveis, isso pode ser adiado a pedido do
|
||||
relator ou de uma parte afetada por até 7 dias corridos a partir do início do
|
||||
processo de lançamento, com uma extensão excepcional para 14 dias corridos se
|
||||
for acordado que a criticidade do bug exige mais tempo. O único motivo válido
|
||||
para adiar a publicação de uma correção é acomodar a logística de QA e as
|
||||
implantações em larga escala que exigem coordenação de lançamento.
|
||||
|
||||
Embora as informações sob embargo possam ser compartilhadas com indivíduos de
|
||||
confiança para o desenvolvimento de uma correção, tais informações não serão
|
||||
publicadas juntamente com a correção ou em qualquer outro canal de divulgação
|
||||
sem a permissão do relator. Isso inclui, mas não se limita ao relatório de bug
|
||||
original e discussões de acompanhamento (se houver), exploits, informações de
|
||||
CVE ou a identidade do relator.
|
||||
|
||||
Em outras palavras, nosso único interesse é fazer com que os bugs sejam
|
||||
corrigidos. Todas as outras informações enviadas à lista de segurança e
|
||||
quaisquer discussões de acompanhamento do relatório são tratadas de forma
|
||||
confidencial, mesmo após o término do embargo, perpetuamente.
|
||||
|
||||
Coordenação com outros grupos
|
||||
-----------------------------
|
||||
|
||||
Embora a equipe de segurança do kernel se concentre exclusivamente em corrigir
|
||||
bugs, outros grupos se concentram em corrigir problemas em distribuições e em
|
||||
coordenar a divulgação entre fornecedores de sistemas operacionais. A
|
||||
coordenação é geralmente tratada pela lista de discussão "linux-distros" e a
|
||||
divulgação pela lista pública "oss-security", ambas intimamente relacionadas
|
||||
e apresentadas na wiki da linux-distros:
|
||||
https://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||
|
||||
Por favor, note que as respectivas políticas e regras são diferentes, já que as
|
||||
3 listas buscam objetivos distintos. A coordenação entre a equipe de segurança
|
||||
do kernel e outras equipes é difícil porque para a equipe de segurança do
|
||||
kernel os embargos ocasionais (sujeitos a um número máximo de dias permitido)
|
||||
começam a partir da disponibilidade de uma correção, enquanto para a
|
||||
"linux-distros" eles começam a partir da postagem inicial na lista,
|
||||
independentemente da disponibilidade de uma correção.
|
||||
|
||||
Como tal, a equipe de segurança do kernel recomenda fortemente que, como
|
||||
relator de um potencial problema de segurança, você NÃO contate a lista de
|
||||
discussão "linux-distros" ATÉ que uma correção seja aceita pelos mantenedores
|
||||
do código afetado e você tenha lido a página wiki das distribuições acima e
|
||||
compreendido totalmente os requisitos que o contato com a "linux-distros"
|
||||
imporá a você e à comunidade do kernel. Isso também significa que, em geral,
|
||||
não faz sentido colocar ambas as listas em Cc: ao mesmo tempo, exceto talvez
|
||||
para coordenação se e enquanto uma correção aceita ainda não tiver sido
|
||||
mesclada. Em outras palavras, até que uma correção seja aceita, não coloque
|
||||
em Cc: "linux-distros", e após ela ser mesclada, não coloque em Cc: a equipe
|
||||
de segurança do kernel.
|
||||
|
||||
Atribuição de CVE
|
||||
-----------------
|
||||
|
||||
A equipe de segurança não atribui CVEs, nem os exigimos para relatórios ou
|
||||
correções, pois isso pode complicar desnecessariamente o processo e adiar o
|
||||
tratamento do bug. Se um relator desejar que um identificador CVE seja
|
||||
atribuído para um problema confirmado, ele pode entrar em contato com a
|
||||
:doc:`kernel CVE assignment team<../../../process/cve>` para obter um.
|
||||
|
||||
Acordo de não divulgação
|
||||
------------------------
|
||||
|
||||
A equipe de segurança do kernel Linux não é um órgão formal e, portanto, é
|
||||
incapaz de celebrar quaisquer acordos de não divulgação.
|
||||
145
Documentation/translations/pt_BR/process/submit-checklist.rst
Normal file
145
Documentation/translations/pt_BR/process/submit-checklist.rst
Normal file
@@ -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.
|
||||
@@ -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/下的文件相同。
|
||||
|
||||
|
||||
@@ -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
|
||||
* sysctl/index
|
||||
* features
|
||||
|
||||
本节介绍CPU漏洞及其缓解措施。
|
||||
内核管理接口的重要组成部分是 /proc 和 sysfs 虚拟文件系统;这些文档描述了如何
|
||||
与之交互。
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cputopology
|
||||
|
||||
Todolist:
|
||||
|
||||
* sysfs-rules
|
||||
* sysctl/index
|
||||
* abi
|
||||
|
||||
安全相关文档:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Todolist:
|
||||
|
||||
* hw-vuln/index
|
||||
* LSM/index
|
||||
* perf-security
|
||||
|
||||
下面的一组文档,针对的是试图跟踪问题和bug的用户。
|
||||
|
||||
内核启动
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
bootconfig
|
||||
|
||||
Todolist:
|
||||
|
||||
* kernel-parameters
|
||||
* efi-stub
|
||||
* initrd
|
||||
|
||||
|
||||
追踪和识别问题
|
||||
--------------
|
||||
|
||||
以下是一组面向试图追踪特定问题和 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
|
||||
|
||||
这是应用程序开发人员感兴趣的章节的开始。可以在这里找到涵盖内核ABI各个
|
||||
方面的文档。
|
||||
|
||||
Todolist:
|
||||
|
||||
* sysfs-rules
|
||||
|
||||
本手册的其余部分包括各种指南,介绍如何根据您的喜好配置内核的特定行为。
|
||||
核心内核子系统
|
||||
--------------
|
||||
|
||||
这些文档描述了核心内核管理接口,这些接口几乎在任何系统上都值得关注。
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
bootconfig
|
||||
clearing-warn-once
|
||||
cpu-load
|
||||
cputopology
|
||||
lockup-watchdogs
|
||||
numastat
|
||||
unicode
|
||||
sysrq
|
||||
mm/index
|
||||
module-signing
|
||||
numastat
|
||||
|
||||
Todolist:
|
||||
|
||||
* cgroup-v2
|
||||
* cgroup-v1/index
|
||||
* namespaces/index
|
||||
* pm/index
|
||||
* syscall-user-dispatch
|
||||
|
||||
|
||||
对非原生二进制格式的支持。请注意,其中一些文档相当 **古老**。
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Todolist:
|
||||
|
||||
* binfmt-misc
|
||||
* java
|
||||
* mono
|
||||
|
||||
|
||||
块设备和文件系统管理
|
||||
--------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Todolist:
|
||||
|
||||
* bcache
|
||||
* binderfs
|
||||
* blockdev/index
|
||||
* cifs/index
|
||||
* device-mapper/index
|
||||
* ext4
|
||||
* filesystem-monitoring
|
||||
* nfs/index
|
||||
* iostats
|
||||
* jfs
|
||||
* md
|
||||
* ufs
|
||||
* xfs
|
||||
|
||||
|
||||
专用设备指南
|
||||
------------
|
||||
|
||||
如何在 Linux 系统中配置硬件。
|
||||
|
||||
.. 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
|
||||
* nfs/index
|
||||
* gpio/index
|
||||
* highuid
|
||||
* hw_random
|
||||
* initrd
|
||||
* iostats
|
||||
* java
|
||||
* jfs
|
||||
* kernel-per-CPU-kthreads
|
||||
* 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`
|
||||
|
||||
250
Documentation/translations/zh_CN/admin-guide/module-signing.rst
Normal file
250
Documentation/translations/zh_CN/admin-guide/module-signing.rst
Normal file
@@ -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`` 确保每个配置具有不同的内核发布字
|
||||
符串。
|
||||
@@ -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``
|
||||
|
||||
@@ -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。
|
||||
|
||||
最后,如果检测时没有 warning 和 error 需要被处理或者您只有一个补丁,请跳
|
||||
过下面这个步骤,否则请重新导出补丁制作封面::
|
||||
如果您有多个补丁,请按补丁集中补丁顺序对每个补丁重复上述流程,一次只处理
|
||||
一个,不要一次 git am 多个补丁。全部处理完毕后再重新导出并再次测试。
|
||||
|
||||
为补丁集制作封面
|
||||
----------------
|
||||
|
||||
对于单个补丁,请跳过本节。
|
||||
|
||||
如果您有多个补丁,则需要为补丁集制作一份封面,即 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 -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 的建议调整段落顺序
|
||||
|
||||
Documentation/translations/zh_CN/xxx.rst | 100 ++++++
|
||||
1 file changed, 100 insertions(+)
|
||||
|
||||
后续迭代 v3、v4 …… 时,新的 changelog 放在最上面,旧的保留在下方,按
|
||||
从新到旧的顺序叠加。例如 v3 补丁的 --- 下方::
|
||||
|
||||
---
|
||||
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 处编写相较于上个版本,您做了哪些改动。
|
||||
打开 0 号补丁,在 BLURB HERE 处写明整组补丁相较 v1 的总体改动,格式
|
||||
同上面的单个补丁 changelog 示例。如果某个补丁需要单独说明,可在该
|
||||
补丁文件的 --- 分割线下方追加单个补丁的 changelog。最后执行::
|
||||
|
||||
然后执行::
|
||||
|
||||
git send-email v2* --to <maintainer email addr> --cc <others addr>
|
||||
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/ 上找到您
|
||||
的邮件,请联系您的网络管理员帮忙解决。
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
``arm64`` Maintained 仅小端序。
|
||||
``loongarch`` Maintained \-
|
||||
``riscv`` Maintained 仅 ``riscv64``,且仅限 LLVM/Clang。
|
||||
``s390`` Maintained 必须禁用 ``CONFIG_EXPOLINE``。
|
||||
``um`` Maintained \-
|
||||
``x86`` Maintained 仅 ``x86_64``。
|
||||
============= ================ ==============================================
|
||||
|
||||
@@ -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 文档包括集成搜索、链接项(如类型、函数、常量)、源代码等。
|
||||
它们可以在以下地址阅读:
|
||||
|
||||
http://kernel.org/
|
||||
https://rust.docs.kernel.org
|
||||
|
||||
对于 linux-next,请参阅:
|
||||
|
||||
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
|
||||
|
||||
@@ -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的名字。
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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()计算每个性能域在给定的利用率条件
|
||||
下的预期能量消耗。
|
||||
|
||||
下面详细介绍一个优化能量消耗的任务放置决策的例子。
|
||||
|
||||
@@ -97,7 +97,7 @@ ARCH_OPTIONAL_KERNEL_RWX时的默认设置。
|
||||
--------------------
|
||||
|
||||
对于64位系统,一种消除许多系统调用最简单的方法是构建时不启用
|
||||
CONFIG_CONPAT。然而,这种情况通常不可行。
|
||||
CONFIG_COMPAT。然而,这种情况通常不可行。
|
||||
|
||||
“seccomp”系统为用户空间提供了一种可选功能,提供了一种减少可供
|
||||
运行中进程使用内核入口点数量的方法。这限制了可以访问内核代码
|
||||
|
||||
@@ -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發佈一起發
|
||||
布。
|
||||
|
||||
|
||||
@@ -7738,6 +7738,7 @@ F: include/linux/dmi.h
|
||||
DOCUMENTATION
|
||||
M: Jonathan Corbet <corbet@lwn.net>
|
||||
R: Shuah Khan <skhan@linuxfoundation.org>
|
||||
R: Randy Dunlap <rdunlap@infradead.org>
|
||||
L: linux-doc@vger.kernel.org
|
||||
S: Maintained
|
||||
P: Documentation/doc-guide/maintainer-profile.rst
|
||||
@@ -27569,10 +27570,10 @@ F: kernel/trace/trace_osnoise.c
|
||||
F: kernel/trace/trace_sched_wakeup.c
|
||||
|
||||
TRADITIONAL CHINESE DOCUMENTATION
|
||||
M: Hu Haowen <2023002089@link.tyut.edu.cn>
|
||||
M: Chen-Yu Yeh <chenyou910331@gmail.com>
|
||||
M: Weijie Yuan <wy@wyuan.org>
|
||||
M: Dongliang Mu <dzm91@hust.edu.cn>
|
||||
S: Maintained
|
||||
W: https://github.com/srcres258/linux-doc
|
||||
T: git https://github.com/srcres258/linux-doc.git doc-zh-tw
|
||||
F: Documentation/translations/zh_TW/
|
||||
|
||||
TRIGGER SOURCE
|
||||
|
||||
18
README
18
README
@@ -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
|
||||
|
||||
@@ -3124,11 +3124,12 @@ sub process {
|
||||
}
|
||||
}
|
||||
|
||||
# Assisted-by uses AGENT_NAME:MODEL_VERSION format, not email
|
||||
# Assisted-by uses a free-form value (e.g. "LLM"), not an
|
||||
# email address, so skip the email format checks below.
|
||||
if ($sign_off =~ /^Assisted-by:/i) {
|
||||
if ($email !~ /^\S+:\S+/) {
|
||||
if ($email =~ /^\s*$/) {
|
||||
WARN("BAD_SIGN_OFF",
|
||||
"Assisted-by expects 'AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]' format\n" . $herecurr);
|
||||
"Assisted-by requires a value\n" . $herecurr);
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ while (<IN>) {
|
||||
# Check if exists, evaluating wildcards
|
||||
next if (grep -e, glob("$ref $fulref"));
|
||||
|
||||
# Accept relative Documentation patches for tools/
|
||||
# Accept relative Documentation paths for tools/
|
||||
if ($f =~ m/tools/) {
|
||||
my $path = $f;
|
||||
$path =~ s,(.*)/.*,$1,;
|
||||
|
||||
@@ -99,9 +99,9 @@ class SphinxBuilder:
|
||||
|
||||
def get_path(self, path, use_cwd=False, abs_path=False):
|
||||
"""
|
||||
Ancillary routine to handle patches the right way, as shell does.
|
||||
Ancillary routine to handle paths the right way, as shell does.
|
||||
|
||||
It first expands "~" and "~user". Then, if patch is not absolute,
|
||||
It first expands "~" and "~user". Then, if path is not absolute,
|
||||
join self.srctree. Finally, if requested, convert to abspath.
|
||||
"""
|
||||
|
||||
@@ -219,6 +219,15 @@ class SphinxBuilder:
|
||||
self.kernelrelease = os.environ.get("KERNELRELEASE", "unknown")
|
||||
self.pdflatex = os.environ.get("PDFLATEX", "xelatex")
|
||||
|
||||
#
|
||||
# Add localversion* to kernelversion if present
|
||||
#
|
||||
for file in glob(os.environ["srctree"] + "/localversion*"):
|
||||
if not file.endswith(".orig"):
|
||||
with open(file, 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
self.kernelversion += text
|
||||
|
||||
#
|
||||
# Kernel main Makefile defines a PYTHON3 variable whose default is
|
||||
# "python3". When set to a different value, it allows running a
|
||||
|
||||
@@ -65,8 +65,7 @@ class AbiRegex(AbiParser):
|
||||
(re.compile(r"\[[^\]]+\]"), "\\\\w\xf7"),
|
||||
|
||||
(re.compile(r"XX+"), "\\\\w\xf7"),
|
||||
(re.compile(r"([^A-Z])[XYZ]([^A-Z])"), "\\1\\\\w\xf7\\2"),
|
||||
(re.compile(r"([^A-Z])[XYZ]$"), "\\1\\\\w\xf7"),
|
||||
(re.compile(r"(?<![A-Z])[XYZ](?![A-Z])"), "\\\\w\xf7"),
|
||||
(re.compile(r"_[AB]_"), "_\\\\w\xf7_"),
|
||||
|
||||
# Recover [0-9] type of patterns
|
||||
@@ -155,7 +154,7 @@ class AbiRegex(AbiParser):
|
||||
if self.search_string:
|
||||
if what.find(self.search_string) >= 0:
|
||||
print(f"What: {what}")
|
||||
except re.PatternError:
|
||||
except re.error:
|
||||
self.log.warning("Ignoring '%s' as it produced an invalid regex:\n"
|
||||
" '%s'", what, new)
|
||||
|
||||
@@ -194,7 +193,7 @@ class AbiRegex(AbiParser):
|
||||
|
||||
try:
|
||||
self.re_string = re.compile(self.search_string)
|
||||
except re.PatternError as e:
|
||||
except re.error as e:
|
||||
msg = f"{self.search_string} is not a valid regular expression"
|
||||
raise ValueError(msg) from e
|
||||
|
||||
@@ -223,9 +222,9 @@ class AbiRegex(AbiParser):
|
||||
for r, s in self.re_whats:
|
||||
try:
|
||||
new = r.sub(s, new)
|
||||
except re.PatternError as e:
|
||||
except re.error as e:
|
||||
# Help debugging troubles with new regexes
|
||||
raise re.PatternError(f"{e}\nwhile re.sub('{r.pattern}', {s}, str)") from e
|
||||
raise re.error(f"{e}\nwhile re.sub('{r.pattern}', {s}, str)") from e
|
||||
|
||||
v["regex"].append(new)
|
||||
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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,51 @@ 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 ""
|
||||
|
||||
joined_suggestions = "', '".join(suggestions)
|
||||
return f"(did you mean one of: '{joined_suggestions}')"
|
||||
|
||||
def check_sections(self, ln, decl_name, decl_type):
|
||||
"""
|
||||
Check for errors inside sections, emitting warnings if not found
|
||||
@@ -566,12 +612,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 +638,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):
|
||||
"""
|
||||
@@ -791,7 +839,7 @@ class KernelDoc:
|
||||
|
||||
if self.entry.identifier != declaration_name:
|
||||
self.emit_msg(ln, f"expecting prototype for {decl_type} {self.entry.identifier}. "
|
||||
f"Prototype was for {decl_type} {declaration_name} instead\n")
|
||||
f"Prototype was for {decl_type} {declaration_name} instead")
|
||||
return
|
||||
#
|
||||
# Go through the list of members applying all of our transformations.
|
||||
@@ -1108,7 +1156,7 @@ class KernelDoc:
|
||||
|
||||
if self.entry.identifier != declaration_name:
|
||||
self.emit_msg(ln,
|
||||
f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n")
|
||||
f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead")
|
||||
return
|
||||
|
||||
self.create_parameter_list(ln, 'function', args, ',', declaration_name)
|
||||
@@ -1128,7 +1176,7 @@ class KernelDoc:
|
||||
|
||||
if self.entry.identifier != declaration_name:
|
||||
self.emit_msg(ln,
|
||||
f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n")
|
||||
f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead")
|
||||
return
|
||||
|
||||
self.output_declaration('typedef', declaration_name,
|
||||
|
||||
@@ -90,6 +90,7 @@ class CTransforms:
|
||||
(CMatch("__(?:re)?alloc_size"), ""),
|
||||
(CMatch("__diagnose_as"), ""),
|
||||
(CMatch("DECL_BUCKET_PARAMS"), r"\1, \2"),
|
||||
(CMatch("DEFINE_IDTENTRY_IRQ"), r"static void \1(struct pt_regs *regs, u32 vector)"),
|
||||
(CMatch("__cond_acquires"), ""),
|
||||
(CMatch("__cond_releases"), ""),
|
||||
(CMatch("__acquires"), ""),
|
||||
|
||||
Reference in New Issue
Block a user