A fairly normal cycle for documentation stuff. We have a new

document on perf security, more Italian translations, more
 improvements to the memory-management docs, improvements to the
 pathname lookup documentation, and the usual array of smaller
 fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQFDBAABCAAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAlwmSPkPHGNvcmJldEBs
 d24ubmV0AAoJEBdDWhNsDH5Y9ZoH/joPnMFykOxS0SmdfI7Z+F4EiJct/ZwF9bHx
 T673T0RC30IgnUXGmBl5OtktfWqVh9aGqHOGwgh65ybp2QvzemdP0k6Lu6RtwNk9
 6LfkpvuUb8FzaQmCHnSMzMSDmXtZUw3Z/mOjCBcQtfGAsUULNT08xl+Dr+gwWIWt
 H+gPEEP+MCXTOQO1jm2dHOHW8NGm6XOijMTpOxp/pkoEY5tUxkVB1T//8EeX7LVh
 c1QHzFrufE3bmmubCLtIuyVqZbm/V5l6rHREDQ46fnH/G9fM4gojzsrAL/Y2m4bt
 E4y0XJHycjLMRDimAnYhbPm1ryTFAX1lNzHP3M/EF6Heqx8YHAk=
 =vtwu
 -----END PGP SIGNATURE-----

Merge tag 'docs-5.0' of git://git.lwn.net/linux

Pull documentation update from Jonathan Corbet:
 "A fairly normal cycle for documentation stuff. We have a new document
  on perf security, more Italian translations, more improvements to the
  memory-management docs, improvements to the pathname lookup
  documentation, and the usual array of smaller fixes.

  As is often the case, there are a few reaches outside of
  Documentation/ to adjust kerneldoc comments"

* tag 'docs-5.0' of git://git.lwn.net/linux: (38 commits)
  docs: improve pathname-lookup document structure
  configfs: fix wrong name of struct in documentation
  docs/mm-api: link slab_common.c to "The Slab Cache" section
  slab: make kmem_cache_create{_usercopy} description proper kernel-doc
  doc:process: add links where missing
  docs/core-api: make mm-api.rst more structured
  x86, boot: documentation whitespace fixup
  Documentation: devres: note checking needs when converting
  doc🇮🇹 add some process/* translations
  doc🇮🇹 fixes in process/1.Intro
  Documentation: convert path-lookup from markdown to resturctured text
  Documentation/admin-guide: update admin-guide index.rst
  Documentation/admin-guide: introduce perf-security.rst file
  scripts/kernel-doc: Fix struct and struct field attribute processing
  Documentation: dev-tools: Fix typos in index.rst
  Correct gen_init_cpio tool's documentation
  Document /proc/pid PID reuse behavior
  Documentation: update path-lookup.md for parallel lookups
  Documentation: Use "while" instead of "whilst"
  dmaengine: Add mailing list address to the documentation
  ...
This commit is contained in:
Linus Torvalds 2018-12-29 11:21:49 -08:00
commit 3868772b99
119 changed files with 6694 additions and 660 deletions

View File

@ -31,14 +31,13 @@
#define YBLANK 38 #define YBLANK 38
#define XOFFSET 8 #define XOFFSET 8
#define XPULSE 144 #define XPULSE 144
#define YOFFSET (63+3) #define YOFFSET 3
#define YPULSE (63+6) #define YPULSE 6
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux XGA" #define TIMING_NAME "Linux XGA"
#define ESTABLISHED_TIMING2_BITS 0x08 /* Bit 3 -> 1024x768 @60 Hz */ #define ESTABLISHED_TIMING2_BITS 0x08 /* Bit 3 -> 1024x768 @60 Hz */
#define HSYNC_POL 0 #define HSYNC_POL 0
#define VSYNC_POL 0 #define VSYNC_POL 0
#define CRC 0x55
#include "edid.S" #include "edid.S"

View File

@ -31,14 +31,13 @@
#define YBLANK 42 #define YBLANK 42
#define XOFFSET 48 #define XOFFSET 48
#define XPULSE 112 #define XPULSE 112
#define YOFFSET (63+1) #define YOFFSET 1
#define YPULSE (63+3) #define YPULSE 3
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux SXGA" #define TIMING_NAME "Linux SXGA"
/* No ESTABLISHED_TIMINGx_BITS */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0xa0
#include "edid.S" #include "edid.S"

View File

@ -31,14 +31,13 @@
#define YBLANK 50 #define YBLANK 50
#define XOFFSET 64 #define XOFFSET 64
#define XPULSE 192 #define XPULSE 192
#define YOFFSET (63+1) #define YOFFSET 1
#define YPULSE (63+3) #define YPULSE 3
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux UXGA" #define TIMING_NAME "Linux UXGA"
/* No ESTABLISHED_TIMINGx_BITS */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x9d
#include "edid.S" #include "edid.S"

View File

@ -31,14 +31,13 @@
#define YBLANK 39 #define YBLANK 39
#define XOFFSET 104 #define XOFFSET 104
#define XPULSE 176 #define XPULSE 176
#define YOFFSET (63+3) #define YOFFSET 3
#define YPULSE (63+6) #define YPULSE 6
#define DPI 96 #define DPI 96
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux WSXGA" #define TIMING_NAME "Linux WSXGA"
/* No ESTABLISHED_TIMINGx_BITS */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x26
#include "edid.S" #include "edid.S"

View File

@ -31,14 +31,13 @@
#define YBLANK 45 #define YBLANK 45
#define XOFFSET 88 #define XOFFSET 88
#define XPULSE 44 #define XPULSE 44
#define YOFFSET (63+4) #define YOFFSET 4
#define YPULSE (63+5) #define YPULSE 5
#define DPI 96 #define DPI 96
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux FHD" #define TIMING_NAME "Linux FHD"
/* No ESTABLISHED_TIMINGx_BITS */ /* No ESTABLISHED_TIMINGx_BITS */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0x05
#include "edid.S" #include "edid.S"

View File

@ -28,14 +28,13 @@
#define YBLANK 28 #define YBLANK 28
#define XOFFSET 40 #define XOFFSET 40
#define XPULSE 128 #define XPULSE 128
#define YOFFSET (63+1) #define YOFFSET 1
#define YPULSE (63+4) #define YPULSE 4
#define DPI 72 #define DPI 72
#define VFREQ 60 /* Hz */ #define VFREQ 60 /* Hz */
#define TIMING_NAME "Linux SVGA" #define TIMING_NAME "Linux SVGA"
#define ESTABLISHED_TIMING1_BITS 0x01 /* Bit 0: 800x600 @ 60Hz */ #define ESTABLISHED_TIMING1_BITS 0x01 /* Bit 0: 800x600 @ 60Hz */
#define HSYNC_POL 1 #define HSYNC_POL 1
#define VSYNC_POL 1 #define VSYNC_POL 1
#define CRC 0xc2
#include "edid.S" #include "edid.S"

View File

@ -45,14 +45,5 @@ EDID:
#define YPIX vdisp #define YPIX vdisp
#define YBLANK vtotal-vdisp #define YBLANK vtotal-vdisp
#define YOFFSET (63+(vsyncstart-vdisp)) #define YOFFSET vsyncstart-vdisp
#define YPULSE (63+(vsyncend-vsyncstart)) #define YPULSE vsyncend-vsyncstart
The CRC value in the last line
#define CRC 0x55
also is a bit tricky. After a first version of the binary data set is
created, it must be checked with the "edid-decode" utility which will
most probably complain about a wrong CRC. Fortunately, the utility also
displays the correct CRC which must then be inserted into the source
file. After the make procedure is repeated, the EDID data set is ready
to be used.

View File

@ -15,10 +15,21 @@ clean:
%.o: %.S %.o: %.S
@cc -c $^ @cc -c $^
%.bin: %.o %.bin.nocrc: %.o
@objcopy -Obinary $^ $@ @objcopy -Obinary $^ $@
%.bin.ihex: %.o %.crc: %.bin.nocrc
@list=$$(for i in `seq 1 127`; do head -c$$i $^ | tail -c1 \
| hexdump -v -e '/1 "%02X+"'; done); \
echo "ibase=16;100-($${list%?})%100" | bc >$@
%.p: %.crc %.S
@cc -c -DCRC="$$(cat $*.crc)" -o $@ $*.S
%.bin: %.p
@objcopy -Obinary $^ $@
%.bin.ihex: %.p
@objcopy -Oihex $^ $@ @objcopy -Oihex $^ $@
@dos2unix $@ 2>/dev/null @dos2unix $@ 2>/dev/null

View File

