doc🇮🇹 add some process/* translations
Translated documents: - 2.Process - 3.Early-stage - 4.Coding - 5.Posting - 6.Followthrough - 7.AdvancedTopics - 8.Conclusion - adding-syscalls Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it> Signed-off-by: Alessia Mantegazza <amantegazza@vaga.pv.it> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
a4a2bf0e24
commit
fdf0345e59
|
@ -1,12 +1,531 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/2.Process.rst <development_process>`
|
:Original: :ref:`Documentation/process/2.Process.rst <development_process>`
|
||||||
|
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_process:
|
.. _it_development_process:
|
||||||
|
|
||||||
Come funziona il processo di sviluppo
|
Come funziona il processo di sviluppo
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
Il quadro d'insieme
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Gli sviluppatori kernel utilizzano un calendario di rilascio generico, dove
|
||||||
|
ogni due o tre mesi viene effettuata un rilascio importante del kernel.
|
||||||
|
I rilasci più recenti sono stati:
|
||||||
|
|
||||||
|
====== =================
|
||||||
|
4.11 Aprile 30, 2017
|
||||||
|
4.12 Luglio 2, 2017
|
||||||
|
4.13 Settembre 3, 2017
|
||||||
|
4.14 Novembre 12, 2017
|
||||||
|
4.15 Gennaio 28, 2018
|
||||||
|
4.16 Aprile 1, 2018
|
||||||
|
====== =================
|
||||||
|
|
||||||
|
Ciascun rilascio 4.x è un importante rilascio del kernel con nuove
|
||||||
|
funzionalità, modifiche interne dell'API, e molto altro. Un tipico
|
||||||
|
rilascio 4.x contiene quasi 13,000 gruppi di modifiche con ulteriori
|
||||||
|
modifiche a parecchie migliaia di linee di codice. La 4.x. è pertanto la
|
||||||
|
linea di confine nello sviluppo del kernel Linux; il kernel utilizza un sistema
|
||||||
|
di sviluppo continuo che integra costantemente nuove importanti modifiche.
|
||||||
|
|
||||||
|
Viene seguita una disciplina abbastanza lineare per l'inclusione delle
|
||||||
|
patch di ogni rilascio. All'inizio di ogni ciclo di sviluppo, la
|
||||||
|
"finestra di inclusione" viene dichiarata aperta. In quel momento il codice
|
||||||
|
ritenuto sufficientemente stabile(e che è accettato dalla comunità di sviluppo)
|
||||||
|
viene incluso nel ramo principale del kernel. La maggior parte delle
|
||||||
|
patch per un nuovo ciclo di sviluppo (e tutte le più importanti modifiche)
|
||||||
|
saranno inserite durante questo periodo, ad un ritmo che si attesta sulle
|
||||||
|
1000 modifiche ("patch" o "gruppo di modifiche") al giorno.
|
||||||
|
|
||||||
|
(per inciso, vale la pena notare che i cambiamenti integrati durante la
|
||||||
|
"finestra di inclusione" non escono dal nulla; questi infatti, sono stati
|
||||||
|
raccolti e, verificati in anticipo. Il funzionamento di tale procedimento
|
||||||
|
verrà descritto dettagliatamente più avanti).
|
||||||
|
|
||||||
|
La finestra di inclusione resta attiva approssimativamente per due settimane.
|
||||||
|
Al termine di questo periodo, Linus Torvald dichiarerà che la finestra è
|
||||||
|
chiusa e rilascerà il primo degli "rc" del kernel.
|
||||||
|
Per il kernel che è destinato ad essere 2.6.40, per esempio, il rilascio
|
||||||
|
che emerge al termine della finestra d'inclusione si chiamerà 2.6.40-rc1.
|
||||||
|
Questo rilascio indica che il momento di aggiungere nuovi componenti è
|
||||||
|
passato, e che è iniziato il periodo di stabilizzazione del prossimo kernel.
|
||||||
|
|
||||||
|
Nelle successive sei/dieci settimane, potranno essere sottoposte solo modifiche
|
||||||
|
che vanno a risolvere delle problematiche. Occasionalmente potrà essere
|
||||||
|
consentita una modifica più consistente, ma tali occasioni sono rare.
|
||||||
|
Gli sviluppatori che tenteranno di aggiungere nuovi elementi al di fuori della
|
||||||
|
finestra di inclusione, tendenzialmente, riceveranno un accoglienza poco
|
||||||
|
amichevole. Come regola generale: se vi perdete la finestra di inclusione per
|
||||||
|
un dato componente, la cosa migliore da fare è aspettare il ciclo di sviluppo
|
||||||
|
successivo (un'eccezione può essere fatta per i driver per hardware non
|
||||||
|
supportati in precedenza; se toccano codice non facente parte di quello
|
||||||
|
attuale, che non causino regressioni e che potrebbero essere aggiunti in
|
||||||
|
sicurezza in un qualsiasi momento)
|
||||||
|
|
||||||
|
Mentre le correzioni si aprono la loro strada all'interno del ramo principale,
|
||||||
|
il ritmo delle modifiche rallenta col tempo. Linus rilascia un nuovo
|
||||||
|
kernel -rc circa una volta alla settimana; e ne usciranno circa 6 o 9 prima
|
||||||
|
che il kernel venga considerato sufficientemente stabile e che il rilascio
|
||||||
|
finale 2.6.x venga fatto. A quel punto tutto il processo ricomincerà.
|
||||||
|
|
||||||
|
Esempio: ecco com'è andato il ciclo di sviluppo della versione 4.16
|
||||||
|
(tutte le date si collocano nel 2018)
|
||||||
|
|
||||||
|
|
||||||
|
============== =======================================
|
||||||
|
Gennaio 28 4.15 rilascio stabile
|
||||||
|
Febbraio 11 4.16-rc1, finestra di inclusione chiusa
|
||||||
|
Febbraio 18 4.16-rc2
|
||||||
|
Febbraio 25 4.16-rc3
|
||||||
|
Marzo 4 4.16-rc4
|
||||||
|
Marzo 11 4.16-rc5
|
||||||
|
Marzo 18 4.16-rc6
|
||||||
|
Marzo 25 4.16-rc7
|
||||||
|
Aprile 1 4.17 rilascio stabile
|
||||||
|
============== =======================================
|
||||||
|
|
||||||
|
In che modo gli sviluppatori decidono quando chiudere il ciclo di sviluppo e
|
||||||
|
creare quindi una rilascio stabile? Un metro valido è il numero di regressioni
|
||||||
|
rilevate nel precedente rilascio. Nessun baco è il benvenuto, ma quelli che
|
||||||
|
procurano problemi su sistemi che hanno funzionato in passato sono considerati
|
||||||
|
particolarmente seri. Per questa ragione, le modifiche che portano ad una
|
||||||
|
regressione sono viste sfavorevolmente e verranno quasi sicuramente annullate
|
||||||
|
durante il periodo di stabilizzazione.
|
||||||
|
|
||||||
|
L'obiettivo degli sviluppatori è quello di aggiustare tutte le regressioni
|
||||||
|
conosciute prima che avvenga il rilascio stabile. Nel mondo reale, questo
|
||||||
|
tipo di perfezione difficilmente viene raggiunta; esistono troppe variabili
|
||||||
|
in un progetto di questa portata. Arriva un punto dove ritardare il rilascio
|
||||||
|
finale peggiora la situazione; la quantità di modifiche in attesa della
|
||||||
|
prossima finestra di inclusione crescerà enormemente, creando ancor più
|
||||||
|
regressioni al giro successivo. Quindi molti kernel 4.x escono con una
|
||||||
|
manciata di regressioni delle quali, si spera, nessuna è grave.
|
||||||
|
|
||||||
|
Una volta che un rilascio stabile è fatto, il suo costante mantenimento è
|
||||||
|
affidato al "squadra stabilità", attualmente composta da Greg Kroah-Hartman.
|
||||||
|
Questa squadra rilascia occasionalmente degli aggiornamenti relativi al
|
||||||
|
rilascio stabile usando la numerazione 4.x.y. Per essere presa in
|
||||||
|
considerazione per un rilascio d'aggiornamento, una modifica deve:
|
||||||
|
(1) correggere un baco importante (2) essere già inserita nel ramo principale
|
||||||
|
per il prossimo sviluppo del kernel. Solitamente, passato il loro rilascio
|
||||||
|
iniziale, i kernel ricevono aggiornamenti per più di un ciclo di sviluppo.
|
||||||
|
Quindi, per esempio, la storia del kernel 4.13 appare così:
|
||||||
|
|
||||||
|
============== ===============================
|
||||||
|
Settembre 3 4.13 rilascio stabile
|
||||||
|
Settembre 13 4.13.1
|
||||||
|
Settembre 20 4.13.2
|
||||||
|
Settembre 27 4.13.3
|
||||||
|
Ottobre 5 4.13.4
|
||||||
|
Ottobre 12 4.13.5
|
||||||
|
... ...
|
||||||
|
Novembre 24 4.13.16
|
||||||
|
============== ===============================
|
||||||
|
|
||||||
|
La 4.13.16 fu l'aggiornamento finale per la versione 4.13.
|
||||||
|
|
||||||
|
Alcuni kernel sono destinati ad essere kernel a "lungo termine"; questi
|
||||||
|
riceveranno assistenza per un lungo periodo di tempo. Al momento in cui
|
||||||
|
scriviamo, i manutentori dei kernel stabili a lungo termine sono:
|
||||||
|
|
||||||
|
====== ====================== ==========================================
|
||||||
|
3.16 Ben Hutchings (kernel stabile molto più a lungo termine)
|
||||||
|
4.1 Sasha Levin
|
||||||
|
4.4 Greg Kroah-Hartman (kernel stabile molto più a lungo termine)
|
||||||
|
4.9 Greg Kroah-Hartman
|
||||||
|
4.14 Greg Kroah-Hartman
|
||||||
|
====== ====================== ==========================================
|
||||||
|
|
||||||
|
|
||||||
|
Questa selezione di kernel di lungo periodo sono puramente dovuti ai loro
|
||||||
|
manutentori, alla loro necessità e al tempo per tenere aggiornate proprio
|
||||||
|
quelle versioni. Non ci sono altri kernel a lungo termine in programma per
|
||||||
|
alcun rilascio in arrivo.
|
||||||
|
|
||||||
|
Il ciclo di vita di una patch
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Le patch non passano direttamente dalla tastiera dello sviluppatori
|
||||||
|
al ramo principale del kernel. Esiste, invece, una procedura disegnata
|
||||||
|
per assicurare che ogni patch sia di buona qualità e desiderata nel
|
||||||
|
ramo principale. Questo processo avviene velocemente per le correzioni
|
||||||
|
meno importanti, o, nel caso di patch ampie e controverse, va avanti per anni.
|
||||||
|
Per uno sviluppatore la maggior frustrazione viene dalla mancanza di
|
||||||
|
comprensione di questo processo o dai tentativi di aggirarlo.
|
||||||
|
|
||||||
|
Nella speranza di ridurre questa frustrazione, questo documento spiegherà
|
||||||
|
come una patch viene inserita nel kernel. Ciò che segue è un'introduzione
|
||||||
|
che descrive il processo ideale. Approfondimenti verranno invece trattati
|
||||||
|
più avanti.
|
||||||
|
|
||||||
|
Una patch attraversa, generalmente, le seguenti fasi:
|
||||||
|
|
||||||
|
- Progetto. In questa fase sono stabilite quelli che sono i requisiti
|
||||||
|
della modifica - e come verranno soddisfatti. Il lavoro di progettazione
|
||||||
|
viene spesso svolto senza coinvolgere la comunità, ma è meglio renderlo
|
||||||
|
il più aperto possibile; questo può far risparmiare molto tempo evitando
|
||||||
|
eventuali riprogettazioni successive.
|
||||||
|
|
||||||
|
- Prima revisione. Le patch vengono pubblicate sulle liste di discussione
|
||||||
|
interessate, e gli sviluppatori in quella lista risponderanno coi loro
|
||||||
|
commenti. Se si svolge correttamente, questo procedimento potrebbe far
|
||||||
|
emergere problemi rilevanti in una patch.
|
||||||
|
|
||||||
|
- Revisione più ampia. Quando la patch è quasi pronta per essere inserita
|
||||||
|
nel ramo principale, un manutentore importante del sottosistema dovrebbe
|
||||||
|
accettarla - anche se, questa accettazione non è una garanzia che la
|
||||||
|
patch arriverà nel ramo principale. La patch sarà visibile nei sorgenti
|
||||||
|
del sottosistema in questione e nei sorgenti -next (descritti sotto).
|
||||||
|
Quando il processo va a buon fine, questo passo porta ad una revisione
|
||||||
|
più estesa della patch e alla scoperta di problemi d'integrazione
|
||||||
|
con il lavoro altrui.
|
||||||
|
|
||||||
|
- Per favore, tenete da conto che la maggior parte dei manutentori ha
|
||||||
|
anche un lavoro quotidiano, quindi integrare le vostre patch potrebbe
|
||||||
|
non essere la loro priorità più alta. Se una vostra patch riceve
|
||||||
|
dei suggerimenti su dei cambiamenti necessari, dovreste applicare
|
||||||
|
quei cambiamenti o giustificare perché non sono necessari. Se la vostra
|
||||||
|
patch non riceve alcuna critica ma non è stata integrata dal
|
||||||
|
manutentore del driver o sottosistema, allora dovreste continuare con
|
||||||
|
i necessari aggiornamenti per mantenere la patch aggiornata al kernel
|
||||||
|
più recente cosicché questa possa integrarsi senza problemi; continuate
|
||||||
|
ad inviare gli aggiornamenti per essere revisionati e integrati.
|
||||||
|
|
||||||
|
- Inclusione nel ramo principale. Eventualmente, una buona patch verrà
|
||||||
|
inserita all'interno nel repositorio principale, gestito da
|
||||||
|
Linus Torvalds. In questa fase potrebbero emergere nuovi problemi e/o
|
||||||
|
commenti; è importante che lo sviluppatore sia collaborativo e che sistemi
|
||||||
|
ogni questione che possa emergere.
|
||||||
|
|
||||||
|
- Rilascio stabile. Ora, il numero di utilizzatori che sono potenzialmente
|
||||||
|
toccati dalla patch è aumentato, quindi, ancora una volta, potrebbero
|
||||||
|
emergere nuovi problemi.
|
||||||
|
|
||||||
|
- Manutenzione di lungo periodo. Nonostante sia possibile che uno sviluppatore
|
||||||
|
si dimentichi del codice dopo la sua integrazione, questo comportamento
|
||||||
|
lascia una brutta impressione nella comunità di sviluppo. Integrare il
|
||||||
|
codice elimina alcuni degli oneri facenti parte della manutenzione, in
|
||||||
|
particolare, sistemerà le problematiche causate dalle modifiche all'API.
|
||||||
|
Ma lo sviluppatore originario dovrebbe continuare ad assumersi la
|
||||||
|
responsabilità per il codice se quest'ultimo continua ad essere utile
|
||||||
|
nel lungo periodo.
|
||||||
|
|
||||||
|
Uno dei più grandi errori fatti dagli sviluppatori kernel (o dai loro datori
|
||||||
|
di lavoro) è quello di cercare di ridurre tutta la procedura ad una singola
|
||||||
|
"integrazione nel remo principale". Questo approccio inevitabilmente conduce
|
||||||
|
a una condizione di frustrazione per tutti coloro che sono coinvolti.
|
||||||
|
|
||||||
|
Come le modifiche finiscono nel Kernel
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Esiste una sola persona che può inserire le patch nel repositorio principale
|
||||||
|
del kernel: Linus Torvalds. Ma, di tutte le 9500 patch che entrarono nella
|
||||||
|
versione 2.6.38 del kernel, solo 112 (circa l'1,3%) furono scelte direttamente
|
||||||
|
da Linus in persona. Il progetto del kernel è cresciuto fino a raggiungere
|
||||||
|
una dimensione tale per cui un singolo sviluppatore non può controllare e
|
||||||
|
selezionare indipendentemente ogni modifica senza essere supportato.
|
||||||
|
La via scelta dagli sviluppatori per indirizzare tale crescita è stata quella
|
||||||
|
di utilizzare un sistema di "sottotenenti" basato sulla fiducia.
|
||||||
|
|
||||||
|
Il codice base del kernel è spezzato in una serie si sottosistemi: rete,
|
||||||
|
supporto per specifiche architetture, gestione della memoria, video e
|
||||||
|
strumenti, etc. Molti sottosistemi hanno un manutentore designato: ovvero uno
|
||||||
|
sviluppatore che ha piena responsabilità di tutto il codice presente in quel
|
||||||
|
sottosistema. Tali manutentori di sottosistema sono i guardiani
|
||||||
|
(in un certo senso) della parte di kernel che gestiscono; sono coloro che
|
||||||
|
(solitamente) accetteranno una patch per l'inclusione nel ramo principale
|
||||||
|
del kernel.
|
||||||
|
|
||||||
|
I manutentori di sottosistema gestiscono ciascuno la propria parte dei sorgenti
|
||||||
|
del kernel, utilizzando abitualmente (ma certamente non sempre) git.
|
||||||
|
Strumenti come git (e affini come quilt o mercurial) permettono ai manutentori
|
||||||
|
di stilare una lista delle patch, includendo informazioni sull'autore ed
|
||||||
|
altri metadati. In ogni momento, il manutentore può individuare quale patch
|
||||||
|
nel sua repositorio non si trova nel ramo principale.
|
||||||
|
|
||||||
|
Quando la "finestra di integrazione" si apre, i manutentori di alto livello
|
||||||
|
chiederanno a Linus di "prendere" dai loro repositori le modifiche che hanno
|
||||||
|
selezionato per l'inclusione. Se Linus acconsente, il flusso di patch si
|
||||||
|
convoglierà nel repositorio di quest ultimo, divenendo così parte del ramo
|
||||||
|
principale del kernel. La quantità d'attenzione che Linus presta alle
|
||||||
|
singole patch ricevute durante l'operazione di integrazione varia.
|
||||||
|
È chiaro che, qualche volta, guardi più attentamente. Ma, come regola
|
||||||
|
generale, Linus confida nel fatto che i manutentori di sottosistema non
|
||||||
|
selezionino pessime patch.
|
||||||
|
|
||||||
|
I manutentori di sottosistemi, a turno, possono "prendere" patch
|
||||||
|
provenienti da altri manutentori. Per esempio, i sorgenti per la rete rete
|
||||||
|
sono costruiti da modifiche che si sono accumulate inizialmente nei sorgenti
|
||||||
|
dedicati ai driver per dispositivi di rete, rete senza fili, ecc. Tale
|
||||||
|
catena di repositori può essere più o meno lunga, benché raramente ecceda
|
||||||
|
i due o tre collegamenti. Questo processo è conosciuto come
|
||||||
|
"la catena della fiducia", perché ogni manutentore all'interno della
|
||||||
|
catena si fida di coloro che gestiscono i livelli più bassi.
|
||||||
|
|
||||||
|
Chiaramente, in un sistema come questo, l'inserimento delle patch all'interno
|
||||||
|
del kernel si basa sul trovare il manutentore giusto. Di norma, inviare
|
||||||
|
patch direttamente a Linus non è la via giusta.
|
||||||
|
|
||||||
|
|
||||||
|
Sorgenti -next
|
||||||
|
--------------
|
||||||
|
|
||||||
|
La catena di sottosistemi guida il flusso di patch all'interno del kernel,
|
||||||
|
ma solleva anche un interessante quesito: se qualcuno volesse vedere tutte le
|
||||||
|
patch pronte per la prossima finestra di integrazione?
|
||||||
|
Gli sviluppatori si interesseranno alle patch in sospeso per verificare
|
||||||
|
che non ci siano altri conflitti di cui preoccuparsi; una modifica che, per
|
||||||
|
esempio, cambia il prototipo di una funzione fondamentale del kernel andrà in
|
||||||
|
conflitto con qualsiasi altra modifica che utilizzi la vecchia versione di
|
||||||
|
quella funzione. Revisori e tester vogliono invece avere accesso alle
|
||||||
|
modifiche nella loro totalità prima che approdino nel ramo principale del
|
||||||
|
kernel. Uno potrebbe prendere le patch provenienti da tutti i sottosistemi
|
||||||
|
d'interesse, ma questo sarebbe un lavoro enorme e fallace.
|
||||||
|
|
||||||
|
La risposta ci viene sotto forma di sorgenti -next, dove i sottosistemi sono
|
||||||
|
raccolti per essere testati e controllati. Il più vecchio di questi sorgenti,
|
||||||
|
gestito da Andrew Morton, è chiamato "-mm" (memory management, che è l'inizio
|
||||||
|
di tutto). L'-mm integra patch proveniente da una lunga lista di sottosistemi;
|
||||||
|
e ha, inoltre, alcune patch destinate al supporto del debugging.
|
||||||
|
|
||||||
|
Oltre a questo, -mm contiene una raccolta significativa di patch che sono
|
||||||
|
state selezionate da Andrew direttamente. Queste patch potrebbero essere
|
||||||
|
state inviate in una lista di discussione, o possono essere applicate ad una
|
||||||
|
parte del kernel per la quale non esiste un sottosistema dedicato.
|
||||||
|
Di conseguenza, -mm opera come una specie di sottosistema "ultima spiaggia";
|
||||||
|
se per una patch non esiste una via chiara per entrare nel ramo principale,
|
||||||
|
allora è probabile che finirà in -mm. Le patch passate per -mm
|
||||||
|
eventualmente finiranno nel sottosistema più appropriato o saranno inviate
|
||||||
|
direttamente a Linus. In un tipico ciclo di sviluppo, circa il 5-10% delle
|
||||||
|
patch andrà nel ramo principale attraverso -mm.
|
||||||
|
|
||||||
|
La patch -mm correnti sono disponibili nella cartella "mmotm" (-mm of
|
||||||
|
the moment) all'indirizzo:
|
||||||
|
|
||||||
|
http://www.ozlabs.org/~akpm/mmotm/
|
||||||
|
|
||||||
|
È molto probabile che l'uso dei sorgenti MMOTM diventi un'esperienza
|
||||||
|
frustrante; ci sono buone probabilità che non compili nemmeno.
|
||||||
|
|
||||||
|
I sorgenti principali per il prossimo ciclo d'integrazione delle patch
|
||||||
|
è linux-next, gestito da Stephen Rothwell. I sorgenti linux-next sono, per
|
||||||
|
definizione, un'istantanea di come dovrà apparire il ramo principale dopo che
|
||||||
|
la prossima finestra di inclusione si chiuderà. I linux-next sono annunciati
|
||||||
|
sulla lista di discussione linux-kernel e linux-next nel momento in cui
|
||||||
|
vengono assemblati; e possono essere scaricate da:
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/linux/kernel/next/
|
||||||
|
|
||||||
|
Linux-next è divenuto parte integrante del processo di sviluppo del kernel;
|
||||||
|
tutte le patch incorporate durante una finestra di integrazione dovrebbero
|
||||||
|
aver trovato la propria strada in linux-next, a volte anche prima dell'apertura
|
||||||
|
della finestra di integrazione.
|
||||||
|
|
||||||
|
|
||||||
|
Sorgenti in preparazione
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Nei sorgenti del kernel esiste la cartella drivers/staging/, dove risiedono
|
||||||
|
molte sotto-cartelle per i driver o i filesystem che stanno per essere aggiunti
|
||||||
|
al kernel. Questi restano nella cartella drivers/staging fintanto che avranno
|
||||||
|
bisogno di maggior lavoro; una volta completato, possono essere spostate
|
||||||
|
all'interno del kernel nel posto più appropriato. Questo è il modo di tener
|
||||||
|
traccia dei driver che non sono ancora in linea con gli standard di codifica
|
||||||
|
o qualità, ma che le persone potrebbero voler usare ugualmente e tracciarne
|
||||||
|
lo sviluppo.
|
||||||
|
|
||||||
|
Greg Kroah-Hartman attualmente gestisce i sorgenti in preparazione. I driver
|
||||||
|
che non sono completamente pronti vengono inviati a lui, e ciascun driver avrà
|
||||||
|
la propria sotto-cartella in drivers/staging/. Assieme ai file sorgenti
|
||||||
|
dei driver, dovrebbe essere presente nella stessa cartella anche un file TODO.
|
||||||
|
Il file TODO elenca il lavoro ancora da fare su questi driver per poter essere
|
||||||
|
accettati nel kernel, e indica anche la lista di persone da inserire in copia
|
||||||
|
conoscenza per ogni modifica fatta. Le regole attuali richiedono che i
|
||||||
|
driver debbano, come minimo, compilare adeguatamente.
|
||||||
|
|
||||||
|
La *preparazione* può essere una via relativamente facile per inserire nuovi
|
||||||
|
driver all'interno del ramo principale, dove, con un po' di fortuna, saranno
|
||||||
|
notati da altri sviluppatori e migliorati velocemente. Entrare nella fase
|
||||||
|
di preparazione non è però la fine della storia, infatti, il codice che si
|
||||||
|
trova nella cartella staging che non mostra regolari progressi potrebbe
|
||||||
|
essere rimosso. Le distribuzioni, inoltre, tendono a dimostrarsi relativamente
|
||||||
|
riluttanti nell'attivare driver in preparazione. Quindi lo preparazione è,
|
||||||
|
nel migliore dei casi, una tappa sulla strada verso il divenire un driver
|
||||||
|
del ramo principale.
|
||||||
|
|
||||||
|
|
||||||
|
Strumenti
|
||||||
|
---------
|
||||||
|
|
||||||
|
Come è possibile notare dal testo sopra, il processo di sviluppo del kernel
|
||||||
|
dipende pesantemente dalla capacità di guidare la raccolta di patch in
|
||||||
|
diverse direzioni. L'intera cosa non funzionerebbe se non venisse svolta
|
||||||
|
con l'uso di strumenti appropriati e potenti. Spiegare l'uso di tali
|
||||||
|
strumenti non è lo scopo di questo documento, ma c'è spazio per alcuni
|
||||||
|
consigli.
|
||||||
|
|
||||||
|
In assoluto, nella comunità del kernel, predomina l'uso di git come sistema
|
||||||
|
di gestione dei sorgenti. Git è una delle diverse tipologie di sistemi
|
||||||
|
distribuiti di controllo versione che sono stati sviluppati nella comunità
|
||||||
|
del software libero. Esso è calibrato per lo sviluppo del kernel, e si
|
||||||
|
comporta abbastanza bene quando ha a che fare con repositori grandi e con un
|
||||||
|
vasto numero di patch. Git ha inoltre la reputazione di essere difficile
|
||||||
|
da imparare e utilizzare, benché stia migliorando. Agli sviluppatori
|
||||||
|
del kernel viene richiesta un po' di familiarità con git; anche se non lo
|
||||||
|
utilizzano per il proprio lavoro, hanno bisogno di git per tenersi al passo
|
||||||
|
con il lavoro degli altri sviluppatori (e con il ramo principale).
|
||||||
|
|
||||||
|
Git è ora compreso in quasi tutte le distribuzioni Linux. Esiste una sito che
|
||||||
|
potete consultare:
|
||||||
|
|
||||||
|
http://git-scm.com/
|
||||||
|
|
||||||
|
Qui troverete i riferimenti alla documentazione e alle guide passo-passo.
|
||||||
|
|
||||||
|
Tra gli sviluppatori Kernel che non usano git, la scelta alternativa più
|
||||||
|
popolare è quasi sicuramente Mercurial:
|
||||||
|
|
||||||
|
http://www.selenic.com/mercurial/
|
||||||
|
|
||||||
|
Mercurial condivide diverse caratteristiche con git, ma fornisce
|
||||||
|
un'interfaccia che potrebbe risultare più semplice da utilizzare.
|
||||||
|
|
||||||
|
L'altro strumento che vale la pena conoscere è Quilt:
|
||||||
|
|
||||||
|
http://savannah.nongnu.org/projects/quilt/
|
||||||
|
|
||||||
|
|
||||||
|
Quilt è un sistema di gestione delle patch, piuttosto che un sistema
|
||||||
|
di gestione dei sorgenti. Non mantiene uno storico degli eventi; ma piuttosto
|
||||||
|
è orientato verso il tracciamento di uno specifico insieme di modifiche
|
||||||
|
rispetto ad un codice in evoluzione. Molti dei più grandi manutentori di
|
||||||
|
sottosistema utilizzano quilt per gestire le patch che dovrebbero essere
|
||||||
|
integrate. Per la gestione di certe tipologie di sorgenti (-mm, per esempio),
|
||||||
|
quilt è il miglior strumento per svolgere il lavoro.
|
||||||
|
|
||||||
|
|
||||||
|
Liste di discussione
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Una grossa parte del lavoro di sviluppo del Kernel Linux viene svolto tramite
|
||||||
|
le liste di discussione. È difficile essere un membro della comunità
|
||||||
|
pienamente coinvolto se non si partecipa almeno ad una lista da qualche
|
||||||
|
parte. Ma, le liste di discussione di Linux rappresentano un potenziale
|
||||||
|
problema per gli sviluppatori, che rischiano di venir sepolti da un mare di
|
||||||
|
email, restare incagliati nelle convenzioni in vigore nelle liste Linux,
|
||||||
|
o entrambi.
|
||||||
|
|
||||||
|
Molte delle liste di discussione del Kernel girano su vger.kernel.org;
|
||||||
|
l'elenco principale lo si trova sul sito:
|
||||||
|
|
||||||
|
http://vger.kernel.org/vger-lists.html
|
||||||
|
|
||||||
|
Esistono liste gestite altrove; un certo numero di queste sono in
|
||||||
|
lists.redhat.com.
|
||||||
|
|
||||||
|
La lista di discussione principale per lo sviluppo del kernel è, ovviamente,
|
||||||
|
linux-kernel. Questa lista è un luogo ostile dove trovarsi; i volumi possono
|
||||||
|
raggiungere i 500 messaggi al giorno, la quantità di "rumore" è elevata,
|
||||||
|
la conversazione può essere strettamente tecnica e i partecipanti non sono
|
||||||
|
sempre preoccupati di mostrare un alto livello di educazione. Ma non esiste
|
||||||
|
altro luogo dove la comunità di sviluppo del kernel si unisce per intero;
|
||||||
|
gli sviluppatori che evitano tale lista si perderanno informazioni importanti.
|
||||||
|
|
||||||
|
Ci sono alcuni consigli che possono essere utili per sopravvivere a
|
||||||
|
linux-kernel:
|
||||||
|
|
||||||
|
- Tenete la lista in una cartella separata, piuttosto che inserirla nella
|
||||||
|
casella di posta principale. Così da essere in grado di ignorare il flusso
|
||||||
|
di mail per un certo periodo di tempo.
|
||||||
|
|
||||||
|
- Non cercate di seguire ogni conversazione - nessuno lo fa. È importante
|
||||||
|
filtrare solo gli argomenti d'interesse (sebbene va notato che le
|
||||||
|
conversazioni di lungo periodo possono deviare dall'argomento originario
|
||||||
|
senza cambiare il titolo della mail) e le persone che stanno partecipando.
|
||||||
|
|
||||||
|
- Non alimentate i troll. Se qualcuno cerca di creare nervosismo, ignoratelo.
|
||||||
|
|
||||||
|
- Quando rispondete ad una mail linux-kernel (o ad altre liste) mantenete
|
||||||
|
tutti i Cc:. In assenza di importanti motivazioni (come una richiesta
|
||||||
|
esplicita), non dovreste mai togliere destinatari. Assicuratevi sempre che
|
||||||
|
la persona alla quale state rispondendo sia presente nella lista Cc. Questa
|
||||||
|
usanza fa si che divenga inutile chiedere esplicitamente di essere inseriti
|
||||||
|
in copia nel rispondere al vostro messaggio.
|
||||||
|
|
||||||
|
- Cercate nell'archivio della lista (e nella rete nella sua totalità) prima
|
||||||
|
di far domande. Molti sviluppatori possono divenire impazienti con le
|
||||||
|
persone che chiaramente non hanno svolto i propri compiti a casa.
|
||||||
|
|
||||||
|
- Evitate il *top-posting* (cioè la pratica di mettere la vostra risposta sopra
|
||||||
|
alla frase alla quale state rispondendo). Ciò renderebbe la vostra risposta
|
||||||
|
difficile da leggere e genera scarsa impressione.
|
||||||
|
|
||||||
|
- Chiedete nella lista di discussione corretta. Linux-kernel può essere un
|
||||||
|
punto di incontro generale, ma non è il miglior posto dove trovare
|
||||||
|
sviluppatori da tutti i sottosistemi.
|
||||||
|
|
||||||
|
Infine, la ricerca della corretta lista di discussione è uno degli errori più
|
||||||
|
comuni per gli sviluppatori principianti. Qualcuno che pone una domanda
|
||||||
|
relativa alla rete su linux-kernel riceverà quasi certamente il suggerimento
|
||||||
|
di chiedere sulla lista netdev, che è la lista frequentata dagli sviluppatori
|
||||||
|
di rete. Ci sono poi altre liste per i sottosistemi SCSI, video4linux, IDE,
|
||||||
|
filesystem, etc. Il miglior posto dove cercare una lista di discussione è il
|
||||||
|
file MAINTAINERS che si trova nei sorgenti del kernel.
|
||||||
|
|
||||||
|
Iniziare con lo sviluppo del Kernel
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Sono comuni le domande sul come iniziare con lo sviluppo del kernel - sia da
|
||||||
|
singole persone che da aziende. Altrettanto comuni sono i passi falsi che
|
||||||
|
rendono l'inizio di tale relazione più difficile di quello che dovrebbe essere.
|
||||||
|
|
||||||
|
Le aziende spesso cercano di assumere sviluppatori noti per creare un gruppo
|
||||||
|
di sviluppo iniziale. Questo, in effetti, può essere una tecnica efficace.
|
||||||
|
Ma risulta anche essere dispendiosa e non va ad accrescere il bacino di
|
||||||
|
sviluppatori kernel con esperienza. È possibile anche "portare a casa"
|
||||||
|
sviluppatori per accelerare lo sviluppo del kernel, dando comunque
|
||||||
|
all'investimento un po' di tempo. Prendersi questo tempo può fornire
|
||||||
|
al datore di lavoro un gruppo di sviluppatori che comprendono sia il kernel
|
||||||
|
che l'azienda stessa, e che possono supportare la formazione di altre persone.
|
||||||
|
Nel medio periodo, questa è spesso uno delle soluzioni più proficue.
|
||||||
|
|
||||||
|
I singoli sviluppatori sono spesso, comprensibilmente, una perdita come punto
|
||||||
|
di partenza. Iniziare con un grande progetto può rivelarsi intimidatorio;
|
||||||
|
spesso all'inizio si vuole solo verificare il terreno con qualcosa di piccolo.
|
||||||
|
Questa è una delle motivazioni per le quali molti sviluppatori saltano alla
|
||||||
|
creazione di patch che vanno a sistemare errori di battitura o
|
||||||
|
problematiche minori legate allo stile del codice. Sfortunatamente, tali
|
||||||
|
patch creano un certo livello di rumore che distrae l'intera comunità di
|
||||||
|
sviluppo, quindi, sempre di più, esse vengono degradate. I nuovi sviluppatori
|
||||||
|
che desiderano presentarsi alla comunità non riceveranno l'accoglienza
|
||||||
|
che vorrebbero con questi mezzi.
|
||||||
|
|
||||||
|
Andrew Morton da questo consiglio agli aspiranti sviluppatori kernel
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Il primo progetto per un neofita del kernel dovrebbe essere
|
||||||
|
sicuramente quello di "assicurarsi che il kernel funzioni alla
|
||||||
|
perfezione sempre e su tutte le macchine sulle quali potete stendere
|
||||||
|
la vostra mano". Solitamente il modo per fare ciò è quello di
|
||||||
|
collaborare con gli altri nel sistemare le cose (questo richiede
|
||||||
|
persistenza!) ma va bene - è parte dello sviluppo kernel.
|
||||||
|
|
||||||
|
(http://lwn.net/Articles/283982/).
|
||||||
|
|
||||||
|
In assenza di problemi ovvi da risolvere, si consiglia agli sviluppatori
|
||||||
|
di consultare, in generale, la lista di regressioni e di bachi aperti.
|
||||||
|
Non c'è mai carenza di problematiche bisognose di essere sistemate;
|
||||||
|
accollandosi tali questioni gli sviluppatori accumuleranno esperienza con
|
||||||
|
la procedura, ed allo stesso tempo, aumenteranno la loro rispettabilità
|
||||||
|
all'interno della comunità di sviluppo.
|
||||||
|
|
|
@ -1,12 +1,241 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/3.Early-stage.rst <development_early_stage>`
|
:Original: :ref:`Documentation/process/3.Early-stage.rst <development_early_stage>`
|
||||||
|
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_early_stage:
|
.. _it_development_early_stage:
|
||||||
|
|
||||||
Primi passi della pianificazione
|
I primi passi della pianificazione
|
||||||
================================
|
==================================
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
Specificare il problema
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Come qualsiasi progetto ingegneristico, un miglioramento del kernel di
|
||||||
|
successo parte con una chiara descrizione del problema da risolvere.
|
||||||
|
In alcuni casi, questo passaggio è facile: ad esempio quando un driver è
|
||||||
|
richiesto per un particolare dispositivo. In altri casi invece, si
|
||||||
|
tende a confondere il problema reale con le soluzioni proposte e questo
|
||||||
|
può portare all'emergere di problemi.
|
||||||
|
|
||||||
|
Facciamo un esempio: qualche anno fa, gli sviluppatori che lavoravano con
|
||||||
|
linux audio cercarono un modo per far girare le applicazioni senza dropouts
|
||||||
|
o altri artefatti dovuti all'eccessivo ritardo nel sistema. La soluzione
|
||||||
|
alla quale giunsero fu un modulo del kernel destinato ad agganciarsi al
|
||||||
|
framework Linux Security Module (LSM); questo modulo poteva essere
|
||||||
|
configurato per dare ad una specifica applicazione accesso allo
|
||||||
|
schedulatore *realtime*. Tale modulo fu implementato e inviato nella
|
||||||
|
lista di discussione linux-kernel, dove incontrò subito dei problemi.
|
||||||
|
|
||||||
|
Per gli sviluppatori audio, questo modulo di sicurezza era sufficiente a
|
||||||
|
risolvere il loro problema nell'immediato. Per l'intera comunità kernel,
|
||||||
|
invece, era un uso improprio del framework LSM (che non è progettato per
|
||||||
|
conferire privilegi a processi che altrimenti non avrebbero potuto ottenerli)
|
||||||
|
e un rischio per la stabilità del sistema. Le loro soluzioni di punta nel
|
||||||
|
breve periodo, comportavano un accesso alla schedulazione realtime attraverso
|
||||||
|
il meccanismo rlimit, e nel lungo periodo un costante lavoro nella riduzione
|
||||||
|
dei ritardi.
|
||||||
|
|
||||||
|
La comunità audio, comunque, non poteva vedere al di là della singola
|
||||||
|
soluzione che avevano implementato; erano riluttanti ad accettare alternative.
|
||||||
|
Il conseguente dissenso lasciò in quegli sviluppatori un senso di
|
||||||
|
disillusione nei confronti dell'intero processo di sviluppo; uno di loro
|
||||||
|
scrisse questo messaggio:
|
||||||
|
|
||||||
|
Ci sono numerosi sviluppatori del kernel Linux davvero bravi, ma
|
||||||
|
rischiano di restare sovrastati da una vasta massa di stolti arroganti.
|
||||||
|
Cercare di comunicare le richieste degli utenti a queste persone è
|
||||||
|
una perdita di tempo. Loro sono troppo "intelligenti" per stare ad
|
||||||
|
ascoltare dei poveri mortali.
|
||||||
|
|
||||||
|
(http://lwn.net/Articles/131776/).
|
||||||
|
|
||||||
|
La realtà delle cose fu differente; gli sviluppatori del kernel erano molto
|
||||||
|
più preoccupati per la stabilità del sistema, per la manutenzione di lungo
|
||||||
|
periodo e cercavano la giusta soluzione alla problematica esistente con uno
|
||||||
|
specifico modulo. La morale della storia è quella di concentrarsi sul
|
||||||
|
problema - non su di una specifica soluzione- e di discuterne con la comunità
|
||||||
|
di sviluppo prima di investire tempo nella scrittura del codice.
|
||||||
|
|
||||||
|
Quindi, osservando un progetto di sviluppo del kernel, si dovrebbe
|
||||||
|
rispondere a questa lista di domande:
|
||||||
|
|
||||||
|
- Qual'è, precisamente, il problema che dev'essere risolto?
|
||||||
|
|
||||||
|
- Chi sono gli utenti coinvolti da tal problema? A quale caso dovrebbe
|
||||||
|
essere indirizzata la soluzione?
|
||||||
|
|
||||||
|
- In che modo il kernel risulta manchevole nell'indirizzare il problema
|
||||||
|
in questione?
|
||||||
|
|
||||||
|
Solo dopo ha senso iniziare a considerare le possibili soluzioni.
|
||||||
|
|
||||||
|
Prime discussioni
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Quando si pianifica un progetto di sviluppo per il kernel, sarebbe quanto meno
|
||||||
|
opportuno discuterne inizialmente con la comunità prima di lanciarsi
|
||||||
|
nell'implementazione. Una discussione preliminare può far risparmiare sia
|
||||||
|
tempo che problemi in svariati modi:
|
||||||
|
|
||||||
|
- Potrebbe essere che il problema sia già stato risolto nel kernel in
|
||||||
|
una maniera che non avete ancora compreso. Il kernel Linux è grande e ha
|
||||||
|
una serie di funzionalità e capacità che non sono scontate nell'immediato.
|
||||||
|
Non tutte le capacità del kernel sono documentate così bene come ci
|
||||||
|
piacerebbe, ed è facile perdersi qualcosa. Il vostro autore ha assistito
|
||||||
|
alla pubblicazione di un driver intero che duplica un altro driver
|
||||||
|
esistente di cui il nuovo autore era ignaro. Il codice che rinnova
|
||||||
|
ingranaggi già esistenti non è soltanto dispendioso; non verrà nemmeno
|
||||||
|
accettato nel ramo principale del kernel.
|
||||||
|
|
||||||
|
- Potrebbero esserci proposte che non sono considerate accettabili per
|
||||||
|
l'integrazione all'interno del ramo principale. È meglio affrontarle
|
||||||
|
prima di scrivere il codice.
|
||||||
|
|
||||||
|
- È possibile che altri sviluppatori abbiano pensato al problema; potrebbero
|
||||||
|
avere delle idee per soluzioni migliori, e potrebbero voler contribuire
|
||||||
|
alla loro creazione.
|
||||||
|
|
||||||
|
Anni di esperienza con la comunità di sviluppo del kernel hanno impartito una
|
||||||
|
chiara lezione: il codice per il kernel che è pensato e sviluppato a porte
|
||||||
|
chiuse, inevitabilmente, ha problematiche che si rivelano solo quando il
|
||||||
|
codice viene rilasciato pubblicamente. Qualche volta tali problemi sono
|
||||||
|
importanti e richiedono mesi o anni di sforzi prima che il codice possa
|
||||||
|
raggiungere gli standard richiesti della comunità.
|
||||||
|
Alcuni esempi possono essere:
|
||||||
|
|
||||||
|
- La rete Devicescape è stata creata e implementata per sistemi
|
||||||
|
mono-processore. Non avrebbe potuto essere inserita nel ramo principale
|
||||||
|
fino a che non avesse supportato anche i sistemi multi-processore.
|
||||||
|
Riadattare i meccanismi di sincronizzazione e simili è un compito difficile;
|
||||||
|
come risultato, l'inserimento di questo codice (ora chiamato mac80211)
|
||||||
|
fu rimandato per più di un anno.
|
||||||
|
|
||||||
|
- Il filesystem Reiser4 include una seria di funzionalità che, secondo
|
||||||
|
l'opinione degli sviluppatori principali del kernel, avrebbero dovuto
|
||||||
|
essere implementate a livello di filesystem virtuale. Comprende
|
||||||
|
anche funzionalità che non sono facilmente implementabili senza esporre
|
||||||
|
il sistema al rischio di uno stallo. La scoperta tardiva di questi
|
||||||
|
problemi - e il diniego a risolverne alcuni - ha avuto come conseguenza
|
||||||
|
il fatto che Raiser4 resta fuori dal ramo principale del kernel.
|
||||||
|
|
||||||
|
- Il modulo di sicurezza AppArmor utilizzava strutture dati del
|
||||||
|
filesystem virtuale interno in modi che sono stati considerati rischiosi e
|
||||||
|
inattendibili. Questi problemi (tra le altre cose) hanno tenuto AppArmor
|
||||||
|
fuori dal ramo principale per anni.
|
||||||
|
|
||||||
|
Ciascuno di questi casi è stato un travaglio e ha richiesto del lavoro
|
||||||
|
straordinario, cose che avrebbero potuto essere evitate con alcune
|
||||||
|
"chiacchierate" preliminari con gli sviluppatori kernel.
|
||||||
|
|
||||||
|
Con chi parlare?
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Quando gli sviluppatori hanno deciso di rendere pubblici i propri progetti, la
|
||||||
|
domanda successiva sarà: da dove partiamo? La risposta è quella di trovare
|
||||||
|
la giusta lista di discussione e il giusto manutentore. Per le liste di
|
||||||
|
discussione, il miglior approccio è quello di cercare la lista più adatta
|
||||||
|
nel file MAINTAINERS. Se esiste una lista di discussione di sottosistema,
|
||||||
|
è preferibile pubblicare lì piuttosto che sulla lista di discussione generale
|
||||||
|
del kernel Linux; avrete maggiori probabilità di trovare sviluppatori con
|
||||||
|
esperienza sul tema, e l'ambiente che troverete potrebbe essere più
|
||||||
|
incoraggiante.
|
||||||
|
|
||||||
|
Trovare manutentori può rivelarsi un po' difficoltoso. Ancora, il file
|
||||||
|
MAINTAINERS è il posto giusto da dove iniziare. Il file potrebbe non essere
|
||||||
|
sempre aggiornato, inoltre, non tutti i sottosistemi sono rappresentati qui.
|
||||||
|
Coloro che sono elencati nel file MAINTAINERS potrebbero, in effetti, non
|
||||||
|
essere le persone che attualmente svolgono quel determinato ruolo. Quindi,
|
||||||
|
quando c'è un dubbio su chi contattare, un trucco utile è quello di usare
|
||||||
|
git (git log in particolare) per vedere chi attualmente è attivo all'interno
|
||||||
|
del sottosistema interessato. Controllate chi sta scrivendo le patch,
|
||||||
|
e chi, se non ci fosse nessuno, sta aggiungendo la propria firma
|
||||||
|
(Signed-off-by) a quelle patch. Quelle sono le persone maggiormente
|
||||||
|
qualificate per aiutarvi con lo sviluppo di nuovo progetto.
|
||||||
|
|
||||||
|
Il compito di trovare il giusto manutentore, a volte, è una tale sfida che
|
||||||
|
ha spinto gli sviluppatori del kernel a scrivere uno script che li aiutasse
|
||||||
|
in questa ricerca:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
.../scripts/get_maintainer.pl
|
||||||
|
|
||||||
|
Se questo script viene eseguito con l'opzione "-f" ritornerà il
|
||||||
|
manutentore(i) attuale per un dato file o cartella. Se viene passata una
|
||||||
|
patch sulla linea di comando, lo script elencherà i manutentori che
|
||||||
|
dovrebbero riceverne una copia. Ci sono svariate opzioni che regolano
|
||||||
|
quanto a fondo get_maintainer.pl debba cercare i manutentori;
|
||||||
|
siate quindi prudenti nell'utilizzare le opzioni più aggressive poiché
|
||||||
|
potreste finire per includere sviluppatori che non hanno un vero interesse
|
||||||
|
per il codice che state modificando.
|
||||||
|
|
||||||
|
Se tutto ciò dovesse fallire, parlare con Andrew Morton potrebbe essere
|
||||||
|
un modo efficace per capire chi è il manutentore di un dato pezzo di codice.
|
||||||
|
|
||||||
|
Quando pubblicare
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Se potete, pubblicate i vostri intenti durante le fasi preliminari, sarà
|
||||||
|
molto utile. Descrivete il problema da risolvere e ogni piano che è stato
|
||||||
|
elaborato per l'implementazione. Ogni informazione fornita può aiutare
|
||||||
|
la comunità di sviluppo a fornire spunti utili per il progetto.
|
||||||
|
|
||||||
|
Un evento che potrebbe risultare scoraggiate e che potrebbe accadere in
|
||||||
|
questa fase non è il ricevere una risposta ostile, ma, invece, ottenere
|
||||||
|
una misera o inesistente reazione. La triste verità è che: (1) gli
|
||||||
|
sviluppatori del kernel tendono ad essere occupati, (2) ci sono tante persone
|
||||||
|
con grandi progetti e poco codice (o anche solo la prospettiva di
|
||||||
|
avere un codice) a cui riferirsi e (3) nessuno è obbligato a revisionare
|
||||||
|
o a fare osservazioni in merito ad idee pubblicate da altri. Oltre a
|
||||||
|
questo, progetti di alto livello spesso nascondono problematiche che si
|
||||||
|
rivelano solo quando qualcuno cerca di implementarle; per questa ragione
|
||||||
|
gli sviluppatori kernel preferirebbero vedere il codice.
|
||||||
|
|
||||||
|
Quindi, se una richiesta pubblica di commenti riscuote poco successo, non
|
||||||
|
pensate che ciò significhi che non ci sia interesse nel progetto.
|
||||||
|
Sfortunatamente, non potete nemmeno assumere che non ci siano problemi con
|
||||||
|
la vostra idea. La cosa migliore da fare in questa situazione è quella di
|
||||||
|
andare avanti e tenere la comunità informata mentre procedete.
|
||||||
|
|
||||||
|
Ottenere riscontri ufficiali
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Se il vostro lavoro è stato svolto in un ambiente aziendale - come molto
|
||||||
|
del lavoro fatto su Linux - dovete, ovviamente, avere il permesso dei
|
||||||
|
dirigenti prima che possiate pubblicare i progetti, o il codice aziendale,
|
||||||
|
su una lista di discussione pubblica. La pubblicazione di codice che non
|
||||||
|
è stato rilascio espressamente con licenza GPL-compatibile può rivelarsi
|
||||||
|
problematico; prima la dirigenza, e il personale legale, troverà una decisione
|
||||||
|
sulla pubblicazione di un progetto, meglio sarà per tutte le persone coinvolte.
|
||||||
|
|
||||||
|
A questo punto, alcuni lettori potrebbero pensare che il loro lavoro sul
|
||||||
|
kernel è preposto a supportare un prodotto che non è ancora ufficialmente
|
||||||
|
riconosciuto. Rivelare le intenzioni dei propri datori di lavori in una
|
||||||
|
lista di discussione pubblica potrebbe non essere una soluzione valida.
|
||||||
|
In questi casi, vale la pena considerare se la segretezza sia necessaria
|
||||||
|
o meno; spesso non c'è una reale necessità di mantenere chiusi i progetti di
|
||||||
|
sviluppo.
|
||||||
|
|
||||||
|
Detto ciò, ci sono anche casi dove l'azienda legittimamente non può rivelare
|
||||||
|
le proprie intenzioni in anticipo durante il processo di sviluppo. Le aziende
|
||||||
|
che hanno sviluppatori kernel esperti possono scegliere di procedere a
|
||||||
|
carte coperte partendo dall'assunto che saranno in grado di evitare, o gestire,
|
||||||
|
in futuro, eventuali problemi d'integrazione. Per le aziende senza questo tipo
|
||||||
|
di esperti, la migliore opzione è spesso quella di assumere uno sviluppatore
|
||||||
|
esterno che revisioni i progetti con un accordo di segretezza.
|
||||||
|
La Linux Foundation applica un programma di NDA creato appositamente per
|
||||||
|
aiutare le aziende in questa particolare situazione; potrete trovare più
|
||||||
|
informazioni sul sito:
|
||||||
|
|
||||||
|
http://www.linuxfoundation.org/en/NDA_program
|
||||||
|
|
||||||
|
Questa tipologia di revisione è spesso sufficiente per evitare gravi problemi
|
||||||
|
senza che sia richiesta l'esposizione pubblica del progetto.
|
||||||
|
|
|
@ -1,12 +1,447 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/4.Coding.rst <development_coding>`
|
:Original: :ref:`Documentation/process/4.Coding.rst <development_coding>`
|
||||||
|
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_coding:
|
.. _it_development_coding:
|
||||||
|
|
||||||
Scrivere codice corretto
|
Scrivere codice corretto
|
||||||
========================
|
========================
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
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/process/clang-format.rst <clangformat>`
|
||||||
|
per maggiori dettagli
|
||||||
|
|
||||||
|
|
||||||
|
Livelli di astrazione
|
||||||
|
*********************
|
||||||
|
|
||||||
|
|
||||||
|
I professori di Informatica insegnano ai propri studenti a fare ampio uso dei
|
||||||
|
livelli di astrazione nel nome della flessibilità e del nascondere informazioni.
|
||||||
|
Certo il kernel fa un grande uso dell'astrazione; nessun progetto con milioni
|
||||||
|
di righe di codice potrebbe fare altrimenti e sopravvivere. Ma l'esperienza
|
||||||
|
ha dimostrato che un'eccessiva o prematura astrazione può rivelarsi dannosa
|
||||||
|
al pari di una prematura ottimizzazione. L'astrazione dovrebbe essere usata
|
||||||
|
fino al livello necessario e non oltre.
|
||||||
|
|
||||||
|
Ad un livello base, considerate una funzione che ha un argomento che viene
|
||||||
|
sempre impostato a zero da tutti i chiamanti. Uno potrebbe mantenere
|
||||||
|
quell'argomento nell'eventualità qualcuno volesse sfruttare la flessibilità
|
||||||
|
offerta. In ogni caso, tuttavia, ci sono buone possibilità che il codice
|
||||||
|
che va ad implementare questo argomento aggiuntivo, sia stato rotto in maniera
|
||||||
|
sottile, in un modo che non è mai stato notato - perché non è mai stato usato.
|
||||||
|
Oppure, quando sorge la necessità di avere più flessibilità, questo argomento
|
||||||
|
non la fornisce in maniera soddisfacente. Gli sviluppatori di Kernel,
|
||||||
|
sottopongono costantemente patch che vanno a rimuovere gli argomenti
|
||||||
|
inutilizzate; anche se, in generale, non avrebbero dovuto essere aggiunti.
|
||||||
|
|
||||||
|
I livelli di astrazione che nascondono l'accesso all'hardware -
|
||||||
|
spesso per poter usare dei driver su diversi sistemi operativi - vengono
|
||||||
|
particolarmente disapprovati. Tali livelli oscurano il codice e possono
|
||||||
|
peggiorare le prestazioni; essi non appartengono al kernel Linux.
|
||||||
|
|
||||||
|
D'altro canto, se vi ritrovate a dover copiare una quantità significativa di
|
||||||
|
codice proveniente da un altro sottosistema del kernel, è tempo di chiedersi
|
||||||
|
se, in effetti, non avrebbe più senso togliere parte di quel codice e metterlo
|
||||||
|
in una libreria separata o di implementare quella funzionalità ad un livello
|
||||||
|
più elevato. Non c'è utilità nel replicare lo stesso codice per tutto
|
||||||
|
il kernel.
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef e l'uso del preprocessore in generale
|
||||||
|
********************************************
|
||||||
|
|
||||||
|
Il preprocessore C sembra essere una fonte di attrazione per qualche
|
||||||
|
programmatore C, che ci vede una via per ottenere una grande flessibilità
|
||||||
|
all'interno di un file sorgente. Ma il preprocessore non è scritto in C,
|
||||||
|
e un suo massiccio impiego conduce a un codice che è molto più difficile
|
||||||
|
da leggere per gli altri e che rende più difficile il lavoro di verifica del
|
||||||
|
compilatore. L'uso eccessivo del preprocessore è praticamente sempre il segno
|
||||||
|
di un codice che necessita di un certo lavoro di pulizia.
|
||||||
|
|
||||||
|
La compilazione condizionata con #ifdef è, in effetti, un potente strumento,
|
||||||
|
ed esso viene usato all'interno del kernel. Ma esiste un piccolo desiderio:
|
||||||
|
quello di vedere il codice coperto solo da una leggera spolverata di
|
||||||
|
blocchi #ifdef. Come regola generale, quando possibile, l'uso di #ifdef
|
||||||
|
dovrebbe essere confinato nei file d'intestazione. Il codice compilato
|
||||||
|
condizionatamente può essere confinato a funzioni tali che, nel caso in cui
|
||||||
|
il codice non deve essere presente, diventano vuote. Il compilatore poi
|
||||||
|
ottimizzerà la chiamata alla funzione vuota rimuovendola. Il risultato è
|
||||||
|
un codice molto più pulito, più facile da seguire.
|
||||||
|
|
||||||
|
Le macro del preprocessore C presentano una serie di pericoli, inclusi
|
||||||
|
valutazioni multiple di espressioni che hanno effetti collaterali e non
|
||||||
|
garantiscono una sicurezza rispetto ai tipi. Se siete tentati dal definire
|
||||||
|
una macro, considerate l'idea di creare invece una funzione inline. Il codice
|
||||||
|
che ne risulterà sarà lo stesso, ma le funzioni inline sono più leggibili,
|
||||||
|
non considerano i propri argomenti più volte, e permettono al compilatore di
|
||||||
|
effettuare controlli sul tipo degli argomenti e del valore di ritorno.
|
||||||
|
|
||||||
|
|
||||||
|
Funzioni inline
|
||||||
|
***************
|
||||||
|
|
||||||
|
Comunque, anche le funzioni inline hanno i loro pericoli. I programmatori
|
||||||
|
potrebbero innamorarsi dell'efficienza percepita derivata dalla rimozione
|
||||||
|
di una chiamata a funzione. Queste funzioni, tuttavia, possono ridurre le
|
||||||
|
prestazioni. Dato che il loro codice viene replicato ovunque vi sia una
|
||||||
|
chiamata ad esse, si finisce per gonfiare le dimensioni del kernel compilato.
|
||||||
|
Questi, a turno, creano pressione sulla memoria cache del processore, e questo
|
||||||
|
può causare rallentamenti importanti. Le funzioni inline, di norma, dovrebbero
|
||||||
|
essere piccole e usate raramente. Il costo di una chiamata a funzione, dopo
|
||||||
|
tutto, non è così alto; la creazione di molte funzioni inline è il classico
|
||||||
|
esempio di un'ottimizzazione prematura.
|
||||||
|
|
||||||
|
In generale, i programmatori del kernel ignorano gli effetti della cache a
|
||||||
|
loro rischio e pericolo. Il classico compromesso tempo/spazio teorizzato
|
||||||
|
all'inizio delle lezioni sulle strutture dati spesso non si applica
|
||||||
|
all'hardware moderno. Lo spazio *è* tempo, in questo senso un programma
|
||||||
|
più grande sarà più lento rispetto ad uno più compatto.
|
||||||
|
|
||||||
|
I compilatori più recenti hanno preso un ruolo attivo nel decidere se
|
||||||
|
una data funzione deve essere resa inline oppure no. Quindi l'uso
|
||||||
|
indiscriminato della parola chiave "inline" potrebbe non essere non solo
|
||||||
|
eccessivo, ma anche irrilevante.
|
||||||
|
|
||||||
|
Sincronizzazione
|
||||||
|
****************
|
||||||
|
|
||||||
|
Nel maggio 2006, il sistema di rete "Devicescape" fu rilasciato in pompa magna
|
||||||
|
sotto la licenza GPL e reso disponibile per la sua inclusione nella ramo
|
||||||
|
principale del kernel. Questa donazione fu una notizia bene accolta;
|
||||||
|
il supporto per le reti senza fili era considerata, nel migliore dei casi,
|
||||||
|
al di sotto degli standard; il sistema Deviscape offrì la promessa di una
|
||||||
|
risoluzione a tale situazione. Tuttavia, questo codice non fu inserito nel
|
||||||
|
ramo principale fino al giugno del 2007 (2.6.22). Cosa accadde?
|
||||||
|
|
||||||
|
Quel codice mostrava numerosi segnali di uno sviluppo in azienda avvenuto
|
||||||
|
a porte chiuse. Ma in particolare, un grosso problema fu che non fu
|
||||||
|
progettato per girare in un sistema multiprocessore. Prima che questo
|
||||||
|
sistema di rete (ora chiamato mac80211) potesse essere inserito, fu necessario
|
||||||
|
un lavoro sugli schemi di sincronizzazione.
|
||||||
|
|
||||||
|
Una volta, il codice del kernel Linux poteva essere sviluppato senza pensare
|
||||||
|
ai problemi di concorrenza presenti nei sistemi multiprocessore. Ora,
|
||||||
|
comunque, questo documento è stato scritto su di un portatile dual-core.
|
||||||
|
Persino su sistemi a singolo processore, il lavoro svolto per incrementare
|
||||||
|
la capacità di risposta aumenterà il livello di concorrenza interno al kernel.
|
||||||
|
I giorni nei quali il codice poteva essere scritto senza pensare alla
|
||||||
|
sincronizzazione sono da passati tempo.
|
||||||
|
|
||||||
|
Ogni risorsa (strutture dati, registri hardware, etc.) ai quali si potrebbe
|
||||||
|
avere accesso simultaneo da più di un thread deve essere sincronizzato. Il
|
||||||
|
nuovo codice dovrebbe essere scritto avendo tale accortezza in testa;
|
||||||
|
riadattare la sincronizzazione a posteriori è un compito molto più difficile.
|
||||||
|
Gli sviluppatori del kernel dovrebbero prendersi il tempo di comprendere bene
|
||||||
|
le primitive di sincronizzazione, in modo da sceglier lo strumento corretto
|
||||||
|
per eseguire un compito. Il codice che presenta una mancanza di attenzione
|
||||||
|
alla concorrenza avrà un percorso difficile all'interno del ramo principale.
|
||||||
|
|
||||||
|
Regressioni
|
||||||
|
***********
|
||||||
|
|
||||||
|
Vale la pena menzionare un ultimo pericolo: potrebbe rivelarsi accattivante
|
||||||
|
l'idea di eseguire un cambiamento (che potrebbe portare a grandi
|
||||||
|
miglioramenti) che porterà ad alcune rotture per gli utenti esistenti.
|
||||||
|
Questa tipologia di cambiamento è chiamata "regressione", e le regressioni son
|
||||||
|
diventate mal viste nel ramo principale del kernel. Con alcune eccezioni,
|
||||||
|
i cambiamenti che causano regressioni saranno fermati se quest'ultime non
|
||||||
|
potranno essere corrette in tempo utile. È molto meglio quindi evitare
|
||||||
|
la regressione fin dall'inizio.
|
||||||
|
|
||||||
|
Spesso si è argomentato che una regressione può essere giustificata se essa
|
||||||
|
porta risolve più problemi di quanti non ne crei. Perché, dunque, non fare
|
||||||
|
un cambiamento se questo porta a nuove funzionalità a dieci sistemi per
|
||||||
|
ognuno dei quali esso determina una rottura? La migliore risposta a questa
|
||||||
|
domanda ci è stata fornita da Linus nel luglio 2007:
|
||||||
|
|
||||||
|
::
|
||||||
|
Dunque, noi non sistemiamo bachi introducendo nuovi problemi. Quella
|
||||||
|
via nasconde insidie, e nessuno può sapere del tutto se state facendo
|
||||||
|
dei progressi reali. Sono due passi avanti e uno indietro, oppure
|
||||||
|
un passo avanti e due indietro?
|
||||||
|
|
||||||
|
(http://lwn.net/Articles/243460/).
|
||||||
|
|
||||||
|
Una particolare tipologia di regressione mal vista consiste in una qualsiasi
|
||||||
|
sorta di modifica all'ABI dello spazio utente. Una volta che un'interfaccia
|
||||||
|
viene esportata verso lo spazio utente, dev'essere supportata all'infinito.
|
||||||
|
Questo fatto rende la creazione di interfacce per lo spazio utente
|
||||||
|
particolarmente complicato: dato che non possono venir cambiate introducendo
|
||||||
|
incompatibilità, esse devono essere fatte bene al primo colpo. Per questa
|
||||||
|
ragione sono sempre richieste: ampie riflessioni, documentazione chiara e
|
||||||
|
ampie revisioni dell'interfaccia verso lo spazio utente.
|
||||||
|
|
||||||
|
|
||||||
|
Strumenti di verifica del codice
|
||||||
|
--------------------------------
|
||||||
|
Almeno per ora la scrittura di codice priva di errori resta un ideale
|
||||||
|
irraggiungibile ai più. Quello che speriamo di poter fare, tuttavia, è
|
||||||
|
trovare e correggere molti di questi errori prima che il codice entri nel
|
||||||
|
ramo principale del kernel. A tal scopo gli sviluppatori del kernel devono
|
||||||
|
mettere insieme una schiera impressionante di strumenti che possano
|
||||||
|
localizzare automaticamente un'ampia varietà di problemi. Qualsiasi problema
|
||||||
|
trovato dal computer è un problema che non affliggerà l'utente in seguito,
|
||||||
|
ne consegue che gli strumenti automatici dovrebbero essere impiegati ovunque
|
||||||
|
possibile.
|
||||||
|
|
||||||
|
Il primo passo consiste semplicemente nel fare attenzione agli avvertimenti
|
||||||
|
proveniente dal compilatore. Versioni moderne di gcc possono individuare
|
||||||
|
(e segnalare) un gran numero di potenziali errori. Molto spesso, questi
|
||||||
|
avvertimenti indicano problemi reali. Di regola, il codice inviato per la
|
||||||
|
revisione non dovrebbe produrre nessun avvertimento da parte del compilatore.
|
||||||
|
Per mettere a tacere gli avvertimenti, cercate di comprenderne le cause reali
|
||||||
|
e cercate di evitare le "riparazioni" che fan sparire l'avvertimento senza
|
||||||
|
però averne trovato la causa.
|
||||||
|
|
||||||
|
Tenete a mente che non tutti gli avvertimenti sono disabilitati di default.
|
||||||
|
Costruite il kernel con "make EXTRA_CFLAGS=-W" per ottenerli tutti.
|
||||||
|
|
||||||
|
Il kernel fornisce differenti opzioni che abilitano funzionalità di debugging;
|
||||||
|
molti di queste sono trovano all'interno del sotto menu "kernel hacking".
|
||||||
|
La maggior parte di queste opzioni possono essere attivate per qualsiasi
|
||||||
|
kernel utilizzato per lo sviluppo o a scopo di test. In particolare dovreste
|
||||||
|
attivare:
|
||||||
|
|
||||||
|
- ENABLE_WARN_DEPRECATED, ENABLE_MUST_CHECK, e FRAME_WARN per ottenere degli
|
||||||
|
avvertimenti dedicati a problemi come l'uso di interfacce deprecate o
|
||||||
|
l'ignorare un importante valore di ritorno di una funzione. Il risultato
|
||||||
|
generato da questi avvertimenti può risultare verboso, ma non bisogna
|
||||||
|
preoccuparsi per gli avvertimenti provenienti da altre parti del kernel.
|
||||||
|
|
||||||
|
- DEBUG_OBJECTS aggiungerà un codice per tracciare il ciclo di vita di
|
||||||
|
diversi oggetti creati dal kernel e avvisa quando qualcosa viene eseguito
|
||||||
|
fuori controllo. Se state aggiungendo un sottosistema che crea (ed
|
||||||
|
esporta) oggetti complessi propri, considerate l'aggiunta di un supporto
|
||||||
|
al debugging dell'oggetto.
|
||||||
|
|
||||||
|
- DEBUG_SLAB può trovare svariati errori di uso e di allocazione di memoria;
|
||||||
|
esso dovrebbe esser usato dalla maggior parte dei kernel di sviluppo.
|
||||||
|
|
||||||
|
- DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP, e DEBUG_MUTEXES troveranno un certo
|
||||||
|
numero di errori comuni di sincronizzazione.
|
||||||
|
|
||||||
|
Esistono ancora delle altre opzioni di debugging, di alcune di esse
|
||||||
|
discuteremo qui sotto. Alcune di esse hanno un forte impatto e non dovrebbero
|
||||||
|
essere usate tutte le volte. Ma qualche volta il tempo speso nell'capire
|
||||||
|
le opzioni disponibili porterà ad un risparmio di tempo nel breve termine.
|
||||||
|
|
||||||
|
Uno degli strumenti di debugging più tosti è il *locking checker*, o
|
||||||
|
"lockdep". Questo strumento traccerà qualsiasi acquisizione e rilascio di
|
||||||
|
ogni *lock* (spinlock o mutex) nel sistema, l'ordine con il quale i *lock*
|
||||||
|
sono acquisiti in relazione l'uno con l'altro, l'ambiente corrente di
|
||||||
|
interruzione, eccetera. Inoltre esso può assicurare che i *lock* vengano
|
||||||
|
acquisiti sempre nello stesso ordine, che le stesse assunzioni sulle
|
||||||
|
interruzioni si applichino in tutte le occasioni, e così via. In altre parole,
|
||||||
|
lockdep può scovare diversi scenari nei quali il sistema potrebbe, in rari
|
||||||
|
casi, trovarsi in stallo. Questa tipologia di problema può essere grave
|
||||||
|
(sia per gli sviluppatori che per gli utenti) in un sistema in uso; lockdep
|
||||||
|
permette di trovare tali problemi automaticamente e in anticipo.
|
||||||
|
|
||||||
|
In qualità di programmatore kernel diligente, senza dubbio, dovrete controllare
|
||||||
|
il valore di ritorno di ogni operazione (come l'allocazione della memoria)
|
||||||
|
poiché esso potrebbe fallire. Il nocciolo della questione è che i percorsi
|
||||||
|
di gestione degli errori, con grande probabilità, non sono mai stati
|
||||||
|
collaudati del tutto. Il codice collaudato tende ad essere codice bacato;
|
||||||
|
potrete quindi essere più a vostro agio con il vostro codice se tutti questi
|
||||||
|
percorsi fossero stati verificati un po' di volte.
|
||||||
|
|
||||||
|
Il kernel fornisce un framework per l'inserimento di fallimenti che fa
|
||||||
|
esattamente al caso, specialmente dove sono coinvolte allocazioni di memoria.
|
||||||
|
Con l'opzione per l'inserimento dei fallimenti abilitata, una certa percentuale
|
||||||
|
di allocazione di memoria sarà destinata al fallimento; questi fallimenti
|
||||||
|
possono essere ridotti ad uno specifico pezzo di codice. Procedere con
|
||||||
|
l'inserimento dei fallimenti attivo permette al programmatore di verificare
|
||||||
|
come il codice risponde quando le cose vanno male. Consultate:
|
||||||
|
Documentation/fault-injection/fault-injection.txt per avere maggiori
|
||||||
|
informazioni su come utilizzare questo strumento.
|
||||||
|
|
||||||
|
Altre tipologie di errori possono essere riscontrati con lo strumento di
|
||||||
|
analisi statica "sparse". Con Sparse, il programmatore può essere avvisato
|
||||||
|
circa la confusione tra gli indirizzi dello spazio utente e dello spazio
|
||||||
|
kernel, un miscuglio fra quantità big-endian e little-endian, il passaggio
|
||||||
|
di un valore intero dove ci sia aspetta un gruppo di flag, e così via.
|
||||||
|
Sparse deve essere installato separatamente (se il vostra distribuzione non
|
||||||
|
lo prevede, potete trovarlo su https://sparse.wiki.kernel.org/index.php/Main_Page);
|
||||||
|
può essere attivato sul codice aggiungendo "C=1" al comando make.
|
||||||
|
|
||||||
|
Lo strumento "Coccinelle" (http://coccinelle.lip6.fr/) è in grado di trovare
|
||||||
|
una vasta varietà di potenziali problemi di codifica; e può inoltre proporre
|
||||||
|
soluzioni per risolverli. Un buon numero di "patch semantiche" per il kernel
|
||||||
|
sono state preparate nella cartella scripts/coccinelle; utilizzando
|
||||||
|
"make coccicheck" esso percorrerà tali patch semantiche e farà rapporto su
|
||||||
|
qualsiasi problema trovato. Per maggiori informazioni, consultate
|
||||||
|
:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`.
|
||||||
|
|
||||||
|
Altri errori di portabilità sono meglio scovati compilando il vostro codice
|
||||||
|
per altre architetture. Se non vi accade di avere un sistema S/390 o una
|
||||||
|
scheda di sviluppo Blackfin sotto mano, potete comunque continuare la fase
|
||||||
|
di compilazione. Un vasto numero di cross-compilatori per x86 possono
|
||||||
|
essere trovati al sito:
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/tools/crosstool/
|
||||||
|
|
||||||
|
Il tempo impiegato nell'installare e usare questi compilatori sarà d'aiuto
|
||||||
|
nell'evitare situazioni imbarazzanti nel futuro.
|
||||||
|
|
||||||
|
|
||||||
|
Documentazione
|
||||||
|
--------------
|
||||||
|
|
||||||
|
La documentazione è spesso stata più un'eccezione che una regola nello
|
||||||
|
sviluppo del kernel. Nonostante questo, un'adeguata documentazione aiuterà
|
||||||
|
a facilitare l'inserimento di nuovo codice nel kernel, rende la vita più
|
||||||
|
facile per gli altri sviluppatori e sarà utile per i vostri utenti. In molti
|
||||||
|
casi, la documentazione è divenuta sostanzialmente obbligatoria.
|
||||||
|
|
||||||
|
La prima parte di documentazione per qualsiasi patch è il suo changelog.
|
||||||
|
Questi dovrebbero descrivere le problematiche risolte, la tipologia di
|
||||||
|
soluzione, le persone che lavorano alla patch, ogni effetto rilevante
|
||||||
|
sulle prestazioni e tutto ciò che può servire per la comprensione della
|
||||||
|
patch. Assicuratevi che il changelog dica *perché*, vale la pena aggiungere
|
||||||
|
la patch; un numero sorprendente di sviluppatori sbaglia nel fornire tale
|
||||||
|
informazione.
|
||||||
|
|
||||||
|
Qualsiasi codice che aggiunge una nuova interfaccia in spazio utente - inclusi
|
||||||
|
nuovi file in sysfs o /proc - dovrebbe includere la documentazione di tale
|
||||||
|
interfaccia così da permette agli sviluppatori dello spazio utente di sapere
|
||||||
|
con cosa stanno lavorando. Consultate: Documentation/ABI/README per avere una
|
||||||
|
descrizione di come questi documenti devono essere impostati e quali
|
||||||
|
informazioni devono essere fornite.
|
||||||
|
|
||||||
|
Il file :ref:`Documentation/translations/it_IT/admin-guide/kernel-parameters.rst <kernelparameters>`
|
||||||
|
descrive tutti i parametri di avvio del kernel. Ogni patch che aggiunga
|
||||||
|
nuovi parametri dovrebbe aggiungere nuove voci a questo file.
|
||||||
|
|
||||||
|
Ogni nuova configurazione deve essere accompagnata da un testo di supporto
|
||||||
|
che spieghi chiaramente le opzioni e spieghi quando l'utente potrebbe volerle
|
||||||
|
selezionare.
|
||||||
|
|
||||||
|
Per molti sottosistemi le informazioni sull'API interna sono documentate sotto
|
||||||
|
forma di commenti formattati in maniera particolare; questi commenti possono
|
||||||
|
essere estratti e formattati in differenti modi attraverso lo script
|
||||||
|
"kernel-doc". Se state lavorando all'interno di un sottosistema che ha
|
||||||
|
commenti kerneldoc dovreste mantenerli e aggiungerli, in maniera appropriata,
|
||||||
|
per le funzioni disponibili esternamente. Anche in aree che non sono molto
|
||||||
|
documentate, non c'è motivo per non aggiungere commenti kerneldoc per il
|
||||||
|
futuro; infatti, questa può essere un'attività utile per sviluppatori novizi
|
||||||
|
del kernel. Il formato di questi commenti, assieme alle informazione su come
|
||||||
|
creare modelli per kerneldoc, possono essere trovati in
|
||||||
|
:ref:`Documentation/translations/it_IT/doc-guide/ <doc_guide>`.
|
||||||
|
|
||||||
|
Chiunque legga un ammontare significativo di codice kernel noterà che, spesso,
|
||||||
|
i commenti si fanno maggiormente notare per la loro assenza. Ancora una volta,
|
||||||
|
le aspettative verso il nuovo codice sono più alte rispetto al passato;
|
||||||
|
inserire codice privo di commenti sarà più difficile. Detto ciò, va aggiunto
|
||||||
|
che non si desiderano commenti prolissi per il codice. Il codice dovrebbe
|
||||||
|
essere, di per sé, leggibile, con dei commenti che spieghino gli aspetti più
|
||||||
|
sottili.
|
||||||
|
|
||||||
|
Determinate cose dovrebbero essere sempre commentate. L'uso di barriere
|
||||||
|
di memoria dovrebbero essere accompagnate da una riga che spieghi perché sia
|
||||||
|
necessaria. Le regole di sincronizzazione per le strutture dati, generalmente,
|
||||||
|
necessitano di una spiegazioni da qualche parte. Le strutture dati più
|
||||||
|
importanti, in generale, hanno bisogno di una documentazione onnicomprensiva.
|
||||||
|
Le dipendenze che non sono ovvie tra bit separati di codice dovrebbero essere
|
||||||
|
indicate. Tutto ciò che potrebbe indurre un inserviente del codice a fare
|
||||||
|
una "pulizia" incorretta, ha bisogno di un commento che dica perché è stato
|
||||||
|
fatto in quel modo. E così via.
|
||||||
|
|
||||||
|
Cambiamenti interni dell'API
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
L'interfaccia binaria fornita dal kernel allo spazio utente non può essere
|
||||||
|
rotta tranne che in circostanze eccezionali. L'interfaccia di programmazione
|
||||||
|
interna al kernel, invece, è estremamente fluida e può essere modificata al
|
||||||
|
bisogno. Se vi trovate a dover lavorare attorno ad un'API del kernel o
|
||||||
|
semplicemente non state utilizzando una funzionalità offerta perché questa
|
||||||
|
non rispecchia i vostri bisogni, allora questo potrebbe essere un segno che
|
||||||
|
l'API ha bisogno di essere cambiata. In qualità di sviluppatore del kernel,
|
||||||
|
hai il potere di fare questo tipo di modifica.
|
||||||
|
|
||||||
|
Ci sono ovviamente alcuni punti da cogliere. I cambiamenti API possono essere
|
||||||
|
fatti, ma devono essere giustificati. Quindi ogni patch che porta ad una
|
||||||
|
modifica dell'API interna dovrebbe essere accompagnata da una descrizione
|
||||||
|
della modifica in sé e del perché essa è necessaria. Questo tipo di
|
||||||
|
cambiamenti dovrebbero, inoltre, essere fatti in una patch separata, invece di
|
||||||
|
essere sepolti all'interno di una patch più grande.
|
||||||
|
|
||||||
|
L'altro punto da cogliere consiste nel fatto che uno sviluppatore che
|
||||||
|
modifica l'API deve, in generale, essere responsabile della correzione
|
||||||
|
di tutto il codice del kernel che viene rotto per via della sua modifica.
|
||||||
|
Per una funzione ampiamente usata, questo compito può condurre letteralmente
|
||||||
|
a centinaia o migliaia di modifiche, molte delle quali sono in conflitto con
|
||||||
|
il lavoro svolto da altri sviluppatori. Non c'è bisogno di dire che questo
|
||||||
|
può essere un lavoro molto grosso, quindi è meglio essere sicuri che la
|
||||||
|
motivazione sia ben solida. Notate che lo strumento Coccinelle può fornire
|
||||||
|
un aiuto con modifiche estese dell'API.
|
||||||
|
|
||||||
|
Quando viene fatta una modifica API incompatibile, una persona dovrebbe,
|
||||||
|
quando possibile, assicurarsi che quel codice non aggiornato sia trovato
|
||||||
|
dal compilatore. Questo vi aiuterà ad essere sicuri d'avere trovato,
|
||||||
|
tutti gli usi di quell'interfaccia. Inoltre questo avviserà gli sviluppatori
|
||||||
|
di codice fuori dal kernel che c'è un cambiamento per il quale è necessario del
|
||||||
|
lavoro. Il supporto al codice fuori dal kernel non è qualcosa di cui gli
|
||||||
|
sviluppatori del kernel devono preoccuparsi, ma non dobbiamo nemmeno rendere
|
||||||
|
più difficile del necessario la vita agli sviluppatori di questo codice.
|
||||||
|
|
|
@ -1,12 +1,348 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/4.Posting.rst <development_posting>`
|
:Original: :ref:`Documentation/process/5.Posting.rst <development_posting>`
|
||||||
|
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_posting:
|
.. _it_development_posting:
|
||||||
|
|
||||||
Pubblicare modifiche
|
Pubblicare modifiche
|
||||||
====================
|
====================
|
||||||
|
|
||||||
.. warning::
|
Prima o poi arriva il momento in cui il vostro lavoro è pronto per essere
|
||||||
|
presentato alla comunità per una revisione ed eventualmente per la sua
|
||||||
|
inclusione nel ramo principale del kernel. Com'era prevedibile,
|
||||||
|
la comunità di sviluppo del kernel ha elaborato un insieme di convenzioni
|
||||||
|
e di procedure per la pubblicazione delle patch; seguirle renderà la vita
|
||||||
|
più facile a tutti quanti. Questo documento cercherà di coprire questi
|
||||||
|
argomenti con un ragionevole livello di dettaglio; più informazioni possono
|
||||||
|
essere trovare nella cartella 'Documentation', nei file
|
||||||
|
:ref:`translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`,
|
||||||
|
:ref:`translations/it_IT/process/submitting-drivers.rst <it_submittingdrivers>`, e
|
||||||
|
:ref:`translations/it_IT/process/submit-checklist.rst <it_submitchecklist>`.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
|
||||||
|
Quando pubblicarle
|
||||||
|
------------------
|
||||||
|
|
||||||
|
C'è sempre una certa resistenza nel pubblicare patch finché non sono
|
||||||
|
veramente "pronte". Per semplici patch questo non è un problema.
|
||||||
|
Ma quando il lavoro è di una certa complessità, c'è molto da guadagnare
|
||||||
|
dai riscontri che la comunità può darvi prima che completiate il lavoro.
|
||||||
|
Dovreste considerare l'idea di pubblicare un lavoro incompleto, o anche
|
||||||
|
preparare un ramo git disponibile agli sviluppatori interessati, cosicché
|
||||||
|
possano stare al passo col vostro lavoro in qualunque momento.
|
||||||
|
|
||||||
|
Quando pubblicate del codice che non è considerato pronto per l'inclusione,
|
||||||
|
è bene che lo diciate al momento della pubblicazione. Inoltre, aggiungete
|
||||||
|
informazioni sulle cose ancora da sviluppare e sui problemi conosciuti.
|
||||||
|
Poche persone guarderanno delle patch che si sa essere fatte a metà,
|
||||||
|
ma quelli che lo faranno penseranno di potervi aiutare a condurre il vostro
|
||||||
|
sviluppo nella giusta direzione.
|
||||||
|
|
||||||
|
|
||||||
|
Prima di creare patch
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Ci sono un certo numero di cose che dovreste fare prima di considerare
|
||||||
|
l'invio delle patch alla comunità di sviluppo. Queste cose includono:
|
||||||
|
|
||||||
|
- Verificare il codice fino al massimo che vi è consentito. Usate gli
|
||||||
|
strumenti di debug del kernel, assicuratevi che il kernel compili con
|
||||||
|
tutte le più ragionevoli combinazioni d'opzioni, usate cross-compilatori
|
||||||
|
per compilare il codice per differenti architetture, eccetera.
|
||||||
|
|
||||||
|
- Assicuratevi che il vostro codice sia conforme alla linee guida del
|
||||||
|
kernel sullo stile del codice.
|
||||||
|
|
||||||
|
- La vostra patch ha delle conseguenze in termini di prestazioni?
|
||||||
|
Se è così, dovreste eseguire dei *benchmark* che mostrino il loro
|
||||||
|
impatto (anche positivo); un riassunto dei risultati dovrebbe essere
|
||||||
|
incluso nella patch.
|
||||||
|
|
||||||
|
- Siate certi d'avere i diritti per pubblicare il codice. Se questo
|
||||||
|
lavoro è stato fatto per un datore di lavoro, egli avrà dei diritti su
|
||||||
|
questo lavoro e dovrà quindi essere d'accordo alla sua pubblicazione
|
||||||
|
con una licenza GPL
|
||||||
|
|
||||||
|
Come regola generale, pensarci un po' di più prima di inviare il codice
|
||||||
|
ripaga quasi sempre lo sforzo.
|
||||||
|
|
||||||
|
|
||||||
|
Preparazione di una patch
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
La preparazione delle patch per la pubblicazione può richiedere una quantità
|
||||||
|
di lavoro significativa, ma, ripetiamolo ancora, generalmente sconsigliamo
|
||||||
|
di risparmiare tempo in questa fase, anche sul breve periodo.
|
||||||
|
|
||||||
|
Le patch devono essere preparate per una specifica versione del kernel.
|
||||||
|
Come regola generale, una patch dovrebbe basarsi sul ramo principale attuale
|
||||||
|
così come lo si trova nei sorgenti git di Linus. Quando vi basate sul ramo
|
||||||
|
principale, cominciate da un punto di rilascio ben noto - uno stabile o
|
||||||
|
un -rc - piuttosto che creare il vostro ramo da quello principale in un punto
|
||||||
|
a caso.
|
||||||
|
|
||||||
|
Per facilitare una revisione e una verifica più estesa, potrebbe diventare
|
||||||
|
necessaria la produzione di versioni per -mm, linux-next o i sorgenti di un
|
||||||
|
sottosistema. Basare questa patch sui suddetti sorgenti potrebbe richiedere
|
||||||
|
un lavoro significativo nella risoluzione dei conflitti e nella correzione dei
|
||||||
|
cambiamenti di API; questo potrebbe variare a seconda dell'area d'interesse
|
||||||
|
della vostra patch e da quello che succede altrove nel kernel.
|
||||||
|
|
||||||
|
Solo le modifiche più semplici dovrebbero essere preparate come una singola
|
||||||
|
patch; tutto il resto dovrebbe essere preparato come una serie logica di
|
||||||
|
modifiche. Spezzettare le patch è un po' un'arte; alcuni sviluppatori
|
||||||
|
passano molto tempo nel capire come farlo in modo che piaccia alla comunità.
|
||||||
|
Ci sono alcune regole spannometriche, che comunque possono aiutare
|
||||||
|
considerevolmente:
|
||||||
|
|
||||||
|
- La serie di patch che pubblicherete, quasi sicuramente, non sarà
|
||||||
|
come quella che trovate nel vostro sistema di controllo di versione.
|
||||||
|
Invece, le vostre modifiche dovranno essere considerate nella loro forma
|
||||||
|
finale, e quindi separate in parti che abbiano un senso. Gli sviluppatori
|
||||||
|
sono interessati in modifiche che siano discrete e indipendenti, non
|
||||||
|
alla strada che avete percorso per ottenerle.
|
||||||
|
|
||||||
|
- Ogni modifica logicamente indipendente dovrebbe essere preparata come una
|
||||||
|
patch separata. Queste modifiche possono essere piccole ("aggiunto un
|
||||||
|
campo in questa struttura") o grandi (l'aggiunta di un driver nuovo,
|
||||||
|
per esempio), ma dovrebbero essere concettualmente piccole da permettere
|
||||||
|
una descrizione in una sola riga. Ogni patch dovrebbe fare modifiche
|
||||||
|
specifiche che si possano revisionare indipendentemente e di cui si possa
|
||||||
|
verificare la veridicità.
|
||||||
|
|
||||||
|
- Giusto per riaffermare quando detto sopra: non mischiate diversi tipi di
|
||||||
|
modifiche nella stessa patch. Se una modifica corregge un baco critico
|
||||||
|
per la sicurezza, riorganizza alcune strutture, e riformatta il codice,
|
||||||
|
ci sono buone probabilità che venga ignorata e che la correzione importante
|
||||||
|
venga persa.
|
||||||
|
|
||||||
|
- Ogni modifica dovrebbe portare ad un kernel che compila e funziona
|
||||||
|
correttamente; se la vostra serie di patch si interrompe a metà il
|
||||||
|
risultato dovrebbe essere comunque un kernel funzionante. L'applicazione
|
||||||
|
parziale di una serie di patch è uno scenario comune nel quale il
|
||||||
|
comando "git bisect" viene usato per trovare delle regressioni; se il
|
||||||
|
risultato è un kernel guasto, renderete la vita degli sviluppatori più
|
||||||
|
difficile così come quella di chi s'impegna nel nobile lavoro di
|
||||||
|
scovare i problemi.
|
||||||
|
|
||||||
|
- Però, non strafate. Una volta uno sviluppatore pubblicò una serie di 500
|
||||||
|
patch che modificavano un unico file - un atto che non lo rese la persona
|
||||||
|
più popolare sulla lista di discussione del kernel. Una singola patch
|
||||||
|
può essere ragionevolmente grande fintanto che contenga un singolo
|
||||||
|
cambiamento *logico*.
|
||||||
|
|
||||||
|
- Potrebbe essere allettante l'idea di aggiungere una nuova infrastruttura
|
||||||
|
come una serie di patch, ma di lasciare questa infrastruttura inutilizzata
|
||||||
|
finché l'ultima patch della serie non abilita tutto quanto. Quando è
|
||||||
|
possibile, questo dovrebbe essere evitato; se questa serie aggiunge delle
|
||||||
|
regressioni, "bisect" indicherà quest'ultima patch come causa del
|
||||||
|
problema anche se il baco si trova altrove. Possibilmente, quando una
|
||||||
|
patch aggiunge del nuovo codice dovrebbe renderlo attivo immediatamente.
|
||||||
|
|
||||||
|
Lavorare per creare la serie di patch perfetta potrebbe essere frustrante
|
||||||
|
perché richiede un certo tempo e soprattutto dopo che il "vero lavoro" è
|
||||||
|
già stato fatto. Quando ben fatto, comunque, è tempo ben speso.
|
||||||
|
|
||||||
|
|
||||||
|
Formattazione delle patch e i changelog
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
Quindi adesso avete una serie perfetta di patch pronte per la pubblicazione,
|
||||||
|
ma il lavoro non è davvero finito. Ogni patch deve essere preparata con
|
||||||
|
un messaggio che spieghi al resto del mondo, in modo chiaro e veloce,
|
||||||
|
il suo scopo. Per ottenerlo, ogni patch sarà composta dai seguenti elementi:
|
||||||
|
|
||||||
|
- Un campo opzionale "From" col nome dell'autore della patch. Questa riga
|
||||||
|
è necessaria solo se state passando la patch di qualcun altro via email,
|
||||||
|
ma nel dubbio non fa di certo male aggiungerlo.
|
||||||
|
|
||||||
|
- Una descrizione di una riga che spieghi cosa fa la patch. Questo
|
||||||
|
messaggio dovrebbe essere sufficiente per far comprendere al lettore lo
|
||||||
|
scopo della patch senza altre informazioni. Questo messaggio,
|
||||||
|
solitamente, presenta in testa il nome del sottosistema a cui si riferisce,
|
||||||
|
seguito dallo scopo della patch. Per esempio:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
gpio: fix build on CONFIG_GPIO_SYSFS=n
|
||||||
|
|
||||||
|
- Una riga bianca seguita da una descrizione dettagliata della patch.
|
||||||
|
Questa descrizione può essere lunga tanto quanto serve; dovrebbe spiegare
|
||||||
|
cosa fa e perché dovrebbe essere aggiunta al kernel.
|
||||||
|
|
||||||
|
- Una o più righe etichette, con, minimo, una riga *Signed-off-by:*
|
||||||
|
col nome dall'autore della patch. Queste etichette verranno descritte
|
||||||
|
meglio più avanti.
|
||||||
|
|
||||||
|
Gli elementi qui sopra, assieme, formano il changelog di una patch.
|
||||||
|
Scrivere un buon changelog è cruciale ma è spesso un'arte trascurata;
|
||||||
|
vale la pena spendere qualche parola in più al riguardo. Quando scrivete
|
||||||
|
un changelog dovreste tenere ben presente che molte persone leggeranno
|
||||||
|
le vostre parole. Queste includono i manutentori di un sotto-sistema, e i
|
||||||
|
revisori che devono decidere se la patch debba essere inclusa o no,
|
||||||
|
le distribuzioni e altri manutentori che cercano di valutare se la patch
|
||||||
|
debba essere applicata su kernel più vecchi, i cacciatori di bachi che si
|
||||||
|
chiederanno se la patch è la causa di un problema che stanno cercando,
|
||||||
|
gli utenti che vogliono sapere com'è cambiato il kernel, e molti altri.
|
||||||
|
Un buon changelog fornisce le informazioni necessarie a tutte queste
|
||||||
|
persone nel modo più diretto e conciso possibile.
|
||||||
|
|
||||||
|
A questo scopo, la riga riassuntiva dovrebbe descrivere gli effetti della
|
||||||
|
modifica e la motivazione della patch nel modo migliore possibile nonostante
|
||||||
|
il limite di una sola riga. La descrizione dettagliata può spiegare meglio
|
||||||
|
i temi e fornire maggiori informazioni. Se una patch corregge un baco,
|
||||||
|
citate, se possibile, il commit che lo introdusse (e per favore, quando
|
||||||
|
citate un commit aggiungete sia il suo identificativo che il titolo),
|
||||||
|
Se il problema è associabile ad un file di log o all' output del compilatore,
|
||||||
|
includeteli al fine d'aiutare gli altri a trovare soluzioni per lo stesso
|
||||||
|
problema. Se la modifica ha lo scopo di essere di supporto a sviluppi
|
||||||
|
successivi, ditelo. Se le API interne vengono cambiate, dettagliate queste
|
||||||
|
modifiche e come gli altri dovrebbero agire per applicarle. In generale,
|
||||||
|
più riuscirete ad entrare nei panni di tutti quelli che leggeranno il
|
||||||
|
vostro changelog, meglio sarà il changelog (e il kernel nel suo insieme).
|
||||||
|
|
||||||
|
Non serve dirlo, un changelog dovrebbe essere il testo usato nel messaggio
|
||||||
|
di commit in un sistema di controllo di versione. Sarà seguito da:
|
||||||
|
|
||||||
|
- La patch stessa, nel formato unificato per patch ("-u"). Usare
|
||||||
|
l'opzione "-p" assocerà alla modifica il nome della funzione alla quale
|
||||||
|
si riferisce, rendendo il risultato più facile da leggere per gli altri.
|
||||||
|
|
||||||
|
Dovreste evitare di includere nelle patch delle modifiche per file
|
||||||
|
irrilevanti (quelli generati dal processo di generazione, per esempio, o i file
|
||||||
|
di backup del vostro editor). Il file "dontdiff" nella cartella Documentation
|
||||||
|
potrà esservi d'aiuto su questo punto; passatelo a diff con l'opzione "-X".
|
||||||
|
|
||||||
|
Le etichette sopra menzionante sono usate per descrivere come i vari
|
||||||
|
sviluppatori sono stati associati allo sviluppo di una patch. Sono descritte
|
||||||
|
in dettaglio nel documento :ref:`translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`;
|
||||||
|
quello che segue è un breve riassunto. Ognuna di queste righe ha il seguente
|
||||||
|
formato:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
tag: Full Name <email address> optional-other-stuff
|
||||||
|
|
||||||
|
Le etichette in uso più comuni sono:
|
||||||
|
|
||||||
|
- Signed-off-by: questa è la certificazione che lo sviluppatore ha il diritto
|
||||||
|
di sottomettere la patch per l'integrazione nel kernel. Questo rappresenta
|
||||||
|
il consenso verso il certificato d'origine degli sviluppatori, il testo
|
||||||
|
completo potrà essere trovato in
|
||||||
|
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
|
||||||
|
Codice che non presenta una firma appropriata non potrà essere integrato.
|
||||||
|
|
||||||
|
- Co-developed-by: indica che la patch è stata sviluppata anche da un altro
|
||||||
|
sviluppatore assieme all'autore originale. Questo è utile quando più
|
||||||
|
persone lavorano sulla stessa patch. Da notare che questa persona deve
|
||||||
|
avere anche una riga "Signed-off-by:" nella patch.
|
||||||
|
|
||||||
|
- Acked-by: indica il consenso di un altro sviluppatore (spesso il manutentore
|
||||||
|
del codice in oggetto) all'integrazione della patch nel kernel.
|
||||||
|
|
||||||
|
- Tested-by: menziona la persona che ha verificato la patch e l'ha trovata
|
||||||
|
funzionante.
|
||||||
|
|
||||||
|
- Reviwed-by: menziona lo sviluppatore che ha revisionato la patch; per
|
||||||
|
maggiori dettagli leggete la dichiarazione dei revisori in
|
||||||
|
:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`
|
||||||
|
|
||||||
|
- Reported-by: menziona l'utente che ha riportato il problema corretto da
|
||||||
|
questa patch; quest'etichetta viene usata per dare credito alle persone
|
||||||
|
che hanno verificato il codice e ci hanno fatto sapere quando le cose non
|
||||||
|
funzionavano correttamente.
|
||||||
|
|
||||||
|
- Cc: la persona menzionata ha ricevuto una copia della patch ed ha avuto
|
||||||
|
l'opportunità di commentarla.
|
||||||
|
|
||||||
|
State attenti ad aggiungere queste etichette alla vostra patch: solo
|
||||||
|
"Cc:" può essere aggiunta senza il permesso esplicito della persona menzionata.
|
||||||
|
|
||||||
|
Inviare la modifica
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Prima di inviare la vostra patch, ci sarebbero ancora un paio di cose di cui
|
||||||
|
dovreste aver cura:
|
||||||
|
|
||||||
|
- Siete sicuri che il vostro programma di posta non corromperà le patch?
|
||||||
|
Le patch che hanno spazi bianchi in libertà o andate a capo aggiunti
|
||||||
|
dai programmi di posta non funzioneranno per chi le riceve, e spesso
|
||||||
|
non verranno nemmeno esaminate in dettaglio. Se avete un qualsiasi dubbio,
|
||||||
|
inviate la patch a voi stessi e verificate che sia integra.
|
||||||
|
|
||||||
|
:ref:`Documentation/translations/it_IT/process/email-clients.rst <it_email_clients>`
|
||||||
|
contiene alcuni suggerimenti utili sulla configurazione dei programmi
|
||||||
|
di posta al fine di inviare patch.
|
||||||
|
|
||||||
|
- Siete sicuri che la vostra patch non contenga sciocchi errori? Dovreste
|
||||||
|
sempre processare le patch con scripts/checkpatch.pl e correggere eventuali
|
||||||
|
problemi riportati. Per favore tenete ben presente che checkpatch.pl non è
|
||||||
|
più intelligente di voi, nonostante sia il risultato di un certa quantità di
|
||||||
|
ragionamenti su come debba essere una patch per il kernel. Se seguire
|
||||||
|
i suggerimenti di checkpatch.pl rende il codice peggiore, allora non fatelo.
|
||||||
|
|
||||||
|
Le patch dovrebbero essere sempre inviate come testo puro. Per favore non
|
||||||
|
inviatele come allegati; questo rende molto più difficile, per i revisori,
|
||||||
|
citare parti della patch che si vogliono commentare. Invece, mettete la vostra
|
||||||
|
patch direttamente nel messaggio.
|
||||||
|
|
||||||
|
Quando inviate le patch, è importante inviarne una copia a tutte le persone che
|
||||||
|
potrebbero esserne interessate. Al contrario di altri progetti, il kernel
|
||||||
|
incoraggia le persone a peccare nell'invio di tante copie; non presumente che
|
||||||
|
le persone interessate vedano i vostri messaggi sulla lista di discussione.
|
||||||
|
In particolare le copie dovrebbero essere inviate a:
|
||||||
|
|
||||||
|
- I manutentori dei sottosistemi affetti della modifica. Come descritto
|
||||||
|
in precedenza, il file MAINTAINERS è il primo luogo dove cercare i nomi
|
||||||
|
di queste persone.
|
||||||
|
|
||||||
|
- Altri sviluppatori che hanno lavorato nello stesso ambiente - specialmente
|
||||||
|
quelli che potrebbero lavorarci proprio ora. Usate git potrebbe essere
|
||||||
|
utile per vedere chi altri ha modificato i file su cui state lavorando.
|
||||||
|
|
||||||
|
- Se state rispondendo a un rapporto su un baco, o a una richiesta di
|
||||||
|
funzionalità, includete anche gli autori di quei rapporti/richieste.
|
||||||
|
|
||||||
|
- Inviate una copia alle liste di discussione interessate, o, se nient'altro
|
||||||
|
è adatto, alla lista linux-kernel
|
||||||
|
|
||||||
|
- Se state correggendo un baco, pensate se la patch dovrebbe essere inclusa
|
||||||
|
nel prossimo rilascio stabile. Se è così, la lista di discussione
|
||||||
|
stable@vger.kernel.org dovrebbe riceverne una copia. Aggiungete anche
|
||||||
|
l'etichetta "Cc: stable@vger.kernel.org" nella patch stessa; questo
|
||||||
|
permetterà alla squadra *stable* di ricevere una notifica quando questa
|
||||||
|
correzione viene integrata nel ramo principale.
|
||||||
|
|
||||||
|
Quando scegliete i destinatari della patch, è bene avere un'idea di chi
|
||||||
|
pensiate che sia colui che, eventualmente, accetterà la vostra patch e
|
||||||
|
la integrerà. Nonostante sia possibile inviare patch direttamente a
|
||||||
|
Linus Torvalds, e lasciare che sia lui ad integrarle,solitamente non è la
|
||||||
|
strada migliore da seguire. Linus è occupato, e ci sono dei manutentori di
|
||||||
|
sotto-sistema che controllano una parte specifica del kernel. Solitamente,
|
||||||
|
vorreste che siano questi manutentori ad integrare le vostre patch. Se non
|
||||||
|
c'è un chiaro manutentore, l'ultima spiaggia è spesso Andrew Morton.
|
||||||
|
|
||||||
|
Le patch devono avere anche un buon oggetto. Il tipico formato per l'oggetto
|
||||||
|
di una patch assomiglia a questo:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[PATCH nn/mm] subsys: one-line description of the patch
|
||||||
|
|
||||||
|
dove "nn" è il numero ordinale della patch, "mm" è il numero totale delle patch
|
||||||
|
nella serie, e "subsys" è il nome del sottosistema interessato. Chiaramente,
|
||||||
|
nn/mm può essere omesso per una serie composta da una singola patch.
|
||||||
|
|
||||||
|
Se avete una significative serie di patch, è prassi inviare una descrizione
|
||||||
|
introduttiva come parte zero. Tuttavia questa convenzione non è universalmente
|
||||||
|
seguita; se la usate, ricordate che le informazioni nell'introduzione non
|
||||||
|
faranno parte del changelog del kernel. Quindi per favore, assicuratevi che
|
||||||
|
ogni patch abbia un changelog completo.
|
||||||
|
|
||||||
|
In generale, la seconda parte e quelle successive di una patch "composta"
|
||||||
|
dovrebbero essere inviate come risposta alla prima, cosicché vengano viste
|
||||||
|
come un unico *thread*. Strumenti come git e quilt hanno comandi per inviare
|
||||||
|
gruppi di patch con la struttura appropriata. Se avete una serie lunga
|
||||||
|
e state usando git, per favore state alla larga dall'opzione --chain-reply-to
|
||||||
|
per evitare di creare un annidamento eccessivo.
|
||||||
|
|
|
@ -1,10 +1,240 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/6.Followthrough.rst <development_followthrough>`
|
:Original: :ref:`Documentation/process/6.Followthrough.rst <development_followthrough>`
|
||||||
|
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
|
||||||
|
|
||||||
|
.. _it_development_followthrough:
|
||||||
|
|
||||||
|
=============
|
||||||
Completamento
|
Completamento
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
È raro che una modifica sia così bella alla sua prima pubblicazione che non
|
||||||
|
ci sia alcuno spazio di miglioramento. Il programma di sviluppo del kernel
|
||||||
|
riconosce questo fatto e quindi, è fortemente orientato al miglioramento
|
||||||
|
del codice pubblicato. Voi, in qualità di autori del codice, dovrete
|
||||||
|
lavorare con la comunità del kernel per assicurare che il vostro codice
|
||||||
|
mantenga gli standard qualitativi richiesti. Un fallimento in questo
|
||||||
|
processo è quasi come impedire l'inclusione delle vostre patch nel
|
||||||
|
ramo principale.
|
||||||
|
|
||||||
|
Lavorare con i revisori
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Una patch che abbia una certa rilevanza avrà ricevuto numerosi commenti
|
||||||
|
da parte di altri sviluppatori dato che avranno revisionato il codice.
|
||||||
|
Lavorare con i revisori può rivelarsi, per molti sviluppatori, la parte
|
||||||
|
più intimidatoria del processo di sviluppo del kernel. La vita può esservi
|
||||||
|
resa molto più facile se tenete presente alcuni dettagli:
|
||||||
|
|
||||||
|
- Se avete descritto la vostra modifica correttamente, i revisori ne
|
||||||
|
comprenderanno il valore e il perché vi siete presi il disturbo di
|
||||||
|
scriverla. Ma tale valore non li tratterrà dal porvi una domanda
|
||||||
|
fondamentale: come verrà mantenuto questo codice nel kernel nei prossimi
|
||||||
|
cinque o dieci anni? Molti dei cambiamenti che potrebbero esservi
|
||||||
|
richiesti - da piccoli problemi di stile a sostanziali ristesure -
|
||||||
|
vengono dalla consapevolezza che Linux resterà in circolazione e in
|
||||||
|
continuo sviluppo ancora per diverse decadi.
|
||||||
|
|
||||||
|
- La revisione del codice è un duro lavoro, ed è un mestiere poco
|
||||||
|
riconosciuto; le persone ricordano chi ha scritto il codice, ma meno
|
||||||
|
fama è attribuita a chi lo ha revisionato. Quindi i revisori potrebbero
|
||||||
|
divenire burberi, specialmente quando vendono i medesimi errori venire
|
||||||
|
fatti ancora e ancora. Se ricevete una revisione che vi sembra abbia
|
||||||
|
un tono arrabbiato, insultante o addirittura offensivo, resistente alla
|
||||||
|
tentazione di rispondere a tono. La revisione riguarda il codice e non
|
||||||
|
la persona, e i revisori non vi stanno attaccando personalmente.
|
||||||
|
|
||||||
|
- Similarmente, i revisori del codice non stanno cercando di promuovere
|
||||||
|
i loro interessi a vostre spese. Gli sviluppatori del kernel spesso si
|
||||||
|
aspettano di lavorare sul kernel per anni, ma sanno che il loro datore
|
||||||
|
di lavoro può cambiare. Davvero, senza praticamente eccezioni, loro
|
||||||
|
stanno lavorando per la creazione del miglior kernel possibile; non
|
||||||
|
stanno cercando di creare un disagio ad aziende concorrenti.
|
||||||
|
|
||||||
|
Quello che si sta cercando di dire è che, quando i revisori vi inviano degli
|
||||||
|
appunti dovete fare attenzione alle osservazioni tecniche che vi stanno
|
||||||
|
facendo. Non lasciate che il loro modo di esprimersi o il vostro orgoglio
|
||||||
|
impediscano che ciò accada. Quando avete dei suggerimenti sulla revisione,
|
||||||
|
prendetevi il tempo per comprendere cosa il revisore stia cercando di
|
||||||
|
comunicarvi. Se possibile, sistemate le cose che il revisore vi chiede di
|
||||||
|
modificare. E rispondete al revisore ringraziandolo e spiegando come
|
||||||
|
intendete fare.
|
||||||
|
|
||||||
|
Notate che non dovete per forza essere d'accordo con ogni singola modifica
|
||||||
|
suggerita dai revisori. Se credete che il revisore non abbia compreso
|
||||||
|
il vostro codice, spiegateglielo. Se avete un'obiezione tecnica da fargli
|
||||||
|
su di una modifica suggerita, spiegatela inserendo anche la vostra soluzione
|
||||||
|
al problema. Se la vostra spiegazione ha senso, il revisore la accetterà.
|
||||||
|
Tuttavia, la vostra motivazione potrebbe non essere del tutto persuasiva,
|
||||||
|
specialmente se altri iniziano ad essere d'accordo con il revisore.
|
||||||
|
Prendetevi quindi un po' di tempo per pensare ancora alla cosa. Può risultare
|
||||||
|
facile essere accecati dalla propria soluzione al punto che non realizzate che
|
||||||
|
c'è qualcosa di fondamentalmente sbagliato o, magari, non state nemmeno
|
||||||
|
risolvendo il problema giusto.
|
||||||
|
|
||||||
|
Andrew Morton suggerisce che ogni suggerimento di revisione che non è
|
||||||
|
presente nella modifica del codice dovrebbe essere inserito in un commento
|
||||||
|
aggiuntivo; ciò può essere d'aiuto ai futuri revisori nell'evitare domande
|
||||||
|
che sorgono al primo sguardo.
|
||||||
|
|
||||||
|
Un errore fatale è quello di ignorare i commenti di revisione nella speranza
|
||||||
|
che se ne andranno. Non andranno via. Se pubblicherete nuovamente il
|
||||||
|
codice senza aver risposto ai commenti ricevuti, probabilmente le vostre
|
||||||
|
modifiche non andranno da nessuna parte.
|
||||||
|
|
||||||
|
Parlando di ripubblicazione del codice: per favore tenete a mente che i
|
||||||
|
revisori non ricorderanno tutti i dettagli del codice che avete pubblicato
|
||||||
|
l'ultima volta. Quindi è sempre una buona idea quella di ricordare ai
|
||||||
|
revisori le questioni sollevate precedetemene e come le avete risolte.
|
||||||
|
I revisori non dovrebbero star lì a cercare all'interno degli archivi per
|
||||||
|
famigliarizzare con ciò che è stato detto l'ultima volta; se li aiutate
|
||||||
|
in questo senso, saranno di umore migliore quando riguarderanno il vostro
|
||||||
|
codice.
|
||||||
|
|
||||||
|
Se invece avete cercato di far tutto correttamente ma le cose continuano
|
||||||
|
a non andar bene? Molti disaccordi di natura tecnica possono essere risolti
|
||||||
|
attraverso la discussione, ma ci sono volte dove qualcuno deve prendere
|
||||||
|
una decisione. Se credete veramente che tale decisione andrà contro di voi
|
||||||
|
ingiustamente, potete sempre tentare di rivolgervi a qualcuno più
|
||||||
|
in alto di voi. Per cose di questo genere la persona con più potere è
|
||||||
|
Andrew Morton. Andrew è una figura molto rispettata all'interno della
|
||||||
|
comunità di sviluppo del kernel; lui può spesso sbrogliare situazioni che
|
||||||
|
sembrano irrimediabilmente bloccate. Rivolgersi ad Andrew non deve essere
|
||||||
|
fatto alla leggera, e non deve essere fatto prima di aver esplorato tutte
|
||||||
|
le altre alternative. E tenete a mente, ovviamente, che nemmeno lui
|
||||||
|
potrebbe non essere d'accordo con voi.
|
||||||
|
|
||||||
|
Cosa accade poi
|
||||||
|
===============
|
||||||
|
|
||||||
|
Se la modifica è ritenuta un elemento valido da essere aggiunta al kernel,
|
||||||
|
e una volta che la maggior parte degli appunti dei revisori sono stati
|
||||||
|
sistemati, il passo successivo solitamente è quello di entrare in un
|
||||||
|
sottosistema gestito da un manutentore. Come ciò avviene dipende dal
|
||||||
|
sottosistema medesimo; ogni manutentore ha il proprio modo di fare le cose.
|
||||||
|
In particolare, ci potrebbero essere diversi sorgenti - uno, magari, dedicato
|
||||||
|
alle modifiche pianificate per la finestra di fusione successiva, e un altro
|
||||||
|
per il lavoro di lungo periodo.
|
||||||
|
|
||||||
|
Per le modifiche proposte in aree per le quali non esiste un sottosistema
|
||||||
|
preciso (modifiche di gestione della memoria, per esempio), i sorgenti di
|
||||||
|
ripiego finiscono per essere -mm. Ed anche le modifiche che riguardano
|
||||||
|
più sottosistemi possono finire in quest'ultimo.
|
||||||
|
|
||||||
|
L'inclusione nei sorgenti di un sottosistema può comportare per una patch,
|
||||||
|
un alto livello di visibilità. Ora altri sviluppatori che stanno lavorando
|
||||||
|
in quei medesimi sorgenti avranno le vostre modifiche. I sottosistemi
|
||||||
|
solitamente riforniscono anche Linux-next, rendendo i propri contenuti
|
||||||
|
visibili all'intera comunità di sviluppo. A questo punto, ci sono buone
|
||||||
|
possibilità per voi di ricevere ulteriori commenti da un nuovo gruppo di
|
||||||
|
revisori; anche a questi commenti dovrete rispondere come avete già fatto per
|
||||||
|
gli altri.
|
||||||
|
|
||||||
|
Ciò che potrebbe accadere a questo punto, in base alla natura della vostra
|
||||||
|
modifica, riguarda eventuali conflitti con il lavoro svolto da altri.
|
||||||
|
Nella peggiore delle situazioni, i conflitti più pesanti tra modifiche possono
|
||||||
|
concludersi con la messa a lato di alcuni dei lavori svolti cosicché le
|
||||||
|
modifiche restanti possano funzionare ed essere integrate. Altre volte, la
|
||||||
|
risoluzione dei conflitti richiederà del lavoro con altri sviluppatori e,
|
||||||
|
possibilmente, lo spostamento di alcune patch da dei sorgenti a degli altri
|
||||||
|
in modo da assicurare che tutto sia applicato in modo pulito. Questo lavoro
|
||||||
|
può rivelarsi una spina nel fianco, ma consideratevi fortunati: prima
|
||||||
|
dell'avvento dei sorgenti linux-next, questi conflitti spesso emergevano solo
|
||||||
|
durante l'apertura della finestra di integrazione e dovevano essere smaltiti
|
||||||
|
in fretta. Ora essi possono essere risolti comodamente, prima dell'apertura
|
||||||
|
della finestra.
|
||||||
|
|
||||||
|
Un giorno, se tutto va bene, vi collegherete e vedrete che la vostra patch
|
||||||
|
è stata inserita nel ramo principale de kernel. Congratulazioni! Terminati
|
||||||
|
i festeggiamenti (nel frattempo avrete inserito il vostro nome nel file
|
||||||
|
MAINTAINERS) vale la pena ricordare una piccola cosa, ma importante: il
|
||||||
|
lavoro non è ancora finito. L'inserimento nel ramo principale porta con se
|
||||||
|
nuove sfide.
|
||||||
|
|
||||||
|
Cominciamo con il dire che ora la visibilità della vostra modifica è
|
||||||
|
ulteriormente cresciuta. Ci potrebbe portare ad una nuova fase di
|
||||||
|
commenti dagli sviluppatori che non erano ancora a conoscenza della vostra
|
||||||
|
patch. Ignorarli potrebbe essere allettante dato che non ci sono più
|
||||||
|
dubbi sull'integrazione della modifica. Resistete a tale tentazione, dovete
|
||||||
|
mantenervi disponibili agli sviluppatori che hanno domande o suggerimenti
|
||||||
|
per voi.
|
||||||
|
|
||||||
|
Ancora più importante: l'inclusione nel ramo principale mette il vostro
|
||||||
|
codice nelle mani di un gruppo di *tester* molto più esteso. Anche se avete
|
||||||
|
contribuito ad un driver per un hardware che non è ancora disponibile, sarete
|
||||||
|
sorpresi da quante persone inseriranno il vostro codice nei loro kernel.
|
||||||
|
E, ovviamente, dove ci sono *tester*, ci saranno anche dei rapporti su
|
||||||
|
eventuali bachi.
|
||||||
|
|
||||||
|
La peggior specie di rapporti sono quelli che indicano delle regressioni.
|
||||||
|
Se la vostra modifica causa una regressione, avrete un gran numero di
|
||||||
|
occhi puntati su di voi; la regressione deve essere sistemata il prima
|
||||||
|
possibile. Se non vorrete o non sarete capaci di sistemarla (e nessuno
|
||||||
|
lo farà per voi), la vostra modifica sarà quasi certamente rimossa durante
|
||||||
|
la fase di stabilizzazione. Oltre alla perdita di tutto il lavoro svolto
|
||||||
|
per far si che la vostra modifica fosse inserita nel ramo principale,
|
||||||
|
l'avere una modifica rimossa a causa del fallimento nel sistemare una
|
||||||
|
regressione, potrebbe rendere più difficile per voi far accettare
|
||||||
|
il vostro lavoro in futuro.
|
||||||
|
|
||||||
|
Dopo che ogni regressione è stata affrontata, ci potrebbero essere altri
|
||||||
|
bachi ordinari da "sconfiggere". Il periodo di stabilizzazione è la
|
||||||
|
vostra migliore opportunità per sistemare questi bachi e assicurarvi che
|
||||||
|
il debutto del vostro codice nel ramo principale del kernel sia il più solido
|
||||||
|
possibile. Quindi, per favore, rispondete ai rapporti sui bachi e ponete
|
||||||
|
rimedio, se possibile, a tutti i problemi. È a questo che serve il periodo
|
||||||
|
di stabilizzazione; potete iniziare creando nuove fantastiche modifiche
|
||||||
|
una volta che ogni problema con le vecchie sia stato risolto.
|
||||||
|
|
||||||
|
Non dimenticate che esistono altre pietre miliari che possono generare
|
||||||
|
rapporti sui bachi: il successivo rilascio stabile, quando una distribuzione
|
||||||
|
importante usa una versione del kernel nel quale è presente la vostra
|
||||||
|
modifica, eccetera. Il continuare a rispondere a questi rapporti è fonte di
|
||||||
|
orgoglio per il vostro lavoro. Se questa non è una sufficiente motivazione,
|
||||||
|
allora, è anche consigliabile considera che la comunità di sviluppo ricorda
|
||||||
|
gli sviluppatori che hanno perso interesse per il loro codice una volta
|
||||||
|
integrato. La prossima volta che pubblicherete una patch, la comunità
|
||||||
|
la valuterà anche sulla base del fatto che non sarete disponibili a
|
||||||
|
prendervene cura anche nel futuro.
|
||||||
|
|
||||||
|
|
||||||
|
Altre cose che posso accadere
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Un giorno, potreste aprire la vostra email e vedere che qualcuno vi ha
|
||||||
|
inviato una patch per il vostro codice. Questo, dopo tutto, è uno dei
|
||||||
|
vantaggi di avere il vostro codice "là fuori". Se siete d'accordo con
|
||||||
|
la modifica, potrete anche inoltrarla ad un manutentore di sottosistema
|
||||||
|
(assicuratevi di includere la riga "From:" cosicché l'attribuzione sia
|
||||||
|
corretta, e aggiungete una vostra firma "Signed-off-by"), oppure inviate
|
||||||
|
un "Acked-by:" e lasciate che l'autore originale la invii.
|
||||||
|
|
||||||
|
Se non siete d'accordo con la patch, inviate una risposta educata
|
||||||
|
spiegando il perché. Se possibile, dite all'autore quali cambiamenti
|
||||||
|
servirebbero per rendere la patch accettabile da voi. C'è una certa
|
||||||
|
riluttanza nell'inserire modifiche con un conflitto fra autore
|
||||||
|
e manutentore del codice, ma solo fino ad un certo punto. Se siete visti
|
||||||
|
come qualcuno che blocca un buon lavoro senza motivo, quelle patch vi
|
||||||
|
passeranno oltre e andranno nel ramo principale in ogni caso. Nel kernel
|
||||||
|
Linux, nessuno ha potere di veto assoluto su alcun codice. Eccezione
|
||||||
|
fatta per Linus, forse.
|
||||||
|
|
||||||
|
In rarissime occasioni, potreste vedere qualcosa di completamente diverso:
|
||||||
|
un altro sviluppatore che pubblica una soluzione differente al vostro
|
||||||
|
problema. A questo punto, c'è una buona probabilità che una delle due
|
||||||
|
modifiche non verrà integrata, e il "c'ero prima io" non è considerato
|
||||||
|
un argomento tecnico rilevante. Se la modifica di qualcun'altro rimpiazza
|
||||||
|
la vostra ed entra nel ramo principale, esiste un unico modo di reagire:
|
||||||
|
siate contenti che il vostro problema sia stato risolto e andate avanti con
|
||||||
|
il vostro lavoro. L'avere un vostro lavoro spintonato da parte in questo
|
||||||
|
modo può essere avvilente e scoraggiante, ma la comunità ricorderà come
|
||||||
|
avrete reagito anche dopo che avrà dimenticato quale fu la modifica accettata.
|
||||||
|
|
|
@ -1,13 +1,191 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>`
|
:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>`
|
||||||
|
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_advancedtopics:
|
.. _it_development_advancedtopics:
|
||||||
|
|
||||||
Argomenti avanzati
|
Argomenti avanzati
|
||||||
==================
|
==================
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
Gestire le modifiche con git
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
L'uso di un sistema distribuito per il controllo delle versioni del kernel
|
||||||
|
ebbe iniziò nel 2002 quando Linux iniziò a provare il programma proprietario
|
||||||
|
BitKeeper. Nonostante l'uso di BitKeeper fosse opinabile, di certo il suo
|
||||||
|
approccio alla gestione dei sorgenti non lo era. Un sistema distribuito per
|
||||||
|
il controllo delle versioni accelerò immediatamente lo sviluppo del kernel.
|
||||||
|
Oggigiorno, ci sono diverse alternative libere a BitKeeper. Per il meglio o il
|
||||||
|
peggio, il progetto del kernel ha deciso di usare git per gestire i sorgenti.
|
||||||
|
|
||||||
|
Gestire le modifiche con git può rendere la vita dello sviluppatore molto
|
||||||
|
più facile, specialmente quando il volume delle modifiche cresce.
|
||||||
|
Git ha anche i suoi lati taglienti che possono essere pericolosi; è uno
|
||||||
|
strumento giovane e potente che è ancora in fase di civilizzazione da parte
|
||||||
|
dei suoi sviluppatori. Questo documento non ha lo scopo di insegnare l'uso
|
||||||
|
di git ai suoi lettori; ci sarebbe materiale a sufficienza per un lungo
|
||||||
|
documento al riguardo. Invece, qui ci concentriamo in particolare su come
|
||||||
|
git è parte del processo di sviluppo del kernel. Gli sviluppatori che
|
||||||
|
desiderassero diventare agili con git troveranno più informazioni ai
|
||||||
|
seguenti indirizzi:
|
||||||
|
|
||||||
|
http://git-scm.com/
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
|
||||||
|
|
||||||
|
e su varie guide che potrete trovare su internet.
|
||||||
|
|
||||||
|
La prima cosa da fare prima di usarlo per produrre patch che saranno
|
||||||
|
disponibili ad altri, è quella di leggere i siti qui sopra e di acquisire una
|
||||||
|
base solida su come funziona git. Uno sviluppatore che sappia usare git
|
||||||
|
dovrebbe essere capace di ottenere una copia del repositorio principale,
|
||||||
|
esplorare la storia della revisione, registrare le modifiche, usare i rami,
|
||||||
|
eccetera. Una certa comprensione degli strumenti git per riscrivere la storia
|
||||||
|
(come ``rebase``) è altrettanto utile. Git ha i propri concetti e la propria
|
||||||
|
terminologia; un nuovo utente dovrebbe conoscere *refs*, *remote branch*,
|
||||||
|
*index*, *fast-forward merge*, *push* e *pull*, *detached head*, eccetera.
|
||||||
|
Il tutto potrebbe essere un po' intimidatorio visto da fuori, ma con un po'
|
||||||
|
di studio i concetti non saranno così difficili da capire.
|
||||||
|
|
||||||
|
Utilizzare git per produrre patch da sottomettere via email può essere
|
||||||
|
un buon esercizio da fare mentre si sta prendendo confidenza con lo strumento.
|
||||||
|
|
||||||
|
Quando sarete in grado di creare rami git che siano guardabili da altri,
|
||||||
|
vi servirà, ovviamente, un server dal quale sia possibile attingere le vostre
|
||||||
|
modifiche. Se avete un server accessibile da Internet, configurarlo per
|
||||||
|
eseguire git-daemon è relativamente semplice . Altrimenti, iniziano a
|
||||||
|
svilupparsi piattaforme che offrono spazi pubblici, e gratuiti (Github,
|
||||||
|
per esempio). Gli sviluppatori permanenti possono ottenere un account
|
||||||
|
su kernel.org, ma non è proprio facile da ottenere; per maggiori informazioni
|
||||||
|
consultate la pagina web http://kernel.org/faq/.
|
||||||
|
|
||||||
|
In git è normale avere a che fare con tanti rami. Ogni linea di sviluppo
|
||||||
|
può essere separata in "rami per argomenti" e gestiti indipendentemente.
|
||||||
|
In git i rami sono facilissimi, per cui non c'è motivo per non usarli
|
||||||
|
in libertà. In ogni caso, non dovreste sviluppare su alcun ramo dal
|
||||||
|
quale altri potrebbero attingere. I rami disponibili pubblicamente dovrebbero
|
||||||
|
essere creati con attenzione; integrate patch dai rami di sviluppo
|
||||||
|
solo quando sono complete e pronte ad essere consegnate - non prima.
|
||||||
|
|
||||||
|
Git offre alcuni strumenti che vi permettono di riscrivere la storia del
|
||||||
|
vostro sviluppo. Una modifica errata (diciamo, una che rompe la bisezione,
|
||||||
|
oppure che ha un qualche tipo di baco evidente) può essere corretta sul posto
|
||||||
|
o fatta sparire completamente dalla storia. Una serie di patch può essere
|
||||||
|
riscritta come se fosse stata scritta in cima al ramo principale di oggi,
|
||||||
|
anche se ci avete lavorato per mesi. Le modifiche possono essere spostate
|
||||||
|
in modo trasparente da un ramo ad un altro. E così via. Un uso giudizioso
|
||||||
|
di git per revisionare la storia può aiutare nella creazione di una serie
|
||||||
|
di patch pulite e con meno problemi.
|
||||||
|
|
||||||
|
Un uso eccessivo può portare ad altri tipi di problemi, tuttavia, oltre
|
||||||
|
alla semplice ossessione per la creazione di una storia del progetto che sia
|
||||||
|
perfetta. Riscrivere la storia riscriverà le patch contenute in quella
|
||||||
|
storia, trasformando un kernel verificato (si spera) in uno da verificare.
|
||||||
|
Ma, oltre a questo, gli sviluppatori non possono collaborare se non condividono
|
||||||
|
la stessa vista sulla storia del progetto; se riscrivete la storia dalla quale
|
||||||
|
altri sviluppatori hanno attinto per i loro repositori, renderete la loro vita
|
||||||
|
molto più difficile. Quindi tenete conto di questa semplice regola generale:
|
||||||
|
la storia che avete esposto ad altri, generalmente, dovrebbe essere vista come
|
||||||
|
immutabile.
|
||||||
|
|
||||||
|
Dunque, una volta che il vostro insieme di patch è stato reso disponibile
|
||||||
|
pubblicamente non dovrebbe essere più sovrascritto. Git tenterà di imporre
|
||||||
|
questa regola, e si rifiuterà di pubblicare nuove patch che non risultino
|
||||||
|
essere dirette discendenti di quelle pubblicate in precedenza (in altre parole,
|
||||||
|
patch che non condividono la stessa storia). È possibile ignorare questo
|
||||||
|
controllo, e ci saranno momenti in cui sarà davvero necessario riscrivere
|
||||||
|
un ramo già pubblicato. Un esempio è linux-next dove le patch vengono
|
||||||
|
spostate da un ramo all'altro al fine di evitare conflitti. Ma questo tipo
|
||||||
|
d'azione dovrebbe essere un'eccezione. Questo è uno dei motivi per cui lo
|
||||||
|
sviluppo dovrebbe avvenire in rami privati (che possono essere sovrascritti
|
||||||
|
quando lo si ritiene necessario) e reso pubblico solo quando è in uno stato
|
||||||
|
avanzato.
|
||||||
|
|
||||||
|
Man mano che il ramo principale (o altri rami su cui avete basato le
|
||||||
|
modifiche) avanza, diventa allettante l'idea di integrare tutte le patch
|
||||||
|
per rimanere sempre aggiornati. Per un ramo privato, il *rebase* può essere
|
||||||
|
un modo semplice per rimanere aggiornati, ma questa non è un'opzione nel
|
||||||
|
momento in cui il vostro ramo è stato esposto al mondo intero.
|
||||||
|
*Merge* occasionali possono essere considerati di buon senso, ma quando
|
||||||
|
diventano troppo frequenti confondono inutilmente la storia. La tecnica
|
||||||
|
suggerita in questi casi è quella di fare *merge* raramente, e più in generale
|
||||||
|
solo nei momenti di rilascio (per esempio gli -rc del ramo principale).
|
||||||
|
Se siete nervosi circa alcune patch in particolare, potete sempre fare
|
||||||
|
dei *merge* di test in un ramo privato. In queste situazioni git "rerere"
|
||||||
|
può essere utile; questo strumento si ricorda come i conflitti di *merge*
|
||||||
|
furono risolti in passato cosicché non dovrete fare lo stesso lavoro due volte.
|
||||||
|
|
||||||
|
Una delle lamentele più grosse e ricorrenti sull'uso di strumenti come git
|
||||||
|
è il grande movimento di patch da un repositorio all'altro che rende
|
||||||
|
facile l'integrazione nel ramo principale di modifiche mediocri, il tutto
|
||||||
|
sotto il naso dei revisori. Gli sviluppatori del kernel tendono ad essere
|
||||||
|
scontenti quando vedono succedere queste cose; preparare un ramo git con
|
||||||
|
patch che non hanno ricevuto alcuna revisione o completamente avulse, potrebbe
|
||||||
|
influire sulla vostra capacita di proporre, in futuro, l'integrazione dei
|
||||||
|
vostri rami. Citando Linus
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Potete inviarmi le vostre patch, ma per far si che io integri una
|
||||||
|
vostra modifica da git, devo sapere che voi sappiate cosa state
|
||||||
|
facendo, e ho bisogno di fidarmi *senza* dover passare tutte
|
||||||
|
le modifiche manualmente una per una.
|
||||||
|
|
||||||
|
(http://lwn.net/Articles/224135/).
|
||||||
|
|
||||||
|
Per evitare queste situazioni, assicuratevi che tutte le patch in un ramo
|
||||||
|
siano strettamente correlate al tema delle modifiche; un ramo "driver fixes"
|
||||||
|
non dovrebbe fare modifiche al codice principale per la gestione della memoria.
|
||||||
|
E, più importante ancora, non usate un repositorio git per tentare di
|
||||||
|
evitare il processo di revisione. Pubblicate un sommario di quello che il
|
||||||
|
vostro ramo contiene sulle liste di discussione più opportune, e , quando
|
||||||
|
sarà il momento, richiedete che il vostro ramo venga integrato in linux-next.
|
||||||
|
|
||||||
|
Se e quando altri inizieranno ad inviarvi patch per essere incluse nel
|
||||||
|
vostro repositorio, non dovete dimenticare di revisionarle. Inoltre
|
||||||
|
assicuratevi di mantenerne le informazioni di paternità; al riguardo git "am"
|
||||||
|
fa del suo meglio, ma potreste dover aggiungere una riga "From:" alla patch
|
||||||
|
nel caso in cui sia arrivata per vie traverse.
|
||||||
|
|
||||||
|
Quando richiedete l'integrazione, siate certi di fornire tutte le informazioni:
|
||||||
|
dov'è il vostro repositorio, quale ramo integrare, e quali cambiamenti si
|
||||||
|
otterranno dall'integrazione. Il comando git request-pull può essere d'aiuto;
|
||||||
|
preparerà una richiesta nel modo in cui gli altri sviluppatori se l'aspettano,
|
||||||
|
e verificherà che vi siate ricordati di pubblicare quelle patch su un
|
||||||
|
server pubblico.
|
||||||
|
|
||||||
|
Revisionare le patch
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Alcuni lettori potrebbero avere obiezioni sulla presenza di questa sezione
|
||||||
|
negli "argomenti avanzati" sulla base che anche gli sviluppatori principianti
|
||||||
|
dovrebbero revisionare le patch. É certamente vero che non c'è modo
|
||||||
|
migliore di imparare come programmare per il kernel che guardare il codice
|
||||||
|
pubblicato dagli altri. In aggiunta, i revisori sono sempre troppo pochi;
|
||||||
|
guardando il codice potete apportare un significativo contributo all'intero
|
||||||
|
processo.
|
||||||
|
|
||||||
|
Revisionare il codice potrebbe risultare intimidatorio, specialmente per i
|
||||||
|
nuovi arrivati che potrebbero sentirsi un po' nervosi nel questionare
|
||||||
|
il codice - in pubblico - pubblicato da sviluppatori più esperti. Perfino
|
||||||
|
il codice scritto dagli sviluppatori più esperti può essere migliorato.
|
||||||
|
Forse il suggerimento migliore per i revisori (tutti) è questo: formulate
|
||||||
|
i commenti come domande e non come critiche. Chiedere "Come viene rilasciato
|
||||||
|
il *lock* in questo percorso?" funziona sempre molto meglio che
|
||||||
|
"qui la sincronizzazione è sbagliata".
|
||||||
|
|
||||||
|
Diversi sviluppatori revisioneranno il codice con diversi punti di vista.
|
||||||
|
Alcuni potrebbero concentrarsi principalmente sullo stile del codice e se
|
||||||
|
alcune linee hanno degli spazio bianchi di troppo. Altri si chiederanno
|
||||||
|
se accettare una modifica interamente è una cosa positiva per il kernel
|
||||||
|
o no. E altri ancora si focalizzeranno sui problemi di sincronizzazione,
|
||||||
|
l'uso eccessivo di *stack*, problemi di sicurezza, duplicazione del codice
|
||||||
|
in altri contesti, documentazione, effetti negativi sulle prestazioni, cambi
|
||||||
|
all'ABI dello spazio utente, eccetera. Qualunque tipo di revisione è ben
|
||||||
|
accetta e di valore, se porta ad avere un codice migliore nel kernel.
|
||||||
|
|
|
@ -1,12 +1,85 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/8.Conclusion.rst <development_conclusion>`
|
:Original: :ref:`Documentation/process/8.Conclusion.rst <development_conclusion>`
|
||||||
|
:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_development_conclusion:
|
.. _it_development_conclusion:
|
||||||
|
|
||||||
Per maggiori informazioni
|
Per maggiori informazioni
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
.. warning::
|
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.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
Il file :ref:`process/howto.rst <it_process_howto>` è un punto di partenza
|
||||||
|
importante; :ref:`process/submitting-patches.rst <it_submittingpatches>` e
|
||||||
|
:ref:`process/submitting-drivers.rst <it_submittingdrivers>` sono
|
||||||
|
anch'essi qualcosa che tutti gli sviluppatori del kernel dovrebbero leggere.
|
||||||
|
Molte API interne al kernel sono documentate utilizzando il meccanismo
|
||||||
|
kerneldoc; "make htmldocs" o "make pdfdocs" possono essere usati per generare
|
||||||
|
quei documenti in HTML o PDF (sebbene le versioni di TeX di alcune
|
||||||
|
distribuzioni hanno dei limiti interni e fallisce nel processare
|
||||||
|
appropriatamente i documenti).
|
||||||
|
|
||||||
|
Diversi siti web approfondiscono lo sviluppo del kernel ad ogni livello
|
||||||
|
di dettaglio. Il vostro autore vorrebbe umilmente suggerirvi
|
||||||
|
http://lwn.net/ come fonte; usando l'indice 'kernel' su LWN troverete
|
||||||
|
molti argomenti specifici sul kernel:
|
||||||
|
|
||||||
|
http://lwn.net/Kernel/Index/
|
||||||
|
|
||||||
|
Oltre a ciò, una risorsa valida per gli sviluppatori kernel è:
|
||||||
|
|
||||||
|
http://kernelnewbies.org/
|
||||||
|
|
||||||
|
E, ovviamente, una fonte da non dimenticare è http://kernel.org/, il luogo
|
||||||
|
definitivo per le informazioni sui rilasci del kernel.
|
||||||
|
|
||||||
|
Ci sono numerosi libri sullo sviluppo del kernel:
|
||||||
|
|
||||||
|
Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro
|
||||||
|
Rubini, and Greg Kroah-Hartman). In linea all'indirizzo
|
||||||
|
http://lwn.net/Kernel/LDD3/.
|
||||||
|
|
||||||
|
Linux Kernel Development (Robert Love).
|
||||||
|
|
||||||
|
Understanding the Linux Kernel (Daniel Bovet and Marco Cesati).
|
||||||
|
|
||||||
|
Tutti questi libri soffrono di un errore comune: tendono a risultare in un
|
||||||
|
certo senso obsoleti dal momento che si trovano in libreria da diverso
|
||||||
|
tempo. Comunque contengono informazioni abbastanza buone.
|
||||||
|
|
||||||
|
La documentazione per git la troverete su:
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/software/scm/git/docs/
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Conclusioni
|
||||||
|
===========
|
||||||
|
|
||||||
|
Congratulazioni a chiunque ce l'abbia fatta a terminare questo documento di
|
||||||
|
lungo-respiro. Si spera che abbia fornito un'utile comprensione d'insieme
|
||||||
|
di come il kernel Linux viene sviluppato e di come potete partecipare a
|
||||||
|
tale processo.
|
||||||
|
|
||||||
|
Infine, quello che conta è partecipare. Qualsiasi progetto software
|
||||||
|
open-source non è altro che la somma di quello che i suoi contributori
|
||||||
|
mettono al suo interno. Il kernel Linux è cresciuto velocemente e bene
|
||||||
|
perché ha ricevuto il supporto di un impressionante gruppo di sviluppatori,
|
||||||
|
ognuno dei quali sta lavorando per renderlo migliore. Il kernel è un esempio
|
||||||
|
importante di cosa può essere fatto quando migliaia di persone lavorano
|
||||||
|
insieme verso un obiettivo comune.
|
||||||
|
|
||||||
|
Il kernel può sempre beneficiare di una larga base di sviluppatori, tuttavia,
|
||||||
|
c'è sempre molto lavoro da fare. Ma, cosa non meno importante, molti degli
|
||||||
|
altri partecipanti all'ecosistema Linux possono trarre beneficio attraverso
|
||||||
|
il contributo al kernel. Inserire codice nel ramo principale è la chiave
|
||||||
|
per arrivare ad una qualità del codice più alta, bassa manutenzione e
|
||||||
|
bassi prezzi di distribuzione, alti livelli d'influenza sulla direzione
|
||||||
|
dello sviluppo del kernel, e molto altro. È una situazione nella quale
|
||||||
|
tutti coloro che sono coinvolti vincono. Mollate il vostro editor e
|
||||||
|
raggiungeteci; sarete più che benvenuti.
|
||||||
|
|
|
@ -1,12 +1,643 @@
|
||||||
.. include:: ../disclaimer-ita.rst
|
.. include:: ../disclaimer-ita.rst
|
||||||
|
|
||||||
:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
|
:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
|
||||||
|
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
|
||||||
|
|
||||||
.. _it_addsyscalls:
|
.. _it_addsyscalls:
|
||||||
|
|
||||||
Aggiungere una nuova chiamata di sistema
|
Aggiungere una nuova chiamata di sistema
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
.. warning::
|
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>`.
|
||||||
|
|
||||||
TODO ancora da tradurre
|
|
||||||
|
Alternative alle chiamate di sistema
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
La prima considerazione da fare quando si aggiunge una nuova chiamata di
|
||||||
|
sistema è quella di valutare le alternative. Nonostante le chiamate di sistema
|
||||||
|
siano il punto di interazione fra spazio utente e kernel più tradizionale ed
|
||||||
|
ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle
|
||||||
|
vostra interfaccia.
|
||||||
|
|
||||||
|
- Se le operazioni coinvolte possono rassomigliare a quelle di un filesystem,
|
||||||
|
allora potrebbe avere molto più senso la creazione di un nuovo filesystem o
|
||||||
|
dispositivo. Inoltre, questo rende più facile incapsulare la nuova
|
||||||
|
funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore
|
||||||
|
del kernel.
|
||||||
|
|
||||||
|
- Se la nuova funzionalità prevede operazioni dove il kernel notifica
|
||||||
|
lo spazio utente su un avvenimento, allora restituire un descrittore
|
||||||
|
di file all'oggetto corrispondente permette allo spazio utente di
|
||||||
|
utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche.
|
||||||
|
- Tuttavia, le operazioni che non si sposano bene con operazioni tipo
|
||||||
|
:manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate
|
||||||
|
come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in
|
||||||
|
un qualche modo opaca.
|
||||||
|
|
||||||
|
- Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in
|
||||||
|
sysfs (vedere ``Documentation/translations/it_IT/filesystems/sysfs.txt``) o
|
||||||
|
in procfs potrebbe essere sufficiente. Tuttavia, l'accesso a questi
|
||||||
|
meccanismi richiede che il filesystem sia montato, il che potrebbe non
|
||||||
|
essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot).
|
||||||
|
Evitate d'aggiungere nuove API in debugfs perché questo non viene
|
||||||
|
considerata un'interfaccia di 'produzione' verso lo spazio utente.
|
||||||
|
- Se l'operazione è specifica ad un particolare file o descrittore, allora
|
||||||
|
potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`.
|
||||||
|
Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che
|
||||||
|
nasconde una notevole complessità, quindi è ottima solo quando la nuova
|
||||||
|
funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure
|
||||||
|
la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere
|
||||||
|
un semplice flag associato ad un descrittore di file).
|
||||||
|
- Se l'operazione è specifica ad un particolare processo, allora
|
||||||
|
potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`.
|
||||||
|
Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso
|
||||||
|
multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti
|
||||||
|
nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo
|
||||||
|
al processo.
|
||||||
|
|
||||||
|
|
||||||
|
Progettare l'API: pianificare le estensioni
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
Una nuova chiamata di sistema diventerà parte dell'API del kernel, e
|
||||||
|
dev'essere supportata per un periodo indefinito. Per questo, è davvero
|
||||||
|
un'ottima idea quella di discutere apertamente l'interfaccia sulla lista
|
||||||
|
di discussione del kernel, ed è altrettanto importante pianificarne eventuali
|
||||||
|
estensioni future.
|
||||||
|
|
||||||
|
(Nella tabella delle chiamate di sistema sono disseminati esempi dove questo
|
||||||
|
non fu fatto, assieme ai corrispondenti aggiornamenti -
|
||||||
|
``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
|
||||||
|
``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia
|
||||||
|
del kernel e pianificate le estensioni fin dall'inizio)
|
||||||
|
|
||||||
|
Per semplici chiamate di sistema che accettano solo un paio di argomenti,
|
||||||
|
il modo migliore di permettere l'estensibilità è quello di includere un
|
||||||
|
argomento *flags* alla chiamata di sistema. Per assicurarsi che i programmi
|
||||||
|
dello spazio utente possano usare in sicurezza *flags* con diverse versioni
|
||||||
|
del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto,
|
||||||
|
in qual caso rifiutate la chiamata di sistema (con ``EINVAL``)::
|
||||||
|
|
||||||
|
if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
(Se *flags* non viene ancora utilizzato, verificate che l'argomento sia zero)
|
||||||
|
|
||||||
|
Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di
|
||||||
|
argomenti, il modo migliore è quello di incapsularne la maggior parte in una
|
||||||
|
struttura dati che verrà passata per puntatore. Questa struttura potrà
|
||||||
|
funzionare con future estensioni includendo un campo *size*::
|
||||||
|
|
||||||
|
struct xyzzy_params {
|
||||||
|
u32 size; /* userspace sets p->size = sizeof(struct xyzzy_params) */
|
||||||
|
u32 param_1;
|
||||||
|
u64 param_2;
|
||||||
|
u64 param_3;
|
||||||
|
};
|
||||||
|
|
||||||
|
Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per
|
||||||
|
offrire il comportamento precedente quando vale zero, allora questo permetterà
|
||||||
|
di gestire un conflitto di versione in entrambe le direzioni:
|
||||||
|
|
||||||
|
- un vecchio kernel può gestire l'accesso di una versione moderna di un
|
||||||
|
programma in spazio utente verificando che la memoria oltre la dimensione
|
||||||
|
della struttura dati attesa sia zero (in pratica verificare che
|
||||||
|
``param_4 == 0``).
|
||||||
|
- un nuovo kernel può gestire l'accesso di una versione vecchia di un
|
||||||
|
programma in spazio utente estendendo la struttura dati con zeri (in pratica
|
||||||
|
``param_4 = 0``).
|
||||||
|
|
||||||
|
Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in
|
||||||
|
``kernel/events/core.c``) per un esempio pratico di questo approccio.
|
||||||
|
|
||||||
|
|
||||||
|
Progettare l'API: altre considerazioni
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema permette allo spazio utente di fare
|
||||||
|
riferimento ad un oggetto del kernel, allora questa dovrebbe usare un
|
||||||
|
descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di
|
||||||
|
accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica
|
||||||
|
ben definita per utilizzare i descrittori di file.
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ritorna un nuovo
|
||||||
|
descrittore di file, allora l'argomento *flags* dovrebbe includere un valore
|
||||||
|
equivalente a ``O_CLOEXEC`` per i nuovi descrittori. Questo rende possibile,
|
||||||
|
nello spazio utente, la chiusura della finestra temporale fra le chiamate a
|
||||||
|
``xyzzy()`` e ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, dove un inaspettato
|
||||||
|
``fork()`` o ``execve()`` potrebbe trasferire il descrittore al programma
|
||||||
|
eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di
|
||||||
|
``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una
|
||||||
|
enumerazione di flag ``O_*`` che è abbastanza ricca).
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema ritorna un nuovo descrittore di file,
|
||||||
|
dovreste considerare che significato avrà l'uso delle chiamate di sistema
|
||||||
|
della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto
|
||||||
|
per la lettura o la scrittura è il tipico modo del kernel per notificare lo
|
||||||
|
spazio utente circa un evento associato all'oggetto del kernel.
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ha un argomento
|
||||||
|
che è il percorso ad un file::
|
||||||
|
|
||||||
|
int sys_xyzzy(const char __user *path, ..., unsigned int flags);
|
||||||
|
|
||||||
|
dovreste anche considerare se non sia più appropriata una versione
|
||||||
|
:manpage:`xyzzyat(2)`::
|
||||||
|
|
||||||
|
int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
|
||||||
|
|
||||||
|
Questo permette più flessibilità su come lo spazio utente specificherà il file
|
||||||
|
in questione; in particolare, permette allo spazio utente di richiedere la
|
||||||
|
funzionalità su un descrittore di file già aperto utilizzando il *flag*
|
||||||
|
``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione
|
||||||
|
:manpage:`fxyzzy(3)`::
|
||||||
|
|
||||||
|
- xyzzyat(AT_FDCWD, path, ..., 0) is equivalent to xyzzy(path,...)
|
||||||
|
- xyzzyat(fd, "", ..., AT_EMPTY_PATH) is equivalent to fxyzzy(fd, ...)
|
||||||
|
|
||||||
|
(Per maggiori dettagli sulla logica delle chiamate \*at(), leggete la pagina
|
||||||
|
man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina
|
||||||
|
man :manpage:`fstatat(2)`).
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede un parametro
|
||||||
|
per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come
|
||||||
|
tipo cosicché scostamenti a 64-bit potranno essere supportati anche su
|
||||||
|
architetture a 32-bit.
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede l'uso di
|
||||||
|
funzioni riservate, allora dev'essere gestita da un opportuno bit di privilegio
|
||||||
|
(verificato con una chiamata a ``capable()``), come descritto nella pagina man
|
||||||
|
:manpage:`capabilities(7)`. Scegliete un bit di privilegio già esistente per
|
||||||
|
gestire la funzionalità associata, ma evitate la combinazione di diverse
|
||||||
|
funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il
|
||||||
|
principio di *capabilities* di separare i poteri di root. In particolare,
|
||||||
|
evitate di aggiungere nuovi usi al fin-troppo-generico privilegio
|
||||||
|
``CAP_SYS_ADMIN``.
|
||||||
|
|
||||||
|
Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` manipola altri
|
||||||
|
processi oltre a quello chiamato, allora dovrebbe essere limitata (usando
|
||||||
|
la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
|
||||||
|
con gli stessi permessi del processo in oggetto, o con i necessari privilegi,
|
||||||
|
possa manipolarlo.
|
||||||
|
|
||||||
|
Infine, state attenti che in alcune architetture non-x86 la vita delle chiamate
|
||||||
|
di sistema con argomenti a 64-bit viene semplificata se questi argomenti
|
||||||
|
ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette
|
||||||
|
l'uso di coppie contigue di registri a 32-bit. (Questo non conta se gli
|
||||||
|
argomenti sono parte di una struttura dati che viene passata per puntatore).
|
||||||
|
|
||||||
|
|
||||||
|
Proporre l'API
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio
|
||||||
|
che dividiate le modifiche i pezzi separati. Questi dovrebbero includere
|
||||||
|
almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto
|
||||||
|
più avanti):
|
||||||
|
|
||||||
|
- l'essenza dell'implementazione della chiamata di sistema, con i prototipi,
|
||||||
|
i numeri generici, le modifiche al Kconfig e l'implementazione *stub* di
|
||||||
|
ripiego.
|
||||||
|
- preparare la nuova chiamata di sistema per un'architettura specifica,
|
||||||
|
solitamente x86 (ovvero tutti: x86_64, x86_32 e x32).
|
||||||
|
- un programma di auto-verifica da mettere in ``tools/testing/selftests/``
|
||||||
|
che mostri l'uso della chiamata di sistema.
|
||||||
|
- una bozza di pagina man per la nuova chiamata di sistema. Può essere
|
||||||
|
scritta nell'email di presentazione, oppure come modifica vera e propria
|
||||||
|
al repositorio delle pagine man.
|
||||||
|
|
||||||
|
Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del
|
||||||
|
kernel, deve essere sottomessa alla lista di discussione
|
||||||
|
linux-api@vger.kernel.org.
|
||||||
|
|
||||||
|
|
||||||
|
Implementazione di chiamate di sistema generiche
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
Il principale punto d'accesso alla vostra nuova chiamata di sistema
|
||||||
|
:manpage:`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo
|
||||||
|
esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'
|
||||||
|
indica il numero di argomenti della chiamata di sistema; la macro ha come
|
||||||
|
argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)
|
||||||
|
per definire i suoi parametri. L'uso di questa macro permette di avere
|
||||||
|
i metadati della nuova chiamata di sistema disponibili anche per altri
|
||||||
|
strumenti.
|
||||||
|
|
||||||
|
Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in
|
||||||
|
``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli
|
||||||
|
il modo in cui quelle chiamate di sistema verranno invocate::
|
||||||
|
|
||||||
|
asmlinkage long sys_xyzzy(...);
|
||||||
|
|
||||||
|
Alcune architetture (per esempio x86) hanno le loro specifiche tabelle di
|
||||||
|
chiamate di sistema (syscall), ma molte altre architetture condividono una
|
||||||
|
tabella comune di syscall. Aggiungete alla lista generica la vostra nuova
|
||||||
|
chiamata di sistema aggiungendo un nuovo elemento alla lista in
|
||||||
|
``include/uapi/asm-generic/unistd.h``::
|
||||||
|
|
||||||
|
#define __NR_xyzzy 292
|
||||||
|
__SYSCALL(__NR_xyzzy, sys_xyzzy)
|
||||||
|
|
||||||
|
Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con
|
||||||
|
l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova
|
||||||
|
chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero
|
||||||
|
della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i
|
||||||
|
conflitti.
|
||||||
|
|
||||||
|
Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che
|
||||||
|
ritornano ``-ENOSYS``. Aggiungete la vostra nuova chiamata di sistema anche
|
||||||
|
qui::
|
||||||
|
|
||||||
|
COND_SYSCALL(xyzzy);
|
||||||
|
|
||||||
|
La vostra nuova funzionalità del kernel, e la chiamata di sistema che la
|
||||||
|
controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione
|
||||||
|
``CONFIG`` (solitamente in ``init/Kconfig``). Come al solito per le nuove
|
||||||
|
opzioni ``CONFIG``:
|
||||||
|
|
||||||
|
- Includete una descrizione della nuova funzionalità e della chiamata di
|
||||||
|
sistema che la controlla.
|
||||||
|
- Rendete l'opzione dipendente da EXPERT se dev'essere nascosta agli utenti
|
||||||
|
normali.
|
||||||
|
- Nel Makefile, rendere tutti i nuovi file sorgenti, che implementano la
|
||||||
|
nuova funzionalità, dipendenti dall'opzione CONFIG (per esempio
|
||||||
|
``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
|
||||||
|
- Controllate due volte che sia possibile generare il kernel con la nuova
|
||||||
|
opzione CONFIG disabilitata.
|
||||||
|
|
||||||
|
Per riassumere, vi serve un *commit* che includa:
|
||||||
|
|
||||||
|
- un'opzione ``CONFIG``per la nuova funzione, normalmente in ``init/Kconfig``
|
||||||
|
- ``SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
|
||||||
|
- il corrispondente prototipo in ``include/linux/syscalls.h``
|
||||||
|
- un elemento nella tabella generica in ``include/uapi/asm-generic/unistd.h``
|
||||||
|
- *stub* di ripiego in ``kernel/sys_ni.c``
|
||||||
|
|
||||||
|
|
||||||
|
Implementazione delle chiamate di sistema x86
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
|
||||||
|
dovete aggiornate la tabella principale di syscall. Assumendo che la vostra
|
||||||
|
nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
|
||||||
|
dovete aggiungere un elemento *common* (per x86_64 e x32) in
|
||||||
|
arch/x86/entry/syscalls/syscall_64.tbl::
|
||||||
|
|
||||||
|
333 common xyzzy sys_xyzzy
|
||||||
|
|
||||||
|
e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
|
||||||
|
|
||||||
|
380 i386 xyzzy sys_xyzzy
|
||||||
|
|
||||||
|
Ancora una volta, questi numeri potrebbero essere cambiati se generano
|
||||||
|
conflitti durante la finestra di integrazione.
|
||||||
|
|
||||||
|
|
||||||
|
Chiamate di sistema compatibili (generico)
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
|
||||||
|
invocata anche quando il programma in spazio utente è a 32-bit; anche se la
|
||||||
|
chiamata di sistema include esplicitamente un puntatore, questo viene gestito
|
||||||
|
in modo trasparente.
|
||||||
|
|
||||||
|
Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
|
||||||
|
livello di gestione della compatibilità per risolvere le differenze di
|
||||||
|
dimensioni fra 32-bit e 64-bit.
|
||||||
|
|
||||||
|
Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
|
||||||
|
utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
|
||||||
|
potrebbero contenere valori a 32-bit o a 64-bit. In particolar modo, questo
|
||||||
|
è necessario quando un argomento di una chiamata di sistema è:
|
||||||
|
|
||||||
|
- un puntatore ad un puntatore
|
||||||
|
- un puntatore ad una struttura dati contenente a sua volta un puntatore
|
||||||
|
( ad esempio ``struct iovec __user *``)
|
||||||
|
- un puntatore ad un tipo intero di dimensione variabile (``time_t``,
|
||||||
|
``off_t``, ``long``, ...)
|
||||||
|
- un puntatore ad una struttura dati contenente un tipo intero di dimensione
|
||||||
|
variabile.
|
||||||
|
|
||||||
|
Il secondo caso che richiede un livello di gestione della compatibilità è
|
||||||
|
quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
|
||||||
|
a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
|
||||||
|
In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
|
||||||
|
a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
|
||||||
|
in questo livello di compatibilità.
|
||||||
|
|
||||||
|
(Da notare che non serve questo livello di compatibilità per argomenti che
|
||||||
|
sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
|
||||||
|
:manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
|
||||||
|
di una chiamata di sistema ``compat_``)
|
||||||
|
|
||||||
|
La versione compatibile della nostra chiamata di sistema si chiamerà
|
||||||
|
``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
|
||||||
|
``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn). Questa versione
|
||||||
|
dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
|
||||||
|
che trasformerà secondo le necessità (tipicamente, la versione
|
||||||
|
``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
|
||||||
|
può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
|
||||||
|
le parti comuni).
|
||||||
|
|
||||||
|
Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
|
||||||
|
in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
|
||||||
|
il modo in cui quelle chiamate di sistema verranno invocate::
|
||||||
|
|
||||||
|
asmlinkage long compat_sys_xyzzy(...);
|
||||||
|
|
||||||
|
Se la chiamata di sistema prevede una struttura dati organizzata in modo
|
||||||
|
diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo
|
||||||
|
``struct xyzzy_args``, allora il file d'intestazione
|
||||||
|
``then the include/linux/compat.h`` deve includere la sua versione
|
||||||
|
*compatibile* (``struct compat_xyzzy_args``); ogni variabile con
|
||||||
|
dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
|
||||||
|
a quello in ``struct xyzzy_args``. La funzione ``compat_sys_xyzzy()``
|
||||||
|
può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
|
||||||
|
da una chiamata a 32-bit.
|
||||||
|
|
||||||
|
Per esempio, se avete i seguenti campi::
|
||||||
|
|
||||||
|
struct xyzzy_args {
|
||||||
|
const char __user *ptr;
|
||||||
|
__kernel_long_t varying_val;
|
||||||
|
u64 fixed_val;
|
||||||
|
/* ... */
|
||||||
|
};
|
||||||
|
|
||||||
|
nella struttura ``struct xyzzy_args``, allora la struttura
|
||||||
|
``struct compat_xyzzy_args`` dovrebbe avere::
|
||||||
|
|
||||||
|
struct compat_xyzzy_args {
|
||||||
|
compat_uptr_t ptr;
|
||||||
|
compat_long_t varying_val;
|
||||||
|
u64 fixed_val;
|
||||||
|
/* ... */
|
||||||
|
};
|
||||||
|
|
||||||
|
La lista generica delle chiamate di sistema ha bisogno di essere
|
||||||
|
aggiustata al fine di permettere l'uso della versione *compatibile*;
|
||||||
|
la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare
|
||||||
|
``__SC_COMP`` piuttosto di ``__SYSCALL``::
|
||||||
|
|
||||||
|
#define __NR_xyzzy 292
|
||||||
|
__SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
|
||||||
|
|
||||||
|
Riassumendo, vi serve:
|
||||||
|
|
||||||
|
- un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
|
||||||
|
*compatibile*
|
||||||
|
- un prototipo in ``include/linux/compat.h``
|
||||||
|
- (se necessario) una struttura di compatibilità a 32-bit in
|
||||||
|
``include/linux/compat.h``
|
||||||
|
- una voce ``__SC_COMP``, e non ``__SYSCALL``, in
|
||||||
|
``include/uapi/asm-generic/unistd.h``
|
||||||
|
|
||||||
|
Compatibilità delle chiamate di sistema (x86)
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
Per collegare una chiamata di sistema, su un'architettura x86, con la sua
|
||||||
|
versione *compatibile*, è necessario aggiustare la voce nella tabella
|
||||||
|
delle syscall.
|
||||||
|
|
||||||
|
Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
|
||||||
|
un argomento aggiuntivo per indicare che un programma in spazio utente
|
||||||
|
a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
|
||||||
|
d'accesso compatibile::
|
||||||
|
|
||||||
|
380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy
|
||||||
|
|
||||||
|
Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
|
||||||
|
per la versione dell'ABI x32. Qui C'è una scelta da fare: gli argomenti
|
||||||
|
possono corrisponde alla versione a 64-bit o a quella a 32-bit.
|
||||||
|
|
||||||
|
Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
|
||||||
|
quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
|
||||||
|
``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
|
||||||
|
x32 eseguano la chiamata *compatibile*::
|
||||||
|
|
||||||
|
333 64 xyzzy sys_xyzzy
|
||||||
|
...
|
||||||
|
555 x32 xyzzy __x32_compat_sys_xyzzy
|
||||||
|
|
||||||
|
Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
|
||||||
|
sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
|
||||||
|
arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
|
||||||
|
|
||||||
|
In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
|
||||||
|
abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
|
||||||
|
32-bit (-m32) o 64-bit (-m64).
|
||||||
|
|
||||||
|
|
||||||
|
Chiamate di sistema che ritornano altrove
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
Nella maggior parte delle chiamate di sistema, al termine della loro
|
||||||
|
esecuzione, i programmi in spazio utente riprendono esattamente dal punto
|
||||||
|
in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
|
||||||
|
stesso *stack* e con la maggior parte del registri com'erano stati
|
||||||
|
lasciati prima della chiamata di sistema, e anche con la stessa memoria
|
||||||
|
virtuale.
|
||||||
|
|
||||||
|
Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
|
||||||
|
Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
|
||||||
|
la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
|
||||||
|
l'architettura del programma (``execve``/``execveat``).
|
||||||
|
|
||||||
|
Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
|
||||||
|
chiamate di sistema potrebbero dover salvare e ripristinare registri
|
||||||
|
aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
|
||||||
|
su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
|
||||||
|
chiamata di sistema.
|
||||||
|
|
||||||
|
Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
|
||||||
|
dei punti d'accesso in *assembly* per salvare/ripristinare i registri
|
||||||
|
aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
|
||||||
|
sistema.
|
||||||
|
|
||||||
|
Per l'architettura x86_64, questo è implementato come un punto d'accesso
|
||||||
|
``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella
|
||||||
|
di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
|
||||||
|
conseguenza::
|
||||||
|
|
||||||
|
333 common xyzzy stub_xyzzy
|
||||||
|
|
||||||
|
L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
|
||||||
|
normalmente chiamato ``stub32_xyzzy`` e implementato in
|
||||||
|
``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
|
||||||
|
di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
|
||||||
|
seguente modo::
|
||||||
|
|
||||||
|
380 i386 xyzzy sys_xyzzy stub32_xyzzy
|
||||||
|
|
||||||
|
Se una chiamata di sistema necessita di un livello di compatibilità (come
|
||||||
|
nella sezione precedente), allora la versione ``stub32_`` deve invocare
|
||||||
|
la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit. In aggiunta,
|
||||||
|
se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
|
||||||
|
voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
|
||||||
|
``compat_sys_``,
|
||||||
|
|
||||||
|
Per completezza, sarebbe carino impostare una mappatura cosicché
|
||||||
|
*user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
|
||||||
|
farà riferimento a stub_xyzzy, ma UML non include l'implementazione
|
||||||
|
in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
|
||||||
|
Correggerlo è semplice, basta aggiungere una #define in
|
||||||
|
``arch/x86/um/sys_call_table_64.c``::
|
||||||
|
|
||||||
|
#define stub_xyzzy sys_xyzzy
|
||||||
|
|
||||||
|
|
||||||
|
Altri dettagli
|
||||||
|
--------------
|
||||||
|
|
||||||
|
La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
|
||||||
|
ma possono esserci rare eccezioni per le quali potrebbe essere necessario
|
||||||
|
l'aggiornamento della vostra chiamata di sistema.
|
||||||
|
|
||||||
|
Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
|
||||||
|
speciali; esso include (per architettura) funzioni che classificano alcuni
|
||||||
|
tipi di chiamate di sistema -- in particolare apertura dei file
|
||||||
|
(``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
|
||||||
|
oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
|
||||||
|
di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
|
||||||
|
essere aggiornato.
|
||||||
|
|
||||||
|
Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
|
||||||
|
vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
|
||||||
|
di sistema esistente per verificare che non ci siano altri casi speciali.
|
||||||
|
|
||||||
|
|
||||||
|
Verifica
|
||||||
|
--------
|
||||||
|
|
||||||
|
Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
|
||||||
|
ai revisori un programma in spazio utente che mostri l'uso della chiamata di
|
||||||
|
sistema. Un buon modo per combinare queste cose è quello di aggiungere un
|
||||||
|
semplice programma di auto-verifica in una nuova cartella in
|
||||||
|
``tools/testing/selftests/``.
|
||||||
|
|
||||||
|
Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
|
||||||
|
in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
|
||||||
|
inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
|
||||||
|
visibile in spazio utente, il file d'intestazione necessario dev'essere
|
||||||
|
installato al fine di compilare il programma.
|
||||||
|
|
||||||
|
Assicuratevi che il programma di auto-verifica possa essere eseguito
|
||||||
|
correttamente su tutte le architetture supportate. Per esempio, verificate che
|
||||||
|
funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
|
||||||
|
|
||||||
|
Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
|
||||||
|
dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
|
||||||
|
oppure al progetto xfstests per cambiamenti relativi al filesystem.
|
||||||
|
|
||||||
|
- https://linux-test-project.github.io/
|
||||||
|
- git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
|
||||||
|
|
||||||
|
|
||||||
|
Pagine man
|
||||||
|
----------
|
||||||
|
|
||||||
|
Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
|
||||||
|
idealmente usando i marcatori groff, ma anche il puro testo può andare. Se
|
||||||
|
state usando groff, è utile che includiate nella email di presentazione una
|
||||||
|
versione già convertita in formato ASCII: semplificherà la vita dei revisori.
|
||||||
|
|
||||||
|
Le pagine man dovrebbero essere in copia-conoscenza verso
|
||||||
|
linux-man@vger.kernel.org
|
||||||
|
Per maggiori dettagli, leggere
|
||||||
|
https://www.kernel.org/doc/man-pages/patches.html
|
||||||
|
|
||||||
|
|
||||||
|
Non invocate chiamate di sistema dal kernel
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
Le chiamate di sistema sono, come già detto prima, punti di interazione fra
|
||||||
|
lo spazio utente e il kernel. Perciò, le chiamate di sistema come
|
||||||
|
``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
|
||||||
|
spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
|
||||||
|
kernel. Se la nuova funzionalità è utile all'interno del kernel, per esempio
|
||||||
|
dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
|
||||||
|
dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
|
||||||
|
allora dev'essere implementata come una funzione di supporto
|
||||||
|
(*helper function*) (per esempio ``kern_xyzzy()``). Questa funzione potrà
|
||||||
|
essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
|
||||||
|
(``compat_sys_xyzzy()``), e/o da altri parti del kernel.
|
||||||
|
|
||||||
|
Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
|
||||||
|
fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
|
||||||
|
Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove
|
||||||
|
``struct pt_regs`` viene decodificata al volo in una funzione che racchiude
|
||||||
|
la chiamata di sistema la quale verrà eseguita successivamente.
|
||||||
|
Questo significa che verranno passati solo i parametri che sono davvero
|
||||||
|
necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
|
||||||
|
6 registri del processore con contenuti presi dallo spazio utente (potrebbe
|
||||||
|
causare seri problemi nella sequenza di chiamate).
|
||||||
|
|
||||||
|
Inoltre, le regole su come i dati possano essere usati potrebbero differire
|
||||||
|
fra il kernel e l'utente. Questo è un altro motivo per cui invocare
|
||||||
|
``sys_xyzzy()`` è generalmente una brutta idea.
|
||||||
|
|
||||||
|
Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
|
||||||
|
che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
|
||||||
|
o per altro codice in arch/
|
||||||
|
|
||||||
|
|
||||||
|
Riferimenti e fonti
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle
|
||||||
|
chiamate di sistema: https://lwn.net/Articles/585415/
|
||||||
|
- Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in
|
||||||
|
una chiamata di sistema: https://lwn.net/Articles/588444/
|
||||||
|
- Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit
|
||||||
|
delle chiamate di sistema: https://lwn.net/Articles/311630/
|
||||||
|
- Una coppia di articoli di David Drysdale che descrivono i dettagli del
|
||||||
|
percorso implementativo di una chiamata di sistema per la versione v3.14:
|
||||||
|
|
||||||
|
- https://lwn.net/Articles/604287/
|
||||||
|
- https://lwn.net/Articles/604515/
|
||||||
|
|
||||||
|
- Requisiti specifici alle architetture sono discussi nella pagina man
|
||||||
|
:manpage:`syscall(2)` :
|
||||||
|
http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
|
||||||
|
- Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:
|
||||||
|
http://yarchive.net/comp/linux/ioctl.html
|
||||||
|
- "Come non inventare interfacce del kernel", Arnd Bergmann,
|
||||||
|
http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
|
||||||
|
- Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN:
|
||||||
|
https://lwn.net/Articles/486306/
|
||||||
|
- Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni
|
||||||
|
su una nuova chiamata di sistema dovrebbero essere contenute nello stesso
|
||||||
|
filone di discussione di email: https://lkml.org/lkml/2014/7/24/641
|
||||||
|
- Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
|
||||||
|
sistema dovrebbero avere una pagina man: https://lkml.org/lkml/2014/6/13/309
|
||||||
|
- Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
|
||||||
|
x86 dovrebbe avvenire in un *commit* differente:
|
||||||
|
https://lkml.org/lkml/2014/11/19/254
|
||||||
|
- Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un
|
||||||
|
programma di auto-verifica per le nuove chiamate di sistema:
|
||||||
|
https://lkml.org/lkml/2014/3/19/710
|
||||||
|
- Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
|
||||||
|
le estensioni :manpage:`prctl(2)`: https://lkml.org/lkml/2014/6/3/411
|
||||||
|
- Consigli da Ingo Molnar che le chiamate di sistema con più argomenti
|
||||||
|
dovrebbero incapsularli in una struttura che includa un argomento
|
||||||
|
*size* per garantire l'estensibilità futura:
|
||||||
|
https://lkml.org/lkml/2015/7/30/117
|
||||||
|
- Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*:
|
||||||
|
|
||||||
|
- commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
|
||||||
|
check")
|
||||||
|
- commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
|
||||||
|
conflict")
|
||||||
|
- commit bb458c644a59 ("Safer ABI for O_TMPFILE")
|
||||||
|
|
||||||
|
- Discussion from Matthew Wilcox about restrictions on 64-bit arguments:
|
||||||
|
https://lkml.org/lkml/2008/12/12/187
|
||||||
|
- Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
|
||||||
|
essere controllati: https://lkml.org/lkml/2014/7/17/577
|
||||||
|
- Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero
|
||||||
|
favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit:
|
||||||
|
https://lkml.org/lkml/2011/8/31/244
|
||||||
|
|
Loading…
Reference in New Issue