Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -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.
@@ -0,0 +1,530 @@
.. 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:
====== =================
5.0 3 marzo, 2019
5.1 5 maggio, 2019
5.2 7 luglio, 2019
5.3 15 settembre, 2019
5.4 24 novembre, 2019
5.5 6 gennaio, 2020
====== =================
Ciascun rilascio 5.x è un importante rilascio del kernel con nuove
funzionalità, modifiche interne dell'API, e molto altro. Un tipico
rilascio contiene quasi 13,000 gruppi di modifiche con ulteriori
modifiche a parecchie migliaia di linee di codice. La 5.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 5.6, per esempio, il rilascio
che emerge al termine della finestra d'inclusione si chiamerà 5.6-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 venga fatto. A quel punto tutto il processo ricomincerà.
Esempio: ecco com'è andato il ciclo di sviluppo della versione 5.4
(tutte le date si collocano nel 2018)
============== =======================================
15 settembre 5.3 rilascio stabile
30 settembre 5.4-rc1, finestra di inclusione chiusa
6 ottobre 5.4-rc2
13 ottobre 5.4-rc3
20 ottobre 5.4-rc4
27 ottobre 5.4-rc5
3 novembre 5.4-rc6
10 novembre 5.4-rc7
17 novembre 5.4-rc8
24 novembre 5.4 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 5.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 5.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 5.2 appare così (anno 2019):
============== ===============================
7 luglio 5.2 rilascio stabile
14 luglio 5.2.1
21 luglio 5.2.2
26 luglio 5.2.3
28 luglio 5.2.4
31 luglio 5.2.5
... ...
11 ottobre 5.2.21
============== ===============================
La 5.2.21 fu l'aggiornamento finale per la versione 5.2.
Alcuni kernel sono destinati ad essere kernel a "lungo termine"; questi
riceveranno assistenza per un lungo periodo di tempo. Consultate il seguente
collegamento per avere la lista delle versioni attualmente supportate e i
relativi manutentori:
https://www.kernel.org/category/releases.html
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, per esempio, 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:
https://subspace.kernel.org
Tuttavia, esistono liste gestite altrove; controllare il file MAINTAINERS per
trovare la lista relativa ad un sottosistema specifico.
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.
- Rispondete sotto alla porzione di righe citate, così da dare un contesto alle
vostre risposte, e quindi renderle più leggibili (in altre parole, evitate di
rispondere in cima, ovvero prima del testo citato). Per maggiori dettagli
leggete :ref:`Documentation/translations/it_IT/process/submitting-patches.rst
<it_interleaved_replies>`.
- 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.
@@ -0,0 +1,242 @@
.. 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.
Questo è la maniera raccomandata (non quella con "-f") per ottenere la lista di
persone da aggiungere a Cc per le vostre patch. 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.
@@ -0,0 +1,451 @@
.. 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.
L’altra 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/dev-tools/clang-format.rst <clangformat>`
per maggiori dettagli
Se utilizzate un programma compatibile con EditorConfig, allora alcune
configurazioni basilari come l'indentazione e la fine delle righe verranno
applicate automaticamente. Per maggiori informazioni consultate la pagina:
https://editorconfig.org/
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 KCFLAGS=-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:
- FRAME_WARN per ottenere degli avvertimenti su stack frame più
grandi di un dato valore. 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.rst 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" (https://coccinelle.gitlabpages.inria.fr/website/)
è 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.
@@ -0,0 +1,381 @@
.. 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>`
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.
Le etichette sopracitate danno un'idea di come una patch prende vita e sono
descritte nel dettaglio nel documento
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
Qui di seguito un breve riassunto.
Un'etichetta ci può dire quale commit ha introdotto il problema che viene corretto nella patch::
Fixes: 1f2e3d4c5b6a ("The first line of the commit specified by the first 12 characters of its SHA-1 ID")
Un'altra etichetta viene usata per fornire collegamenti a pagine web contenenti
maggiori informazioni, per esempio una discussione avvenuta precedentemente
circa il baco risolto dalla patch, oppure un documento con le specifiche
implementate dalla patch::
Link: https://example.com/somewhere.html optional-other-stuff
Alcuni manutentori aggiungono quest'etichetta alla patch per fare riferimento
alla più recente discussione pubblica. A volte questo è fatto automaticamente da
alcuni strumenti come b4 or un *hook* git come quello descritto qui
'Documentation/translations/it_IT/maintainer/configure-git.rst'
Se il collegamento indirizza verso un rapporto su un baco risolto dalla patch,
allora usate l'etichetta "Closes:"::
Closes: https://example.com/issues/1234 optional-other-stuff
Alcune piattaforme di tracciamento di bachi hanno la capacità di chiudere
automaticamente il problema se l'etichetta è presente nel messaggio. Alcuni
automatismi che monitorano la liste di discussione possono anche tracciare
queste etichette e intraprendere azioni. Piattaforme private e URL invalidi sono
proibiti.
Un altro tipo di etichetta viene usato per indicare chi ha contribuito allo
sviluppo della patch. Tutte queste etichette seguono il 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 cosviluppata da diversi
sviluppatori; viene usato per assegnare più autori (in aggiunta a quello
associato all'etichetta From:) quando più persone lavorano ad una patch.
Ogni Co-developed-by: dev'essere seguito immediatamente da un Signed-off-by:
del corrispondente coautore. Maggiori dettagli ed esempi sono disponibili
in :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
- 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. Questa etichetta dovrebbe essere seguita da
quella Closes: con un indirizzo al rapporto, a meno che questo non sia
disponibile sul web. L'etichetta Link: può essere usata in alternativa a
Closes: se la patch corregge solo in parte il problema riportato nel
rapporto.
Se esiste un rapporto disponibile sul web, allora
L'etichetta dovrebbe essere seguita da un collegamento al suddetto rapporto.
- 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. Il più
delle volte anche Reported-by: va bene, ma è sempre meglio chiedere specialmente
se il baco è stato riportato in una comunicazione privata.
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.
@@ -0,0 +1,247 @@
.. 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.
- Preparatevi a richieste apparentemente sciocche di modifiche allo stile di
codifica e a richieste di trasferire parte del vostro codice in parti
condivise del kernel. Uno dei compiti dei manutentori è quello di mantenere
lo aspetto del codice. A volte questo significa che l'ingegnoso stratagemma
nel vostro driver per aggirare un problema deve diventare una caratteristica
generalizzata del kernel pronta per essere riutilizzata.
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.
@@ -0,0 +1,210 @@
.. 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:
https://git-scm.com/
https://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 https://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.
(https://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.
.. _development_advancedtopics_reviews_it:
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".
In caso di disaccordi, può essere utile chiedere una terza opinione. Se dopo
pochi scambi la discussione raggiunge un punto morto, allora chiedete ai
manutentori o altri revisori di partecipare esprimendo la loro opinione. Spesso
vige un silenzio assenso per cui gli altri revisori non intervengono se non gli
viene richiesto esplicitamente. L'opinione di più persone avrà sicuramente un
peso maggiore.
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.
Non esistono requisiti particolarmente stringenti per l'uso di etichette come
``Reviewed-by``. Tuttavia, perché la revisione sia efficace ci si aspetta un
qualche tipo di messaggio che dica "ho verificato A, B e C nel codice che è
appena stato inviato e mi sembra tutto in ordine". Inoltre, questo permette ai
manutentori di prendere conoscenza circa una revisione avvenuta per davvero.
Per finire, la revisione delle patch può diventare un processo negativo, troppo
focalizzato sulla ricerca dei problemi. Provate a fare qualche complimento di
tanto in tanto, specialmente con i nuovi arrivati.
@@ -0,0 +1,84 @@
.. 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>` è
anch'esso 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.
@@ -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/filesystems/sysfs.rst``) 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 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 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
`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
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 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 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 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
`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 ``ksys_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://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
- Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
- Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
x86 dovrebbe avvenire in un *commit* differente:
https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
- 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://lore.kernel.org/r/20140320025530.GA25469@kroah.com
- Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
- 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://lore.kernel.org/r/20150730083831.GA22182@gmail.com
- 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://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org
- Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
- 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://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com
@@ -0,0 +1,15 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/applying-patches.rst <applying_patches>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_applying_patches:
Applicare patch al kernel Linux
+++++++++++++++++++++++++++++++
.. note::
Questo documento è obsoleto. Nella maggior parte dei casi, piuttosto
che usare ``patch`` manualmente, vorrete usare Git. Per questo motivo
il documento non verrà tradotto.
@@ -0,0 +1,249 @@
.. include:: ../disclaimer-ita.rst
:Original: Documentation/process/botching-up-ioctls.rst
==========================================
(Come evitare di) Raffazzonare delle ioctl
==========================================
Preso da: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html
Scritto da : Daniel Vetter, Copyright © 2013 Intel Corporation
Una cosa che gli sviluppatori del sottosistema grafico del kernel Linux hanno
imparato negli ultimi anni è l'inutilità di cercare di creare un'interfaccia
unificata per gestire la memoria e le unità esecutive di diverse GPU. Dunque,
oggigiorno ogni driver ha il suo insieme di ioctl per allocare memoria ed
inviare dei programmi alla GPU. Il che è va bene dato che non c'è più un insano
sistema che finge di essere generico, ma al suo posto ci sono interfacce
dedicate. Ma al tempo stesso è più facile incasinare le cose.
Per evitare di ripetere gli stessi errori ho preso nota delle lezioni imparate
mentre raffazzonavo il driver drm/i915. La maggior parte di queste lezioni si
focalizzano sui tecnicismi e non sulla visione d'insieme, come le discussioni
riguardo al modo migliore per implementare una ioctl per inviare compiti alla
GPU. Probabilmente, ogni sviluppatore di driver per GPU dovrebbe imparare queste
lezioni in autonomia.
Prerequisiti
------------
Prima i prerequisiti. Seguite i seguenti suggerimenti se non volete fallire in
partenza e ritrovarvi ad aggiungere un livello di compatibilità a 32-bit.
* Usate solamente interi a lunghezza fissa. Per evitare i conflitti coi tipi
definiti nello spazio utente, il kernel definisce alcuni tipi speciali, come:
``__u32``, ``__s64``. Usateli.
* Allineate tutto alla lunghezza naturale delle piattaforma in uso e riempite
esplicitamente i vuoti. Non necessariamente le piattaforme a 32-bit allineano
i valori a 64-bit rispettandone l'allineamento, ma le piattaforme a 64-bit lo
fanno. Dunque, per farlo correttamente in entrambe i casi dobbiamo sempre
riempire i vuoti.
* Se una struttura dati contiene valori a 64-bit, allora fate si che la sua
dimensione sia allineata a 64-bit, altrimenti la sua dimensione varierà su
sistemi a 32-bit e 64-bit. Avere una dimensione differente causa problemi
quando si passano vettori di strutture dati al kernel, o quando il kernel
effettua verifiche sulla dimensione (per esempio il sistema drm lo fa).
* I puntatori sono di tipo ``__u64``, con un *cast* da/a ``uintptr_t`` da lato
spazio utente e da/a ``void __user *`` nello spazio kernel. Sforzatevi il più
possibile per non ritardare la conversione, o peggio maneggiare ``__u64`` nel
vostro codice perché questo riduce le verifiche che strumenti come sparse
possono effettuare. La macro u64_to_user_ptr() può essere usata nel kernel
per evitare avvisi riguardo interi e puntatori di dimensioni differenti.
Le Basi
-------
Con la gioia d'aver evitato un livello di compatibilità, possiamo ora dare uno
sguardo alle basi. Trascurare questi punti renderà difficile la gestione della
compatibilità all'indietro ed in avanti. E dato che sbagliare al primo colpo è
garantito, dovrete rivisitare il codice o estenderlo per ogni interfaccia.
* Abbiate un modo chiaro per capire dallo spazio utente se una nuova ioctl, o
l'estensione di una esistente, sia supportata dal kernel in esecuzione. Se non
potete fidarvi del fatto che un vecchio kernel possa rifiutare correttamente
un nuovo *flag*, modalità, o ioctl, (probabilmente perché avevate raffazzonato
qualcosa nel passato) allora dovrete implementare nel driver un meccanismo per
notificare quali funzionalità sono supportate, o in alternativa un numero di
versione.
* Abbiate un piano per estendere le ioctl con nuovi *flag* o campi alla fine di
una struttura dati. Il sistema drm verifica la dimensione di ogni ioctl in
arrivo, ed estende con zeri ogni incongruenza fra kernel e spazio utente.
Questo aiuta, ma non è una soluzione completa dato che uno spazio utente nuovo
su un kernel vecchio non noterebbe che i campi nuovi alla fine della struttura
vengono ignorati. Dunque, anche questo avrà bisogno di essere notificato dal
driver allo spazio utente.
* Verificate tutti i campi e *flag* inutilizzati ed i riempimenti siano a 0,
altrimenti rifiutare la ioctl. Se non lo fate il vostro bel piano per
estendere le ioctl andrà a rotoli dato che qualcuno userà delle ioctl con
strutture dati con valori casuali dallo stack nei campi inutilizzati. Il che
si traduce nell'avere questi campi nell'ABI, e la cui unica utilità sarà
quella di contenere spazzatura. Per questo dovrete esplicitamente riempire i
vuoti di tutte le vostre strutture dati, anche se non le userete in un
vettore. Il riempimento fatto dal compilatore potrebbe contenere valori
casuali.
* Abbiate un semplice codice di test per ognuno dei casi sopracitati.
Divertirsi coi percorsi d'errore
--------------------------------
Oggigiorno non ci sono più scuse rimaste per permettere ai driver drm di essere
sfruttati per diventare root. Questo significa che dobbiamo avere una completa
validazione degli input e gestire in modo robusto i percorsi - tanto le GPU
moriranno comunque nel più strano dei casi particolari:
* Le ioctl devono verificare l'overflow dei vettori. Inoltre, per i valori
interi si devono verificare *overflow*, *underflow*, e *clamping*. Il
classico esempio è l'inserimento direttamente nell'hardware di valori di
posizionamento di un'immagine *sprite* quando l'hardware supporta giusto 12
bit, o qualcosa del genere. Tutto funzionerà finché qualche strano *display
server* non decide di preoccuparsi lui stesso del *clamping* e il cursore
farà il giro dello schermo.
* Avere un test semplice per ogni possibile fallimento della vostra ioctl.
Verificate che il codice di errore rispetti le aspettative. Ed infine,
assicuratevi che verifichiate un solo percorso sbagliato per ogni sotto-test
inviando comunque dati corretti. Senza questo, verifiche precedenti
potrebbero rigettare la ioctl troppo presto, impedendo l'esecuzione del
codice che si voleva effettivamente verificare, rischiando quindi di
mascherare bachi e regressioni.
* Fate si che tutte le vostre ioctl siano rieseguibili. Prima di tutto X adora
i segnali; secondo questo vi permetterà di verificare il 90% dei percorsi
d'errore interrompendo i vostri test con dei segnali. Grazie all'amore di X
per i segnali, otterrete gratuitamente un eccellente copertura di base per
tutti i vostri percorsi d'errore. Inoltre, siate consistenti sul modo di
gestire la riesecuzione delle ioctl - per esempio, drm ha una piccola
funzione di supporto `drmIoctl` nella sua librerie in spazio utente. Il
driver i915 l'abbozza con l'ioctl `set_tiling`, ed ora siamo inchiodati per
sempre con una semantica arcana sia nel kernel che nello spazio utente.
* Se non potete rendere un pezzo di codice rieseguibile, almeno rendete
possibile la sua interruzione. Le GPU moriranno e i vostri utenti non vi
apprezzeranno affatto se tenete in ostaggio il loro scatolotto (mediante un
processo X insopprimibile). Se anche recuperare lo stato è troppo complicato,
allora implementate una scadenza oppure come ultima spiaggia una rete di
sicurezza per rilevare situazioni di stallo quando l'hardware da di matto.
* Preparate dei test riguardo ai casi particolarmente estremi nel codice di
recupero del sistema - è troppo facile create uno stallo fra il vostro codice
anti-stallo e un processo scrittore.
Tempi, attese e mancate scadenze
--------------------------------
Le GPU fanno quasi tutto in modo asincrono, dunque dobbiamo regolare le
operazioni ed attendere quelle in sospeso. Questo è davvero difficile; al
momento nessuna delle ioctl supportante dal driver drm/i915 riesce a farlo
perfettamente, il che significa che qui ci sono ancora una valanga di lezioni da
apprendere.
* Per fare riferimento al tempo usate sempre ``CLOCK_MONOTONIC``. Oggigiorno
questo è quello che viene usato di base da alsa, drm, e v4l. Tuttavia,
lasciate allo spazio utente la possibilità di capire quali *timestamp*
derivano da domini temporali diversi come il vostro orologio di sistema
(fornito dal kernel) oppure un contatore hardware indipendente da qualche
parte. Gli orologi divergeranno, ma con questa informazione gli strumenti di
analisi delle prestazioni possono compensare il problema. Se il vostro spazio
utente può ottenere i valori grezzi degli orologi, allora considerate di
esporre anch'essi.
* Per descrivere il tempo, usate ``__s64`` per i secondi e ``__u64`` per i
nanosecondi. Non è il modo migliore per specificare il tempo, ma è
praticamente uno standard.
* Verificate che gli input di valori temporali siano normalizzati, e se non lo
sono scartateli. Fate attenzione perché la struttura dati ``struct ktime``
del kernel usa interi con segni sia per i secondi che per i nanosecondi.
* Per le scadenze (*timeout*) usate valori temporali assoluti. Se siete dei
bravi ragazzi e avete reso la vostra ioctl rieseguibile, allora i tempi
relativi tendono ad essere troppo grossolani e a causa degli arrotondamenti
potrebbero estendere in modo indefinito i tempi di attesa ad ogni
riesecuzione. Particolarmente vero se il vostro orologio di riferimento è
qualcosa di molto lento come il contatore di *frame*. Con la giacca da
avvocato delle specifiche diremmo che questo non è un baco perché tutte le
scadenze potrebbero essere estese - ma sicuramente gli utenti vi odieranno
quando le animazioni singhiozzano.
* Considerate l'idea di eliminare tutte le ioctl sincrone con scadenze, e di
sostituirle con una versione asincrona il cui stato può essere consultato
attraverso il descrittore di file mediante ``poll``. Questo approccio si
sposa meglio in un applicazione guidata dagli eventi.
* Sviluppate dei test per i casi estremi, specialmente verificate che i valori
di ritorno per gli eventi già completati, le attese terminate con successo, e
le attese scadute abbiano senso e servano ai vostri scopi.
Non perdere risorse
-------------------
Nel suo piccolo il driver drm implementa un sistema operativo specializzato per
certe GPU. Questo significa che il driver deve esporre verso lo spazio
utente tonnellate di agganci per accedere ad oggetti e altre risorse. Farlo
correttamente porterà con se alcune insidie:
* Collegate sempre la vita di una risorsa creata dinamicamente, a quella del
descrittore di file. Considerate una mappatura 1:1 se la vostra risorsa
dev'essere condivisa fra processi - passarsi descrittori di file sul socket
unix semplifica la gestione anche per lo spazio utente.
* Dev'esserci sempre Il supporto ``O_CLOEXEC``.
* Assicuratevi di avere abbastanza isolamento fra utenti diversi. Di base
impostate uno spazio dei nomi riservato per ogni descrittore di file, il che
forzerà ogni condivisione ad essere esplicita. Usate uno spazio più globale
per dispositivo solo se gli oggetti sono effettivamente unici per quel
dispositivo. Un controesempio viene dall'interfaccia drm modeset, dove
oggetti specifici di dispositivo, come i connettori, condividono uno spazio
dei nomi con oggetti per il *framebuffer*, ma questi non sono per niente
condivisi. Uno spazio separato, privato di base, per i *framebuffer* sarebbe
stato meglio.
* Pensate all'identificazione univoca degli agganci verso lo spazio utente. Per
esempio, per la maggior parte dei driver drm, si considera fallace la doppia
sottomissione di un oggetto allo stesso comando ioctl. Ma per evitarlo, se
gli oggetti sono condivisibili, lo spazio utente ha bisogno di sapere se il
driver ha importato un oggetto da un altro processo. Non l'ho ancora provato,
ma considerate l'idea di usare il numero di inode come identificatore per i
descrittori di file condivisi - che poi è come si distinguono i veri file.
Sfortunatamente, questo richiederebbe lo sviluppo di un vero e proprio
filesystem virtuale nel kernel.
Ultimo, ma non meno importante
------------------------------
Non tutti i problemi si risolvono con una nuova ioctl:
* Pensateci su due o tre volte prima di implementare un'interfaccia privata per
un driver. Ovviamente è molto più veloce seguire questa via piuttosto che
buttarsi in lunghe discussioni alla ricerca di una soluzione più generica. Ed
a volte un'interfaccia privata è quello che serve per sviluppare un nuovo
concetto. Ma alla fine, una volta che c'è un'interfaccia generica a
disposizione finirete per mantenere due interfacce. Per sempre.
* Considerate interfacce alternative alle ioctl. Gli attributi sysfs sono molto
meglio per impostazioni che sono specifiche di un dispositivo, o per
sotto-oggetti con una vita piuttosto statica (come le uscite dei connettori in
drm con tutti gli attributi per la sovrascrittura delle rilevazioni). O magari
solo il vostro sistema di test ha bisogno di una certa interfaccia, e allora
debugfs (che non ha un'interfaccia stabile) sarà la soluzione migliore.
Per concludere. Questo gioco consiste nel fare le cose giuste fin da subito,
dato che se il vostro driver diventa popolare e la piattaforma hardware longeva
finirete per mantenere le vostre ioctl per sempre. Potrete tentare di deprecare
alcune orribili ioctl, ma ci vorranno anni per riuscirci effettivamente. E
ancora, altri anni prima che sparisca l'ultimo utente capace di lamentarsi per
una regressione.
@@ -0,0 +1,553 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/changes.rst <changes>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_changes:
Requisiti minimi per compilare il kernel
++++++++++++++++++++++++++++++++++++++++
Introduzione
============
Questo documento fornisce una lista dei software necessari per eseguire questa
versione del kernel.
Questo documento è basato sul file "Changes" del kernel 2.0.x e quindi le
persone che lo scrissero meritano credito (Jared Mauch, Axel Boldt,
Alessandro Sigala, e tanti altri nella rete).
Requisiti minimi correnti
*************************
Prima di pensare d'avere trovato un baco, aggiornate i seguenti programmi
**almeno** alla versione indicata! Se non siete certi della versione che state
usando, il comando indicato dovrebbe dirvelo.
Questa lista presume che abbiate già un kernel Linux funzionante. In aggiunta,
non tutti gli strumenti sono necessari ovunque; ovviamente, se non avete una
PC Card, per esempio, probabilmente non dovreste preoccuparvi di pcmciautils.
====================== ================= ========================================
Programma Versione minima Comando per verificare la versione
====================== ================= ========================================
GNU C 8.1 gcc --version
Clang/LLVM (optional) 17.0.1 clang --version
Rust (opzionale) 1.78.0 rustc --version
bindgen (opzionale) 0.65.1 bindgen --version
GNU make 4.0 make --version
bash 4.2 bash --version
binutils 2.30 ld -v
flex 2.5.35 flex --version
bison 2.0 bison --version
pahole 1.16 pahole --version
util-linux 2.10o mount --version
kmod 13 depmod -V
e2fsprogs 1.41.4 e2fsck -V
jfsutils 1.1.3 fsck.jfs -V
xfsprogs 2.6.0 xfs_db -V
squashfs-tools 4.0 mksquashfs -version
btrfs-progs 0.18 btrfsck
pcmciautils 004 pccardctl -V
quota-tools 3.09 quota -V
PPP 2.4.0 pppd --version
nfs-utils 1.0.5 showmount --version
procps 3.2.0 ps --version
udev 081 udevd --version
grub 0.93 grub --version || grub-install --version
mcelog 0.6 mcelog --version
iptables 1.4.2 iptables -V
openssl & libcrypto 1.0.0 openssl version
bc 1.06.95 bc --version
Sphinx\ [#f1]_ 2.4.4 sphinx-build --version
cpio any cpio --version
GNU tar 1.28 tar --version
gtags (opzionale) 6.6.5 gtags --version
mkimage (opzionale) 2017.01 mkimage --version
Python (opzionale) 3.5.x python3 --version
====================== ================= ========================================
.. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel
Compilazione del kernel
***********************
GCC
---
La versione necessaria di gcc potrebbe variare a seconda del tipo di CPU nel
vostro calcolatore.
Clang/LLVM (opzionale)
----------------------
L'ultima versione di clang e *LLVM utils* (secondo `releases.llvm.org
<https://releases.llvm.org>`_) sono supportati per la generazione del
kernel. Non garantiamo che anche i rilasci più vecchi funzionino, inoltre
potremmo rimuovere gli espedienti che abbiamo implementato per farli
funzionare. Per maggiori informazioni
:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
Rust (opzionale)
----------------
È necessaria una versione recente del compilatore Rust.
Verificate le istruzioni Documentation/rust/quick-start.rst su come soddisfare i
requisiti per compilare code Rust. In particolare, la regola ``rustavailable``
nel ``Makefile`` è utile per verificare perché gli strumenti di compilazione non
vengono trovati.
bindgen (opzionale)
-------------------
``bindgen`` viene usato per generare il collegamento (binding) da Rust al lato C del kernel. Dipende da ``libclang``.
Make
----
Per compilare il kernel vi servirà GNU make 4.0 o successivo.
Bash
----
Per generare il kernel vengono usati alcuni script per bash.
Questo richiede bash 4.2 o successivo.
Binutils
--------
Per generare il kernel è necessario avere Binutils 2.30 o superiore.
pkg-config
----------
Il sistema di compilazione, dalla versione 4.18, richiede pkg-config per
verificare l'esistenza degli strumenti kconfig e per determinare le
impostazioni da usare in 'make {g,x}config'. Precedentemente pkg-config
veniva usato ma non verificato o documentato.
Flex
----
Dalla versione 4.16, il sistema di compilazione, durante l'esecuzione, genera
un analizzatore lessicale. Questo richiede flex 2.5.35 o successivo.
Bison
-----
Dalla versione 4.16, il sistema di compilazione, durante l'esecuzione, genera
un parsificatore. Questo richiede bison 2.0 o successivo.
pahole
------
Dalla versione 5.2, quando viene impostato CONFIG_DEBUG_INFO_BTF, il sistema di
compilazione genera BTF (BPF Type Format) a partire da DWARF per vmlinux. Più
tardi anche per i moduli. Questo richiede pahole v1.16 o successivo.
A seconda della distribuzione, lo si può trovare nei pacchetti 'dwarves' o
'pahole'. Oppure lo si può trovare qui: https://fedorapeople.org/~acme/dwarves/.
Perl
----
Per compilare il kernel vi servirà perl 5 e i seguenti moduli ``Getopt::Long``,
``Getopt::Std``, ``File::Basename``, e ``File::Find``.
BC
--
Vi servirà bc per compilare i kernel dal 3.10 in poi.
OpenSSL
-------
Il programma OpenSSL e la libreria crypto vengono usati per la firma dei moduli
e la gestione dei certificati; sono usati per la creazione della chiave e
la generazione della firma.
Se la firma dei moduli è abilitata, allora vi servirà openssl per compilare il
kernel 3.7 e successivi. Vi serviranno anche i pacchetti di sviluppo di
openssl per compilare il kernel 4.3 o successivi.
Tar
---
GNU Tar è necessario per accedere ai file d'intestazione del kernel usando sysfs
(CONFIG_IKHEADERS)
gtags / GNU GLOBAL (opzionale)
------------------------------
Il programma GNU GLOBAL versione 6.6.5, o successiva, è necessario quando si
vuole eseguire ``make gtags`` e generare i relativi indici. Internamente si fa
uso del parametro gtags ``-C (--directory)`` che compare in questa versione.
mkimage
-------
Questo strumento viene usato per produrre un *Flat Image Tree* (FIT),
tipicamente usato su sistemi ARM. Questo strumento è disponibile tramite il
pacchetto ``u-boot-tools`` oppure può essere compilato dal codice sorgente di
U-Boot. Consultate le istruzioni
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
Strumenti di sistema
********************
Modifiche architetturali
------------------------
DevFS è stato reso obsoleto da udev
(http://www.kernel.org/pub/linux/utils/kernel/hotplug/)
Il supporto per UID a 32-bit è ora disponibile. Divertitevi!
La documentazione delle funzioni in Linux è una fase di transizione
verso una documentazione integrata nei sorgenti stessi usando dei commenti
formattati in modo speciale e posizionati vicino alle funzioni che descrivono.
Al fine di arricchire la documentazione, questi commenti possono essere
combinati con i file ReST presenti in Documentation/; questi potranno
poi essere convertiti in formato PostScript, HTML, LaTex, ePUB o PDF.
Per convertire i documenti da ReST al formato che volete, avete bisogno di
Sphinx.
Util-linux
----------
Le versioni più recenti di util-linux: forniscono il supporto a ``fdisk`` per
dischi di grandi dimensioni; supportano le nuove opzioni di mount; riconoscono
più tipi di partizioni; hanno un fdformat che funziona con i kernel 2.4;
e altre chicche. Probabilmente vorrete aggiornarlo.
Ksymoops
--------
Se l'impensabile succede e il kernel va in oops, potrebbe servirvi lo strumento
ksymoops per decodificarlo, ma nella maggior parte dei casi non vi servirà.
Generalmente è preferibile compilare il kernel con l'opzione ``CONFIG_KALLSYMS``
cosicché venga prodotto un output più leggibile che può essere usato così com'è
(produce anche un output migliore di ksymoops). Se per qualche motivo il
vostro kernel non è stato compilato con ``CONFIG_KALLSYMS`` e non avete modo di
ricompilarlo e riprodurre l'oops con quell'opzione abilitata, allora potete
usare ksymoops per decodificare l'oops.
Mkinitrd
--------
I cambiamenti della struttura in ``/lib/modules`` necessita l'aggiornamento di
mkinitrd.
E2fsprogs
---------
L'ultima versione di ``e2fsprogs`` corregge diversi bachi in fsck e debugfs.
Ovviamente, aggiornarlo è una buona idea.
JFSutils
--------
Il pacchetto ``jfsutils`` contiene programmi per il file-system JFS.
Sono disponibili i seguenti strumenti:
- ``fsck.jfs`` - avvia la ripetizione del log delle transizioni, e verifica e
ripara una partizione formattata secondo JFS
- ``mkfs.jfs`` - crea una partizione formattata secondo JFS
- sono disponibili altri strumenti per il file-system.
Xfsprogs
--------
L'ultima versione di ``xfsprogs`` contiene, fra i tanti, i programmi
``mkfs.xfs``, ``xfs_db`` e ``xfs_repair`` per il file-system XFS.
Dipendono dell'architettura e qualsiasi versione dalla 2.0.0 in poi
dovrebbe funzionare correttamente con la versione corrente del codice
XFS nel kernel (sono raccomandate le versioni 2.6.0 o successive per via
di importanti miglioramenti).
PCMCIAutils
-----------
PCMCIAutils sostituisce ``pcmica-cs``. Serve ad impostare correttamente i
connettori PCMCIA all'avvio del sistema e a caricare i moduli necessari per
i dispositivi a 16-bit se il kernel è stato modularizzato e il sottosistema
hotplug è in uso.
Quota-tools
-----------
Il supporto per uid e gid a 32 bit richiedono l'uso della versione 2 del
formato quota. La versione 3.07 e successive di quota-tools supportano
questo formato. Usate la versione raccomandata nella lista qui sopra o una
successiva.
Micro codice per Intel IA32
---------------------------
Per poter aggiornare il micro codice per Intel IA32, è stato aggiunto un
apposito driver; il driver è accessibile come un normale dispositivo a
caratteri (misc). Se non state usando udev probabilmente sarà necessario
eseguire i seguenti comandi come root prima di poterlo aggiornare::
mkdir /dev/cpu
mknod /dev/cpu/microcode c 10 184
chmod 0644 /dev/cpu/microcode
Probabilmente, vorrete anche il programma microcode_ctl da usare con questo
dispositivo.
udev
----
``udev`` è un programma in spazio utente il cui scopo è quello di popolare
dinamicamente la cartella ``/dev`` coi dispositivi effettivamente presenti.
``udev`` sostituisce le funzionalità base di devfs, consentendo comunque
nomi persistenti per i dispositivi.
FUSE
----
Serve libfuse 2.4.0 o successiva. Il requisito minimo assoluto è 2.3.0 ma
le opzioni di mount ``direct_io`` e ``kernel_cache`` non funzioneranno.
Rete
****
Cambiamenti generali
--------------------
Se per quanto riguarda la configurazione di rete avete esigenze di un certo
livello dovreste prendere in considerazione l'uso degli strumenti in ip-route2.
Filtro dei pacchetti / NAT
--------------------------
Il codice per filtraggio dei pacchetti e il NAT fanno uso degli stessi
strumenti come nelle versioni del kernel antecedenti la 2.4.x (iptables).
Include ancora moduli di compatibilità per 2.2.x ipchains e 2.0.x ipdwadm.
PPP
---
Il driver per PPP è stato ristrutturato per supportare collegamenti multipli e
per funzionare su diversi livelli. Se usate PPP, aggiornate pppd almeno alla
versione 2.4.0.
Se non usate udev, dovete avere un file /dev/ppp che può essere creato da root
col seguente comando::
mknod /dev/ppp c 108 0
NFS-utils
---------
Nei kernel più antichi (2.4 e precedenti), il server NFS doveva essere
informato sui clienti ai quali si voleva fornire accesso via NFS. Questa
informazione veniva passata al kernel quando un cliente montava un file-system
mediante ``mountd``, oppure usando ``exportfs`` all'avvio del sistema.
exportfs prende le informazioni circa i clienti attivi da ``/var/lib/nfs/rmtab``.
Questo approccio è piuttosto delicato perché dipende dalla correttezza di
rmtab, che non è facile da garantire, in particolare quando si cerca di
implementare un *failover*. Anche quando il sistema funziona bene, ``rmtab``
ha il problema di accumulare vecchie voci inutilizzate.
Sui kernel più recenti il kernel ha la possibilità di informare mountd quando
arriva una richiesta da una macchina sconosciuta, e mountd può dare al kernel
le informazioni corrette per l'esportazione. Questo rimuove la dipendenza con
``rmtab`` e significa che il kernel deve essere al corrente solo dei clienti
attivi.
Per attivare questa funzionalità, dovete eseguire il seguente comando prima di
usare exportfs o mountd::
mount -t nfsd nfsd /proc/fs/nfsd
Dove possibile, raccomandiamo di proteggere tutti i servizi NFS dall'accesso
via internet mediante un firewall.
mcelog
------
Quando ``CONFIG_x86_MCE`` è attivo, il programma mcelog processa e registra
gli eventi *machine check*. Gli eventi *machine check* sono errori riportati
dalla CPU. Incoraggiamo l'analisi di questi errori.
Documentazione del kernel
*************************
Sphinx
------
Per i dettaglio sui requisiti di Sphinx, fate riferimento a :ref:`it_sphinx_install`
in :ref:`Documentation/translations/it_IT/doc-guide/sphinx.rst <it_sphinxdoc>`
Ottenere software aggiornato
============================
Compilazione del kernel
***********************
gcc
---
- <ftp://ftp.gnu.org/gnu/gcc/>
Clang/LLVM
----------
- :ref:`Getting LLVM <getting_llvm>`.
Make
----
- <ftp://ftp.gnu.org/gnu/make/>
Bash
----
- <ftp://ftp.gnu.org/gnu/bash/>
Binutils
--------
- <https://www.kernel.org/pub/linux/devel/binutils/>
Flex
----
- <https://github.com/westes/flex/releases>
Bison
-----
- <ftp://ftp.gnu.org/gnu/bison/>
OpenSSL
-------
- <https://www.openssl.org/>
Strumenti di sistema
********************
Util-linux
----------
- <https://www.kernel.org/pub/linux/utils/util-linux/>
Kmod
----
- <https://www.kernel.org/pub/linux/utils/kernel/kmod/>
- <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
Ksymoops
--------
- <https://www.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
Mkinitrd
--------
- <https://code.launchpad.net/initrd-tools/main>
E2fsprogs
---------
- <https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/>
- <https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/>
JFSutils
--------
- <https://jfs.sourceforge.net/>
Xfsprogs
--------
- <https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git>
- <https://www.kernel.org/pub/linux/utils/fs/xfs/xfsprogs/>
Pcmciautils
-----------
- <https://www.kernel.org/pub/linux/utils/kernel/pcmcia/>
Quota-tools
-----------
- <https://sourceforge.net/projects/linuxquota/>
Microcodice Intel P6
--------------------
- <https://downloadcenter.intel.com/>
udev
----
- <http://www.freedesktop.org/software/systemd/man/udev.html>
FUSE
----
- <https://github.com/libfuse/libfuse/releases>
mcelog
------
- <https://www.mcelog.org/>
cpio
----
- <https://www.gnu.org/software/cpio/>
Rete
****
PPP
---
- <https://download.samba.org/pub/ppp/>
- <https://git.ozlabs.org/?p=ppp.git>
- <https://github.com/paulusmack/ppp/>
NFS-utils
---------
- <https://sourceforge.net/project/showfiles.php?group_id=14>
- <https://nfs.sourceforge.net/>
Iptables
--------
- <https://netfilter.org/projects/iptables/index.html>
Ip-route2
---------
- <https://www.kernel.org/pub/linux/utils/net/iproute2/>
OProfile
--------
- <https://oprofile.sf.net/download/>
Documentazione del kernel
*************************
Sphinx
------
- <http://www.sphinx-doc.org/>
@@ -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
@@ -0,0 +1,409 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_deprecated:
==============================================================================
Interfacce deprecate, caratteristiche del linguaggio, attributi, e convenzioni
==============================================================================
In un mondo perfetto, sarebbe possibile prendere tutti gli usi di
un'interfaccia deprecata e convertirli in quella nuova, e così sarebbe
possibile rimuovere la vecchia interfaccia in un singolo ciclo di sviluppo.
Tuttavia, per via delle dimensioni del kernel, la gerarchia dei manutentori e
le tempistiche, non è sempre possibile fare questo tipo di conversione tutta
in una volta. Questo significa che nuove istanze di una vecchia interfaccia
potrebbero aggiungersi al kernel proprio quando si sta cercando di rimuoverle,
aumentando così il carico di lavoro. Al fine di istruire gli sviluppatori su
cosa è considerato deprecato (e perché), è stata create la seguente lista a cui
fare riferimento quando qualcuno propone modifiche che usano cose deprecate.
__deprecated
------------
Nonostante questo attributo marchi visibilmente un interfaccia come deprecata,
`non produce più alcun avviso durante la compilazione
<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
perché uno degli obiettivi del kernel è quello di compilare senza avvisi;
inoltre, nessuno stava agendo per rimuovere queste interfacce. Nonostante l'uso
di `__deprecated` in un file d'intestazione sia opportuno per segnare una
interfaccia come 'vecchia', questa non è una soluzione completa. L'interfaccia
deve essere rimossa dal kernel, o aggiunta a questo documento per scoraggiarne
l'uso.
BUG() e BUG_ON()
----------------
Al loro posto usate WARN() e WARN_ON() per gestire le
condizioni "impossibili" e gestitele come se fosse possibile farlo.
Nonostante le funzioni della famiglia BUG() siano state progettate
per asserire "situazioni impossibili" e interrompere in sicurezza un
thread del kernel, queste si sono rivelate essere troppo rischiose
(per esempio, in quale ordine rilasciare i *lock*? Ci sono stati che
sono stati ripristinati?). Molto spesso l'uso di BUG()
destabilizza il sistema o lo corrompe del tutto, il che rende
impossibile un'attività di debug o anche solo leggere un rapporto
circa l'errore. Linus ha un'opinione molto critica al riguardo:
`email 1
<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_,
`email 2
<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_
Tenete presente che la famiglia di funzioni WARN() dovrebbe essere
usato solo per situazioni che si suppone siano "impossibili". Se
volete avvisare gli utenti riguardo a qualcosa di possibile anche se
indesiderato, usare le funzioni della famiglia pr_warn(). Chi
amministra il sistema potrebbe aver attivato l'opzione sysctl
*panic_on_warn* per essere sicuri che il sistema smetta di funzionare
in caso si verifichino delle condizioni "inaspettate". (per esempio,
date un'occhiata al questo `commit
<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_)
Calcoli codificati negli argomenti di un allocatore
----------------------------------------------------
Il calcolo dinamico delle dimensioni (specialmente le moltiplicazioni) non
dovrebbero essere fatto negli argomenti di funzioni di allocazione di memoria
(o simili) per via del rischio di overflow. Questo può portare a valori più
piccoli di quelli che il chiamante si aspettava. L'uso di questo modo di
allocare può portare ad un overflow della memoria di heap e altri
malfunzionamenti. (Si fa eccezione per valori numerici per i quali il
compilatore può generare avvisi circa un potenziale overflow. Tuttavia, anche in
questi casi è preferibile riscrivere il codice come suggerito di seguito).
Per esempio, non usate ``count * size`` come argomento::
foo = kmalloc(count * size, GFP_KERNEL);
Al suo posto, si dovrebbe usare l'allocatore a due argomenti::
foo = kmalloc_array(count, size, GFP_KERNEL);
Nello specifico, kmalloc() può essere sostituta da kmalloc_array(), e kzalloc()
da kcalloc().
Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
le funzioni del tipo *saturate-on-overflow*::
bar = dma_alloc_coherent(dev, array_size(count, size), &dma, GFP_KERNEL);
Un altro tipico caso da evitare è quello di calcolare la dimensione di una
struttura seguita da un vettore di altre strutture, come nel seguente caso::
header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
GFP_KERNEL);
Invece, usate la seguente funzione::
header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
.. note:: Se per caso state usando struct_size() su una struttura dati che
in coda contiene un array di lunghezza zero o uno, allora siete
invitati a riorganizzare il vostro codice usando il
`flexible array member <#zero-length-and-one-element-arrays>`_.
Per altri calcoli, usate le funzioni size_mul(), size_add(), e size_sub(). Per
esempio, al posto di::
foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
dovreste scrivere:
foo = krealloc(size_add(current_size,
size_mul(chunk_size,
size_sub(count, 3))), GFP_KERNEL);
Per maggiori dettagli fate riferimento a array3_size() e flex_array_size(), ma
anche le funzioni della famiglia check_mul_overflow(), check_add_overflow(),
check_sub_overflow(), e check_shl_overflow().
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
Le funzioni simple_strtol(), simple_strtoll(),
simple_strtoul(), e simple_strtoull() ignorano volutamente
i possibili overflow, e questo può portare il chiamante a generare risultati
inaspettati. Le rispettive funzioni kstrtol(), kstrtoll(),
kstrtoul(), e kstrtoull() sono da considerarsi le corrette
sostitute; tuttavia va notato che queste richiedono che la stringa sia
terminata con il carattere NUL o quello di nuova riga.
strcpy()
--------
La funzione strcpy() non fa controlli agli estremi del buffer
di destinazione. Questo può portare ad un overflow oltre i limiti del
buffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione
`CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano
a ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare
questa funzione. La versione sicura da usare è strscpy(), tuttavia va
prestata attenzione a tutti quei casi dove viene usato il valore di
ritorno di strcpy(). La funzione strscpy() non ritorna un puntatore
alla destinazione, ma un contatore dei byte non NUL copiati (oppure
un errno negativo se la stringa è stata troncata).
strncpy() su stringe terminate con NUL
--------------------------------------
L'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che
il buffer di destinazione verrà terminato con il carattere NUL. Questo
potrebbe portare a diversi overflow di lettura o altri malfunzionamenti
causati, appunto, dalla mancanza del terminatore. Questa estende la
terminazione nel buffer di destinazione quando la stringa d'origine è più
corta; questo potrebbe portare ad una penalizzazione delle prestazioni per
chi usa solo stringe terminate. La versione sicura da usare è
strscpy(), tuttavia va prestata attenzione a tutti quei casi dove
viene usato il valore di ritorno di strncpy(). La funzione strscpy()
non ritorna un puntatore alla destinazione, ma un contatore dei byte
non NUL copiati (oppure un errno negativo se la stringa è stata
troncata). Tutti i casi che necessitano di estendere la
terminazione con NUL dovrebbero usare strscpy_pad().
Se il chiamate no usa stringhe terminate con NUL, allore strncpy()
può continuare ad essere usata, ma i buffer di destinazione devono essere
marchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
per evitare avvisi durante la compilazione.
strlcpy()
---------
La funzione strlcpy(), per prima cosa, legge interamente il buffer di
origine, magari leggendo più di quanto verrà effettivamente copiato. Questo
è inefficiente e può portare a overflow di lettura quando la stringa non è
terminata con NUL. La versione sicura da usare è strscpy(), tuttavia
va prestata attenzione a tutti quei casi dove viene usato il valore di
ritorno di strlcpy(), dato che strscpy() ritorna un valore di errno
negativo quanto la stringa viene troncata.
Segnaposto %p nella stringa di formato
--------------------------------------
Tradizionalmente, l'uso del segnaposto "%p" nella stringa di formato
esponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera. Per
evitare che questi indirizzi vengano sfruttati da malintenzionati,
tutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo,
rendendolo di fatto inutilizzabile. Nuovi usi di "%p" non dovrebbero
essere aggiunti al kernel. Per una rappresentazione testuale di un
indirizzo usate "%pS", l'output è migliore perché mostrerà il nome del
simbolo. Per tutto il resto, semplicemente non usate "%p".
Parafrasando la `guida
<https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_
di Linus:
- Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso
è importante. Forse dovrebbe essere rimosso del tutto?
- Se credi davvero che il vero valore del puntatore sia importante,
perché alcuni stati del sistema o i livelli di privilegi di un
utente sono considerati "special"? Se pensi di poterlo giustificare
(in un commento e nel messaggio del commit) abbastanza bene da
affrontare il giudizio di Linus, allora forse potrai usare "%px",
assicurandosi anche di averne il permesso.
Potete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa
funzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo
aggiungete l'opzione di debug "`no_hash_pointers
<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_" alla
riga di comando del kernel.
Vettori a dimensione variabile (VLA)
------------------------------------
Usare VLA sullo stack produce codice molto peggiore rispetto a quando si usano
vettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_,
tutt'altro che banali, sono già un motivo valido per eliminare i VLA; in
aggiunta sono anche un problema per la sicurezza. La crescita dinamica di un
vettore nello stack potrebbe eccedere la memoria rimanente in tale segmento.
Questo può portare a dei malfunzionamenti, potrebbe sovrascrivere
dati importanti alla fine dello stack (quando il kernel è compilato senza
`CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente
allo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`).
Salto implicito nell'istruzione switch-case
-------------------------------------------
Il linguaggio C permette ai casi di un'istruzione `switch` di saltare al
prossimo caso quando l'istruzione "break" viene omessa alla fine del caso
corrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se
l'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio,
osservando il seguente pezzo di codice non è chiaro se lo stato
`STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`::
switch (value) {
case STATE_ONE:
do_something();
case STATE_TWO:
do_other();
break;
default:
WARN("unknown state");
}
Dato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione
"break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non
permettiamo più che vi sia un "salto implicito" (*fall-through*). Per
identificare un salto implicito intenzionale abbiamo adottato la pseudo
parola chiave 'fallthrough' che viene espansa nell'estensione di gcc
`__attribute__((fallthrough))` `Statement Attributes
<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
(Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente
supportata dai compilatori C, analizzatori statici, e dagli IDE,
allora potremo usare quella sintassi per la pseudo parola chiave)
Quando la sintassi [[fallthrough]] sarà più comunemente supportata dai
compilatori, analizzatori statici, e ambienti di sviluppo IDE,
allora potremo usarla anche noi.
Ne consegue che tutti i blocchi switch/case devono finire in uno dei seguenti
modi:
* ``break;``
* `fallthrough;``
* ``continue;``
* ``goto <label>;``
* ``return [expression];``
Array di lunghezza zero o con un solo elemento
----------------------------------------------
All'interno del kernel ricorre spesso la necessita di avere membri
di dimensione variabile all'interno di una struttura dati. In questi
casi il codice del kernel dovrebbe usare sempre i `"flexible array
member" <https://en.wikipedia.org/wiki/Flexible_array_member>`_. La
tecnica degli array a lunghezza nulla o di un solo elemento non
dovrebbe essere più usata.
Nel codice C più vecchio, la dichiarazione di un membro di dimensione
variabile in coda ad una struttura dati veniva fatto dichiarando un
array di un solo elemento posizionato alla fine della struttura dati::
struct something {
size_t count;
struct foo items[1];
};
Questo ha portato ad un calcolo di sizeof() traballante (dovrebbe
rimuovere la dimensione del singolo elemento in coda per calcolare la
dimensione esatta dell' "intestazione"). Per evitare questi problemi è
stata introdotta un' `estensione a GNU C
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ che
permettesse la dichiarazione di array a lungezza zero::
struct something {
size_t count;
struct foo items[0];
};
Ma questo ha portato nuovi problemi, e non ha risolto alcuni dei
problemi che affliggono entrambe le tecniche: per esempio
l'impossibilità di riconoscere se un array di quel tipo viene usato
nel mezzo di una struttura dati e _non_ alla fine (potrebbe accadere
sia direttamente, sia indirettamente quando si usano le unioni o le
strutture di strutture).
Lo standard C99 introduce i "flexible array members". Questi array non
hanno una dimensione nella loro dichiarazione::
struct something {
size_t count;
struct foo items[];
};
Questo è il modo con cui ci si aspetta che vengano dichiarati gli
elementi di lunghezza variabile in coda alle strutture dati. Permette
al compilatore di produrre errori quando gli array flessibili non si
trovano alla fine della struttura dati, il che permette di prevenire
alcuni tipi di bachi dovuti a `comportamenti inaspettati
<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
Inoltre, permette al compilatore di analizzare correttamente le
dimensioni degli array (attraverso sizeof(), `CONFIG_FORTIFY_SOURCE`,
e `CONFIG_UBSAN_BOUNDS`). Per esempio, non esiste alcun meccanismo in
grado di avvisarci che il seguente uso di sizeof() dia sempre come
zero come risultato::
struct something {
size_t count;
struct foo items[0];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
instance->count = count;
size = sizeof(instance->items) * instance->count;
memcpy(instance->items, source, size);
Il valore di ``size`` nell'ultima riga sarà ``zero``, quando uno
invece si aspetterebbe che il suo valore sia la dimensione totale in
byte dell'allocazione dinamica che abbiamo appena fatto per l'array
``items``. Qui un paio di esempi reali del problema: `collegamento 1
<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
`collegamento 2
<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
Invece, `i flexible array members hanno un tipo incompleto, e quindi
sizeof() non può essere applicato
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_; dunque ogni
uso scorretto di questo operatore verrà identificato immediatamente
durante la compilazione.
Per quanto riguarda gli array di un solo elemento, bisogna essere
consapevoli che `questi array occupano almeno quanto lo spazio di un
singolo oggetti dello stesso tipo
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, e quindi
contribuiscono al calcolo della dimensione della struttura che li
contiene. In questo caso è facile commettere errori quando si vuole
calcolare la dimensione totale della memoria totale da allocare per
una struttura dati::
struct something {
size_t count;
struct foo items[1];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
instance->count = count;
size = sizeof(instance->items) * instance->count;
memcpy(instance->items, source, size);
In questo esempio ci siamo dovuti ricordare di usare ``count - 1`` in
struct_size(), altrimenti avremmo --inavvertitamente-- allocato
memoria per un oggetti ``items`` in più. Il modo più pulito e meno
propenso agli errori è quello di usare i `flexible array member`, in
combinazione con struct_size() e flex_array_size()::
struct something {
size_t count;
struct foo items[];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
instance->count = count;
memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
Ci sono due casi speciali dove è necessario usare la macro DECLARE_FLEX_ARRAY()
(da notare che la stessa macro è chiamata __DECLARE_FLEX_ARRAY() nei file di
intestazione UAPI). Uno è quando l'array flessibile è l'unico elemento di una
struttura, e l'altro quando è parte di un unione. Per motivi non tecnici, entrambi
i casi d'uso non sono permessi dalla specifica C99. Per esempio, per
convertire il seguente codice::
struct something {
...
union {
struct type1 one[0];
struct type2 two[0];
};
};
La macro di supporto dev'essere usata::
struct something {
...
union {
DECLARE_FLEX_ARRAY(struct type1, one);
DECLARE_FLEX_ARRAY(struct type2, two);
};
};
@@ -0,0 +1,32 @@
.. 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
============================================
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.
.. toctree::
:caption: Contenuti
:numbered:
:maxdepth: 2
1.Intro
2.Process
3.Early-stage
4.Coding
5.Posting
6.Followthrough
7.AdvancedTopics
8.Conclusion
@@ -0,0 +1,376 @@
.. include:: ../disclaimer-ita.rst
:Original: :doc:`../../../process/email-clients`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_email_clients:
Informazioni sui programmi di posta elettronica per Linux
=========================================================
Git
---
Oggigiorno, la maggior parte degli sviluppatori utilizza ``git send-email``
al posto dei classici programmi di posta elettronica. Le pagine man sono
abbastanza buone. Dal lato del ricevente, i manutentori utilizzano ``git am``
per applicare le patch.
Se siete dei novelli utilizzatori di ``git`` allora inviate la patch a voi
stessi. Salvatela come testo includendo tutte le intestazioni. Poi eseguite
il comando ``git am messaggio-formato-testo.txt`` e revisionatene il risultato
con ``git log``. Quando tutto funziona correttamente, allora potete inviare
la patch alla lista di discussione più appropriata.
Panoramica delle opzioni
------------------------
Le patch per il kernel vengono inviate per posta elettronica, preferibilmente
come testo integrante del messaggio. Alcuni manutentori accettano gli
allegati, ma in questo caso gli allegati devono avere il *content-type*
impostato come ``text/plain``. Tuttavia, generalmente gli allegati non sono
ben apprezzati perché rende più difficile citare porzioni di patch durante il
processo di revisione.
Inoltre, è vivamente raccomandato l'uso di puro testo nel corpo del
messaggio, sia per la patch che per qualsiasi altro messaggio. Il sito
https://useplaintext.email/ può esservi d'aiuto per configurare il
vostro programma di posta elettronica.
I programmi di posta elettronica che vengono usati per inviare le patch per il
kernel Linux dovrebbero inviarle senza alterazioni. Per esempio, non
dovrebbero modificare o rimuovere tabulazioni o spazi, nemmeno all'inizio o
alla fine delle righe.
Non inviate patch con ``format=flowed``. Questo potrebbe introdurre
interruzioni di riga inaspettate e indesiderate.
Non lasciate che il vostro programma di posta vada a capo automaticamente.
Questo può corrompere le patch.
I programmi di posta non dovrebbero modificare la codifica dei caratteri nel
testo. Le patch inviate per posta elettronica dovrebbero essere codificate in
ASCII o UTF-8.
Se configurate il vostro programma per inviare messaggi codificati con UTF-8
eviterete possibili problemi di codifica.
I programmi di posta dovrebbero generare e mantenere le intestazioni
"References" o "In-Reply-To:" cosicché la discussione non venga interrotta.
Di solito, il copia-e-incolla (o taglia-e-incolla) non funziona con le patch
perché le tabulazioni vengono convertite in spazi. Usando xclipboard, xclip
e/o xcutsel potrebbe funzionare, ma è meglio che lo verifichiate o meglio
ancora: non usate il copia-e-incolla.
Non usate firme PGP/GPG nei messaggi che contengono delle patch. Questo
impedisce il corretto funzionamento di alcuni script per leggere o applicare
patch (questo si dovrebbe poter correggere).
Prima di inviare le patch sulle liste di discussione Linux, può essere una
buona idea quella di inviare la patch a voi stessi, salvare il messaggio
ricevuto, e applicarlo ai sorgenti con successo.
Alcuni suggerimenti per i programmi di posta elettronica (MUA)
--------------------------------------------------------------
Qui troverete alcuni suggerimenti per configurare i vostri MUA allo scopo
di modificare ed inviare patch per il kernel Linux. Tuttavia, questi
suggerimenti non sono da considerarsi come un riassunto di una configurazione
completa.
Legenda:
- TUI = interfaccia utente testuale (*text-based user interface*)
- GUI = interfaccia utente grafica (*graphical user interface*)
Alpine (TUI)
************
Opzioni per la configurazione:
Nella sezione :menuselection:`Sending Preferences`:
- :menuselection:`Do Not Send Flowed Text` deve essere ``enabled``
- :menuselection:`Strip Whitespace Before Sending` deve essere ``disabled``
Quando state scrivendo un messaggio, il cursore dev'essere posizionato
dove volete che la patch inizi, poi premendo `CTRL-R` vi verrà chiesto
di selezionare il file patch da inserire nel messaggio.
Claws Mail (GUI)
****************
Funziona. Alcune persone riescono ad usarlo con successo per inviare le patch.
Per inserire una patch usate :menuselection:`Messaggio-->Inserisci file`
(`CTRL-I`) oppure un editor esterno.
Se la patch che avete inserito dev'essere modificata usando la finestra di
scrittura di Claws, allora assicuratevi che l'"auto-interruzione" sia
disabilitata :menuselection:`Configurazione-->Preferenze-->Composizione-->Interruzione riga`.
Evolution (GUI)
***************
Alcune persone riescono ad usarlo con successo per inviare le patch.
Quando state scrivendo una lettera selezionate: Preformattato
da :menuselection:`Formato-->Stile del paragrafo-->Preformattato`
(`CTRL-7`) o dalla barra degli strumenti
Poi per inserire la patch usate:
:menuselection:`Inserisci--> File di testo...` (`ALT-N x`)
Potete anche eseguire ``diff -Nru old.c new.c | xclip``, selezionare
:menuselection:`Preformattato`, e poi usare il tasto centrale del mouse.
Kmail (GUI)
***********
Alcune persone riescono ad usarlo con successo per inviare le patch.
La configurazione base che disabilita la composizione di messaggi HTML è
corretta; non abilitatela.
Quando state scrivendo un messaggio, nel menu opzioni, togliete la selezione a
"A capo automatico". L'unico svantaggio sarà che qualsiasi altra cosa scriviate
nel messaggio non verrà mandata a capo in automatico ma dovrete farlo voi.
Il modo più semplice per ovviare a questo problema è quello di scrivere il
messaggio con l'opzione abilitata e poi di salvarlo nelle bozze. Riaprendo ora
il messaggio dalle bozze le andate a capo saranno parte integrante del
messaggio, per cui togliendo l'opzione "A capo automatico" non perderete nulla.
Alla fine del vostro messaggio, appena prima di inserire la vostra patch,
aggiungete il delimitatore di patch: tre trattini (``---``).
Ora, dal menu :menuselection:`Messaggio`, selezionate :menuselection:`Inserisci file di testo...`
quindi scegliete la vostra patch.
Come soluzione aggiuntiva potreste personalizzare la vostra barra degli
strumenti aggiungendo un'icona per :menuselection:`Inserisci file di testo...`.
Allargate la finestra di scrittura abbastanza da evitare andate a capo.
Questo perché in Kmail 1.13.5 (KDE 4.5.4), Kmail aggiunge andate a capo
automaticamente al momento dell'invio per tutte quelle righe che graficamente,
nella vostra finestra di composizione, si sono estete su una riga successiva.
Disabilitare l'andata a capo automatica non è sufficiente. Dunque, se la vostra
patch contiene delle righe molto lunghe, allora dovrete allargare la finestra
di composizione per evitare che quelle righe vadano a capo. Vedere:
https://bugs.kde.org/show_bug.cgi?id=174034
Potete firmare gli allegati con GPG, ma per le patch si preferisce aggiungerle
al testo del messaggio per cui non usate la firma GPG. Firmare le patch
inserite come testo del messaggio le rende più difficili da estrarre dalla loro
codifica a 7-bit.
Se dovete assolutamente inviare delle patch come allegati invece di integrarle
nel testo del messaggio, allora premete il tasto destro sull'allegato e
selezionate :menuselection:`Proprietà`, e poi attivate
:menuselection:`Suggerisci visualizzazione automatica` per far si che
l'allegato sia più leggibile venendo visualizzato come parte del messaggio.
Per salvare le patch inviate come parte di un messaggio, selezionate il
messaggio che la contiene, premete il tasto destro e selezionate
:menuselection:`Salva come`. Se il messaggio fu ben preparato, allora potrete
usarlo interamente senza alcuna modifica.
I messaggi vengono salvati con permessi di lettura-scrittura solo per l'utente,
nel caso in cui vogliate copiarli altrove per renderli disponibili ad altri
gruppi o al mondo, ricordatevi di usare ``chmod`` per cambiare i permessi.
Lotus Notes (GUI)
*****************
Scappate finché potete.
IBM Verse (Web GUI)
*******************
Vedi il commento per Lotus Notes.
Mutt (TUI)
**********
Un sacco di sviluppatori Linux usano ``mutt``, per cui deve funzionare
abbastanza bene.
Mutt non ha un proprio editor, quindi qualunque sia il vostro editor dovrete
configurarlo per non aggiungere automaticamente le andate a capo. Molti
editor hanno un'opzione :menuselection:`Inserisci file` che inserisce il
contenuto di un file senza alterarlo.
Per usare ``vim`` come editor per mutt::
set editor="vi"
Se per inserire la patch nel messaggio usate xclip, scrivete il comando::
:set paste
prima di premere il tasto centrale o shift-insert. Oppure usate il
comando::
:r filename
(a)llega funziona bene senza ``set paste``
Potete generare le patch con ``git format-patch`` e usare Mutt per inviarle::
$ mutt -H 0001-some-bug-fix.patch
Opzioni per la configurazione:
Tutto dovrebbe funzionare già nella configurazione base.
Tuttavia, è una buona idea quella di impostare ``send_charset``::
set send_charset="us-ascii:utf-8"
Mutt è molto personalizzabile. Qui di seguito trovate la configurazione minima
per iniziare ad usare Mutt per inviare patch usando Gmail::
# .muttrc
# ================ IMAP ====================
set imap_user = 'yourusername@gmail.com'
set imap_pass = 'yourpassword'
set spoolfile = imaps://imap.gmail.com/INBOX
set folder = imaps://imap.gmail.com/
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
# ================ SMTP ====================
set smtp_url = "smtp://username@smtp.gmail.com:587/"
set smtp_pass = $imap_pass
set ssl_force_tls = yes # Require encrypted connection
# ================ Composition ====================
set editor = `echo \$EDITOR`
set edit_headers = yes # See the headers when editing
set charset = UTF-8 # value of $LANG; also fallback for send_charset
# Sender, email address, and sign-off line must match
unset use_domain # because joe@localhost is just embarrassing
set realname = "YOUR NAME"
set from = "username@gmail.com"
set use_from = yes
La documentazione di Mutt contiene molte più informazioni:
https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail
http://www.mutt.org/doc/manual/
Pine (TUI)
**********
Pine aveva alcuni problemi con gli spazi vuoti, ma questi dovrebbero essere
stati risolti.
Se potete usate alpine (il successore di pine).
Opzioni di configurazione:
- Nelle versioni più recenti è necessario avere ``quell-flowed-text``
- l'opzione ``no-strip-whitespace-before-send`` è necessaria
Sylpheed (GUI)
**************
- funziona bene per aggiungere testo in linea (o usando allegati)
- permette di utilizzare editor esterni
- è lento su cartelle grandi
- non farà l'autenticazione TSL SMTP su una connessione non SSL
- ha un utile righello nella finestra di scrittura
- la rubrica non comprende correttamente il nome da visualizzare e
l'indirizzo associato
Thunderbird (GUI)
*****************
Thunderbird è un clone di Outlook a cui piace maciullare il testo, ma esistono
modi per impedirglielo.
Dopo la configurazione, inclusa l'installazione delle estenzioni, dovrete
riavviare Thunderbird.
- permettere l'uso di editor esterni:
La cosa più semplice da fare con Thunderbird e le patch è quello di usare
estensioni che permettano di aprire il vostro editor preferito.
Di seguito alcune estensioni che possono essere utili al caso.
- "External Editor Revived"
https://github.com/Frederick888/external-editor-revived
https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/
L'estensione richiede l'installazione di "native messaging host". Date
un'occhiata alla seguente wiki:
https://github.com/Frederick888/external-editor-revived/wiki
- "External Editor"
https://github.com/exteditor/exteditor
Per usarlo, scaricate ed installate l'applicazione. Poi aprite la finestra
:menuselection:`Scrivi` e a seguire aggiungete un bottone per eseguirlo
`Visualizza-->Barra degli strumenti-->Personalizza...`. Infine, premente
questo nuovo bottone tutte le volte che volete usare l'editor esterno.
Tenete presente che "external editor" richiede che il vostro editor non
faccia alcun fork, in altre parole, l'editor non deve ritornare prima di
essere stato chiuso. Potreste dover passare dei parametri aggiuntivi al
vostro editor oppure cambiargli la configurazione. Per esempio, usando
gvim dovrete aggiungere l'opzione -f ``/usr/bin/gvim -f`` (Se il binario
si trova in ``/usr/bin``) nell'apposito campo nell'interfaccia di
configurazione di :menuselection:`external editor`. Se usate altri editor
consultate il loro manuale per sapere come configurarli.``)``
Per rendere l'editor interno un po' più sensato, fate così:
- Modificate le impostazioni di Thunderbird per far si che non usi ``format=flowed``!
Andate sulla finestra principale e cercate il bottone per il menu a tendina principale.
Poi :menuselection:`Modifica-->Preferenze-->Avanzate-->Editor di configurazione`
per invocare il registro delle impostazioni.
- impostate ``mailnews.send_plaintext_flowed`` a ``false``
- impostate ``mailnews.wraplength`` da ``72`` a ``0``
- Non scrivete messaggi HTML! Andate sulla finestra principale ed aprite la
schermata :menuselection:`Menu principale-->Impostazioni account-->nome@unserver.ovunque-->Composizioni e indirizzi`.
Qui potrete disabilitare l'opzione "Componi i messaggi in HTML"
- Aprite i messaggi solo in formato testo! Andate sulla finestra principale e
selezionate
:menuselection:`Menu principale-->Visualizza-->Copro del messaggio come-->Testo semplice`
TkRat (GUI)
***********
Funziona. Usare "Inserisci file..." o un editor esterno.
Gmail (Web GUI)
***************
Non funziona per inviare le patch.
Il programma web Gmail converte automaticamente i tab in spazi.
Allo stesso tempo aggiunge andata a capo ogni 78 caratteri. Comunque
il problema della conversione fra spazi e tab può essere risolto usando
un editor esterno.
Un altro problema è che Gmail usa la codifica base64 per tutti quei messaggi
che contengono caratteri non ASCII. Questo include cose tipo i nomi europei.
HacKerMaiL (TUI)
****************
HacKerMaiL (hkml) è una semplice casella pubblica per la gestione dei messaggi
di posta che non richiede alcuna sottoscrizione ad una lista di discussione.
Viene sviluppato e mantenuto dal manutentore di DAMON e si pone come obiettivo
quello di gestire il processo di sviluppo semplice come quello di DAMON e più in
generale i sottosistemi del kernel. Per maggiori dettagli, fate riferimento al
documento README (https://github.com/sjp38/hackermail/blob/master/README.md).
@@ -0,0 +1,642 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/howto.rst <process_howto>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_process_howto:
Come partecipare allo sviluppo del kernel Linux
===============================================
Questo è il documento fulcro di quanto trattato sull'argomento.
Esso contiene le istruzioni su come diventare uno sviluppatore
del kernel Linux e spiega come lavorare con la comunità di
sviluppo kernel Linux. Il documento non tratterà alcun aspetto
tecnico relativo alla programmazione del kernel, ma vi aiuterà
indirizzandovi sulla corretta strada.
Se qualsiasi cosa presente in questo documento diventasse obsoleta,
vi preghiamo di inviare le correzioni agli amministratori di questo
file, indicati in fondo al presente documento.
Introduzione
------------
Dunque, volete imparare come diventare sviluppatori del kernel Linux?
O vi è stato detto dal vostro capo, "Vai, scrivi un driver Linux per
questo dispositivo". Bene, l'obbiettivo di questo documento è quello
di insegnarvi tutto ciò che dovete sapere per raggiungere il vostro
scopo descrivendo il procedimento da seguire e consigliandovi
su come lavorare con la comunità. Il documento cercherà, inoltre,
di spiegare alcune delle ragioni per le quali la comunità lavora in un
modo suo particolare.
Il kernel è scritto prevalentemente nel linguaggio C con alcune parti
specifiche dell'architettura scritte in linguaggio assembly.
Per lo sviluppo kernel è richiesta una buona conoscenza del linguaggio C.
L'assembly (di qualsiasi architettura) non è richiesto, a meno che non
pensiate di fare dello sviluppo di basso livello per un'architettura.
Sebbene essi non siano un buon sostituto ad un solido studio del
linguaggio C o ad anni di esperienza, i seguenti libri sono, se non
altro, utili riferimenti:
- "The C Programming Language" di Kernighan e Ritchie [Prentice Hall]
- "Practical C Programming" di Steve Oualline [O'Reilly]
- "C: A Reference Manual" di Harbison and Steele [Prentice Hall]
Il kernel è stato scritto usando GNU C e la toolchain GNU.
Sebbene si attenga allo standard ISO C11, esso utilizza una serie di
estensioni che non sono previste in questo standard. Il kernel è un
ambiente C indipendente, che non ha alcuna dipendenza dalle librerie
C standard, così alcune parti del C standard non sono supportate.
Le divisioni ``long long`` e numeri in virgola mobile non sono permessi.
Qualche volta è difficile comprendere gli assunti che il kernel ha
riguardo gli strumenti e le estensioni in uso, e sfortunatamente non
esiste alcuna indicazione definitiva. Per maggiori informazioni, controllate,
la pagina `info gcc`.
Tenete a mente che state cercando di apprendere come lavorare con la comunità
di sviluppo già esistente. Questo è un gruppo eterogeneo di persone, con alti
standard di codifica, di stile e di procedura. Questi standard sono stati
creati nel corso del tempo basandosi su quanto hanno riscontrato funzionare al
meglio per un squadra così grande e geograficamente sparsa. Cercate di
imparare, in anticipo, il più possibile circa questi standard, poichè ben
spiegati; non aspettatevi che gli altri si adattino al vostro modo di fare
o a quello della vostra azienda.
Note legali
------------
Il codice sorgente del kernel Linux è rilasciato sotto GPL. Siete pregati
di visionare il file, COPYING, presente nella cartella principale dei
sorgente, per eventuali dettagli sulla licenza. Se avete ulteriori domande
sulla licenza, contattate un avvocato, non chiedete sulle liste di discussione
del kernel Linux. Le persone presenti in queste liste non sono avvocati,
e non dovreste basarvi sulle loro dichiarazioni in materia giuridica.
Per domande più frequenti e risposte sulla licenza GPL, guardare:
https://www.gnu.org/licenses/gpl-faq.html
Documentazione
--------------
I sorgenti del kernel Linux hanno una vasta base di documenti che vi
insegneranno come interagire con la comunità del kernel. Quando nuove
funzionalità vengono aggiunte al kernel, si raccomanda di aggiungere anche i
relativi file di documentatione che spiegano come usarele.
Quando un cambiamento del kernel genera anche un cambiamento nell'interfaccia
con lo spazio utente, è raccomandabile che inviate una notifica o una
correzione alle pagine *man* spiegando tale modifica agli amministratori di
queste pagine all'indirizzo alx@kernel.org, aggiungendo in CC la
lista linux-api@vger.kernel.org.
Di seguito una lista di file che sono presenti nei sorgente del kernel e che
è richiesto che voi leggiate:
:ref:`Documentation/translations/it_IT/admin-guide/README.rst <it_readme>`
Questo file da una piccola anteprima del kernel Linux e descrive il
minimo necessario per configurare e generare il kernel. I novizi
del kernel dovrebbero iniziare da qui.
:ref:`Documentation/translations/it_IT/process/changes.rst <it_changes>`
Questo file fornisce una lista dei pacchetti software necessari
a compilare e far funzionare il kernel con successo.
:ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`
Questo file descrive lo stile della codifica per il kernel Linux,
e parte delle motivazioni che ne sono alla base. Tutto il nuovo codice deve
seguire le linee guida in questo documento. Molti amministratori
accetteranno patch solo se queste osserveranno tali regole, e molte
persone revisioneranno il codice solo se scritto nello stile appropriato.
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`
Questo file descrive dettagliatamente come creare ed inviare una patch
con successo, includendo (ma non solo questo):
- Contenuto delle email
- Formato delle email
- I destinatari delle email
Seguire tali regole non garantirà il successo (tutte le patch sono soggette
a controlli realitivi a contenuto e stile), ma non seguirle lo precluderà
sempre.
Altre ottime descrizioni di come creare buone patch sono:
"The Perfect Patch"
https://www.ozlabs.org/~akpm/stuff/tpp.txt
"Linux kernel patch submission format"
https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html
:ref:`Documentation/translations/it_IT/process/stable-api-nonsense.rst <it_stable_api_nonsense>`
Questo file descrive la motivazioni sottostanti la conscia decisione di
non avere un API stabile all'interno del kernel, incluso cose come:
- Sottosistemi shim-layers (per compatibilità?)
- Portabilità fra Sistemi Operativi dei driver.
- Attenuare i rapidi cambiamenti all'interno dei sorgenti del kernel
(o prevenirli)
Questo documento è vitale per la comprensione della filosifia alla base
dello sviluppo di Linux ed è molto importante per le persone che arrivano
da esperienze con altri Sistemi Operativi.
:ref:`Documentation/translations/it_IT/process/security-bugs.rst <it_securitybugs>`
Se ritenete di aver trovato un problema di sicurezza nel kernel Linux,
seguite i passaggi scritti in questo documento per notificarlo agli
sviluppatori del kernel, ed aiutare la risoluzione del problema.
:ref:`Documentation/translations/it_IT/process/management-style.rst <it_managementstyle>`
Questo documento descrive come i manutentori del kernel Linux operano
e la filosofia comune alla base del loro metodo. Questa è un'importante
lettura per tutti coloro che sono nuovi allo sviluppo del kernel (o per
chi è semplicemente curioso), poiché risolve molti dei più comuni
fraintendimenti e confusioni dovuti al particolare comportamento dei
manutentori del kernel.
:ref:`Documentation/translations/it_IT/process/stable-kernel-rules.rst <it_stable_kernel_rules>`
Questo file descrive le regole sulle quali vengono basati i rilasci del
kernel, e spiega cosa fare se si vuole che una modifica venga inserita
in uno di questi rilasci.
:ref:`Documentation/translations/it_IT/process/kernel-docs.rst <it_kernel_docs>`
Una lista di documenti pertinenti allo sviluppo del kernel.
Per favore consultate questa lista se non trovate ciò che cercate nella
documentazione interna del kernel.
:ref:`Documentation/translations/it_IT/process/applying-patches.rst <it_applying_patches>`
Una buona introduzione che descrivere esattamente cos'è una patch e come
applicarla ai differenti rami di sviluppo del kernel.
Il kernel inoltre ha un vasto numero di documenti che possono essere
automaticamente generati dal codice sorgente stesso o da file
ReStructuredText (ReST), come questo. Esso include una completa
descrizione dell'API interna del kernel, e le regole su come gestire la
sincronizzazione (locking) correttamente
Tutte queste tipologie di documenti possono essere generati in PDF o in
HTML utilizzando::
make pdfdocs
make htmldocs
rispettivamente dalla cartella principale dei sorgenti del kernel.
I documenti che impiegano ReST saranno generati nella cartella
Documentation/output.
Questi posso essere generati anche in formato LaTex e ePub con::
make latexdocs
make epubdocs
Diventare uno sviluppatore del kernel
-------------------------------------
Se non sapete nulla sullo sviluppo del kernel Linux, dovreste dare uno
sguardo al progetto *Linux KernelNewbies*:
https://kernelnewbies.org
Esso prevede un'utile lista di discussione dove potete porre più o meno ogni
tipo di quesito relativo ai concetti fondamentali sullo sviluppo del kernel
(assicuratevi di cercare negli archivi, prima di chiedere qualcosa alla
quale è già stata fornita risposta in passato). Esistono inoltre, un canale IRC
che potete usare per formulare domande in tempo reale, e molti documenti utili
che vi faciliteranno nell'apprendimento dello sviluppo del kernel Linux.
Il sito internet contiene informazioni di base circa l'organizzazione del
codice, sottosistemi e progetti attuali (sia interni che esterni a Linux).
Esso descrive, inoltre, informazioni logistiche di base, riguardanti ad esempio
la compilazione del kernel e l'applicazione di una modifica.
Se non sapete dove cominciare, ma volete cercare delle attività dalle quali
partire per partecipare alla comunità di sviluppo, andate al progetto Linux
Kernel Janitor's.
https://kernelnewbies.org/KernelJanitors
È un buon posto da cui iniziare. Esso presenta una lista di problematiche
relativamente semplici da sistemare e pulire all'interno della sorgente del
kernel Linux. Lavorando con gli sviluppatori incaricati di questo progetto,
imparerete le basi per l'inserimento delle vostre modifiche all'interno dei
sorgenti del kernel Linux, e possibilmente, sarete indirizzati al lavoro
successivo da svolgere, se non ne avrete ancora idea.
Prima di apportare una qualsiasi modifica al codice del kernel Linux,
è imperativo comprendere come tale codice funziona. A questo scopo, non c'è
nulla di meglio che leggerlo direttamente (la maggior parte dei bit più
complessi sono ben commentati), eventualmente anche con l'aiuto di strumenti
specializzati. Uno degli strumenti che è particolarmente raccomandato è
il progetto Linux Cross-Reference, che è in grado di presentare codice
sorgente in un formato autoreferenziale ed indicizzato. Un eccellente ed
aggiornata fonte di consultazione del codice del kernel la potete trovare qui:
https://elixir.bootlin.com/
Il processo di sviluppo
-----------------------
Il processo di sviluppo del kernel Linux si compone di pochi "rami" principali
e di molti altri rami per specifici sottosistemi. Questi rami sono:
- I sorgenti kernel 4.x
- I sorgenti stabili del kernel 4.x.y -stable
- Sorgenti dei sottosistemi del kernel e le loro modifiche
- Il kernel 4.x -next per test d'integrazione
I sorgenti kernel 4.x
~~~~~~~~~~~~~~~~~~~~~
I kernel 4.x sono amministrati da Linus Torvald, e possono essere trovati
su https://kernel.org nella cartella pub/linux/kernel/v4.x/. Il processo
di sviluppo è il seguente:
- Non appena un nuovo kernel viene rilasciato si apre una finestra di due
settimane. Durante questo periodo i manutentori possono proporre a Linus
dei grossi cambiamenti; solitamente i cambiamenti che sono già stati
inseriti nel ramo -next del kernel per alcune settimane. Il modo migliore
per sottoporre dei cambiamenti è attraverso git (lo strumento usato per
gestire i sorgenti del kernel, più informazioni sul sito
https://git-scm.com/) ma anche delle patch vanno bene.
- Al termine delle due settimane un kernel -rc1 viene rilasciato e
l'obbiettivo ora è quello di renderlo il più solido possibile. A questo
punto la maggior parte delle patch dovrebbero correggere un'eventuale
regressione. I bachi che sono sempre esistiti non sono considerabili come
regressioni, quindi inviate questo tipo di cambiamenti solo se sono
importanti. Notate che un intero driver (o filesystem) potrebbe essere
accettato dopo la -rc1 poiché non esistono rischi di una possibile
regressione con tale cambiamento, fintanto che quest'ultimo è
auto-contenuto e non influisce su aree esterne al codice che è stato
aggiunto. git può essere utilizzato per inviare le patch a Linus dopo che
la -rc1 è stata rilasciata, ma è anche necessario inviare le patch ad
una lista di discussione pubblica per un'ulteriore revisione.
- Una nuova -rc viene rilasciata ogni volta che Linus reputa che gli attuali
sorgenti siano in uno stato di salute ragionevolmente adeguato ai test.
L'obiettivo è quello di rilasciare una nuova -rc ogni settimana.
- Il processo continua fino a che il kernel è considerato "pronto"; tale
processo dovrebbe durare circa in 6 settimane.
È utile menzionare quanto scritto da Andrew Morton sulla lista di discussione
kernel-linux in merito ai rilasci del kernel:
*"Nessuno sa quando un kernel verrà rilasciato, poichè questo è
legato allo stato dei bachi e non ad una cronologia preventiva."*
I sorgenti stabili del kernel 4.x.y -stable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I kernel con versioni in 3-parti sono "kernel stabili". Essi contengono
correzioni critiche relativamente piccole nell'ambito della sicurezza
oppure significative regressioni scoperte in un dato 4.x kernel.
Questo è il ramo raccomandato per gli utenti che vogliono un kernel recente
e stabile e non sono interessati a dare il proprio contributo alla verifica
delle versioni di sviluppo o sperimentali.
Se non è disponibile alcun kernel 4.x.y., quello più aggiornato e stabile
sarà il kernel 4.x con la numerazione più alta.
4.x.y sono amministrati dal gruppo "stable" <stable@vger.kernel.org>, e sono
rilasciati a seconda delle esigenze. Il normale periodo di rilascio è
approssimativamente di due settimane, ma può essere più lungo se non si
verificano problematiche urgenti. Un problema relativo alla sicurezza, invece,
può determinare un rilascio immediato.
Il file Documentation/process/stable-kernel-rules.rst (nei sorgenti) documenta
quali tipologie di modifiche sono accettate per i sorgenti -stable, e come
avviene il processo di rilascio.
Sorgenti dei sottosistemi del kernel e le loro patch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I manutentori dei diversi sottosistemi del kernel --- ed anche molti
sviluppatori di sottosistemi --- mostrano il loro attuale stato di sviluppo
nei loro repositori. In questo modo, altri possono vedere cosa succede nelle
diverse parti del kernel. In aree dove lo sviluppo è rapido, potrebbe essere
chiesto ad uno sviluppatore di basare le proprie modifiche su questi repositori
in modo da evitare i conflitti fra le sottomissioni ed altri lavori in corso
La maggior parte di questi repositori sono git, ma esistono anche altri SCM
in uso, o file di patch pubblicate come una serie quilt.
Gli indirizzi dei repositori di sottosistema sono indicati nel file
MAINTAINERS. Molti di questi posso essere trovati su https://git.kernel.org/.
Prima che una modifica venga inclusa in questi sottosistemi, sarà soggetta ad
una revisione che inizialmente avviene tramite liste di discussione (vedere la
sezione dedicata qui sotto). Per molti sottosistemi del kernel, tale processo
di revisione è monitorato con lo strumento patchwork.
Patchwork offre un'interfaccia web che mostra le patch pubblicate, inclusi i
commenti o le revisioni fatte, e gli amministratori possono indicare le patch
come "in revisione", "accettate", o "rifiutate". Diversi siti Patchwork sono
elencati al sito https://patchwork.kernel.org/.
Il kernel 4.x -next per test d'integrazione
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prima che gli aggiornamenti dei sottosistemi siano accorpati nel ramo
principale 4.x, sarà necessario un test d'integrazione.
A tale scopo, esiste un repositorio speciale di test nel quale virtualmente
tutti i rami dei sottosistemi vengono inclusi su base quotidiana:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
In questo modo, i kernel -next offrono uno sguardo riassuntivo su quello che
ci si aspetterà essere nel kernel principale nel successivo periodo
d'incorporazione.
Coloro che vorranno fare dei test d'esecuzione del kernel -next sono più che
benvenuti.
Riportare Bug
-------------
Il file 'Documentation/admin-guide/reporting-issues.rst' nella
cartella principale del kernel spiega come segnalare un baco nel
kernel, e fornisce dettagli su quali informazioni sono necessarie agli
sviluppatori del kernel per poter studiare il problema.
Gestire i rapporti sui bug
--------------------------
Uno dei modi migliori per mettere in pratica le vostre capacità di hacking è
quello di riparare bachi riportati da altre persone. Non solo aiuterete a far
diventare il kernel più stabile, ma imparerete a riparare problemi veri dal
mondo ed accrescerete le vostre competenze, e gli altri sviluppatori saranno
al corrente della vostra presenza. Riparare bachi è una delle migliori vie per
acquisire meriti tra gli altri sviluppatori, perchè non a molte persone piace
perdere tempo a sistemare i bachi di altri.
Per lavorare sui bachi già segnalati, per prima cosa cercate il
sottosistema che vi interessa. Poi, verificate nel file MAINTAINERS
dove vengono collezionati solitamente i bachi per quel sottosistema;
spesso sarà una lista di discussione, raramente un bugtracker. Cercate
bachi nell'archivio e aiutate dove credete di poterlo fare. Potete
anche consultare https://bugzilla.kernel.org; però, solo una manciata di
sottosistemi lo usano attivamente, ciò nonostante i bachi che
coinvolgono l'intero kernel sono sempre riportati lì.
Liste di discussione
--------------------
Come descritto in molti dei documenti qui sopra, la maggior parte degli
sviluppatori del kernel partecipano alla lista di discussione Linux Kernel.
I dettagli su come iscriversi e disiscriversi dalla lista possono essere
trovati al sito:
https://subspace.kernel.org/subscribing.html
Ci sono diversi archivi della lista di discussione. Usate un qualsiasi motore
di ricerca per trovarli. Per esempio:
https://lore.kernel.org/linux-kernel/
É caldamente consigliata una ricerca in questi archivi sul tema che volete
sollevare, prima di pubblicarlo sulla lista. Molte cose sono già state
discusse in dettaglio e registrate negli archivi della lista di discussione.
Molti dei sottosistemi del kernel hanno anche una loro lista di discussione
dedicata. Guardate nel file MAINTAINERS per avere una lista delle liste di
discussione e il loro uso.
Molte di queste liste sono gestite su kernel.org. Per informazioni consultate
la seguente pagina:
https://subspace.kernel.org
Per favore ricordatevi della buona educazione quando utilizzate queste liste.
Sebbene sia un pò dozzinale, il seguente URL contiene alcune semplici linee
guida per interagire con la lista (o con qualsiasi altra lista):
https://subspace.kernel.org/etiquette.html
Se diverse persone rispondo alla vostra mail, la lista dei riceventi (copia
conoscenza) potrebbe diventare abbastanza lunga. Non cancellate nessuno dalla
lista di CC: senza un buon motivo, e non rispondete solo all'indirizzo
della lista di discussione. Fateci l'abitudine perché capita spesso di
ricevere la stessa email due volte: una dal mittente ed una dalla lista; e non
cercate di modificarla aggiungendo intestazioni stravaganti, agli altri non
piacerà.
Ricordate di rimanere sempre in argomento e di mantenere le attribuzioni
delle vostre risposte invariate; mantenete il "John Kernelhacker wrote ...:"
in cima alla vostra replica e aggiungete le vostre risposte fra i singoli
blocchi citati, non scrivete all'inizio dell'email.
Se aggiungete patch alla vostra mail, assicuratevi che siano del tutto
leggibili come indicato in Documentation/process/submitting-patches.rst.
Gli sviluppatori kernel non vogliono avere a che fare con allegati o patch
compresse; vogliono invece poter commentare le righe dei vostri cambiamenti,
il che può funzionare solo in questo modo.
Assicuratevi di utilizzare un gestore di mail che non alterì gli spazi ed i
caratteri. Un ottimo primo test è quello di inviare a voi stessi una mail e
cercare di sottoporre la vostra stessa patch. Se non funziona, sistemate il
vostro programma di posta, o cambiatelo, finché non funziona.
Ed infine, per favore ricordatevi di mostrare rispetto per gli altri
sottoscriventi.
Lavorare con la comunità
------------------------
L'obiettivo di questa comunità è quello di fornire il miglior kernel possibile.
Quando inviate una modifica che volete integrare, sarà valutata esclusivamente
dal punto di vista tecnico. Quindi, cosa dovreste aspettarvi?
- critiche
- commenti
- richieste di cambiamento
- richieste di spiegazioni
- nulla
Ricordatevi che questo fa parte dell'integrazione della vostra modifica
all'interno del kernel. Dovete essere in grado di accettare le critiche,
valutarle a livello tecnico ed eventualmente rielaborare nuovamente le vostre
modifiche o fornire delle chiare e concise motivazioni per le quali le
modifiche suggerite non dovrebbero essere fatte.
Se non riceverete risposte, aspettate qualche giorno e riprovate ancora,
qualche volta le cose si perdono nell'enorme mucchio di email.
Cosa non dovreste fare?
- aspettarvi che la vostra modifica venga accettata senza problemi
- mettervi sulla difensiva
- ignorare i commenti
- sottomettere nuovamente la modifica senza fare nessuno dei cambiamenti
richiesti
In una comunità che è alla ricerca delle migliori soluzioni tecniche possibili,
ci saranno sempre opinioni differenti sull'utilità di una modifica.
Siate cooperativi e vogliate adattare la vostra idea in modo che sia inserita
nel kernel. O almeno vogliate dimostrare che la vostra idea vale.
Ricordatevi, sbagliare è accettato fintanto che siate disposti a lavorare verso
una soluzione che è corretta.
È normale che le risposte alla vostra prima modifica possa essere
semplicemente una lista con dozzine di cose che dovreste correggere.
Questo **non** implica che la vostra patch non sarà accettata, e questo
**non** è contro di voi personalmente.
Semplicemente correggete tutte le questioni sollevate contro la vostra modifica
ed inviatela nuovamente.
Differenze tra la comunità del kernel e le strutture aziendali
--------------------------------------------------------------
La comunità del kernel funziona diversamente rispetto a molti ambienti di
sviluppo aziendali. Qui di seguito una lista di cose che potete provare a
fare per evitare problemi:
Cose da dire riguardanti le modifiche da voi proposte:
- "Questo risolve più problematiche."
- "Questo elimina 2000 stringhe di codice."
- "Qui una modifica che spiega cosa sto cercando di fare."
- "L'ho testato su 5 diverse architetture.."
- "Qui una serie di piccole modifiche che.."
- "Questo aumenta le prestazioni di macchine standard..."
Cose che dovreste evitare di dire:
- "Lo abbiamo fatto in questo modo in AIX/ptx/Solaris, di conseguenza
deve per forza essere giusto..."
- "Ho fatto questo per 20 anni, quindi.."
- "Questo è richiesto dalla mia Azienda per far soldi"
- "Questo è per la linea di prodotti della nostra Azienda"
- "Ecco il mio documento di design di 1000 pagine che descrive ciò che ho
in mente"
- "Ci ho lavorato per 6 mesi..."
- "Ecco una patch da 5000 righe che.."
- "Ho riscritto il pasticcio attuale, ed ecco qua.."
- "Ho una scadenza, e questa modifica ha bisogno di essere approvata ora"
Un'altra cosa nella quale la comunità del kernel si differenzia dai più
classici ambienti di ingegneria del software è la natura "senza volto" delle
interazioni umane. Uno dei benefici dell'uso delle email e di irc come forma
primordiale di comunicazione è l'assenza di discriminazione basata su genere e
razza. L'ambienti di lavoro Linux accetta donne e minoranze perchè tutto quello
che sei è un indirizzo email. Aiuta anche l'aspetto internazionale nel
livellare il terreno di gioco perchè non è possibile indovinare il genere
basandosi sul nome di una persona. Un uomo può chiamarsi Andrea ed una donna
potrebbe chiamarsi Pat. Gran parte delle donne che hanno lavorato al kernel
Linux e che hanno espresso una personale opinione hanno avuto esperienze
positive.
La lingua potrebbe essere un ostacolo per quelle persone che non si trovano
a loro agio con l'inglese. Una buona padronanza del linguaggio può essere
necessaria per esporre le proprie idee in maniera appropiata all'interno
delle liste di discussione, quindi è consigliabile che rileggiate le vostre
email prima di inviarle in modo da essere certi che abbiano senso in inglese.
Spezzare le vostre modifiche
----------------------------
La comunità del kernel Linux non accetta con piacere grossi pezzi di codice
buttati lì tutti in una volta. Le modifiche necessitano di essere
adeguatamente presentate, discusse, e suddivise in parti più piccole ed
indipendenti. Questo è praticamente l'esatto opposto di quello che le
aziende fanno solitamente. La vostra proposta dovrebbe, inoltre, essere
presentata prestissimo nel processo di sviluppo, così che possiate ricevere
un riscontro su quello che state facendo. Lasciate che la comunità
senta che state lavorando con loro, e che non li stiate sfruttando come
discarica per le vostre aggiunte. In ogni caso, non inviate 50 email nello
stesso momento in una lista di discussione, il più delle volte la vostra serie
di modifiche dovrebbe essere più piccola.
I motivi per i quali dovreste frammentare le cose sono i seguenti:
1) Piccole modifiche aumentano le probabilità che vengano accettate,
altrimenti richiederebbe troppo tempo o sforzo nel verificarne
la correttezza. Una modifica di 5 righe può essere accettata da un
manutentore con a mala pena una seconda occhiata. Invece, una modifica da
500 linee può richiedere ore di rilettura per verificarne la correttezza
(il tempo necessario è esponenzialmente proporzionale alla dimensione della
modifica, o giù di lì)
Piccole modifiche sono inoltre molto facili da debuggare quando qualcosa
non va. È molto più facile annullare le modifiche una per una che
dissezionare una patch molto grande dopo la sua sottomissione (e rompere
qualcosa).
2) È importante non solo inviare piccole modifiche, ma anche riscriverle e
semplificarle (o più semplicemente ordinarle) prima di sottoporle.
Qui un'analogia dello sviluppatore kernel Al Viro:
*"Pensate ad un insegnante di matematica che corregge il compito
di uno studente (di matematica). L'insegnante non vuole vedere le
prove e gli errori commessi dallo studente prima che arrivi alla
soluzione. Vuole vedere la risposta più pulita ed elegante
possibile. Un buono studente lo sa, e non presenterebbe mai le
proprie bozze prima prima della soluzione finale"*
*"Lo stesso vale per lo sviluppo del kernel. I manutentori ed i
revisori non vogliono vedere il procedimento che sta dietro al
problema che uno sta risolvendo. Vogliono vedere una soluzione
semplice ed elegante."*
Può essere una vera sfida il saper mantenere l'equilibrio fra una presentazione
elegante della vostra soluzione, lavorare insieme ad una comunità e dibattere
su un lavoro incompleto. Pertanto è bene entrare presto nel processo di
revisione per migliorare il vostro lavoro, ma anche per riuscire a tenere le
vostre modifiche in pezzettini che potrebbero essere già accettate, nonostante
la vostra intera attività non lo sia ancora.
In fine, rendetevi conto che non è accettabile inviare delle modifiche
incomplete con la promessa che saranno "sistemate dopo".
Giustificare le vostre modifiche
--------------------------------
Insieme alla frammentazione delle vostre modifiche, è altrettanto importante
permettere alla comunità Linux di capire perché dovrebbero accettarle.
Nuove funzionalità devono essere motivate come necessarie ed utili.
Documentare le vostre modifiche
-------------------------------
Quando inviate le vostre modifiche, fate particolare attenzione a quello che
scrivete nella vostra email. Questa diventerà il *ChangeLog* per la modifica,
e sarà visibile a tutti per sempre. Dovrebbe descrivere la modifica nella sua
interezza, contenendo:
- perchè la modifica è necessaria
- l'approccio d'insieme alla patch
- dettagli supplementari
- risultati dei test
Per maggiori dettagli su come tutto ciò dovrebbe apparire, riferitevi alla
sezione ChangeLog del documento:
"The Perfect Patch"
http://www.ozlabs.org/~akpm/stuff/tpp.txt
A volte tutto questo è difficile da realizzare. Il perfezionamento di queste
pratiche può richiedere anni (eventualmente). È un processo continuo di
miglioramento che richiede molta pazienza e determinazione. Ma non mollate,
si può fare. Molti lo hanno fatto prima, ed ognuno ha dovuto iniziare dove
siete voi ora.
----------
Grazie a Paolo Ciarrocchi che ha permesso che la sezione "Development Process"
(https://lwn.net/Articles/94386/) fosse basata sui testi da lui scritti, ed a
Randy Dunlap e Gerrit Huizenga per la lista di cose che dovreste e non
dovreste dire. Grazie anche a Pat Mochel, Hanna Linder, Randy Dunlap,
Kay Sievers, Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton,
Andi Kleen, Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop,
David A. Wheeler, Junio Hamano, Michael Kerrisk, e Alex Shepard per le
loro revisioni, commenti e contributi. Senza il loro aiuto, questo documento
non sarebbe stato possibile.
Manutentore: Greg Kroah-Hartman <greg@kroah.com>
@@ -0,0 +1,107 @@
.. raw:: latex
\renewcommand\thesection*
\renewcommand\thesubsection*
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/index.rst <process_index>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_process_index:
===============================================
Lavorare con la comunità di sviluppo del kernel
===============================================
Quindi volete diventare sviluppatori del kernel? Benvenuti! C'è molto da
imparare sul lato tecnico del kernel, ma è anche importante capire come
funziona la nostra comunità. Leggere questi documenti renderà più facile
l'accettazione delle vostre modifiche con il minimo sforzo.
Di seguito le guide che ogni sviluppatore dovrebbe leggere.
Introduzione al funzionamento dello sviluppo del kernel
-------------------------------------------------------
Innanzitutto, leggete questi documenti che vi aiuteranno ad entrare nella
comunità del kernel.
.. toctree::
:maxdepth: 1
howto
development-process
submitting-patches
submit-checklist
Strumenti e guide tecniche per gli sviluppatori del kernel
----------------------------------------------------------
Quella che segue è una raccolta di documenti che uno sviluppatore del kernel
Linux dovrebbe conoscere.
.. toctree::
:maxdepth: 1
changes
programming-language
coding-style
maintainer-pgp-guide
email-clients
applying-patches
adding-syscalls
volatile-considered-harmful
botching-up-ioctls
Politiche e dichiarazioni degli sviluppatori
--------------------------------------------
Quelle che seguono rappresentano le regole che cerchiamo di seguire all'interno
della comunità del kernel (e oltre).
.. toctree::
:maxdepth: 1
code-of-conduct
kernel-enforcement-statement
kernel-driver-statement
stable-api-nonsense
stable-kernel-rules
management-style
Gestire i bachi
---------------
I bachi sono parte della nostra vita; dunque è importante che vengano trattati
con riguardo. I documenti che seguono descrivono le nostre politiche riguardo al
trattamento di alcune classi particolari di bachi: le regressioni e i problemi
di sicurezza.
Informazioni per i manutentori
------------------------------
Come trovare le persone che accetteranno le vostre modifiche.
.. toctree::
:maxdepth: 1
maintainers
Altri documenti
---------------
Poi ci sono altre guide sulla comunità che sono di interesse per molti
degli sviluppatori:
.. toctree::
:maxdepth: 1
kernel-docs
.. only:: subproject and html
Indices
=======
* :ref:`genindex`
@@ -0,0 +1,18 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/kernel-docs.rst <kernel_docs>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_kernel_docs:
Ulteriore Documentazione Del Kernel Linux
=========================================
.. note::
Questo documento contiene riferimenti a documenti in lingua inglese; inoltre
utilizza dai campi *ReStructuredText* di supporto alla ricerca e che per
questo motivo è meglio non tradurre al fine di garantirne un corretto
utilizzo.
Per questi motivi il documento non verrà tradotto. Per favore fate
riferimento al documento originale in lingua inglese.
@@ -0,0 +1,211 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/kernel-driver-statement.rst <process_statement_driver>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_process_statement_driver:
Dichiarazioni sui driver per il kernel
======================================
Presa di posizione sui moduli per il kernel Linux
-------------------------------------------------
Noi, i sottoscritti sviluppatori del kernel, consideriamo pericoloso
o indesiderato qualsiasi modulo o driver per il kernel Linux di tipo
*a sorgenti chiusi* (*closed-source*). Ripetutamente, li abbiamo
trovati deleteri per gli utenti Linux, le aziende, ed in generale
l'ecosistema Linux. Questi moduli impediscono l'apertura, la stabilità,
la flessibilità, e la manutenibilità del modello di sviluppo di Linux
e impediscono ai loro utenti di beneficiare dell'esperienza dalla
comunità Linux. I fornitori che distribuiscono codice a sorgenti chiusi
obbligano i propri utenti a rinunciare ai principali vantaggi di Linux
o a cercarsi nuovi fornitori.
Perciò, al fine di sfruttare i vantaggi che codice aperto ha da offrire,
come l'abbattimento dei costi e un supporto condiviso, spingiamo i
fornitori ad adottare una politica di supporto ai loro clienti Linux
che preveda il rilascio dei sorgenti per il kernel.
Parliamo solo per noi stessi, e non per una qualsiasi azienda per la
quale lavoriamo oggi, o abbiamo lavorato in passato, o lavoreremo in
futuro.
- Dave Airlie
- Nick Andrew
- Jens Axboe
- Ralf Baechle
- Felipe Balbi
- Ohad Ben-Cohen
- Muli Ben-Yehuda
- Jiri Benc
- Arnd Bergmann
- Thomas Bogendoerfer
- Vitaly Bordug
- James Bottomley
- Josh Boyer
- Neil Brown
- Mark Brown
- David Brownell
- Michael Buesch
- Franck Bui-Huu
- Adrian Bunk
- François Cami
- Ralph Campbell
- Luiz Fernando N. Capitulino
- Mauro Carvalho Chehab
- Denis Cheng
- Jonathan Corbet
- Glauber Costa
- Alan Cox
- Magnus Damm
- Ahmed S. Darwish
- Robert P. J. Day
- Hans de Goede
- Arnaldo Carvalho de Melo
- Helge Deller
- Jean Delvare
- Mathieu Desnoyers
- Sven-Thorsten Dietrich
- Alexey Dobriyan
- Daniel Drake
- Alex Dubov
- Randy Dunlap
- Michael Ellerman
- Pekka Enberg
- Jan Engelhardt
- Mark Fasheh
- J. Bruce Fields
- Larry Finger
- Jeremy Fitzhardinge
- Mike Frysinger
- Kumar Gala
- Robin Getz
- Liam Girdwood
- Jan-Benedict Glaw
- Thomas Gleixner
- Brice Goglin
- Cyrill Gorcunov
- Andy Gospodarek
- Thomas Graf
- Krzysztof Halasa
- Harvey Harrison
- Stephen Hemminger
- Michael Hennerich
- Tejun Heo
- Benjamin Herrenschmidt
- Kristian Høgsberg
- Henrique de Moraes Holschuh
- Marcel Holtmann
- Mike Isely
- Takashi Iwai
- Olof Johansson
- Dave Jones
- Jesper Juhl
- Matthias Kaehlcke
- Kenji Kaneshige
- Jan Kara
- Jeremy Kerr
- Russell King
- Olaf Kirch
- Roel Kluin
- Hans-Jürgen Koch
- Auke Kok
- Peter Korsgaard
- Jiri Kosina
- Aaro Koskinen
- Mariusz Kozlowski
- Greg Kroah-Hartman
- Michael Krufky
- Aneesh Kumar
- Clemens Ladisch
- Christoph Lameter
- Gunnar Larisch
- Anders Larsen
- Grant Likely
- John W. Linville
- Yinghai Lu
- Tony Luck
- Pavel Machek
- Matt Mackall
- Paul Mackerras
- Roland McGrath
- Patrick McHardy
- Kyle McMartin
- Paul Menage
- Thierry Merle
- Eric Miao
- Akinobu Mita
- Ingo Molnar
- James Morris
- Andrew Morton
- Paul Mundt
- Oleg Nesterov
- Luca Olivetti
- S.Çağlar Onur
- Pierre Ossman
- Keith Owens
- Venkatesh Pallipadi
- Nick Piggin
- Nicolas Pitre
- Evgeniy Polyakov
- Richard Purdie
- Mike Rapoport
- Sam Ravnborg
- Gerrit Renker
- Stefan Richter
- David Rientjes
- Luis R. Rodriguez
- Stefan Roese
- Francois Romieu
- Rami Rosen
- Stephen Rothwell
- Maciej W. Rozycki
- Mark Salyzyn
- Yoshinori Sato
- Deepak Saxena
- Holger Schurig
- Amit Shah
- Yoshihiro Shimoda
- Sergei Shtylyov
- Kay Sievers
- Sebastian Siewior
- Rik Snel
- Jes Sorensen
- Alexey Starikovskiy
- Alan Stern
- Timur Tabi
- Hirokazu Takata
- Eliezer Tamir
- Eugene Teo
- Doug Thompson
- FUJITA Tomonori
- Dmitry Torokhov
- Marcelo Tosatti
- Steven Toth
- Theodore Tso
- Matthias Urlichs
- Geert Uytterhoeven
- Arjan van de Ven
- Ivo van Doorn
- Rik van Riel
- Wim Van Sebroeck
- Hans Verkuil
- Horst H. von Brand
- Dmitri Vorobiev
- Anton Vorontsov
- Daniel Walker
- Johannes Weiner
- Harald Welte
- Matthew Wilcox
- Dan J. Williams
- Darrick J. Wong
- David Woodhouse
- Chris Wright
- Bryan Wu
- Rafael J. Wysocki
- Herbert Xu
- Vlad Yasevich
- Peter Zijlstra
- Bartlomiej Zolnierkiewicz
@@ -0,0 +1,175 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/kernel-enforcement-statement.rst <process_statement_kernel>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_process_statement_kernel:
Applicazione della licenza sul kernel Linux
===========================================
Come sviluppatori del kernel Linux, abbiamo un certo interessa su come il
nostro software viene usato e su come la sua licenza viene fatta rispettare.
Il rispetto reciproco degli obblighi di condivisione della GPL-2.0 è
fondamentale per la sostenibilità di lungo periodo del nostro software e
della nostra comunità.
Benché ognuno abbia il diritto a far rispettare il diritto d'autore per i
propri contributi alla nostra comunità, condividiamo l'interesse a far si che
ogni azione individuale nel far rispettare i propri diritti sia condotta in
modo da portare beneficio alla comunità e che non abbia, involontariamente,
impatti negativi sulla salute e la crescita del nostro ecosistema software.
Al fine di scoraggiare l'esecuzione di azioni inutili, concordiamo che è nel
migliore interesse della nostra comunità di sviluppo di impegnarci nel
rispettare i seguenti obblighi nei confronti degli utenti del kernel Linux
per conto nostro e di qualsiasi successore ai nostri interessi sul diritto
d'autore:
Malgrado le clausole di risoluzione della licenza GPL-2.0, abbiamo
concordato che è nel migliore interesse della nostra comunità di sviluppo
adottare le seguenti disposizioni della GPL-3.0 come permessi aggiuntivi
alla nostra licenza nei confronti di qualsiasi affermazione non difensiva
di diritti sulla licenza.
In ogni caso, se cessano tutte le violazioni di questa Licenza, allora
la tua licenza da parte di un dato detentore del copyright viene
ripristinata (a) in via cautelativa, a meno che e fino a quando il
detentore del copyright non cessa esplicitamente e definitivamente
la tua licenza, e (b) in via permanente se il detentore del copyright
non ti notifica in alcun modo la violazione entro 60 giorni dalla
cessazione della licenza.
Inoltre, la tua licenza da parte di un dato detentore del copyright
viene ripristinata in maniera permanente se il detentore del copyright
ti notifica la violazione in maniera adeguata, se questa è la prima
volta che ricevi una notifica di violazione di questa Licenza (per
qualunque Programma) dallo stesso detentore di copyright, e se rimedi
alla violazione entro 30 giorni dalla data di ricezione della notifica
di violazione.
Fornendo queste garanzie, abbiamo l'intenzione di incoraggiare l'uso del
software. Vogliamo che le aziende e le persone usino, modifichino e
distribuiscano a questo software. Vogliamo lavorare con gli utenti in modo
aperto e trasparente per eliminare ogni incertezza circa le nostre aspettative
sul rispetto o l'ottemperanza alla licenza che possa limitare l'uso del nostro
software. Vediamo l'azione legale come ultima spiaggia, da avviare solo quando
gli altri sforzi della comunità hanno fallito nel risolvere il problema.
Per finire, una volta che un problema di non rispetto della licenza viene
risolto, speriamo che gli utenti si sentano i benvenuti ad aggregarsi a noi
nello sviluppo di questo progetto. Lavorando assieme, saremo più forti.
Ad eccezione deve specificato, parliamo per noi stessi, e non per una qualsiasi
azienda per la quale lavoriamo oggi, o per cui abbiamo lavorato in passato, o
lavoreremo in futuro.
- Laura Abbott
- Bjorn Andersson (Linaro)
- Andrea Arcangeli
- Neil Armstrong
- Jens Axboe
- Pablo Neira Ayuso
- Khalid Aziz
- Ralf Baechle
- Felipe Balbi
- Arnd Bergmann
- Ard Biesheuvel
- Tim Bird
- Paolo Bonzini
- Christian Borntraeger
- Mark Brown (Linaro)
- Paul Burton
- Javier Martinez Canillas
- Rob Clark
- Kees Cook (Google)
- Jonathan Corbet
- Dennis Dalessandro
- Vivien Didelot (Savoir-faire Linux)
- Hans de Goede
- Mel Gorman (SUSE)
- Sven Eckelmann
- Alex Elder (Linaro)
- Fabio Estevam
- Larry Finger
- Bhumika Goyal
- Andy Gross
- Juergen Gross
- Shawn Guo
- Ulf Hansson
- Stephen Hemminger (Microsoft)
- Tejun Heo
- Rob Herring
- Masami Hiramatsu
- Michal Hocko
- Simon Horman
- Johan Hovold (Hovold Consulting AB)
- Christophe JAILLET
- Olof Johansson
- Lee Jones (Linaro)
- Heiner Kallweit
- Srinivas Kandagatla
- Jan Kara
- Shuah Khan (Samsung)
- David Kershner
- Jaegeuk Kim
- Namhyung Kim
- Colin Ian King
- Jeff Kirsher
- Greg Kroah-Hartman (Linux Foundation)
- Christian König
- Vinod Koul
- Krzysztof Kozlowski
- Viresh Kumar
- Aneesh Kumar K.V
- Julia Lawall
- Doug Ledford
- Chuck Lever (Oracle)
- Daniel Lezcano
- Shaohua Li
- Xin Long
- Tony Luck
- Catalin Marinas (Arm Ltd)
- Mike Marshall
- Chris Mason
- Paul E. McKenney
- Arnaldo Carvalho de Melo
- David S. Miller
- Ingo Molnar
- Kuninori Morimoto
- Trond Myklebust
- Martin K. Petersen (Oracle)
- Borislav Petkov
- Jiri Pirko
- Josh Poimboeuf
- Sebastian Reichel (Collabora)
- Guenter Roeck
- Joerg Roedel
- Leon Romanovsky
- Steven Rostedt (VMware)
- Frank Rowand
- Ivan Safonov
- Anna Schumaker
- Jes Sorensen
- K.Y. Srinivasan
- David Sterba (SUSE)
- Heiko Stuebner
- Jiri Kosina (SUSE)
- Willy Tarreau
- Dmitry Torokhov
- Linus Torvalds
- Thierry Reding
- Rik van Riel
- Luis R. Rodriguez
- Geert Uytterhoeven (Glider bvba)
- Eduardo Valentin (Amazon.com)
- Daniel Vetter
- Linus Walleij
- Richard Weinberger
- Dan Williams
- Rafael J. Wysocki
- Arvind Yadav
- Masahiro Yamada
- Wei Yongjun
- Lv Zheng
- Marc Zyngier (Arm Ltd)
@@ -0,0 +1,500 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/license-rules.rst <kernel_licensing>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_kernel_licensing:
Regole per licenziare il kernel Linux
=====================================
Il kernel Linux viene rilasciato sotto i termini definiti dalla seconda
versione della licenza *GNU General Public License* (GPL-2.0), di cui una
copia è disponibile nel file LICENSES/preferred/GPL-2.0; a questo si
aggiunge eccezione per le chiamate di sistema come descritto in
LICENSES/exceptions/Linux-syscall-note; tutto ciò è descritto nel file COPYING.
Questo documento fornisce una descrizione su come ogni singolo file sorgente
debba essere licenziato per far si che sia chiaro e non ambiguo. Questo non
sostituisce la licenza del kernel.
La licenza descritta nel file COPYING si applica ai sorgenti del kernel nella
loro interezza, quindi i singoli file sorgenti possono avere diverse licenze ma
devono essere compatibili con la GPL-2.0::
GPL-1.0+ : GNU General Public License v1.0 o successiva
GPL-2.0+ : GNU General Public License v2.0 o successiva
LGPL-2.0 : GNU Library General Public License v2
LGPL-2.0+ : GNU Library General Public License v2 o successiva
LGPL-2.1 : GNU Lesser General Public License v2.1
LGPL-2.1+ : GNU Lesser General Public License v2.1 o successiva
A parte questo, i singolo file possono essere forniti con una doppia licenza,
per esempio con una delle varianti compatibili della GPL e alternativamente con
una licenza permissiva come BSD, MIT eccetera.
I file d'intestazione per l'API verso lo spazio utente (UAPI) descrivono
le interfacce usate dai programmi, e per questo sono un caso speciale.
Secondo le note nel file COPYING, le chiamate di sistema sono un chiaro
confine oltre il quale non si estendono i requisiti della GPL per quei
programmi che le usano per comunicare con il kernel. Dato che i file
d'intestazione UAPI devono poter essere inclusi nei sorgenti di un
qualsiasi programma eseguibile sul kernel Linux, questi meritano
un'eccezione documentata da una clausola speciale.
Il modo più comune per indicare la licenza dei file sorgenti è quello di
aggiungere il corrispondente blocco di testo come commento in testa a detto
file. Per via della formattazione, dei refusi, eccetera, questi blocchi di
testo sono difficili da identificare dagli strumenti usati per verificare il
rispetto delle licenze.
Un'alternativa ai blocchi di testo è data dall'uso degli identificatori
*Software Package Data Exchange* (SPDX) in ogni file sorgente. Gli
identificatori di licenza SPDX sono analizzabili dalle macchine e sono precisi
simboli stenografici che identificano la licenza sotto la quale viene
licenziato il file che lo include. Gli identificatori di licenza SPDX sono
gestiti del gruppo di lavoro SPDX presso la Linux Foundation e sono stati
concordati fra i soci nell'industria, gli sviluppatori di strumenti, e i
rispettivi gruppi legali. Per maggiori informazioni, consultate
https://spdx.org/
Il kernel Linux richiede un preciso identificatore SPDX in tutti i file
sorgenti. Gli identificatori validi verranno spiegati nella sezione
`Identificatori di licenza`_ e sono stati copiati dalla lista ufficiale di
licenze SPDX assieme al rispettivo testo come mostrato in
https://spdx.org/licenses/.
Sintassi degli identificatori di licenza
----------------------------------------
1. Posizionamento:
L'identificativo di licenza SPDX dev'essere posizionato come prima riga
possibile di un file che possa contenere commenti. Per la maggior parte
dei file questa è la prima riga, fanno eccezione gli script che richiedono
come prima riga '#!PATH_TO_INTERPRETER'. Per questi script l'identificativo
SPDX finisce nella seconda riga.
|
2. Stile:
L'identificativo di licenza SPDX viene aggiunto sotto forma di commento.
Lo stile del commento dipende dal tipo di file::
sorgenti C: // SPDX-License-Identifier: <SPDX License Expression>
intestazioni C: /* SPDX-License-Identifier: <SPDX License Expression> */
ASM: /* SPDX-License-Identifier: <SPDX License Expression> */
scripts: # SPDX-License-Identifier: <SPDX License Expression>
.rst: .. SPDX-License-Identifier: <SPDX License Expression>
.dts{i}: // SPDX-License-Identifier: <SPDX License Expression>
Se un particolare programma non dovesse riuscire a gestire lo stile
principale per i commenti, allora dev'essere usato il meccanismo accettato
dal programma. Questo è il motivo per cui si ha "/\* \*/" nei file
d'intestazione C. Notammo che 'ld' falliva nell'analizzare i commenti del
C++ nei file .lds che venivano prodotti. Oggi questo è stato corretto,
ma ci sono in giro ancora vecchi programmi che non sono in grado di
gestire lo stile dei commenti del C++.
|
3. Sintassi:
Una <espressione di licenza SPDX> può essere scritta usando l'identificatore
SPDX della licenza come indicato nella lista di licenze SPDX, oppure la
combinazione di due identificatori SPDX separati da "WITH" per i casi
eccezionali. Quando si usano più licenze l'espressione viene formata da
sottoespressioni separate dalle parole chiave "AND", "OR" e racchiuse fra
parentesi tonde "(", ")".
Gli identificativi di licenza per licenze come la [L]GPL che si avvalgono
dell'opzione 'o successive' si formano aggiungendo alla fine il simbolo "+"
per indicare l'opzione 'o successive'.::
// SPDX-License-Identifier: GPL-2.0+
// SPDX-License-Identifier: LGPL-2.1+
WITH dovrebbe essere usato quando sono necessarie delle modifiche alla
licenza. Per esempio, la UAPI del kernel linux usa l'espressione::
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
// SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note
Altri esempi di usi di WITH all'interno del kernel sono::
// SPDX-License-Identifier: GPL-2.0 WITH mif-exception
// SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0
Le eccezioni si possono usare solo in combinazione con identificatori di
licenza. Gli identificatori di licenza riconosciuti sono elencati nei
corrispondenti file d'eccezione. Per maggiori dettagli consultate
`Eccezioni`_ nel capitolo `Identificatori di licenza`_
La parola chiave OR dovrebbe essere usata solo quando si usa una doppia
licenza e solo una dev'essere scelta. Per esempio, alcuni file dtsi sono
disponibili con doppia licenza::
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
Esempi dal kernel di espressioni per file licenziati con doppia licenza
sono::
// SPDX-License-Identifier: GPL-2.0 OR MIT
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
// SPDX-License-Identifier: GPL-2.0 OR MPL-1.1
// SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT
// SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause OR OpenSSL
La parola chiave AND dovrebbe essere usata quando i termini di più licenze
si applicano ad un file. Per esempio, quando il codice viene preso da
un altro progetto il quale da i permessi per aggiungerlo nel kernel ma
richiede che i termini originali della licenza rimangano intatti::
// SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT
Di seguito, un altro esempio dove entrambe i termini di licenza devono
essere rispettati::
// SPDX-License-Identifier: GPL-1.0+ AND LGPL-2.1+
Identificatori di licenza
-------------------------
Le licenze attualmente in uso, così come le licenze aggiunte al kernel, possono
essere categorizzate in:
1. _`Licenze raccomandate`:
Ovunque possibile le licenze qui indicate dovrebbero essere usate perché
pienamente compatibili e molto usate. Queste licenze sono disponibile nei
sorgenti del kernel, nella cartella::
LICENSES/preferred/
I file in questa cartella contengono il testo completo della licenza e i
`Metatag`_. Il nome di questi file è lo stesso usato come identificatore
di licenza SPDX e che deve essere usato nei file sorgenti.
Esempi::
LICENSES/preferred/GPL-2.0
Contiene il testo della seconda versione della licenza GPL e i metatag
necessari::
LICENSES/preferred/MIT
Contiene il testo della licenza MIT e i metatag necessari.
_`Metatag`:
I seguenti metatag devono essere presenti in un file di licenza:
- Valid-License-Identifier:
Una o più righe che dichiarano quali identificatori di licenza sono validi
all'interno del progetto per far riferimento alla licenza in questione.
Solitamente, questo è un unico identificatore valido, ma per esempio le
licenze che permettono l'opzione 'o successive' hanno due identificatori
validi.
- SPDX-URL:
L'URL della pagina SPDX che contiene informazioni aggiuntive riguardanti
la licenza.
- Usage-Guidance:
Testo in formato libero per dare suggerimenti agli utenti. Il testo deve
includere degli esempi su come usare gli identificatori di licenza SPDX
in un file sorgente in conformità con le linea guida in
`Sintassi degli identificatori di licenza`_.
- License-Text:
Tutto il testo che compare dopo questa etichetta viene trattato
come se fosse parte del testo originale della licenza.
Esempi::
Valid-License-Identifier: GPL-2.0
Valid-License-Identifier: GPL-2.0+
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
Usage-Guide:
To use this license in source code, put one of the following SPDX
tag/value pairs into a comment according to the placement
guidelines in the licensing rules documentation.
For 'GNU General Public License (GPL) version 2 only' use:
SPDX-License-Identifier: GPL-2.0
For 'GNU General Public License (GPL) version 2 or any later version' use:
SPDX-License-Identifier: GPL-2.0+
License-Text:
Full license text
::
SPDX-License-Identifier: MIT
SPDX-URL: https://spdx.org/licenses/MIT.html
Usage-Guide:
To use this license in source code, put the following SPDX
tag/value pair into a comment according to the placement
guidelines in the licensing rules documentation.
SPDX-License-Identifier: MIT
License-Text:
Full license text
|
2. Licenze deprecate:
Questo tipo di licenze dovrebbero essere usate solo per codice già esistente
o quando si prende codice da altri progetti. Le licenze sono disponibili
nei sorgenti del kernel nella cartella::
LICENSES/deprecated/
I file in questa cartella contengono il testo completo della licenza e i
`Metatag`_. Il nome di questi file è lo stesso usato come identificatore
di licenza SPDX e che deve essere usato nei file sorgenti.
Esempi::
LICENSES/deprecated/ISC
Contiene il testo della licenza Internet System Consortium e i suoi
metatag::
LICENSES/deprecated/GPL-1.0
Contiene il testo della versione 1 della licenza GPL e i suoi metatag.
Metatag:
I metatag necessari per le 'altre' ('other') licenze sono gli stessi
di usati per le `Licenze raccomandate`_.
Esempio del formato del file::
Valid-License-Identifier: ISC
SPDX-URL: https://spdx.org/licenses/ISC.html
Usage-Guide:
Usage of this license in the kernel for new code is discouraged
and it should solely be used for importing code from an already
existing project.
To use this license in source code, put the following SPDX
tag/value pair into a comment according to the placement
guidelines in the licensing rules documentation.
SPDX-License-Identifier: ISC
License-Text:
Full license text
|
3. Solo per doppie licenze
Queste licenze dovrebbero essere usate solamente per codice licenziato in
combinazione con un'altra licenza che solitamente è quella preferita.
Queste licenze sono disponibili nei sorgenti del kernel nella cartella::
LICENSES/dual
I file in questa cartella contengono il testo completo della rispettiva
licenza e i suoi `Metatag`_. I nomi dei file sono identici agli
identificatori di licenza SPDX che dovrebbero essere usati nei file
sorgenti.
Esempi::
LICENSES/dual/MPL-1.1
Questo file contiene il testo della versione 1.1 della licenza *Mozilla
Pulic License* e i metatag necessari::
LICENSES/dual/Apache-2.0
Questo file contiene il testo della versione 2.0 della licenza Apache e i
metatag necessari.
Metatag:
I requisiti per le 'altre' ('*other*') licenze sono identici a quelli per le
`Licenze raccomandate`_.
Esempio del formato del file::
Valid-License-Identifier: MPL-1.1
SPDX-URL: https://spdx.org/licenses/MPL-1.1.html
Usage-Guide:
Do NOT use. The MPL-1.1 is not GPL2 compatible. It may only be used for
dual-licensed files where the other license is GPL2 compatible.
If you end up using this it MUST be used together with a GPL2 compatible
license using "OR".
To use the Mozilla Public License version 1.1 put the following SPDX
tag/value pair into a comment according to the placement guidelines in
the licensing rules documentation:
SPDX-License-Identifier: MPL-1.1
License-Text:
Full license text
|
4. _`Eccezioni`:
Alcune licenze possono essere corrette con delle eccezioni che forniscono
diritti aggiuntivi. Queste eccezioni sono disponibili nei sorgenti del
kernel nella cartella::
LICENSES/exceptions/
I file in questa cartella contengono il testo completo dell'eccezione e i
`Metatag per le eccezioni`_.
Esempi::
LICENSES/exceptions/Linux-syscall-note
Contiene la descrizione dell'eccezione per le chiamate di sistema Linux
così come documentato nel file COPYING del kernel Linux; questo viene usato
per i file d'intestazione per la UAPI. Per esempio
/\* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note \*/::
LICENSES/exceptions/GCC-exception-2.0
Contiene la 'eccezione di linking' che permette di collegare qualsiasi
binario, indipendentemente dalla sua licenza, con un compilato il cui file
sorgente è marchiato con questa eccezione. Questo è necessario per creare
eseguibili dai sorgenti che non sono compatibili con la GPL.
_`Metatag per le eccezioni`:
Un file contenente un'eccezione deve avere i seguenti metatag:
- SPDX-Exception-Identifier:
Un identificatore d'eccezione che possa essere usato in combinazione con
un identificatore di licenza SPDX.
- SPDX-URL:
L'URL della pagina SPDX che contiene informazioni aggiuntive riguardanti
l'eccezione.
- SPDX-Licenses:
Una lista di licenze SPDX separate da virgola, che possono essere usate
con l'eccezione.
- Usage-Guidance:
Testo in formato libero per dare suggerimenti agli utenti. Il testo deve
includere degli esempi su come usare gli identificatori di licenza SPDX
in un file sorgente in conformità con le linea guida in
`Sintassi degli identificatori di licenza`_.
- Exception-Text:
Tutto il testo che compare dopo questa etichetta viene trattato
come se fosse parte del testo originale della licenza.
Esempi::
SPDX-Exception-Identifier: Linux-syscall-note
SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html
SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+
Usage-Guidance:
This exception is used together with one of the above SPDX-Licenses
to mark user-space API (uapi) header files so they can be included
into non GPL compliant user-space application code.
To use this exception add it with the keyword WITH to one of the
identifiers in the SPDX-Licenses tag:
SPDX-License-Identifier: <SPDX-License> WITH Linux-syscall-note
Exception-Text:
Full exception text
::
SPDX-Exception-Identifier: GCC-exception-2.0
SPDX-URL: https://spdx.org/licenses/GCC-exception-2.0.html
SPDX-Licenses: GPL-2.0, GPL-2.0+
Usage-Guidance:
The "GCC Runtime Library exception 2.0" is used together with one
of the above SPDX-Licenses for code imported from the GCC runtime
library.
To use this exception add it with the keyword WITH to one of the
identifiers in the SPDX-Licenses tag:
SPDX-License-Identifier: <SPDX-License> WITH GCC-exception-2.0
Exception-Text:
Full exception text
Per ogni identificatore di licenza SPDX e per le eccezioni dev'esserci un file
nella sotto-cartella LICENSES. Questo è necessario per permettere agli
strumenti di effettuare verifiche (come checkpatch.pl), per avere le licenze
disponibili per la lettura e per estrarre i diritti dai sorgenti, così come
raccomandato da diverse organizzazioni FOSS, per esempio l'`iniziativa FSFE
REUSE <https://reuse.software/>`_.
_`MODULE_LICENSE`
-----------------
I moduli del kernel necessitano di un'etichetta MODULE_LICENSE(). Questa
etichetta non sostituisce le informazioni sulla licenza del codice sorgente
(SPDX-License-Identifier) né fornisce informazioni che esprimono o
determinano l'esatta licenza sotto la quale viene rilasciato.
Il solo scopo di questa etichetta è quello di fornire sufficienti
informazioni al caricatore di moduli del kernel, o agli strumenti in spazio
utente, per capire se il modulo è libero o proprietario.
Le stringe di licenza valide per MODULE_LICENSE() sono:
============================= =============================================
"GPL" Il modulo è licenziato con la GPL versione 2.
Questo non fa distinzione fra GPL'2.0-only o
GPL-2.0-or-later. L'esatta licenza può essere
determinata solo leggendo i corrispondenti
file sorgenti.
"GPL v2" Stesso significato di "GPL". Esiste per
motivi storici.
"GPL and additional rights" Questa è una variante che esiste per motivi
storici che indica che i sorgenti di un
modulo sono rilasciati sotto una variante
della licenza GPL v2 e quella MIT. Per favore
non utilizzatela per codice nuovo.
"Dual MIT/GPL" Questo è il modo corretto per esprimere il
il fatto che il modulo è rilasciato con
doppia licenza a scelta fra: una variante
della GPL v2 o la licenza MIT.
"Dual BSD/GPL" Questo modulo è rilasciato con doppia licenza
a scelta fra: una variante della GPL v2 o la
licenza BSD. La variante esatta della licenza
BSD può essere determinata solo attraverso i
corrispondenti file sorgenti.
"Dual MPL/GPL" Questo modulo è rilasciato con doppia licenza
a scelta fra: una variante della GPL v2 o la
Mozilla Public License (MPL). La variante
esatta della licenza MPL può essere
determinata solo attraverso i corrispondenti
file sorgenti.
"Proprietary" Questo modulo è rilasciato con licenza
proprietaria. Questa stringa è solo per i
moduli proprietari di terze parti e non può
essere usata per quelli che risiedono nei
sorgenti del kernel. I moduli etichettati in
questo modo stanno contaminando il kernel e
gli viene assegnato un flag 'P'; quando
vengono caricati, il caricatore di moduli del
kernel si rifiuterà di collegare questi
moduli ai simboli che sono stati esportati
con EXPORT_SYMBOL_GPL().
============================= =============================================
@@ -0,0 +1,24 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
:Original: Documentation/process/maintainer-handbooks.rst
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_maintainer_handbooks_main:
Note sul processo di sviluppo dei sottosistemi e dei sorgenti dei manutentori
=============================================================================
Lo scopo di questo documento è quello di fornire informazioni sul processo di
sviluppo dedicate ai sottosistemi che vanno ad integrare quelle più generali
descritte in :ref:`Documentation/translations/it_IT/process
<it_development_process_main>`.
Indice:
.. toctree::
:numbered:
:maxdepth: 2
maintainer-tip
@@ -0,0 +1,941 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/maintainer-pgp-guide.rst <pgpguide>`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_pgpguide:
=========================================
La guida a PGP per manutentori del kernel
=========================================
:Author: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Questo documento è destinato agli sviluppatori del kernel Linux, in particolar
modo ai manutentori. Contiene degli approfondimenti riguardo informazioni che
sono state affrontate in maniera più generale nella sezione
"`Protecting Code Integrity`_" pubblicata dalla Linux Foundation.
Per approfondire alcuni argomenti trattati in questo documento è consigliato
leggere il documento sopraindicato
.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md
Il ruolo di PGP nello sviluppo del kernel Linux
===============================================
PGP aiuta ad assicurare l'integrità del codice prodotto dalla comunità
di sviluppo del kernel e, in secondo luogo, stabilisce canali di comunicazione
affidabili tra sviluppatori attraverso lo scambio di email firmate con PGP.
Il codice sorgente del kernel Linux è disponibile principalmente in due
formati:
- repositori distribuiti di sorgenti (git)
- rilasci periodici di istantanee (archivi tar)
Sia i repositori git che gli archivi tar portano le firme PGP degli
sviluppatori che hanno creato i rilasci ufficiali del kernel. Queste firme
offrono una garanzia crittografica che le versioni scaricabili rese disponibili
via kernel.org, o altri portali, siano identiche a quelle che gli sviluppatori
hanno sul loro posto di lavoro. A tal scopo:
- i repositori git forniscono firme PGP per ogni tag
- gli archivi tar hanno firme separate per ogni archivio
.. _it_devs_not_infra:
Fidatevi degli sviluppatori e non dell'infrastruttura
-----------------------------------------------------
Fin dal 2011, quando i sistemi di kernel.org furono compromessi, il principio
generale del progetto Kernel Archives è stato quello di assumere che qualsiasi
parte dell'infrastruttura possa essere compromessa in ogni momento. Per questa
ragione, gli amministratori hanno intrapreso deliberatemene dei passi per
enfatizzare che la fiducia debba risiedere sempre negli sviluppatori e mai nel
codice che gestisce l'infrastruttura, indipendentemente da quali che siano le
pratiche di sicurezza messe in atto.
Il principio sopra indicato è la ragione per la quale è necessaria questa
guida. Vogliamo essere sicuri che il riporre la fiducia negli sviluppatori
non sia fatto semplicemente per incolpare qualcun'altro per future falle di
sicurezza. L'obiettivo è quello di fornire una serie di linee guida che gli
sviluppatori possano seguire per creare un ambiente di lavoro sicuro e
salvaguardare le chiavi PGP usate nello stabilire l'integrità del kernel Linux
stesso.
.. _it_pgp_tools:
Strumenti PGP
=============
Usare GnuPG 2.2 o successivo
----------------------------
La vostra distribuzione potrebbe avere già installato GnuPG, dovete solo
verificare che stia utilizzando la versione abbastanza recente. Per controllate
usate::
$ gpg --version | head -n1
Se state utilizzando la version 2.2 o successiva, allora siete pronti a partire.
Se invece state usando una versione precedente, allora alcuni comandi elencati
in questa guida potrebbero non funzionare.
Configurare le opzioni di gpg-agent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
L'agente GnuPG è uno strumento di aiuto che partirà automaticamente ogni volta
che userete il comando ``gpg`` e funzionerà in *background* con l'obiettivo di
individuare la passphrase. Ci sono due opzioni che dovreste conoscere
per personalizzare la scadenza della passphrase nella cache:
- ``default-cache-ttl`` (secondi): Se usate ancora la stessa chiave prima
che il time-to-live termini, il conto alla rovescia si resetterà per un
altro periodo. Di base è di 600 (10 minuti).
- ``max-cache-ttl`` (secondi): indipendentemente da quanto sia recente l'ultimo
uso della chiave da quando avete inserito la passphrase, se il massimo
time-to-live è scaduto, dovrete reinserire nuovamente la passphrase.
Di base è di 30 minuti.
Se ritenete entrambe questi valori di base troppo corti (o troppo lunghi),
potete creare il vostro file ``~/.gnupg/gpg-agent.conf`` ed impostare i vostri
valori::
# set to 30 minutes for regular ttl, and 2 hours for max ttl
default-cache-ttl 1800
max-cache-ttl 7200
.. note::
Non è più necessario far partire l'agente gpg manualmente all'inizio della
vostra sessione. Dovreste controllare i file rc per rimuovere tutto ciò che
riguarda vecchie le versioni di GnuPG, poiché potrebbero non svolgere più
bene il loro compito.
.. _it_protect_your_key:
Proteggere la vostra chiave PGP primaria
========================================
Questa guida parte dal presupposto che abbiate già una chiave PGP che usate
per lo sviluppo del kernel Linux. Se non ne avete ancora una, date uno sguardo
al documento "`Protecting Code Integrity`_" che abbiamo menzionato prima.
Dovreste inoltre creare una nuova chiave se quella attuale è inferiore a 2048
bit (RSA).
Le sottochiavi PGP
------------------
Raramente le chiavi PGP sono composte da una singola coppia -- solitamente, sono
una collezione di sottochiavi indipendenti usate per diversi scopi in funzione
delle capacità assegnate al momento della creazione. Una chiave PGP può avere
quattro capacità:
- **[S]** può essere usata per firmare
- **[E]** può essere usata per criptare
- **[A]** può essere usata per autenticare
- **[C]** può essere usata per certificare altre chiavi
La chiave con la capacità **[C]** viene spesso chiamata chiave "passepartout"
(*master key*), ma è una terminologia fuorviante perché lascia intendere che la
chiave di certificato possa essere usate in sostituzione delle altre (proprio
come le vere chiavi passpartout in grado di aprire diverse serrature). Dato che
questo non è il caso, per evitare fraintendimenti, in questa guida ci riferiremo
a questa chiave chiamandola "La chiave di certificazione".
I seguenti punti sono molto importanti:
1. Tutte le sottochiavi sono indipendenti. Se perdete una sottochiave privata
non potrete recuperarla usando le altre.
2. Ad eccezione della chiave di certificazione, ci possono essere più
sottochiavi con le stesse capacità (per esempio, potete avere 2 sottochiavi
per criptare, 3 per firmare, ma solo una per una sola per certificare). Tutte
le sottochiavi sono indipendenti -- un messaggio criptato usando una chiave
**[E]** non può essere decriptato usano altre sottochiavi **[E]**.
3. Una sottochiave può avere più capacità (per esempio, la chiave **[C]** può
anche essere una chiave **[S]**).
La chiave con capacità **[C]** (certificazione) è la sola che può essere usata
per indicare relazioni fra chiavi. Solo la chiave **[C]** può essere usata per:
- aggiungere o revocare altre chiavi (sottochiavi) che hanno capacità S/E/A;
- aggiungere, modificare o eliminare le identità (unids) associate alla chiave;
- aggiungere o modificare la propria data di scadenza o delle sottochiavi;
- firmare le chiavi di altre persone a scopo di creare una rete di fiducia.
Di base, alla creazione di nuove chiavi, GnuPG genera quanto segue:
- Una chiave la capacità di certificazione che quella di firma (**[SC]**)
- Una sottochiave separata con capacità di criptare (**[E]**)
Se avete usato i parametri predefiniti per generare la vostra chiave, quello
sarà il risultato. Potete verificarlo utilizzando ``gpg --list-secret-keys``,
per esempio::
sec ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]
La lunga riga sotto la voce ``sec`` è la vostra impronta digitale --
negli esempi che seguono, quando vedere ``[fpr]`` ci si riferisce a questa
stringa di 40 caratteri.
Assicuratevi che la vostra passphrase sia forte
-----------------------------------------------
GnuPG utilizza le passphrases per criptare la vostra chiave privata prima
di salvarla sul disco. In questo modo, anche se il contenuto della vostra
cartella ``.gnupg`` venisse letto o trafugato nella sia interezza, gli
attaccanti non potrebbero comunque utilizzare le vostre chiavi private senza
aver prima ottenuto la passphrase per decriptarle.
È assolutamente essenziale che le vostre chiavi private siano protette da
una passphrase forte. Per impostarla o cambiarla, usate::
$ gpg --change-passphrase [fpr]
Create una sottochiave di firma separata
----------------------------------------
Il nostro obiettivo è di proteggere la chiave primaria spostandola su un
dispositivo sconnesso dalla rete, dunque se avete solo una chiave combinata
**[SC]** allora dovreste creare una sottochiave di firma separata::
$ gpg --quick-add-key [fpr] ed25519 sign
Ricordate di informare il keyserver del vostro cambiamento, cosicché altri
possano ricevere la vostra nuova sottochiave::
$ gpg --send-key [fpr]
.. note:: Supporto ECC in GnuPG
Tenete presente che se avete intenzione di usare un dispositivo che non
supporta chiavi ED25519 ECC, allora dovreste usare "nistp256" al posto di
"ed25519". Più avanti ci sono alcune raccomandazioni per i dispositivi.
Copia di riserva della chiave primaria per gestire il recupero da disastro
--------------------------------------------------------------------------
Maggiori sono le firme di altri sviluppatori che vengono applicate alla vostra,
maggiori saranno i motivi per avere una copia di riserva che non sia digitale,
al fine di effettuare un recupero da disastro.
Il modo migliore per creare una copia fisica della vostra chiave privata è
l'uso del programma ``paperkey``. Consultate ``man paperkey`` per maggiori
dettagli sul formato dell'output ed i suoi punti di forza rispetto ad altre
soluzioni. Paperkey dovrebbe essere già pacchettizzato per la maggior parte
delle distribuzioni.
Eseguite il seguente comando per creare una copia fisica di riserva della
vostra chiave privata::
$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt
Stampate il file (o fate un pipe direttamente verso lpr), poi prendete
una penna e scrivete la passphare sul margine del foglio. **Questo è
caldamente consigliato** perché la copia cartacea è comunque criptata con
la passphrase, e se mai doveste cambiarla non vi ricorderete qual'era al
momento della creazione di quella copia -- *garantito*.
Mettete la copia cartacea e la passphrase scritta a mano in una busta e
mettetela in un posto sicuro e ben protetto, preferibilmente fuori casa,
magari in una cassetta di sicurezza in banca.
.. note::
Probabilmente la vostra stampante non è più quello stupido dispositivo
connesso alla porta parallela, ma dato che il suo output è comunque
criptato con la passphrase, eseguire la stampa in un sistema "cloud"
moderno dovrebbe essere comunque relativamente sicuro.
Copia di riserva di tutta la cartella GnuPG
-------------------------------------------
.. warning::
**!!!Non saltate questo passo!!!**
Quando avete bisogno di recuperare le vostre chiavi PGP è importante avere
una copia di riserva pronta all'uso. Questo sta su un diverso piano di
prontezza rispetto al recupero da disastro che abbiamo risolto con
``paperkey``. Vi affiderete a queste copie esterne quando dovreste usare la
vostra chiave Certify -- ovvero quando fate modifiche alle vostre chiavi o
firmate le chiavi di altre persone ad una conferenza o ad un gruppo d'incontro.
Incominciate con una piccola chiavetta di memoria USB (preferibilmente due)
che userete per le copie di riserva. Dovrete criptarle usando LUKS -- fate
riferimento alla documentazione della vostra distribuzione per capire come
fare.
Per la passphrase di criptazione, potete usare la stessa della vostra chiave
primaria.
Una volta che il processo di criptazione è finito, reinserite il disco USB ed
assicurativi che venga montato correttamente. Copiate interamente la cartella
``.gnugp`` nel disco criptato::
$ cp -a ~/.gnupg /media/disk/foo/gnupg-backup
Ora dovreste verificare che tutto continui a funzionare::
$ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]
Se non vedete errori, allora dovreste avere fatto tutto con successo.
Smontate il disco USB, etichettatelo per bene di modo da evitare di
distruggerne il contenuto non appena vi serve una chiavetta USB a caso, ed
infine mettetelo in un posto sicuro -- ma non troppo lontano, perché vi servirà
di tanto in tanto per modificare le identità, aggiungere o revocare
sottochiavi, o firmare le chiavi di altre persone.
Togliete la chiave primaria dalla vostra home
---------------------------------------------
I file che si trovano nella vostra cartella home non sono poi così ben protetti
come potreste pensare. Potrebbero essere letti o trafugati in diversi modi:
- accidentalmente quando fate una rapida copia della cartella home per
configurare una nuova postazione
- da un amministratore di sistema negligente o malintenzionato
- attraverso copie di riserva insicure
- attraverso malware installato in alcune applicazioni (browser, lettori PDF,
eccetera)
- attraverso coercizione quando attraversate confini internazionali
Proteggere la vostra chiave con una buona passphare aiuta notevolmente a
ridurre i rischi elencati qui sopra, ma le passphrase possono essere scoperte
attraverso i keylogger, il shoulder-surfing, o altri modi. Per questi motivi,
nella configurazione si raccomanda di rimuove la chiave primaria dalla vostra
cartella home e la si archivia su un dispositivo disconnesso.
.. warning::
Per favore, fate riferimento alla sezione precedente e assicuratevi
di aver fatto una copia di riserva totale della cartella GnuPG. Quello
che stiamo per fare renderà la vostra chiave inutile se non avete delle
copie di riserva utilizzabili!
Per prima cosa, identificate il keygrip della vostra chiave primaria::
$ gpg --with-keygrip --list-key [fpr]
L'output assomiglierà a questo::
pub ed25519 2022-12-20 [SC] [expires: 2022-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
Keygrip = 1111000000000000000000000000000000000000
uid [ultimate] Alice Dev <adev@kernel.org>
sub cv25519 2022-12-20 [E] [expires: 2022-12-19]
Keygrip = 2222000000000000000000000000000000000000
sub ed25519 2022-12-20 [S]
Keygrip = 3333000000000000000000000000000000000000
Trovate la voce keygrid che si trova sotto alla riga ``pub`` (appena sotto
all'impronta digitale della chiave primaria). Questo corrisponderà direttamente
ad un file nella cartella ``~/.gnupg``::
$ cd ~/.gnupg/private-keys-v1.d
$ ls
1111000000000000000000000000000000000000.key
2222000000000000000000000000000000000000.key
3333000000000000000000000000000000000000.key
Quello che dovrete fare è rimuovere il file .key che corrisponde al keygrip
della chiave primaria::
$ cd ~/.gnupg/private-keys-v1.d
$ rm 1111000000000000000000000000000000000000.key
Ora, se eseguite il comando ``--list-secret-keys``, vedrete che la chiave
primaria non compare più (il simbolo ``#`` indica che non è disponibile)::
$ gpg --list-secret-keys
sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb ed25519 2022-12-20 [S]
Dovreste rimuovere anche i file ``secring.gpg`` che si trovano nella cartella
``~/.gnupg``, in quanto rimasugli delle versioni precedenti di GnuPG.
Se non avete la cartella "private-keys-v1.d"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Se non avete la cartella ``~/.gnupg/private-keys-v1.d``, allora le vostre
chiavi segrete sono ancora salvate nel vecchio file ``secring.gpg`` usato
da GnuPG v1. Effettuare una qualsiasi modifica alla vostra chiave, come
cambiare la passphare o aggiungere una sottochiave, dovrebbe convertire
automaticamente il vecchio formato ``secring.gpg``nel nuovo
``private-keys-v1.d``.
Una volta che l'avete fatto, assicuratevi di rimuovere il file ``secring.gpg``,
che continua a contenere la vostra chiave privata.
.. _it_smartcards:
Spostare le sottochiavi in un apposito dispositivo criptato
===========================================================
Nonostante la chiave primaria sia ora al riparo da occhi e mani indiscrete,
le sottochiavi si trovano ancora nella vostra cartella home. Chiunque riesca
a mettere le sue mani su quelle chiavi riuscirà a decriptare le vostre
comunicazioni o a falsificare le vostre firme (se conoscono la passphrase).
Inoltre, ogni volta che viene fatta un'operazione con GnuPG, le chiavi vengono
caricate nella memoria di sistema e potrebbero essere rubate con l'uso di
malware sofisticati (pensate a Meltdown e a Spectre).
Il miglior modo per proteggere le proprie chiave è di spostarle su un
dispositivo specializzato in grado di effettuare operazioni smartcard.
I benefici di una smartcard
---------------------------
Una smartcard contiene un chip crittografico che è capace di immagazzinare
le chiavi private ed effettuare operazioni crittografiche direttamente sulla
carta stessa. Dato che la chiave non lascia mai la smartcard, il sistema
operativo usato sul computer non sarà in grado di accedere alle chiavi.
Questo è molto diverso dai dischi USB criptati che abbiamo usato allo scopo di
avere una copia di riserva sicura -- quando il dispositivo USB è connesso e
montato, il sistema operativo potrà accedere al contenuto delle chiavi private.
L'uso di un disco USB criptato non può sostituire le funzioni di un dispositivo
capace di operazioni di tipo smartcard.
Dispositivi smartcard disponibili
---------------------------------
A meno che tutti i vostri computer dispongano di lettori smartcard, il modo
più semplice è equipaggiarsi di un dispositivo USB specializzato che
implementi le funzionalità delle smartcard. Sul mercato ci sono diverse
soluzioni disponibili:
- `Nitrokey Start`_: è Open hardware e Free Software, è basata sul progetto
`GnuK`_ della FSIJ. Questo è uno dei pochi dispositivi a supportare le chiavi
ECC ED25519, ma offre meno funzionalità di sicurezza (come la resistenza
alla manomissione o alcuni attacchi ad un canale laterale).
- `Nitrokey Pro 2`_: è simile alla Nitrokey Start, ma è più resistente alla
manomissione e offre più funzionalità di sicurezza. La Pro 2 supporta la
crittografia ECC (NISTP).
- `Yubikey 5`_: l'hardware e il software sono proprietari, ma è più economica
della Nitrokey Pro ed è venduta anche con porta USB-C il che è utile con i
computer portatili più recenti. In aggiunta, offre altre funzionalità di
sicurezza come FIDO, U2F, e ora supporta anche le chiavi ECC (NISTP)
La vostra scelta dipenderà dal costo, la disponibilità nella vostra regione, e
sulla scelta fra dispositivi aperti e proprietari.
.. note::
Se siete nella lista MAINTAINERS o avete un profilo su kernel.org, allora
`potrete avere gratuitamente una Nitrokey Start`_ grazie alla fondazione
Linux.
.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nitrokey-pro-2-3
.. _`Yubikey 5`: https://www.yubico.com/product/yubikey-5-overview/
.. _Gnuk: https://www.fsij.org/doc-gnuk/
.. _`potrete avere gratuitamente una Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html
Configurare il vostro dispositivo smartcard
-------------------------------------------
Il vostro dispositivo smartcard dovrebbe iniziare a funzionare non appena
lo collegate ad un qualsiasi computer Linux moderno. Potete verificarlo
eseguendo::
$ gpg --card-status
Se vedete tutti i dettagli della smartcard, allora ci siamo. Sfortunatamente,
affrontare tutti i possibili motivi per cui le cose potrebbero non funzionare
non è lo scopo di questa guida. Se avete problemi nel far funzionare la carta
con GnuPG, cercate aiuto attraverso i soliti canali di supporto.
Per configurare la vostra smartcard, dato che non c'è una via facile dalla
riga di comando, dovrete usate il menu di GnuPG::
$ gpg --card-edit
[...omitted...]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
Dovreste impostare il PIN dell'utente (1), quello dell'amministratore (3) e il
codice di reset (4). Assicuratevi di annotare e salvare questi codici in un
posto sicuro -- specialmente il PIN dell'amministratore e il codice di reset
(che vi permetterà di azzerare completamente la smartcard). Il PIN
dell'amministratore viene usato così raramente che è inevitabile dimenticarselo
se non lo si annota.
Tornando al nostro menu, potete impostare anche altri valori (come il nome,
il sesso, informazioni d'accesso, eccetera), ma non sono necessari e aggiunge
altre informazioni sulla carta che potrebbero trapelare in caso di smarrimento.
.. note::
A dispetto del nome "PIN", né il PIN utente né quello dell'amministratore
devono essere esclusivamente numerici.
.. warning::
Alcuni dispositivi richiedono la presenza delle sottochiavi nel dispositivo
stesso prima che possiate cambiare la passphare. Verificate la
documentazione del produttore.
Spostare le sottochiavi sulla smartcard
---------------------------------------
Uscite dal menu (usando "q") e salverete tutte le modifiche. Poi, spostiamo
tutte le sottochiavi sulla smartcard. Per la maggior parte delle operazioni
vi serviranno sia la passphrase della chiave PGP che il PIN
dell'amministratore::
$ gpg --edit-key [fpr]
Secret subkeys are available.
pub ed25519/AAAABBBBCCCCDDDD
created: 2022-12-20 expires: 2024-12-19 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/1111222233334444
created: 2022-12-20 expires: never usage: E
ssb ed25519/5555666677778888
created: 2017-12-07 expires: never usage: S
[ultimate] (1). Alice Dev <adev@kernel.org>
gpg>
Usando ``--edit-key`` si tornerà alla modalità menu e noterete che
la lista delle chiavi è leggermente diversa. Da questo momento in poi,
tutti i comandi saranno eseguiti nella modalità menu, come indicato
da ``gpg>``.
Per prima cosa, selezioniamo la chiave che verrà messa sulla carta --
potete farlo digitando ``key 1`` (è la prima della lista, la sottochiave
**[E]**)::
gpg> key 1
Nel'output dovreste vedere ``ssb*`` associato alla chiave **[E]**. Il simbolo
``*`` indica che la chiave è stata "selezionata". Funziona come un
interruttore, ovvero se scrivete nuovamente ``key 1``, il simbolo ``*`` sparirà
e la chiave non sarà più selezionata.
Ora, spostiamo la chiave sulla smartcard::
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
Dato che è la nostra chiave **[E]**, ha senso metterla nella sezione criptata.
Quando confermerete la selezione, vi verrà chiesta la passphrase della vostra
chiave PGP, e poi il PIN dell'amministratore. Se il comando ritorna senza
errori, allora la vostra chiave è stata spostata con successo.
**Importante**: digitate nuovamente ``key 1`` per deselezionare la prima chiave
e selezionate la seconda chiave **[S]** con ``key 2``::
gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
Potete usare la chiave **[S]** sia per firmare che per autenticare, ma vogliamo
che sia nella sezione di firma, quindi scegliete (1). Ancora una volta, se il
comando ritorna senza errori, allora l'operazione è avvenuta con successo::
gpg> q
Save changes? (y/N) y
Salvando le modifiche cancellerete dalla vostra cartella home tutte le chiavi
che avete spostato sulla carta (ma questo non è un problema, perché abbiamo
fatto delle copie di sicurezza nel caso in cui dovessimo configurare una
nuova smartcard).
Verificare che le chiavi siano state spostate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ora, se doveste usare l'opzione ``--list-secret-keys``, vedrete una
sottile differenza nell'output::
$ gpg --list-secret-keys
sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19]
000000000000000000000000AAAABBBBCCCCDDDD
uid [ultimate] Alice Dev <adev@kernel.org>
ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb> ed25519 2022-12-20 [S]
Il simbolo ``>`` in ``ssb>`` indica che la sottochiave è disponibile solo
nella smartcard. Se tornate nella vostra cartella delle chiavi segrete e
guardate al suo contenuto, noterete che i file ``.key`` sono stati sostituiti
con degli stub::
$ cd ~/.gnupg/private-keys-v1.d
$ strings *.key | grep 'private-key'
Per indicare che i file sono solo degli stub e che in realtà il contenuto è
sulla smartcard, l'output dovrebbe mostrarvi ``shadowed-private-key``.
Verificare che la smartcard funzioni
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Per verificare che la smartcard funzioni come dovuto, potete creare
una firma::
$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
$ gpg --verify /tmp/test.asc
Col primo comando dovrebbe chiedervi il PIN della smartcard, e poi dovrebbe
mostrare "Good signature" dopo l'esecuzione di ``gpg --verify``.
Complimenti, siete riusciti a rendere estremamente difficile il furto della
vostra identità digitale di sviluppatore.
Altre operazioni possibili con GnuPG
------------------------------------
Segue un breve accenno ad alcune delle operazioni più comuni che dovrete
fare con le vostre chiavi PGP.
Montare il disco con la chiave primaria
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vi servirà la vostra chiave principale per tutte le operazioni che seguiranno,
per cui per prima cosa dovrete accedere ai vostri backup e dire a GnuPG di
usarli::
$ export GNUPGHOME=/media/disk/foo/gnupg-backup
$ gpg --list-secret-keys
Dovete assicurarvi di vedere ``sec`` e non ``sec#`` nell'output del programma
(il simbolo ``#`` significa che la chiave non è disponibile e che state ancora
utilizzando la vostra solita cartella di lavoro).
Estendere la data di scadenza di una chiave
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
La chiave principale ha una data di scadenza di 2 anni dal momento della sua
creazione. Questo per motivi di sicurezza e per rendere obsolete le chiavi
che, eventualmente, dovessero sparire dai keyserver.
Per estendere di un anno, dalla data odierna, la scadenza di una vostra chiave,
eseguite::
$ gpg --quick-set-expire [fpr] 1y
Se per voi è più facile da memorizzare, potete anche utilizzare una data
specifica (per esempio, il vostro compleanno o capodanno)::
$ gpg --quick-set-expire [fpr] 2025-07-01
Ricordatevi di inviare l'aggiornamento ai keyserver::
$ gpg --send-key [fpr]
Aggiornare la vostra cartella di lavoro dopo ogni modifica
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dopo aver fatto delle modifiche alle vostre chiavi usando uno spazio a parte,
dovreste importarle nella vostra cartella di lavoro abituale::
$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME
Usare gpg-agent con ssh
~~~~~~~~~~~~~~~~~~~~~~~
Se dovete firmare tag o commit su un sistema remoto, potete ridirezionare il
vostro gpg-agent attraverso ssh. Consultate le istruzioni disponibili nella wiki
GnuPG:
- `Agent Forwarding over SSH`_
Funziona senza troppi intoppi se avete la possibilità di modificare le
impostazioni di sshd sul sistema remoto.
.. _`Agent Forwarding over SSH`: https://wiki.gnupg.org/AgentForwarding
.. _it_pgp_with_git:
Usare PGP con Git
=================
Una delle caratteristiche fondanti di Git è la sua natura decentralizzata --
una volta che il repositorio è stato clonato sul vostro sistema, avete la
storia completa del progetto, inclusi i suoi tag, i commit ed i rami. Tuttavia,
con i centinaia di repositori clonati che ci sono in giro, come si fa a
verificare che la loro copia di linux.git non è stata manomessa da qualcuno?
Oppure, cosa succede se viene scoperta una backdoor nel codice e la riga
"Autore" dice che sei stato tu, mentre tu sei abbastanza sicuro di
`non averci niente a che fare`_?
Per risolvere entrambi i problemi, Git ha introdotto l'integrazione con PGP.
I tag firmati dimostrano che il repositorio è integro assicurando che il suo
contenuto è lo stesso che si trova sulle macchine degli sviluppatori che hanno
creato il tag; mentre i commit firmati rendono praticamente impossibile
ad un malintenzionato di impersonarvi senza avere accesso alle vostre chiavi
PGP.
.. _`non averci niente a che fare`: https://github.com/jayphelps/git-blame-someone-else
Configurare git per usare la vostra chiave PGP
----------------------------------------------
Se avete solo una chiave segreta nel vostro portachiavi, allora non avete nulla
da fare in più dato che sarà la vostra chiave di base. Tuttavia, se doveste
avere più chiavi segrete, potete dire a git quale dovrebbe usare (``[fpg]``
è la vostra impronta digitale)::
$ git config --global user.signingKey [fpr]
Come firmare i tag
------------------
Per creare un tag firmato, passate l'opzione ``-s`` al comando tag::
$ git tag -s [tagname]
La nostra raccomandazione è quella di firmare sempre i tag git, perché
questo permette agli altri sviluppatori di verificare che il repositorio
git dal quale stanno prendendo il codice non è stato alterato intenzionalmente.
Come verificare i tag firmati
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Per verificare un tag firmato, potete usare il comando ``verify-tag``::
$ git verify-tag [tagname]
Se state prendendo un tag da un fork del repositorio del progetto, git
dovrebbe verificare automaticamente la firma di quello che state prendendo
e vi mostrerà il risultato durante l'operazione di merge::
$ git pull [url] tags/sometag
Il merge conterrà qualcosa di simile::
Merge tag 'sometag' of [url]
[Tag message]
# gpg: Signature made [...]
# gpg: Good signature from [...]
Se state verificando il tag di qualcun altro, allora dovrete importare
la loro chiave PGP. Fate riferimento alla sezione ":ref:`it_verify_identities`"
che troverete più avanti.
Configurare git per firmare sempre i tag con annotazione
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Se state creando un tag con annotazione è molto probabile che vogliate
firmarlo. Per imporre a git di firmare sempre un tag con annotazione,
dovete impostare la seguente opzione globale::
$ git config --global tag.forceSignAnnotated true
Come usare commit firmati
-------------------------
Creare dei commit firmati è facile, ma è molto più difficile utilizzarli
nello sviluppo del kernel linux per via del fatto che ci si affida alle
liste di discussione e questo modo di procedere non mantiene le firme PGP
nei commit. In aggiunta, quando si usa *rebase* nel proprio repositorio
locale per allinearsi al kernel anche le proprie firme PGP verranno scartate.
Per questo motivo, la maggior parte degli sviluppatori del kernel non si
preoccupano troppo di firmare i propri commit ed ignoreranno quelli firmati
che si trovano in altri repositori usati per il proprio lavoro.
Tuttavia, se avete il vostro repositorio di lavoro disponibile al pubblico
su un qualche servizio di hosting git (kernel.org, infradead.org, ozlabs.org,
o altri), allora la raccomandazione è di firmare tutti i vostri commit
anche se gli sviluppatori non ne beneficeranno direttamente.
Vi raccomandiamo di farlo per i seguenti motivi:
1. Se dovesse mai esserci la necessità di fare delle analisi forensi o
tracciare la provenienza di un codice, anche sorgenti mantenuti
esternamente che hanno firme PGP sui commit avranno un certo valore a
questo scopo.
2. Se dovesse mai capitarvi di clonare il vostro repositorio locale (per
esempio dopo un danneggiamento del disco), la firma vi permetterà di
verificare l'integrità del repositorio prima di riprendere il lavoro.
3. Se qualcuno volesse usare *cherry-pick* sui vostri commit, allora la firma
permetterà di verificare l'integrità dei commit prima di applicarli.
Creare commit firmati
~~~~~~~~~~~~~~~~~~~~~
Per creare un commit firmato, dovete solamente aggiungere l'opzione ``-S``
al comando ``git commit`` (si usa la lettera maiuscola per evitare
conflitti con un'altra opzione)::
$ git commit -S
Configurare git per firmare sempre i commit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Potete dire a git di firmare sempre i commit::
git config --global commit.gpgSign true
.. note::
Assicuratevi di aver configurato ``gpg-agent`` prima di abilitare
questa opzione.
.. _it_verify_identities:
Come lavorare con patch firmate
-------------------------------
Esiste la possibilità di usare la vostra chiave PGP per firmare le patch che
invierete alla liste di discussione del kernel. I meccanismi esistenti per la
firma delle email (PGP-Mime o PGP-inline) tendono a causare problemi
nell'attività di revisione del codice. Si suggerisce, invece, di utilizare lo
strumento sviluppato da kernel.org che mette nell'intestazione del messaggio
un'attestazione delle firme crittografiche (tipo DKIM):
- `Patatt Patch Attestation`_
.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/
Installare e configurate patatt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lo strumento patatt è disponibile per diverse distribuzioni, dunque cercatelo
prima lì. Oppure potete installarlo usano pypi "``pip install patatt``"
Se avete già configurato git con la vostra chiave PGP (usando
``user.signingKey``), allora patatt non ha bisogno di alcuna configurazione
aggiuntiva. Potete iniziare a firmare le vostre patch aggiungendo un aggancio a
git-send-email nel vostro repositorio::
patatt install-hook
Ora, qualsiasi patch che invierete con ``git send-email`` verrà automaticamente
firmata usando la vostra firma crittografica.
Verificare le firme di patatt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Se usate ``b4`` per verificare ed applicare le patch, allora tenterà
automaticamente di verificare tutte le firme DKIM e patatt disponibili. Per
esempio::
$ b4 am 20220720205013.890942-1-broonie@kernel.org
[...]
Checking attestation on all messages, may take a moment...
---
✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers
✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall
✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls
---
✓ Signed: openpgp/broonie@kernel.org
✓ Signed: DKIM/kernel.org
.. note::
Lo sviluppo di patatt e b4 è piuttosto attivo. Si consiglia di verificare la
documentazione più recente.
.. _it_kernel_identities:
Come verificare l'identità degli sviluppatori del kernel
========================================================
Firmare i tag e i commit è facile, ma come si fa a verificare che la chiave
usata per firmare qualcosa appartenga davvero allo sviluppatore e non ad un
impostore?
Configurare l'auto-key-retrieval usando WKD e DANE
--------------------------------------------------
Se non siete ancora in possesso di una vasta collezione di chiavi pubbliche
di altri sviluppatori, allora potreste iniziare il vostro portachiavi
affidandovi ai servizi di auto-scoperta e auto-recupero. GnuPG può affidarsi
ad altre tecnologie di delega della fiducia, come DNSSEC e TLS, per sostenervi
nel caso in cui iniziare una propria rete di fiducia da zero sia troppo
scoraggiante.
Aggiungete il seguente testo al vostro file ``~/.gnupg/gpg.conf``::
auto-key-locate wkd,dane,local
auto-key-retrieve
La *DNS-Based Authentication of Named Entities* ("DANE") è un metodo
per la pubblicazione di chiavi pubbliche su DNS e per renderle sicure usando
zone firmate con DNSSEC. Il *Web Key Directory* ("WKD") è un metodo
alternativo che usa https a scopo di ricerca. Quando si usano DANE o WKD
per la ricerca di chiavi pubbliche, GnuPG validerà i certificati DNSSEC o TLS
prima di aggiungere al vostro portachiavi locale le eventuali chiavi trovate.
Kernel.org pubblica la WKD per tutti gli sviluppatori che hanno un account
kernel.org. Una volta che avete applicato le modifiche al file ``gpg.conf``,
potrete auto-recuperare le chiavi di Linus Torvalds e Greg Kroah-Hartman
(se non le avete già)::
$ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org
Se avete un account kernel.org, al fine di rendere più utile l'uso di WKD
da parte di altri sviluppatori del kernel, dovreste `aggiungere alla vostra
chiave lo UID di kernel.org`_.
.. _`aggiungere alla vostra chiave lo UID di kernel.org`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key
Web of Trust (WOT) o Trust on First Use (TOFU)
----------------------------------------------
PGP incorpora un meccanismo di delega della fiducia conosciuto come
"Web of Trust". Di base, questo è un tentativo di sostituire la necessità
di un'autorità certificativa centralizzata tipica del mondo HTTPS/TLS.
Invece di avere svariati produttori software che decidono chi dovrebbero
essere le entità di certificazione di cui dovreste fidarvi, PGP lascia
la responsabilità ad ogni singolo utente.
Sfortunatamente, solo poche persone capiscono come funziona la rete di fiducia.
Nonostante sia un importante aspetto della specifica OpenPGP, recentemente
le versioni di GnuPG (2.2 e successive) hanno implementato un meccanisco
alternativo chiamato "Trust on First Use" (TOFU). Potete pensare a TOFU come
"ad un approccio all fidicia simile ad SSH". In SSH, la prima volta che vi
connettete ad un sistema remoto, l'impronta digitale della chiave viene
registrata e ricordata. Se la chiave dovesse cambiare in futuro, il programma
SSH vi avviserà e si rifiuterà di connettersi, obbligandovi a prendere una
decisione circa la fiducia che riponete nella nuova chiave. In modo simile,
la prima volta che importate la chiave PGP di qualcuno, si assume sia valida.
Se ad un certo punto GnuPG trova un'altra chiave con la stessa identità,
entrambe, la vecchia e la nuova, verranno segnate come invalide e dovrete
verificare manualmente quale tenere.
Vi raccomandiamo di usare il meccanisco TOFU+PGP (che è la nuova configurazione
di base di GnuPG v2). Per farlo, aggiungete (o modificate) l'impostazione
``trust-model`` in ``~/.gnupg/gpg.conf``::
trust-model tofu+pgp
Usare il repositorio kernel.org per il web of trust
---------------------------------------------------
Il progetto kernel.org mantiene un repositorio git con le chiavi pubbliche degli sviluppatori in alternativa alla replica dei server di chiavi che negli ultimi anni sono spariti. La documentazione completa su come impostare il repositorio come vostra sorgente di chiavi pubbliche può essere trovato qui:
- `Kernel developer PGP Keyring`_
Se siete uno sviluppatore del kernel, per favore valutate l'idea di inviare la
vostra chiave per l'inclusione in quel portachiavi.
If you are a kernel developer, please consider submitting your key for
inclusion into that keyring.
.. _`Kernel developer PGP Keyring`: https://korg.docs.kernel.org/pgpkeys.html
@@ -0,0 +1,10 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
:Original: Documentation/process/maintainer-tip.rst
Il tascabile dei sorgenti tip
=============================
.. note:: To be translated
@@ -0,0 +1,13 @@
:Original: Documentation/process/maintainers.rst
Lista dei manutentori e come inviare modifiche al kernel
========================================================
Questa pagina non verrà tradotta. Fate riferimento alla versione originale in
inglese.
.. note:: La pagina originale usa una direttiva speciale per integrare il file
`MAINTAINERS` in sphinx. La parte di quel documento che si potrebbe
tradurre contiene comunque informazioni già presenti in
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst
<it_submittingpatches>`.
@@ -0,0 +1,295 @@
.. include:: ../disclaimer-ita.rst
:Original: :doc:`../../../process/management-style`
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
.. _it_managementstyle:
Il modello di gestione del kernel Linux
=======================================
Questo breve documento descrive il modello di gestione del kernel Linux.
Per certi versi, esso rispecchia il documento
:ref:`translations/it_IT/process/coding-style.rst <it_codingstyle>`,
ed è principalmente scritto per evitare di rispondere [#f1]_ in continuazione
alle stesse identiche (o quasi) domande.
Il modello di gestione è qualcosa di molto personale e molto più difficile da
qualificare rispetto a delle semplici regole di codifica, quindi questo
documento potrebbe avere più o meno a che fare con la realtà. È cominciato
come un gioco, ma ciò non significa che non possa essere vero.
Lo dovrete decidere voi stessi.
In ogni caso, quando si parla del "dirigente del kernel", ci si riferisce
sempre alla persona che dirige tecnicamente, e non a coloro che
tradizionalmente hanno un ruolo direttivo all'interno delle aziende. Se vi
occupate di convalidare acquisti o avete una qualche idea sul budget del vostro
gruppo, probabilmente non siete un dirigente del kernel. Quindi i suggerimenti
qui indicati potrebbero fare al caso vostro, oppure no.
Prima di tutto, suggerirei di acquistare "Le sette regole per avere successo",
e di non leggerlo. Bruciatelo, è un grande gesto simbolico.
.. [#f1] Questo documento non fa molto per risponde alla domanda, ma rende
così dannatamente ovvio a chi la pone che non abbiamo la minima idea
di come rispondere.
Comunque, partiamo:
.. _it_decisions:
1) Le decisioni
---------------
Tutti pensano che i dirigenti decidano, e che questo prendere decisioni
sia importante. Più grande e dolorosa è la decisione, più importante deve
essere il dirigente che la prende. Questo è molto profondo ed ovvio, ma non è
del tutto vero.
Il gioco consiste nell'"evitare" di dover prendere decisioni. In particolare
se qualcuno vi chiede di "Decidere" tra (a) o (b), e vi dice che ha
davvero bisogno di voi per questo, come dirigenti siete nei guai.
Le persone che gestite devono conoscere i dettagli più di quanto li conosciate
voi, quindi se vengono da voi per una decisione tecnica, siete fottuti.
Non sarete chiaramente competente per prendere quella decisione per loro.
(Corollario: se le persone che gestite non conoscono i dettagli meglio di voi,
anche in questo caso sarete fregati, tuttavia per altre ragioni. Ossia state
facendo il lavoro sbagliato, e che invece dovrebbero essere "loro" a gestirvi)
Quindi il gioco si chiama "evitare" decisioni, almeno le più grandi e
difficili. Prendere decisioni piccoli e senza conseguenze va bene, e vi fa
sembrare competenti in quello che state facendo, quindi quello che un dirigente
del kernel ha bisogno di fare è trasformare le decisioni grandi e difficili
in minuzie delle quali nessuno importa.
Ciò aiuta a capire che la differenza chiave tra una grande decisione ed una
piccola sta nella possibilità di modificare tale decisione in seguito.
Qualsiasi decisione importante può essere ridotta in decisioni meno importanti,
ma dovete assicurarvi che possano essere reversibili in caso di errori
(presenti o futuri). Improvvisamente, dovrete essere doppiamente dirigenti
per **due** decisioni non sequenziali - quella sbagliata **e** quella giusta.
E le persone vedranno tutto ciò come prova di vera capacità di comando
(*cough* cavolata *cough*)
Così la chiave per evitare le decisioni difficili diviene l'evitare
di fare cose che non possono essere disfatte. Non infilatevi in un angolo
dal quale non potrete sfuggire. Un topo messo all'angolo può rivelarsi
pericoloso - un dirigente messo all'angolo è solo pietoso.
**In ogni caso** dato che nessuno è stupido al punto da lasciare veramente ad
un dirigente del kernel un enorme responsabilità, solitamente è facile fare
marcia indietro. Annullare una decisione è molto facile: semplicemente dite a
tutti che siete stati degli scemi incompetenti, dite che siete dispiaciuti, ed
annullate tutto l'inutile lavoro sul quale gli altri hanno lavorato nell'ultimo
anno. Improvvisamente la decisione che avevate preso un anno fa non era poi
così grossa, dato che può essere facilmente annullata.
È emerso che alcune persone hanno dei problemi con questo tipo di approccio,
questo per due ragioni:
- ammettere di essere degli idioti è più difficile di quanto sembri. A tutti
noi piace mantenere le apparenze, ed uscire allo scoperto in pubblico per
ammettere che ci si è sbagliati è qualcosa di davvero impegnativo.
- avere qualcuno che ti dice che ciò su cui hai lavorato nell'ultimo anno
non era del tutto valido, può rivelarsi difficile anche per un povero ed
umile ingegnere, e mentre il **lavoro** vero era abbastanza facile da
cancellare, dall'altro canto potreste aver irrimediabilmente perso la
fiducia di quell'ingegnere. E ricordate che l'"irrevocabile" era quello
che avevamo cercato di evitare fin dall'inizio, e la vostra decisione
ha finito per esserlo.
Fortunatamente, entrambe queste ragioni posso essere mitigate semplicemente
ammettendo fin dal principio che non avete una cavolo di idea, dicendo
agli altri in anticipo che la vostra decisione è puramente ipotetica, e che
potrebbe essere sbagliata. Dovreste sempre riservarvi il diritto di cambiare
la vostra opinione, e rendere gli altri ben **consapevoli** di ciò.
Ed è molto più facile ammettere di essere stupidi quando non avete **ancora**
fatto quella cosa stupida.
Poi, quando è realmente emersa la vostra stupidità, le persone semplicemente
roteeranno gli occhi e diranno "Uffa, no, ancora".
Questa ammissione preventiva di incompetenza potrebbe anche portare le persone
che stanno facendo il vero lavoro, a pensarci due volte. Dopo tutto, se
**loro** non sono certi se sia una buona idea, voi, sicuro come la morte,
non dovreste incoraggiarli promettendogli che ciò su cui stanno lavorando
verrà incluso. Fate si che ci pensino due volte prima che si imbarchino in un
grosso lavoro.
Ricordate: loro devono sapere più cose sui dettagli rispetto a voi, e
solitamente pensano di avere già la risposta a tutto. La miglior cosa che
potete fare in qualità di dirigente è di non instillare troppa fiducia, ma
invece fornire una salutare dose di pensiero critico su quanto stanno facendo.
Comunque, un altro modo di evitare una decisione è quello di lamentarsi
malinconicamente dicendo : "non possiamo farli entrambi e basta?" e con uno
sguardo pietoso. Fidatevi, funziona. Se non è chiaro quale sia il miglior
approccio, lo scopriranno. La risposta potrebbe essere data dal fatto che
entrambe i gruppi di lavoro diventano frustati al punto di rinunciarvi.
Questo può suonare come un fallimento, ma di solito questo è un segno che
c'era qualcosa che non andava in entrambe i progetti, e il motivo per
il quale le persone coinvolte non abbiano potuto decidere era che entrambe
sbagliavano. Voi ne uscirete freschi come una rosa, e avrete evitato un'altra
decisione con la quale avreste potuto fregarvi.
2) Le persone
-------------
Ci sono molte persone stupide, ed essere un dirigente significa che dovrete
scendere a patti con questo, e molto più importate, che **loro** devono avere
a che fare con **voi**.
Ne emerge che mentre è facile annullare degli errori tecnici, non è invece
così facile rimuovere i disordini della personalità. Dovrete semplicemente
convivere con i loro, ed i vostri, problemi.
Comunque, al fine di preparavi in qualità di dirigenti del kernel, è meglio
ricordare di non abbattere alcun ponte, bombardare alcun paesano innocente,
o escludere troppi sviluppatori kernel. Ne emerge che escludere le persone
è piuttosto facile, mentre includerle nuovamente è difficile. Così
"l'esclusione" immediatamente cade sotto il titolo di "non reversibile", e
diviene un no-no secondo la sezione :ref:`it_decisions`.
Esistono alcune semplici regole qui:
(1) non chiamate le persone teste di c*** (al meno, non in pubblico)
(2) imparate a scusarvi quando dimenticate la regola (1)
Il problema del punto numero 1 è che è molto facile da rispettare, dato che
è possibile dire "sei una testa di c***" in milioni di modi differenti [#f2]_,
a volte senza nemmeno pensarci, e praticamente sempre con la calda convinzione
di essere nel giusto.
E più convinti sarete che avete ragione (e diciamolo, potete chiamare
praticamente **tutti** testa di c**, e spesso **sarete** nel giusto), più
difficile sarà scusarvi successivamente.
Per risolvere questo problema, avete due possibilità:
- diventare davvero bravi nello scusarsi
- essere amabili così che nessuno finirà col sentirsi preso di mira. Siate
creativi abbastanza, e potrebbero esserne divertiti.
L'opzione dell'essere immancabilmente educati non esiste proprio. Nessuno
si fiderà di qualcuno che chiaramente sta nascondendo il suo vero carattere.
.. [#f2] Paul Simon cantava: "50 modi per lasciare il vostro amante", perché,
molto francamente, "Un milione di modi per dire ad uno sviluppatore
Testa di c***" non avrebbe funzionato. Ma sono sicuro che ci abbia
pensato.
3) Le persone II - quelle buone
-------------------------------
Mentre emerge che la maggior parte delle persone sono stupide, il corollario
a questo è il triste fatto che anche voi siete fra queste, e che mentre
possiamo tutti crogiolarci nella sicurezza di essere migliori della media
delle persone (diciamocelo, nessuno crede di essere nelle media o sotto di
essa), dovremmo anche ammettere che non siamo il "coltello più affilato" del
circondario, e che ci saranno altre persone che sono meno stupide di quanto
lo siete voi.
Molti reagiscono male davanti alle persone intelligenti. Altri le usano a
proprio vantaggio.
Assicuratevi che voi, in qualità di manutentori del kernel, siate nel secondo
gruppo. Inchinatevi dinanzi a loro perché saranno le persone che vi renderanno
il lavoro più facile. In particolare, prenderanno le decisioni per voi, che è
l'oggetto di questo gioco.
Quindi quando trovate qualcuno più sveglio di voi, prendetevela comoda.
Le vostre responsabilità dirigenziali si ridurranno in gran parte nel dire
"Sembra una buona idea - Vai", oppure "Sembra buono, ma invece circa questo e
quello?". La seconda versione in particolare è una gran modo per imparare
qualcosa di nuovo circa "questo e quello" o di sembrare **extra** dirigenziali
sottolineando qualcosa alla quale i più svegli non avevano pensato. In
entrambe i casi, vincete.
Una cosa alla quale dovete fare attenzione è che l'essere grandi in qualcosa
non si traduce automaticamente nell'essere grandi anche in altre cose. Quindi
dovreste dare una spintarella alle persone in una specifica direzione, ma
diciamocelo, potrebbero essere bravi in ciò che fanno e far schifo in tutto
il resto. La buona notizia è che le persone tendono a gravitare attorno a ciò
in cui sono bravi, quindi non state facendo nulla di irreversibile quando li
spingete verso una certa direzione, solo non spingete troppo.
4) Addossare le colpe
---------------------
Le cose andranno male, e le persone vogliono qualcuno da incolpare. Sarete voi.
Non è poi così difficile accettare la colpa, specialmente se le persone
riescono a capire che non era **tutta** colpa vostra. Il che ci porta
sulla miglior strada per assumersi la colpa: fatelo per qualcun'altro.
Vi sentirete bene nel assumervi la responsabilità, e loro si sentiranno
bene nel non essere incolpati, e coloro che hanno perso i loro 36GB di
pornografia a causa della vostra incompetenza ammetteranno a malincuore che
almeno non avete cercato di fare il furbetto.
Successivamente fate in modo che gli sviluppatori che in realtà hanno fallito
(se riuscite a trovarli) sappiano **in privato** che sono "fottuti".
Questo non per fargli sapere che la prossima volta possono evitarselo ma per
fargli capire che sono in debito. E, forse cosa più importante, sono loro che
devono sistemare la cosa. Perché, ammettiamolo, è sicuro non sarete voi a
farlo.
Assumersi la colpa è anche ciò che vi rendere dirigenti in prima battuta.
È parte di ciò che spinge gli altri a fidarsi di voi, e vi garantisce
la gloria potenziale, perché siete gli unici a dire "Ho fatto una cavolata".
E se avete seguito le regole precedenti, sarete decisamente bravi nel dirlo.
5) Le cose da evitare
---------------------
Esiste una cosa che le persone odiano più che essere chiamate "teste di c****",
ed è essere chiamate "teste di c****" con fare da bigotto. Se per il primo
caso potrete comunque scusarvi, per il secondo non ve ne verrà data nemmeno
l'opportunità. Probabilmente smetteranno di ascoltarvi anche se tutto sommato
state svolgendo un buon lavoro.
Tutti crediamo di essere migliori degli altri, il che significa che quando
qualcuno inizia a darsi delle arie, ci da **davvero** fastidio. Potreste anche
essere moralmente ed intellettualmente superiore a tutti quelli attorno a voi,
ma non cercate di renderlo ovvio per gli altri a meno che non **vogliate**
veramente far arrabbiare qualcuno [#f3]_.
Allo stesso modo evitate di essere troppo gentili e pacati. Le buone maniere
facilmente finiscono per strabordare e nascondere i problemi, e come si usa
dire, "su internet nessuno può sentire la vostra pacatezza". Usate argomenti
diretti per farvi capire, non potete sperare che la gente capisca in altro
modo.
Un po' di umorismo può aiutare a smorzare sia la franchezza che la moralità.
Andare oltre i limiti al punto d'essere ridicolo può portare dei punti a casa
senza renderlo spiacevole per i riceventi, i quali penseranno che stavate
facendo gli scemi. Può anche aiutare a lasciare andare quei blocchi mentali
che abbiamo nei confronti delle critiche.
.. [#f3] Suggerimento: i forum di discussione su internet, che non sono
collegati col vostro lavoro, sono ottimi modi per sfogare la frustrazione
verso altre persone. Di tanto in tanto scrivete messaggi offensivi col ghigno
in faccia per infiammare qualche discussione: vi sentirete purificati. Solo
cercate di non cagare troppo vicino a casa.
6) Perché io?
-------------
Dato che la vostra responsabilità principale è quella di prendervi le colpe
d'altri, e rendere dolorosamente ovvio a tutti che siete degli incompetenti,
la domanda naturale che ne segue sarà : perché dovrei fare tutto ciò?
Innanzitutto, potreste diventare o no popolari al punto da avere la fila di
ragazzine (o ragazzini, evitiamo pregiudizi o sessismo) che gridano e bussano
alla porta del vostro camerino, ma comunque **proverete** un immenso senso di
realizzazione personale dall'essere "in carica". Dimenticate il fatto che voi
state discutendo con tutti e che cercate di inseguirli il più velocemente che
potete. Tutti continueranno a pensare che voi siete la persona in carica.
È un bel lavoro se riuscite ad adattarlo a voi.
@@ -0,0 +1,68 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/programming-language.rst <programming_language>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_programming_language:
Linguaggio di programmazione
============================
Il kernel è scritto nel linguaggio di programmazione C [it-c-language]_.
Più precisamente, il kernel viene compilato con ``gcc`` [it-gcc]_ usando
l'opzione ``-std=gnu11`` [it-gcc-c-dialect-options]_: il dialetto GNU
dello standard ISO C11.
Linux supporta anche ``clang`` [it-clang]_, leggete la documentazione
:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
Questo dialetto contiene diverse estensioni al linguaggio [it-gnu-extensions]_,
e molte di queste vengono usate sistematicamente dal kernel.
Attributi
---------
Una delle estensioni più comuni e usate nel kernel sono gli attributi
[it-gcc-attribute-syntax]_. Gli attributi permettono di aggiungere una semantica,
definita dell'implementazione, alle entità del linguaggio (come le variabili,
le funzioni o i tipi) senza dover fare importanti modifiche sintattiche al
linguaggio stesso (come l'aggiunta di nuove parole chiave) [it-n2049]_.
In alcuni casi, gli attributi sono opzionali (ovvero un compilatore che non
dovesse supportarli dovrebbe produrre comunque codice corretto, anche se
più lento o che non esegue controlli aggiuntivi durante la compilazione).
Il kernel definisce alcune pseudo parole chiave (per esempio ``__pure``)
in alternativa alla sintassi GNU per gli attributi (per esempio
``__attribute__((__pure__))``) allo scopo di mostrare quali funzionalità si
possono usare e/o per accorciare il codice.
Per maggiori informazioni consultate il file d'intestazione
``include/linux/compiler_attributes.h``.
Rust
----
Il kernel supporta sperimentalmente il linguaggio di programmazione Rust
[it-rust-language]_ abilitando l'opzione di configurazione ``CONFIG_RUST``. Il
codice verrà compilato usando ``rustc`` [it-rustc]_ con l'opzione
``--edition=2021`` [it-rust-editions]_. Le edizioni Rust sono un modo per
introdurre piccole modifiche senza compatibilità all'indietro._
In aggiunta, nel kernel vengono utilizzate alcune funzionalità considerate
instabili [it-rust-unstable-features]_. Queste funzionalità potrebbero cambiare
in futuro, dunque è un'obiettivo importante è quello di far uso solo di
funzionalità stabili.
Per maggiori informazioni fate riferimento a Documentation/rust/index.rst .
.. [it-c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
.. [it-gcc] https://gcc.gnu.org
.. [it-clang] https://clang.llvm.org
.. [it-gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
.. [it-gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
.. [it-gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
.. [it-n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
.. [it-rust-language] https://www.rust-lang.org
.. [it-rustc] https://doc.rust-lang.org/rustc/
.. [it-rust-editions] https://doc.rust-lang.org/edition-guide/editions/
.. [it-rust-unstable-features] https://github.com/Rust-for-Linux/linux/issues/2
@@ -0,0 +1,12 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/security-bugs.rst <securitybugs>`
.. _it_securitybugs:
Bachi di sicurezza
==================
.. warning::
TODO ancora da tradurre
@@ -0,0 +1,209 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/stable-api-nonsense.rst <stable_api_nonsense>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_stable_api_nonsense:
L'interfaccia dei driver per il kernel Linux
============================================
(tutte le risposte alle vostre domande e altro)
Greg Kroah-Hartman <greg@kroah.com>
Questo è stato scritto per cercare di spiegare perché Linux **non ha
un'interfaccia binaria, e non ha nemmeno un'interfaccia stabile**.
.. note::
Questo articolo parla di interfacce **interne al kernel**, non delle
interfacce verso lo spazio utente.
L'interfaccia del kernel verso lo spazio utente è quella usata dai
programmi, ovvero le chiamate di sistema. Queste interfacce sono **molto**
stabili nel tempo e non verranno modificate. Ho vecchi programmi che sono
stati compilati su un kernel 0.9 (circa) e tuttora funzionano sulle versioni
2.6 del kernel. Queste interfacce sono quelle che gli utenti e i
programmatori possono considerare stabili.
Riepilogo generale
------------------
Pensate di volere un'interfaccia del kernel stabile, ma in realtà non la
volete, e nemmeno sapete di non volerla. Quello che volete è un driver
stabile che funzioni, e questo può essere ottenuto solo se il driver si trova
nei sorgenti del kernel. Ci sono altri vantaggi nell'avere il proprio driver
nei sorgenti del kernel, ognuno dei quali hanno reso Linux un sistema operativo
robusto, stabile e maturo; questi sono anche i motivi per cui avete scelto
Linux.
Introduzione
------------
Solo le persone un po' strambe vorrebbero scrivere driver per il kernel con
la costante preoccupazione per i cambiamenti alle interfacce interne. Per il
resto del mondo, queste interfacce sono invisibili o non di particolare
interesse.
Innanzitutto, non tratterò **alcun** problema legale riguardante codice
chiuso, nascosto, avvolto, blocchi binari, o qualsia altra cosa che descrive
driver che non hanno i propri sorgenti rilasciati con licenza GPL. Per favore
fate riferimento ad un avvocato per qualsiasi questione legale, io sono un
programmatore e perciò qui vi parlerò soltanto delle questioni tecniche (non
per essere superficiali sui problemi legali, sono veri e dovete esserne a
conoscenza in ogni circostanza).
Dunque, ci sono due tematiche principali: interfacce binarie del kernel e
interfacce stabili nei sorgenti. Ognuna dipende dall'altra, ma discuteremo
prima delle cose binarie per toglierle di mezzo.
Interfaccia binaria del kernel
------------------------------
Supponiamo d'avere un'interfaccia stabile nei sorgenti del kernel, di
conseguenza un'interfaccia binaria dovrebbe essere anche'essa stabile, giusto?
Sbagliato. Prendete in considerazione i seguenti fatti che riguardano il
kernel Linux:
- A seconda della versione del compilatore C che state utilizzando, diverse
strutture dati del kernel avranno un allineamento diverso, e possibilmente
un modo diverso di includere le funzioni (renderle inline oppure no).
L'organizzazione delle singole funzioni non è poi così importante, ma la
spaziatura (*padding*) nelle strutture dati, invece, lo è.
- In base alle opzioni che sono state selezionate per generare il kernel,
un certo numero di cose potrebbero succedere:
- strutture dati differenti potrebbero contenere campi differenti
- alcune funzioni potrebbero non essere implementate (per esempio,
alcuni *lock* spariscono se compilati su sistemi mono-processore)
- la memoria interna del kernel può essere allineata in differenti modi
a seconda delle opzioni di compilazione.
- Linux funziona su una vasta gamma di architetture di processore. Non esiste
alcuna possibilità che il binario di un driver per un'architettura funzioni
correttamente su un'altra.
Alcuni di questi problemi possono essere risolti compilando il proprio modulo
con la stessa identica configurazione del kernel, ed usando la stessa versione
del compilatore usato per compilare il kernel. Questo è sufficiente se volete
fornire un modulo per uno specifico rilascio su una specifica distribuzione
Linux. Ma moltiplicate questa singola compilazione per il numero di
distribuzioni Linux e il numero dei rilasci supportati da quest'ultime e vi
troverete rapidamente in un incubo fatto di configurazioni e piattaforme
hardware (differenti processori con differenti opzioni); dunque, anche per il
singolo rilascio di un modulo, dovreste creare differenti versioni dello
stesso.
Fidatevi, se tenterete questa via, col tempo, diventerete pazzi; l'ho imparato
a mie spese molto tempo fa...
Interfaccia stabile nei sorgenti del kernel
-------------------------------------------
Se parlate con le persone che cercano di mantenere aggiornato un driver per
Linux ma che non si trova nei sorgenti, allora per queste persone l'argomento
sarà "ostico".
Lo sviluppo del kernel Linux è continuo e viaggia ad un ritmo sostenuto, e non
rallenta mai. Perciò, gli sviluppatori del kernel trovano bachi nelle
interfacce attuali, o trovano modi migliori per fare le cose. Se le trovano,
allora le correggeranno per migliorarle. In questo frangente, i nomi delle
funzioni potrebbero cambiare, le strutture dati potrebbero diventare più grandi
o più piccole, e gli argomenti delle funzioni potrebbero essere ripensati.
Se questo dovesse succedere, nello stesso momento, tutte le istanze dove questa
interfaccia viene utilizzata verranno corrette, garantendo che tutto continui
a funzionare senza problemi.
Portiamo ad esempio l'interfaccia interna per il sottosistema USB che ha subito
tre ristrutturazioni nel corso della sua vita. Queste ristrutturazioni furono
fatte per risolvere diversi problemi:
- È stato fatto un cambiamento da un flusso di dati sincrono ad uno
asincrono. Questo ha ridotto la complessità di molti driver e ha
aumentato la capacità di trasmissione di tutti i driver fino a raggiungere
quasi la velocità massima possibile.
- È stato fatto un cambiamento nell'allocazione dei pacchetti da parte del
sottosistema USB per conto dei driver, cosicché ora i driver devono fornire
più informazioni al sottosistema USB al fine di correggere un certo numero
di stalli.
Questo è completamente l'opposto di quello che succede in alcuni sistemi
operativi proprietari che hanno dovuto mantenere, nel tempo, il supporto alle
vecchie interfacce USB. I nuovi sviluppatori potrebbero usare accidentalmente
le vecchie interfacce e sviluppare codice nel modo sbagliato, portando, di
conseguenza, all'instabilità del sistema.
In entrambe gli scenari, gli sviluppatori hanno ritenuto che queste importanti
modifiche erano necessarie, e quindi le hanno fatte con qualche sofferenza.
Se Linux avesse assicurato di mantenere stabile l'interfaccia interna, si
sarebbe dovuto procedere alla creazione di una nuova, e quelle vecchie, e
mal funzionanti, avrebbero dovuto ricevere manutenzione, creando lavoro
aggiuntivo per gli sviluppatori del sottosistema USB. Dato che gli
sviluppatori devono dedicare il proprio tempo a questo genere di lavoro,
chiedergli di dedicarne dell'altro, senza benefici, magari gratuitamente, non
è contemplabile.
Le problematiche relative alla sicurezza sono molto importanti per Linux.
Quando viene trovato un problema di sicurezza viene corretto in breve tempo.
A volte, per prevenire il problema di sicurezza, si sono dovute cambiare
delle interfacce interne al kernel. Quando è successo, allo stesso tempo,
tutti i driver che usavano quelle interfacce sono stati aggiornati, garantendo
la correzione definitiva del problema senza doversi preoccupare di rivederlo
per sbaglio in futuro. Se non si fossero cambiate le interfacce interne,
sarebbe stato impossibile correggere il problema e garantire che non si sarebbe
più ripetuto.
Nel tempo le interfacce del kernel subiscono qualche ripulita. Se nessuno
sta più usando un'interfaccia, allora questa verrà rimossa. Questo permette
al kernel di rimanere il più piccolo possibile, e garantisce che tutte le
potenziali interfacce sono state verificate nel limite del possibile (le
interfacce inutilizzate sono impossibili da verificare).
Cosa fare
---------
Dunque, se avete un driver per il kernel Linux che non si trova nei sorgenti
principali del kernel, come sviluppatori, cosa dovreste fare? Rilasciare un
file binario del driver per ogni versione del kernel e per ogni distribuzione,
è un incubo; inoltre, tenere il passo con tutti i cambiamenti del kernel è un
brutto lavoro.
Semplicemente, fate sì che il vostro driver per il kernel venga incluso nei
sorgenti principali (ricordatevi, stiamo parlando di driver rilasciati secondo
una licenza compatibile con la GPL; se il vostro codice non ricade in questa
categoria: buona fortuna, arrangiatevi, siete delle sanguisughe)
Se il vostro driver è nei sorgenti del kernel e un'interfaccia cambia, il
driver verrà corretto immediatamente dalla persona che l'ha modificata. Questo
garantisce che sia sempre possibile compilare il driver, che funzioni, e tutto
con un minimo sforzo da parte vostra.
Avere il proprio driver nei sorgenti principali del kernel ha i seguenti
vantaggi:
- La qualità del driver aumenterà e i costi di manutenzione (per lo
sviluppatore originale) diminuiranno.
- Altri sviluppatori aggiungeranno nuove funzionalità al vostro driver.
- Altri persone troveranno e correggeranno bachi nel vostro driver.
- Altri persone troveranno degli aggiustamenti da fare al vostro driver.
- Altri persone aggiorneranno il driver quando è richiesto da un cambiamento
di un'interfaccia.
- Il driver sarà automaticamente reso disponibile in tutte le distribuzioni
Linux senza dover chiedere a nessuna di queste di aggiungerlo.
Dato che Linux supporta più dispositivi di qualsiasi altro sistema operativo,
e che girano su molti più tipi di processori di qualsiasi altro sistema
operativo; ciò dimostra che questo modello di sviluppo qualcosa di giusto,
dopo tutto, lo fa :)
------
Dei ringraziamenti vanno a Randy Dunlap, Andrew Morton, David Brownell,
Hanna Linder, Robert Love, e Nishanth Aravamudan per la loro revisione
e per i loro commenti sulle prime bozze di questo articolo.
@@ -0,0 +1,248 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_stable_kernel_rules:
Tutto quello che volevate sapere sui rilasci -stable di Linux
==============================================================
Regole sul tipo di patch che vengono o non vengono accettate nei sorgenti
"-stable":
- Questa patch o una equivalente deve esistere già nei sorgenti principali di
Linux (upstream)
- Ovviamente dev'essere corretta e verificata.
- Non dev'essere più grande di 100 righe, incluso il contesto.
- Deve rispettare le regole scritte in
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`
- Deve correggere un vero baco che causi problemi agli utenti oppure aggiunge
un nuovo identificatore di dispositivo. Maggiori dettagli per il primo caso:
- Corregge un problema come un oops, un blocco, una corruzione di dati, un
vero problema di sicurezza, una stranezza hardware, un problema di
compilazione (ma non per cose già segnate con CONFIG_BROKEN), o problemi
del tipo "oh, questo non va bene".
- Problemi importanti riportati dagli utenti di una distribuzione potrebbero
essere considerati se correggono importanti problemi di prestazioni o di
interattività. Dato che questi problemi non sono così ovvi e la loro
correzione ha un'alta probabilità d'introdurre una regressione,
dovrebbero essere sottomessi solo dal manutentore della distribuzione
includendo un link, se esiste, ad un rapporto su bugzilla, e informazioni
aggiuntive sull'impatto che ha sugli utenti.
- Non si accettano cose del tipo "Questo potrebbe essere un problema ..."
come una teorica sezione critica, senza aver fornito anche una spiegazione
su come il baco possa essere sfruttato.
- Non deve includere alcuna correzione "banale" (correzioni grammaticali,
pulizia dagli spazi bianchi, eccetera).
Procedura per sottomettere patch per i sorgenti -stable
-------------------------------------------------------
.. note::
Una patch di sicurezza non dovrebbe essere gestita (solamente) dal processo
di revisione -stable, ma dovrebbe seguire le procedure descritte in
:ref:`Documentation/translations/it_IT/process/security-bugs.rst <it_securitybugs>`.
Ci sono tre opzioni per inviare una modifica per i sorgenti -stable:
1. Aggiungi un'etichetta 'stable' alla descrizione della patch al momento della
sottomissione per l'inclusione nei sorgenti principali.
2. Chiedere alla squadra "stable" di prendere una patch già applicata sui
sorgenti principali
3. Sottomettere una patch alla squadra "stable" equivalente ad una modifica già
fatta sui sorgenti principali.
Le seguenti sezioni descrivono con maggiori dettagli ognuna di queste opzioni
L':ref:`it_option_1` è **fortemente** raccomandata; è il modo più facile e
usato. L':ref:`it_option_2` si usa quando al momento della sottomissione non si
era pensato di riportare la modifica su versioni precedenti.
L':ref:`it_option_3` è un'alternativa ai due metodi precedenti quando la patch
nei sorgenti principali ha bisogno di aggiustamenti per essere applicata su
versioni precedenti (per esempio a causa di cambiamenti dell'API).
Quando si utilizza l'opzione 2 o 3 è possibile chiedere che la modifica sia
inclusa in specifiche versioni stabili. In tal caso, assicurarsi che la correzione
o una equivalente sia applicabile, o già presente in tutti i sorgenti
stabili più recenti ancora supportati. Questo ha lo scopo di prevenire
regressioni che gli utenti potrebbero incontrare in seguito durante
l'aggiornamento, se ad esempio una correzione per 5.19-rc1 venisse
riportata a 5.10.y, ma non a 5.15.y.
.. _it_option_1:
Opzione 1
*********
Aggiungete la seguente etichetta nell'area delle firme per far sì che una patch
che state inviando per l'inclusione nei sorgenti principali venga presa
automaticamente anche per quelli stabili::
Cc: stable@vger.kernel.org
Invece, usate ``Cc: stable@vger.kernel.org`` quando state inviando correzioni
per vulnerabilità non ancora di pubblico dominio: questo riduce il rischio di
esporre accidentalmente al pubblico la correzione quando si usa 'git
send-email', perché i messaggi inviati a quell'indirizzo non vengono inviati da
nessuna parte.
Una volta che la patch è stata inclusa, verrà applicata anche sui sorgenti
stabili senza che l'autore o il manutentore del sottosistema debba fare
qualcosa.
Per lasciare una nota per la squadra "stable", usate commenti in linea in stile
shell (leggere oltre per maggiori dettagli).
* Specificate i prerequisiti per le patch aggiuntive::
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
Cc: <stable@vger.kernel.org> # 3.3.x
Signed-off-by: Ingo Molnar <mingo@elte.hu>
La sequenza di etichette ha il seguente significato::
git cherry-pick a1f84a3
git cherry-pick 1b9508f
git cherry-pick fd21073
git cherry-pick <this commit>
Notate che per una serie di patch non dovere elencare come necessarie tutte
le patch della serie stessa. Per esempio se avete la seguente serie::
patch1
patch2
dove patch2 dipende da patch1, non dovete elencare patch1 come requisito per
patch2 se avete già menzionato patch1 per l'inclusione in "stable"
* Evidenziate le patch che hanno dei requisiti circa la versione del kernel::
Cc: <stable@vger.kernel.org> # 3.3.x
L'etichetta ha il seguente significato::
git cherry-pick <this commit>
per ogni sorgente "-stable" che inizia con la versione indicata.
Notate che queste etichette non sono necessarie se la squadre "stable" può
dedurre la versione dalle etichette Fixes:
* Ritardare l'inclusione di patch::
Cc: <stable@vger.kernel.org> # after -rc3
* Evidenziare problemi noti::
Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.3
Esiste un'ulteriore variante per l'etichetta "stable" che permette di comunicare
allo strumento di *backporting* di ignorare un cambiamento::
Cc: <stable+noautosel@kernel.org> # reason goes here, and must be present
.. _it_option_2:
Opzione 2
*********
Se la patch è già stata inclusa nei sorgenti Linux, inviate una mail a
stable@vger.kernel.org includendo: il titolo della patch, l'identificativo
del commit, il perché pensate che debba essere applicata, e in quali versioni
del kernel la vorreste vedere.
.. _it_option_3:
Opzione 3
*********
Dopo aver verificato che rispetta le regole descritte in precedenza, inviata la
patch a stable@vger.kernel.org facendo anche menzione delle versioni nella quale
si vorrebbe applicarla. Nel farlo, dovete annotare nel changelog
l'identificativo del commit nei sorgenti principali, così come la versione del
kernel nel quale vorreste vedere la patch.::
commit <sha1> upstream.
o in alternativa::
[ Upstream commit <sha1> ]
Se la patch inviata devia rispetto all'originale presente nei sorgenti
principali (per esempio per adattarsi ad un cambiamento di API), allora questo
dev'essere giustificato e dettagliato in modo chiaro nella descrizione.
Dopo la sottomissione
---------------------
Il mittente riceverà un ACK quando la patch è stata accettata e messa in coda,
oppure un NAK se la patch è stata rigettata. La risposta potrebbe richiedere
alcuni giorni in funzione dei piani dei membri della squadra "stable",
Se accettata, la patch verrà aggiunta alla coda -stable per essere revisionata
dal altri sviluppatori e dal principale manutentore del sottosistema.
Ciclo di una revisione
----------------------
- Quando i manutentori -stable decidono di fare un ciclo di revisione, le
patch vengono mandate al comitato per la revisione, ai manutentori soggetti
alle modifiche delle patch (a meno che il mittente non sia anche il
manutentore di quell'area del kernel) e in CC: alla lista di discussione
linux-kernel.
- La commissione per la revisione ha 48 ore per dare il proprio ACK o NACK
alle patch.
- Se una patch viene rigettata da un membro della commissione, o un membro
della lista linux-kernel obietta la bontà della patch, sollevando problemi
che i manutentori ed i membri non avevano compreso, allora la patch verrà
rimossa dalla coda.
- Le patch che hanno ricevuto un ACK verranno inviate nuovamente come parte di
un rilascio candidato (-rc) al fine di essere verificate dagli sviluppatori e
dai testatori.
- Solitamente si pubblica solo una -rc, tuttavia se si riscontrano problemi
importanti, alcune patch potrebbero essere modificate o essere scartate,
oppure nuove patch potrebbero essere messe in coda. Dunque, verranno pubblicate
nuove -rc e così via finché non si ritiene che non vi siano più problemi.
- Si può rispondere ad una -rc scrivendo sulla lista di discussione un'email
con l'etichetta "Tested-by:". Questa etichetta verrà raccolta ed aggiunta al
commit rilascio.
- Alla fine del ciclo di revisione il nuovo rilascio -stable conterrà tutte le
patch che erano in coda e sono state verificate.
- Le patch di sicurezza verranno accettate nei sorgenti -stable direttamente
dalla squadra per la sicurezza del kernel, e non passerà per il normale
ciclo di revisione. Contattate la suddetta squadra per maggiori dettagli
su questa procedura.
Sorgenti
--------
- La coda delle patch, sia quelle già applicate che in fase di revisione,
possono essere trovate al seguente indirizzo:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git
- Il rilascio definitivo, e marchiato, di tutti i kernel stabili può essere
trovato in rami distinti per versione al seguente indirizzo:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
- I rilasci candidati di tutti i kernel stabili possono essere trovati al
seguente indirizzo:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/
.. warning::
I sorgenti -stable-rc sono un'istantanea dei sorgenti stable-queue e
subirà frequenti modifiche, dunque verrà anche trapiantato spesso.
Dovrebbe essere usato solo allo scopo di verifica (per esempio in un
sistema di CI)
Comitato per la revisione
-------------------------
- Questo comitato è fatto di sviluppatori del kernel che si sono offerti
volontari per questo lavoro, e pochi altri che non sono proprio volontari.
@@ -0,0 +1,142 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/submit-checklist.rst <submitchecklist>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_submitchecklist:
============================================================================
Lista delle verifiche da fare prima di inviare una patch per il kernel Linux
============================================================================
Qui troverete una lista di cose che uno sviluppatore dovrebbe fare per
vedere le proprie patch accettate più rapidamente.
Tutti questi punti integrano la documentazione fornita riguardo alla
sottomissione delle patch, in particolare
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
Revisiona il tuo codice
=======================
1) Se state usando delle funzionalità del kernel allora includete (#include)
i file che le dichiarano/definiscono. Non dipendente dal fatto che un file
d'intestazione include anche quelli usati da voi.
2) Controllate lo stile del codice della vostra patch secondo le direttive
scritte in :ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`.
3) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``,
``rmb()``, ``wmb()``} devono essere accompagnate da un commento nei
sorgenti che ne spieghi la logica: cosa fanno e perché.
Revisionate i cambiamenti a Kconfig
===================================
1) Le opzioni ``CONFIG``, nuove o modificate, non scombussolano il menu
di configurazione e sono preimpostate come disabilitate a meno che non
soddisfino i criteri descritti in ``Documentation/kbuild/kconfig-language.rst``
alla punto "Voci di menu: valori predefiniti".
2) Tutte le nuove opzioni ``Kconfig`` hanno un messaggio di aiuto.
3) La patch è stata accuratamente revisionata rispetto alle più importanti
configurazioni ``Kconfig``. Questo è molto difficile da fare
correttamente - un buono lavoro di testa sarà utile.
Fornite documentazione
======================
1) Includete :ref:`kernel-doc <kernel_doc>` per documentare API globali del
kernel.
2) Tutti i nuovi elementi in ``/proc`` sono documentati in ``Documentation/``.
3) Tutti i nuovi parametri d'avvio del kernel sono documentati in
``Documentation/admin-guide/kernel-parameters.rst``.
4) Tutti i nuovi parametri dei moduli sono documentati con ``MODULE_PARM_DESC()``.
5) Tutte le nuove interfacce verso lo spazio utente sono documentate in
``Documentation/ABI/``. Leggete Documentation/admin-guide/abi.rst
(o ``Documentation/ABI/README``) per maggiori informazioni.
Le patch che modificano le interfacce utente dovrebbero essere inviate
in copia anche a linux-api@vger.kernel.org.
6) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
Verificate il vostro codice con gli strumenti
=============================================
1) Prima dell'invio della patch, usate il verificatore di stile
(``script/checkpatch.pl``) per scovare le violazioni più semplici.
Dovreste essere in grado di giustificare tutte le violazioni rimanenti nella
vostra patch.
2) Verificare il codice con sparse.
3) Usare ``make checkstack`` e correggere tutti i problemi rilevati. Da notare
che ``checkstack`` non evidenzia esplicitamente i problemi, ma una funzione
che usa più di 512 byte sullo stack è una buona candidata per una correzione.
Compilare il codice
===================
1) Compilazione pulita:
a) con le opzioni ``CONFIG`` negli stati ``=y``, ``=m`` e ``=n``. Nessun
avviso/errore di ``gcc`` e nessun avviso/errore dal linker.
b) con ``allnoconfig``, ``allmodconfig``
c) quando si usa ``O=builddir``
d) Qualsiasi modifica in Documentation/ deve compilare con successo senza
avvisi o errori. Usare ``make htmldocs`` o ``make pdfdocs`` per verificare
e correggere i problemi
2) Compilare per diverse architetture di processore usando strumenti per la
cross-compilazione o altri. Una buona architettura per la verifica della
cross-compilazione è la ppc64 perché tende ad usare ``unsigned long`` per le
quantità a 64-bit.
3) Il nuovo codice è stato compilato con ``gcc -W`` (usate
``make KCFLAGS=-W``). Questo genererà molti avvisi, ma è ottimo
per scovare bachi come "warning: comparison between signed and unsigned".
4) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o
funzionalità del kernel che è associata a uno dei seguenti simboli
``Kconfig``, allora verificate che il kernel compili con diverse
configurazioni dove i simboli sono disabilitati e/o ``=m`` (se c'è la
possibilità) [non tutti contemporaneamente, solo diverse combinazioni
casuali]:
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``,
``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``,
``CONFIG_NET``, ``CONFIG_INET=n`` (ma l'ultimo con ``CONFIG_NET=y``).
Verificate il vostro codice
===========================
1) La patch è stata verificata con le seguenti opzioni abilitate
contemporaneamente: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
``CONFIG_SLUB_DEBUG``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``,
``CONFIG_PROVE_RCU`` e ``CONFIG_DEBUG_OBJECTS_RCU_HEAD``.
2) La patch è stata compilata e verificata in esecuzione con, e senza,
le opzioni ``CONFIG_SMP`` e ``CONFIG_PREEMPT``.
3) Tutti i percorsi del codice sono stati verificati con tutte le funzionalità
di lockdep abilitate.
4) La patch è stata verificata con l'iniezione di fallimenti in slab e
nell'allocazione di pagine. Vedere ``Documentation/fault-injection/``.
Se il nuovo codice è corposo, potrebbe essere opportuno aggiungere
l'iniezione di fallimenti specifici per il sottosistema.
5) La patch è stata verificata sul tag più recente di linux-next per assicurarsi
che funzioni assieme a tutte le altre patch in coda, assieme ai vari
cambiamenti nei sottosistemi VM, VFS e altri.
@@ -0,0 +1,930 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_submittingpatches:
Inviare patch: la guida essenziale per vedere il vostro codice nel kernel
=========================================================================
Una persona o un'azienda che volesse inviare una patch al kernel potrebbe
sentirsi scoraggiata dal processo di sottomissione, specialmente quando manca
una certa familiarità col "sistema". Questo testo è una raccolta di
suggerimenti che aumenteranno significativamente le probabilità di vedere le
vostre patch accettate.
Questo documento contiene un vasto numero di suggerimenti concisi. Per maggiori
dettagli su come funziona il processo di sviluppo del kernel leggete
Documentation/translations/it_IT/process/development-process.rst. Leggete anche
Documentation/translations/it_IT/process/submit-checklist.rst per una lista di
punti da verificare prima di inviare del codice.
Per delle patch relative alle associazioni per Device Tree leggete
Documentation/translations/it_IT/process/submitting-patches.rst.
Questa documentazione assume che sappiate usare ``git`` per preparare le patch.
Se non siete pratici di ``git``, allora è bene che lo impariate;
renderà la vostra vita di sviluppatore del kernel molto più semplice.
I sorgenti di alcuni sottosistemi e manutentori contengono più informazioni
riguardo al loro modo di lavorare ed aspettative. Consultate
:ref:`Documentation/translations/it_IT/process/maintainer-handbooks.rst <it_maintainer_handbooks_main>`
Ottenere i sorgenti attuali
---------------------------
Se non avete un repositorio coi sorgenti del kernel più recenti, allora usate
``git`` per ottenerli. Vorrete iniziare col repositorio principale che può
essere recuperato col comando::
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Notate, comunque, che potreste non voler sviluppare direttamente coi sorgenti
principali del kernel. La maggior parte dei manutentori hanno i propri
sorgenti e desiderano che le patch siano preparate basandosi su di essi.
Guardate l'elemento **T:** per un determinato sottosistema nel file MAINTANERS
che troverete nei sorgenti, o semplicemente chiedete al manutentore nel caso
in cui i sorgenti da usare non siano elencati il quel file.
.. _it_describe_changes:
Descrivete le vostre modifiche
------------------------------
Descrivete il vostro problema. Esiste sempre un problema che via ha spinto
ha fare il vostro lavoro, che sia la correzione di un baco da una riga o una
nuova funzionalità da 5000 righe di codice. Convincete i revisori che vale
la pena risolvere il vostro problema e che ha senso continuare a leggere oltre
al primo paragrafo.
Descrivete ciò che sarà visibile agli utenti. Chiari incidenti nel sistema
e blocchi sono abbastanza convincenti, ma non tutti i bachi sono così evidenti.
Anche se il problema è stato scoperto durante la revisione del codice,
descrivete l'impatto che questo avrà sugli utenti. Tenete presente che
la maggior parte delle installazioni Linux usa un kernel che arriva dai
sorgenti stabili o dai sorgenti di una distribuzione particolare che prende
singolarmente le patch dai sorgenti principali; quindi, includete tutte
le informazioni che possono essere utili a capire le vostre modifiche:
le circostanze che causano il problema, estratti da dmesg, descrizioni di
un incidente di sistema, prestazioni di una regressione, picchi di latenza,
blocchi, eccetera.
Quantificare le ottimizzazioni e i compromessi. Se affermate di aver
migliorato le prestazioni, il consumo di memoria, l'impatto sollo stack,
o la dimensione del file binario, includete dei numeri a supporto della
vostra dichiarazione. Ma ricordatevi di descrivere anche eventuali costi
che non sono ovvi. Solitamente le ottimizzazioni non sono gratuite, ma sono
un compromesso fra l'uso di CPU, la memoria e la leggibilità; o, quando si
parla di ipotesi euristiche, fra differenti carichi. Descrivete i lati
negativi che vi aspettate dall'ottimizzazione cosicché i revisori possano
valutare i costi e i benefici.
Una volta che il problema è chiaro, descrivete come lo risolvete andando
nel dettaglio tecnico. È molto importante che descriviate la modifica
in un inglese semplice cosicché i revisori possano verificare che il codice si
comporti come descritto.
I manutentori vi saranno grati se scrivete la descrizione della patch in un
formato che sia compatibile con il gestore dei sorgenti usato dal kernel,
``git``, come un "commit log". Leggete :ref:`it_the_canonical_patch_format`.
Risolvete solo un problema per patch. Se la vostra descrizione inizia ad
essere lunga, potrebbe essere un segno che la vostra patch necessita d'essere
divisa. Leggete :ref:`it_split_changes`.
Quando inviate o rinviate una patch o una serie, includete la descrizione
completa delle modifiche e la loro giustificazione. Non limitatevi a dire che
questa è la versione N della patch (o serie). Non aspettatevi che i
manutentori di un sottosistema vadano a cercare le versioni precedenti per
cercare la descrizione da aggiungere. In pratica, la patch (o serie) e la sua
descrizione devono essere un'unica cosa. Questo aiuta i manutentori e i
revisori. Probabilmente, alcuni revisori non hanno nemmeno ricevuto o visto
le versioni precedenti della patch.
Descrivete le vostro modifiche usando l'imperativo, per esempio "make xyzzy
do frotz" piuttosto che "[This patch] makes xyzzy do frotz" or "[I] changed
xyzzy to do frotz", come se steste dando ordini al codice di cambiare il suo
comportamento.
Se volete far riferimento a uno specifico commit, non usate solo
l'identificativo SHA-1. Per cortesia, aggiungete anche la breve riga
riassuntiva del commit per rendere la chiaro ai revisori l'oggetto.
Per esempio::
Commit e21d2170f36602ae2708 ("video: remove unnecessary
platform_set_drvdata()") removed the unnecessary
platform_set_drvdata(), but left the variable "dev" unused,
delete it.
Dovreste anche assicurarvi di usare almeno i primi 12 caratteri
dell'identificativo SHA-1. Il repositorio del kernel ha *molti* oggetti e
questo rende possibile la collisione fra due identificativi con pochi
caratteri. Tenete ben presente che anche se oggi non ci sono collisioni con il
vostro identificativo a 6 caratteri, potrebbero essercene fra 5 anni da oggi.
Se ci sono delle discussioni, o altre informazioni d'interesse, che fanno
riferimento alla patch, allora aggiungete l'etichetta 'Link:' per farvi
riferimento. Se la patch è il risultato di una discussione avvenuta
precedentemente o di un documento sul presente sul web, allora fatevi
riferimento.
Per esempio, se la vostra patch corregge un baco potete aggiungere
quest'etichetta per fare riferimento ad un rapporto su una lista di discussione
o un *bug tracker*. Un altro esempio; potete usare quest'etichetta per far
riferimento ad una discussione precedentemente avvenuta su una lista di
discussione, o qualcosa di documentato sul web, da cui poi è nata la patch in
questione.
Quando volete fare riferimento ad una lista di discussione, preferite il
servizio d'archiviazione lore.kernel.org. Per create un collegamento URL è
sufficiente usare il campo ``Message-ID``, presente nell'intestazione del
messaggio, senza parentesi angolari. Per esempio::
Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
Prima d'inviare il messaggio ricordatevi di verificare che il collegamento così
creato funzioni e che indirizzi verso il messaggio desiderato.
Tuttavia, provate comunque a dare una spiegazione comprensibile anche senza
accedere alle fonti esterne. Inoltre, riassumente i punti più salienti che hanno
condotto all'invio della patch.
Se il collegamento indirizza verso un rapporto su un baco risolto dalla patch,
allora usate l'etichetta "Closes:"::
Closes: https://example.com/issues/1234 optional-other-stuff
Alcune piattaforme di tracciamento di bachi hanno la capacità di chiudere
automaticamente il problema se l'etichetta è presente nel messaggio. Alcuni
automatismi che monitorano la liste di discussione possono anche tracciare
queste etichette e intraprendere azioni. Piattaforme private e URL invalidi sono
proibiti.
Se la vostra patch corregge un baco in un commit specifico, per esempio avete
trovato un problema usando ``git bisect``, per favore usate l'etichetta
'Fixes:' indicando i primi 12 caratteri dell'identificativo SHA-1 seguiti
dalla riga riassuntiva. Per esempio::
Fixes: e21d2170f366 ("video: remove unnecessary platform_set_drvdata()")
La seguente configurazione di ``git config`` può essere usata per formattare
i risultati dei comandi ``git log`` o ``git show`` come nell'esempio
precedente::
[core]
abbrev = 12
[pretty]
fixes = Fixes: %h (\"%s\")
Un esempio::
$ git log -1 --pretty=fixes 54a4f0239f2e
Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
.. _it_split_changes:
Separate le vostre modifiche
----------------------------
Separate ogni **cambiamento logico** in patch distinte.
Per esempio, se i vostri cambiamenti per un singolo driver includono
sia delle correzioni di bachi che miglioramenti alle prestazioni,
allora separateli in due o più patch. Se i vostri cambiamenti includono
un aggiornamento dell'API e un nuovo driver che lo sfrutta, allora separateli
in due patch.
D'altro canto, se fate una singola modifica su più file, raggruppate tutte
queste modifiche in una singola patch. Dunque, un singolo cambiamento logico
è contenuto in una sola patch.
Il punto da ricordare è che ogni modifica dovrebbe fare delle modifiche
che siano facilmente comprensibili e che possano essere verificate dai revisori.
Ogni patch dovrebbe essere giustificabile di per sé.
Se al fine di ottenere un cambiamento completo una patch dipende da un'altra,
va bene. Semplicemente scrivete una nota nella descrizione della patch per
farlo presente: **"this patch depends on patch X"**.
Quando dividete i vostri cambiamenti in una serie di patch, prestate
particolare attenzione alla verifica di ogni patch della serie; per ognuna
il kernel deve compilare ed essere eseguito correttamente. Gli sviluppatori
che usano ``git bisect`` per scovare i problemi potrebbero finire nel mezzo
della vostra serie in un punto qualsiasi; non vi saranno grati se nel mezzo
avete introdotto dei bachi.
Se non potete condensare la vostra serie di patch in una più piccola, allora
pubblicatene una quindicina alla volta e aspettate che vengano revisionate
ed integrate.
4) Verificate lo stile delle vostre modifiche
---------------------------------------------
Controllate che la vostra patch non violi lo stile del codice, maggiori
dettagli sono disponibili in Documentation/translations/it_IT/process/coding-style.rst.
Non farlo porta semplicemente a una perdita di tempo da parte dei revisori e
voi vedrete la vostra patch rifiutata, probabilmente senza nemmeno essere stata
letta.
Un'eccezione importante si ha quando del codice viene spostato da un file
ad un altro -- in questo caso non dovreste modificare il codice spostato
per nessun motivo, almeno non nella patch che lo sposta. Questo separa
chiaramente l'azione di spostare il codice e il vostro cambiamento.
Questo aiuta enormemente la revisione delle vere differenze e permette agli
strumenti di tenere meglio la traccia della storia del codice.
Prima di inviare una patch, verificatene lo stile usando l'apposito
verificatore (scripts/checkpatch.pl). Da notare, comunque, che il verificator
di stile dovrebbe essere visto come una guida, non come un sostituto al
giudizio umano. Se il vostro codice è migliore nonostante una violazione
dello stile, probabilmente è meglio lasciarlo com'è.
Il verificatore ha tre diversi livelli di severità:
- ERROR: le cose sono molto probabilmente sbagliate
- WARNING: le cose necessitano d'essere revisionate con attenzione
- CHECK: le cose necessitano di un pensierino
Dovreste essere in grado di giustificare tutte le eventuali violazioni rimaste
nella vostra patch.
5) Selezionate i destinatari della vostra patch
-----------------------------------------------
Dovreste sempre inviare una copia della patch ai manutentori e alle liste di
discussione dei sottosistemi interessati dalle modifiche; date un'occhiata al
file MAINTAINERS e alla storia delle revisioni per scoprire chi si occupa del
codice. Lo script scripts/get_maintainer.pl può esservi d'aiuto (passategli il
percorso alle vostre patch). Se non riuscite a trovare un manutentore per il
sottosistema su cui state lavorando, allora Andrew Morton
(akpm@linux-foundation.org) sarà la vostra ultima possibilità.
La lista linux-kernel@vger.kernel.org dovrebbe essere usata per l'invio di tutte
le patch, ma il volume ha raggiunto un livello tale d'aver spinto alcuni
sviluppatori a non seguirla più. Dunque, per favore, evitate di inviare messaggi
scorrelati al tema della lista o a persone che non dovrebbero essere
interessate all'argomento.
Normalmente, dovreste anche scegliere una lista di discussione a cui inviare la
vostra serie di patch. La lista di discussione linux-kernel@vger.kernel.org
dovrebbe essere usata per inviare tutte le patch, ma il traffico è tale per cui
diversi sviluppatori la trascurano. Guardate nel file MAINTAINERS per trovare la
lista di discussione dedicata ad un sottosistema; probabilmente lì la vostra
patch riceverà molta più attenzione. Tuttavia, per favore, non spammate le liste
di discussione che non sono interessate al vostro lavoro.
Molte delle liste di discussione relative al kernel vengono ospitate su
kernel.org; potete trovare un loro elenco alla pagina
https://subspace.kernel.org. Tuttavia, ci sono altre liste di discussione
ospitate altrove.
L'ultimo giudizio sull'integrazione delle modifiche accettate spetta a
Linux Torvalds. Il suo indirizzo e-mail è <torvalds@linux-foundation.org>.
Riceve moltissime e-mail, e, a questo punto, solo poche patch passano
direttamente attraverso il suo giudizio; quindi, dovreste fare del vostro
meglio per -evitare di- inviargli e-mail.
Se avete una patch che corregge un baco di sicurezza che potrebbe essere
sfruttato, inviatela a security@kernel.org. Per bachi importanti, un breve
embargo potrebbe essere preso in considerazione per dare il tempo alle
distribuzioni di prendere la patch e renderla disponibile ai loro utenti;
in questo caso, ovviamente, la patch non dovrebbe essere inviata su alcuna
lista di discussione pubblica. Leggete anche
Documentation/process/security-bugs.rst.
Patch che correggono bachi importanti su un kernel già rilasciato, dovrebbero
essere inviate ai manutentori dei kernel stabili aggiungendo la seguente riga::
Cc: stable@vger.kernel.org
nella vostra patch, nell'area dedicata alle firme (notate, NON come destinatario
delle e-mail). In aggiunta a questo file, dovreste leggere anche
Documentation/translations/it_IT/process/stable-kernel-rules.rst.
Se le modifiche hanno effetti sull'interfaccia con lo spazio utente, per favore
inviate una patch per le pagine man ai manutentori di suddette pagine (elencati
nel file MAINTAINERS), o almeno una notifica circa la vostra modifica,
cosicché l'informazione possa trovare la sua strada nel manuale. Le modifiche
all'API dello spazio utente dovrebbero essere inviate in copia anche a
linux-api@vger.kernel.org.
Niente: MIME, links, compressione, allegati. Solo puro testo
-------------------------------------------------------------
Linus e gli altri sviluppatori del kernel devono poter commentare
le modifiche che sottomettete. Per uno sviluppatore è importante
essere in grado di "citare" le vostre modifiche, usando normali
programmi di posta elettronica, cosicché sia possibile commentare
una porzione specifica del vostro codice.
Per questa ragione tutte le patch devono essere inviate via e-mail
come testo. Il modo più facile, e quello raccomandato, è con ``git
send-email``. Al sito https://git-send-email.io è disponibile una
guida interattiva sull'uso di ``git send-email``.
Se decidete di non usare ``git send-email``:
.. warning::
Se decidete di copiare ed incollare la patch nel corpo dell'e-mail, state
attenti che il vostro programma non corrompa il contenuto con andate
a capo automatiche.
La patch non deve essere un allegato MIME, compresso o meno. Molti
dei più popolari programmi di posta elettronica non trasmettono un allegato
MIME come puro testo, e questo rende impossibile commentare il vostro codice.
Inoltre, un allegato MIME rende l'attività di Linus più laboriosa, diminuendo
così la possibilità che il vostro allegato-MIME venga accettato.
Eccezione: se il vostro servizio di posta storpia le patch, allora qualcuno
potrebbe chiedervi di rinviarle come allegato MIME.
Leggete Documentation/translations/it_IT/process/email-clients.rst
per dei suggerimenti sulla configurazione del programmi di posta elettronica
per l'invio di patch intatte.
Rispondere ai commenti di revisione
-----------------------------------
In risposta alla vostra email, quasi certamente i revisori vi
invieranno dei commenti su come migliorare la vostra patch. Dovete
rispondere a questi commenti; ignorare i revisori è un ottimo modo per
essere ignorati. Riscontri o domande che non conducono ad una
modifica del codice quasi certamente dovrebbero portare ad un commento
nel changelog cosicché il prossimo revisore potrà meglio comprendere
cosa stia accadendo.
Assicuratevi di dire ai revisori quali cambiamenti state facendo e di
ringraziarli per il loro tempo. Revisionare codice è un lavoro faticoso e che
richiede molto tempo, e a volte i revisori diventano burberi. Tuttavia, anche in
questo caso, rispondete con educazione e concentratevi sul problema che hanno
evidenziato. Quando inviate una versione successiva ricordatevi di aggiungere un
``patch changelog`` alla email di intestazione o ad ogni singola patch spiegando
le differenze rispetto a sottomissioni precedenti (vedere
:ref:`it_the_canonical_patch_format`). Aggiungete a CC tutte le persone che
vi hanno fornito dei commenti per notificarle di eventuali nuove versioni.
Leggete Documentation/translations/it_IT/process/email-clients.rst per
le raccomandazioni sui programmi di posta elettronica e l'etichetta da usare
sulle liste di discussione.
.. _it_interleaved_replies:
Rispondere alle email in riga e riducendo la citazioni
------------------------------------------------------
Nelle discussioni riguardo allo sviluppo del kernel viene fortemente scoraggiato
l'uso di risposte in cima ai messaggi di posta elettronica. Rispondere in riga
rende le conversazioni molto più scorrevoli. Maggiori dettagli possono essere
trovati qui: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
Come spesso citato nelle liste di discussione::
R: http://en.wikipedia.org/wiki/Top_post
D: Dove posso trovare informazioni riguardo alle "risposte in cima"?
R: Perché incasina il normale ordine con cui si legge un testo.
D: Perché è così terribile rispondere in cima?
R: Risposte in cima.
Q: Qual è la cosa più fastidiosa nei messaggi di posta elettronica?
Allo stesso modo, per favore eliminate tutte le citazioni non necessarie per la
vostra risposta. Questo permette di trovare più facilmente le risposte, e
permette di risparmiare tempo e spazio. Per maggiori dettagli:
http://daringfireball.net/2007/07/on_top ::
R: No.
D: Dovrei includere un blocco di citazione dopo la mia risposta?
.. _it_resend_reminders:
Non scoraggiatevi - o impazientitevi
------------------------------------
Dopo che avete inviato le vostre modifiche, siate pazienti e aspettate.
I revisori sono persone occupate e potrebbero non ricevere la vostra patch
immediatamente.
Un tempo, le patch erano solite scomparire nel vuoto senza alcun commento, ma
ora il processo di sviluppo funziona meglio. Dovreste ricevere commenti in poche
settimane (tipicamente 2 o 3); se questo non dovesse accadere, assicuratevi di
aver inviato le patch correttamente. Aspettate almeno una settimana prima di
rinviare le modifiche o sollecitare i revisori - probabilmente anche di più
durante la finestra d'integrazione.
Potete anche rinviare la patch, o la serie di patch, dopo un paio di settimane
aggiungendo la parola "RESEND" nel titolo::
[PATCH Vx RESEND] sub/sys: Condensed patch summary
Ma non aggiungete "RESEND" quando state sottomettendo una versione modificata
della vostra patch, o serie di patch - "RESEND" si applica solo alla
sottomissione di patch, o serie di patch, che non hanno subito modifiche
dall'ultima volta che sono state inviate.
Aggiungete PATCH nell'oggetto
-----------------------------
Dato l'alto volume di e-mail per Linus, e la lista linux-kernel, è prassi
prefiggere il vostro oggetto con [PATCH]. Questo permette a Linus e agli
altri sviluppatori del kernel di distinguere facilmente le patch dalle altre
discussioni.
``git send-email`` lo fa automaticamente.
Firmate il vostro lavoro - Il certificato d'origine dello sviluppatore
----------------------------------------------------------------------
Per migliorare la tracciabilità su "chi ha fatto cosa", specialmente per
quelle patch che per raggiungere lo stadio finale passano attraverso
diversi livelli di manutentori, abbiamo introdotto la procedura di "firma"
delle patch che vengono inviate per e-mail.
La firma è una semplice riga alla fine della descrizione della patch che
certifica che l'avete scritta voi o che avete il diritto di pubblicarla
come patch open-source. Le regole sono abbastanza semplici: se potete
certificare quanto segue:
Il certificato d'origine dello sviluppatore 1.1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Contribuendo a questo progetto, io certifico che:
(a) Il contributo è stato creato interamente, o in parte, da me e che
ho il diritto di inviarlo in accordo con la licenza open-source
indicata nel file; oppure
(b) Il contributo è basato su un lavoro precedente che, nei limiti
della mia conoscenza, è coperto da un'appropriata licenza
open-source che mi da il diritto di modificarlo e inviarlo,
le cui modifiche sono interamente o in parte mie, in accordo con
la licenza open-source (a meno che non abbia il permesso di usare
un'altra licenza) indicata nel file; oppure
(c) Il contributo mi è stato fornito direttamente da qualcuno che
ha certificato (a), (b) o (c) e non l'ho modificata.
(d) Capisco e concordo col fatto che questo progetto e i suoi
contributi sono pubblici e che un registro dei contributi (incluse
tutte le informazioni personali che invio con essi, inclusa la mia
firma) verrà mantenuto indefinitamente e che possa essere
ridistribuito in accordo con questo progetto o le licenze
open-source coinvolte.
poi dovete solo aggiungere una riga che dice::
Signed-off-by: Random J Developer <random@developer.example.org>
usando il vostro vero nome (spiacenti, non si accettano
contributi anonimi). Questo verrà fatto automaticamente se usate
``git commit -s``. Anche il ripristino di uno stato precedente dovrebbe
includere "Signed-off-by", se usate ``git revert -s`` questo verrà
fatto automaticamente.
Alcune persone aggiungono delle etichette alla fine. Per ora queste verranno
ignorate, ma potete farlo per meglio identificare procedure aziendali interne o
per aggiungere dettagli circa la firma.
In seguito al SoB (Signed-off-by:) dell'autore ve ne sono altri da
parte di tutte quelle persone che si sono occupate della gestione e
del trasporto della patch. Queste però non sono state coinvolte nello
sviluppo, ma la loro sequenza d'apparizione ci racconta il percorso
**reale** che una patch a intrapreso dallo sviluppatore, fino al
manutentore, per poi giungere a Linus.
Quando utilizzare Acked-by:, Cc:, e Co-developed-by:
----------------------------------------------------
L'etichetta Signed-off-by: indica che il firmatario è stato coinvolto nello
sviluppo della patch, o che era nel suo percorso di consegna.
Se una persona non è direttamente coinvolta con la preparazione o gestione
della patch ma desidera firmare e mettere agli atti la loro approvazione,
allora queste persone possono chiedere di aggiungere al changelog della patch
una riga Acked-by:.
Acked-by: viene spesso utilizzato dai manutentori del sottosistema in oggetto
quando quello stesso manutentore non ha contribuito né trasmesso la patch.
Acked-by: non è formale come Signed-off-by:. Questo indica che la persona ha
revisionato la patch e l'ha trovata accettabile. Per cui, a volte, chi
integra le patch convertirà un "sì, mi sembra che vada bene" in un Acked-by:
(ma tenete presente che solitamente è meglio chiedere esplicitamente).
Acked-by: non indica l'accettazione di un'intera patch. Per esempio, quando
una patch ha effetti su diversi sottosistemi e ha un Acked-by: da un
manutentore di uno di questi, significa che il manutentore accetta quella
parte di codice relativa al sottosistema che mantiene. Qui dovremmo essere
giudiziosi. Quando si hanno dei dubbi si dovrebbe far riferimento alla
discussione originale negli archivi della lista di discussione.
Se una persona ha avuto l'opportunità di commentare la patch, ma non lo ha
fatto, potete aggiungere l'etichetta ``Cc:`` alla patch. Questa è l'unica
etichetta che può essere aggiunta senza che la persona in questione faccia
alcunché - ma dovrebbe indicare che la persona ha ricevuto una copia della
patch. Questa etichetta documenta che terzi potenzialmente interessati sono
stati inclusi nella discussione.
Co-developed-by: indica che la patch è stata cosviluppata da diversi
sviluppatori; viene usato per assegnare più autori (in aggiunta a quello
associato all'etichetta From:) quando più persone lavorano ad una patch. Dato
che Co-developed-by: implica la paternità della patch, ogni Co-developed-by:
dev'essere seguito immediatamente dal Signed-off-by: del corrispondente
coautore. Qui si applica la procedura di base per sign-off, in pratica
l'ordine delle etichette Signed-off-by: dovrebbe riflettere il più possibile
l'ordine cronologico della storia della patch, indipendentemente dal fatto che
la paternità venga assegnata via From: o Co-developed-by:. Da notare che
l'ultimo Signed-off-by: dev'essere quello di colui che ha sottomesso la patch.
Notate anche che l'etichetta From: è opzionale quando l'autore in From: è
anche la persona (e indirizzo email) indicato nel From: dell'intestazione
dell'email.
Esempio di una patch sottomessa dall'autore in From:::
<changelog>
Co-developed-by: First Co-Author <first@coauthor.example.org>
Signed-off-by: First Co-Author <first@coauthor.example.org>
Co-developed-by: Second Co-Author <second@coauthor.example.org>
Signed-off-by: Second Co-Author <second@coauthor.example.org>
Signed-off-by: From Author <from@author.example.org>
Esempio di una patch sottomessa dall'autore Co-developed-by:::
From: From Author <from@author.example.org>
<changelog>
Co-developed-by: Random Co-Author <random@coauthor.example.org>
Signed-off-by: Random Co-Author <random@coauthor.example.org>
Signed-off-by: From Author <from@author.example.org>
Co-developed-by: Submitting Co-Author <sub@coauthor.example.org>
Signed-off-by: Submitting Co-Author <sub@coauthor.example.org>
Utilizzare Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: e Fixes:
-------------------------------------------------------------------------
L'etichetta Reported-by da credito alle persone che trovano e riportano i bachi
e si spera che questo possa ispirarli ad aiutarci nuovamente in futuro.
Rammentate che se il baco è stato riportato in privato, dovrete chiedere il
permesso prima di poter utilizzare l'etichetta Reported-by. Questa etichetta va
usata per i bachi, dunque non usatela per richieste di nuove funzionalità.
Questa etichetta dovrebbe essere seguita da quella Closes: con un indirizzo al
rapporto, a meno che questo non sia disponibile sul web. L'etichetta Link: può
essere usata in alternativa a Closes: se la patch corregge solo in parte il
problema riportato nel rapporto.
L'etichetta Tested-by: indica che la patch è stata verificata con successo
(su un qualche sistema) dalla persona citata. Questa etichetta informa i
manutentori che qualche verifica è stata fatta, fornisce un mezzo per trovare
persone che possano verificare il codice in futuro, e garantisce che queste
stesse persone ricevano credito per il loro lavoro.
Reviewed-by:, invece, indica che la patch è stata revisionata ed è stata
considerata accettabile in accordo con la dichiarazione dei revisori:
Dichiarazione di svista dei revisori
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Offrendo la mia etichetta Reviewed-by, dichiaro quanto segue:
(a) Ho effettuato una revisione tecnica di questa patch per valutarne
l'adeguatezza ai fini dell'inclusione nel ramo principale del
kernel.
(b) Tutti i problemi e le domande riguardanti la patch sono stati
comunicati al mittente. Sono soddisfatto dalle risposte
del mittente.
(c) Nonostante ci potrebbero essere cose migliorabili in queste
sottomissione, credo che sia, in questo momento, (1) una modifica
di interesse per il kernel, e (2) libera da problemi che
potrebbero metterne in discussione l'integrazione.
(d) Nonostante abbia revisionato la patch e creda che vada bene,
non garantisco (se non specificato altrimenti) che questa
otterrà quello che promette o funzionerà correttamente in tutte
le possibili situazioni.
L'etichetta Reviewed-by è la dichiarazione di un parere sulla bontà di
una modifica che si ritiene appropriata e senza alcun problema tecnico
importante. Qualsiasi revisore interessato (quelli che lo hanno fatto)
possono offrire il proprio Reviewed-by per la patch. Questa etichetta serve
a dare credito ai revisori e a informare i manutentori sul livello di revisione
che è stato fatto sulla patch. L'etichetta Reviewed-by, quando fornita da
revisori conosciuti per la loro conoscenza sulla materia in oggetto e per la
loro serietà nella revisione, accrescerà le probabilità che la vostra patch
venga integrate nel kernel.
Quando si riceve una email sulla lista di discussione da un tester o
un revisore, le etichette Tested-by o Reviewed-by devono essere
aggiunte dall'autore quando invierà nuovamente la patch. Tuttavia, se
la patch è cambiata in modo significativo, queste etichette potrebbero
non avere più senso e quindi andrebbero rimosse. Solitamente si tiene traccia
della rimozione nel changelog della patch (subito dopo il separatore '---').
L'etichetta Suggested-by: indica che l'idea della patch è stata suggerita
dalla persona nominata e le da credito. Tenete a mente che questa etichetta
non dovrebbe essere aggiunta senza un permesso esplicito, specialmente se
l'idea non è stata pubblicata in un forum pubblico. Detto ciò, dando credito
a chi ci fornisce delle idee, si spera di poterli ispirare ad aiutarci
nuovamente in futuro.
L'etichetta Fixes: indica che la patch corregge un problema in un commit
precedente. Serve a chiarire l'origine di un baco, il che aiuta la revisione
del baco stesso. Questa etichetta è di aiuto anche per i manutentori dei
kernel stabili al fine di capire quale kernel deve ricevere la correzione.
Questo è il modo suggerito per indicare che un baco è stato corretto nella
patch. Per maggiori dettagli leggete :ref:`it_describe_changes`
Da notare che aggiungere un tag "Fixes:" non esime dalle regole
previste per i kernel stabili, e nemmeno dalla necessità di aggiungere
in copia conoscenza stable@vger.kernel.org su tutte le patch per
suddetti kernel.
.. _it_the_canonical_patch_format:
Il formato canonico delle patch
-------------------------------
Questa sezione descrive il formato che dovrebbe essere usato per le patch.
Notate che se state usando un repositorio ``git`` per salvare le vostre patch
potere usare il comando ``git format-patch`` per ottenere patch nel formato
appropriato. Lo strumento non crea il testo necessario, per cui, leggete
le seguenti istruzioni.
L'oggetto di una patch canonica è la riga::
Subject: [PATCH 001/123] subsystem: summary phrase
Il corpo di una patch canonica contiene i seguenti elementi:
- Una riga ``from`` che specifica l'autore della patch, seguita
da una riga vuota (necessaria soltanto se la persona che invia la
patch non ne è l'autore).
- Il corpo della spiegazione, con linee non più lunghe di 75 caratteri,
che verrà copiato permanentemente nel changelog per descrivere la patch.
- Una riga vuota
- Le righe ``Signed-off-by:``, descritte in precedenza, che finiranno
anch'esse nel changelog.
- Una linea di demarcazione contenente semplicemente ``---``.
- Qualsiasi altro commento che non deve finire nel changelog.
- Le effettive modifiche al codice (il prodotto di ``diff``).
Il formato usato per l'oggetto permette ai programmi di posta di usarlo
per ordinare le patch alfabeticamente - tutti i programmi di posta hanno
questa funzionalità - dato che al numero sequenziale si antepongono degli zeri;
in questo modo l'ordine numerico ed alfabetico coincidono.
Il ``subsystem`` nell'oggetto dell'email dovrebbe identificare l'area
o il sottosistema modificato dalla patch.
La ``summary phrase`` nell'oggetto dell'email dovrebbe descrivere brevemente
il contenuto della patch. La ``summary phrase`` non dovrebbe essere un nome
di file. Non utilizzate la stessa ``summary phrase`` per tutte le patch in
una serie (dove una ``serie di patch`` è una sequenza ordinata di diverse
patch correlate).
Ricordatevi che la ``summary phrase`` della vostra email diventerà un
identificatore globale ed unico per quella patch. Si propaga fino al
changelog ``git``. La ``summary phrase`` potrà essere usata in futuro
dagli sviluppatori per riferirsi a quella patch. Le persone vorranno
cercare la ``summary phrase`` su internet per leggere le discussioni che la
riguardano. Potrebbe anche essere l'unica cosa che le persone vedranno
quando, in due o tre mesi, riguarderanno centinaia di patch usando strumenti
come ``gitk`` o ``git log --oneline``.
Per queste ragioni, dovrebbe essere lunga fra i 70 e i 75 caratteri, e deve
descrivere sia cosa viene modificato, sia il perché sia necessario. Essere
brevi e descrittivi è una bella sfida, ma questo è quello che fa un riassunto
ben scritto.
La ``summary phrase`` può avere un'etichetta (*tag*) di prefisso racchiusa fra
le parentesi quadre "Subject: [PATCH <tag>...] <summary phrase>".
Le etichette non verranno considerate come parte della frase riassuntiva, ma
indicano come la patch dovrebbe essere trattata. Fra le etichette più comuni
ci sono quelle di versione che vengono usate quando una patch è stata inviata
più volte (per esempio, "v1, v2, v3"); oppure "RFC" per indicare che si
attendono dei commenti (*Request For Comments*).
Se ci sono quattro patch nella serie, queste dovrebbero essere
enumerate così: 1/4, 2/4, 3/4, 4/4. Questo assicura che gli
sviluppatori capiranno l'ordine in cui le patch dovrebbero essere
applicate, e per tracciare quelle che hanno revisionate o che hanno
applicato.
Un paio di esempi di oggetti::
Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching
Subject: [PATCH v2 01/27] x86: fix eflags tracking
Subject: [PATCH v2] sub/sys: Condensed patch summary
Subject: [PATCH v2 M/N] sub/sys: Condensed patch summary
La riga ``from`` dev'essere la prima nel corpo del messaggio ed è nel
formato:
From: Patch Author <author@example.com>
La riga ``from`` indica chi verrà accreditato nel changelog permanente come
l'autore della patch. Se la riga ``from`` è mancante, allora per determinare
l'autore da inserire nel changelog verrà usata la riga ``From``
nell'intestazione dell'email.
Il corpo della spiegazione verrà incluso nel changelog permanente, per cui
deve aver senso per un lettore esperto che è ha dimenticato i dettagli della
discussione che hanno portato alla patch. L'inclusione di informazioni
sui problemi oggetto dalla patch (messaggi del kernel, messaggi di oops,
eccetera) è particolarmente utile per le persone che potrebbero cercare fra
i messaggi di log per la patch che li tratta. Il testo dovrebbe essere scritto
con abbastanza dettagli da far capire al lettore **perché** quella
patch fu creata, e questo a distanza di settimane, mesi, o addirittura
anni.
Se la patch corregge un errore di compilazione, non sarà necessario
includere proprio _tutto_ quello che è uscito dal compilatore;
aggiungete solo quello che è necessario per far si che la vostra patch
venga trovata. Come nella ``summary phrase``, è importante essere sia
brevi che descrittivi.
La linea di demarcazione ``---`` serve essenzialmente a segnare dove finisce
il messaggio di changelog.
Aggiungere il ``diffstat`` dopo ``---`` è un buon uso di questo spazio, per
mostrare i file che sono cambiati, e il numero di file aggiunto o rimossi.
Un ``diffstat`` è particolarmente utile per le patch grandi. Se
includete un ``diffstat`` dopo ``---``, usate le opzioni ``-p 1 -w70``
cosicché i nomi dei file elencati non occupino troppo spazio
(facilmente rientreranno negli 80 caratteri, magari con qualche
indentazione). (``git`` genera di base dei diffstat adatti).
I commenti che sono importanti solo per i manutentori, quindi
inadatti al changelog permanente, dovrebbero essere messi qui. Un
buon esempio per questo tipo di commenti potrebbe essere il cosiddetto
``patch changelogs`` che descrivere le differenze fra le versioni
della patch.
Queste informazioni devono andare **dopo** la linea ``---`` che separa
il *changelog* dal resto della patch. Le informazioni riguardanti la
versione di una patch non sono parte del *chagelog* che viene incluso
in git. Queste sono informazioni utili solo ai revisori. Se venissero
messe sopra la riga, qualcuno dovrà fare del lavoro manuale per
rimuoverle; cosa che invece viene fatta automaticamente quando vengono
messe correttamente oltre la riga.::
<commit message>
...
Signed-off-by: Author <author@mail>
---
V2 -> V3: Removed redundant helper function
V1 -> V2: Cleaned up coding style and addressed review comments
path/to/file | 5+++--
...
Maggiori dettagli sul formato delle patch nei riferimenti qui di seguito.
.. _it_backtraces:
Aggiungere i *backtrace* nei messaggi di commit
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I *backtrace* aiutano a documentare la sequenza di chiamate a funzione
che portano ad un problema. Tuttavia, non tutti i *backtrace* sono
davvero utili. Per esempio, le sequenze iniziali di avvio sono uniche
e ovvie. Copiare integralmente l'output di ``dmesg`` aggiunge tante
informazioni che distraggono dal vero problema (per esempio, i
marcatori temporali, la lista dei moduli, la lista dei registri, lo
stato dello stack).
Quindi, per rendere utile un *backtrace* dovreste eliminare le
informazioni inutili, cosicché ci si possa focalizzare sul
problema. Ecco un esempio di un *backtrace* essenziale::
unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064)
at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20)
Call Trace:
mba_wrmsr
update_domains
rdtgroup_mkdir
.. _it_explicit_in_reply_to:
Usare esplicitamente In-Reply-To nell'intestazione
--------------------------------------------------
Aggiungere manualmente In-Reply-To: nell'intestazione dell'e-mail
potrebbe essere d'aiuto per associare una patch ad una discussione
precedente, per esempio per collegare la correzione di un baco con l'e-mail
che lo riportava. Tuttavia, per serie di patch multiple è generalmente
sconsigliato l'uso di In-Reply-To: per collegare precedenti versioni.
In questo modo versioni multiple di una patch non diventeranno un'ingestibile
giungla di riferimenti all'interno dei programmi di posta. Se un collegamento
è utile, potete usare https://lore.kernel.org/ per ottenere i collegamenti
ad una versione precedente di una serie di patch (per esempio, potete usarlo
per l'email introduttiva alla serie).
Fornire informazioni circa i sorgenti
-------------------------------------
Quando gli altri sviluppatori ricevono le vostre patch e iniziano il processo di
revisione, è assolutamente necessario che sappiano qual è il commit/ramo di base
su cui si base il vostro lavoro: considerate l'enorme quantità di sorgenti dei
manutentori presenti al giorno d'oggi. Si noti ancora una volta la voce **T:**
nel file MAINTAINERS spiegato sopra.
Questo è ancora più importante per i processi automatizzati di CI che tentano di
eseguire una serie di test per stabilire la qualità del codice prima che il
manutentore inizi la revisione.
Se si usa ``git format-patch`` per generare le patch, si possono includere
automaticamente le informazioni sull'albero di base nell'invio usando il flag
``--base``. Il modo più semplice e comodo di usare questa opzione è con i rami
topici::
$ git checkout -t -b my-topical-branch master
Branch 'my-topical-branch' set up to track local branch 'master'.
Switched to a new branch 'my-topical-branch'
[perform your edits and commits]
$ git format-patch --base=auto --cover-letter -o outgoing/ master
outgoing/0000-cover-letter.patch
outgoing/0001-First-Commit.patch
outgoing/...
Aprendo ``outgoing/0000-cover-letter.patch`` per la modifica, si noterà
che ha ``base-commit:`` in fondo, questo fornisce al revisore e agli
strumenti CI informazioni sufficienti per eseguire correttamente ``git am``
senza preoccuparsi dei conflitti::
$ git checkout -b patch-review [base-commit-id]
Switched to a new branch 'patch-review'
$ git am patches.mbox
Applying: First Commit
Applying: ...
Consultate ``man git-format-patch`` per maggiori informazioni circa questa
opzione.
.. note::
L'opzione ``--base`` fu introdotta con git versione 2.9.0
Se non si usa git per produrre le patch, si può comunque includere
``base-commit`` per indicare l'hash del commit dei sorgenti su cui si basa il
lavoro. Dovreste aggiungerlo nella lettera di accompagnamento o nella prima
patch della serie e dovrebbe essere collocato sotto la riga ``---`` o in fondo a
tutti gli altri contenuti, subito prima della vostra firma e-mail.
Assicuratevi che il commit si basi su sorgenti ufficiali del
manutentore/mainline e non su sorgenti interni, accessibile solo a voi,
altrimenti sarebbe inutile.
Strumenti
---------
Molti degli aspetti più tecnici di questo processo possono essere automatizzati
usando b4, la cui documentazione è disponibile all'indirizzo
<https://b4.docs.kernel.org/en/latest/>. Può aiutare a tracciare la dipendenze,
eseguire checkpatch e con la formattazione e l'invio di messaggi di posta.
Riferimenti
-----------
Andrew Morton, "La patch perfetta" (tpp).
<https://www.ozlabs.org/~akpm/stuff/tpp.txt>
Jeff Garzik, "Formato per la sottomissione di patch per il kernel Linux"
<https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html>
Greg Kroah-Hartman, "Come scocciare un manutentore di un sottosistema"
<http://www.kroah.com/log/linux/maintainer.html>
<http://www.kroah.com/log/linux/maintainer-02.html>
<http://www.kroah.com/log/linux/maintainer-03.html>
<http://www.kroah.com/log/linux/maintainer-04.html>
<http://www.kroah.com/log/linux/maintainer-05.html>
<http://www.kroah.com/log/linux/maintainer-06.html>
Kernel Documentation/translations/it_IT/process/coding-style.rst.
E-mail di Linus Torvalds sul formato canonico di una patch:
<https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org>
Andi Kleen, "Su come sottomettere patch del kernel"
Alcune strategie su come sottomettere modifiche toste o controverse.
http://halobates.de/on-submitting-patches.pdf
@@ -0,0 +1,134 @@
.. include:: ../disclaimer-ita.rst
:Original: :ref:`Documentation/process/volatile-considered-harmful.rst <volatile_considered_harmful>`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
.. _it_volatile_considered_harmful:
Perché la parola chiave "volatile" non dovrebbe essere usata
------------------------------------------------------------
Spesso i programmatori C considerano volatili quelle variabili che potrebbero
essere cambiate al di fuori dal thread di esecuzione corrente; come risultato,
a volte saranno tentati dall'utilizzare *volatile* nel kernel per le
strutture dati condivise. In altre parole, gli è stato insegnato ad usare
*volatile* come una variabile atomica di facile utilizzo, ma non è così.
L'uso di *volatile* nel kernel non è quasi mai corretto; questo documento ne
descrive le ragioni.
Il punto chiave da capire su *volatile* è che il suo scopo è quello di
sopprimere le ottimizzazioni, che non è quasi mai quello che si vuole.
Nel kernel si devono proteggere le strutture dati condivise contro accessi
concorrenti e indesiderati: questa è un'attività completamente diversa.
Il processo di protezione contro gli accessi concorrenti indesiderati eviterà
anche la maggior parte dei problemi relativi all'ottimizzazione in modo più
efficiente.
Come *volatile*, le primitive del kernel che rendono sicuro l'accesso ai dati
(spinlock, mutex, barriere di sincronizzazione, ecc) sono progettate per
prevenire le ottimizzazioni indesiderate. Se vengono usate opportunamente,
non ci sarà bisogno di utilizzare *volatile*. Se vi sembra che *volatile* sia
comunque necessario, ci dev'essere quasi sicuramente un baco da qualche parte.
In un pezzo di codice kernel scritto a dovere, *volatile* può solo servire a
rallentare le cose.
Considerate questo tipico blocco di codice kernel::
spin_lock(&the_lock);
do_something_on(&shared_data);
do_something_else_with(&shared_data);
spin_unlock(&the_lock);
Se tutto il codice seguisse le regole di sincronizzazione, il valore di un
dato condiviso non potrebbe cambiare inaspettatamente mentre si trattiene un
lock. Un qualsiasi altro blocco di codice che vorrà usare quel dato rimarrà
in attesa del lock. Gli spinlock agiscono come barriere di sincronizzazione
- sono stati esplicitamente scritti per agire così - il che significa che gli
accessi al dato condiviso non saranno ottimizzati. Quindi il compilatore
potrebbe pensare di sapere cosa ci sarà nel dato condiviso ma la chiamata
spin_lock(), che agisce come una barriera di sincronizzazione, gli imporrà di
dimenticarsi tutto ciò che sapeva su di esso.
Se il dato condiviso fosse stato dichiarato come *volatile*, la
sincronizzazione rimarrebbe comunque necessaria. Ma verrà impedito al
compilatore di ottimizzare gli accessi al dato anche _dentro_ alla sezione
critica, dove sappiamo che in realtà nessun altro può accedervi. Mentre si
trattiene un lock, il dato condiviso non è *volatile*. Quando si ha a che
fare con dei dati condivisi, un'opportuna sincronizzazione rende inutile
l'uso di *volatile* - anzi potenzialmente dannoso.
L'uso di *volatile* fu originalmente pensato per l'accesso ai registri di I/O
mappati in memoria. All'interno del kernel, l'accesso ai registri, dovrebbe
essere protetto dai lock, ma si potrebbe anche desiderare che il compilatore
non "ottimizzi" l'accesso ai registri all'interno di una sezione critica.
Ma, all'interno del kernel, l'accesso alla memoria di I/O viene sempre fatto
attraverso funzioni d'accesso; accedere alla memoria di I/O direttamente
con i puntatori è sconsigliato e non funziona su tutte le architetture.
Queste funzioni d'accesso sono scritte per evitare ottimizzazioni indesiderate,
quindi, di nuovo, *volatile* è inutile.
Un'altra situazione dove qualcuno potrebbe essere tentato dall'uso di
*volatile*, è nel caso in cui il processore è in un'attesa attiva sul valore
di una variabile. Il modo giusto di fare questo tipo di attesa è il seguente::
while (my_variable != what_i_want)
cpu_relax();
La chiamata cpu_relax() può ridurre il consumo di energia del processore
o cedere il passo ad un processore hyperthreaded gemello; funziona anche come
una barriera per il compilatore, quindi, ancora una volta, *volatile* non è
necessario. Ovviamente, tanto per puntualizzare, le attese attive sono
generalmente un atto antisociale.
Ci sono comunque alcune rare situazioni dove l'uso di *volatile* nel kernel
ha senso:
- Le funzioni d'accesso sopracitate potrebbero usare *volatile* su quelle
architetture che supportano l'accesso diretto alla memoria di I/O.
In pratica, ogni chiamata ad una funzione d'accesso diventa una piccola
sezione critica a se stante, e garantisce che l'accesso avvenga secondo
le aspettative del programmatore.
- I codice *inline assembly* che fa cambiamenti nella memoria, ma che non
ha altri effetti espliciti, rischia di essere rimosso da GCC. Aggiungere
la parola chiave *volatile* a questo codice ne previene la rimozione.
- La variabile jiffies è speciale in quanto assume un valore diverso ogni
volta che viene letta ma può essere lette senza alcuna sincronizzazione.
Quindi jiffies può essere *volatile*, ma l'aggiunta ad altre variabili di
questo è sconsigliata. Jiffies è considerata uno "stupido retaggio"
(parole di Linus) in questo contesto; correggerla non ne varrebbe la pena e
causerebbe più problemi.
- I puntatori a delle strutture dati in una memoria coerente che potrebbe
essere modificata da dispositivi di I/O può, a volte, essere legittimamente
*volatile*. Un esempio pratico può essere quello di un adattatore di rete
che utilizza un puntatore ad un buffer circolare, questo viene cambiato
dall'adattatore per indicare quali descrittori sono stati processati.
Per la maggior parte del codice, nessuna delle giustificazioni sopracitate può
essere considerata. Di conseguenza, l'uso di *volatile* è probabile che venga
visto come un baco e porterà a verifiche aggiuntive. Gli sviluppatori tentati
dall'uso di *volatile* dovrebbero fermarsi e pensare a cosa vogliono davvero
ottenere.
Le modifiche che rimuovono variabili *volatile* sono generalmente ben accette
- purché accompagnate da una giustificazione che dimostri che i problemi di
concorrenza siano stati opportunamente considerati.
Riferimenti
===========
[1] https://lwn.net/Articles/233481/
[2] https://lwn.net/Articles/233482/
Crediti
=======
Impulso e ricerca originale di Randy Dunlap
Scritto da Jonathan Corbet
Migliorato dai commenti di Satyam Sharma, Johannes Stezenbach, Jesper
Juhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, e Stefan Richter.