@ -47,9 +47,11 @@
#define mfgname2id(v1,v2,v3) \ #define mfgname2id(v1,v2,v3) \
((((v1-'@')&0x1f)<<10)+(((v2-'@')&0x1f)<<5)+((v3-'@')&0x1f)) ((((v1-'@')&0x1f)<<10)+(((v2-'@')&0x1f)<<5)+((v3-'@')&0x1f))
#define swap16(v1) ((v1>>8)+((v1&0xff)<<8)) #define swap16(v1) ((v1>>8)+((v1&0xff)<<8))
#define lsbs2(v1,v2) (((v1&0x0f)<<4)+(v2&0x0f))
#define msbs2(v1,v2) ((((v1>>8)&0x0f)<<4)+((v2>>8)&0x0f)) #define msbs2(v1,v2) ((((v1>>8)&0x0f)<<4)+((v2>>8)&0x0f))
#define msbs4(v1,v2,v3,v4) \ #define msbs4(v1,v2,v3,v4) \
(((v1&0x03)>>2)+((v2&0x03)>>4)+((v3&0x03)>>6)+((v4&0x03)>>8)) ((((v1>>8)&0x03)<<6)+(((v2>>8)&0x03)<<4)+\
(((v3>>4)&0x03)<<2)+((v4>>4)&0x03))
#define pixdpi2mm(pix,dpi) ((pix*25)/dpi) #define pixdpi2mm(pix,dpi) ((pix*25)/dpi)
#define xsize pixdpi2mm(XPIX,DPI) #define xsize pixdpi2mm(XPIX,DPI)
#define ysize pixdpi2mm(YPIX,DPI) #define ysize pixdpi2mm(YPIX,DPI)
@ -200,9 +202,9 @@ y_msbs: .byte msbs2(YPIX,YBLANK)
x_snc_off_lsb: .byte XOFFSET&0xff x_snc_off_lsb: .byte XOFFSET&0xff
/* Horizontal sync pulse width pixels 8 lsbits (0-1023) */ /* Horizontal sync pulse width pixels 8 lsbits (0-1023) */
x_snc_pls_lsb: .byte XPULSE&0xff x_snc_pls_lsb: .byte XPULSE&0xff
/* Bits 7-4 Vertical sync offset lines 4 lsbits -63) /* Bits 7-4 Vertical sync offset lines 4 lsbits (0-63)
Bits 3-0 Vertical sync pulse width lines 4 lsbits -63) */ Bits 3-0 Vertical sync pulse width lines 4 lsbits (0-63) */
y_snc_lsb: .byte ((YOFFSET-63)<<4)+(YPULSE-63) y_snc_lsb: .byte lsbs2(YOFFSET, YPULSE)
/* Bits 7-6 Horizontal sync offset pixels 2 msbits /* Bits 7-6 Horizontal sync offset pixels 2 msbits
Bits 5-4 Horizontal sync pulse width pixels 2 msbits Bits 5-4 Horizontal sync pulse width pixels 2 msbits
Bits 3-2 Vertical sync offset lines 2 msbits Bits 3-2 Vertical sync offset lines 2 msbits

View File

@ -1,3 +1,4 @@
.. _admin_devices:
Linux allocated devices (4.x+ version) Linux allocated devices (4.x+ version)
====================================== ======================================

View File

@ -110,8 +110,8 @@ If your query set is big, you can batch them too::
~# cat query-batch-file > <debugfs>/dynamic_debug/control ~# cat query-batch-file > <debugfs>/dynamic_debug/control
A another way is to use wildcard. The match rule support ``*`` (matches Another way is to use wildcards. The match rule supports ``*`` (matches
zero or more characters) and ``?`` (matches exactly one character).For zero or more characters) and ``?`` (matches exactly one character). For
example, you can match all usb drivers:: example, you can match all usb drivers::
~# echo "file drivers/usb/* +p" > <debugfs>/dynamic_debug/control ~# echo "file drivers/usb/* +p" > <debugfs>/dynamic_debug/control
@ -258,7 +258,7 @@ this boot parameter for debugging purposes.
If ``foo`` module is not built-in, ``foo.dyndbg`` will still be processed at If ``foo`` module is not built-in, ``foo.dyndbg`` will still be processed at
boot time, without effect, but will be reprocessed when module is boot time, without effect, but will be reprocessed when module is
loaded later. ``dyndbg_query=`` and bare ``dyndbg=`` are only processed at loaded later. ``ddebug_query=`` and bare ``dyndbg=`` are only processed at
boot. boot.
@ -301,7 +301,7 @@ The ``dyndbg`` option is a "fake" module parameter, which means:
For ``CONFIG_DYNAMIC_DEBUG`` kernels, any settings given at boot-time (or For ``CONFIG_DYNAMIC_DEBUG`` kernels, any settings given at boot-time (or
enabled by ``-DDEBUG`` flag during compilation) can be disabled later via enabled by ``-DDEBUG`` flag during compilation) can be disabled later via
the sysfs interface if the debug messages are no longer needed:: the debugfs interface if the debug messages are no longer needed::
echo "module module_name -p" > <debugfs>/dynamic_debug/control echo "module module_name -p" > <debugfs>/dynamic_debug/control

View File

@ -76,6 +76,7 @@ configure specific aspects of kernel behavior to your liking.
thunderbolt thunderbolt
LSM/index LSM/index
mm/index mm/index
perf-security
.. only:: subproject and html .. only:: subproject and html

View File

@ -331,7 +331,7 @@
APC and your system crashes randomly. APC and your system crashes randomly.
apic= [APIC,X86] Advanced Programmable Interrupt Controller apic= [APIC,X86] Advanced Programmable Interrupt Controller
Change the output verbosity whilst booting Change the output verbosity while booting
Format: { quiet (default) | verbose | debug } Format: { quiet (default) | verbose | debug }
Change the amount of debugging information output Change the amount of debugging information output
when initialising the APIC and IO-APIC components. when initialising the APIC and IO-APIC components.

View File

@ -4,13 +4,13 @@
Concepts overview Concepts overview
================= =================
The memory management in Linux is complex system that evolved over the The memory management in Linux is a complex system that evolved over the
years and included more and more functionality to support variety of years and included more and more functionality to support a variety of
systems from MMU-less microcontrollers to supercomputers. The memory systems from MMU-less microcontrollers to supercomputers. The memory
management for systems without MMU is called ``nommu`` and it management for systems without an MMU is called ``nommu`` and it
definitely deserves a dedicated document, which hopefully will be definitely deserves a dedicated document, which hopefully will be
eventually written. Yet, although some of the concepts are the same, eventually written. Yet, although some of the concepts are the same,
here we assume that MMU is available and CPU can translate a virtual here we assume that an MMU is available and a CPU can translate a virtual
address to a physical address. address to a physical address.
.. contents:: :local: .. contents:: :local:
@ -21,10 +21,10 @@ Virtual Memory Primer
The physical memory in a computer system is a limited resource and The physical memory in a computer system is a limited resource and
even for systems that support memory hotplug there is a hard limit on even for systems that support memory hotplug there is a hard limit on
the amount of memory that can be installed. The physical memory is not the amount of memory that can be installed. The physical memory is not
necessary contiguous, it might be accessible as a set of distinct necessarily contiguous; it might be accessible as a set of distinct
address ranges. Besides, different CPU architectures, and even address ranges. Besides, different CPU architectures, and even
different implementations of the same architecture have different view different implementations of the same architecture have different views
how these address ranges defined. of how these address ranges are defined.
All this makes dealing directly with physical memory quite complex and All this makes dealing directly with physical memory quite complex and
to avoid this complexity a concept of virtual memory was developed. to avoid this complexity a concept of virtual memory was developed.
@ -48,8 +48,8 @@ appropriate kernel configuration option.
Each physical memory page can be mapped as one or more virtual Each physical memory page can be mapped as one or more virtual
pages. These mappings are described by page tables that allow pages. These mappings are described by page tables that allow
translation from virtual address used by programs to real address in translation from a virtual address used by programs to the physical
the physical memory. The page tables organized hierarchically. memory address. The page tables are organized hierarchically.
The tables at the lowest level of the hierarchy contain physical The tables at the lowest level of the hierarchy contain physical
addresses of actual pages used by the software. The tables at higher addresses of actual pages used by the software. The tables at higher
@ -121,8 +121,8 @@ Nodes
Many multi-processor machines are NUMA - Non-Uniform Memory Access - Many multi-processor machines are NUMA - Non-Uniform Memory Access -
systems. In such systems the memory is arranged into banks that have systems. In such systems the memory is arranged into banks that have
different access latency depending on the "distance" from the different access latency depending on the "distance" from the
processor. Each bank is referred as `node` and for each node Linux processor. Each bank is referred to as a `node` and for each node Linux
constructs an independent memory management subsystem. A node has it's constructs an independent memory management subsystem. A node has its
own set of zones, lists of free and used pages and various statistics own set of zones, lists of free and used pages and various statistics
counters. You can find more details about NUMA in counters. You can find more details about NUMA in
:ref:`Documentation/vm/numa.rst <numa>` and in :ref:`Documentation/vm/numa.rst <numa>` and in
@ -149,9 +149,9 @@ for program's stack and heap or by explicit calls to mmap(2) system
call. Usually, the anonymous mappings only define virtual memory areas call. Usually, the anonymous mappings only define virtual memory areas
that the program is allowed to access. The read accesses will result that the program is allowed to access. The read accesses will result
in creation of a page table entry that references a special physical in creation of a page table entry that references a special physical
page filled with zeroes. When the program performs a write, regular page filled with zeroes. When the program performs a write, a regular
physical page will be allocated to hold the written data. The page physical page will be allocated to hold the written data. The page
will be marked dirty and if the kernel will decide to repurpose it, will be marked dirty and if the kernel decides to repurpose it,
the dirty page will be swapped out. the dirty page will be swapped out.
Reclaim Reclaim
@ -181,8 +181,8 @@ pressure.
The process of freeing the reclaimable physical memory pages and The process of freeing the reclaimable physical memory pages and
repurposing them is called (surprise!) `reclaim`. Linux can reclaim repurposing them is called (surprise!) `reclaim`. Linux can reclaim
pages either asynchronously or synchronously, depending on the state pages either asynchronously or synchronously, depending on the state
of the system. When system is not loaded, most of the memory is free of the system. When the system is not loaded, most of the memory is free
and allocation request will be satisfied immediately from the free and allocation requests will be satisfied immediately from the free
pages supply. As the load increases, the amount of the free pages goes pages supply. As the load increases, the amount of the free pages goes
down and when it reaches a certain threshold (high watermark), an down and when it reaches a certain threshold (high watermark), an
allocation request will awaken the ``kswapd`` daemon. It will allocation request will awaken the ``kswapd`` daemon. It will
@ -190,7 +190,7 @@ asynchronously scan memory pages and either just free them if the data
they contain is available elsewhere, or evict to the backing storage they contain is available elsewhere, or evict to the backing storage
device (remember those dirty pages?). As memory usage increases even device (remember those dirty pages?). As memory usage increases even
more and reaches another threshold - min watermark - an allocation more and reaches another threshold - min watermark - an allocation
will trigger the `direct reclaim`. In this case allocation is stalled will trigger `direct reclaim`. In this case allocation is stalled
until enough memory pages are reclaimed to satisfy the request. until enough memory pages are reclaimed to satisfy the request.
Compaction Compaction
@ -200,7 +200,7 @@ As the system runs, tasks allocate and free the memory and it becomes
fragmented. Although with virtual memory it is possible to present fragmented. Although with virtual memory it is possible to present
scattered physical pages as virtually contiguous range, sometimes it is scattered physical pages as virtually contiguous range, sometimes it is
necessary to allocate large physically contiguous memory areas. Such necessary to allocate large physically contiguous memory areas. Such
need may arise, for instance, when a device driver requires large need may arise, for instance, when a device driver requires a large
buffer for DMA, or when THP allocates a huge page. Memory `compaction` buffer for DMA, or when THP allocates a huge page. Memory `compaction`
addresses the fragmentation issue. This mechanism moves occupied pages addresses the fragmentation issue. This mechanism moves occupied pages
from the lower part of a memory zone to free pages in the upper part from the lower part of a memory zone to free pages in the upper part
@ -208,15 +208,16 @@ of the zone. When a compaction scan is finished free pages are grouped
together at the beginning of the zone and allocations of large together at the beginning of the zone and allocations of large
physically contiguous areas become possible. physically contiguous areas become possible.
Like reclaim, the compaction may happen asynchronously in ``kcompactd`` Like reclaim, the compaction may happen asynchronously in the ``kcompactd``
daemon or synchronously as a result of memory allocation request. daemon or synchronously as a result of a memory allocation request.
OOM killer OOM killer
========== ==========
It may happen, that on a loaded machine memory will be exhausted. When It is possible that on a loaded machine memory will be exhausted and the
the kernel detects that the system runs out of memory (OOM) it invokes kernel will be unable to reclaim enough memory to continue to operate. In
`OOM killer`. Its mission is simple: all it has to do is to select a order to save the rest of the system, it invokes the `OOM killer`.
task to sacrifice for the sake of the overall system health. The
selected task is killed in a hope that after it exits enough memory The `OOM killer` selects a task to sacrifice for the sake of the overall
will be freed to continue normal operation. system health. The selected task is killed in a hope that after it exits
enough memory will be freed to continue normal operation.

View File

@ -0,0 +1,97 @@
.. _perf_security:
Perf Events and tool security
=============================
Overview
--------
Usage of Performance Counters for Linux (perf_events) [1]_ , [2]_ , [3]_ can
impose a considerable risk of leaking sensitive data accessed by monitored
processes. The data leakage is possible both in scenarios of direct usage of
perf_events system call API [2]_ and over data files generated by Perf tool user
mode utility (Perf) [3]_ , [4]_ . The risk depends on the nature of data that
perf_events performance monitoring units (PMU) [2]_ collect and expose for
performance analysis. Having that said perf_events/Perf performance monitoring
is the subject for security access control management [5]_ .
perf_events/Perf access control
-------------------------------
To perform security checks, the Linux implementation splits processes into two
categories [6]_ : a) privileged processes (whose effective user ID is 0, referred
to as superuser or root), and b) unprivileged processes (whose effective UID is
nonzero). Privileged processes bypass all kernel security permission checks so
perf_events performance monitoring is fully available to privileged processes
without access, scope and resource restrictions.
Unprivileged processes are subject to a full security permission check based on
the process's credentials [5]_ (usually: effective UID, effective GID, and
supplementary group list).
Linux divides the privileges traditionally associated with superuser into
distinct units, known as capabilities [6]_ , which can be independently enabled
and disabled on per-thread basis for processes and files of unprivileged users.
Unprivileged processes with enabled CAP_SYS_ADMIN capability are treated as
privileged processes with respect to perf_events performance monitoring and
bypass *scope* permissions checks in the kernel.
Unprivileged processes using perf_events system call API is also subject for
PTRACE_MODE_READ_REALCREDS ptrace access mode check [7]_ , whose outcome
determines whether monitoring is permitted. So unprivileged processes provided
with CAP_SYS_PTRACE capability are effectively permitted to pass the check.
Other capabilities being granted to unprivileged processes can effectively
enable capturing of additional data required for later performance analysis of
monitored processes or a system. For example, CAP_SYSLOG capability permits
reading kernel space memory addresses from /proc/kallsyms file.
perf_events/Perf unprivileged users
-----------------------------------
perf_events/Perf *scope* and *access* control for unprivileged processes is
governed by perf_event_paranoid [2]_ setting:
-1:
Impose no *scope* and *access* restrictions on using perf_events performance
monitoring. Per-user per-cpu perf_event_mlock_kb [2]_ locking limit is
ignored when allocating memory buffers for storing performance data.
This is the least secure mode since allowed monitored *scope* is
maximized and no perf_events specific limits are imposed on *resources*
allocated for performance monitoring.
>=0:
*scope* includes per-process and system wide performance monitoring
but excludes raw tracepoints and ftrace function tracepoints monitoring.
CPU and system events happened when executing either in user or
in kernel space can be monitored and captured for later analysis.
Per-user per-cpu perf_event_mlock_kb locking limit is imposed but
ignored for unprivileged processes with CAP_IPC_LOCK [6]_ capability.
>=1:
*scope* includes per-process performance monitoring only and excludes
system wide performance monitoring. CPU and system events happened when
executing either in user or in kernel space can be monitored and
captured for later analysis. Per-user per-cpu perf_event_mlock_kb
locking limit is imposed but ignored for unprivileged processes with
CAP_IPC_LOCK capability.
>=2:
*scope* includes per-process performance monitoring only. CPU and system
events happened when executing in user space only can be monitored and
captured for later analysis. Per-user per-cpu perf_event_mlock_kb
locking limit is imposed but ignored for unprivileged processes with
CAP_IPC_LOCK capability.
Bibliography
------------
.. [1] `<https://lwn.net/Articles/337493/>`_
.. [2] `<http://man7.org/linux/man-pages/man2/perf_event_open.2.html>`_
.. [3] `<http://web.eece.maine.edu/~vweaver/projects/perf_events/>`_
.. [4] `<https://perf.wiki.kernel.org/index.php/Main_Page>`_
.. [5] `<https://www.kernel.org/doc/html/latest/security/credentials.html>`_
.. [6] `<http://man7.org/linux/man-pages/man7/capabilities.7.html>`_
.. [7] `<http://man7.org/linux/man-pages/man2/ptrace.2.html>`_

View File

@ -54,7 +54,7 @@ those errors are correctable.
Types of errors Types of errors
--------------- ---------------
Most mechanisms used on modern systems use use technologies like Hamming Most mechanisms used on modern systems use technologies like Hamming
Codes that allow error correction when the number of errors on a bit packet Codes that allow error correction when the number of errors on a bit packet
is below a threshold. If the number of errors is above, those mechanisms is below a threshold. If the number of errors is above, those mechanisms
can indicate with a high degree of confidence that an error happened, but can indicate with a high degree of confidence that an error happened, but

View File

@ -44,7 +44,7 @@ only valid reason for deferring the publication of a fix is to accommodate
the logistics of QA and large scale rollouts which require release the logistics of QA and large scale rollouts which require release
coordination. coordination.
Whilst embargoed information may be shared with trusted individuals in While embargoed information may be shared with trusted individuals in
order to develop a fix, such information will not be published alongside order to develop a fix, such information will not be published alongside
the fix or on any other disclosure channel without the permission of the the fix or on any other disclosure channel without the permission of the
reporter. This includes but is not limited to the original bug report reporter. This includes but is not limited to the original bug report

View File

@ -126,7 +126,7 @@ tagged list.
The boot loader must pass at a minimum the size and location of the The boot loader must pass at a minimum the size and location of the
system memory, and the root filesystem location. The dtb must be system memory, and the root filesystem location. The dtb must be
placed in a region of memory where the kernel decompressor will not placed in a region of memory where the kernel decompressor will not
overwrite it, whilst remaining within the region which will be covered overwrite it, while remaining within the region which will be covered
by the kernel's low-memory mapping. by the kernel's low-memory mapping.
A safe location is just above the 128MiB boundary from start of RAM. A safe location is just above the 128MiB boundary from start of RAM.

View File

@ -55,7 +55,7 @@ out s3c2410 API, then here are some notes on the process.
as they have the same arguments, and can either take the pin specific as they have the same arguments, and can either take the pin specific
values, or the more generic special-function-number arguments. values, or the more generic special-function-number arguments.
3) s3c2410_gpio_pullup() changes have the problem that whilst the 3) s3c2410_gpio_pullup() changes have the problem that while the
s3c2410_gpio_pullup(x, 1) can be easily translated to the s3c2410_gpio_pullup(x, 1) can be easily translated to the
s3c_gpio_setpull(x, S3C_GPIO_PULL_NONE), the s3c2410_gpio_pullup(x, 0) s3c_gpio_setpull(x, S3C_GPIO_PULL_NONE), the s3c2410_gpio_pullup(x, 0)
are not so easy. are not so easy.

View File

@ -17,7 +17,7 @@ Introduction
versions. versions.
The S3C2416 and S3C2450 devices are very similar and S3C2450 support is The S3C2416 and S3C2450 devices are very similar and S3C2450 support is
included under the arch/arm/mach-s3c2416 directory. Note, whilst core included under the arch/arm/mach-s3c2416 directory. Note, while core
support for these SoCs is in, work on some of the extra peripherals support for these SoCs is in, work on some of the extra peripherals
and extra interrupts is still ongoing. and extra interrupts is still ongoing.

View File

@ -87,7 +87,7 @@ Debugging
suspending, which means that use of printascii() or similar direct suspending, which means that use of printascii() or similar direct
access to the UARTs will cause the debug to stop. access to the UARTs will cause the debug to stop.
2) Whilst the pm code itself will attempt to re-enable the UART clocks, 2) While the pm code itself will attempt to re-enable the UART clocks,
care should be taken that any external clock sources that the UARTs care should be taken that any external clock sources that the UARTs
rely on are still enabled at that point. rely on are still enabled at that point.

View File

@ -34,7 +34,7 @@ properties:
8. The array can iterated over. The objects will not necessarily come out in 8. The array can iterated over. The objects will not necessarily come out in
key order. key order.
9. The array can be iterated over whilst it is being modified, provided the 9. The array can be iterated over while it is being modified, provided the
RCU readlock is being held by the iterator. Note, however, under these RCU readlock is being held by the iterator. Note, however, under these
circumstances, some objects may be seen more than once. If this is a circumstances, some objects may be seen more than once. If this is a
problem, the iterator should lock against modification. Objects will not problem, the iterator should lock against modification. Objects will not
@ -42,7 +42,7 @@ properties:
10. Objects in the array can be looked up by means of their index key. 10. Objects in the array can be looked up by means of their index key.
11. Objects can be looked up whilst the array is being modified, provided the 11. Objects can be looked up while the array is being modified, provided the
RCU readlock is being held by the thread doing the look up. RCU readlock is being held by the thread doing the look up.
The implementation uses a tree of 16-pointer nodes internally that are indexed The implementation uses a tree of 16-pointer nodes internally that are indexed
@ -273,7 +273,7 @@ The function will return ``0`` if successful and ``-ENOMEM`` if there wasn't
enough memory. enough memory.
It is possible for other threads to iterate over or search the array under It is possible for other threads to iterate over or search the array under
the RCU read lock whilst this function is in progress. The caller should the RCU read lock while this function is in progress. The caller should
lock exclusively against other modifiers of the array. lock exclusively against other modifiers of the array.

View File

@ -1,3 +1,5 @@
.. _memory-allocation:
======================= =======================
Memory Allocation Guide Memory Allocation Guide
======================= =======================

View File

@ -46,11 +46,20 @@ The Slab Cache
.. kernel-doc:: mm/slab.c .. kernel-doc:: mm/slab.c
:export: :export:
.. kernel-doc:: mm/slab_common.c
:export:
.. kernel-doc:: mm/util.c .. kernel-doc:: mm/util.c
:functions: kfree_const kvmalloc_node kvfree :functions: kfree_const kvmalloc_node kvfree
More Memory Management Functions Virtually Contiguous Mappings
================================ =============================
.. kernel-doc:: mm/vmalloc.c
:export:
File Mapping and Page Cache
===========================
.. kernel-doc:: mm/readahead.c .. kernel-doc:: mm/readahead.c
:export: :export:
@ -58,23 +67,28 @@ More Memory Management Functions
.. kernel-doc:: mm/filemap.c .. kernel-doc:: mm/filemap.c
:export: :export:
.. kernel-doc:: mm/memory.c
:export:
.. kernel-doc:: mm/vmalloc.c
:export:
.. kernel-doc:: mm/page_alloc.c
:internal:
.. kernel-doc:: mm/mempool.c
:export:
.. kernel-doc:: mm/dmapool.c
:export:
.. kernel-doc:: mm/page-writeback.c .. kernel-doc:: mm/page-writeback.c
:export: :export:
.. kernel-doc:: mm/truncate.c .. kernel-doc:: mm/truncate.c
:export: :export:
Memory pools
============
.. kernel-doc:: mm/mempool.c
:export:
DMA pools
=========
.. kernel-doc:: mm/dmapool.c
:export:
More Memory Management Functions
================================
.. kernel-doc:: mm/memory.c
:export:
.. kernel-doc:: mm/page_alloc.c

View File

@ -4,6 +4,8 @@
.. highlight:: none .. highlight:: none
.. _devtools_coccinelle:
Coccinelle Coccinelle
========== ==========

View File

@ -4,7 +4,7 @@ Development tools for the kernel
This document is a collection of documents about development tools that can This document is a collection of documents about development tools that can
be used to work on the kernel. For now, the documents have been pulled be used to work on the kernel. For now, the documents have been pulled
together without any significant effot to integrate them into a coherent together without any significant effort to integrate them into a coherent
whole; patches welcome! whole; patches welcome!
.. class:: toc-title .. class:: toc-title

View File

@ -9,7 +9,7 @@ and booting a kernel.
On some systems, hot-plug tests could hang forever waiting for cpu and On some systems, hot-plug tests could hang forever waiting for cpu and
memory to be ready to be offlined. A special hot-plug target is created memory to be ready to be offlined. A special hot-plug target is created
to run full range of hot-plug tests. In default mode, hot-plug tests run to run the full range of hot-plug tests. In default mode, hot-plug tests run
in safe mode with a limited scope. In limited mode, cpu-hotplug test is in safe mode with a limited scope. In limited mode, cpu-hotplug test is
run on a single cpu as opposed to all hotplug capable cpus, and memory run on a single cpu as opposed to all hotplug capable cpus, and memory
hotplug test is run on 2% of hotplug capable memory instead of 10%. hotplug test is run on 2% of hotplug capable memory instead of 10%.
@ -89,9 +89,9 @@ Note that some tests will require root privileges.
Install selftests Install selftests
================= =================
You can use kselftest_install.sh tool installs selftests in default You can use the kselftest_install.sh tool to install selftests in the
location which is tools/testing/selftests/kselftest or a user specified default location, which is tools/testing/selftests/kselftest, or in a
location. user specified location.
To install selftests in default location:: To install selftests in default location::
@ -109,7 +109,7 @@ Running installed selftests
Kselftest install as well as the Kselftest tarball provide a script Kselftest install as well as the Kselftest tarball provide a script
named "run_kselftest.sh" to run the tests. named "run_kselftest.sh" to run the tests.
You can simply do the following to run the installed Kselftests. Please You can simply do the following to run the installed Kselftests. Please
note some tests will require root privileges:: note some tests will require root privileges::
$ cd kselftest $ cd kselftest
@ -139,7 +139,7 @@ Contributing new tests (details)
default. default.
TEST_CUSTOM_PROGS should be used by tests that require custom build TEST_CUSTOM_PROGS should be used by tests that require custom build
rule and prevent common build rule use. rules and prevent common build rule use.
TEST_PROGS are for test shell scripts. Please ensure shell script has TEST_PROGS are for test shell scripts. Please ensure shell script has
its exec bit set. Otherwise, lib.mk run_tests will generate a warning. its exec bit set. Otherwise, lib.mk run_tests will generate a warning.

View File

@ -146,7 +146,7 @@ The target is named "raid" and it accepts the following parameters:
[data_offset <sectors>] [data_offset <sectors>]
This option value defines the offset into each data device This option value defines the offset into each data device
where the data starts. This is used to provide out-of-place where the data starts. This is used to provide out-of-place
reshaping space to avoid writing over data whilst reshaping space to avoid writing over data while
changing the layout of stripes, hence an interruption/crash changing the layout of stripes, hence an interruption/crash
may happen at any time without the risk of losing data. may happen at any time without the risk of losing data.
E.g. when adding devices to an existing raid set during E.g. when adding devices to an existing raid set during

View File

@ -142,7 +142,7 @@ characterised by the following graph:
The graph is split in two parts delimited by time 1ms on the X-axis. The graph is split in two parts delimited by time 1ms on the X-axis.
The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope
and denotes the energy costs incurred whilst entering and leaving the idle and denotes the energy costs incurred while entering and leaving the idle
state. state.
The graph curve in the area delimited by X-axis values = {x | x > 1ms } has The graph curve in the area delimited by X-axis values = {x | x > 1ms } has
shallower slope and essentially represents the energy consumption of the idle shallower slope and essentially represents the energy consumption of the idle

View File

@ -56,7 +56,7 @@ For CAM, this 24-bit offset is:
cfg_offset(bus, device, function, register) = cfg_offset(bus, device, function, register) =
bus << 16 | device << 11 | function << 8 | register bus << 16 | device << 11 | function << 8 | register
Whilst ECAM extends this by 4 bits to accommodate 4k of function space: While ECAM extends this by 4 bits to accommodate 4k of function space:
cfg_offset(bus, device, function, register) = cfg_offset(bus, device, function, register) =
bus << 20 | device << 15 | function << 12 | register bus << 20 | device << 15 | function << 12 | register

View File

@ -16,7 +16,7 @@ Optional properties:
- linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485 - linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485
feature at boot time. It can be disabled later with proper ioctl. feature at boot time. It can be disabled later with proper ioctl.
- rs485-rx-during-tx: empty property that enables the receiving of data even - rs485-rx-during-tx: empty property that enables the receiving of data even
whilst sending data. while sending data.
RS485 example for Atmel USART: RS485 example for Atmel USART:
usart0: serial@fff8c000 { usart0: serial@fff8c000 {

View File

@ -77,7 +77,7 @@ The general format of a function and function-like macro kernel-doc comment is::
* Context: Describes whether the function can sleep, what locks it takes, * Context: Describes whether the function can sleep, what locks it takes,
* releases, or expects to be held. It can extend over multiple * releases, or expects to be held. It can extend over multiple
* lines. * lines.
* Return: Describe the return value of foobar. * Return: Describe the return value of function_name.
* *
* The return value description can also have multiple paragraphs, and should * The return value description can also have multiple paragraphs, and should
* be placed at the end of the comment block. * be placed at the end of the comment block.

View File

@ -1,3 +1,5 @@
.. _sphinxdoc:
Introduction Introduction
============ ============

View File

@ -11,6 +11,10 @@ This small document introduces how to test DMA drivers using dmatest module.
capability of the following: DMA_MEMCPY (memory-to-memory), DMA_MEMSET capability of the following: DMA_MEMCPY (memory-to-memory), DMA_MEMSET
(const-to-memory or memory-to-memory, when emulated), DMA_XOR, DMA_PQ. (const-to-memory or memory-to-memory, when emulated), DMA_XOR, DMA_PQ.
.. note::
In case of any related questions use the official mailing list
dmaengine@vger.kernel.org.
Part 1 - How to build the test module Part 1 - How to build the test module
===================================== =====================================

View File

@ -6,6 +6,8 @@
.. |struct wakeup_source| replace:: :c:type:`struct wakeup_source <wakeup_source>` .. |struct wakeup_source| replace:: :c:type:`struct wakeup_source <wakeup_source>`
.. |struct device| replace:: :c:type:`struct device <device>` .. |struct device| replace:: :c:type:`struct device <device>`
.. _driverapi_pm_devices:
============================== ==============================
Device Power Management Basics Device Power Management Basics
============================== ==============================

View File

@ -132,6 +132,13 @@ devres. Complexity is shifted from less maintained low level drivers
to better maintained higher layer. Also, as init failure path is to better maintained higher layer. Also, as init failure path is
shared with exit path, both can get more testing. shared with exit path, both can get more testing.
Note though that when converting current calls or assignments to
managed devm_* versions it is up to you to check if internal operations
like allocating memory, have failed. Managed resources pertains to the
freeing of these resources *only* - all other checks needed are still
on you. In some cases this may mean introducing checks that were not
necessary before moving to the managed devm_* calls.
3. Devres group 3. Devres group
--------------- ---------------

View File

@ -52,7 +52,7 @@ user root (0). INITRAMFS_ROOT_GID can be set to a group ID that needs
to be mapped to group root (0). to be mapped to group root (0).
A source file must be directives in the format required by the A source file must be directives in the format required by the
usr/gen_init_cpio utility (run 'usr/gen_init_cpio --help' to get the usr/gen_init_cpio utility (run 'usr/gen_init_cpio -h' to get the
file format). The directives in the file will be passed directly to file format). The directives in the file will be passed directly to
usr/gen_init_cpio. usr/gen_init_cpio.

View File

@ -704,7 +704,7 @@ FS-Cache provides some utilities that a cache backend may make use of:
void fscache_get_retrieval(struct fscache_retrieval *op); void fscache_get_retrieval(struct fscache_retrieval *op);
void fscache_put_retrieval(struct fscache_retrieval *op); void fscache_put_retrieval(struct fscache_retrieval *op);
These two functions are used to retain a retrieval record whilst doing These two functions are used to retain a retrieval record while doing
asynchronous data retrieval and block allocation. asynchronous data retrieval and block allocation.

View File

@ -45,7 +45,7 @@ filesystems are very specific in nature.
CacheFiles creates a misc character device - "/dev/cachefiles" - that is used CacheFiles creates a misc character device - "/dev/cachefiles" - that is used
to communication with the daemon. Only one thing may have this open at once, to communication with the daemon. Only one thing may have this open at once,
and whilst it is open, a cache is at least partially in existence. The daemon and while it is open, a cache is at least partially in existence. The daemon
opens this and sends commands down it to control the cache. opens this and sends commands down it to control the cache.
CacheFiles is currently limited to a single cache. CacheFiles is currently limited to a single cache.
@ -163,7 +163,7 @@ Do not mount other things within the cache as this will cause problems. The
kernel module contains its own very cut-down path walking facility that ignores kernel module contains its own very cut-down path walking facility that ignores
mountpoints, but the daemon can't avoid them. mountpoints, but the daemon can't avoid them.
Do not create, rename or unlink files and directories in the cache whilst the Do not create, rename or unlink files and directories in the cache while the
cache is active, as this may cause the state to become uncertain. cache is active, as this may cause the state to become uncertain.
Renaming files in the cache might make objects appear to be other objects (the Renaming files in the cache might make objects appear to be other objects (the

View File

@ -382,7 +382,7 @@ MISCELLANEOUS OBJECT REGISTRATION
An optional step is to request an object of miscellaneous type be created in An optional step is to request an object of miscellaneous type be created in
the cache. This is almost identical to index cookie acquisition. The only the cache. This is almost identical to index cookie acquisition. The only
difference is that the type in the object definition should be something other difference is that the type in the object definition should be something other
than index type. Whilst the parent object could be an index, it's more likely than index type. While the parent object could be an index, it's more likely
it would be some other type of object such as a data file. it would be some other type of object such as a data file.
xattr->cache = xattr->cache =

View File

@ -171,7 +171,7 @@ Operations are used through the following procedure:
(3) If the submitting thread wants to do the work itself, and has marked the (3) If the submitting thread wants to do the work itself, and has marked the
operation with FSCACHE_OP_MYTHREAD, then it should monitor operation with FSCACHE_OP_MYTHREAD, then it should monitor
FSCACHE_OP_WAITING as described above and check the state of the object if FSCACHE_OP_WAITING as described above and check the state of the object if
necessary (the object might have died whilst the thread was waiting). necessary (the object might have died while the thread was waiting).
When it has finished doing its processing, it should call When it has finished doing its processing, it should call
fscache_op_complete() and fscache_put_operation() on it. fscache_op_complete() and fscache_put_operation() on it.

View File

@ -216,7 +216,7 @@ be called whenever userspace asks for a write(2) on the attribute.
[struct configfs_bin_attribute] [struct configfs_bin_attribute]
struct configfs_attribute { struct configfs_bin_attribute {
struct configfs_attribute cb_attr; struct configfs_attribute cb_attr;
void *cb_private; void *cb_private;
size_t cb_max_size; size_t cb_max_size;

View File

@ -359,3 +359,24 @@ encryption of files and directories.
:maxdepth: 2 :maxdepth: 2
fscrypt fscrypt
Pathname lookup
===============
This write-up is based on three articles published at lwn.net:
- <https://lwn.net/Articles/649115/> Pathname lookup in Linux
- <https://lwn.net/Articles/649729/> RCU-walk: faster pathname lookup in Linux
- <https://lwn.net/Articles/650786/> A walk among the symlinks
Written by Neil Brown with help from Al Viro and Jon Corbet.
It has subsequently been updated to reflect changes in the kernel
including:
- per-directory parallel name lookup.
.. toctree::
:maxdepth: 2
path-lookup.rst

View File

@ -125,6 +125,13 @@ process running on the system, which is named after the process ID (PID).
The link self points to the process reading the file system. Each process The link self points to the process reading the file system. Each process
subdirectory has the entries listed in Table 1-1. subdirectory has the entries listed in Table 1-1.
Note that an open a file descriptor to /proc/<pid> or to any of its
contained files or subdirectories does not prevent <pid> being reused
for some other process in the event that <pid> exits. Operations on
open /proc/<pid> file descriptors corresponding to dead processes
never act on any new process that the kernel may, through chance, have
also assigned the process ID <pid>. Instead, operations on these FDs
usually fail with ESRCH.
Table 1-1: Process specific entries in /proc Table 1-1: Process specific entries in /proc
.............................................................................. ..............................................................................
@ -194,8 +201,10 @@ read the file /proc/PID/status:
CapPrm: 0000000000000000 CapPrm: 0000000000000000
CapEff: 0000000000000000 CapEff: 0000000000000000
CapBnd: ffffffffffffffff CapBnd: ffffffffffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0 NoNewPrivs: 0
Seccomp: 0 Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
voluntary_ctxt_switches: 0 voluntary_ctxt_switches: 0
nonvoluntary_ctxt_switches: 1 nonvoluntary_ctxt_switches: 1
@ -215,7 +224,7 @@ asynchronous manner and the value may not be very precise. To see a precise
snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table. snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
It's slow but very precise. It's slow but very precise.
Table 1-2: Contents of the status files (as of 4.8) Table 1-2: Contents of the status files (as of 4.19)
.............................................................................. ..............................................................................
Field Content Field Content
Name filename of the executable Name filename of the executable
@ -270,8 +279,10 @@ Table 1-2: Contents of the status files (as of 4.8)
CapPrm bitmap of permitted capabilities CapPrm bitmap of permitted capabilities
CapEff bitmap of effective capabilities CapEff bitmap of effective capabilities
CapBnd bitmap of capabilities bounding set CapBnd bitmap of capabilities bounding set
CapAmb bitmap of ambient capabilities
NoNewPrivs no_new_privs, like prctl(PR_GET_NO_NEW_PRIV, ...) NoNewPrivs no_new_privs, like prctl(PR_GET_NO_NEW_PRIV, ...)
Seccomp seccomp mode, like prctl(PR_GET_SECCOMP, ...) Seccomp seccomp mode, like prctl(PR_GET_SECCOMP, ...)
Speculation_Store_Bypass speculative store bypass mitigation status
Cpus_allowed mask of CPUs on which this process may run Cpus_allowed mask of CPUs on which this process may run
Cpus_allowed_list Same as previous, but in "list format" Cpus_allowed_list Same as previous, but in "list format"
Mems_allowed mask of memory nodes allowed to this process Mems_allowed mask of memory nodes allowed to this process

View File

@ -87,7 +87,7 @@ addressed with 16 direct blocks.
For more than 16 blocks an indirect addressing in form of another tree is For more than 16 blocks an indirect addressing in form of another tree is
used. (scheme is the same as the one used for the superblock root nodes) used. (scheme is the same as the one used for the superblock root nodes)
The filesize is stored 64bit. Inode counting starts with 1. (whilst long The filesize is stored 64bit. Inode counting starts with 1. (while long
filename inodes start with 0) filename inodes start with 0)
Directories Directories
@ -155,7 +155,7 @@ Then userspace.
The requirement for a static, fixed preallocated system area comes from how The requirement for a static, fixed preallocated system area comes from how
qnx6fs deals with writes. qnx6fs deals with writes.
Each superblock got it's own half of the system area. So superblock #1 Each superblock got it's own half of the system area. So superblock #1
always uses blocks from the lower half whilst superblock #2 just writes to always uses blocks from the lower half while superblock #2 just writes to
blocks represented by the upper half bitmap system area bits. blocks represented by the upper half bitmap system area bits.
Bitmap blocks, Inode blocks and indirect addressing blocks for those two Bitmap blocks, Inode blocks and indirect addressing blocks for those two

View File

@ -452,7 +452,7 @@ RETURN VALUE
ERRORS ERRORS
EACCESS EACCES
The current user does not have write access on the spufs mount The current user does not have write access on the spufs mount
point. point.

View File

@ -1131,7 +1131,7 @@ struct dentry_operations {
d_manage: called to allow the filesystem to manage the transition from a d_manage: called to allow the filesystem to manage the transition from a
dentry (optional). This allows autofs, for example, to hold up clients dentry (optional). This allows autofs, for example, to hold up clients
waiting to explore behind a 'mountpoint' whilst letting the daemon go waiting to explore behind a 'mountpoint' while letting the daemon go
past and construct the subtree there. 0 should be returned to let the past and construct the subtree there. 0 should be returned to let the
calling process continue. -EISDIR can be returned to tell pathwalk to calling process continue. -EISDIR can be returned to tell pathwalk to
use this directory as an ordinary directory and to ignore anything use this directory as an ordinary directory and to ignore anything

View File

@ -110,7 +110,7 @@ owner field in the metadata object, we can immediately do top down validation to
determine the scope of the problem. determine the scope of the problem.
Different types of metadata have different owner identifiers. For example, Different types of metadata have different owner identifiers. For example,
directory, attribute and extent tree blocks are all owned by an inode, whilst directory, attribute and extent tree blocks are all owned by an inode, while
freespace btree blocks are owned by an allocation group. Hence the size and freespace btree blocks are owned by an allocation group. Hence the size and
contents of the owner field are determined by the type of metadata object we are contents of the owner field are determined by the type of metadata object we are
looking at. The owner information can also identify misplaced writes (e.g. looking at. The owner information can also identify misplaced writes (e.g.

View File

@ -417,7 +417,7 @@ level directory:
filesystem from ever unmounting fully in the case of "retry forever" filesystem from ever unmounting fully in the case of "retry forever"
handler configurations. handler configurations.
Note: there is no guarantee that fail_at_unmount can be set whilst an Note: there is no guarantee that fail_at_unmount can be set while an
unmount is in progress. It is possible that the sysfs entries are unmount is in progress. It is possible that the sysfs entries are
removed by the unmounting filesystem before a "retry forever" error removed by the unmounting filesystem before a "retry forever" error
handler configuration causes unmount to hang, and hence the filesystem handler configuration causes unmount to hang, and hence the filesystem

View File

@ -190,11 +190,11 @@ ENOSPC:
Simply running out of kernel/system memory is signalled through ENOMEM. Simply running out of kernel/system memory is signalled through ENOMEM.
EPERM/EACCESS: EPERM/EACCES:
Returned for an operation that is valid, but needs more privileges. Returned for an operation that is valid, but needs more privileges.
E.g. root-only or much more common, DRM master-only operations return E.g. root-only or much more common, DRM master-only operations return
this when when called by unpriviledged clients. There's no clear this when when called by unpriviledged clients. There's no clear
difference between EACCESS and EPERM. difference between EACCES and EPERM.
ENODEV: ENODEV:
The device is not (yet) present or fully initialized. The device is not (yet) present or fully initialized.

View File

@ -15,7 +15,7 @@ existing subsystems with minimal additional code. Examples are the disk-activity
nand-disk and sharpsl-charge triggers. With led triggers disabled, the code nand-disk and sharpsl-charge triggers. With led triggers disabled, the code
optimises away. optimises away.
Complex triggers whilst available to all LEDs have LED specific Complex triggers while available to all LEDs have LED specific
parameters and work on a per LED basis. The timer trigger is an example. parameters and work on a per LED basis. The timer trigger is an example.
The timer trigger will periodically change the LED brightness between The timer trigger will periodically change the LED brightness between
LED_OFF and the current brightness setting. The "on" and "off" time can LED_OFF and the current brightness setting. The "on" and "off" time can

View File

@ -4003,7 +4003,7 @@ demodulator. It receives radio frequency (RF) from the antenna and
converts that received signal to lower intermediate frequency (IF) or converts that received signal to lower intermediate frequency (IF) or
baseband frequency (BB). Tuners that could do baseband output are often baseband frequency (BB). Tuners that could do baseband output are often
called Zero-IF tuners. Older tuners were typically simple PLL tuners called Zero-IF tuners. Older tuners were typically simple PLL tuners
inside a metal box, whilst newer ones are highly integrated chips inside a metal box, while newer ones are highly integrated chips
without a metal box "silicon tuners". These controls are mostly without a metal box "silicon tuners". These controls are mostly
applicable for new feature rich silicon tuners, just because older applicable for new feature rich silicon tuners, just because older
tuners does not have much adjustable features. tuners does not have much adjustable features.

View File

@ -587,7 +587,7 @@ leading to the following situation:
(Q == &B) and (D == 2) ???? (Q == &B) and (D == 2) ????
Whilst this may seem like a failure of coherency or causality maintenance, it While this may seem like a failure of coherency or causality maintenance, it
isn't, and this behaviour can be observed on certain real CPUs (such as the DEC isn't, and this behaviour can be observed on certain real CPUs (such as the DEC
Alpha). Alpha).
@ -2008,7 +2008,7 @@ for each construct. These operations all imply certain barriers:
Certain locking variants of the ACQUIRE operation may fail, either due to Certain locking variants of the ACQUIRE operation may fail, either due to
being unable to get the lock immediately, or due to receiving an unblocked being unable to get the lock immediately, or due to receiving an unblocked
signal whilst asleep waiting for the lock to become available. Failed signal while asleep waiting for the lock to become available. Failed
locks do not imply any sort of barrier. locks do not imply any sort of barrier.
[!] Note: one of the consequences of lock ACQUIREs and RELEASEs being only [!] Note: one of the consequences of lock ACQUIREs and RELEASEs being only
@ -2508,7 +2508,7 @@ CPU, that CPU's dependency ordering logic will take care of everything else.
ATOMIC OPERATIONS ATOMIC OPERATIONS
----------------- -----------------
Whilst they are technically interprocessor interaction considerations, atomic While they are technically interprocessor interaction considerations, atomic
operations are noted specially as some of them imply full memory barriers and operations are noted specially as some of them imply full memory barriers and
some don't, but they're very heavily relied on as a group throughout the some don't, but they're very heavily relied on as a group throughout the
kernel. kernel.
@ -2531,7 +2531,7 @@ the device to malfunction.
Inside of the Linux kernel, I/O should be done through the appropriate accessor Inside of the Linux kernel, I/O should be done through the appropriate accessor
routines - such as inb() or writel() - which know how to make such accesses routines - such as inb() or writel() - which know how to make such accesses
appropriately sequential. Whilst this, for the most part, renders the explicit appropriately sequential. While this, for the most part, renders the explicit
use of memory barriers unnecessary, there are a couple of situations where they use of memory barriers unnecessary, there are a couple of situations where they
might be needed: might be needed:
@ -2555,7 +2555,7 @@ access the device.
This may be alleviated - at least in part - by disabling local interrupts (a This may be alleviated - at least in part - by disabling local interrupts (a
form of locking), such that the critical operations are all contained within form of locking), such that the critical operations are all contained within
the interrupt-disabled section in the driver. Whilst the driver's interrupt the interrupt-disabled section in the driver. While the driver's interrupt
routine is executing, the driver's core may not run on the same CPU, and its routine is executing, the driver's core may not run on the same CPU, and its
interrupt is not permitted to happen again until the current interrupt has been interrupt is not permitted to happen again until the current interrupt has been
handled, thus the interrupt handler does not need to lock against that. handled, thus the interrupt handler does not need to lock against that.
@ -2763,7 +2763,7 @@ CACHE COHERENCY
Life isn't quite as simple as it may appear above, however: for while the Life isn't quite as simple as it may appear above, however: for while the
caches are expected to be coherent, there's no guarantee that that coherency caches are expected to be coherent, there's no guarantee that that coherency
will be ordered. This means that whilst changes made on one CPU will will be ordered. This means that while changes made on one CPU will
eventually become visible on all CPUs, there's no guarantee that they will eventually become visible on all CPUs, there's no guarantee that they will
become apparent in the same order on those other CPUs. become apparent in the same order on those other CPUs.
@ -2799,7 +2799,7 @@ Imagine the system has the following properties:
(*) an even-numbered cache line may be in cache B, cache D or it may still be (*) an even-numbered cache line may be in cache B, cache D or it may still be
resident in memory; resident in memory;
(*) whilst the CPU core is interrogating one cache, the other cache may be (*) while the CPU core is interrogating one cache, the other cache may be
making use of the bus to access the rest of the system - perhaps to making use of the bus to access the rest of the system - perhaps to
displace a dirty cacheline or to do a speculative load; displace a dirty cacheline or to do a speculative load;
@ -2835,7 +2835,7 @@ now imagine that the second CPU wants to read those values:
x = *q; x = *q;
The above pair of reads may then fail to happen in the expected order, as the The above pair of reads may then fail to happen in the expected order, as the
cacheline holding p may get updated in one of the second CPU's caches whilst cacheline holding p may get updated in one of the second CPU's caches while
the update to the cacheline holding v is delayed in the other of the second the update to the cacheline holding v is delayed in the other of the second
CPU's caches by some other cache event: CPU's caches by some other cache event:
@ -2855,7 +2855,7 @@ CPU's caches by some other cache event:
<C:unbusy> <C:unbusy>
<C:commit v=2> <C:commit v=2>
Basically, whilst both cachelines will be updated on CPU 2 eventually, there's Basically, while both cachelines will be updated on CPU 2 eventually, there's
no guarantee that, without intervention, the order of update will be the same no guarantee that, without intervention, the order of update will be the same
as that committed on CPU 1. as that committed on CPU 1.
@ -2885,7 +2885,7 @@ coherency queue before processing any further requests:
This sort of problem can be encountered on DEC Alpha processors as they have a This sort of problem can be encountered on DEC Alpha processors as they have a
split cache that improves performance by making better use of the data bus. split cache that improves performance by making better use of the data bus.
Whilst most CPUs do imply a data dependency barrier on the read when a memory While most CPUs do imply a data dependency barrier on the read when a memory
access depends on a read, not all do, so it may not be relied on. access depends on a read, not all do, so it may not be relied on.
Other CPUs may also have split caches, but must coordinate between the various Other CPUs may also have split caches, but must coordinate between the various
@ -2974,7 +2974,7 @@ assumption doesn't hold because:
thus cutting down on transaction setup costs (memory and PCI devices may thus cutting down on transaction setup costs (memory and PCI devices may
both be able to do this); and both be able to do this); and
(*) the CPU's data cache may affect the ordering, and whilst cache-coherency (*) the CPU's data cache may affect the ordering, and while cache-coherency
mechanisms may alleviate this - once the store has actually hit the cache mechanisms may alleviate this - once the store has actually hit the cache
- there's no guarantee that the coherency management will be propagated in - there's no guarantee that the coherency management will be propagated in
order to other CPUs. order to other CPUs.

View File

@ -84,7 +84,7 @@
Automedia detection is included so that in principle you can disconnect Automedia detection is included so that in principle you can disconnect
from, e.g. TP, reconnect to BNC and things will still work (after a from, e.g. TP, reconnect to BNC and things will still work (after a
pause whilst the driver figures out where its media went). My tests pause while the driver figures out where its media went). My tests
using ping showed that it appears to work.... using ping showed that it appears to work....
By default, the driver will now autodetect any DECchip based card. By default, the driver will now autodetect any DECchip based card.

View File

@ -661,7 +661,7 @@ A server would be set up to accept operations in the following manner:
setsockopt(server, SOL_RXRPC, RXRPC_SECURITY_KEYRING, "AFSkeys", 7); setsockopt(server, SOL_RXRPC, RXRPC_SECURITY_KEYRING, "AFSkeys", 7);
The keyring can be manipulated after it has been given to the socket. This The keyring can be manipulated after it has been given to the socket. This
permits the server to add more keys, replace keys, etc. whilst it is live. permits the server to add more keys, replace keys, etc. while it is live.
(3) A local address must then be bound: (3) A local address must then be bound:
@ -1032,7 +1032,7 @@ The kernel interface functions are as follows:
struct sockaddr_rxrpc *srx, struct sockaddr_rxrpc *srx,
struct key *key); struct key *key);
This attempts to partially reinitialise a call and submit it again whilst This attempts to partially reinitialise a call and submit it again while
reusing the original call's Tx queue to avoid the need to repackage and reusing the original call's Tx queue to avoid the need to repackage and
re-encrypt the data to be sent. call indicates the call to retry, srx the re-encrypt the data to be sent. call indicates the call to retry, srx the
new address to send it to and key the encryption key to use for signing or new address to send it to and key the encryption key to use for signing or
@ -1066,7 +1066,7 @@ The kernel interface functions are as follows:
alive after waiting for a suitable interval. alive after waiting for a suitable interval.
This allows the caller to work out if the server is still contactable and This allows the caller to work out if the server is still contactable and
if the call is still alive on the server whilst waiting for the server to if the call is still alive on the server while waiting for the server to
process a client operation. process a client operation.
The second function causes a ping ACK to be transmitted to try to provoke The second function causes a ping ACK to be transmitted to try to provoke
@ -1149,14 +1149,14 @@ adjusted through sysctls in /proc/net/rxrpc/:
(*) connection_expiry (*) connection_expiry
The amount of time in seconds after a connection was last used before we The amount of time in seconds after a connection was last used before we
remove it from the connection list. Whilst a connection is in existence, remove it from the connection list. While a connection is in existence,
it serves as a placeholder for negotiated security; when it is deleted, it serves as a placeholder for negotiated security; when it is deleted,
the security must be renegotiated. the security must be renegotiated.
(*) transport_expiry (*) transport_expiry
The amount of time in seconds after a transport was last used before we The amount of time in seconds after a transport was last used before we
remove it from the transport list. Whilst a transport is in existence, it remove it from the transport list. While a transport is in existence, it
serves to anchor the peer data and keeps the connection ID counter. serves to anchor the peer data and keeps the connection ID counter.
(*) rxrpc_rx_window_size (*) rxrpc_rx_window_size

View File

@ -22,7 +22,7 @@ Nomenclature
Some terms used in this document:- Some terms used in this document:-
o Regulator - Electronic device that supplies power to other devices. o Regulator - Electronic device that supplies power to other devices.
Most regulators can enable and disable their output whilst Most regulators can enable and disable their output while
some can control their output voltage and or current. some can control their output voltage and or current.
Input Voltage -> Regulator -> Output Voltage Input Voltage -> Regulator -> Output Voltage

View File

@ -1,3 +1,5 @@
.. _development_process_intro:
Introduction Introduction
============ ============

View File

@ -315,7 +315,8 @@ variety of potential coding problems; it can also propose fixes for those
problems. Quite a few "semantic patches" for the kernel have been packaged problems. Quite a few "semantic patches" for the kernel have been packaged
under the scripts/coccinelle directory; running "make coccicheck" will run under the scripts/coccinelle directory; running "make coccicheck" will run
through those semantic patches and report on any problems found. See through those semantic patches and report on any problems found. See
Documentation/dev-tools/coccinelle.rst for more information. :ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`
for more information.
Other kinds of portability errors are best found by compiling your code for Other kinds of portability errors are best found by compiling your code for
other architectures. If you do not happen to have an S/390 system or a other architectures. If you do not happen to have an S/390 system or a

View File

@ -9,9 +9,10 @@ kernel. Unsurprisingly, the kernel development community has evolved a set
of conventions and procedures which are used in the posting of patches; of conventions and procedures which are used in the posting of patches;
following them will make life much easier for everybody involved. This following them will make life much easier for everybody involved. This
document will attempt to cover these expectations in reasonable detail; document will attempt to cover these expectations in reasonable detail;
more information can also be found in the files process/submitting-patches.rst, more information can also be found in the files
process/submitting-drivers.rst, and process/submit-checklist.rst in the kernel :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`,
documentation directory. :ref:`Documentation/process/submitting-drivers.rst <submittingdrivers>`
and :ref:`Documentation/process/submit-checklist.rst <submitchecklist>`.
When to post When to post
@ -198,8 +199,10 @@ pass it to diff with the "-X" option.
The tags mentioned above are used to describe how various developers have The tags mentioned above are used to describe how various developers have
been associated with the development of this patch. They are described in been associated with the development of this patch. They are described in
detail in the process/submitting-patches.rst document; what follows here is a detail in
brief summary. Each of these lines has the format: the :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
document; what follows here is a brief summary. Each of these lines has
the format:
:: ::
@ -210,8 +213,8 @@ The tags in common use are:
- Signed-off-by: this is a developer's certification that he or she has - Signed-off-by: this is a developer's certification that he or she has
the right to submit the patch for inclusion into the kernel. It is an the right to submit the patch for inclusion into the kernel. It is an
agreement to the Developer's Certificate of Origin, the full text of agreement to the Developer's Certificate of Origin, the full text of
which can be found in Documentation/process/submitting-patches.rst. Code which can be found in :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
without a proper signoff cannot be merged into the mainline. Code without a proper signoff cannot be merged into the mainline.
- Co-developed-by: states that the patch was also created by another developer - Co-developed-by: states that the patch was also created by another developer
along with the original author. This is useful at times when multiple along with the original author. This is useful at times when multiple
@ -226,7 +229,7 @@ The tags in common use are:
it to work. it to work.
- Reviewed-by: the named developer has reviewed the patch for correctness; - Reviewed-by: the named developer has reviewed the patch for correctness;
see the reviewer's statement in Documentation/process/submitting-patches.rst see the reviewer's statement in :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
for more detail. for more detail.
- Reported-by: names a user who reported a problem which is fixed by this - Reported-by: names a user who reported a problem which is fixed by this
@ -253,8 +256,8 @@ take care of:
be examined in any detail. If there is any doubt at all, mail the patch be examined in any detail. If there is any doubt at all, mail the patch
to yourself and convince yourself that it shows up intact. to yourself and convince yourself that it shows up intact.
Documentation/process/email-clients.rst has some helpful hints on making :ref:`Documentation/process/email-clients.rst <email_clients>` has some
specific mail clients work for sending patches. helpful hints on making specific mail clients work for sending patches.
- Are you sure your patch is free of silly mistakes? You should always - Are you sure your patch is free of silly mistakes? You should always
run patches through scripts/checkpatch.pl and address the complaints it run patches through scripts/checkpatch.pl and address the complaints it

View File

@ -5,9 +5,10 @@ For more information
There are numerous sources of information on Linux kernel development and There are numerous sources of information on Linux kernel development and
related topics. First among those will always be the Documentation related topics. First among those will always be the Documentation
directory found in the kernel source distribution. The top-level process/howto.rst directory found in the kernel source distribution. The top-level :ref:`process/howto.rst <process_howto>`
file is an important starting point; process/submitting-patches.rst and file is an important starting point; :ref:`process/submitting-patches.rst <submittingpatches>`
process/submitting-drivers.rst are also something which all kernel developers should and :ref:`process/submitting-drivers.rst <submittingdrivers>`
are also something which all kernel developers should
read. Many internal kernel APIs are documented using the kerneldoc read. Many internal kernel APIs are documented using the kerneldoc
mechanism; "make htmldocs" or "make pdfdocs" can be used to generate those mechanism; "make htmldocs" or "make pdfdocs" can be used to generate those
documents in HTML or PDF format (though the version of TeX shipped by some documents in HTML or PDF format (though the version of TeX shipped by some

View File

@ -1,3 +1,6 @@
.. _addsyscalls:
Adding a New System Call Adding a New System Call
======================== ========================

View File

@ -326,7 +326,7 @@ Kernel documentation
Sphinx Sphinx
------ ------
Please see :ref:`sphinx_install` in ``Documentation/doc-guide/sphinx.rst`` Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>`
for details about Sphinx requirements. for details about Sphinx requirements.
Getting updated software Getting updated software

View File

@ -1075,5 +1075,5 @@ gcc internals and indent, all available from http://www.gnu.org/manual/
WG14 is the international standardization working group for the programming WG14 is the international standardization working group for the programming
language C, URL: http://www.open-std.org/JTC1/SC22/WG14/ language C, URL: http://www.open-std.org/JTC1/SC22/WG14/
Kernel process/coding-style.rst, by greg@kroah.com at OLS 2002: Kernel :ref:`process/coding-style.rst <codingstyle>`, by greg@kroah.com at OLS 2002:
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/

View File

@ -1,3 +1,5 @@
.. _process_howto:
HOWTO do Linux kernel development HOWTO do Linux kernel development
================================= =================================
@ -296,9 +298,9 @@ two weeks, but it can be longer if there are no pressing problems. A
security-related problem, instead, can cause a release to happen almost security-related problem, instead, can cause a release to happen almost
instantly. instantly.
The file Documentation/process/stable-kernel-rules.rst in the kernel tree The file :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
documents what kinds of changes are acceptable for the -stable tree, and in the kernel tree documents what kinds of changes are acceptable for
how the release process works. the -stable tree, and how the release process works.
4.x -git patches 4.x -git patches
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -358,7 +360,8 @@ tool. For details on how to use the kernel bugzilla, please see:
https://bugzilla.kernel.org/page.cgi?id=faq.html https://bugzilla.kernel.org/page.cgi?id=faq.html
The file admin-guide/reporting-bugs.rst in the main kernel source directory has a good The file :ref:`admin-guide/reporting-bugs.rst <reportingbugs>`
in the main kernel source directory has a good
template for how to report a possible kernel bug, and details what kind template for how to report a possible kernel bug, and details what kind
of information is needed by the kernel developers to help track down the of information is needed by the kernel developers to help track down the
problem. problem.
@ -424,7 +427,7 @@ add your statements between the individual quoted sections instead of
writing at the top of the mail. writing at the top of the mail.
If you add patches to your mail, make sure they are plain readable text If you add patches to your mail, make sure they are plain readable text
as stated in Documentation/process/submitting-patches.rst. as stated in :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`.
Kernel developers don't want to deal with Kernel developers don't want to deal with
attachments or compressed patches; they may want to comment on attachments or compressed patches; they may want to comment on
individual lines of your patch, which works only that way. Make sure you individual lines of your patch, which works only that way. Make sure you

View File

@ -1,3 +1,5 @@
.. _process_statement_driver:
Kernel Driver Statement Kernel Driver Statement
----------------------- -----------------------

View File

@ -1,4 +1,6 @@
Linux Kernel Enforcement Statement .. _process_statement_kernel:
Linux Kernel Enforcement Statement
---------------------------------- ----------------------------------
As developers of the Linux kernel, we have a keen interest in how our software As developers of the Linux kernel, we have a keen interest in how our software

View File

@ -1,3 +1,5 @@
.. _magicnumbers:
Linux magic numbers Linux magic numbers
=================== ===================

View File

@ -5,8 +5,9 @@ Linux kernel management style
This is a short document describing the preferred (or made up, depending This is a short document describing the preferred (or made up, depending
on who you ask) management style for the linux kernel. It's meant to on who you ask) management style for the linux kernel. It's meant to
mirror the process/coding-style.rst document to some degree, and mainly written to mirror the :ref:`process/coding-style.rst <codingstyle>` document to some
avoid answering [#f1]_ the same (or similar) questions over and over again. degree, and mainly written to avoid answering [#f1]_ the same (or similar)
questions over and over again.
Management style is very personal and much harder to quantify than Management style is very personal and much harder to quantify than
simple coding style rules, so this document may or may not have anything simple coding style rules, so this document may or may not have anything

View File

@ -16,7 +16,8 @@ you should probably talk to XFree86 (http://www.xfree86.org/) and/or X.Org
Oh, and we don't really recommend submitting changes to XFree86 :) Oh, and we don't really recommend submitting changes to XFree86 :)
Also read the Documentation/process/submitting-patches.rst document. Also read the :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
document.
Allocating Device Numbers Allocating Device Numbers
@ -27,7 +28,8 @@ by the Linux assigned name and number authority (currently this is
Torben Mathiasen). The site is http://www.lanana.org/. This Torben Mathiasen). The site is http://www.lanana.org/. This
also deals with allocating numbers for devices that are not going to also deals with allocating numbers for devices that are not going to
be submitted to the mainstream kernel. be submitted to the mainstream kernel.
See Documentation/admin-guide/devices.rst for more information on this. See :ref:`Documentation/admin-guide/devices.rst <admin_devices>`
for more information on this.
If you don't use assigned numbers then when your device is submitted it will If you don't use assigned numbers then when your device is submitted it will
be given an assigned number even if that is different from values you may be given an assigned number even if that is different from values you may
@ -117,7 +119,7 @@ PM support:
anything. For the driver testing instructions see anything. For the driver testing instructions see
Documentation/power/drivers-testing.txt and for a relatively Documentation/power/drivers-testing.txt and for a relatively
complete overview of the power management issues related to complete overview of the power management issues related to
drivers see Documentation/driver-api/pm/devices.rst. drivers see :ref:`Documentation/driver-api/pm/devices.rst <driverapi_pm_devices>`.
Control: Control:
In general if there is active maintenance of a driver by In general if there is active maintenance of a driver by

View File

@ -16,7 +16,7 @@ Sep 2002: Dynamically get 3270 input buffer
Sep 2002: Fix tubfs kmalloc()s Sep 2002: Fix tubfs kmalloc()s
* Do read and write lengths correctly in fs3270_read() * Do read and write lengths correctly in fs3270_read()
and fs3270_write(), whilst never asking kmalloc() and fs3270_write(), while never asking kmalloc()
for more than 0x800 bytes. Affects tubfs.c and tubio.h. for more than 0x800 bytes. Affects tubfs.c and tubio.h.
Sep 2002: Recognize 3270 control unit type 3174 Sep 2002: Recognize 3270 control unit type 3174

View File

@ -291,7 +291,7 @@ for example), it must be considered immutable, barring two exceptions:
1. The reference count may be altered. 1. The reference count may be altered.
2. Whilst the keyring subscriptions of a set of credentials may not be 2. While the keyring subscriptions of a set of credentials may not be
changed, the keyrings subscribed to may have their contents altered. changed, the keyrings subscribed to may have their contents altered.
To catch accidental credential alteration at compile time, struct task_struct To catch accidental credential alteration at compile time, struct task_struct
@ -358,7 +358,7 @@ Once a reference has been obtained, it must be released with ``put_cred()``,
Accessing Another Task's Credentials Accessing Another Task's Credentials
------------------------------------ ------------------------------------
Whilst a task may access its own credentials without the need for locking, the While a task may access its own credentials without the need for locking, the
same is not true of a task wanting to access another task's credentials. It same is not true of a task wanting to access another task's credentials. It
must use the RCU read lock and ``rcu_dereference()``. must use the RCU read lock and ``rcu_dereference()``.
@ -382,7 +382,7 @@ This should be used inside the RCU read lock, as in the following example::
} }
Should it be necessary to hold another task's credentials for a long period of Should it be necessary to hold another task's credentials for a long period of
time, and possibly to sleep whilst doing so, then the caller should get a time, and possibly to sleep while doing so, then the caller should get a
reference on them using:: reference on them using::
const struct cred *get_task_cred(struct task_struct *task); const struct cred *get_task_cred(struct task_struct *task);
@ -442,7 +442,7 @@ duplicate of the current process's credentials, returning with the mutex still
held if successful. It returns NULL if not successful (out of memory). held if successful. It returns NULL if not successful (out of memory).
The mutex prevents ``ptrace()`` from altering the ptrace state of a process The mutex prevents ``ptrace()`` from altering the ptrace state of a process
whilst security checks on credentials construction and changing is taking place while security checks on credentials construction and changing is taking place
as the ptrace state may alter the outcome, particularly in the case of as the ptrace state may alter the outcome, particularly in the case of
``execve()``. ``execve()``.

View File

@ -132,7 +132,7 @@ Negative Instantiation And Rejection
Rather than instantiating a key, it is possible for the possessor of an Rather than instantiating a key, it is possible for the possessor of an
authorisation key to negatively instantiate a key that's under construction. authorisation key to negatively instantiate a key that's under construction.
This is a short duration placeholder that causes any attempt at re-requesting This is a short duration placeholder that causes any attempt at re-requesting
the key whilst it exists to fail with error ENOKEY if negated or the specified the key while it exists to fail with error ENOKEY if negated or the specified
error if rejected. error if rejected.
This is provided to prevent excessive repeated spawning of /sbin/request-key This is provided to prevent excessive repeated spawning of /sbin/request-key

View File

@ -75,7 +75,7 @@
/* Set rts delay after send, if needed: */ /* Set rts delay after send, if needed: */
rs485conf.delay_rts_after_send = ...; rs485conf.delay_rts_after_send = ...;
/* Set this flag if you want to receive data even whilst sending data */ /* Set this flag if you want to receive data even while sending data */
rs485conf.flags |= SER_RS485_RX_DURING_TX; rs485conf.flags |= SER_RS485_RX_DURING_TX;
if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {

View File

@ -24,7 +24,7 @@ I2S
=== ===
I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
Rx lines are used for audio transmission, whilst the bit clock (BCLK) and Rx lines are used for audio transmission, while the bit clock (BCLK) and
left/right clock (LRC) synchronise the link. I2S is flexible in that either the left/right clock (LRC) synchronise the link. I2S is flexible in that either the
controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
usually varies depending on the sample rate and the master system clock usually varies depending on the sample rate and the master system clock
@ -49,9 +49,9 @@ PCM
PCM is another 4 wire interface, very similar to I2S, which can support a more PCM is another 4 wire interface, very similar to I2S, which can support a more
flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used
to synchronise the link whilst the Tx and Rx lines are used to transmit and to synchronise the link while the Tx and Rx lines are used to transmit and
receive the audio data. Bit clock usually varies depending on sample rate receive the audio data. Bit clock usually varies depending on sample rate
whilst sync runs at the sample rate. PCM also supports Time Division while sync runs at the sample rate. PCM also supports Time Division
Multiplexing (TDM) in that several devices can use the bus simultaneously (this Multiplexing (TDM) in that several devices can use the bus simultaneously (this
is sometimes referred to as network mode). is sometimes referred to as network mode).

View File

@ -218,7 +218,7 @@ like a BT phone call :-
* * <----DAI5-----> FM * * <----DAI5-----> FM
************* *************
This allows the host CPU to sleep whilst the DSP, MODEM DAI and the BT DAI are This allows the host CPU to sleep while the DSP, MODEM DAI and the BT DAI are
still in operation. still in operation.
A BE DAI link can also set the codec to a dummy device if the code is a device A BE DAI link can also set the codec to a dummy device if the code is a device

View File

@ -156,7 +156,7 @@ or increment/decrement function.
Note that switching branches results in some locks being taken, Note that switching branches results in some locks being taken,
particularly the CPU hotplug lock (in order to avoid races against particularly the CPU hotplug lock (in order to avoid races against
CPUs being brought in the kernel whilst the kernel is getting CPUs being brought in the kernel while the kernel is getting
patched). Calling the static key API from within a hotplug notifier is patched). Calling the static key API from within a hotplug notifier is
thus a sure deadlock recipe. In order to still allow use of the thus a sure deadlock recipe. In order to still allow use of the
functionnality, the following functions are provided: functionnality, the following functions are provided:

View File

@ -110,7 +110,7 @@ the permitted thermal "ramp" of the system. For instance, a lower
`k_pu` value will provide a slower ramp, at the cost of capping `k_pu` value will provide a slower ramp, at the cost of capping
available capacity at a low temperature. On the other hand, a high available capacity at a low temperature. On the other hand, a high
value of `k_pu` will result in the governor granting very high power value of `k_pu` will result in the governor granting very high power
whilst temperature is low, and may lead to temperature overshooting. while temperature is low, and may lead to temperature overshooting.
The default value for `k_pu` is: The default value for `k_pu` is:

View File

@ -24,13 +24,13 @@ It can be used for debugging or analyzing latencies and
performance issues that take place outside of user-space. performance issues that take place outside of user-space.
Although ftrace is typically considered the function tracer, it Although ftrace is typically considered the function tracer, it
is really a frame work of several assorted tracing utilities. is really a framework of several assorted tracing utilities.
There's latency tracing to examine what occurs between interrupts There's latency tracing to examine what occurs between interrupts
disabled and enabled, as well as for preemption and from a time disabled and enabled, as well as for preemption and from a time
a task is woken to the task is actually scheduled in. a task is woken to the task is actually scheduled in.
One of the most common uses of ftrace is the event tracing. One of the most common uses of ftrace is the event tracing.
Through out the kernel is hundreds of static event points that Throughout the kernel is hundreds of static event points that
can be enabled via the tracefs file system to see what is can be enabled via the tracefs file system to see what is
going on in certain parts of the kernel. going on in certain parts of the kernel.
@ -462,7 +462,7 @@ of ftrace. Here is a list of some of the key files:
mono_raw: mono_raw:
This is the raw monotonic clock (CLOCK_MONOTONIC_RAW) This is the raw monotonic clock (CLOCK_MONOTONIC_RAW)
which is montonic but is not subject to any rate adjustments which is monotonic but is not subject to any rate adjustments
and ticks at the same rate as the hardware clocksource. and ticks at the same rate as the hardware clocksource.
boot: boot:
@ -914,8 +914,8 @@ The above is mostly meaningful for kernel developers.
current trace and the next trace. current trace and the next trace.
- '$' - greater than 1 second - '$' - greater than 1 second
- '@' - greater than 100 milisecond - '@' - greater than 100 millisecond
- '*' - greater than 10 milisecond - '*' - greater than 10 millisecond
- '#' - greater than 1000 microsecond - '#' - greater than 1000 microsecond
- '!' - greater than 100 microsecond - '!' - greater than 100 microsecond
- '+' - greater than 10 microsecond - '+' - greater than 10 microsecond
@ -2541,7 +2541,7 @@ At compile time every C file object is run through the
recordmcount program (located in the scripts directory). This recordmcount program (located in the scripts directory). This
program will parse the ELF headers in the C object to find all program will parse the ELF headers in the C object to find all
the locations in the .text section that call mcount. Starting the locations in the .text section that call mcount. Starting
with gcc verson 4.6, the -mfentry has been added for x86, which with gcc version 4.6, the -mfentry has been added for x86, which
calls "__fentry__" instead of "mcount". Which is called before calls "__fentry__" instead of "mcount". Which is called before
the creation of the stack frame. the creation of the stack frame.
@ -2978,7 +2978,7 @@ The following commands are supported:
When the function is hit, it will dump the contents of the ftrace When the function is hit, it will dump the contents of the ftrace
ring buffer to the console. This is useful if you need to debug ring buffer to the console. This is useful if you need to debug
something, and want to dump the trace when a certain function something, and want to dump the trace when a certain function
is hit. Perhaps its a function that is called before a tripple is hit. Perhaps it's a function that is called before a triple
fault happens and does not allow you to get a regular dump. fault happens and does not allow you to get a regular dump.
- cpudump: - cpudump:

View File

@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/admin-guide/README.rst <readme>`
.. _it_readme:
Rilascio del kernel Linux 4.x <http://kernel.org/>
===================================================
.. warning::
TODO ancora da tradurre

View File

@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`
.. _it_securitybugs:
Bachi di sicurezza
==================
.. warning::
TODO ancora da tradurre

View File

@ -107,7 +107,7 @@ macro simil-funzioni è il seguente::
* Context: Describes whether the function can sleep, what locks it takes, * Context: Describes whether the function can sleep, what locks it takes,
* releases, or expects to be held. It can extend over multiple * releases, or expects to be held. It can extend over multiple
* lines. * lines.
* Return: Describe the return value of foobar. * Return: Describe the return value of function_name.
* *
* The return value description can also have multiple paragraphs, and should * The return value description can also have multiple paragraphs, and should
* be placed at the end of the comment block. * be placed at the end of the comment block.

View File

@ -86,6 +86,7 @@ vostre modifiche molto più semplice
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
process/index
doc-guide/index doc-guide/index
kernel-hacking/index kernel-hacking/index

View File

@ -593,8 +593,8 @@ l'opzione ``GFP_KERNEL`` che è permessa solo in contesto utente. Ho supposto
che :c:func:`cache_add()` venga chiamata dal contesto utente, altrimenti che :c:func:`cache_add()` venga chiamata dal contesto utente, altrimenti
questa opzione deve diventare un parametro di :c:func:`cache_add()`. questa opzione deve diventare un parametro di :c:func:`cache_add()`.
Exposing Objects Outside This File Esporre gli oggetti al di fuori del file
---------------------------------- ----------------------------------------
Se i vostri oggetti contengono più informazioni, potrebbe non essere Se i vostri oggetti contengono più informazioni, potrebbe non essere
sufficiente copiare i dati avanti e indietro: per esempio, altre parti del sufficiente copiare i dati avanti e indietro: per esempio, altre parti del

View File

@ -0,0 +1,297 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/1.Intro.rst <development_process_intro>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_intro:
Introduzione
============
Riepilogo generale
------------------
Il resto di questa sezione riguarda il processo di sviluppo del kernel e
quella sorta di frustrazione che gli sviluppatori e i loro datori di lavoro
potrebbero dover affrontare. Ci sono molte ragioni per le quali del codice
per il kernel debba essere incorporato nel kernel ufficiale, fra le quali:
disponibilità immediata agli utilizzatori, supporto della comunità in
differenti modalità, e la capacità di influenzare la direzione dello sviluppo
del kernel.
Il codice che contribuisce al kernel Linux deve essere reso disponibile sotto
una licenza GPL-compatibile.
La sezione :ref:`it_development_process` introduce il processo di sviluppo,
il ciclo di rilascio del kernel, ed i meccanismi della finestra
d'incorporazione. Il capitolo copre le varie fasi di una modifica: sviluppo,
revisione e ciclo d'incorporazione. Ci sono alcuni dibattiti su strumenti e
liste di discussione. Gli sviluppatori che sono in attesa di poter sviluppare
qualcosa per il kernel sono invitati ad individuare e sistemare bachi come
esercizio iniziale.
La sezione :ref:`it_development_early_stage` copre i primi stadi della
pianificazione di un progetto di sviluppo, con particolare enfasi sul
coinvolgimento della comunità, il prima possibile.
La sezione :ref:`it_development_coding` riguarda il processo di scrittura
del codice. Qui, sono esposte le diverse insidie che sono state già affrontate
da altri sviluppatori. Il capitolo copre anche alcuni dei requisiti per le
modifiche, ed esiste un'introduzione ad alcuni strumenti che possono aiutarvi
nell'assicurarvi che le modifiche per il kernel siano corrette.
La sezione :ref:`it_development_posting` parla del processo di pubblicazione
delle modifiche per la revisione. Per essere prese in considerazione dalla
comunità di sviluppo, le modifiche devono essere propriamente formattate ed
esposte, e devono essere inviate nel posto giusto. Seguire i consigli presenti
in questa sezione dovrebbe essere d'aiuto nell'assicurare la migliore
accoglienza possibile del vostro lavoro.
La sezione :ref:`it_development_followthrough` copre ciò che accade dopo
la pubblicazione delle modifiche; a questo punto il lavoro è lontano
dall'essere concluso. Lavorare con i revisori è una parte cruciale del
processo di sviluppo; questa sezione offre una serie di consigli su come
evitare problemi in questa importante fase. Gli sviluppatori sono diffidenti
nell'affermare che il lavoro è concluso quando una modifica è incorporata nei
sorgenti principali.
La sezione :ref:`it_development_advancedtopics` introduce un paio di argomenti
"avanzati": gestire le modifiche con git e controllare le modifiche pubblicate
da altri.
La sezione :ref:`it_development_conclusion` chiude il documento con dei
riferimenti ad altre fonti che forniscono ulteriori informazioni sullo sviluppo
del kernel.
Di cosa parla questo documento
------------------------------
Il kernel Linux, ha oltre 8 milioni di linee di codice e ben oltre 1000
contributori ad ogni rilascio; è uno dei più vasti e più attivi software
liberi progettati mai esistiti. Sin dal sul modesto inizio nel 1991,
questo kernel si è evoluto nel miglior componente per sistemi operativi
che fanno funzionare piccoli riproduttori musicali, PC, grandi super computer
e tutte le altre tipologie di sistemi fra questi estremi. È una soluzione
robusta, efficiente ed adattabile a praticamente qualsiasi situazione.
Con la crescita di Linux è arrivato anche un aumento di sviluppatori
(ed aziende) desiderosi di partecipare a questo sviluppo. I produttori di
hardware vogliono assicurarsi che il loro prodotti siano supportati da Linux,
rendendo questi prodotti attrattivi agli utenti Linux. I produttori di
sistemi integrati, che usano Linux come componente di un prodotto integrato,
vogliono che Linux sia capace ed adeguato agli obiettivi ed il più possibile
alla mano. Fornitori ed altri produttori di software che basano i propri
prodotti su Linux hanno un chiaro interesse verso capacità, prestazioni ed
affidabilità del kernel Linux. E gli utenti finali, anche, spesso vorrebbero
cambiare Linux per renderlo più aderente alle proprie necessità.
Una delle caratteristiche più coinvolgenti di Linux è quella dell'accessibilità
per gli sviluppatori; chiunque con le capacità richieste può migliorare
Linux ed influenzarne la direzione di sviluppo. Prodotti non open-source non
possono offrire questo tipo di apertura, che è una caratteristica del software
libero. Ma, anzi, il kernel è persino più aperto rispetto a molti altri
progetti di software libero. Un classico ciclo di sviluppo trimestrale può
coinvolgere 1000 sviluppatori che lavorano per più di 100 differenti aziende
(o per nessuna azienda).
Lavorare con la comunità di sviluppo del kernel non è particolarmente
difficile. Ma, ciononostante, diversi potenziali contributori hanno trovato
delle difficoltà quando hanno cercato di lavorare sul kernel. La comunità del
kernel utilizza un proprio modo di operare che gli permette di funzionare
agevolmente (e genera un prodotto di alta qualità) in un ambiente dove migliaia
di stringhe di codice sono modificate ogni giorni. Quindi non deve sorprendere
che il processo di sviluppo del kernel differisca notevolmente dai metodi di
sviluppo privati.
Il processo di sviluppo del Kernel può, dall'altro lato, risultare
intimidatorio e strano ai nuovi sviluppatori, ma ha dietro di se buone ragioni
e solide esperienze. Uno sviluppatore che non comprende i modi della comunità
del kernel (o, peggio, che cerchi di aggirarli o violarli) avrà un'esperienza
deludente nel proprio bagaglio. La comunità di sviluppo, sebbene sia utile
a coloro che cercano di imparare, ha poco tempo da dedicare a coloro che non
ascoltano o coloro che non sono interessati al processo di sviluppo.
Si spera che coloro che leggono questo documento saranno in grado di evitare
queste esperienze spiacevoli. C'è molto materiale qui, ma lo sforzo della
lettura sarà ripagato in breve tempo. La comunità di sviluppo ha sempre
bisogno di sviluppatori che vogliano aiutare a rendere il kernel migliore;
il testo seguente potrebbe esservi d'aiuto - o essere d'aiuto ai vostri
collaboratori- per entrare a far parte della nostra comunità.
Crediti
-------
Questo documento è stato scritto da Jonathan Corbet, corbet@lwn.net.
È stato migliorato da Johannes Berg, James Berry, Alex Chiang, Roland
Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh,
Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata e Jochen Voß.
Questo lavoro è stato supportato dalla Linux Foundation; un ringraziamento
speciale ad Amanda McPherson, che ha visto il valore di questo lavoro e lo ha
reso possibile.
L'importanza d'avere il codice nei sorgenti principali
------------------------------------------------------
Alcune aziende e sviluppatori ogni tanto si domandano perché dovrebbero
preoccuparsi di apprendere come lavorare con la comunità del kernel e di
inserire il loro codice nel ramo di sviluppo principale (per ramo principale
s'intende quello mantenuto da Linus Torvalds e usato come base dai
distributori Linux). Nel breve termine, contribuire al codice può sembrare
un costo inutile; può sembra più facile tenere separato il proprio codice e
supportare direttamente i suoi utilizzatori. La verità è che il tenere il
codice separato ("fuori dai sorgenti", *"out-of-tree"*) è un falso risparmio.
Per dimostrare i costi di un codice "fuori dai sorgenti", eccovi
alcuni aspetti rilevanti del processo di sviluppo kernel; la maggior parte
di essi saranno approfonditi dettagliatamente più avanti in questo documento.
Considerate:
- Il codice che è stato inserito nel ramo principale del kernel è disponibile
a tutti gli utilizzatori Linux. Sarà automaticamente presente in tutte le
distribuzioni che lo consentono. Non c'è bisogno di: driver per dischi,
scaricare file, o della scocciatura del dover supportare diverse versioni di
diverse distribuzioni; funziona già tutto, per gli sviluppatori e per gli
utilizzatori. L'inserimento nel ramo principale risolve un gran numero di
problemi di distribuzione e di supporto.
- Nonostante gli sviluppatori kernel si sforzino di tenere stabile
l'interfaccia dello spazio utente, quella interna al kernel è in continuo
cambiamento. La mancanza di un'interfaccia interna è deliberatamente una
decisione di progettazione; ciò permette che i miglioramenti fondamentali
vengano fatti in un qualsiasi momento e che risultino fatti con un codice di
alta qualità. Ma una delle conseguenze di questa politica è che qualsiasi
codice "fuori dai sorgenti" richiede costante manutenzione per renderlo
funzionante coi kernel più recenti. Tenere un codice "fuori dai sorgenti"
richiede una mole di lavoro significativa solo per farlo funzionare.
Invece, il codice che si trova nel ramo principale non necessita di questo
tipo di lavoro poiché ad ogni sviluppatore che faccia una modifica alle
interfacce viene richiesto di sistemare anche il codice che utilizza
quell'interfaccia. Quindi, il codice che è stato inserito nel ramo principale
ha dei costi di mantenimento significativamente più bassi.
- Oltre a ciò, spesso il codice che è all'interno del kernel sarà migliorato da
altri sviluppatori. Dare pieni poteri alla vostra comunità di utenti e ai
clienti può portare a sorprendenti risultati che migliorano i vostri
prodotti.
- Il codice kernel è soggetto a revisioni, sia prima che dopo l'inserimento
nel ramo principale. Non importa quanto forti fossero le abilità dello
sviluppatore originale, il processo di revisione troverà il modo di migliore
il codice. Spesso la revisione trova bachi importanti e problemi di
sicurezza. Questo è particolarmente vero per il codice che è stato
sviluppato in un ambiente chiuso; tale codice ottiene un forte beneficio
dalle revisioni provenienti da sviluppatori esteri. Il codice
"fuori dai sorgenti", invece, è un codice di bassa qualità.
- La partecipazione al processo di sviluppo costituisce la vostra via per
influenzare la direzione di sviluppo del kernel. Gli utilizzatori che
"reclamano da bordo campo" sono ascoltati, ma gli sviluppatori attivi
hanno una voce più forte - e la capacità di implementare modifiche che
renderanno il kernel più funzionale alle loro necessità.
- Quando il codice è gestito separatamente, esiste sempre la possibilità che
terze parti contribuiscano con una differente implementazione che fornisce
le stesse funzionalità. Se dovesse accadere, l'inserimento del codice
diventerà molto più difficile - fino all'impossibilità. Poi, dovrete far
fronte a delle alternative poco piacevoli, come: (1) mantenere un elemento
non standard "fuori dai sorgenti" per un tempo indefinito, o (2) abbandonare
il codice e far migrare i vostri utenti alla versione "nei sorgenti".
- Contribuire al codice è l'azione fondamentale che fa funzionare tutto il
processo. Contribuendo attraverso il vostro codice potete aggiungere nuove
funzioni al kernel e fornire competenze ed esempi che saranno utili ad
altri sviluppatori. Se avete sviluppato del codice Linux (o state pensando
di farlo), avete chiaramente interesse nel far proseguire il successo di
questa piattaforma. Contribuire al codice è une delle migliori vie per
aiutarne il successo.
Il ragionamento sopra citato si applica ad ogni codice "fuori dai sorgenti"
dal kernel, incluso il codice proprietario distribuito solamente in formato
binario. Ci sono, comunque, dei fattori aggiuntivi che dovrebbero essere
tenuti in conto prima di prendere in considerazione qualsiasi tipo di
distribuzione binaria di codice kernel. Questo include che:
- Le questioni legali legate alla distribuzione di moduli kernel proprietari
sono molto nebbiose; parecchi detentori di copyright sul kernel credono che
molti moduli binari siano prodotti derivati del kernel e che, come risultato,
la loro diffusione sia una violazione della licenza generale di GNU (della
quale si parlerà più avanti). L'autore qui non è un avvocato, e
niente in questo documento può essere considerato come un consiglio legale.
Il vero stato legale dei moduli proprietari può essere determinato
esclusivamente da un giudice. Ma l'incertezza che perseguita quei moduli
è lì comunque.
- I moduli binari aumentano di molto la difficoltà di fare debugging del
kernel, al punto che la maggior parte degli sviluppatori del kernel non
vorranno nemmeno tentare. Quindi la diffusione di moduli esclusivamente
binari renderà difficile ai vostri utilizzatori trovare un supporto dalla
comunità.
- Il supporto è anche difficile per i distributori di moduli binari che devono
fornire una versione del modulo per ogni distribuzione e per ogni versione
del kernel che vogliono supportate. Per fornire una copertura ragionevole e
comprensiva, può essere richiesto di produrre dozzine di singoli moduli.
E inoltre i vostri utilizzatori dovranno aggiornare il vostro modulo
separatamente ogni volta che aggiornano il loro kernel.
- Tutto ciò che è stato detto prima riguardo alla revisione del codice si
applica doppiamente al codice proprietario. Dato che questo codice non è
del tutto disponibile, non può essere revisionato dalla comunità e avrà,
senza dubbio, seri problemi.
I produttori di sistemi integrati, in particolare, potrebbero esser tentati
dall'evitare molto di ciò che è stato detto in questa sezione, credendo che
stiano distribuendo un prodotto finito che utilizza una versione del kernel
immutabile e che non richiede un ulteriore sviluppo dopo il rilascio. Questa
idea non comprende il valore di una vasta revisione del codice e il valore
del permettere ai propri utenti di aggiungere funzionalità al vostro prodotto.
Ma anche questi prodotti, hanno una vita commerciale limitata, dopo la quale
deve essere rilasciata una nuova versione. A quel punto, i produttori il cui
codice è nel ramo principale di sviluppo avranno un codice ben mantenuto e
saranno in una posizione migliore per ottenere velocemente un nuovo prodotto
pronto per essere distribuito.
Licenza
-------
IL codice Linux utilizza diverse licenze, ma il codice completo deve essere
compatibile con la seconda versione della licenza GNU General Public License
(GPLv2), che è la licenza che copre la distribuzione del kernel.
Nella pratica, ciò significa che tutti i contributi al codice sono coperti
anche'essi dalla GPLv2 (con, opzionalmente, una dicitura che permette la
possibilità di distribuirlo con licenze più recenti di GPL) o dalla licenza
three-clause BSD. Qualsiasi contributo che non è coperto da una licenza
compatibile non verrà accettata nel kernel.
Per il codice sottomesso al kernel non è necessario (o richiesto) la
concessione del Copyright. Tutto il codice inserito nel ramo principale del
kernel conserva la sua proprietà originale; ne risulta che ora il kernel abbia
migliaia di proprietari.
Una conseguenza di questa organizzazione della proprietà è che qualsiasi
tentativo di modifica della licenza del kernel è destinata ad un quasi sicuro
fallimento. Esistono alcuni scenari pratici nei quali il consenso di tutti
i detentori di copyright può essere ottenuto (o il loro codice verrà rimosso
dal kernel). Quindi, in sostanza, non esiste la possibilità che si giunga ad
una versione 3 della licenza GPL nel prossimo futuro.
È imperativo che tutto il codice che contribuisce al kernel sia legittimamente
software libero. Per questa ragione, un codice proveniente da un contributore
anonimo (o sotto pseudonimo) non verrà accettato. È richiesto a tutti i
contributori di firmare il proprio codice, attestando così che quest'ultimo
può essere distribuito insieme al kernel sotto la licenza GPL. Il codice che
non è stato licenziato come software libero dal proprio creatore, o che
potrebbe creare problemi di copyright per il kernel (come il codice derivante
da processi di ingegneria inversa senza le opportune tutele), non può essere
diffuso.
Domande relative a questioni legate al copyright sono frequenti nelle liste
di discussione dedicate allo sviluppo di Linux. Tali quesiti, normalmente,
non riceveranno alcuna risposta, ma una cosa deve essere tenuta presente:
le persone che risponderanno a quelle domande non sono avvocati e non possono
fornire supporti legali. Se avete questioni legali relative ai sorgenti
del codice Linux, non esiste alternativa che quella di parlare con un
avvocato esperto nel settore. Fare affidamento sulle risposte ottenute da
una lista di discussione tecnica è rischioso.

View File

@ -0,0 +1,531 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/2.Process.rst <development_process>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_process:
Come funziona il processo di sviluppo
=====================================
Lo sviluppo del Kernel agli inizi degli anno '90 era abbastanza libero, con
un numero di utenti e sviluppatori relativamente basso. Con una base
di milioni di utenti e con 2000 sviluppatori coinvolti nel giro di un anno,
il kernel da allora ha messo in atto un certo numero di procedure per rendere
lo sviluppo più agevole. È richiesta una solida conoscenza di come tale
processo si svolge per poter esserne parte attiva.
Il quadro d'insieme
-------------------
Gli sviluppatori kernel utilizzano un calendario di rilascio generico, dove
ogni due o tre mesi viene effettuata un rilascio importante del kernel.
I rilasci più recenti sono stati:
====== =================
4.11 Aprile 30, 2017
4.12 Luglio 2, 2017
4.13 Settembre 3, 2017
4.14 Novembre 12, 2017
4.15 Gennaio 28, 2018
4.16 Aprile 1, 2018
====== =================
Ciascun rilascio 4.x è un importante rilascio del kernel con nuove
funzionalità, modifiche interne dell'API, e molto altro. Un tipico
rilascio 4.x contiene quasi 13,000 gruppi di modifiche con ulteriori
modifiche a parecchie migliaia di linee di codice. La 4.x. è pertanto la
linea di confine nello sviluppo del kernel Linux; il kernel utilizza un sistema
di sviluppo continuo che integra costantemente nuove importanti modifiche.
Viene seguita una disciplina abbastanza lineare per l'inclusione delle
patch di ogni rilascio. All'inizio di ogni ciclo di sviluppo, la
"finestra di inclusione" viene dichiarata aperta. In quel momento il codice
ritenuto sufficientemente stabile(e che è accettato dalla comunità di sviluppo)
viene incluso nel ramo principale del kernel. La maggior parte delle
patch per un nuovo ciclo di sviluppo (e tutte le più importanti modifiche)
saranno inserite durante questo periodo, ad un ritmo che si attesta sulle
1000 modifiche ("patch" o "gruppo di modifiche") al giorno.
(per inciso, vale la pena notare che i cambiamenti integrati durante la
"finestra di inclusione" non escono dal nulla; questi infatti, sono stati
raccolti e, verificati in anticipo. Il funzionamento di tale procedimento
verrà descritto dettagliatamente più avanti).
La finestra di inclusione resta attiva approssimativamente per due settimane.
Al termine di questo periodo, Linus Torvald dichiarerà che la finestra è
chiusa e rilascerà il primo degli "rc" del kernel.
Per il kernel che è destinato ad essere 2.6.40, per esempio, il rilascio
che emerge al termine della finestra d'inclusione si chiamerà 2.6.40-rc1.
Questo rilascio indica che il momento di aggiungere nuovi componenti è
passato, e che è iniziato il periodo di stabilizzazione del prossimo kernel.
Nelle successive sei/dieci settimane, potranno essere sottoposte solo modifiche
che vanno a risolvere delle problematiche. Occasionalmente potrà essere
consentita una modifica più consistente, ma tali occasioni sono rare.
Gli sviluppatori che tenteranno di aggiungere nuovi elementi al di fuori della
finestra di inclusione, tendenzialmente, riceveranno un accoglienza poco
amichevole. Come regola generale: se vi perdete la finestra di inclusione per
un dato componente, la cosa migliore da fare è aspettare il ciclo di sviluppo
successivo (un'eccezione può essere fatta per i driver per hardware non
supportati in precedenza; se toccano codice non facente parte di quello
attuale, che non causino regressioni e che potrebbero essere aggiunti in
sicurezza in un qualsiasi momento)
Mentre le correzioni si aprono la loro strada all'interno del ramo principale,
il ritmo delle modifiche rallenta col tempo. Linus rilascia un nuovo
kernel -rc circa una volta alla settimana; e ne usciranno circa 6 o 9 prima
che il kernel venga considerato sufficientemente stabile e che il rilascio
finale 2.6.x venga fatto. A quel punto tutto il processo ricomincerà.
Esempio: ecco com'è andato il ciclo di sviluppo della versione 4.16
(tutte le date si collocano nel 2018)
============== =======================================
Gennaio 28 4.15 rilascio stabile
Febbraio 11 4.16-rc1, finestra di inclusione chiusa
Febbraio 18 4.16-rc2
Febbraio 25 4.16-rc3
Marzo 4 4.16-rc4
Marzo 11 4.16-rc5
Marzo 18 4.16-rc6
Marzo 25 4.16-rc7
Aprile 1 4.17 rilascio stabile
============== =======================================
In che modo gli sviluppatori decidono quando chiudere il ciclo di sviluppo e
creare quindi una rilascio stabile? Un metro valido è il numero di regressioni
rilevate nel precedente rilascio. Nessun baco è il benvenuto, ma quelli che
procurano problemi su sistemi che hanno funzionato in passato sono considerati
particolarmente seri. Per questa ragione, le modifiche che portano ad una
regressione sono viste sfavorevolmente e verranno quasi sicuramente annullate
durante il periodo di stabilizzazione.
L'obiettivo degli sviluppatori è quello di aggiustare tutte le regressioni
conosciute prima che avvenga il rilascio stabile. Nel mondo reale, questo
tipo di perfezione difficilmente viene raggiunta; esistono troppe variabili
in un progetto di questa portata. Arriva un punto dove ritardare il rilascio
finale peggiora la situazione; la quantità di modifiche in attesa della
prossima finestra di inclusione crescerà enormemente, creando ancor più
regressioni al giro successivo. Quindi molti kernel 4.x escono con una
manciata di regressioni delle quali, si spera, nessuna è grave.
Una volta che un rilascio stabile è fatto, il suo costante mantenimento è
affidato al "squadra stabilità", attualmente composta da Greg Kroah-Hartman.
Questa squadra rilascia occasionalmente degli aggiornamenti relativi al
rilascio stabile usando la numerazione 4.x.y. Per essere presa in
considerazione per un rilascio d'aggiornamento, una modifica deve:
(1) correggere un baco importante (2) essere già inserita nel ramo principale
per il prossimo sviluppo del kernel. Solitamente, passato il loro rilascio
iniziale, i kernel ricevono aggiornamenti per più di un ciclo di sviluppo.
Quindi, per esempio, la storia del kernel 4.13 appare così:
============== ===============================
Settembre 3 4.13 rilascio stabile
Settembre 13 4.13.1
Settembre 20 4.13.2
Settembre 27 4.13.3
Ottobre 5 4.13.4
Ottobre 12 4.13.5
... ...
Novembre 24 4.13.16
============== ===============================
La 4.13.16 fu l'aggiornamento finale per la versione 4.13.
Alcuni kernel sono destinati ad essere kernel a "lungo termine"; questi
riceveranno assistenza per un lungo periodo di tempo. Al momento in cui
scriviamo, i manutentori dei kernel stabili a lungo termine sono:
====== ====================== ==========================================
3.16 Ben Hutchings (kernel stabile molto più a lungo termine)
4.1 Sasha Levin
4.4 Greg Kroah-Hartman (kernel stabile molto più a lungo termine)
4.9 Greg Kroah-Hartman
4.14 Greg Kroah-Hartman
====== ====================== ==========================================
Questa selezione di kernel di lungo periodo sono puramente dovuti ai loro
manutentori, alla loro necessità e al tempo per tenere aggiornate proprio
quelle versioni. Non ci sono altri kernel a lungo termine in programma per
alcun rilascio in arrivo.
Il ciclo di vita di una patch
-----------------------------
Le patch non passano direttamente dalla tastiera dello sviluppatori
al ramo principale del kernel. Esiste, invece, una procedura disegnata
per assicurare che ogni patch sia di buona qualità e desiderata nel
ramo principale. Questo processo avviene velocemente per le correzioni
meno importanti, o, nel caso di patch ampie e controverse, va avanti per anni.
Per uno sviluppatore la maggior frustrazione viene dalla mancanza di
comprensione di questo processo o dai tentativi di aggirarlo.
Nella speranza di ridurre questa frustrazione, questo documento spiegherà
come una patch viene inserita nel kernel. Ciò che segue è un'introduzione
che descrive il processo ideale. Approfondimenti verranno invece trattati
più avanti.
Una patch attraversa, generalmente, le seguenti fasi:
- Progetto. In questa fase sono stabilite quelli che sono i requisiti
della modifica - e come verranno soddisfatti. Il lavoro di progettazione
viene spesso svolto senza coinvolgere la comunità, ma è meglio renderlo
il più aperto possibile; questo può far risparmiare molto tempo evitando
eventuali riprogettazioni successive.
- Prima revisione. Le patch vengono pubblicate sulle liste di discussione
interessate, e gli sviluppatori in quella lista risponderanno coi loro
commenti. Se si svolge correttamente, questo procedimento potrebbe far
emergere problemi rilevanti in una patch.
- Revisione più ampia. Quando la patch è quasi pronta per essere inserita
nel ramo principale, un manutentore importante del sottosistema dovrebbe
accettarla - anche se, questa accettazione non è una garanzia che la
patch arriverà nel ramo principale. La patch sarà visibile nei sorgenti
del sottosistema in questione e nei sorgenti -next (descritti sotto).
Quando il processo va a buon fine, questo passo porta ad una revisione
più estesa della patch e alla scoperta di problemi d'integrazione
con il lavoro altrui.
- Per favore, tenete da conto che la maggior parte dei manutentori ha
anche un lavoro quotidiano, quindi integrare le vostre patch potrebbe
non essere la loro priorità più alta. Se una vostra patch riceve
dei suggerimenti su dei cambiamenti necessari, dovreste applicare
quei cambiamenti o giustificare perché non sono necessari. Se la vostra
patch non riceve alcuna critica ma non è stata integrata dal
manutentore del driver o sottosistema, allora dovreste continuare con
i necessari aggiornamenti per mantenere la patch aggiornata al kernel
più recente cosicché questa possa integrarsi senza problemi; continuate
ad inviare gli aggiornamenti per essere revisionati e integrati.
- Inclusione nel ramo principale. Eventualmente, una buona patch verrà
inserita all'interno nel repositorio principale, gestito da
Linus Torvalds. In questa fase potrebbero emergere nuovi problemi e/o
commenti; è importante che lo sviluppatore sia collaborativo e che sistemi
ogni questione che possa emergere.
- Rilascio stabile. Ora, il numero di utilizzatori che sono potenzialmente
toccati dalla patch è aumentato, quindi, ancora una volta, potrebbero
emergere nuovi problemi.
- Manutenzione di lungo periodo. Nonostante sia possibile che uno sviluppatore
si dimentichi del codice dopo la sua integrazione, questo comportamento
lascia una brutta impressione nella comunità di sviluppo. Integrare il
codice elimina alcuni degli oneri facenti parte della manutenzione, in
particolare, sistemerà le problematiche causate dalle modifiche all'API.
Ma lo sviluppatore originario dovrebbe continuare ad assumersi la
responsabilità per il codice se quest'ultimo continua ad essere utile
nel lungo periodo.
Uno dei più grandi errori fatti dagli sviluppatori kernel (o dai loro datori
di lavoro) è quello di cercare di ridurre tutta la procedura ad una singola
"integrazione nel remo principale". Questo approccio inevitabilmente conduce
a una condizione di frustrazione per tutti coloro che sono coinvolti.
Come le modifiche finiscono nel Kernel
--------------------------------------
Esiste una sola persona che può inserire le patch nel repositorio principale
del kernel: Linus Torvalds. Ma, di tutte le 9500 patch che entrarono nella
versione 2.6.38 del kernel, solo 112 (circa l'1,3%) furono scelte direttamente
da Linus in persona. Il progetto del kernel è cresciuto fino a raggiungere
una dimensione tale per cui un singolo sviluppatore non può controllare e
selezionare indipendentemente ogni modifica senza essere supportato.
La via scelta dagli sviluppatori per indirizzare tale crescita è stata quella
di utilizzare un sistema di "sottotenenti" basato sulla fiducia.
Il codice base del kernel è spezzato in una serie si sottosistemi: rete,
supporto per specifiche architetture, gestione della memoria, video e
strumenti, etc. Molti sottosistemi hanno un manutentore designato: ovvero uno
sviluppatore che ha piena responsabilità di tutto il codice presente in quel
sottosistema. Tali manutentori di sottosistema sono i guardiani
(in un certo senso) della parte di kernel che gestiscono; sono coloro che
(solitamente) accetteranno una patch per l'inclusione nel ramo principale
del kernel.
I manutentori di sottosistema gestiscono ciascuno la propria parte dei sorgenti
del kernel, utilizzando abitualmente (ma certamente non sempre) git.
Strumenti come git (e affini come quilt o mercurial) permettono ai manutentori
di stilare una lista delle patch, includendo informazioni sull'autore ed
altri metadati. In ogni momento, il manutentore può individuare quale patch
nel sua repositorio non si trova nel ramo principale.
Quando la "finestra di integrazione" si apre, i manutentori di alto livello
chiederanno a Linus di "prendere" dai loro repositori le modifiche che hanno
selezionato per l'inclusione. Se Linus acconsente, il flusso di patch si
convoglierà nel repositorio di quest ultimo, divenendo così parte del ramo
principale del kernel. La quantità d'attenzione che Linus presta alle
singole patch ricevute durante l'operazione di integrazione varia.
È chiaro che, qualche volta, guardi più attentamente. Ma, come regola
generale, Linus confida nel fatto che i manutentori di sottosistema non
selezionino pessime patch.
I manutentori di sottosistemi, a turno, possono "prendere" patch
provenienti da altri manutentori. Per esempio, i sorgenti per la rete rete
sono costruiti da modifiche che si sono accumulate inizialmente nei sorgenti
dedicati ai driver per dispositivi di rete, rete senza fili, ecc. Tale
catena di repositori può essere più o meno lunga, benché raramente ecceda
i due o tre collegamenti. Questo processo è conosciuto come
"la catena della fiducia", perché ogni manutentore all'interno della
catena si fida di coloro che gestiscono i livelli più bassi.
Chiaramente, in un sistema come questo, l'inserimento delle patch all'interno
del kernel si basa sul trovare il manutentore giusto. Di norma, inviare
patch direttamente a Linus non è la via giusta.
Sorgenti -next
--------------
La catena di sottosistemi guida il flusso di patch all'interno del kernel,
ma solleva anche un interessante quesito: se qualcuno volesse vedere tutte le
patch pronte per la prossima finestra di integrazione?
Gli sviluppatori si interesseranno alle patch in sospeso per verificare
che non ci siano altri conflitti di cui preoccuparsi; una modifica che, per
esempio, cambia il prototipo di una funzione fondamentale del kernel andrà in
conflitto con qualsiasi altra modifica che utilizzi la vecchia versione di
quella funzione. Revisori e tester vogliono invece avere accesso alle
modifiche nella loro totalità prima che approdino nel ramo principale del
kernel. Uno potrebbe prendere le patch provenienti da tutti i sottosistemi
d'interesse, ma questo sarebbe un lavoro enorme e fallace.
La risposta ci viene sotto forma di sorgenti -next, dove i sottosistemi sono
raccolti per essere testati e controllati. Il più vecchio di questi sorgenti,
gestito da Andrew Morton, è chiamato "-mm" (memory management, che è l'inizio
di tutto). L'-mm integra patch proveniente da una lunga lista di sottosistemi;
e ha, inoltre, alcune patch destinate al supporto del debugging.
Oltre a questo, -mm contiene una raccolta significativa di patch che sono
state selezionate da Andrew direttamente. Queste patch potrebbero essere
state inviate in una lista di discussione, o possono essere applicate ad una
parte del kernel per la quale non esiste un sottosistema dedicato.
Di conseguenza, -mm opera come una specie di sottosistema "ultima spiaggia";
se per una patch non esiste una via chiara per entrare nel ramo principale,
allora è probabile che finirà in -mm. Le patch passate per -mm
eventualmente finiranno nel sottosistema più appropriato o saranno inviate
direttamente a Linus. In un tipico ciclo di sviluppo, circa il 5-10% delle
patch andrà nel ramo principale attraverso -mm.
La patch -mm correnti sono disponibili nella cartella "mmotm" (-mm of
the moment) all'indirizzo:
http://www.ozlabs.org/~akpm/mmotm/
È molto probabile che l'uso dei sorgenti MMOTM diventi un'esperienza
frustrante; ci sono buone probabilità che non compili nemmeno.
I sorgenti principali per il prossimo ciclo d'integrazione delle patch
è linux-next, gestito da Stephen Rothwell. I sorgenti linux-next sono, per
definizione, un'istantanea di come dovrà apparire il ramo principale dopo che
la prossima finestra di inclusione si chiuderà. I linux-next sono annunciati
sulla lista di discussione linux-kernel e linux-next nel momento in cui
vengono assemblati; e possono essere scaricate da:
http://www.kernel.org/pub/linux/kernel/next/
Linux-next è divenuto parte integrante del processo di sviluppo del kernel;
tutte le patch incorporate durante una finestra di integrazione dovrebbero
aver trovato la propria strada in linux-next, a volte anche prima dell'apertura
della finestra di integrazione.
Sorgenti in preparazione
------------------------
Nei sorgenti del kernel esiste la cartella drivers/staging/, dove risiedono
molte sotto-cartelle per i driver o i filesystem che stanno per essere aggiunti
al kernel. Questi restano nella cartella drivers/staging fintanto che avranno
bisogno di maggior lavoro; una volta completato, possono essere spostate
all'interno del kernel nel posto più appropriato. Questo è il modo di tener
traccia dei driver che non sono ancora in linea con gli standard di codifica
o qualità, ma che le persone potrebbero voler usare ugualmente e tracciarne
lo sviluppo.
Greg Kroah-Hartman attualmente gestisce i sorgenti in preparazione. I driver
che non sono completamente pronti vengono inviati a lui, e ciascun driver avrà
la propria sotto-cartella in drivers/staging/. Assieme ai file sorgenti
dei driver, dovrebbe essere presente nella stessa cartella anche un file TODO.
Il file TODO elenca il lavoro ancora da fare su questi driver per poter essere
accettati nel kernel, e indica anche la lista di persone da inserire in copia
conoscenza per ogni modifica fatta. Le regole attuali richiedono che i
driver debbano, come minimo, compilare adeguatamente.
La *preparazione* può essere una via relativamente facile per inserire nuovi
driver all'interno del ramo principale, dove, con un po' di fortuna, saranno
notati da altri sviluppatori e migliorati velocemente. Entrare nella fase
di preparazione non è però la fine della storia, infatti, il codice che si
trova nella cartella staging che non mostra regolari progressi potrebbe
essere rimosso. Le distribuzioni, inoltre, tendono a dimostrarsi relativamente
riluttanti nell'attivare driver in preparazione. Quindi lo preparazione è,
nel migliore dei casi, una tappa sulla strada verso il divenire un driver
del ramo principale.
Strumenti
---------
Come è possibile notare dal testo sopra, il processo di sviluppo del kernel
dipende pesantemente dalla capacità di guidare la raccolta di patch in
diverse direzioni. L'intera cosa non funzionerebbe se non venisse svolta
con l'uso di strumenti appropriati e potenti. Spiegare l'uso di tali
strumenti non è lo scopo di questo documento, ma c'è spazio per alcuni
consigli.
In assoluto, nella comunità del kernel, predomina l'uso di git come sistema
di gestione dei sorgenti. Git è una delle diverse tipologie di sistemi
distribuiti di controllo versione che sono stati sviluppati nella comunità
del software libero. Esso è calibrato per lo sviluppo del kernel, e si
comporta abbastanza bene quando ha a che fare con repositori grandi e con un
vasto numero di patch. Git ha inoltre la reputazione di essere difficile
da imparare e utilizzare, benché stia migliorando. Agli sviluppatori
del kernel viene richiesta un po' di familiarità con git; anche se non lo
utilizzano per il proprio lavoro, hanno bisogno di git per tenersi al passo
con il lavoro degli altri sviluppatori (e con il ramo principale).
Git è ora compreso in quasi tutte le distribuzioni Linux. Esiste una sito che
potete consultare:
http://git-scm.com/
Qui troverete i riferimenti alla documentazione e alle guide passo-passo.
Tra gli sviluppatori Kernel che non usano git, la scelta alternativa più
popolare è quasi sicuramente Mercurial:
http://www.selenic.com/mercurial/
Mercurial condivide diverse caratteristiche con git, ma fornisce
un'interfaccia che potrebbe risultare più semplice da utilizzare.
L'altro strumento che vale la pena conoscere è Quilt:
http://savannah.nongnu.org/projects/quilt/
Quilt è un sistema di gestione delle patch, piuttosto che un sistema
di gestione dei sorgenti. Non mantiene uno storico degli eventi; ma piuttosto
è orientato verso il tracciamento di uno specifico insieme di modifiche
rispetto ad un codice in evoluzione. Molti dei più grandi manutentori di
sottosistema utilizzano quilt per gestire le patch che dovrebbero essere
integrate. Per la gestione di certe tipologie di sorgenti (-mm, per esempio),
quilt è il miglior strumento per svolgere il lavoro.
Liste di discussione
--------------------
Una grossa parte del lavoro di sviluppo del Kernel Linux viene svolto tramite
le liste di discussione. È difficile essere un membro della comunità
pienamente coinvolto se non si partecipa almeno ad una lista da qualche
parte. Ma, le liste di discussione di Linux rappresentano un potenziale
problema per gli sviluppatori, che rischiano di venir sepolti da un mare di
email, restare incagliati nelle convenzioni in vigore nelle liste Linux,
o entrambi.
Molte delle liste di discussione del Kernel girano su vger.kernel.org;
l'elenco principale lo si trova sul sito:
http://vger.kernel.org/vger-lists.html
Esistono liste gestite altrove; un certo numero di queste sono in
lists.redhat.com.
La lista di discussione principale per lo sviluppo del kernel è, ovviamente,
linux-kernel. Questa lista è un luogo ostile dove trovarsi; i volumi possono
raggiungere i 500 messaggi al giorno, la quantità di "rumore" è elevata,
la conversazione può essere strettamente tecnica e i partecipanti non sono
sempre preoccupati di mostrare un alto livello di educazione. Ma non esiste
altro luogo dove la comunità di sviluppo del kernel si unisce per intero;
gli sviluppatori che evitano tale lista si perderanno informazioni importanti.
Ci sono alcuni consigli che possono essere utili per sopravvivere a
linux-kernel:
- Tenete la lista in una cartella separata, piuttosto che inserirla nella
casella di posta principale. Così da essere in grado di ignorare il flusso
di mail per un certo periodo di tempo.
- Non cercate di seguire ogni conversazione - nessuno lo fa. È importante
filtrare solo gli argomenti d'interesse (sebbene va notato che le
conversazioni di lungo periodo possono deviare dall'argomento originario
senza cambiare il titolo della mail) e le persone che stanno partecipando.
- Non alimentate i troll. Se qualcuno cerca di creare nervosismo, ignoratelo.
- Quando rispondete ad una mail linux-kernel (o ad altre liste) mantenete
tutti i Cc:. In assenza di importanti motivazioni (come una richiesta
esplicita), non dovreste mai togliere destinatari. Assicuratevi sempre che
la persona alla quale state rispondendo sia presente nella lista Cc. Questa
usanza fa si che divenga inutile chiedere esplicitamente di essere inseriti
in copia nel rispondere al vostro messaggio.
- Cercate nell'archivio della lista (e nella rete nella sua totalità) prima
di far domande. Molti sviluppatori possono divenire impazienti con le
persone che chiaramente non hanno svolto i propri compiti a casa.
- Evitate il *top-posting* (cioè la pratica di mettere la vostra risposta sopra
alla frase alla quale state rispondendo). Ciò renderebbe la vostra risposta
difficile da leggere e genera scarsa impressione.
- Chiedete nella lista di discussione corretta. Linux-kernel può essere un
punto di incontro generale, ma non è il miglior posto dove trovare
sviluppatori da tutti i sottosistemi.
Infine, la ricerca della corretta lista di discussione è uno degli errori più
comuni per gli sviluppatori principianti. Qualcuno che pone una domanda
relativa alla rete su linux-kernel riceverà quasi certamente il suggerimento
di chiedere sulla lista netdev, che è la lista frequentata dagli sviluppatori
di rete. Ci sono poi altre liste per i sottosistemi SCSI, video4linux, IDE,
filesystem, etc. Il miglior posto dove cercare una lista di discussione è il
file MAINTAINERS che si trova nei sorgenti del kernel.
Iniziare con lo sviluppo del Kernel
-----------------------------------
Sono comuni le domande sul come iniziare con lo sviluppo del kernel - sia da
singole persone che da aziende. Altrettanto comuni sono i passi falsi che
rendono l'inizio di tale relazione più difficile di quello che dovrebbe essere.
Le aziende spesso cercano di assumere sviluppatori noti per creare un gruppo
di sviluppo iniziale. Questo, in effetti, può essere una tecnica efficace.
Ma risulta anche essere dispendiosa e non va ad accrescere il bacino di
sviluppatori kernel con esperienza. È possibile anche "portare a casa"
sviluppatori per accelerare lo sviluppo del kernel, dando comunque
all'investimento un po' di tempo. Prendersi questo tempo può fornire
al datore di lavoro un gruppo di sviluppatori che comprendono sia il kernel
che l'azienda stessa, e che possono supportare la formazione di altre persone.
Nel medio periodo, questa è spesso uno delle soluzioni più proficue.
I singoli sviluppatori sono spesso, comprensibilmente, una perdita come punto
di partenza. Iniziare con un grande progetto può rivelarsi intimidatorio;
spesso all'inizio si vuole solo verificare il terreno con qualcosa di piccolo.
Questa è una delle motivazioni per le quali molti sviluppatori saltano alla
creazione di patch che vanno a sistemare errori di battitura o
problematiche minori legate allo stile del codice. Sfortunatamente, tali
patch creano un certo livello di rumore che distrae l'intera comunità di
sviluppo, quindi, sempre di più, esse vengono degradate. I nuovi sviluppatori
che desiderano presentarsi alla comunità non riceveranno l'accoglienza
che vorrebbero con questi mezzi.
Andrew Morton da questo consiglio agli aspiranti sviluppatori kernel
::
Il primo progetto per un neofita del kernel dovrebbe essere
sicuramente quello di "assicurarsi che il kernel funzioni alla
perfezione sempre e su tutte le macchine sulle quali potete stendere
la vostra mano". Solitamente il modo per fare ciò è quello di
collaborare con gli altri nel sistemare le cose (questo richiede
persistenza!) ma va bene - è parte dello sviluppo kernel.
(http://lwn.net/Articles/283982/).
In assenza di problemi ovvi da risolvere, si consiglia agli sviluppatori
di consultare, in generale, la lista di regressioni e di bachi aperti.
Non c'è mai carenza di problematiche bisognose di essere sistemate;
accollandosi tali questioni gli sviluppatori accumuleranno esperienza con
la procedura, ed allo stesso tempo, aumenteranno la loro rispettabilità
all'interno della comunità di sviluppo.

View File

@ -0,0 +1,241 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/3.Early-stage.rst <development_early_stage>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_early_stage:
I primi passi della pianificazione
==================================
Osservando un progetto di sviluppo per il kernel Linux, si potrebbe essere
tentati dal saltare tutto e iniziare a codificare. Tuttavia, come ogni
progetto significativo, molta della preparazione per giungere al successo
viene fatta prima che una sola linea di codice venga scritta. Il tempo speso
nella pianificazione e la comunicazione può far risparmiare molto
tempo in futuro.
Specificare il problema
-----------------------
Come qualsiasi progetto ingegneristico, un miglioramento del kernel di
successo parte con una chiara descrizione del problema da risolvere.
In alcuni casi, questo passaggio è facile: ad esempio quando un driver è
richiesto per un particolare dispositivo. In altri casi invece, si
tende a confondere il problema reale con le soluzioni proposte e questo
può portare all'emergere di problemi.
Facciamo un esempio: qualche anno fa, gli sviluppatori che lavoravano con
linux audio cercarono un modo per far girare le applicazioni senza dropouts
o altri artefatti dovuti all'eccessivo ritardo nel sistema. La soluzione
alla quale giunsero fu un modulo del kernel destinato ad agganciarsi al
framework Linux Security Module (LSM); questo modulo poteva essere
configurato per dare ad una specifica applicazione accesso allo
schedulatore *realtime*. Tale modulo fu implementato e inviato nella
lista di discussione linux-kernel, dove incontrò subito dei problemi.
Per gli sviluppatori audio, questo modulo di sicurezza era sufficiente a
risolvere il loro problema nell'immediato. Per l'intera comunità kernel,
invece, era un uso improprio del framework LSM (che non è progettato per
conferire privilegi a processi che altrimenti non avrebbero potuto ottenerli)
e un rischio per la stabilità del sistema. Le loro soluzioni di punta nel
breve periodo, comportavano un accesso alla schedulazione realtime attraverso
il meccanismo rlimit, e nel lungo periodo un costante lavoro nella riduzione
dei ritardi.
La comunità audio, comunque, non poteva vedere al di là della singola
soluzione che avevano implementato; erano riluttanti ad accettare alternative.
Il conseguente dissenso lasciò in quegli sviluppatori un senso di
disillusione nei confronti dell'intero processo di sviluppo; uno di loro
scrisse questo messaggio:
Ci sono numerosi sviluppatori del kernel Linux davvero bravi, ma
rischiano di restare sovrastati da una vasta massa di stolti arroganti.
Cercare di comunicare le richieste degli utenti a queste persone è
una perdita di tempo. Loro sono troppo "intelligenti" per stare ad
ascoltare dei poveri mortali.
(http://lwn.net/Articles/131776/).
La realtà delle cose fu differente; gli sviluppatori del kernel erano molto
più preoccupati per la stabilità del sistema, per la manutenzione di lungo
periodo e cercavano la giusta soluzione alla problematica esistente con uno
specifico modulo. La morale della storia è quella di concentrarsi sul
problema - non su di una specifica soluzione- e di discuterne con la comunità
di sviluppo prima di investire tempo nella scrittura del codice.
Quindi, osservando un progetto di sviluppo del kernel, si dovrebbe
rispondere a questa lista di domande:
- Qual'è, precisamente, il problema che dev'essere risolto?
- Chi sono gli utenti coinvolti da tal problema? A quale caso dovrebbe
essere indirizzata la soluzione?
- In che modo il kernel risulta manchevole nell'indirizzare il problema
in questione?
Solo dopo ha senso iniziare a considerare le possibili soluzioni.
Prime discussioni
-----------------
Quando si pianifica un progetto di sviluppo per il kernel, sarebbe quanto meno
opportuno discuterne inizialmente con la comunità prima di lanciarsi
nell'implementazione. Una discussione preliminare può far risparmiare sia
tempo che problemi in svariati modi:
- Potrebbe essere che il problema sia già stato risolto nel kernel in
una maniera che non avete ancora compreso. Il kernel Linux è grande e ha
una serie di funzionalità e capacità che non sono scontate nell'immediato.
Non tutte le capacità del kernel sono documentate così bene come ci
piacerebbe, ed è facile perdersi qualcosa. Il vostro autore ha assistito
alla pubblicazione di un driver intero che duplica un altro driver
esistente di cui il nuovo autore era ignaro. Il codice che rinnova
ingranaggi già esistenti non è soltanto dispendioso; non verrà nemmeno
accettato nel ramo principale del kernel.
- Potrebbero esserci proposte che non sono considerate accettabili per
l'integrazione all'interno del ramo principale. È meglio affrontarle
prima di scrivere il codice.
- È possibile che altri sviluppatori abbiano pensato al problema; potrebbero
avere delle idee per soluzioni migliori, e potrebbero voler contribuire
alla loro creazione.
Anni di esperienza con la comunità di sviluppo del kernel hanno impartito una
chiara lezione: il codice per il kernel che è pensato e sviluppato a porte
chiuse, inevitabilmente, ha problematiche che si rivelano solo quando il
codice viene rilasciato pubblicamente. Qualche volta tali problemi sono
importanti e richiedono mesi o anni di sforzi prima che il codice possa
raggiungere gli standard richiesti della comunità.
Alcuni esempi possono essere:
- La rete Devicescape è stata creata e implementata per sistemi
mono-processore. Non avrebbe potuto essere inserita nel ramo principale
fino a che non avesse supportato anche i sistemi multi-processore.
Riadattare i meccanismi di sincronizzazione e simili è un compito difficile;
come risultato, l'inserimento di questo codice (ora chiamato mac80211)
fu rimandato per più di un anno.
- Il filesystem Reiser4 include una seria di funzionalità che, secondo
l'opinione degli sviluppatori principali del kernel, avrebbero dovuto
essere implementate a livello di filesystem virtuale. Comprende
anche funzionalità che non sono facilmente implementabili senza esporre
il sistema al rischio di uno stallo. La scoperta tardiva di questi
problemi - e il diniego a risolverne alcuni - ha avuto come conseguenza
il fatto che Raiser4 resta fuori dal ramo principale del kernel.
- Il modulo di sicurezza AppArmor utilizzava strutture dati del
filesystem virtuale interno in modi che sono stati considerati rischiosi e
inattendibili. Questi problemi (tra le altre cose) hanno tenuto AppArmor
fuori dal ramo principale per anni.
Ciascuno di questi casi è stato un travaglio e ha richiesto del lavoro
straordinario, cose che avrebbero potuto essere evitate con alcune
"chiacchierate" preliminari con gli sviluppatori kernel.
Con chi parlare?
----------------
Quando gli sviluppatori hanno deciso di rendere pubblici i propri progetti, la
domanda successiva sarà: da dove partiamo? La risposta è quella di trovare
la giusta lista di discussione e il giusto manutentore. Per le liste di
discussione, il miglior approccio è quello di cercare la lista più adatta
nel file MAINTAINERS. Se esiste una lista di discussione di sottosistema,
è preferibile pubblicare lì piuttosto che sulla lista di discussione generale
del kernel Linux; avrete maggiori probabilità di trovare sviluppatori con
esperienza sul tema, e l'ambiente che troverete potrebbe essere più
incoraggiante.
Trovare manutentori può rivelarsi un po' difficoltoso. Ancora, il file
MAINTAINERS è il posto giusto da dove iniziare. Il file potrebbe non essere
sempre aggiornato, inoltre, non tutti i sottosistemi sono rappresentati qui.
Coloro che sono elencati nel file MAINTAINERS potrebbero, in effetti, non
essere le persone che attualmente svolgono quel determinato ruolo. Quindi,
quando c'è un dubbio su chi contattare, un trucco utile è quello di usare
git (git log in particolare) per vedere chi attualmente è attivo all'interno
del sottosistema interessato. Controllate chi sta scrivendo le patch,
e chi, se non ci fosse nessuno, sta aggiungendo la propria firma
(Signed-off-by) a quelle patch. Quelle sono le persone maggiormente
qualificate per aiutarvi con lo sviluppo di nuovo progetto.
Il compito di trovare il giusto manutentore, a volte, è una tale sfida che
ha spinto gli sviluppatori del kernel a scrivere uno script che li aiutasse
in questa ricerca:
::
.../scripts/get_maintainer.pl
Se questo script viene eseguito con l'opzione "-f" ritornerà il
manutentore(i) attuale per un dato file o cartella. Se viene passata una
patch sulla linea di comando, lo script elencherà i manutentori che
dovrebbero riceverne una copia. Ci sono svariate opzioni che regolano
quanto a fondo get_maintainer.pl debba cercare i manutentori;
siate quindi prudenti nell'utilizzare le opzioni più aggressive poiché
potreste finire per includere sviluppatori che non hanno un vero interesse
per il codice che state modificando.
Se tutto ciò dovesse fallire, parlare con Andrew Morton potrebbe essere
un modo efficace per capire chi è il manutentore di un dato pezzo di codice.
Quando pubblicare
-----------------
Se potete, pubblicate i vostri intenti durante le fasi preliminari, sarà
molto utile. Descrivete il problema da risolvere e ogni piano che è stato
elaborato per l'implementazione. Ogni informazione fornita può aiutare
la comunità di sviluppo a fornire spunti utili per il progetto.
Un evento che potrebbe risultare scoraggiate e che potrebbe accadere in
questa fase non è il ricevere una risposta ostile, ma, invece, ottenere
una misera o inesistente reazione. La triste verità è che: (1) gli
sviluppatori del kernel tendono ad essere occupati, (2) ci sono tante persone
con grandi progetti e poco codice (o anche solo la prospettiva di
avere un codice) a cui riferirsi e (3) nessuno è obbligato a revisionare
o a fare osservazioni in merito ad idee pubblicate da altri. Oltre a
questo, progetti di alto livello spesso nascondono problematiche che si
rivelano solo quando qualcuno cerca di implementarle; per questa ragione
gli sviluppatori kernel preferirebbero vedere il codice.
Quindi, se una richiesta pubblica di commenti riscuote poco successo, non
pensate che ciò significhi che non ci sia interesse nel progetto.
Sfortunatamente, non potete nemmeno assumere che non ci siano problemi con
la vostra idea. La cosa migliore da fare in questa situazione è quella di
andare avanti e tenere la comunità informata mentre procedete.
Ottenere riscontri ufficiali
----------------------------
Se il vostro lavoro è stato svolto in un ambiente aziendale - come molto
del lavoro fatto su Linux - dovete, ovviamente, avere il permesso dei
dirigenti prima che possiate pubblicare i progetti, o il codice aziendale,
su una lista di discussione pubblica. La pubblicazione di codice che non
è stato rilascio espressamente con licenza GPL-compatibile può rivelarsi
problematico; prima la dirigenza, e il personale legale, troverà una decisione
sulla pubblicazione di un progetto, meglio sarà per tutte le persone coinvolte.
A questo punto, alcuni lettori potrebbero pensare che il loro lavoro sul
kernel è preposto a supportare un prodotto che non è ancora ufficialmente
riconosciuto. Rivelare le intenzioni dei propri datori di lavori in una
lista di discussione pubblica potrebbe non essere una soluzione valida.
In questi casi, vale la pena considerare se la segretezza sia necessaria
o meno; spesso non c'è una reale necessità di mantenere chiusi i progetti di
sviluppo.
Detto ciò, ci sono anche casi dove l'azienda legittimamente non può rivelare
le proprie intenzioni in anticipo durante il processo di sviluppo. Le aziende
che hanno sviluppatori kernel esperti possono scegliere di procedere a
carte coperte partendo dall'assunto che saranno in grado di evitare, o gestire,
in futuro, eventuali problemi d'integrazione. Per le aziende senza questo tipo
di esperti, la migliore opzione è spesso quella di assumere uno sviluppatore
esterno che revisioni i progetti con un accordo di segretezza.
La Linux Foundation applica un programma di NDA creato appositamente per
aiutare le aziende in questa particolare situazione; potrete trovare più
informazioni sul sito:
http://www.linuxfoundation.org/en/NDA_program
Questa tipologia di revisione è spesso sufficiente per evitare gravi problemi
senza che sia richiesta l'esposizione pubblica del progetto.

View File

@ -0,0 +1,447 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/4.Coding.rst <development_coding>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_coding:
Scrivere codice corretto
========================
Nonostante ci sia molto da dire sul processo di creazione, sulla sua solidità
e sul suo orientamento alla comunità, la prova di ogni progetto di sviluppo
del kernel si trova nel codice stesso. È il codice che sarà esaminato dagli
altri sviluppatori ed inserito (o no) nel ramo principale. Quindi è la
qualità di questo codice che determinerà il successo finale del progetto.
Questa sezione esaminerà il processo di codifica. Inizieremo con uno sguardo
sulle diverse casistiche nelle quali gli sviluppatori kernel possono
sbagliare. Poi, l'attenzione si sposterà verso "il fare le cose
correttamente" e sugli strumenti che possono essere utili in questa missione.
Trappole
--------
Lo stile del codice
*******************
Il kernel ha da tempo delle norme sullo stile di codifica che sono descritte in
:ref:`Documentation/translations/it_IT/process/coding-style.rst <codingstyle>`.
Per la maggior parte del tempo, la politica descritta in quel file è stata
praticamente informativa. Ne risulta che ci sia una quantità sostanziale di
codice nel kernel che non rispetta le linee guida relative allo stile.
La presenza di quel codice conduce a due distinti pericoli per gli
sviluppatori kernel.
Il primo di questi è credere che gli standard di codifica del kernel
non sono importanti e possono non essere applicati. La verità è che
aggiungere nuovo codice al kernel è davvero difficile se questo non
rispetta le norme; molti sviluppatori richiederanno che il codice sia
riformulato prima che anche solo lo revisionino. Una base di codice larga
quanto il kernel richiede una certa uniformità, in modo da rendere possibile
per gli sviluppatori una comprensione veloce di ogni sua parte. Non ci sono,
quindi, più spazi per un codice formattato alla carlona.
Occasionalmente, lo stile di codifica del kernel andrà in conflitto con lo
stile richiesto da un datore di lavoro. In alcuni casi, lo stile del kernel
dovrà prevalere prima che il codice venga inserito. Mettere il codice
all'interno del kernel significa rinunciare a un certo grado di controllo
in differenti modi - incluso il controllo sul come formattare il codice.
Laltra trappola è quella di pensare che il codice già presente nel kernel
abbia urgentemente bisogno di essere sistemato. Gli sviluppatori potrebbero
iniziare a generare patch che correggono lo stile come modo per prendere
famigliarità con il processo, o come modo per inserire i propri nomi nei
changelog del kernel o entrambe. La comunità di sviluppo vede un attività
di codifica puramente correttiva come "rumore"; queste attività riceveranno
una fredda accoglienza. Di conseguenza è meglio evitare questo tipo di patch.
Mentre si lavora su un pezzo di codice è normale correggerne anche lo stile,
ma le modifiche di stile non dovrebbero essere fatte fini a se stesse.
Il documento sullo stile del codice non dovrebbe essere letto come una legge
assoluta che non può mai essere trasgredita. Se cè un a buona ragione
(per esempio, una linea che diviene poco leggibile se divisa per rientrare
nel limite di 80 colonne), fatelo e basta.
Notate che potete utilizzare lo strumento “clang-format” per aiutarvi con
le regole, per una riformattazione automatica e veloce del vostro codice
e per revisionare interi file per individuare errori nello stile di codifica,
refusi e possibili miglioramenti. Inoltre è utile anche per classificare gli
``#includes``, per allineare variabili/macro, per testi derivati ed altri
compiti del genere. Consultate il file
:ref:`Documentation/translations/it_IT/process/clang-format.rst <clangformat>`
per maggiori dettagli
Livelli di astrazione
*********************
I professori di Informatica insegnano ai propri studenti a fare ampio uso dei
livelli di astrazione nel nome della flessibilità e del nascondere informazioni.
Certo il kernel fa un grande uso dell'astrazione; nessun progetto con milioni
di righe di codice potrebbe fare altrimenti e sopravvivere. Ma l'esperienza
ha dimostrato che un'eccessiva o prematura astrazione può rivelarsi dannosa
al pari di una prematura ottimizzazione. L'astrazione dovrebbe essere usata
fino al livello necessario e non oltre.
Ad un livello base, considerate una funzione che ha un argomento che viene
sempre impostato a zero da tutti i chiamanti. Uno potrebbe mantenere
quell'argomento nell'eventualità qualcuno volesse sfruttare la flessibilità
offerta. In ogni caso, tuttavia, ci sono buone possibilità che il codice
che va ad implementare questo argomento aggiuntivo, sia stato rotto in maniera
sottile, in un modo che non è mai stato notato - perché non è mai stato usato.
Oppure, quando sorge la necessità di avere più flessibilità, questo argomento
non la fornisce in maniera soddisfacente. Gli sviluppatori di Kernel,
sottopongono costantemente patch che vanno a rimuovere gli argomenti
inutilizzate; anche se, in generale, non avrebbero dovuto essere aggiunti.
I livelli di astrazione che nascondono l'accesso all'hardware -
spesso per poter usare dei driver su diversi sistemi operativi - vengono
particolarmente disapprovati. Tali livelli oscurano il codice e possono
peggiorare le prestazioni; essi non appartengono al kernel Linux.
D'altro canto, se vi ritrovate a dover copiare una quantità significativa di
codice proveniente da un altro sottosistema del kernel, è tempo di chiedersi
se, in effetti, non avrebbe più senso togliere parte di quel codice e metterlo
in una libreria separata o di implementare quella funzionalità ad un livello
più elevato. Non c'è utilità nel replicare lo stesso codice per tutto
il kernel.
#ifdef e l'uso del preprocessore in generale
********************************************
Il preprocessore C sembra essere una fonte di attrazione per qualche
programmatore C, che ci vede una via per ottenere una grande flessibilità
all'interno di un file sorgente. Ma il preprocessore non è scritto in C,
e un suo massiccio impiego conduce a un codice che è molto più difficile
da leggere per gli altri e che rende più difficile il lavoro di verifica del
compilatore. L'uso eccessivo del preprocessore è praticamente sempre il segno
di un codice che necessita di un certo lavoro di pulizia.
La compilazione condizionata con #ifdef è, in effetti, un potente strumento,
ed esso viene usato all'interno del kernel. Ma esiste un piccolo desiderio:
quello di vedere il codice coperto solo da una leggera spolverata di
blocchi #ifdef. Come regola generale, quando possibile, l'uso di #ifdef
dovrebbe essere confinato nei file d'intestazione. Il codice compilato
condizionatamente può essere confinato a funzioni tali che, nel caso in cui
il codice non deve essere presente, diventano vuote. Il compilatore poi
ottimizzerà la chiamata alla funzione vuota rimuovendola. Il risultato è
un codice molto più pulito, più facile da seguire.
Le macro del preprocessore C presentano una serie di pericoli, inclusi
valutazioni multiple di espressioni che hanno effetti collaterali e non
garantiscono una sicurezza rispetto ai tipi. Se siete tentati dal definire
una macro, considerate l'idea di creare invece una funzione inline. Il codice
che ne risulterà sarà lo stesso, ma le funzioni inline sono più leggibili,
non considerano i propri argomenti più volte, e permettono al compilatore di
effettuare controlli sul tipo degli argomenti e del valore di ritorno.
Funzioni inline
***************
Comunque, anche le funzioni inline hanno i loro pericoli. I programmatori
potrebbero innamorarsi dell'efficienza percepita derivata dalla rimozione
di una chiamata a funzione. Queste funzioni, tuttavia, possono ridurre le
prestazioni. Dato che il loro codice viene replicato ovunque vi sia una
chiamata ad esse, si finisce per gonfiare le dimensioni del kernel compilato.
Questi, a turno, creano pressione sulla memoria cache del processore, e questo
può causare rallentamenti importanti. Le funzioni inline, di norma, dovrebbero
essere piccole e usate raramente. Il costo di una chiamata a funzione, dopo
tutto, non è così alto; la creazione di molte funzioni inline è il classico
esempio di un'ottimizzazione prematura.
In generale, i programmatori del kernel ignorano gli effetti della cache a
loro rischio e pericolo. Il classico compromesso tempo/spazio teorizzato
all'inizio delle lezioni sulle strutture dati spesso non si applica
all'hardware moderno. Lo spazio *è* tempo, in questo senso un programma
più grande sarà più lento rispetto ad uno più compatto.
I compilatori più recenti hanno preso un ruolo attivo nel decidere se
una data funzione deve essere resa inline oppure no. Quindi l'uso
indiscriminato della parola chiave "inline" potrebbe non essere non solo
eccessivo, ma anche irrilevante.
Sincronizzazione
****************
Nel maggio 2006, il sistema di rete "Devicescape" fu rilasciato in pompa magna
sotto la licenza GPL e reso disponibile per la sua inclusione nella ramo
principale del kernel. Questa donazione fu una notizia bene accolta;
il supporto per le reti senza fili era considerata, nel migliore dei casi,
al di sotto degli standard; il sistema Deviscape offrì la promessa di una
risoluzione a tale situazione. Tuttavia, questo codice non fu inserito nel
ramo principale fino al giugno del 2007 (2.6.22). Cosa accadde?
Quel codice mostrava numerosi segnali di uno sviluppo in azienda avvenuto
a porte chiuse. Ma in particolare, un grosso problema fu che non fu
progettato per girare in un sistema multiprocessore. Prima che questo
sistema di rete (ora chiamato mac80211) potesse essere inserito, fu necessario
un lavoro sugli schemi di sincronizzazione.
Una volta, il codice del kernel Linux poteva essere sviluppato senza pensare
ai problemi di concorrenza presenti nei sistemi multiprocessore. Ora,
comunque, questo documento è stato scritto su di un portatile dual-core.
Persino su sistemi a singolo processore, il lavoro svolto per incrementare
la capacità di risposta aumenterà il livello di concorrenza interno al kernel.
I giorni nei quali il codice poteva essere scritto senza pensare alla
sincronizzazione sono da passati tempo.
Ogni risorsa (strutture dati, registri hardware, etc.) ai quali si potrebbe
avere accesso simultaneo da più di un thread deve essere sincronizzato. Il
nuovo codice dovrebbe essere scritto avendo tale accortezza in testa;
riadattare la sincronizzazione a posteriori è un compito molto più difficile.
Gli sviluppatori del kernel dovrebbero prendersi il tempo di comprendere bene
le primitive di sincronizzazione, in modo da sceglier lo strumento corretto
per eseguire un compito. Il codice che presenta una mancanza di attenzione
alla concorrenza avrà un percorso difficile all'interno del ramo principale.
Regressioni
***********
Vale la pena menzionare un ultimo pericolo: potrebbe rivelarsi accattivante
l'idea di eseguire un cambiamento (che potrebbe portare a grandi
miglioramenti) che porterà ad alcune rotture per gli utenti esistenti.
Questa tipologia di cambiamento è chiamata "regressione", e le regressioni son
diventate mal viste nel ramo principale del kernel. Con alcune eccezioni,
i cambiamenti che causano regressioni saranno fermati se quest'ultime non
potranno essere corrette in tempo utile. È molto meglio quindi evitare
la regressione fin dall'inizio.
Spesso si è argomentato che una regressione può essere giustificata se essa
porta risolve più problemi di quanti non ne crei. Perché, dunque, non fare
un cambiamento se questo porta a nuove funzionalità a dieci sistemi per
ognuno dei quali esso determina una rottura? La migliore risposta a questa
domanda ci è stata fornita da Linus nel luglio 2007:
::
Dunque, noi non sistemiamo bachi introducendo nuovi problemi. Quella
via nasconde insidie, e nessuno può sapere del tutto se state facendo
dei progressi reali. Sono due passi avanti e uno indietro, oppure
un passo avanti e due indietro?
(http://lwn.net/Articles/243460/).
Una particolare tipologia di regressione mal vista consiste in una qualsiasi
sorta di modifica all'ABI dello spazio utente. Una volta che un'interfaccia
viene esportata verso lo spazio utente, dev'essere supportata all'infinito.
Questo fatto rende la creazione di interfacce per lo spazio utente
particolarmente complicato: dato che non possono venir cambiate introducendo
incompatibilità, esse devono essere fatte bene al primo colpo. Per questa
ragione sono sempre richieste: ampie riflessioni, documentazione chiara e
ampie revisioni dell'interfaccia verso lo spazio utente.
Strumenti di verifica del codice
--------------------------------
Almeno per ora la scrittura di codice priva di errori resta un ideale
irraggiungibile ai più. Quello che speriamo di poter fare, tuttavia, è
trovare e correggere molti di questi errori prima che il codice entri nel
ramo principale del kernel. A tal scopo gli sviluppatori del kernel devono
mettere insieme una schiera impressionante di strumenti che possano
localizzare automaticamente un'ampia varietà di problemi. Qualsiasi problema
trovato dal computer è un problema che non affliggerà l'utente in seguito,
ne consegue che gli strumenti automatici dovrebbero essere impiegati ovunque
possibile.
Il primo passo consiste semplicemente nel fare attenzione agli avvertimenti
proveniente dal compilatore. Versioni moderne di gcc possono individuare
(e segnalare) un gran numero di potenziali errori. Molto spesso, questi
avvertimenti indicano problemi reali. Di regola, il codice inviato per la
revisione non dovrebbe produrre nessun avvertimento da parte del compilatore.
Per mettere a tacere gli avvertimenti, cercate di comprenderne le cause reali
e cercate di evitare le "riparazioni" che fan sparire l'avvertimento senza
però averne trovato la causa.
Tenete a mente che non tutti gli avvertimenti sono disabilitati di default.
Costruite il kernel con "make EXTRA_CFLAGS=-W" per ottenerli tutti.
Il kernel fornisce differenti opzioni che abilitano funzionalità di debugging;
molti di queste sono trovano all'interno del sotto menu "kernel hacking".
La maggior parte di queste opzioni possono essere attivate per qualsiasi
kernel utilizzato per lo sviluppo o a scopo di test. In particolare dovreste
attivare:
- ENABLE_WARN_DEPRECATED, ENABLE_MUST_CHECK, e FRAME_WARN per ottenere degli
avvertimenti dedicati a problemi come l'uso di interfacce deprecate o
l'ignorare un importante valore di ritorno di una funzione. Il risultato
generato da questi avvertimenti può risultare verboso, ma non bisogna
preoccuparsi per gli avvertimenti provenienti da altre parti del kernel.
- DEBUG_OBJECTS aggiungerà un codice per tracciare il ciclo di vita di
diversi oggetti creati dal kernel e avvisa quando qualcosa viene eseguito
fuori controllo. Se state aggiungendo un sottosistema che crea (ed
esporta) oggetti complessi propri, considerate l'aggiunta di un supporto
al debugging dell'oggetto.
- DEBUG_SLAB può trovare svariati errori di uso e di allocazione di memoria;
esso dovrebbe esser usato dalla maggior parte dei kernel di sviluppo.
- DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP, e DEBUG_MUTEXES troveranno un certo
numero di errori comuni di sincronizzazione.
Esistono ancora delle altre opzioni di debugging, di alcune di esse
discuteremo qui sotto. Alcune di esse hanno un forte impatto e non dovrebbero
essere usate tutte le volte. Ma qualche volta il tempo speso nell'capire
le opzioni disponibili porterà ad un risparmio di tempo nel breve termine.
Uno degli strumenti di debugging più tosti è il *locking checker*, o
"lockdep". Questo strumento traccerà qualsiasi acquisizione e rilascio di
ogni *lock* (spinlock o mutex) nel sistema, l'ordine con il quale i *lock*
sono acquisiti in relazione l'uno con l'altro, l'ambiente corrente di
interruzione, eccetera. Inoltre esso può assicurare che i *lock* vengano
acquisiti sempre nello stesso ordine, che le stesse assunzioni sulle
interruzioni si applichino in tutte le occasioni, e così via. In altre parole,
lockdep può scovare diversi scenari nei quali il sistema potrebbe, in rari
casi, trovarsi in stallo. Questa tipologia di problema può essere grave
(sia per gli sviluppatori che per gli utenti) in un sistema in uso; lockdep
permette di trovare tali problemi automaticamente e in anticipo.
In qualità di programmatore kernel diligente, senza dubbio, dovrete controllare
il valore di ritorno di ogni operazione (come l'allocazione della memoria)
poiché esso potrebbe fallire. Il nocciolo della questione è che i percorsi
di gestione degli errori, con grande probabilità, non sono mai stati
collaudati del tutto. Il codice collaudato tende ad essere codice bacato;
potrete quindi essere più a vostro agio con il vostro codice se tutti questi
percorsi fossero stati verificati un po' di volte.
Il kernel fornisce un framework per l'inserimento di fallimenti che fa
esattamente al caso, specialmente dove sono coinvolte allocazioni di memoria.
Con l'opzione per l'inserimento dei fallimenti abilitata, una certa percentuale
di allocazione di memoria sarà destinata al fallimento; questi fallimenti
possono essere ridotti ad uno specifico pezzo di codice. Procedere con
l'inserimento dei fallimenti attivo permette al programmatore di verificare
come il codice risponde quando le cose vanno male. Consultate:
Documentation/fault-injection/fault-injection.txt per avere maggiori
informazioni su come utilizzare questo strumento.
Altre tipologie di errori possono essere riscontrati con lo strumento di
analisi statica "sparse". Con Sparse, il programmatore può essere avvisato
circa la confusione tra gli indirizzi dello spazio utente e dello spazio
kernel, un miscuglio fra quantità big-endian e little-endian, il passaggio
di un valore intero dove ci sia aspetta un gruppo di flag, e così via.
Sparse deve essere installato separatamente (se il vostra distribuzione non
lo prevede, potete trovarlo su https://sparse.wiki.kernel.org/index.php/Main_Page);
può essere attivato sul codice aggiungendo "C=1" al comando make.
Lo strumento "Coccinelle" (http://coccinelle.lip6.fr/) è in grado di trovare
una vasta varietà di potenziali problemi di codifica; e può inoltre proporre
soluzioni per risolverli. Un buon numero di "patch semantiche" per il kernel
sono state preparate nella cartella scripts/coccinelle; utilizzando
"make coccicheck" esso percorrerà tali patch semantiche e farà rapporto su
qualsiasi problema trovato. Per maggiori informazioni, consultate
:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`.
Altri errori di portabilità sono meglio scovati compilando il vostro codice
per altre architetture. Se non vi accade di avere un sistema S/390 o una
scheda di sviluppo Blackfin sotto mano, potete comunque continuare la fase
di compilazione. Un vasto numero di cross-compilatori per x86 possono
essere trovati al sito:
http://www.kernel.org/pub/tools/crosstool/
Il tempo impiegato nell'installare e usare questi compilatori sarà d'aiuto
nell'evitare situazioni imbarazzanti nel futuro.
Documentazione
--------------
La documentazione è spesso stata più un'eccezione che una regola nello
sviluppo del kernel. Nonostante questo, un'adeguata documentazione aiuterà
a facilitare l'inserimento di nuovo codice nel kernel, rende la vita più
facile per gli altri sviluppatori e sarà utile per i vostri utenti. In molti
casi, la documentazione è divenuta sostanzialmente obbligatoria.
La prima parte di documentazione per qualsiasi patch è il suo changelog.
Questi dovrebbero descrivere le problematiche risolte, la tipologia di
soluzione, le persone che lavorano alla patch, ogni effetto rilevante
sulle prestazioni e tutto ciò che può servire per la comprensione della
patch. Assicuratevi che il changelog dica *perché*, vale la pena aggiungere
la patch; un numero sorprendente di sviluppatori sbaglia nel fornire tale
informazione.
Qualsiasi codice che aggiunge una nuova interfaccia in spazio utente - inclusi
nuovi file in sysfs o /proc - dovrebbe includere la documentazione di tale
interfaccia così da permette agli sviluppatori dello spazio utente di sapere
con cosa stanno lavorando. Consultate: Documentation/ABI/README per avere una
descrizione di come questi documenti devono essere impostati e quali
informazioni devono essere fornite.
Il file :ref:`Documentation/translations/it_IT/admin-guide/kernel-parameters.rst <kernelparameters>`
descrive tutti i parametri di avvio del kernel. Ogni patch che aggiunga
nuovi parametri dovrebbe aggiungere nuove voci a questo file.
Ogni nuova configurazione deve essere accompagnata da un testo di supporto
che spieghi chiaramente le opzioni e spieghi quando l'utente potrebbe volerle
selezionare.
Per molti sottosistemi le informazioni sull'API interna sono documentate sotto
forma di commenti formattati in maniera particolare; questi commenti possono
essere estratti e formattati in differenti modi attraverso lo script
"kernel-doc". Se state lavorando all'interno di un sottosistema che ha
commenti kerneldoc dovreste mantenerli e aggiungerli, in maniera appropriata,
per le funzioni disponibili esternamente. Anche in aree che non sono molto
documentate, non c'è motivo per non aggiungere commenti kerneldoc per il
futuro; infatti, questa può essere un'attività utile per sviluppatori novizi
del kernel. Il formato di questi commenti, assieme alle informazione su come
creare modelli per kerneldoc, possono essere trovati in
:ref:`Documentation/translations/it_IT/doc-guide/ <doc_guide>`.
Chiunque legga un ammontare significativo di codice kernel noterà che, spesso,
i commenti si fanno maggiormente notare per la loro assenza. Ancora una volta,
le aspettative verso il nuovo codice sono più alte rispetto al passato;
inserire codice privo di commenti sarà più difficile. Detto ciò, va aggiunto
che non si desiderano commenti prolissi per il codice. Il codice dovrebbe
essere, di per sé, leggibile, con dei commenti che spieghino gli aspetti più
sottili.
Determinate cose dovrebbero essere sempre commentate. L'uso di barriere
di memoria dovrebbero essere accompagnate da una riga che spieghi perché sia
necessaria. Le regole di sincronizzazione per le strutture dati, generalmente,
necessitano di una spiegazioni da qualche parte. Le strutture dati più
importanti, in generale, hanno bisogno di una documentazione onnicomprensiva.
Le dipendenze che non sono ovvie tra bit separati di codice dovrebbero essere
indicate. Tutto ciò che potrebbe indurre un inserviente del codice a fare
una "pulizia" incorretta, ha bisogno di un commento che dica perché è stato
fatto in quel modo. E così via.
Cambiamenti interni dell'API
----------------------------
L'interfaccia binaria fornita dal kernel allo spazio utente non può essere
rotta tranne che in circostanze eccezionali. L'interfaccia di programmazione
interna al kernel, invece, è estremamente fluida e può essere modificata al
bisogno. Se vi trovate a dover lavorare attorno ad un'API del kernel o
semplicemente non state utilizzando una funzionalità offerta perché questa
non rispecchia i vostri bisogni, allora questo potrebbe essere un segno che
l'API ha bisogno di essere cambiata. In qualità di sviluppatore del kernel,
hai il potere di fare questo tipo di modifica.
Ci sono ovviamente alcuni punti da cogliere. I cambiamenti API possono essere
fatti, ma devono essere giustificati. Quindi ogni patch che porta ad una
modifica dell'API interna dovrebbe essere accompagnata da una descrizione
della modifica in sé e del perché essa è necessaria. Questo tipo di
cambiamenti dovrebbero, inoltre, essere fatti in una patch separata, invece di
essere sepolti all'interno di una patch più grande.
L'altro punto da cogliere consiste nel fatto che uno sviluppatore che
modifica l'API deve, in generale, essere responsabile della correzione
di tutto il codice del kernel che viene rotto per via della sua modifica.
Per una funzione ampiamente usata, questo compito può condurre letteralmente
a centinaia o migliaia di modifiche, molte delle quali sono in conflitto con
il lavoro svolto da altri sviluppatori. Non c'è bisogno di dire che questo
può essere un lavoro molto grosso, quindi è meglio essere sicuri che la
motivazione sia ben solida. Notate che lo strumento Coccinelle può fornire
un aiuto con modifiche estese dell'API.
Quando viene fatta una modifica API incompatibile, una persona dovrebbe,
quando possibile, assicurarsi che quel codice non aggiornato sia trovato
dal compilatore. Questo vi aiuterà ad essere sicuri d'avere trovato,
tutti gli usi di quell'interfaccia. Inoltre questo avviserà gli sviluppatori
di codice fuori dal kernel che c'è un cambiamento per il quale è necessario del
lavoro. Il supporto al codice fuori dal kernel non è qualcosa di cui gli
sviluppatori del kernel devono preoccuparsi, ma non dobbiamo nemmeno rendere
più difficile del necessario la vita agli sviluppatori di questo codice.

View File

@ -0,0 +1,348 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/5.Posting.rst <development_posting>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_development_posting:
Pubblicare modifiche
====================
Prima o poi arriva il momento in cui il vostro lavoro è pronto per essere
presentato alla comunità per una revisione ed eventualmente per la sua
inclusione nel ramo principale del kernel. Com'era prevedibile,
la comunità di sviluppo del kernel ha elaborato un insieme di convenzioni
e di procedure per la pubblicazione delle patch; seguirle renderà la vita
più facile a tutti quanti. Questo documento cercherà di coprire questi
argomenti con un ragionevole livello di dettaglio; più informazioni possono
essere trovare nella cartella 'Documentation', nei file
:ref:`translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`,
:ref:`translations/it_IT/process/submitting-drivers.rst <it_submittingdrivers>`, e
:ref:`translations/it_IT/process/submit-checklist.rst <it_submitchecklist>`.
Quando pubblicarle
------------------
C'è sempre una certa resistenza nel pubblicare patch finché non sono
veramente "pronte". Per semplici patch questo non è un problema.
Ma quando il lavoro è di una certa complessità, c'è molto da guadagnare
dai riscontri che la comunità può darvi prima che completiate il lavoro.
Dovreste considerare l'idea di pubblicare un lavoro incompleto, o anche
preparare un ramo git disponibile agli sviluppatori interessati, cosicché
possano stare al passo col vostro lavoro in qualunque momento.
Quando pubblicate del codice che non è considerato pronto per l'inclusione,
è bene che lo diciate al momento della pubblicazione. Inoltre, aggiungete
informazioni sulle cose ancora da sviluppare e sui problemi conosciuti.
Poche persone guarderanno delle patch che si sa essere fatte a metà,
ma quelli che lo faranno penseranno di potervi aiutare a condurre il vostro
sviluppo nella giusta direzione.
Prima di creare patch
---------------------
Ci sono un certo numero di cose che dovreste fare prima di considerare
l'invio delle patch alla comunità di sviluppo. Queste cose includono:
- Verificare il codice fino al massimo che vi è consentito. Usate gli
strumenti di debug del kernel, assicuratevi che il kernel compili con
tutte le più ragionevoli combinazioni d'opzioni, usate cross-compilatori
per compilare il codice per differenti architetture, eccetera.
- Assicuratevi che il vostro codice sia conforme alla linee guida del
kernel sullo stile del codice.
- La vostra patch ha delle conseguenze in termini di prestazioni?
Se è così, dovreste eseguire dei *benchmark* che mostrino il loro
impatto (anche positivo); un riassunto dei risultati dovrebbe essere
incluso nella patch.
- Siate certi d'avere i diritti per pubblicare il codice. Se questo
lavoro è stato fatto per un datore di lavoro, egli avrà dei diritti su
questo lavoro e dovrà quindi essere d'accordo alla sua pubblicazione
con una licenza GPL
Come regola generale, pensarci un po' di più prima di inviare il codice
ripaga quasi sempre lo sforzo.
Preparazione di una patch
-------------------------
La preparazione delle patch per la pubblicazione può richiedere una quantità
di lavoro significativa, ma, ripetiamolo ancora, generalmente sconsigliamo
di risparmiare tempo in questa fase, anche sul breve periodo.
Le patch devono essere preparate per una specifica versione del kernel.
Come regola generale, una patch dovrebbe basarsi sul ramo principale attuale
così come lo si trova nei sorgenti git di Linus. Quando vi basate sul ramo
principale, cominciate da un punto di rilascio ben noto - uno stabile o
un -rc - piuttosto che creare il vostro ramo da quello principale in un punto
a caso.
Per facilitare una revisione e una verifica più estesa, potrebbe diventare
necessaria la produzione di versioni per -mm, linux-next o i sorgenti di un
sottosistema. Basare questa patch sui suddetti sorgenti potrebbe richiedere
un lavoro significativo nella risoluzione dei conflitti e nella correzione dei
cambiamenti di API; questo potrebbe variare a seconda dell'area d'interesse
della vostra patch e da quello che succede altrove nel kernel.
Solo le modifiche più semplici dovrebbero essere preparate come una singola
patch; tutto il resto dovrebbe essere preparato come una serie logica di
modifiche. Spezzettare le patch è un po' un'arte; alcuni sviluppatori
passano molto tempo nel capire come farlo in modo che piaccia alla comunità.
Ci sono alcune regole spannometriche, che comunque possono aiutare
considerevolmente:
- La serie di patch che pubblicherete, quasi sicuramente, non sarà
come quella che trovate nel vostro sistema di controllo di versione.
Invece, le vostre modifiche dovranno essere considerate nella loro forma
finale, e quindi separate in parti che abbiano un senso. Gli sviluppatori
sono interessati in modifiche che siano discrete e indipendenti, non
alla strada che avete percorso per ottenerle.
- Ogni modifica logicamente indipendente dovrebbe essere preparata come una
patch separata. Queste modifiche possono essere piccole ("aggiunto un
campo in questa struttura") o grandi (l'aggiunta di un driver nuovo,
per esempio), ma dovrebbero essere concettualmente piccole da permettere
una descrizione in una sola riga. Ogni patch dovrebbe fare modifiche
specifiche che si possano revisionare indipendentemente e di cui si possa
verificare la veridicità.
- Giusto per riaffermare quando detto sopra: non mischiate diversi tipi di
modifiche nella stessa patch. Se una modifica corregge un baco critico
per la sicurezza, riorganizza alcune strutture, e riformatta il codice,
ci sono buone probabilità che venga ignorata e che la correzione importante
venga persa.
- Ogni modifica dovrebbe portare ad un kernel che compila e funziona
correttamente; se la vostra serie di patch si interrompe a metà il
risultato dovrebbe essere comunque un kernel funzionante. L'applicazione
parziale di una serie di patch è uno scenario comune nel quale il
comando "git bisect" viene usato per trovare delle regressioni; se il
risultato è un kernel guasto, renderete la vita degli sviluppatori più
difficile così come quella di chi s'impegna nel nobile lavoro di
scovare i problemi.
- Però, non strafate. Una volta uno sviluppatore pubblicò una serie di 500
patch che modificavano un unico file - un atto che non lo rese la persona
più popolare sulla lista di discussione del kernel. Una singola patch
può essere ragionevolmente grande fintanto che contenga un singolo
cambiamento *logico*.
- Potrebbe essere allettante l'idea di aggiungere una nuova infrastruttura
come una serie di patch, ma di lasciare questa infrastruttura inutilizzata
finché l'ultima patch della serie non abilita tutto quanto. Quando è
possibile, questo dovrebbe essere evitato; se questa serie aggiunge delle
regressioni, "bisect" indicherà quest'ultima patch come causa del
problema anche se il baco si trova altrove. Possibilmente, quando una
patch aggiunge del nuovo codice dovrebbe renderlo attivo immediatamente.
Lavorare per creare la serie di patch perfetta potrebbe essere frustrante
perché richiede un certo tempo e soprattutto dopo che il "vero lavoro" è
già stato fatto. Quando ben fatto, comunque, è tempo ben speso.
Formattazione delle patch e i changelog
---------------------------------------
Quindi adesso avete una serie perfetta di patch pronte per la pubblicazione,
ma il lavoro non è davvero finito. Ogni patch deve essere preparata con
un messaggio che spieghi al resto del mondo, in modo chiaro e veloce,
il suo scopo. Per ottenerlo, ogni patch sarà composta dai seguenti elementi:
- Un campo opzionale "From" col nome dell'autore della patch. Questa riga
è necessaria solo se state passando la patch di qualcun altro via email,
ma nel dubbio non fa di certo male aggiungerlo.
- Una descrizione di una riga che spieghi cosa fa la patch. Questo
messaggio dovrebbe essere sufficiente per far comprendere al lettore lo
scopo della patch senza altre informazioni. Questo messaggio,
solitamente, presenta in testa il nome del sottosistema a cui si riferisce,
seguito dallo scopo della patch. Per esempio:
::
gpio: fix build on CONFIG_GPIO_SYSFS=n
- Una riga bianca seguita da una descrizione dettagliata della patch.
Questa descrizione può essere lunga tanto quanto serve; dovrebbe spiegare
cosa fa e perché dovrebbe essere aggiunta al kernel.
- Una o più righe etichette, con, minimo, una riga *Signed-off-by:*
col nome dall'autore della patch. Queste etichette verranno descritte
meglio più avanti.
Gli elementi qui sopra, assieme, formano il changelog di una patch.
Scrivere un buon changelog è cruciale ma è spesso un'arte trascurata;
vale la pena spendere qualche parola in più al riguardo. Quando scrivete
un changelog dovreste tenere ben presente che molte persone leggeranno
le vostre parole. Queste includono i manutentori di un sotto-sistema, e i
revisori che devono decidere se la patch debba essere inclusa o no,
le distribuzioni e altri manutentori che cercano di valutare se la patch
debba essere applicata su kernel più vecchi, i cacciatori di bachi che si
chiederanno se la patch è la causa di un problema che stanno cercando,
gli utenti che vogliono sapere com'è cambiato il kernel, e molti altri.
Un buon changelog fornisce le informazioni necessarie a tutte queste
persone nel modo più diretto e conciso possibile.
A questo scopo, la riga riassuntiva dovrebbe descrivere gli effetti della
modifica e la motivazione della patch nel modo migliore possibile nonostante
il limite di una sola riga. La descrizione dettagliata può spiegare meglio
i temi e fornire maggiori informazioni. Se una patch corregge un baco,
citate, se possibile, il commit che lo introdusse (e per favore, quando
citate un commit aggiungete sia il suo identificativo che il titolo),
Se il problema è associabile ad un file di log o all' output del compilatore,
includeteli al fine d'aiutare gli altri a trovare soluzioni per lo stesso
problema. Se la modifica ha lo scopo di essere di supporto a sviluppi
successivi, ditelo. Se le API interne vengono cambiate, dettagliate queste
modifiche e come gli altri dovrebbero agire per applicarle. In generale,
più riuscirete ad entrare nei panni di tutti quelli che leggeranno il
vostro changelog, meglio sarà il changelog (e il kernel nel suo insieme).
Non serve dirlo, un changelog dovrebbe essere il testo usato nel messaggio
di commit in un sistema di controllo di versione. Sarà seguito da:
- La patch stessa, nel formato unificato per patch ("-u"). Usare
l'opzione "-p" assocerà alla modifica il nome della funzione alla quale
si riferisce, rendendo il risultato più facile da leggere per gli altri.
Dovreste evitare di includere nelle patch delle modifiche per file
irrilevanti (quelli generati dal processo di generazione, per esempio, o i file
di backup del vostro editor). Il file "dontdiff" nella cartella Documentation
potrà esservi d'aiuto su questo punto; passatelo a diff con l'opzione "-X".
Le etichette sopra menzionante sono usate per descrivere come i vari
sviluppatori sono stati associati allo sviluppo di una patch. Sono descritte
in dettaglio nel documento :ref:`translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`;
quello che segue è un breve riassunto. Ognuna di queste righe ha il seguente
formato:
::
tag: Full Name <email address> optional-other-stuff
Le etichette in uso più comuni sono:
- Signed-off-by: questa è la certificazione che lo sviluppatore ha il diritto
di sottomettere la patch per l'integrazione nel kernel. Questo rappresenta
il consenso verso il certificato d'origine degli sviluppatori, il testo
completo potrà essere trovato in
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
Codice che non presenta una firma appropriata non potrà essere integrato.
- Co-developed-by: indica che la patch è stata sviluppata anche da un altro
sviluppatore assieme all'autore originale. Questo è utile quando più
persone lavorano sulla stessa patch. Da notare che questa persona deve
avere anche una riga "Signed-off-by:" nella patch.
- Acked-by: indica il consenso di un altro sviluppatore (spesso il manutentore
del codice in oggetto) all'integrazione della patch nel kernel.
- Tested-by: menziona la persona che ha verificato la patch e l'ha trovata
funzionante.
- Reviwed-by: menziona lo sviluppatore che ha revisionato la patch; per
maggiori dettagli leggete la dichiarazione dei revisori in
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`
- Reported-by: menziona l'utente che ha riportato il problema corretto da
questa patch; quest'etichetta viene usata per dare credito alle persone
che hanno verificato il codice e ci hanno fatto sapere quando le cose non
funzionavano correttamente.
- Cc: la persona menzionata ha ricevuto una copia della patch ed ha avuto
l'opportunità di commentarla.
State attenti ad aggiungere queste etichette alla vostra patch: solo
"Cc:" può essere aggiunta senza il permesso esplicito della persona menzionata.
Inviare la modifica
-------------------
Prima di inviare la vostra patch, ci sarebbero ancora un paio di cose di cui
dovreste aver cura:
- Siete sicuri che il vostro programma di posta non corromperà le patch?
Le patch che hanno spazi bianchi in libertà o andate a capo aggiunti
dai programmi di posta non funzioneranno per chi le riceve, e spesso
non verranno nemmeno esaminate in dettaglio. Se avete un qualsiasi dubbio,
inviate la patch a voi stessi e verificate che sia integra.
:ref:`Documentation/translations/it_IT/process/email-clients.rst <it_email_clients>`
contiene alcuni suggerimenti utili sulla configurazione dei programmi
di posta al fine di inviare patch.
- Siete sicuri che la vostra patch non contenga sciocchi errori? Dovreste
sempre processare le patch con scripts/checkpatch.pl e correggere eventuali
problemi riportati. Per favore tenete ben presente che checkpatch.pl non è
più intelligente di voi, nonostante sia il risultato di un certa quantità di
ragionamenti su come debba essere una patch per il kernel. Se seguire
i suggerimenti di checkpatch.pl rende il codice peggiore, allora non fatelo.
Le patch dovrebbero essere sempre inviate come testo puro. Per favore non
inviatele come allegati; questo rende molto più difficile, per i revisori,
citare parti della patch che si vogliono commentare. Invece, mettete la vostra
patch direttamente nel messaggio.
Quando inviate le patch, è importante inviarne una copia a tutte le persone che
potrebbero esserne interessate. Al contrario di altri progetti, il kernel
incoraggia le persone a peccare nell'invio di tante copie; non presumente che
le persone interessate vedano i vostri messaggi sulla lista di discussione.
In particolare le copie dovrebbero essere inviate a:
- I manutentori dei sottosistemi affetti della modifica. Come descritto
in precedenza, il file MAINTAINERS è il primo luogo dove cercare i nomi
di queste persone.
- Altri sviluppatori che hanno lavorato nello stesso ambiente - specialmente
quelli che potrebbero lavorarci proprio ora. Usate git potrebbe essere
utile per vedere chi altri ha modificato i file su cui state lavorando.
- Se state rispondendo a un rapporto su un baco, o a una richiesta di
funzionalità, includete anche gli autori di quei rapporti/richieste.
- Inviate una copia alle liste di discussione interessate, o, se nient'altro
è adatto, alla lista linux-kernel
- Se state correggendo un baco, pensate se la patch dovrebbe essere inclusa
nel prossimo rilascio stabile. Se è così, la lista di discussione
stable@vger.kernel.org dovrebbe riceverne una copia. Aggiungete anche
l'etichetta "Cc: stable@vger.kernel.org" nella patch stessa; questo
permetterà alla squadra *stable* di ricevere una notifica quando questa
correzione viene integrata nel ramo principale.
Quando scegliete i destinatari della patch, è bene avere un'idea di chi
pensiate che sia colui che, eventualmente, accetterà la vostra patch e
la integrerà. Nonostante sia possibile inviare patch direttamente a
Linus Torvalds, e lasciare che sia lui ad integrarle,solitamente non è la
strada migliore da seguire. Linus è occupato, e ci sono dei manutentori di
sotto-sistema che controllano una parte specifica del kernel. Solitamente,
vorreste che siano questi manutentori ad integrare le vostre patch. Se non
c'è un chiaro manutentore, l'ultima spiaggia è spesso Andrew Morton.
Le patch devono avere anche un buon oggetto. Il tipico formato per l'oggetto
di una patch assomiglia a questo:
::
[PATCH nn/mm] subsys: one-line description of the patch
dove "nn" è il numero ordinale della patch, "mm" è il numero totale delle patch
nella serie, e "subsys" è il nome del sottosistema interessato. Chiaramente,
nn/mm può essere omesso per una serie composta da una singola patch.
Se avete una significative serie di patch, è prassi inviare una descrizione
introduttiva come parte zero. Tuttavia questa convenzione non è universalmente
seguita; se la usate, ricordate che le informazioni nell'introduzione non
faranno parte del changelog del kernel. Quindi per favore, assicuratevi che
ogni patch abbia un changelog completo.
In generale, la seconda parte e quelle successive di una patch "composta"
dovrebbero essere inviate come risposta alla prima, cosicché vengano viste
come un unico *thread*. Strumenti come git e quilt hanno comandi per inviare
gruppi di patch con la struttura appropriata. Se avete una serie lunga
e state usando git, per favore state alla larga dall'opzione --chain-reply-to
per evitare di creare un annidamento eccessivo.

View File

@ -0,0 +1,240 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/6.Followthrough.rst <development_followthrough>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_followthrough:
=============
Completamento
=============
A questo punto, avete seguito le linee guida fino a questo punto e, con
l'aggiunta delle vostre capacità ingegneristiche, avete pubblicato una serie
perfetta di patch. Uno dei più grandi errori che possono essere commessi
persino da sviluppatori kernel esperti è quello di concludere che il
lavoro sia ormai finito. In verità, la pubblicazione delle patch
simboleggia una transizione alla fase successiva del processo, con,
probabilmente, ancora un po' di lavoro da fare.
È raro che una modifica sia così bella alla sua prima pubblicazione che non
ci sia alcuno spazio di miglioramento. Il programma di sviluppo del kernel
riconosce questo fatto e quindi, è fortemente orientato al miglioramento
del codice pubblicato. Voi, in qualità di autori del codice, dovrete
lavorare con la comunità del kernel per assicurare che il vostro codice
mantenga gli standard qualitativi richiesti. Un fallimento in questo
processo è quasi come impedire l'inclusione delle vostre patch nel
ramo principale.
Lavorare con i revisori
=======================
Una patch che abbia una certa rilevanza avrà ricevuto numerosi commenti
da parte di altri sviluppatori dato che avranno revisionato il codice.
Lavorare con i revisori può rivelarsi, per molti sviluppatori, la parte
più intimidatoria del processo di sviluppo del kernel. La vita può esservi
resa molto più facile se tenete presente alcuni dettagli:
- Se avete descritto la vostra modifica correttamente, i revisori ne
comprenderanno il valore e il perché vi siete presi il disturbo di
scriverla. Ma tale valore non li tratterrà dal porvi una domanda
fondamentale: come verrà mantenuto questo codice nel kernel nei prossimi
cinque o dieci anni? Molti dei cambiamenti che potrebbero esservi
richiesti - da piccoli problemi di stile a sostanziali ristesure -
vengono dalla consapevolezza che Linux resterà in circolazione e in
continuo sviluppo ancora per diverse decadi.
- La revisione del codice è un duro lavoro, ed è un mestiere poco
riconosciuto; le persone ricordano chi ha scritto il codice, ma meno
fama è attribuita a chi lo ha revisionato. Quindi i revisori potrebbero
divenire burberi, specialmente quando vendono i medesimi errori venire
fatti ancora e ancora. Se ricevete una revisione che vi sembra abbia
un tono arrabbiato, insultante o addirittura offensivo, resistente alla
tentazione di rispondere a tono. La revisione riguarda il codice e non
la persona, e i revisori non vi stanno attaccando personalmente.
- Similarmente, i revisori del codice non stanno cercando di promuovere
i loro interessi a vostre spese. Gli sviluppatori del kernel spesso si
aspettano di lavorare sul kernel per anni, ma sanno che il loro datore
di lavoro può cambiare. Davvero, senza praticamente eccezioni, loro
stanno lavorando per la creazione del miglior kernel possibile; non
stanno cercando di creare un disagio ad aziende concorrenti.
Quello che si sta cercando di dire è che, quando i revisori vi inviano degli
appunti dovete fare attenzione alle osservazioni tecniche che vi stanno
facendo. Non lasciate che il loro modo di esprimersi o il vostro orgoglio
impediscano che ciò accada. Quando avete dei suggerimenti sulla revisione,
prendetevi il tempo per comprendere cosa il revisore stia cercando di
comunicarvi. Se possibile, sistemate le cose che il revisore vi chiede di
modificare. E rispondete al revisore ringraziandolo e spiegando come
intendete fare.
Notate che non dovete per forza essere d'accordo con ogni singola modifica
suggerita dai revisori. Se credete che il revisore non abbia compreso
il vostro codice, spiegateglielo. Se avete un'obiezione tecnica da fargli
su di una modifica suggerita, spiegatela inserendo anche la vostra soluzione
al problema. Se la vostra spiegazione ha senso, il revisore la accetterà.
Tuttavia, la vostra motivazione potrebbe non essere del tutto persuasiva,
specialmente se altri iniziano ad essere d'accordo con il revisore.
Prendetevi quindi un po' di tempo per pensare ancora alla cosa. Può risultare
facile essere accecati dalla propria soluzione al punto che non realizzate che
c'è qualcosa di fondamentalmente sbagliato o, magari, non state nemmeno
risolvendo il problema giusto.
Andrew Morton suggerisce che ogni suggerimento di revisione che non è
presente nella modifica del codice dovrebbe essere inserito in un commento
aggiuntivo; ciò può essere d'aiuto ai futuri revisori nell'evitare domande
che sorgono al primo sguardo.
Un errore fatale è quello di ignorare i commenti di revisione nella speranza
che se ne andranno. Non andranno via. Se pubblicherete nuovamente il
codice senza aver risposto ai commenti ricevuti, probabilmente le vostre
modifiche non andranno da nessuna parte.
Parlando di ripubblicazione del codice: per favore tenete a mente che i
revisori non ricorderanno tutti i dettagli del codice che avete pubblicato
l'ultima volta. Quindi è sempre una buona idea quella di ricordare ai
revisori le questioni sollevate precedetemene e come le avete risolte.
I revisori non dovrebbero star lì a cercare all'interno degli archivi per
famigliarizzare con ciò che è stato detto l'ultima volta; se li aiutate
in questo senso, saranno di umore migliore quando riguarderanno il vostro
codice.
Se invece avete cercato di far tutto correttamente ma le cose continuano
a non andar bene? Molti disaccordi di natura tecnica possono essere risolti
attraverso la discussione, ma ci sono volte dove qualcuno deve prendere
una decisione. Se credete veramente che tale decisione andrà contro di voi
ingiustamente, potete sempre tentare di rivolgervi a qualcuno più
in alto di voi. Per cose di questo genere la persona con più potere è
Andrew Morton. Andrew è una figura molto rispettata all'interno della
comunità di sviluppo del kernel; lui può spesso sbrogliare situazioni che
sembrano irrimediabilmente bloccate. Rivolgersi ad Andrew non deve essere
fatto alla leggera, e non deve essere fatto prima di aver esplorato tutte
le altre alternative. E tenete a mente, ovviamente, che nemmeno lui
potrebbe non essere d'accordo con voi.
Cosa accade poi
===============
Se la modifica è ritenuta un elemento valido da essere aggiunta al kernel,
e una volta che la maggior parte degli appunti dei revisori sono stati
sistemati, il passo successivo solitamente è quello di entrare in un
sottosistema gestito da un manutentore. Come ciò avviene dipende dal
sottosistema medesimo; ogni manutentore ha il proprio modo di fare le cose.
In particolare, ci potrebbero essere diversi sorgenti - uno, magari, dedicato
alle modifiche pianificate per la finestra di fusione successiva, e un altro
per il lavoro di lungo periodo.
Per le modifiche proposte in aree per le quali non esiste un sottosistema
preciso (modifiche di gestione della memoria, per esempio), i sorgenti di
ripiego finiscono per essere -mm. Ed anche le modifiche che riguardano
più sottosistemi possono finire in quest'ultimo.
L'inclusione nei sorgenti di un sottosistema può comportare per una patch,
un alto livello di visibilità. Ora altri sviluppatori che stanno lavorando
in quei medesimi sorgenti avranno le vostre modifiche. I sottosistemi
solitamente riforniscono anche Linux-next, rendendo i propri contenuti
visibili all'intera comunità di sviluppo. A questo punto, ci sono buone
possibilità per voi di ricevere ulteriori commenti da un nuovo gruppo di
revisori; anche a questi commenti dovrete rispondere come avete già fatto per
gli altri.
Ciò che potrebbe accadere a questo punto, in base alla natura della vostra
modifica, riguarda eventuali conflitti con il lavoro svolto da altri.
Nella peggiore delle situazioni, i conflitti più pesanti tra modifiche possono
concludersi con la messa a lato di alcuni dei lavori svolti cosicché le
modifiche restanti possano funzionare ed essere integrate. Altre volte, la
risoluzione dei conflitti richiederà del lavoro con altri sviluppatori e,
possibilmente, lo spostamento di alcune patch da dei sorgenti a degli altri
in modo da assicurare che tutto sia applicato in modo pulito. Questo lavoro
può rivelarsi una spina nel fianco, ma consideratevi fortunati: prima
dell'avvento dei sorgenti linux-next, questi conflitti spesso emergevano solo
durante l'apertura della finestra di integrazione e dovevano essere smaltiti
in fretta. Ora essi possono essere risolti comodamente, prima dell'apertura
della finestra.
Un giorno, se tutto va bene, vi collegherete e vedrete che la vostra patch
è stata inserita nel ramo principale de kernel. Congratulazioni! Terminati
i festeggiamenti (nel frattempo avrete inserito il vostro nome nel file
MAINTAINERS) vale la pena ricordare una piccola cosa, ma importante: il
lavoro non è ancora finito. L'inserimento nel ramo principale porta con se
nuove sfide.
Cominciamo con il dire che ora la visibilità della vostra modifica è
ulteriormente cresciuta. Ci potrebbe portare ad una nuova fase di
commenti dagli sviluppatori che non erano ancora a conoscenza della vostra
patch. Ignorarli potrebbe essere allettante dato che non ci sono più
dubbi sull'integrazione della modifica. Resistete a tale tentazione, dovete
mantenervi disponibili agli sviluppatori che hanno domande o suggerimenti
per voi.
Ancora più importante: l'inclusione nel ramo principale mette il vostro
codice nelle mani di un gruppo di *tester* molto più esteso. Anche se avete
contribuito ad un driver per un hardware che non è ancora disponibile, sarete
sorpresi da quante persone inseriranno il vostro codice nei loro kernel.
E, ovviamente, dove ci sono *tester*, ci saranno anche dei rapporti su
eventuali bachi.
La peggior specie di rapporti sono quelli che indicano delle regressioni.
Se la vostra modifica causa una regressione, avrete un gran numero di
occhi puntati su di voi; la regressione deve essere sistemata il prima
possibile. Se non vorrete o non sarete capaci di sistemarla (e nessuno
lo farà per voi), la vostra modifica sarà quasi certamente rimossa durante
la fase di stabilizzazione. Oltre alla perdita di tutto il lavoro svolto
per far si che la vostra modifica fosse inserita nel ramo principale,
l'avere una modifica rimossa a causa del fallimento nel sistemare una
regressione, potrebbe rendere più difficile per voi far accettare
il vostro lavoro in futuro.
Dopo che ogni regressione è stata affrontata, ci potrebbero essere altri
bachi ordinari da "sconfiggere". Il periodo di stabilizzazione è la
vostra migliore opportunità per sistemare questi bachi e assicurarvi che
il debutto del vostro codice nel ramo principale del kernel sia il più solido
possibile. Quindi, per favore, rispondete ai rapporti sui bachi e ponete
rimedio, se possibile, a tutti i problemi. È a questo che serve il periodo
di stabilizzazione; potete iniziare creando nuove fantastiche modifiche
una volta che ogni problema con le vecchie sia stato risolto.
Non dimenticate che esistono altre pietre miliari che possono generare
rapporti sui bachi: il successivo rilascio stabile, quando una distribuzione
importante usa una versione del kernel nel quale è presente la vostra
modifica, eccetera. Il continuare a rispondere a questi rapporti è fonte di
orgoglio per il vostro lavoro. Se questa non è una sufficiente motivazione,
allora, è anche consigliabile considera che la comunità di sviluppo ricorda
gli sviluppatori che hanno perso interesse per il loro codice una volta
integrato. La prossima volta che pubblicherete una patch, la comunità
la valuterà anche sulla base del fatto che non sarete disponibili a
prendervene cura anche nel futuro.
Altre cose che posso accadere
=============================
Un giorno, potreste aprire la vostra email e vedere che qualcuno vi ha
inviato una patch per il vostro codice. Questo, dopo tutto, è uno dei
vantaggi di avere il vostro codice "là fuori". Se siete d'accordo con
la modifica, potrete anche inoltrarla ad un manutentore di sottosistema
(assicuratevi di includere la riga "From:" cosicché l'attribuzione sia
corretta, e aggiungete una vostra firma "Signed-off-by"), oppure inviate
un "Acked-by:" e lasciate che l'autore originale la invii.
Se non siete d'accordo con la patch, inviate una risposta educata
spiegando il perché. Se possibile, dite all'autore quali cambiamenti
servirebbero per rendere la patch accettabile da voi. C'è una certa
riluttanza nell'inserire modifiche con un conflitto fra autore
e manutentore del codice, ma solo fino ad un certo punto. Se siete visti
come qualcuno che blocca un buon lavoro senza motivo, quelle patch vi
passeranno oltre e andranno nel ramo principale in ogni caso. Nel kernel
Linux, nessuno ha potere di veto assoluto su alcun codice. Eccezione
fatta per Linus, forse.
In rarissime occasioni, potreste vedere qualcosa di completamente diverso:
un altro sviluppatore che pubblica una soluzione differente al vostro
problema. A questo punto, c'è una buona probabilità che una delle due
modifiche non verrà integrata, e il "c'ero prima io" non è considerato
un argomento tecnico rilevante. Se la modifica di qualcun'altro rimpiazza
la vostra ed entra nel ramo principale, esiste un unico modo di reagire:
siate contenti che il vostro problema sia stato risolto e andate avanti con
il vostro lavoro. L'avere un vostro lavoro spintonato da parte in questo
modo può essere avvilente e scoraggiante, ma la comunità ricorderà come
avrete reagito anche dopo che avrà dimenticato quale fu la modifica accettata.

View File

@ -0,0 +1,191 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_development_advancedtopics:
Argomenti avanzati
==================
A questo punto, si spera, dovreste avere un'idea su come funziona il processo
di sviluppo. Ma rimane comunque molto da imparare! Questo capitolo copre
alcuni argomenti che potrebbero essere utili per gli sviluppatori che stanno
per diventare parte integrante del processo di sviluppo del kernel.
Gestire le modifiche con git
-----------------------------
L'uso di un sistema distribuito per il controllo delle versioni del kernel
ebbe iniziò nel 2002 quando Linux iniziò a provare il programma proprietario
BitKeeper. Nonostante l'uso di BitKeeper fosse opinabile, di certo il suo
approccio alla gestione dei sorgenti non lo era. Un sistema distribuito per
il controllo delle versioni accelerò immediatamente lo sviluppo del kernel.
Oggigiorno, ci sono diverse alternative libere a BitKeeper. Per il meglio o il
peggio, il progetto del kernel ha deciso di usare git per gestire i sorgenti.
Gestire le modifiche con git può rendere la vita dello sviluppatore molto
più facile, specialmente quando il volume delle modifiche cresce.
Git ha anche i suoi lati taglienti che possono essere pericolosi; è uno
strumento giovane e potente che è ancora in fase di civilizzazione da parte
dei suoi sviluppatori. Questo documento non ha lo scopo di insegnare l'uso
di git ai suoi lettori; ci sarebbe materiale a sufficienza per un lungo
documento al riguardo. Invece, qui ci concentriamo in particolare su come
git è parte del processo di sviluppo del kernel. Gli sviluppatori che
desiderassero diventare agili con git troveranno più informazioni ai
seguenti indirizzi:
http://git-scm.com/
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
e su varie guide che potrete trovare su internet.
La prima cosa da fare prima di usarlo per produrre patch che saranno
disponibili ad altri, è quella di leggere i siti qui sopra e di acquisire una
base solida su come funziona git. Uno sviluppatore che sappia usare git
dovrebbe essere capace di ottenere una copia del repositorio principale,
esplorare la storia della revisione, registrare le modifiche, usare i rami,
eccetera. Una certa comprensione degli strumenti git per riscrivere la storia
(come ``rebase``) è altrettanto utile. Git ha i propri concetti e la propria
terminologia; un nuovo utente dovrebbe conoscere *refs*, *remote branch*,
*index*, *fast-forward merge*, *push* e *pull*, *detached head*, eccetera.
Il tutto potrebbe essere un po' intimidatorio visto da fuori, ma con un po'
di studio i concetti non saranno così difficili da capire.
Utilizzare git per produrre patch da sottomettere via email può essere
un buon esercizio da fare mentre si sta prendendo confidenza con lo strumento.
Quando sarete in grado di creare rami git che siano guardabili da altri,
vi servirà, ovviamente, un server dal quale sia possibile attingere le vostre
modifiche. Se avete un server accessibile da Internet, configurarlo per
eseguire git-daemon è relativamente semplice . Altrimenti, iniziano a
svilupparsi piattaforme che offrono spazi pubblici, e gratuiti (Github,
per esempio). Gli sviluppatori permanenti possono ottenere un account
su kernel.org, ma non è proprio facile da ottenere; per maggiori informazioni
consultate la pagina web http://kernel.org/faq/.
In git è normale avere a che fare con tanti rami. Ogni linea di sviluppo
può essere separata in "rami per argomenti" e gestiti indipendentemente.
In git i rami sono facilissimi, per cui non c'è motivo per non usarli
in libertà. In ogni caso, non dovreste sviluppare su alcun ramo dal
quale altri potrebbero attingere. I rami disponibili pubblicamente dovrebbero
essere creati con attenzione; integrate patch dai rami di sviluppo
solo quando sono complete e pronte ad essere consegnate - non prima.
Git offre alcuni strumenti che vi permettono di riscrivere la storia del
vostro sviluppo. Una modifica errata (diciamo, una che rompe la bisezione,
oppure che ha un qualche tipo di baco evidente) può essere corretta sul posto
o fatta sparire completamente dalla storia. Una serie di patch può essere
riscritta come se fosse stata scritta in cima al ramo principale di oggi,
anche se ci avete lavorato per mesi. Le modifiche possono essere spostate
in modo trasparente da un ramo ad un altro. E così via. Un uso giudizioso
di git per revisionare la storia può aiutare nella creazione di una serie
di patch pulite e con meno problemi.
Un uso eccessivo può portare ad altri tipi di problemi, tuttavia, oltre
alla semplice ossessione per la creazione di una storia del progetto che sia
perfetta. Riscrivere la storia riscriverà le patch contenute in quella
storia, trasformando un kernel verificato (si spera) in uno da verificare.
Ma, oltre a questo, gli sviluppatori non possono collaborare se non condividono
la stessa vista sulla storia del progetto; se riscrivete la storia dalla quale
altri sviluppatori hanno attinto per i loro repositori, renderete la loro vita
molto più difficile. Quindi tenete conto di questa semplice regola generale:
la storia che avete esposto ad altri, generalmente, dovrebbe essere vista come
immutabile.
Dunque, una volta che il vostro insieme di patch è stato reso disponibile
pubblicamente non dovrebbe essere più sovrascritto. Git tenterà di imporre
questa regola, e si rifiuterà di pubblicare nuove patch che non risultino
essere dirette discendenti di quelle pubblicate in precedenza (in altre parole,
patch che non condividono la stessa storia). È possibile ignorare questo
controllo, e ci saranno momenti in cui sarà davvero necessario riscrivere
un ramo già pubblicato. Un esempio è linux-next dove le patch vengono
spostate da un ramo all'altro al fine di evitare conflitti. Ma questo tipo
d'azione dovrebbe essere un'eccezione. Questo è uno dei motivi per cui lo
sviluppo dovrebbe avvenire in rami privati (che possono essere sovrascritti
quando lo si ritiene necessario) e reso pubblico solo quando è in uno stato
avanzato.
Man mano che il ramo principale (o altri rami su cui avete basato le
modifiche) avanza, diventa allettante l'idea di integrare tutte le patch
per rimanere sempre aggiornati. Per un ramo privato, il *rebase* può essere
un modo semplice per rimanere aggiornati, ma questa non è un'opzione nel
momento in cui il vostro ramo è stato esposto al mondo intero.
*Merge* occasionali possono essere considerati di buon senso, ma quando
diventano troppo frequenti confondono inutilmente la storia. La tecnica
suggerita in questi casi è quella di fare *merge* raramente, e più in generale
solo nei momenti di rilascio (per esempio gli -rc del ramo principale).
Se siete nervosi circa alcune patch in particolare, potete sempre fare
dei *merge* di test in un ramo privato. In queste situazioni git "rerere"
può essere utile; questo strumento si ricorda come i conflitti di *merge*
furono risolti in passato cosicché non dovrete fare lo stesso lavoro due volte.
Una delle lamentele più grosse e ricorrenti sull'uso di strumenti come git
è il grande movimento di patch da un repositorio all'altro che rende
facile l'integrazione nel ramo principale di modifiche mediocri, il tutto
sotto il naso dei revisori. Gli sviluppatori del kernel tendono ad essere
scontenti quando vedono succedere queste cose; preparare un ramo git con
patch che non hanno ricevuto alcuna revisione o completamente avulse, potrebbe
influire sulla vostra capacita di proporre, in futuro, l'integrazione dei
vostri rami. Citando Linus
::
Potete inviarmi le vostre patch, ma per far si che io integri una
vostra modifica da git, devo sapere che voi sappiate cosa state
facendo, e ho bisogno di fidarmi *senza* dover passare tutte
le modifiche manualmente una per una.
(http://lwn.net/Articles/224135/).
Per evitare queste situazioni, assicuratevi che tutte le patch in un ramo
siano strettamente correlate al tema delle modifiche; un ramo "driver fixes"
non dovrebbe fare modifiche al codice principale per la gestione della memoria.
E, più importante ancora, non usate un repositorio git per tentare di
evitare il processo di revisione. Pubblicate un sommario di quello che il
vostro ramo contiene sulle liste di discussione più opportune, e , quando
sarà il momento, richiedete che il vostro ramo venga integrato in linux-next.
Se e quando altri inizieranno ad inviarvi patch per essere incluse nel
vostro repositorio, non dovete dimenticare di revisionarle. Inoltre
assicuratevi di mantenerne le informazioni di paternità; al riguardo git "am"
fa del suo meglio, ma potreste dover aggiungere una riga "From:" alla patch
nel caso in cui sia arrivata per vie traverse.
Quando richiedete l'integrazione, siate certi di fornire tutte le informazioni:
dov'è il vostro repositorio, quale ramo integrare, e quali cambiamenti si
otterranno dall'integrazione. Il comando git request-pull può essere d'aiuto;
preparerà una richiesta nel modo in cui gli altri sviluppatori se l'aspettano,
e verificherà che vi siate ricordati di pubblicare quelle patch su un
server pubblico.
Revisionare le patch
--------------------
Alcuni lettori potrebbero avere obiezioni sulla presenza di questa sezione
negli "argomenti avanzati" sulla base che anche gli sviluppatori principianti
dovrebbero revisionare le patch. É certamente vero che non c'è modo
migliore di imparare come programmare per il kernel che guardare il codice
pubblicato dagli altri. In aggiunta, i revisori sono sempre troppo pochi;
guardando il codice potete apportare un significativo contributo all'intero
processo.
Revisionare il codice potrebbe risultare intimidatorio, specialmente per i
nuovi arrivati che potrebbero sentirsi un po' nervosi nel questionare
il codice - in pubblico - pubblicato da sviluppatori più esperti. Perfino
il codice scritto dagli sviluppatori più esperti può essere migliorato.
Forse il suggerimento migliore per i revisori (tutti) è questo: formulate
i commenti come domande e non come critiche. Chiedere "Come viene rilasciato
il *lock* in questo percorso?" funziona sempre molto meglio che
"qui la sincronizzazione è sbagliata".
Diversi sviluppatori revisioneranno il codice con diversi punti di vista.
Alcuni potrebbero concentrarsi principalmente sullo stile del codice e se
alcune linee hanno degli spazio bianchi di troppo. Altri si chiederanno
se accettare una modifica interamente è una cosa positiva per il kernel
o no. E altri ancora si focalizzeranno sui problemi di sincronizzazione,
l'uso eccessivo di *stack*, problemi di sicurezza, duplicazione del codice
in altri contesti, documentazione, effetti negativi sulle prestazioni, cambi
all'ABI dello spazio utente, eccetera. Qualunque tipo di revisione è ben
accetta e di valore, se porta ad avere un codice migliore nel kernel.

View File

@ -0,0 +1,85 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/8.Conclusion.rst <development_conclusion>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_conclusion:
Per maggiori informazioni
=========================
Esistono numerose fonti di informazioni sullo sviluppo del kernel Linux
e argomenti correlati. Primo tra questi sarà sempre la cartella Documentation
che si trova nei sorgenti kernel.
Il file :ref:`process/howto.rst <it_process_howto>` è un punto di partenza
importante; :ref:`process/submitting-patches.rst <it_submittingpatches>` e
:ref:`process/submitting-drivers.rst <it_submittingdrivers>` sono
anch'essi qualcosa che tutti gli sviluppatori del kernel dovrebbero leggere.
Molte API interne al kernel sono documentate utilizzando il meccanismo
kerneldoc; "make htmldocs" o "make pdfdocs" possono essere usati per generare
quei documenti in HTML o PDF (sebbene le versioni di TeX di alcune
distribuzioni hanno dei limiti interni e fallisce nel processare
appropriatamente i documenti).
Diversi siti web approfondiscono lo sviluppo del kernel ad ogni livello
di dettaglio. Il vostro autore vorrebbe umilmente suggerirvi
http://lwn.net/ come fonte; usando l'indice 'kernel' su LWN troverete
molti argomenti specifici sul kernel:
http://lwn.net/Kernel/Index/
Oltre a ciò, una risorsa valida per gli sviluppatori kernel è:
http://kernelnewbies.org/
E, ovviamente, una fonte da non dimenticare è http://kernel.org/, il luogo
definitivo per le informazioni sui rilasci del kernel.
Ci sono numerosi libri sullo sviluppo del kernel:
Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro
Rubini, and Greg Kroah-Hartman). In linea all'indirizzo
http://lwn.net/Kernel/LDD3/.
Linux Kernel Development (Robert Love).
Understanding the Linux Kernel (Daniel Bovet and Marco Cesati).
Tutti questi libri soffrono di un errore comune: tendono a risultare in un
certo senso obsoleti dal momento che si trovano in libreria da diverso
tempo. Comunque contengono informazioni abbastanza buone.
La documentazione per git la troverete su:
http://www.kernel.org/pub/software/scm/git/docs/
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
Conclusioni
===========
Congratulazioni a chiunque ce l'abbia fatta a terminare questo documento di
lungo-respiro. Si spera che abbia fornito un'utile comprensione d'insieme
di come il kernel Linux viene sviluppato e di come potete partecipare a
tale processo.
Infine, quello che conta è partecipare. Qualsiasi progetto software
open-source non è altro che la somma di quello che i suoi contributori
mettono al suo interno. Il kernel Linux è cresciuto velocemente e bene
perché ha ricevuto il supporto di un impressionante gruppo di sviluppatori,
ognuno dei quali sta lavorando per renderlo migliore. Il kernel è un esempio
importante di cosa può essere fatto quando migliaia di persone lavorano
insieme verso un obiettivo comune.
Il kernel può sempre beneficiare di una larga base di sviluppatori, tuttavia,
c'è sempre molto lavoro da fare. Ma, cosa non meno importante, molti degli
altri partecipanti all'ecosistema Linux possono trarre beneficio attraverso
il contributo al kernel. Inserire codice nel ramo principale è la chiave
per arrivare ad una qualità del codice più alta, bassa manutenzione e
bassi prezzi di distribuzione, alti livelli d'influenza sulla direzione
dello sviluppo del kernel, e molto altro. È una situazione nella quale
tutti coloro che sono coinvolti vincono. Mollate il vostro editor e
raggiungeteci; sarete più che benvenuti.

View File

@ -0,0 +1,643 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_addsyscalls:
Aggiungere una nuova chiamata di sistema
========================================
Questo documento descrive quello che è necessario sapere per aggiungere
nuove chiamate di sistema al kernel Linux; questo è da considerarsi come
un'aggiunta ai soliti consigli su come proporre nuove modifiche
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
Alternative alle chiamate di sistema
------------------------------------
La prima considerazione da fare quando si aggiunge una nuova chiamata di
sistema è quella di valutare le alternative. Nonostante le chiamate di sistema
siano il punto di interazione fra spazio utente e kernel più tradizionale ed
ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle
vostra interfaccia.
- Se le operazioni coinvolte possono rassomigliare a quelle di un filesystem,
allora potrebbe avere molto più senso la creazione di un nuovo filesystem o
dispositivo. Inoltre, questo rende più facile incapsulare la nuova
funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore
del kernel.
- Se la nuova funzionalità prevede operazioni dove il kernel notifica
lo spazio utente su un avvenimento, allora restituire un descrittore
di file all'oggetto corrispondente permette allo spazio utente di
utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche.
- Tuttavia, le operazioni che non si sposano bene con operazioni tipo
:manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate
come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in
un qualche modo opaca.
- Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in
sysfs (vedere ``Documentation/translations/it_IT/filesystems/sysfs.txt``) o
in procfs potrebbe essere sufficiente. Tuttavia, l'accesso a questi
meccanismi richiede che il filesystem sia montato, il che potrebbe non
essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot).
Evitate d'aggiungere nuove API in debugfs perché questo non viene
considerata un'interfaccia di 'produzione' verso lo spazio utente.
- Se l'operazione è specifica ad un particolare file o descrittore, allora
potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`.
Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che
nasconde una notevole complessità, quindi è ottima solo quando la nuova
funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure
la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere
un semplice flag associato ad un descrittore di file).
- Se l'operazione è specifica ad un particolare processo, allora
potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`.
Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso
multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti
nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo
al processo.
Progettare l'API: pianificare le estensioni
-------------------------------------------
Una nuova chiamata di sistema diventerà parte dell'API del kernel, e
dev'essere supportata per un periodo indefinito. Per questo, è davvero
un'ottima idea quella di discutere apertamente l'interfaccia sulla lista
di discussione del kernel, ed è altrettanto importante pianificarne eventuali
estensioni future.
(Nella tabella delle chiamate di sistema sono disseminati esempi dove questo
non fu fatto, assieme ai corrispondenti aggiornamenti -
``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia
del kernel e pianificate le estensioni fin dall'inizio)
Per semplici chiamate di sistema che accettano solo un paio di argomenti,
il modo migliore di permettere l'estensibilità è quello di includere un
argomento *flags* alla chiamata di sistema. Per assicurarsi che i programmi
dello spazio utente possano usare in sicurezza *flags* con diverse versioni
del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto,
in qual caso rifiutate la chiamata di sistema (con ``EINVAL``)::
if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3))
return -EINVAL;
(Se *flags* non viene ancora utilizzato, verificate che l'argomento sia zero)
Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di
argomenti, il modo migliore è quello di incapsularne la maggior parte in una
struttura dati che verrà passata per puntatore. Questa struttura potrà
funzionare con future estensioni includendo un campo *size*::
struct xyzzy_params {
u32 size; /* userspace sets p->size = sizeof(struct xyzzy_params) */
u32 param_1;
u64 param_2;
u64 param_3;
};
Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per
offrire il comportamento precedente quando vale zero, allora questo permetterà
di gestire un conflitto di versione in entrambe le direzioni:
- un vecchio kernel può gestire l'accesso di una versione moderna di un
programma in spazio utente verificando che la memoria oltre la dimensione
della struttura dati attesa sia zero (in pratica verificare che
``param_4 == 0``).
- un nuovo kernel può gestire l'accesso di una versione vecchia di un
programma in spazio utente estendendo la struttura dati con zeri (in pratica
``param_4 = 0``).
Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in
``kernel/events/core.c``) per un esempio pratico di questo approccio.
Progettare l'API: altre considerazioni
--------------------------------------
Se la vostra nuova chiamata di sistema permette allo spazio utente di fare
riferimento ad un oggetto del kernel, allora questa dovrebbe usare un
descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di
accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica
ben definita per utilizzare i descrittori di file.
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ritorna un nuovo
descrittore di file, allora l'argomento *flags* dovrebbe includere un valore
equivalente a ``O_CLOEXEC`` per i nuovi descrittori. Questo rende possibile,
nello spazio utente, la chiusura della finestra temporale fra le chiamate a
``xyzzy()`` e ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, dove un inaspettato
``fork()`` o ``execve()`` potrebbe trasferire il descrittore al programma
eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di
``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una
enumerazione di flag ``O_*`` che è abbastanza ricca).
Se la vostra nuova chiamata di sistema ritorna un nuovo descrittore di file,
dovreste considerare che significato avrà l'uso delle chiamate di sistema
della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto
per la lettura o la scrittura è il tipico modo del kernel per notificare lo
spazio utente circa un evento associato all'oggetto del kernel.
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ha un argomento
che è il percorso ad un file::
int sys_xyzzy(const char __user *path, ..., unsigned int flags);
dovreste anche considerare se non sia più appropriata una versione
:manpage:`xyzzyat(2)`::
int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
Questo permette più flessibilità su come lo spazio utente specificherà il file
in questione; in particolare, permette allo spazio utente di richiedere la
funzionalità su un descrittore di file già aperto utilizzando il *flag*
``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione
:manpage:`fxyzzy(3)`::
- xyzzyat(AT_FDCWD, path, ..., 0) is equivalent to xyzzy(path,...)
- xyzzyat(fd, "", ..., AT_EMPTY_PATH) is equivalent to fxyzzy(fd, ...)
(Per maggiori dettagli sulla logica delle chiamate \*at(), leggete la pagina
man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina
man :manpage:`fstatat(2)`).
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede un parametro
per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come
tipo cosicché scostamenti a 64-bit potranno essere supportati anche su
architetture a 32-bit.
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede l'uso di
funzioni riservate, allora dev'essere gestita da un opportuno bit di privilegio
(verificato con una chiamata a ``capable()``), come descritto nella pagina man
:manpage:`capabilities(7)`. Scegliete un bit di privilegio già esistente per
gestire la funzionalità associata, ma evitate la combinazione di diverse
funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il
principio di *capabilities* di separare i poteri di root. In particolare,
evitate di aggiungere nuovi usi al fin-troppo-generico privilegio
``CAP_SYS_ADMIN``.
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` manipola altri
processi oltre a quello chiamato, allora dovrebbe essere limitata (usando
la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
con gli stessi permessi del processo in oggetto, o con i necessari privilegi,
possa manipolarlo.
Infine, state attenti che in alcune architetture non-x86 la vita delle chiamate
di sistema con argomenti a 64-bit viene semplificata se questi argomenti
ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette
l'uso di coppie contigue di registri a 32-bit. (Questo non conta se gli
argomenti sono parte di una struttura dati che viene passata per puntatore).
Proporre l'API
--------------
Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio
che dividiate le modifiche i pezzi separati. Questi dovrebbero includere
almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto
più avanti):
- l'essenza dell'implementazione della chiamata di sistema, con i prototipi,
i numeri generici, le modifiche al Kconfig e l'implementazione *stub* di
ripiego.
- preparare la nuova chiamata di sistema per un'architettura specifica,
solitamente x86 (ovvero tutti: x86_64, x86_32 e x32).
- un programma di auto-verifica da mettere in ``tools/testing/selftests/``
che mostri l'uso della chiamata di sistema.
- una bozza di pagina man per la nuova chiamata di sistema. Può essere
scritta nell'email di presentazione, oppure come modifica vera e propria
al repositorio delle pagine man.
Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del
kernel, deve essere sottomessa alla lista di discussione
linux-api@vger.kernel.org.
Implementazione di chiamate di sistema generiche
------------------------------------------------
Il principale punto d'accesso alla vostra nuova chiamata di sistema
:manpage:`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo
esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'
indica il numero di argomenti della chiamata di sistema; la macro ha come
argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)
per definire i suoi parametri. L'uso di questa macro permette di avere
i metadati della nuova chiamata di sistema disponibili anche per altri
strumenti.
Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in
``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli
il modo in cui quelle chiamate di sistema verranno invocate::
asmlinkage long sys_xyzzy(...);
Alcune architetture (per esempio x86) hanno le loro specifiche tabelle di
chiamate di sistema (syscall), ma molte altre architetture condividono una
tabella comune di syscall. Aggiungete alla lista generica la vostra nuova
chiamata di sistema aggiungendo un nuovo elemento alla lista in
``include/uapi/asm-generic/unistd.h``::
#define __NR_xyzzy 292
__SYSCALL(__NR_xyzzy, sys_xyzzy)
Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con
l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova
chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero
della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i
conflitti.
Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che
ritornano ``-ENOSYS``. Aggiungete la vostra nuova chiamata di sistema anche
qui::
COND_SYSCALL(xyzzy);
La vostra nuova funzionalità del kernel, e la chiamata di sistema che la
controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione
``CONFIG`` (solitamente in ``init/Kconfig``). Come al solito per le nuove
opzioni ``CONFIG``:
- Includete una descrizione della nuova funzionalità e della chiamata di
sistema che la controlla.
- Rendete l'opzione dipendente da EXPERT se dev'essere nascosta agli utenti
normali.
- Nel Makefile, rendere tutti i nuovi file sorgenti, che implementano la
nuova funzionalità, dipendenti dall'opzione CONFIG (per esempio
``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
- Controllate due volte che sia possibile generare il kernel con la nuova
opzione CONFIG disabilitata.
Per riassumere, vi serve un *commit* che includa:
- un'opzione ``CONFIG``per la nuova funzione, normalmente in ``init/Kconfig``
- ``SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
- il corrispondente prototipo in ``include/linux/syscalls.h``
- un elemento nella tabella generica in ``include/uapi/asm-generic/unistd.h``
- *stub* di ripiego in ``kernel/sys_ni.c``
Implementazione delle chiamate di sistema x86
---------------------------------------------
Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
dovete aggiornate la tabella principale di syscall. Assumendo che la vostra
nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
dovete aggiungere un elemento *common* (per x86_64 e x32) in
arch/x86/entry/syscalls/syscall_64.tbl::
333 common xyzzy sys_xyzzy
e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
380 i386 xyzzy sys_xyzzy
Ancora una volta, questi numeri potrebbero essere cambiati se generano
conflitti durante la finestra di integrazione.
Chiamate di sistema compatibili (generico)
------------------------------------------
Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
invocata anche quando il programma in spazio utente è a 32-bit; anche se la
chiamata di sistema include esplicitamente un puntatore, questo viene gestito
in modo trasparente.
Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
livello di gestione della compatibilità per risolvere le differenze di
dimensioni fra 32-bit e 64-bit.
Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
potrebbero contenere valori a 32-bit o a 64-bit. In particolar modo, questo
è necessario quando un argomento di una chiamata di sistema è:
- un puntatore ad un puntatore
- un puntatore ad una struttura dati contenente a sua volta un puntatore
( ad esempio ``struct iovec __user *``)
- un puntatore ad un tipo intero di dimensione variabile (``time_t``,
``off_t``, ``long``, ...)
- un puntatore ad una struttura dati contenente un tipo intero di dimensione
variabile.
Il secondo caso che richiede un livello di gestione della compatibilità è
quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
in questo livello di compatibilità.
(Da notare che non serve questo livello di compatibilità per argomenti che
sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
:manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
di una chiamata di sistema ``compat_``)
La versione compatibile della nostra chiamata di sistema si chiamerà
``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn). Questa versione
dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
che trasformerà secondo le necessità (tipicamente, la versione
``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
le parti comuni).
Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
il modo in cui quelle chiamate di sistema verranno invocate::
asmlinkage long compat_sys_xyzzy(...);
Se la chiamata di sistema prevede una struttura dati organizzata in modo
diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo
``struct xyzzy_args``, allora il file d'intestazione
``then the include/linux/compat.h`` deve includere la sua versione
*compatibile* (``struct compat_xyzzy_args``); ogni variabile con
dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
a quello in ``struct xyzzy_args``. La funzione ``compat_sys_xyzzy()``
può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
da una chiamata a 32-bit.
Per esempio, se avete i seguenti campi::
struct xyzzy_args {
const char __user *ptr;
__kernel_long_t varying_val;
u64 fixed_val;
/* ... */
};
nella struttura ``struct xyzzy_args``, allora la struttura
``struct compat_xyzzy_args`` dovrebbe avere::
struct compat_xyzzy_args {
compat_uptr_t ptr;
compat_long_t varying_val;
u64 fixed_val;
/* ... */
};
La lista generica delle chiamate di sistema ha bisogno di essere
aggiustata al fine di permettere l'uso della versione *compatibile*;
la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare
``__SC_COMP`` piuttosto di ``__SYSCALL``::
#define __NR_xyzzy 292
__SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
Riassumendo, vi serve:
- un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
*compatibile*
- un prototipo in ``include/linux/compat.h``
- (se necessario) una struttura di compatibilità a 32-bit in
``include/linux/compat.h``
- una voce ``__SC_COMP``, e non ``__SYSCALL``, in
``include/uapi/asm-generic/unistd.h``
Compatibilità delle chiamate di sistema (x86)
---------------------------------------------
Per collegare una chiamata di sistema, su un'architettura x86, con la sua
versione *compatibile*, è necessario aggiustare la voce nella tabella
delle syscall.
Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
un argomento aggiuntivo per indicare che un programma in spazio utente
a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
d'accesso compatibile::
380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy
Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
per la versione dell'ABI x32. Qui C'è una scelta da fare: gli argomenti
possono corrisponde alla versione a 64-bit o a quella a 32-bit.
Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
x32 eseguano la chiamata *compatibile*::
333 64 xyzzy sys_xyzzy
...
555 x32 xyzzy __x32_compat_sys_xyzzy
Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
32-bit (-m32) o 64-bit (-m64).
Chiamate di sistema che ritornano altrove
-----------------------------------------
Nella maggior parte delle chiamate di sistema, al termine della loro
esecuzione, i programmi in spazio utente riprendono esattamente dal punto
in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
stesso *stack* e con la maggior parte del registri com'erano stati
lasciati prima della chiamata di sistema, e anche con la stessa memoria
virtuale.
Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
l'architettura del programma (``execve``/``execveat``).
Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
chiamate di sistema potrebbero dover salvare e ripristinare registri
aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
chiamata di sistema.
Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
dei punti d'accesso in *assembly* per salvare/ripristinare i registri
aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
sistema.
Per l'architettura x86_64, questo è implementato come un punto d'accesso
``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella
di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
conseguenza::
333 common xyzzy stub_xyzzy
L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
normalmente chiamato ``stub32_xyzzy`` e implementato in
``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
seguente modo::
380 i386 xyzzy sys_xyzzy stub32_xyzzy
Se una chiamata di sistema necessita di un livello di compatibilità (come
nella sezione precedente), allora la versione ``stub32_`` deve invocare
la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit. In aggiunta,
se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
``compat_sys_``,
Per completezza, sarebbe carino impostare una mappatura cosicché
*user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
farà riferimento a stub_xyzzy, ma UML non include l'implementazione
in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
Correggerlo è semplice, basta aggiungere una #define in
``arch/x86/um/sys_call_table_64.c``::
#define stub_xyzzy sys_xyzzy
Altri dettagli
--------------
La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
ma possono esserci rare eccezioni per le quali potrebbe essere necessario
l'aggiornamento della vostra chiamata di sistema.
Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
speciali; esso include (per architettura) funzioni che classificano alcuni
tipi di chiamate di sistema -- in particolare apertura dei file
(``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
essere aggiornato.
Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
di sistema esistente per verificare che non ci siano altri casi speciali.
Verifica
--------
Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
ai revisori un programma in spazio utente che mostri l'uso della chiamata di
sistema. Un buon modo per combinare queste cose è quello di aggiungere un
semplice programma di auto-verifica in una nuova cartella in
``tools/testing/selftests/``.
Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
visibile in spazio utente, il file d'intestazione necessario dev'essere
installato al fine di compilare il programma.
Assicuratevi che il programma di auto-verifica possa essere eseguito
correttamente su tutte le architetture supportate. Per esempio, verificate che
funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
oppure al progetto xfstests per cambiamenti relativi al filesystem.
- https://linux-test-project.github.io/
- git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
Pagine man
----------
Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
idealmente usando i marcatori groff, ma anche il puro testo può andare. Se
state usando groff, è utile che includiate nella email di presentazione una
versione già convertita in formato ASCII: semplificherà la vita dei revisori.
Le pagine man dovrebbero essere in copia-conoscenza verso
linux-man@vger.kernel.org
Per maggiori dettagli, leggere
https://www.kernel.org/doc/man-pages/patches.html
Non invocate chiamate di sistema dal kernel
-------------------------------------------
Le chiamate di sistema sono, come già detto prima, punti di interazione fra
lo spazio utente e il kernel. Perciò, le chiamate di sistema come
``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
kernel. Se la nuova funzionalità è utile all'interno del kernel, per esempio
dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
allora dev'essere implementata come una funzione di supporto
(*helper function*) (per esempio ``kern_xyzzy()``). Questa funzione potrà
essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
(``compat_sys_xyzzy()``), e/o da altri parti del kernel.
Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove
``struct pt_regs`` viene decodificata al volo in una funzione che racchiude
la chiamata di sistema la quale verrà eseguita successivamente.
Questo significa che verranno passati solo i parametri che sono davvero
necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
6 registri del processore con contenuti presi dallo spazio utente (potrebbe
causare seri problemi nella sequenza di chiamate).
Inoltre, le regole su come i dati possano essere usati potrebbero differire
fra il kernel e l'utente. Questo è un altro motivo per cui invocare
``sys_xyzzy()`` è generalmente una brutta idea.
Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
o per altro codice in arch/
Riferimenti e fonti
-------------------
- Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle
chiamate di sistema: https://lwn.net/Articles/585415/
- Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in
una chiamata di sistema: https://lwn.net/Articles/588444/
- Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit
delle chiamate di sistema: https://lwn.net/Articles/311630/
- Una coppia di articoli di David Drysdale che descrivono i dettagli del
percorso implementativo di una chiamata di sistema per la versione v3.14:
- https://lwn.net/Articles/604287/
- https://lwn.net/Articles/604515/
- Requisiti specifici alle architetture sono discussi nella pagina man
:manpage:`syscall(2)` :
http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
- Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:
http://yarchive.net/comp/linux/ioctl.html
- "Come non inventare interfacce del kernel", Arnd Bergmann,
http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
- Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN:
https://lwn.net/Articles/486306/
- Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni
su una nuova chiamata di sistema dovrebbero essere contenute nello stesso
filone di discussione di email: https://lkml.org/lkml/2014/7/24/641
- Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
sistema dovrebbero avere una pagina man: https://lkml.org/lkml/2014/6/13/309
- Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
x86 dovrebbe avvenire in un *commit* differente:
https://lkml.org/lkml/2014/11/19/254
- Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un
programma di auto-verifica per le nuove chiamate di sistema:
https://lkml.org/lkml/2014/3/19/710
- Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
le estensioni :manpage:`prctl(2)`: https://lkml.org/lkml/2014/6/3/411
- Consigli da Ingo Molnar che le chiamate di sistema con più argomenti
dovrebbero incapsularli in una struttura che includa un argomento
*size* per garantire l'estensibilità futura:
https://lkml.org/lkml/2015/7/30/117
- Un certo numero di casi strani emersi dall'uso (riuso) dei flag 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")
- Discussion from Matthew Wilcox about restrictions on 64-bit arguments:
https://lkml.org/lkml/2008/12/12/187
- Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
essere controllati: https://lkml.org/lkml/2014/7/17/577
- Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero
favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit:
https://lkml.org/lkml/2011/8/31/244

View File

@ -0,0 +1,13 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/applying-patches.rst <applying_patches>`
.. _it_applying_patches:
Applicare modifiche al kernel Linux
===================================
.. warning::
TODO ancora da tradurre

View File

@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/changes.rst <changes>`
.. _it_changes:
Requisiti minimi per compilare il kernel
++++++++++++++++++++++++++++++++++++++++
.. warning::
TODO ancora da tradurre

View File

@ -0,0 +1,197 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/clang-format.rst <clangformat>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_clangformat:
clang-format
============
``clang-format`` è uno strumento per formattare codice C/C++/... secondo
un gruppo di regole ed euristiche. Come tutti gli strumenti, non è perfetto
e non copre tutti i singoli casi, ma è abbastanza buono per essere utile.
``clang-format`` può essere usato per diversi fini:
- Per riformattare rapidamente un blocco di codice secondo lo stile del
kernel. Particolarmente utile quando si sposta del codice e lo si
allinea/ordina. Vedere it_clangformatreformat_.
- Identificare errori di stile, refusi e possibili miglioramenti nei
file che mantieni, le modifiche che revisioni, le differenze,
eccetera. Vedere it_clangformatreview_.
- Ti aiuta a seguire lo stile del codice, particolarmente utile per i
nuovi arrivati o per coloro che lavorano allo stesso tempo su diversi
progetti con stili di codifica differenti.
Il suo file di configurazione è ``.clang-format`` e si trova nella cartella
principale dei sorgenti del kernel. Le regole scritte in quel file tentano
di approssimare le lo stile di codifica del kernel. Si tenta anche di seguire
il più possibile
:ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`.
Dato che non tutto il kernel segue lo stesso stile, potreste voler aggiustare
le regole di base per un particolare sottosistema o cartella. Per farlo,
potete sovrascriverle scrivendole in un altro file ``.clang-format`` in
una sottocartella.
Questo strumento è già stato incluso da molto tempo nelle distribuzioni
Linux più popolari. Cercate ``clang-format`` nel vostro repositorio.
Altrimenti, potete scaricare una versione pre-generata dei binari di LLVM/clang
oppure generarlo dai codici sorgenti:
http://releases.llvm.org/download.html
Troverete più informazioni ai seguenti indirizzi:
https://clang.llvm.org/docs/ClangFormat.html
https://clang.llvm.org/docs/ClangFormatStyleOptions.html
.. _it_clangformatreview:
Revisionare lo stile di codifica per file e modifiche
-----------------------------------------------------
Eseguendo questo programma, potrete revisionare un intero sottosistema,
cartella o singoli file alla ricerca di errori di stile, refusi o
miglioramenti.
Per farlo, potete eseguire qualcosa del genere::
# Make sure your working directory is clean!
clang-format -i kernel/*.[ch]
E poi date un'occhiata a *git diff*.
Osservare le righe di questo diff è utile a migliorare/aggiustare
le opzioni di stile nel file di configurazione; così come per verificare
le nuove funzionalità/versioni di ``clang-format``.
``clang-format`` è in grado di leggere diversi diff unificati, quindi
potrete revisionare facilmente delle modifiche e *git diff*.
La documentazione si trova al seguente indirizzo:
https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting
Per evitare che ``clang-format`` formatti alcune parti di un file, potete
scrivere nel codice::
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
Nonostante si attraente l'idea di utilizzarlo per mantenere un file
sempre in sintonia con ``clang-format``, specialmente per file nuovi o
se siete un manutentore, ricordatevi che altre persone potrebbero usare
una versione diversa di ``clang-format`` oppure non utilizzarlo del tutto.
Quindi, dovreste trattenervi dall'usare questi marcatori nel codice del
kernel; almeno finché non vediamo che ``clang-format`` è diventato largamente
utilizzato.
.. _it_clangformatreformat:
Riformattare blocchi di codice
------------------------------
Utilizzando dei plugin per il vostro editor, potete riformattare una
blocco (selezione) di codice con una singola combinazione di tasti.
Questo è particolarmente utile: quando si riorganizza il codice, per codice
complesso, macro multi-riga (e allineare le loro "barre"), eccetera.
Ricordatevi che potete sempre aggiustare le modifiche in quei casi dove
questo strumento non ha fatto un buon lavoro. Ma come prima approssimazione,
può essere davvero molto utile.
Questo programma si integra con molti dei più popolari editor. Alcuni di
essi come vim, emacs, BBEdit, Visaul Studio, lo supportano direttamente.
Al seguente indirizzo troverete le istruzioni:
https://clang.llvm.org/docs/ClangFormat.html
Per Atom, Eclipse, Sublime Text, Visual Studio Code, XCode e altri editor
e IDEs dovreste essere in grado di trovare dei plugin pronti all'uso.
Per questo caso d'uso, considerate l'uso di un secondo ``.clang-format``
che potete personalizzare con le vostre opzioni.
Consultare it_clangformatextra_.
.. _it_clangformatmissing:
Cose non supportate
-------------------
``clang-format`` non ha il supporto per alcune cose che sono comuni nel
codice del kernel. Sono facili da ricordare; quindi, se lo usate
regolarmente, imparerete rapidamente a evitare/ignorare certi problemi.
In particolare, quelli più comuni che noterete sono:
- Allineamento di ``#define`` su una singola riga, per esempio::
#define TRACING_MAP_BITS_DEFAULT 11
#define TRACING_MAP_BITS_MAX 17
#define TRACING_MAP_BITS_MIN 7
contro::
#define TRACING_MAP_BITS_DEFAULT 11
#define TRACING_MAP_BITS_MAX 17
#define TRACING_MAP_BITS_MIN 7
- Allineamento dei valori iniziali, per esempio::
static const struct file_operations uprobe_events_ops = {
.owner = THIS_MODULE,
.open = probes_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.write = probes_write,
};
contro::
static const struct file_operations uprobe_events_ops = {
.owner = THIS_MODULE,
.open = probes_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.write = probes_write,
};
.. _it_clangformatextra:
Funzionalità e opzioni aggiuntive
---------------------------------
Al fine di minimizzare le differenze fra il codice attuale e l'output
del programma, alcune opzioni di stile e funzionalità non sono abilitate
nella configurazione base. In altre parole, lo scopo è di rendere le
differenze le più piccole possibili, permettendo la semplificazione
della revisione di file, differenze e modifiche.
In altri casi (per esempio un particolare sottosistema/cartella/file), lo
stile del kernel potrebbe essere diverso e abilitare alcune di queste
opzioni potrebbe dare risultati migliori.
Per esempio:
- Allineare assegnamenti (``AlignConsecutiveAssignments``).
- Allineare dichiarazioni (``AlignConsecutiveDeclarations``).
- Riorganizzare il testo nei commenti (``ReflowComments``).
- Ordinare gli ``#include`` (``SortIncludes``).
Piuttosto che per interi file, solitamente sono utili per la riformattazione
di singoli blocchi. In alternativa, potete creare un altro file
``.clang-format`` da utilizzare con il vostro editor/IDE.

View File

@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/code-of-conduct.rst <code_of_conduct>`
.. _it_code_of_conduct:
Accordo dei contributori sul codice di condotta
+++++++++++++++++++++++++++++++++++++++++++++++
.. warning::
TODO ancora da tradurre

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/development-process.rst <development_process_main>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_development_process_main:
Una guida al processo di sviluppo del Kernel
============================================
Contenuti:
.. toctree::
:numbered:
:maxdepth: 2
1.Intro
2.Process
3.Early-stage
4.Coding
5.Posting
6.Followthrough
7.AdvancedTopics
8.Conclusion
Lo scopo di questo documento è quello di aiutare gli sviluppatori (ed i loro
supervisori) a lavorare con la communità di sviluppo con il minimo sforzo. È
un tentativo di documentare il funzionamento di questa communità in modo che
sia accessibile anche a coloro che non hanno famigliarità con lo sviluppo del
Kernel Linux (o, anzi, con lo sviluppo di software libero in generale). Benchè
qui sia presente del materiale tecnico, questa è una discussione rivolta in
particolare al procedimento, e quindi per essere compreso non richiede una
conoscenza approfondità sullo sviluppo del kernel.

View File

@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/email-clients.rst <email_clients>`
.. _it_email_clients:
Informazioni sui programmi di posta elettronica per Linux
=========================================================
.. warning::
TODO ancora da tradurre

Some files were not shown because too many files have changed in this diff Show More