diff options
Diffstat (limited to 'Documentation/translations/it_IT')
55 files changed, 14768 insertions, 0 deletions
diff --git a/Documentation/translations/it_IT/admin-guide/README.rst b/Documentation/translations/it_IT/admin-guide/README.rst new file mode 100644 index 0000000000..c874586a9a --- /dev/null +++ b/Documentation/translations/it_IT/admin-guide/README.rst @@ -0,0 +1,12 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/admin-guide/README.rst <readme>` + +.. _it_readme: + +Rilascio del kernel Linux 6.x <http://kernel.org/> +=================================================== + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/admin-guide/kernel-parameters.rst b/Documentation/translations/it_IT/admin-guide/kernel-parameters.rst new file mode 100644 index 0000000000..0e36d82a92 --- /dev/null +++ b/Documentation/translations/it_IT/admin-guide/kernel-parameters.rst @@ -0,0 +1,12 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>` + +.. _it_kernelparameters: + +I parametri da linea di comando del kernel +========================================== + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/admin-guide/security-bugs.rst b/Documentation/translations/it_IT/admin-guide/security-bugs.rst new file mode 100644 index 0000000000..20994f4bfa --- /dev/null +++ b/Documentation/translations/it_IT/admin-guide/security-bugs.rst @@ -0,0 +1,12 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/security-bugs.rst <securitybugs>` + +.. _it_securitybugs: + +Bachi di sicurezza +================== + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/core-api/index.rst b/Documentation/translations/it_IT/core-api/index.rst new file mode 100644 index 0000000000..cc4c4328ad --- /dev/null +++ b/Documentation/translations/it_IT/core-api/index.rst @@ -0,0 +1,18 @@ +=============================== +Documentazione dell'API di base +=============================== + +Utilità di base +=============== + +.. toctree:: + :maxdepth: 1 + + symbol-namespaces + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/translations/it_IT/core-api/memory-allocation.rst b/Documentation/translations/it_IT/core-api/memory-allocation.rst new file mode 100644 index 0000000000..11d5148f8d --- /dev/null +++ b/Documentation/translations/it_IT/core-api/memory-allocation.rst @@ -0,0 +1,13 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/core-api/memory-allocation.rst <memory_allocation>` + +.. _it_memory_allocation: + +================================ +Guida all'allocazione di memoria +================================ + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/core-api/symbol-namespaces.rst b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst new file mode 100644 index 0000000000..17abc25ee4 --- /dev/null +++ b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst @@ -0,0 +1,165 @@ +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/core-api/symbol-namespaces.rst + +=========================== +Spazio dei nomi dei simboli +=========================== + +Questo documento descrive come usare lo spazio dei nomi dei simboli +per strutturare quello che viene esportato internamente al kernel +grazie alle macro della famiglia EXPORT_SYMBOL(). + +1. Introduzione +=============== + +Lo spazio dei nomi dei simboli è stato introdotto come mezzo per strutturare +l'API esposta internamente al kernel. Permette ai manutentori di un +sottosistema di organizzare i simboli esportati in diversi spazi di +nomi. Questo meccanismo è utile per la documentazione (pensate ad +esempio allo spazio dei nomi SUBSYSTEM_DEBUG) così come per limitare +la disponibilità di un gruppo di simboli in altre parti del kernel. Ad +oggi, i moduli che usano simboli esportati da uno spazio di nomi +devono prima importare detto spazio. Altrimenti il kernel, a seconda +della configurazione, potrebbe rifiutare di caricare il modulo o +avvisare l'utente di un'importazione mancante. + +2. Come definire uno spazio dei nomi dei simboli +================================================ + +I simboli possono essere esportati in spazi dei nomi usando diversi +meccanismi. Tutti questi meccanismi cambiano il modo in cui +EXPORT_SYMBOL e simili vengono guidati verso la creazione di voci in ksymtab. + +2.1 Usare le macro EXPORT_SYMBOL +================================ + +In aggiunta alle macro EXPORT_SYMBOL() e EXPORT_SYMBOL_GPL(), che permettono +di esportare simboli del kernel nella rispettiva tabella, ci sono +varianti che permettono di esportare simboli all'interno di uno spazio dei +nomi: EXPORT_SYMBOL_NS() ed EXPORT_SYMBOL_NS_GPL(). Queste macro richiedono un +argomento aggiuntivo: lo spazio dei nomi. +Tenete presente che per via dell'espansione delle macro questo argomento deve +essere un simbolo di preprocessore. Per esempio per esportare il +simbolo ``usb_stor_suspend`` nello spazio dei nomi ``USB_STORAGE`` usate:: + + EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); + +Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce +rappresentata dalla struttura ``kernel_symbol`` che avrà il campo +``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio +dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi +di base. Il programma ``modpost`` e il codice in kernel/module/main.c usano lo +spazio dei nomi, rispettivamente, durante la compilazione e durante il +caricamento di un modulo. + +2.2 Usare il simbolo di preprocessore DEFAULT_SYMBOL_NAMESPACE +============================================================== + +Definire lo spazio dei nomi per tutti i simboli di un sottosistema può essere +logorante e di difficile manutenzione. Perciò è stato fornito un simbolo +di preprocessore di base (DEFAULT_SYMBOL_NAMESPACE), che, se impostato, +diventa lo spazio dei simboli di base per tutti gli usi di EXPORT_SYMBOL() +ed EXPORT_SYMBOL_GPL() che non specificano esplicitamente uno spazio dei nomi. + +Ci sono molti modi per specificare questo simbolo di preprocessore e il loro +uso dipende dalle preferenze del manutentore di un sottosistema. La prima +possibilità è quella di definire il simbolo nel ``Makefile`` del sottosistema. +Per esempio per esportare tutti i simboli definiti in usb-common nello spazio +dei nomi USB_COMMON, si può aggiungere la seguente linea in +drivers/usb/common/Makefile:: + + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON + +Questo cambierà tutte le macro EXPORT_SYMBOL() ed EXPORT_SYMBOL_GPL(). Invece, +un simbolo esportato con EXPORT_SYMBOL_NS() non verrà cambiato e il simbolo +verrà esportato nello spazio dei nomi indicato. + +Una seconda possibilità è quella di definire il simbolo di preprocessore +direttamente nei file da compilare. L'esempio precedente diventerebbe:: + + #undef DEFAULT_SYMBOL_NAMESPACE + #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON + +Questo va messo prima di un qualsiasi uso di EXPORT_SYMBOL. + +3. Come usare i simboli esportati attraverso uno spazio dei nomi +================================================================ + +Per usare i simboli esportati da uno spazio dei nomi, i moduli del +kernel devono esplicitamente importare il relativo spazio dei nomi; altrimenti +il kernel potrebbe rifiutarsi di caricare il modulo. Il codice del +modulo deve usare la macro MODULE_IMPORT_NS per importare lo spazio +dei nomi che contiene i simboli desiderati. Per esempio un modulo che +usa il simbolo usb_stor_suspend deve importare lo spazio dei nomi +USB_STORAGE usando la seguente dichiarazione:: + + MODULE_IMPORT_NS(USB_STORAGE); + +Questo creerà un'etichetta ``modinfo`` per ogni spazio dei nomi +importato. Un risvolto di questo fatto è che gli spazi dei +nomi importati da un modulo possono essere ispezionati tramite +modinfo:: + + $ modinfo drivers/usb/storage/ums-karma.ko + [...] + import_ns: USB_STORAGE + [...] + + +Si consiglia di posizionare la dichiarazione MODULE_IMPORT_NS() vicino +ai metadati del modulo come MODULE_AUTHOR() o MODULE_LICENSE(). Fate +riferimento alla sezione 5. per creare automaticamente le importazioni +mancanti. + +4. Caricare moduli che usano simboli provenienti da spazi dei nomi +================================================================== + +Quando un modulo viene caricato (per esempio usando ``insmod``), il kernel +verificherà la disponibilità di ogni simbolo usato e se lo spazio dei nomi +che potrebbe contenerli è stato importato. Il comportamento di base del kernel +è di rifiutarsi di caricare quei moduli che non importano tutti gli spazi dei +nomi necessari. L'errore verrà annotato e il caricamento fallirà con l'errore +EINVAL. Per caricare i moduli che non soddisfano questo requisito esiste +un'opzione di configurazione: impostare +MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y caricherà i moduli comunque ma +emetterà un avviso. + +5. Creare automaticamente la dichiarazione MODULE_IMPORT_NS +=========================================================== + +La mancanza di un'importazione può essere individuata facilmente al momento +della compilazione. Infatti, modpost emetterà un avviso se il modulo usa +un simbolo da uno spazio dei nomi che non è stato importato. +La dichiarazione MODULE_IMPORT_NS() viene solitamente aggiunta in un posto +ben definito (assieme agli altri metadati del modulo). Per facilitare +la vita di chi scrive moduli (e i manutentori di sottosistemi), esistono uno +script e un target make per correggere le importazioni mancanti. Questo può +essere fatto con:: + + $ make nsdeps + +Lo scenario tipico di chi scrive un modulo potrebbe essere:: + + - scrivere codice che dipende da un simbolo appartenente ad uno spazio + dei nomi non importato + - eseguire ``make`` + - aver notato un avviso da modpost che parla di un'importazione + mancante + - eseguire ``make nsdeps`` per aggiungere import nel posto giusto + +Per i manutentori di sottosistemi che vogliono aggiungere uno spazio dei nomi, +l'approccio è simile. Di nuovo, eseguendo ``make nsdeps`` aggiungerà le +importazioni mancanti nei moduli inclusi nel kernel:: + + - spostare o aggiungere simboli ad uno spazio dei nomi (per esempio + usando EXPORT_SYMBOL_NS()) + - eseguire ``make`` (preferibilmente con allmodconfig per coprire tutti + i moduli del kernel) + - aver notato un avviso da modpost che parla di un'importazione + mancante + - eseguire ``make nsdeps`` per aggiungere import nel posto giusto + +Potete anche eseguire nsdeps per moduli esterni. Solitamente si usa così:: + + $ make -C <path_to_kernel_src> M=$PWD nsdeps diff --git a/Documentation/translations/it_IT/devicetree/bindings/submitting-patches.rst b/Documentation/translations/it_IT/devicetree/bindings/submitting-patches.rst new file mode 100644 index 0000000000..b473cd2190 --- /dev/null +++ b/Documentation/translations/it_IT/devicetree/bindings/submitting-patches.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../../disclaimer-ita.rst + +:Original: Documentation/devicetree/bindings/submitting-patches.rst + +================================================ +Sottomettere patch per devicetree (DT) *binding* +================================================ + +.. note:: to be translated diff --git a/Documentation/translations/it_IT/disclaimer-ita.rst b/Documentation/translations/it_IT/disclaimer-ita.rst new file mode 100644 index 0000000000..bfe8a384ba --- /dev/null +++ b/Documentation/translations/it_IT/disclaimer-ita.rst @@ -0,0 +1,6 @@ +:orphan: + +.. warning:: + In caso di dubbi sulla correttezza del contenuto di questa traduzione, + l'unico riferimento valido è la documentazione ufficiale in inglese. + Per maggiori informazioni consultate le :ref:`avvertenze <it_disclaimer>`. diff --git a/Documentation/translations/it_IT/doc-guide/index.rst b/Documentation/translations/it_IT/doc-guide/index.rst new file mode 100644 index 0000000000..9fffff6267 --- /dev/null +++ b/Documentation/translations/it_IT/doc-guide/index.rst @@ -0,0 +1,24 @@ +.. include:: ../disclaimer-ita.rst + +.. note:: Per leggere la documentazione originale in inglese: + :ref:`Documentation/doc-guide/index.rst <doc_guide>` + +.. _it_doc_guide: + +========================================== +Come scrivere la documentazione del kernel +========================================== + +.. toctree:: + :maxdepth: 1 + + sphinx + kernel-doc + parse-headers + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/translations/it_IT/doc-guide/kernel-doc.rst b/Documentation/translations/it_IT/doc-guide/kernel-doc.rst new file mode 100644 index 0000000000..5cece223b4 --- /dev/null +++ b/Documentation/translations/it_IT/doc-guide/kernel-doc.rst @@ -0,0 +1,563 @@ +.. include:: ../disclaimer-ita.rst + +.. note:: Per leggere la documentazione originale in inglese: + :ref:`Documentation/doc-guide/index.rst <doc_guide>` + +.. title:: Commenti in kernel-doc + +.. _it_kernel_doc: + +================================= +Scrivere i commenti in kernel-doc +================================= + +Nei file sorgenti del kernel Linux potrete trovare commenti di documentazione +strutturanti secondo il formato kernel-doc. Essi possono descrivere funzioni, +tipi di dati, e l'architettura del codice. + +.. note:: Il formato kernel-doc può sembrare simile a gtk-doc o Doxygen ma + in realtà è molto differente per ragioni storiche. I sorgenti del kernel + contengono decine di migliaia di commenti kernel-doc. Siete pregati + d'attenervi allo stile qui descritto. + +La struttura kernel-doc è estratta a partire dai commenti; da questi viene +generato il `dominio Sphinx per il C`_ con un'adeguata descrizione per le +funzioni ed i tipi di dato con i loro relativi collegamenti. Le descrizioni +vengono filtrare per cercare i riferimenti ed i marcatori. + +Vedere di seguito per maggiori dettagli. + +.. _`dominio Sphinx per il C`: http://www.sphinx-doc.org/en/stable/domains.html + +Tutte le funzioni esportate verso i moduli esterni utilizzando +``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL`` dovrebbero avere un commento +kernel-doc. Quando l'intenzione è di utilizzarle nei moduli, anche le funzioni +e le strutture dati nei file d'intestazione dovrebbero avere dei commenti +kernel-doc. + +È considerata una buona pratica quella di fornire una documentazione formattata +secondo kernel-doc per le funzioni che sono visibili da altri file del kernel +(ovvero, che non siano dichiarate utilizzando ``static``). Raccomandiamo, +inoltre, di fornire una documentazione kernel-doc anche per procedure private +(ovvero, dichiarate "static") al fine di fornire una struttura più coerente +dei sorgenti. Quest'ultima raccomandazione ha una priorità più bassa ed è a +discrezione dal manutentore (MAINTAINER) del file sorgente. + + + +Sicuramente la documentazione formattata con kernel-doc è necessaria per +le funzioni che sono esportate verso i moduli esterni utilizzando +``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL``. + +Cerchiamo anche di fornire una documentazione formattata secondo kernel-doc +per le funzioni che sono visibili da altri file del kernel (ovvero, che non +siano dichiarate utilizzando "static") + +Raccomandiamo, inoltre, di fornire una documentazione formattata con kernel-doc +anche per procedure private (ovvero, dichiarate "static") al fine di fornire +una struttura più coerente dei sorgenti. Questa raccomandazione ha una priorità +più bassa ed è a discrezione dal manutentore (MAINTAINER) del file sorgente. + +Le strutture dati visibili nei file di intestazione dovrebbero essere anch'esse +documentate utilizzando commenti formattati con kernel-doc. + +Come formattare i commenti kernel-doc +------------------------------------- + +I commenti kernel-doc iniziano con il marcatore ``/**``. Il programma +``kernel-doc`` estrarrà i commenti marchiati in questo modo. Il resto +del commento è formattato come un normale commento multilinea, ovvero +con un asterisco all'inizio d'ogni riga e che si conclude con ``*/`` +su una riga separata. + +I commenti kernel-doc di funzioni e tipi dovrebbero essere posizionati +appena sopra la funzione od il tipo che descrivono. Questo allo scopo di +aumentare la probabilità che chi cambia il codice si ricordi di aggiornare +anche la documentazione. I commenti kernel-doc di tipo più generale possono +essere posizionati ovunque nel file. + +Al fine di verificare che i commenti siano formattati correttamente, potete +eseguire il programma ``kernel-doc`` con un livello di verbosità alto e senza +che questo produca alcuna documentazione. Per esempio:: + + scripts/kernel-doc -v -none drivers/foo/bar.c + +Il formato della documentazione è verificato della procedura di generazione +del kernel quando viene richiesto di effettuare dei controlli extra con GCC:: + + make W=n + +Documentare le funzioni +------------------------ + +Generalmente il formato di un commento kernel-doc per funzioni e +macro simil-funzioni è il seguente:: + + /** + * function_name() - Brief description of function. + * @arg1: Describe the first argument. + * @arg2: Describe the second argument. + * One can provide multiple line descriptions + * for arguments. + * + * A longer description, with more discussion of the function function_name() + * that might be useful to those using or modifying it. Begins with an + * empty comment line, and may include additional embedded empty + * comment lines. + * + * The longer description may have multiple paragraphs. + * + * Context: Describes whether the function can sleep, what locks it takes, + * releases, or expects to be held. It can extend over multiple + * lines. + * Return: Describe the return value of function_name. + * + * The return value description can also have multiple paragraphs, and should + * be placed at the end of the comment block. + */ + +La descrizione introduttiva (*brief description*) che segue il nome della +funzione può continuare su righe successive e termina con la descrizione di +un argomento, una linea di commento vuota, oppure la fine del commento. + +Parametri delle funzioni +~~~~~~~~~~~~~~~~~~~~~~~~ + +Ogni argomento di una funzione dovrebbe essere descritto in ordine, subito +dopo la descrizione introduttiva. Non lasciare righe vuote né fra la +descrizione introduttiva e quella degli argomenti, né fra gli argomenti. + +Ogni ``@argument:`` può estendersi su più righe. + +.. note:: + + Se la descrizione di ``@argument:`` si estende su più righe, + la continuazione dovrebbe iniziare alla stessa colonna della riga + precedente:: + + * @argument: some long description + * that continues on next lines + + or:: + + * @argument: + * some long description + * that continues on next lines + +Se una funzione ha un numero variabile di argomento, la sua descrizione +dovrebbe essere scritta con la notazione kernel-doc:: + + * @...: description + +Contesto delle funzioni +~~~~~~~~~~~~~~~~~~~~~~~ + +Il contesto in cui le funzioni vengono chiamate viene descritto in una +sezione chiamata ``Context``. Questo dovrebbe informare sulla possibilità +che una funzione dorma (*sleep*) o che possa essere chiamata in un contesto +d'interruzione, così come i *lock* che prende, rilascia e che si aspetta che +vengano presi dal chiamante. + +Esempi:: + + * Context: Any context. + * Context: Any context. Takes and releases the RCU lock. + * Context: Any context. Expects <lock> to be held by caller. + * Context: Process context. May sleep if @gfp flags permit. + * Context: Process context. Takes and releases <mutex>. + * Context: Softirq or process context. Takes and releases <lock>, BH-safe. + * Context: Interrupt context. + +Valore di ritorno +~~~~~~~~~~~~~~~~~ + +Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome +``Return``. + +.. note:: + + #) La descrizione multiriga non riconosce il termine d'una riga, per cui + se provate a formattare bene il vostro testo come nel seguente esempio:: + + * Return: + * 0 - OK + * -EINVAL - invalid argument + * -ENOMEM - out of memory + + le righe verranno unite e il risultato sarà:: + + Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory + + Quindi, se volete che le righe vengano effettivamente generate, dovete + utilizzare una lista ReST, ad esempio:: + + * Return: + * * 0 - OK to runtime suspend the device + * * -EBUSY - Device should not be runtime suspended + + #) Se il vostro testo ha delle righe che iniziano con una frase seguita dai + due punti, allora ognuna di queste frasi verrà considerata come il nome + di una nuova sezione, e probabilmente non produrrà gli effetti desiderati. + +Documentare strutture, unioni ed enumerazioni +--------------------------------------------- + +Generalmente il formato di un commento kernel-doc per struct, union ed enum è:: + + /** + * struct struct_name - Brief description. + * @member1: Description of member1. + * @member2: Description of member2. + * One can provide multiple line descriptions + * for members. + * + * Description of the structure. + */ + +Nell'esempio qui sopra, potete sostituire ``struct`` con ``union`` o ``enum`` +per descrivere unioni ed enumerati. ``member`` viene usato per indicare i +membri di strutture ed unioni, ma anche i valori di un tipo enumerato. + +La descrizione introduttiva (*brief description*) che segue il nome della +funzione può continuare su righe successive e termina con la descrizione di +un argomento, una linea di commento vuota, oppure la fine del commento. + +Membri +~~~~~~ + +I membri di strutture, unioni ed enumerati devo essere documentati come i +parametri delle funzioni; seguono la descrizione introduttiva e possono +estendersi su più righe. + +All'interno d'una struttura o d'un unione, potete utilizzare le etichette +``private:`` e ``public:``. I campi che sono nell'area ``private:`` non +verranno inclusi nella documentazione finale. + +Le etichette ``private:`` e ``public:`` devono essere messe subito dopo +il marcatore di un commento ``/*``. Opzionalmente, possono includere commenti +fra ``:`` e il marcatore di fine commento ``*/``. + +Esempio:: + + /** + * struct my_struct - short description + * @a: first member + * @b: second member + * @d: fourth member + * + * Longer description + */ + struct my_struct { + int a; + int b; + /* private: internal use only */ + int c; + /* public: the next one is public */ + int d; + }; + +Strutture ed unioni annidate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +È possibile documentare strutture ed unioni annidate, ad esempio:: + + /** + * struct nested_foobar - a struct with nested unions and structs + * @memb1: first member of anonymous union/anonymous struct + * @memb2: second member of anonymous union/anonymous struct + * @memb3: third member of anonymous union/anonymous struct + * @memb4: fourth member of anonymous union/anonymous struct + * @bar: non-anonymous union + * @bar.st1: struct st1 inside @bar + * @bar.st2: struct st2 inside @bar + * @bar.st1.memb1: first member of struct st1 on union bar + * @bar.st1.memb2: second member of struct st1 on union bar + * @bar.st2.memb1: first member of struct st2 on union bar + * @bar.st2.memb2: second member of struct st2 on union bar + */ + struct nested_foobar { + /* Anonymous union/struct*/ + union { + struct { + int memb1; + int memb2; + } + struct { + void *memb3; + int memb4; + } + } + union { + struct { + int memb1; + int memb2; + } st1; + struct { + void *memb1; + int memb2; + } st2; + } bar; + }; + +.. note:: + + #) Quando documentate una struttura od unione annidata, ad esempio + di nome ``foo``, il suo campo ``bar`` dev'essere documentato + usando ``@foo.bar:`` + #) Quando la struttura od unione annidata è anonima, il suo campo + ``bar`` dev'essere documentato usando ``@bar:`` + +Commenti in linea per la documentazione dei membri +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I membri d'una struttura possono essere documentati in linea all'interno +della definizione stessa. Ci sono due stili: una singola riga di commento +che inizia con ``/**`` e finisce con ``*/``; commenti multi riga come +qualsiasi altro commento kernel-doc:: + + /** + * struct foo - Brief description. + * @foo: The Foo member. + */ + struct foo { + int foo; + /** + * @bar: The Bar member. + */ + int bar; + /** + * @baz: The Baz member. + * + * Here, the member description may contain several paragraphs. + */ + int baz; + union { + /** @foobar: Single line description. */ + int foobar; + }; + /** @bar2: Description for struct @bar2 inside @foo */ + struct { + /** + * @bar2.barbar: Description for @barbar inside @foo.bar2 + */ + int barbar; + } bar2; + }; + + +Documentazione dei tipi di dato +------------------------------- +Generalmente il formato di un commento kernel-doc per typedef è +il seguente:: + + /** + * typedef type_name - Brief description. + * + * Description of the type. + */ + +Anche i tipi di dato per prototipi di funzione possono essere documentati:: + + /** + * typedef type_name - Brief description. + * @arg1: description of arg1 + * @arg2: description of arg2 + * + * Description of the type. + * + * Context: Locking context. + * Return: Meaning of the return value. + */ + typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2); + +Marcatori e riferimenti +----------------------- + +All'interno dei commenti di tipo kernel-doc vengono riconosciuti i seguenti +*pattern* che vengono convertiti in marcatori reStructuredText ed in riferimenti +del `dominio Sphinx per il C`_. + +.. attention:: Questi sono riconosciuti **solo** all'interno di commenti + kernel-doc, e **non** all'interno di documenti reStructuredText. + +``funcname()`` + Riferimento ad una funzione. + +``@parameter`` + Nome di un parametro di una funzione (nessun riferimento, solo formattazione). + +``%CONST`` + Il nome di una costante (nessun riferimento, solo formattazione) + +````literal```` + Un blocco di testo che deve essere riportato così com'è. La rappresentazione + finale utilizzerà caratteri a ``spaziatura fissa``. + + Questo è utile se dovete utilizzare caratteri speciali che altrimenti + potrebbero assumere un significato diverso in kernel-doc o in reStructuredText + + Questo è particolarmente utile se dovete scrivere qualcosa come ``%ph`` + all'interno della descrizione di una funzione. + +``$ENVVAR`` + Il nome di una variabile d'ambiente (nessun riferimento, solo formattazione). + +``&struct name`` + Riferimento ad una struttura. + +``&enum name`` + Riferimento ad un'enumerazione. + +``&typedef name`` + Riferimento ad un tipo di dato. + +``&struct_name->member`` or ``&struct_name.member`` + Riferimento ad un membro di una struttura o di un'unione. Il riferimento sarà + la struttura o l'unione, non il memembro. + +``&name`` + Un generico riferimento ad un tipo. Usate, preferibilmente, il riferimento + completo come descritto sopra. Questo è dedicato ai commenti obsoleti. + +Riferimenti usando reStructuredText +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Nei documenti reStructuredText non serve alcuna sintassi speciale per +fare riferimento a funzioni e tipi definiti nei commenti +kernel-doc. Sarà sufficiente terminare i nomi di funzione con ``()``, +e scrivere ``struct``, ``union``, ``enum``, o ``typedef`` prima di un +tipo. Per esempio:: + + See foo() + See struct foo. + See union bar. + See enum baz. + See typedef meh. + +Tuttavia, la personalizzazione dei collegamenti è possibile solo con +la seguente sintassi:: + + See :c:func:`my custom link text for function foo <foo>`. + See :c:type:`my custom link text for struct bar <bar>`. + + +Commenti per una documentazione generale +---------------------------------------- + +Al fine d'avere il codice ed i commenti nello stesso file, potete includere +dei blocchi di documentazione kernel-doc con un formato libero invece +che nel formato specifico per funzioni, strutture, unioni, enumerati o tipi +di dato. Per esempio, questo tipo di commento potrebbe essere usato per la +spiegazione delle operazioni di un driver o di una libreria + +Questo s'ottiene utilizzando la parola chiave ``DOC:`` a cui viene associato +un titolo. + +Generalmente il formato di un commento generico o di visione d'insieme è +il seguente:: + + /** + * DOC: Theory of Operation + * + * The whizbang foobar is a dilly of a gizmo. It can do whatever you + * want it to do, at any time. It reads your mind. Here's how it works. + * + * foo bar splat + * + * The only drawback to this gizmo is that is can sometimes damage + * hardware, software, or its subject(s). + */ + +Il titolo che segue ``DOC:`` funziona da intestazione all'interno del file +sorgente, ma anche come identificatore per l'estrazione di questi commenti di +documentazione. Quindi, il titolo dev'essere unico all'interno del file. + +======================================= +Includere i commenti di tipo kernel-doc +======================================= + +I commenti di documentazione possono essere inclusi in un qualsiasi documento +di tipo reStructuredText mediante l'apposita direttiva nell'estensione +kernel-doc per Sphinx. + +Le direttive kernel-doc sono nel formato:: + + .. kernel-doc:: source + :option: + +Il campo *source* è il percorso ad un file sorgente, relativo alla cartella +principale dei sorgenti del kernel. La direttiva supporta le seguenti opzioni: + +export: *[source-pattern ...]* + Include la documentazione per tutte le funzioni presenti nel file sorgente + (*source*) che sono state esportate utilizzando ``EXPORT_SYMBOL`` o + ``EXPORT_SYMBOL_GPL`` in *source* o in qualsiasi altro *source-pattern* + specificato. + + Il campo *source-patter* è utile quando i commenti kernel-doc sono stati + scritti nei file d'intestazione, mentre ``EXPORT_SYMBOL`` e + ``EXPORT_SYMBOL_GPL`` si trovano vicino alla definizione delle funzioni. + + Esempi:: + + .. kernel-doc:: lib/bitmap.c + :export: + + .. kernel-doc:: include/net/mac80211.h + :export: net/mac80211/*.c + +internal: *[source-pattern ...]* + Include la documentazione per tutte le funzioni ed i tipi presenti nel file + sorgente (*source*) che **non** sono stati esportati utilizzando + ``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL`` né in *source* né in qualsiasi + altro *source-pattern* specificato. + + Esempio:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :internal: + +identifiers: *[ function/type ...]* + Include la documentazione per ogni *function* e *type* in *source*. + Se non vengono esplicitamente specificate le funzioni da includere, allora + verranno incluse tutte quelle disponibili in *source*. + + Esempi:: + + .. kernel-doc:: lib/bitmap.c + :identifiers: bitmap_parselist bitmap_parselist_user + + .. kernel-doc:: lib/idr.c + :identifiers: + +functions: *[ function ...]* + Questo è uno pseudonimo, deprecato, per la direttiva 'identifiers'. + +doc: *title* + Include la documentazione del paragrafo ``DOC:`` identificato dal titolo + (*title*) all'interno del file sorgente (*source*). Gli spazi in *title* sono + permessi; non virgolettate *title*. Il campo *title* è utilizzato per + identificare un paragrafo e per questo non viene incluso nella documentazione + finale. Verificate d'avere l'intestazione appropriata nei documenti + reStructuredText. + + Esempio:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :doc: High Definition Audio over HDMI and Display Port + +Senza alcuna opzione, la direttiva kernel-doc include tutti i commenti di +documentazione presenti nel file sorgente (*source*). + +L'estensione kernel-doc fa parte dei sorgenti del kernel, la si può trovare +in ``Documentation/sphinx/kerneldoc.py``. Internamente, viene utilizzato +lo script ``scripts/kernel-doc`` per estrarre i commenti di documentazione +dai file sorgenti. + +Come utilizzare kernel-doc per generare pagine man +-------------------------------------------------- + +Se volete utilizzare kernel-doc solo per generare delle pagine man, potete +farlo direttamente dai sorgenti del kernel:: + + $ scripts/kernel-doc -man $(git grep -l '/\*\*' -- :^Documentation :^tools) | scripts/split-man.pl /tmp/man diff --git a/Documentation/translations/it_IT/doc-guide/parse-headers.rst b/Documentation/translations/it_IT/doc-guide/parse-headers.rst new file mode 100644 index 0000000000..c7076a2166 --- /dev/null +++ b/Documentation/translations/it_IT/doc-guide/parse-headers.rst @@ -0,0 +1,195 @@ +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/doc-guide/index.rst + +========================================= +Includere gli i file di intestazione uAPI +========================================= + +Qualche volta è utile includere dei file di intestazione e degli esempi di codice C +al fine di descrivere l'API per lo spazio utente e per generare dei riferimenti +fra il codice e la documentazione. Aggiungere i riferimenti ai file dell'API +dello spazio utente ha ulteriori vantaggi: Sphinx genererà dei messaggi +d'avviso se un simbolo non viene trovato nella documentazione. Questo permette +di mantenere allineate la documentazione della uAPI (API spazio utente) +con le modifiche del kernel. +Il programma :ref:`parse_headers.pl <it_parse_headers>` genera questi riferimenti. +Esso dev'essere invocato attraverso un Makefile, mentre si genera la +documentazione. Per avere un esempio su come utilizzarlo all'interno del kernel +consultate ``Documentation/userspace-api/media/Makefile``. + +.. _it_parse_headers: + +parse_headers.pl +^^^^^^^^^^^^^^^^ + +NOME +**** + + +parse_headers.pl - analizza i file C al fine di identificare funzioni, +strutture, enumerati e definizioni, e creare riferimenti per Sphinx + +SINTASSI +******** + + +\ **parse_headers.pl**\ [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>] + +Dove <options> può essere: --debug, --usage o --help. + + +OPZIONI +******* + + + +\ **--debug**\ + + Lo script viene messo in modalità verbosa, utile per il debugging. + + +\ **--usage**\ + + Mostra un messaggio d'aiuto breve e termina. + + +\ **--help**\ + + Mostra un messaggio d'aiuto dettagliato e termina. + + +DESCRIZIONE +*********** + +Converte un file d'intestazione o un file sorgente C (C_FILE) in un testo +ReStructuredText incluso mediante il blocco ..parsed-literal +con riferimenti alla documentazione che descrive l'API. Opzionalmente, +il programma accetta anche un altro file (EXCEPTIONS_FILE) che +descrive quali elementi debbano essere ignorati o il cui riferimento +deve puntare ad elemento diverso dal predefinito. + +Il file generato sarà disponibile in (OUT_FILE). + +Il programma è capace di identificare *define*, funzioni, strutture, +tipi di dato, enumerati e valori di enumerati, e di creare i riferimenti +per ognuno di loro. Inoltre, esso è capace di distinguere le #define +utilizzate per specificare i comandi ioctl di Linux. + +Il file EXCEPTIONS_FILE contiene due tipi di dichiarazioni: +\ **ignore**\ o \ **replace**\ . + +La sintassi per ignore è: + +ignore \ **tipo**\ \ **nome**\ + +La dichiarazione \ **ignore**\ significa che non verrà generato alcun +riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ . + + +La sintassi per replace è: + +replace \ **tipo**\ \ **nome**\ \ **nuovo_valore**\ + +La dichiarazione \ **replace**\ significa che verrà generato un +riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ , ma, invece +di utilizzare il valore predefinito, verrà utilizzato il valore +\ **nuovo_valore**\ . + +Per entrambe le dichiarazioni, il \ **tipo**\ può essere uno dei seguenti: + + +\ **ioctl**\ + + La dichiarazione ignore o replace verrà applicata su definizioni di ioctl + come la seguente: + + #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) + + + +\ **define**\ + + La dichiarazione ignore o replace verrà applicata su una qualsiasi #define + trovata in C_FILE. + + + +\ **typedef**\ + + La dichiarazione ignore o replace verrà applicata ad una dichiarazione typedef + in C_FILE. + + + +\ **struct**\ + + La dichiarazione ignore o replace verrà applicata ai nomi di strutture + in C_FILE. + + + +\ **enum**\ + + La dichiarazione ignore o replace verrà applicata ai nomi di enumerati + in C_FILE. + + + +\ **symbol**\ + + La dichiarazione ignore o replace verrà applicata ai nomi di valori di + enumerati in C_FILE. + + Per le dichiarazioni di tipo replace, il campo \ **new_value**\ utilizzerà + automaticamente i riferimenti :c:type: per \ **typedef**\ , \ **enum**\ e + \ **struct**\. Invece, utilizzerà :ref: per \ **ioctl**\ , \ **define**\ e + \ **symbol**\. Il tipo di riferimento può essere definito esplicitamente + nella dichiarazione stessa. + + +ESEMPI +****** + + +ignore define _VIDEODEV2_H + + +Ignora una definizione #define _VIDEODEV2_H nel file C_FILE. + +ignore symbol PRIVATE + + +In un enumerato come il seguente: + +enum foo { BAR1, BAR2, PRIVATE }; + +Non genererà alcun riferimento per \ **PRIVATE**\ . + +replace symbol BAR1 :c:type:\`foo\` +replace symbol BAR2 :c:type:\`foo\` + + +In un enumerato come il seguente: + +enum foo { BAR1, BAR2, PRIVATE }; + +Genererà un riferimento ai valori BAR1 e BAR2 dal simbolo foo nel dominio C. + + +BUGS +**** + +Riferire ogni malfunzionamento a Mauro Carvalho Chehab <mchehab@s-opensource.com> + + +COPYRIGHT +********* + + +Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>. + +Licenza GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>. + +Questo è software libero: siete liberi di cambiarlo e ridistribuirlo. +Non c'è alcuna garanzia, nei limiti permessi dalla legge. diff --git a/Documentation/translations/it_IT/doc-guide/sphinx.rst b/Documentation/translations/it_IT/doc-guide/sphinx.rst new file mode 100644 index 0000000000..1f513bc336 --- /dev/null +++ b/Documentation/translations/it_IT/doc-guide/sphinx.rst @@ -0,0 +1,501 @@ +.. include:: ../disclaimer-ita.rst + +.. note:: Per leggere la documentazione originale in inglese: + :ref:`Documentation/doc-guide/index.rst <doc_guide>` + +.. _it_sphinxdoc: + +============================================= +Usare Sphinx per la documentazione del kernel +============================================= + +Il kernel Linux usa `Sphinx`_ per la generazione della documentazione a partire +dai file `reStructuredText`_ che si trovano nella cartella ``Documentation``. +Per generare la documentazione in HTML o PDF, usate comandi ``make htmldocs`` o +``make pdfdocs``. La documentazione così generata sarà disponibile nella +cartella ``Documentation/output``. + +.. _Sphinx: http://www.sphinx-doc.org/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html + +I file reStructuredText possono contenere delle direttive che permettono di +includere i commenti di documentazione, o di tipo kernel-doc, dai file +sorgenti. +Solitamente questi commenti sono utilizzati per descrivere le funzioni, i tipi +e l'architettura del codice. I commenti di tipo kernel-doc hanno una struttura +e formato speciale, ma a parte questo vengono processati come reStructuredText. + +Inoltre, ci sono migliaia di altri documenti in formato testo sparsi nella +cartella ``Documentation``. Alcuni di questi verranno probabilmente convertiti, +nel tempo, in formato reStructuredText, ma la maggior parte di questi rimarranno +in formato testo. + +.. _it_sphinx_install: + +Installazione Sphinx +==================== + +I marcatori ReST utilizzati nei file in Documentation/ sono pensati per essere +processati da ``Sphinx`` nella versione 1.7 o superiore. + +Esiste uno script che verifica i requisiti Sphinx. Per ulteriori dettagli +consultate :ref:`it_sphinx-pre-install`. + +La maggior parte delle distribuzioni Linux forniscono Sphinx, ma l'insieme dei +programmi e librerie è fragile e non è raro che dopo un aggiornamento di +Sphinx, o qualche altro pacchetto Python, la documentazione non venga più +generata correttamente. + +Un modo per evitare questo genere di problemi è quello di utilizzare una +versione diversa da quella fornita dalla vostra distribuzione. Per fare questo, +vi raccomandiamo di installare Sphinx dentro ad un ambiente virtuale usando +``virtualenv-3`` o ``virtualenv`` a seconda di come Python 3 è stato +pacchettizzato dalla vostra distribuzione. + +.. note:: + + #) Viene raccomandato l'uso del tema RTD per la documentazione in HTML. + A seconda della versione di Sphinx, potrebbe essere necessaria + l'installazione tramite il comando ``pip install sphinx_rtd_theme``. + + #) Alcune pagine ReST contengono delle formule matematiche. A causa del + modo in cui Sphinx funziona, queste espressioni sono scritte + utilizzando LaTeX. Per una corretta interpretazione, è necessario aver + installato texlive con i pacchetti amdfonts e amsmath. + +Riassumendo, se volete installare la versione 2.4.4 di Sphinx dovete eseguire:: + + $ virtualenv sphinx_2.4.4 + $ . sphinx_2.4.4/bin/activate + (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt + +Dopo aver eseguito ``. sphinx_2.4.4/bin/activate``, il prompt cambierà per +indicare che state usando il nuovo ambiente. Se aprite un nuova sessione, +prima di generare la documentazione, dovrete rieseguire questo comando per +rientrare nell'ambiente virtuale. + +Generazione d'immagini +---------------------- + +Il meccanismo che genera la documentazione del kernel contiene un'estensione +capace di gestire immagini in formato Graphviz e SVG (per maggior informazioni +vedere :ref:`it_sphinx_kfigure`). + +Per far si che questo funzioni, dovete installare entrambe i pacchetti +Graphviz e ImageMagick. Il sistema di generazione della documentazione è in +grado di procedere anche se questi pacchetti non sono installati, ma il +risultato, ovviamente, non includerà le immagini. + +Generazione in PDF e LaTeX +-------------------------- + +Al momento, la generazione di questi documenti è supportata solo dalle +versioni di Sphinx superiori alla 2.4. + +Per la generazione di PDF e LaTeX, avrete bisogno anche del pacchetto +``XeLaTeX`` nella versione 3.14159265 + +Per alcune distribuzioni Linux potrebbe essere necessario installare +anche una serie di pacchetti ``texlive`` in modo da fornire il supporto +minimo per il funzionamento di ``XeLaTeX``. + +.. _it_sphinx-pre-install: + +Verificare le dipendenze Sphinx +------------------------------- + +Esiste uno script che permette di verificare automaticamente le dipendenze di +Sphinx. Se lo script riesce a riconoscere la vostra distribuzione, allora +sarà in grado di darvi dei suggerimenti su come procedere per completare +l'installazione:: + + $ ./scripts/sphinx-pre-install + Checking if the needed tools for Fedora release 26 (Twenty Six) are available + Warning: better to also install "texlive-luatex85". + You should run: + + sudo dnf install -y texlive-luatex85 + /usr/bin/virtualenv sphinx_2.4.4 + . sphinx_2.4.4/bin/activate + pip install -r Documentation/sphinx/requirements.txt + + Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. + +L'impostazione predefinita prevede il controllo dei requisiti per la generazione +di documenti html e PDF, includendo anche il supporto per le immagini, le +espressioni matematiche e LaTeX; inoltre, presume che venga utilizzato un +ambiente virtuale per Python. I requisiti per generare i documenti html +sono considerati obbligatori, gli altri sono opzionali. + +Questo script ha i seguenti parametri: + +``--no-pdf`` + Disabilita i controlli per la generazione di PDF; + +``--no-virtualenv`` + Utilizza l'ambiente predefinito dal sistema operativo invece che + l'ambiente virtuale per Python; + + +Generazione della documentazione Sphinx +======================================= + +Per generare la documentazione in formato HTML o PDF si eseguono i rispettivi +comandi ``make htmldocs`` o ``make pdfdocs``. Esistono anche altri formati +in cui è possibile generare la documentazione; per maggiori informazioni +potere eseguire il comando ``make help``. +La documentazione così generata sarà disponibile nella sottocartella +``Documentation/output``. + +Ovviamente, per generare la documentazione, Sphinx (``sphinx-build``) +dev'essere installato. Se disponibile, il tema *Read the Docs* per Sphinx +verrà utilizzato per ottenere una documentazione HTML più gradevole. +Per la documentazione in formato PDF, invece, avrete bisogno di ``XeLaTeX` +e di ``convert(1)`` disponibile in ImageMagick +(https://www.imagemagick.org). \ [#ink]_ +Tipicamente, tutti questi pacchetti sono disponibili e pacchettizzati nelle +distribuzioni Linux. + +Per poter passare ulteriori opzioni a Sphinx potete utilizzare la variabile +make ``SPHINXOPTS``. Per esempio, se volete che Sphinx sia più verboso durante +la generazione potete usare il seguente comando ``make SPHINXOPTS=-v htmldocs``. + +Potete anche personalizzare l'ouptut html passando un livello aggiuntivo +DOCS_CSS usando la rispettiva variabile d'ambiente ``DOCS_CSS``. + +La variable make ``SPHINXDIRS`` è utile quando si vuole generare solo una parte +della documentazione. Per esempio, si possono generare solo di documenti in +``Documentation/doc-guide`` eseguendo ``make SPHINXDIRS=doc-guide htmldocs``. La +sezione dedicata alla documentazione di ``make help`` vi mostrerà quali sotto +cartelle potete specificare. + +Potete eliminare la documentazione generata tramite il comando +``make cleandocs``. + +.. [#ink] Avere installato anche ``inkscape(1)`` dal progetto Inkscape () + potrebbe aumentare la qualità delle immagini che verranno integrate + nel documento PDF, specialmente per quando si usando rilasci del + kernel uguali o superiori a 5.18 + +Scrivere la documentazione +========================== + +Aggiungere nuova documentazione è semplice: + +1. aggiungete un file ``.rst`` nella sottocartella ``Documentation`` +2. aggiungete un riferimento ad esso nell'indice (`TOC tree`_) in + ``Documentation/index.rst``. + +.. _TOC tree: http://www.sphinx-doc.org/en/stable/markup/toctree.html + +Questo, di solito, è sufficiente per la documentazione più semplice (come +quella che state leggendo ora), ma per una documentazione più elaborata è +consigliato creare una sottocartella dedicata (o, quando possibile, utilizzarne +una già esistente). Per esempio, il sottosistema grafico è documentato nella +sottocartella ``Documentation/gpu``; questa documentazione è divisa in +diversi file ``.rst`` ed un indice ``index.rst`` (con un ``toctree`` +dedicato) a cui si fa riferimento nell'indice principale. + +Consultate la documentazione di `Sphinx`_ e `reStructuredText`_ per maggiori +informazione circa le loro potenzialità. In particolare, il +`manuale introduttivo a reStructuredText`_ di Sphinx è un buon punto da +cui cominciare. Esistono, inoltre, anche alcuni +`costruttori specifici per Sphinx`_. + +.. _`manuale introduttivo a reStructuredText`: http://www.sphinx-doc.org/en/stable/rest.html +.. _`costruttori specifici per Sphinx`: http://www.sphinx-doc.org/en/stable/markup/index.html + +Guide linea per la documentazione del kernel +-------------------------------------------- + +In questa sezione troverete alcune linee guida specifiche per la documentazione +del kernel: + +* Non esagerate con i costrutti di reStructuredText. Mantenete la + documentazione semplice. La maggior parte della documentazione dovrebbe + essere testo semplice con una strutturazione minima che permetta la + conversione in diversi formati. + +* Mantenete la strutturazione il più fedele possibile all'originale quando + convertite un documento in formato reStructuredText. + +* Aggiornate i contenuti quando convertite della documentazione, non limitatevi + solo alla formattazione. + +* Mantenete la decorazione dei livelli di intestazione come segue: + + 1. ``=`` con una linea superiore per il titolo del documento:: + + ====== + Titolo + ====== + + 2. ``=`` per i capitoli:: + + Capitoli + ======== + + 3. ``-`` per le sezioni:: + + Sezioni + ------- + + 4. ``~`` per le sottosezioni:: + + Sottosezioni + ~~~~~~~~~~~~ + + Sebbene RST non forzi alcun ordine specifico (*Piuttosto che imporre + un numero ed un ordine fisso di decorazioni, l'ordine utilizzato sarà + quello incontrato*), avere uniformità dei livelli principali rende più + semplice la lettura dei documenti. + +* Per inserire blocchi di testo con caratteri a dimensione fissa (codici di + esempio, casi d'uso, eccetera): utilizzate ``::`` quando non è necessario + evidenziare la sintassi, specialmente per piccoli frammenti; invece, + utilizzate ``.. code-block:: <language>`` per blocchi più lunghi che + beneficeranno della sintassi evidenziata. Per un breve pezzo di codice da + inserire nel testo, usate \`\`. + + +Il dominio C +------------ + +Il **Dominio Sphinx C** (denominato c) è adatto alla documentazione delle API C. +Per esempio, un prototipo di una funzione: + +.. code-block:: rst + + .. c:function:: int ioctl( int fd, int request ) + +Il dominio C per kernel-doc ha delle funzionalità aggiuntive. Per esempio, +potete assegnare un nuovo nome di riferimento ad una funzione con un nome +molto comune come ``open`` o ``ioctl``: + +.. code-block:: rst + + .. c:function:: int ioctl( int fd, int request ) + :name: VIDIOC_LOG_STATUS + +Il nome della funzione (per esempio ioctl) rimane nel testo ma il nome del suo +riferimento cambia da ``ioctl`` a ``VIDIOC_LOG_STATUS``. Anche la voce +nell'indice cambia in ``VIDIOC_LOG_STATUS``. + +Notate che per una funzione non c'è bisogno di usare ``c:func:`` per generarne +i riferimenti nella documentazione. Grazie a qualche magica estensione a +Sphinx, il sistema di generazione della documentazione trasformerà +automaticamente un riferimento ad una ``funzione()`` in un riferimento +incrociato quando questa ha una voce nell'indice. Se trovate degli usi di +``c:func:`` nella documentazione del kernel, sentitevi liberi di rimuoverli. + + +Tabelle a liste +--------------- + +Il formato ``list-table`` può essere utile per tutte quelle tabelle che non +possono essere facilmente scritte usando il formato ASCII-art di Sphinx. Però, +questo genere di tabelle sono illeggibili per chi legge direttamente i file di +testo. Dunque, questo formato dovrebbe essere evitato senza forti argomenti che +ne giustifichino l'uso. + +La ``flat-table`` è anch'essa una lista di liste simile alle ``list-table`` +ma con delle funzionalità aggiuntive: + +* column-span: col ruolo ``cspan`` una cella può essere estesa attraverso + colonne successive + +* raw-span: col ruolo ``rspan`` una cella può essere estesa attraverso + righe successive + +* auto-span: la cella più a destra viene estesa verso destra per compensare + la mancanza di celle. Con l'opzione ``:fill-cells:`` questo comportamento + può essere cambiato da *auto-span* ad *auto-fill*, il quale inserisce + automaticamente celle (vuote) invece che estendere l'ultima. + +opzioni: + +* ``:header-rows:`` [int] conta le righe di intestazione +* ``:stub-columns:`` [int] conta le colonne di stub +* ``:widths:`` [[int] [int] ... ] larghezza delle colonne +* ``:fill-cells:`` invece di estendere automaticamente una cella su quelle + mancanti, ne crea di vuote. + +ruoli: + +* ``:cspan:`` [int] colonne successive (*morecols*) +* ``:rspan:`` [int] righe successive (*morerows*) + +L'esempio successivo mostra come usare questo marcatore. Il primo livello della +nostra lista di liste è la *riga*. In una *riga* è possibile inserire solamente +la lista di celle che compongono la *riga* stessa. Fanno eccezione i *commenti* +( ``..`` ) ed i *collegamenti* (per esempio, un riferimento a +``:ref:`last row <last row>``` / :ref:`last row <it last row>`) + +.. code-block:: rst + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - row 1 + - field 1.1 + - field 1.2 with autospan + + * - row 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`it last row`: + + - row 3 + +Che verrà rappresentata nel seguente modo: + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - row 1 + - field 1.1 + - field 1.2 with autospan + + * - row 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`it last row`: + + - row 3 + +Riferimenti incrociati +---------------------- + +Aggiungere un riferimento incrociato da una pagina della +documentazione ad un'altra può essere fatto scrivendo il percorso al +file corrispondende, non serve alcuna sintassi speciale. Si possono +usare sia percorsi assoluti che relativi. Quelli assoluti iniziano con +"documentation/". Per esempio, potete fare riferimento a questo +documento in uno dei seguenti modi (da notare che l'estensione +``.rst`` è necessaria):: + + Vedere Documentation/doc-guide/sphinx.rst. Questo funziona sempre + Guardate pshinx.rst, che si trova nella stessa cartella. + Leggete ../sphinx.rst, che si trova nella cartella precedente. + +Se volete che il collegamento abbia un testo diverso rispetto al +titolo del documento, allora dovrete usare la direttiva Sphinx +``doc``. Per esempio:: + + Vedere :doc:`il mio testo per il collegamento <sphinx>`. + +Nella maggioranza dei casi si consiglia il primo metodo perché è più +pulito ed adatto a chi legge dai sorgenti. Se incontrare un ``:doc:`` +che non da alcun valore, sentitevi liberi di convertirlo in un +percorso al documento. + +Per informazioni riguardo ai riferimenti incrociati ai commenti +kernel-doc per funzioni o tipi, consultate + +.. _it_sphinx_kfigure: + +Figure ed immagini +================== + +Se volete aggiungere un'immagine, utilizzate le direttive ``kernel-figure`` +e ``kernel-image``. Per esempio, per inserire una figura di un'immagine in +formato SVG (:ref:`it_svg_image_example`):: + + .. kernel-figure:: ../../../doc-guide/svg_image.svg + :alt: una semplice immagine SVG + + Una semplice immagine SVG + +.. _it_svg_image_example: + +.. kernel-figure:: ../../../doc-guide/svg_image.svg + :alt: una semplice immagine SVG + + Una semplice immagine SVG + +Le direttive del kernel per figure ed immagini supportano il formato **DOT**, +per maggiori informazioni + +* DOT: http://graphviz.org/pdf/dotguide.pdf +* Graphviz: http://www.graphviz.org/content/dot-language + +Un piccolo esempio (:ref:`it_hello_dot_file`):: + + .. kernel-figure:: ../../../doc-guide/hello.dot + :alt: ciao mondo + + Esempio DOT + +.. _it_hello_dot_file: + +.. kernel-figure:: ../../../doc-guide/hello.dot + :alt: ciao mondo + + Esempio DOT + +Tramite la direttiva ``kernel-render`` è possibile aggiungere codice specifico; +ad esempio nel formato **DOT** di Graphviz.:: + + .. kernel-render:: DOT + :alt: foobar digraph + :caption: Codice **DOT** (Graphviz) integrato + + digraph foo { + "bar" -> "baz"; + } + +La rappresentazione dipenderà dei programmi installati. Se avete Graphviz +installato, vedrete un'immagine vettoriale. In caso contrario, il codice grezzo +verrà rappresentato come *blocco testuale* (:ref:`it_hello_dot_render`). + +.. _it_hello_dot_render: + +.. kernel-render:: DOT + :alt: foobar digraph + :caption: Codice **DOT** (Graphviz) integrato + + digraph foo { + "bar" -> "baz"; + } + +La direttiva *render* ha tutte le opzioni della direttiva *figure*, con +l'aggiunta dell'opzione ``caption``. Se ``caption`` ha un valore allora +un nodo *figure* viene aggiunto. Altrimenti verrà aggiunto un nodo *image*. +L'opzione ``caption`` è necessaria in caso si vogliano aggiungere dei +riferimenti (:ref:`it_hello_svg_render`). + +Per la scrittura di codice **SVG**:: + + .. kernel-render:: SVG + :caption: Integrare codice **SVG** + :alt: so-nw-arrow + + <?xml version="1.0" encoding="UTF-8"?> + <svg xmlns="http://www.w3.org/2000/svg" version="1.1" ...> + ... + </svg> + +.. _it_hello_svg_render: + +.. kernel-render:: SVG + :caption: Integrare codice **SVG** + :alt: so-nw-arrow + + <?xml version="1.0" encoding="UTF-8"?> + <svg xmlns="http://www.w3.org/2000/svg" + version="1.1" baseProfile="full" width="70px" height="40px" viewBox="0 0 700 400"> + <line x1="180" y1="370" x2="500" y2="50" stroke="black" stroke-width="15px"/> + <polygon points="585 0 525 25 585 50" transform="rotate(135 525 25)"/> + </svg> diff --git a/Documentation/translations/it_IT/index.rst b/Documentation/translations/it_IT/index.rst new file mode 100644 index 0000000000..b95dfa1ded --- /dev/null +++ b/Documentation/translations/it_IT/index.rst @@ -0,0 +1,133 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _it_linux_doc: + +================================== +La documentazione del kernel Linux +================================== + +.. raw:: latex + + \kerneldocCJKoff + +:manutentore: Federico Vaga <federico.vaga@vaga.pv.it> + +Questo è il livello principale della documentazione del kernel in +lingua italiana. La traduzione è incompleta, noterete degli avvisi +che vi segnaleranno la mancanza di una traduzione o di un gruppo di +traduzioni. + +Più in generale, la documentazione, come il kernel stesso, sono in +costante sviluppo; particolarmente vero in quanto stiamo lavorando +alla riorganizzazione della documentazione in modo più coerente. +I miglioramenti alla documentazione sono sempre i benvenuti; per cui, +se vuoi aiutare, iscriviti alla lista di discussione linux-doc presso +vger.kernel.org. + +.. _it_disclaimer: + +Avvertenze +========== + +L'obiettivo di questa traduzione è di rendere più facile la lettura e +la comprensione per chi non capisce l'inglese o ha dubbi sulla sua +interpretazione, oppure semplicemente per chi preferisce leggere in lingua +italiana. Tuttavia, tenete ben presente che l'*unica* documentazione +ufficiale è quella in lingua inglese: :ref:`linux_doc` + +La propagazione simultanea a tutte le traduzioni di una modifica in +:ref:`linux_doc` è altamente improbabile. I manutentori delle traduzioni - +e i contributori - seguono l'evolversi della documentazione ufficiale e +cercano di mantenere le rispettive traduzioni allineate nel limite del +possibile. Per questo motivo non c'è garanzia che una traduzione sia +aggiornata all'ultima modifica. Se quello che leggete in una traduzione +non corrisponde a quello che leggete nel codice, informate il manutentore +della traduzione e - se potete - verificate anche la documentazione in +inglese. + +Una traduzione non è un *fork* della documentazione ufficiale, perciò gli +utenti non vi troveranno alcuna informazione diversa rispetto alla versione +ufficiale. Ogni aggiunta, rimozione o modifica dei contenuti deve essere +fatta prima nei documenti in inglese. In seguito, e quando è possibile, la +stessa modifica dovrebbe essere applicata anche alle traduzioni. I manutentori +delle traduzioni accettano contributi che interessano prettamente l'attività +di traduzione (per esempio, nuove traduzioni, aggiornamenti, correzioni). + +Le traduzioni cercano di essere il più possibile accurate ma non è possibile +mappare direttamente una lingua in un'altra. Ogni lingua ha la sua grammatica +e una sua cultura alle spalle, quindi la traduzione di una frase in inglese +potrebbe essere modificata per adattarla all'italiano. Per questo motivo, +quando leggete questa traduzione, potreste trovare alcune differenze di forma +ma che trasmettono comunque il messaggio originale. Nonostante la grande +diffusione di inglesismi nella lingua parlata, quando possibile, questi +verranno sostituiti dalle corrispettive parole italiane + +Se avete bisogno d'aiuto per comunicare con la comunità Linux ma non vi sentite +a vostro agio nello scrivere in inglese, potete chiedere aiuto al manutentore +della traduzione. + +Lavorare con la comunità di sviluppo +==================================== + +Le guide fondamentali per l'interazione con la comunità di sviluppo del kernel e +su come vedere il proprio lavoro integrato. + +.. toctree:: + :maxdepth: 1 + + process/development-process + process/submitting-patches + Code of conduct <process/code-of-conduct> + All development-process docs <process/index> + + +Manuali sull'API interna +======================== + +Di seguito una serie di manuali per gli sviluppatori che hanno bisogno di +interfacciarsi con il resto del kernel. + +.. toctree:: + :maxdepth: 1 + + core-api/index + +Strumenti e processi per lo sviluppo +==================================== + +Di seguito una serie di manuali contenenti informazioni utili a tutti gli +sviluppatori del kernel. + +.. toctree:: + :maxdepth: 1 + + process/license-rules + doc-guide/index + kernel-hacking/index + +Documentazione per gli utenti +============================= + +Di seguito una serie di manuali per gli *utenti* del kernel - ovvero coloro che +stanno cercando di farlo funzionare al meglio per un dato sistema, ma anche +coloro che stanno sviluppando applicazioni che sfruttano l'API verso lo +spazio-utente. + +Consultate anche `Linux man pages <https://www.kernel.org/doc/man-pages/>`_, che +vengono mantenuti separatamente dalla documentazione del kernel Linux + +Documentazione relativa ai firmware +=================================== +Di seguito informazioni sulle aspettative del kernel circa i firmware. + + +Documentazione specifica per architettura +========================================= + + +Documentazione varia +==================== + +Ci sono documenti che sono difficili da inserire nell'attuale organizzazione +della documentazione; altri hanno bisogno di essere migliorati e/o convertiti +nel formato *ReStructured Text*; altri sono semplicamente troppo vecchi. diff --git a/Documentation/translations/it_IT/kernel-hacking/hacking.rst b/Documentation/translations/it_IT/kernel-hacking/hacking.rst new file mode 100644 index 0000000000..dd06bfc1a0 --- /dev/null +++ b/Documentation/translations/it_IT/kernel-hacking/hacking.rst @@ -0,0 +1,870 @@ +.. include:: ../disclaimer-ita.rst + +.. note:: Per leggere la documentazione originale in inglese: + :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` + +:Original: :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_kernel_hacking_hack: + +================================================= +L'inaffidabile guida all'hacking del kernel Linux +================================================= + +:Author: Rusty Russell + +Introduzione +============ + +Benvenuto, gentile lettore, alla notevole ed inaffidabile guida all'hacking +del kernel Linux ad opera di Rusty. Questo documento descrive le procedure +più usate ed i concetti necessari per scrivere codice per il kernel: lo scopo +è di fornire ai programmatori C più esperti un manuale di base per sviluppo. +Eviterò dettagli implementativi: per questo abbiamo il codice, +ed ignorerò intere parti di alcune procedure. + +Prima di leggere questa guida, sappiate che non ho mai voluto scriverla, +essendo esageratamente sotto qualificato, ma ho sempre voluto leggere +qualcosa di simile, e quindi questa era l'unica via. Spero che possa +crescere e diventare un compendio di buone pratiche, punti di partenza +e generiche informazioni. + +Gli attori +========== + +In qualsiasi momento ognuna delle CPU di un sistema può essere: + +- non associata ad alcun processo, servendo un'interruzione hardware; + +- non associata ad alcun processo, servendo un softirq o tasklet; + +- in esecuzione nello spazio kernel, associata ad un processo + (contesto utente); + +- in esecuzione di un processo nello spazio utente; + +Esiste un ordine fra questi casi. Gli ultimi due possono avvicendarsi (preempt) +l'un l'altro, ma a parte questo esiste una gerarchia rigida: ognuno di questi +può avvicendarsi solo ad uno di quelli sottostanti. Per esempio, mentre un +softirq è in esecuzione su d'una CPU, nessun altro softirq può avvicendarsi +nell'esecuzione, ma un'interruzione hardware può. Ciò nonostante, le altre CPU +del sistema operano indipendentemente. + +Più avanti vedremo alcuni modi in cui dal contesto utente è possibile bloccare +le interruzioni, così da impedirne davvero il diritto di prelazione. + +Contesto utente +--------------- + +Ci si trova nel contesto utente quando si arriva da una chiamata di sistema +od altre eccezioni: come nello spazio utente, altre procedure più importanti, +o le interruzioni, possono far valere il proprio diritto di prelazione sul +vostro processo. Potete sospendere l'esecuzione chiamando :c:func:`schedule()`. + +.. note:: + + Si è sempre in contesto utente quando un modulo viene caricato o rimosso, + e durante le operazioni nello strato dei dispositivi a blocchi + (*block layer*). + +Nel contesto utente, il puntatore ``current`` (il quale indica il processo al +momento in esecuzione) è valido, e :c:func:`in_interrupt()` +(``include/linux/preempt.h``) è falsa. + +.. warning:: + + Attenzione che se avete la prelazione o i softirq disabilitati (vedere + di seguito), :c:func:`in_interrupt()` ritornerà un falso positivo. + +Interruzioni hardware (Hard IRQs) +--------------------------------- + +Temporizzatori, schede di rete e tastiere sono esempi di vero hardware +che possono produrre interruzioni in un qualsiasi momento. Il kernel esegue +i gestori d'interruzione che prestano un servizio all'hardware. Il kernel +garantisce che questi gestori non vengano mai interrotti: se una stessa +interruzione arriva, questa verrà accodata (o scartata). +Dato che durante la loro esecuzione le interruzioni vengono disabilitate, +i gestori d'interruzioni devono essere veloci: spesso si limitano +esclusivamente a notificare la presa in carico dell'interruzione, +programmare una 'interruzione software' per l'esecuzione e quindi terminare. + +Potete dire d'essere in una interruzione hardware perché in_hardirq() +ritorna vero. + +.. warning:: + + Attenzione, questa ritornerà un falso positivo se le interruzioni + sono disabilitate (vedere di seguito). + +Contesto d'interruzione software: softirq e tasklet +--------------------------------------------------- + +Quando una chiamata di sistema sta per tornare allo spazio utente, +oppure un gestore d'interruzioni termina, qualsiasi 'interruzione software' +marcata come pendente (solitamente da un'interruzione hardware) viene +eseguita (``kernel/softirq.c``). + +La maggior parte del lavoro utile alla gestione di un'interruzione avviene qui. +All'inizio della transizione ai sistemi multiprocessore, c'erano solo i +cosiddetti 'bottom half' (BH), i quali non traevano alcun vantaggio da questi +sistemi. Non appena abbandonammo i computer raffazzonati con fiammiferi e +cicche, abbandonammo anche questa limitazione e migrammo alle interruzioni +software 'softirqs'. + +Il file ``include/linux/interrupt.h`` elenca i differenti tipi di 'softirq'. +Un tipo di softirq molto importante è il timer (``include/linux/timer.h``): +potete programmarlo per far si che esegua funzioni dopo un determinato +periodo di tempo. + +Dato che i softirq possono essere eseguiti simultaneamente su più di un +processore, spesso diventa estenuante l'averci a che fare. Per questa ragione, +i tasklet (``include/linux/interrupt.h``) vengo usati più di frequente: +possono essere registrati dinamicamente (il che significa che potete averne +quanti ne volete), e garantiscono che un qualsiasi tasklet verrà eseguito +solo su un processore alla volta, sebbene diversi tasklet possono essere +eseguiti simultaneamente. + +.. warning:: + + Il nome 'tasklet' è ingannevole: non hanno niente a che fare + con i 'processi' ('tasks'). + +Potete determinate se siete in un softirq (o tasklet) utilizzando la +macro :c:func:`in_softirq()` (``include/linux/preempt.h``). + +.. warning:: + + State attenti che questa macro ritornerà un falso positivo + se :ref:`bottom half lock <it_local_bh_disable>` è bloccato. + +Alcune regole basilari +====================== + +Nessuna protezione della memoria + Se corrompete la memoria, che sia in contesto utente o d'interruzione, + la macchina si pianterà. Siete sicuri che quello che volete fare + non possa essere fatto nello spazio utente? + +Nessun numero in virgola mobile o MMX + Il contesto della FPU non è salvato; anche se siete in contesto utente + lo stato dell'FPU probabilmente non corrisponde a quello del processo + corrente: vi incasinerete con lo stato di qualche altro processo. Se + volete davvero usare la virgola mobile, allora dovrete salvare e recuperare + lo stato dell'FPU (ed evitare cambi di contesto). Generalmente è una + cattiva idea; usate l'aritmetica a virgola fissa. + +Un limite rigido dello stack + A seconda della configurazione del kernel lo stack è fra 3K e 6K per la + maggior parte delle architetture a 32-bit; è di 14K per la maggior + parte di quelle a 64-bit; e spesso è condiviso con le interruzioni, + per cui non si può usare. + Evitare profonde ricorsioni ad enormi array locali nello stack + (allocateli dinamicamente). + +Il kernel Linux è portabile + Quindi mantenetelo tale. Il vostro codice dovrebbe essere a 64-bit ed + indipendente dall'ordine dei byte (endianess) di un processore. Inoltre, + dovreste minimizzare il codice specifico per un processore; per esempio + il codice assembly dovrebbe essere incapsulato in modo pulito e minimizzato + per facilitarne la migrazione. Generalmente questo codice dovrebbe essere + limitato alla parte di kernel specifica per un'architettura. + +ioctl: non scrivere nuove chiamate di sistema +============================================= + +Una chiamata di sistema, generalmente, è scritta così:: + + asmlinkage long sys_mycall(int arg) + { + return 0; + } + +Primo, nella maggior parte dei casi non volete creare nuove chiamate di +sistema. +Create un dispositivo a caratteri ed implementate l'appropriata chiamata ioctl. +Questo meccanismo è molto più flessibile delle chiamate di sistema: esso non +dev'essere dichiarato in tutte le architetture nei file +``include/asm/unistd.h`` e ``arch/kernel/entry.S``; inoltre, è improbabile +che questo venga accettato da Linus. + +Se tutto quello che il vostro codice fa è leggere o scrivere alcuni parametri, +considerate l'implementazione di un'interfaccia :c:func:`sysfs()`. + +All'interno di una ioctl vi trovate nel contesto utente di un processo. Quando +avviene un errore dovete ritornare un valore negativo di errno (consultate +``include/uapi/asm-generic/errno-base.h``, +``include/uapi/asm-generic/errno.h`` e ``include/linux/errno.h``), altrimenti +ritornate 0. + +Dopo aver dormito dovreste verificare se ci sono stati dei segnali: il modo +Unix/Linux di gestire un segnale è di uscire temporaneamente dalla chiamata +di sistema con l'errore ``-ERESTARTSYS``. La chiamata di sistema ritornerà +al contesto utente, eseguirà il gestore del segnale e poi la vostra chiamata +di sistema riprenderà (a meno che l'utente non l'abbia disabilitata). Quindi, +dovreste essere pronti per continuare l'esecuzione, per esempio nel mezzo +della manipolazione di una struttura dati. + +:: + + if (signal_pending(current)) + return -ERESTARTSYS; + +Se dovete eseguire dei calcoli molto lunghi: pensate allo spazio utente. +Se **davvero** volete farlo nel kernel ricordatevi di verificare periodicamente +se dovete *lasciare* il processore (ricordatevi che, per ogni processore, c'è +un sistema multi-processo senza diritto di prelazione). +Esempio:: + + cond_resched(); /* Will sleep */ + +Una breve nota sulla progettazione delle interfacce: il motto dei sistemi +UNIX è "fornite meccanismi e non politiche" + +La ricetta per uno stallo +========================= + +Non è permesso invocare una procedura che potrebbe dormire, fanno eccezione +i seguenti casi: + +- Siete in un contesto utente. + +- Non trattenete alcun spinlock. + +- Avete abilitato le interruzioni (in realtà, Andy Kleen dice che + lo schedulatore le abiliterà per voi, ma probabilmente questo non è quello + che volete). + +Da tener presente che alcune funzioni potrebbero dormire implicitamente: +le più comuni sono quelle per l'accesso allo spazio utente (\*_user) e +quelle per l'allocazione della memoria senza l'opzione ``GFP_ATOMIC`` + +Dovreste sempre compilare il kernel con l'opzione ``CONFIG_DEBUG_ATOMIC_SLEEP`` +attiva, questa vi avviserà se infrangete una di queste regole. +Se **infrangete** le regole, allora potreste bloccare il vostro scatolotto. + +Veramente. + +Alcune delle procedure più comuni +================================= + +:c:func:`printk()` +------------------ + +Definita in ``include/linux/printk.h`` + +:c:func:`printk()` fornisce messaggi alla console, dmesg, e al demone syslog. +Essa è utile per il debugging o per la notifica di errori; può essere +utilizzata anche all'interno del contesto d'interruzione, ma usatela con +cautela: una macchina che ha la propria console inondata da messaggi diventa +inutilizzabile. La funzione utilizza un formato stringa quasi compatibile con +la printf ANSI C, e la concatenazione di una stringa C come primo argomento +per indicare la "priorità":: + + printk(KERN_INFO "i = %u\n", i); + +Consultate ``include/linux/kern_levels.h`` per gli altri valori ``KERN_``; +questi sono interpretati da syslog come livelli. Un caso speciale: +per stampare un indirizzo IP usate:: + + __be32 ipaddress; + printk(KERN_INFO "my ip: %pI4\n", &ipaddress); + + +:c:func:`printk()` utilizza un buffer interno di 1K e non s'accorge di +eventuali sforamenti. Accertatevi che vi basti. + +.. note:: + + Saprete di essere un vero hacker del kernel quando inizierete a digitare + nei vostri programmi utenti le printf come se fossero printk :) + +.. note:: + + Un'altra nota a parte: la versione originale di Unix 6 aveva un commento + sopra alla funzione printf: "Printf non dovrebbe essere usata per il + chiacchiericcio". Dovreste seguire questo consiglio. + +:c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()` +--------------------------------------------------------------------------------------------------- + +Definite in ``include/linux/uaccess.h`` / ``asm/uaccess.h`` + +**[DORMONO]** + +:c:func:`put_user()` e :c:func:`get_user()` sono usate per ricevere ed +impostare singoli valori (come int, char, o long) da e verso lo spazio utente. +Un puntatore nello spazio utente non dovrebbe mai essere dereferenziato: i dati +dovrebbero essere copiati usando suddette procedure. Entrambe ritornano +``-EFAULT`` oppure 0. + +:c:func:`copy_to_user()` e :c:func:`copy_from_user()` sono più generiche: +esse copiano una quantità arbitraria di dati da e verso lo spazio utente. + +.. warning:: + + Al contrario di:c:func:`put_user()` e :c:func:`get_user()`, queste + funzioni ritornano la quantità di dati copiati (0 è comunque un successo). + +[Sì, questa interfaccia mi imbarazza. La battaglia torna in auge anno +dopo anno. --RR] + +Le funzioni potrebbero dormire implicitamente. Queste non dovrebbero mai essere +invocate fuori dal contesto utente (non ha senso), con le interruzioni +disabilitate, o con uno spinlock trattenuto. + +:c:func:`kmalloc()`/:c:func:`kfree()` +------------------------------------- + +Definite in ``include/linux/slab.h`` + +**[POTREBBERO DORMIRE: LEGGI SOTTO]** + +Queste procedure sono utilizzate per la richiesta dinamica di un puntatore ad +un pezzo di memoria allineato, esattamente come malloc e free nello spazio +utente, ma :c:func:`kmalloc()` ha un argomento aggiuntivo per indicare alcune +opzioni. Le opzioni più importanti sono: + +``GFP_KERNEL`` + Potrebbe dormire per librarare della memoria. L'opzione fornisce il modo + più affidabile per allocare memoria, ma il suo uso è strettamente limitato + allo spazio utente. + +``GFP_ATOMIC`` + Non dorme. Meno affidabile di ``GFP_KERNEL``, ma può essere usata in un + contesto d'interruzione. Dovreste avere **davvero** una buona strategia + per la gestione degli errori in caso di mancanza di memoria. + +``GFP_DMA`` + Alloca memoria per il DMA sul bus ISA nello spazio d'indirizzamento + inferiore ai 16MB. Se non sapete cos'è allora non vi serve. + Molto inaffidabile. + +Se vedete un messaggio d'avviso per una funzione dormiente che viene chiamata +da un contesto errato, allora probabilmente avete usato una funzione +d'allocazione dormiente da un contesto d'interruzione senza ``GFP_ATOMIC``. +Dovreste correggerlo. Sbrigatevi, non cincischiate. + +Se allocate almeno ``PAGE_SIZE``(``asm/page.h`` o ``asm/page_types.h``) byte, +considerate l'uso di :c:func:`__get_free_pages()` (``include/linux/gfp.h``). +Accetta un argomento che definisce l'ordine (0 per per la dimensione di una +pagine, 1 per una doppia pagina, 2 per quattro pagine, eccetra) e le stesse +opzioni d'allocazione viste precedentemente. + +Se state allocando un numero di byte notevolemnte superiore ad una pagina +potete usare :c:func:`vmalloc()`. Essa allocherà memoria virtuale all'interno +dello spazio kernel. Questo è un blocco di memoria fisica non contiguo, ma +la MMU vi darà l'impressione che lo sia (quindi, sarà contiguo solo dal punto +di vista dei processori, non dal punto di vista dei driver dei dispositivi +esterni). +Se per qualche strana ragione avete davvero bisogno di una grossa quantità di +memoria fisica contigua, avete un problema: Linux non ha un buon supporto per +questo caso d'uso perché, dopo un po' di tempo, la frammentazione della memoria +rende l'operazione difficile. Il modo migliore per allocare un simile blocco +all'inizio dell'avvio del sistema è attraverso la procedura +:c:func:`alloc_bootmem()`. + +Prima di inventare la vostra cache per gli oggetti più usati, considerate +l'uso di una cache slab disponibile in ``include/linux/slab.h``. + +:c:macro:`current` +------------------- + +Definita in ``include/asm/current.h`` + +Questa variabile globale (in realtà una macro) contiene un puntatore alla +struttura del processo corrente, quindi è valido solo dal contesto utente. +Per esempio, quando un processo esegue una chiamata di sistema, questo +punterà alla struttura dati del processo chiamate. +Nel contesto d'interruzione in suo valore **non è NULL**. + +:c:func:`mdelay()`/:c:func:`udelay()` +------------------------------------- + +Definite in ``include/asm/delay.h`` / ``include/linux/delay.h`` + +Le funzioni :c:func:`udelay()` e :c:func:`ndelay()` possono essere utilizzate +per brevi pause. Non usate grandi valori perché rischiate d'avere un +overflow - in questo contesto la funzione :c:func:`mdelay()` è utile, +oppure considerate :c:func:`msleep()`. + +:c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()` +----------------------------------------------------------------------------------------------- + +Definite in ``include/asm/byteorder.h`` + +La famiglia di funzioni :c:func:`cpu_to_be32()` (dove "32" può essere +sostituito da 64 o 16, e "be" con "le") forniscono un modo generico +per fare conversioni sull'ordine dei byte (endianess): esse ritornano +il valore convertito. Tutte le varianti supportano anche il processo inverso: +:c:func:`be32_to_cpu()`, eccetera. + +Queste funzioni hanno principalmente due varianti: la variante per +puntatori, come :c:func:`cpu_to_be32p()`, che prende un puntatore +ad un tipo, e ritorna il valore convertito. L'altra variante per +la famiglia di conversioni "in-situ", come :c:func:`cpu_to_be32s()`, +che convertono il valore puntato da un puntatore, e ritornano void. + +:c:func:`local_irq_save()`/:c:func:`local_irq_restore()` +-------------------------------------------------------- + +Definite in ``include/linux/irqflags.h`` + +Queste funzioni abilitano e disabilitano le interruzioni hardware +sul processore locale. Entrambe sono rientranti; esse salvano lo stato +precedente nel proprio argomento ``unsigned long flags``. Se sapete +che le interruzioni sono abilite, potete semplicemente utilizzare +:c:func:`local_irq_disable()` e :c:func:`local_irq_enable()`. + +.. _it_local_bh_disable: + +:c:func:`local_bh_disable()`/:c:func:`local_bh_enable()` +-------------------------------------------------------- + +Definite in ``include/linux/bottom_half.h`` + + +Queste funzioni abilitano e disabilitano le interruzioni software +sul processore locale. Entrambe sono rientranti; se le interruzioni +software erano già state disabilitate in precedenza, rimarranno +disabilitate anche dopo aver invocato questa coppia di funzioni. +Lo scopo è di prevenire l'esecuzione di softirq e tasklet sul processore +attuale. + +:c:func:`smp_processor_id()` +---------------------------- + +Definita in ``include/linux/smp.h`` + +:c:func:`get_cpu()` nega il diritto di prelazione (quindi non potete essere +spostati su un altro processore all'improvviso) e ritorna il numero +del processore attuale, fra 0 e ``NR_CPUS``. Da notare che non è detto +che la numerazione dei processori sia continua. Quando avete terminato, +ritornate allo stato precedente con :c:func:`put_cpu()`. + +Se sapete che non dovete essere interrotti da altri processi (per esempio, +se siete in un contesto d'interruzione, o il diritto di prelazione +è disabilitato) potete utilizzare smp_processor_id(). + + +``__init``/``__exit``/``__initdata`` +------------------------------------ + +Definite in ``include/linux/init.h`` + +Dopo l'avvio, il kernel libera una sezione speciale; le funzioni marcate +con ``__init`` e le strutture dati marcate con ``__initdata`` vengono +eliminate dopo il completamento dell'avvio: in modo simile i moduli eliminano +questa memoria dopo l'inizializzazione. ``__exit`` viene utilizzato per +dichiarare che una funzione verrà utilizzata solo in fase di rimozione: +la detta funzione verrà eliminata quando il file che la contiene non è +compilato come modulo. Guardate l'header file per informazioni. Da notare che +non ha senso avere una funzione marcata come ``__init`` e al tempo stesso +esportata ai moduli utilizzando :c:func:`EXPORT_SYMBOL()` o +:c:func:`EXPORT_SYMBOL_GPL()` - non funzionerà. + + +:c:func:`__initcall()`/:c:func:`module_init()` +---------------------------------------------- + +Definite in ``include/linux/init.h`` / ``include/linux/module.h`` + +Molte parti del kernel funzionano bene come moduli (componenti del kernel +caricabili dinamicamente). L'utilizzo delle macro :c:func:`module_init()` +e :c:func:`module_exit()` semplifica la scrittura di codice che può funzionare +sia come modulo, sia come parte del kernel, senza l'ausilio di #ifdef. + +La macro :c:func:`module_init()` definisce quale funzione dev'essere +chiamata quando il modulo viene inserito (se il file è stato compilato come +tale), o in fase di avvio : se il file non è stato compilato come modulo la +macro :c:func:`module_init()` diventa equivalente a :c:func:`__initcall()`, +la quale, tramite qualche magia del linker, s'assicura che la funzione venga +chiamata durante l'avvio. + +La funzione può ritornare un numero d'errore negativo per scatenare un +fallimento del caricamento (sfortunatamente, questo non ha effetto se il +modulo è compilato come parte integrante del kernel). Questa funzione è chiamata +in contesto utente con le interruzioni abilitate, quindi potrebbe dormire. + + +:c:func:`module_exit()` +----------------------- + + +Definita in ``include/linux/module.h`` + +Questa macro definisce la funzione che dev'essere chiamata al momento della +rimozione (o mai, nel caso in cui il file sia parte integrante del kernel). +Essa verrà chiamata solo quando il contatore d'uso del modulo raggiunge lo +zero. Questa funzione può anche dormire, ma non può fallire: tutto dev'essere +ripulito prima che la funzione ritorni. + +Da notare che questa macro è opzionale: se non presente, il modulo non sarà +removibile (a meno che non usiate 'rmmod -f' ). + + +:c:func:`try_module_get()`/:c:func:`module_put()` +------------------------------------------------- + +Definite in ``include/linux/module.h`` + +Queste funzioni maneggiano il contatore d'uso del modulo per proteggerlo dalla +rimozione (in aggiunta, un modulo non può essere rimosso se un altro modulo +utilizzo uno dei sui simboli esportati: vedere di seguito). Prima di eseguire +codice del modulo, dovreste chiamare :c:func:`try_module_get()` su quel modulo: +se fallisce significa che il modulo è stato rimosso e dovete agire come se +non fosse presente. Altrimenti, potete accedere al modulo in sicurezza, e +chiamare :c:func:`module_put()` quando avete finito. + +La maggior parte delle strutture registrabili hanno un campo owner +(proprietario), come nella struttura +:c:type:`struct file_operations <file_operations>`. +Impostate questo campo al valore della macro ``THIS_MODULE``. + + +Code d'attesa ``include/linux/wait.h`` +====================================== + +**[DORMONO]** + +Una coda d'attesa è usata per aspettare che qualcuno vi attivi quando una +certa condizione s'avvera. Per evitare corse critiche, devono essere usate +con cautela. Dichiarate una :c:type:`wait_queue_head_t`, e poi i processi +che vogliono attendere il verificarsi di quella condizione dichiareranno +una :c:type:`wait_queue_entry_t` facendo riferimento a loro stessi, poi +metteranno questa in coda. + +Dichiarazione +------------- + +Potere dichiarare una ``wait_queue_head_t`` utilizzando la macro +:c:func:`DECLARE_WAIT_QUEUE_HEAD()` oppure utilizzando la procedura +:c:func:`init_waitqueue_head()` nel vostro codice d'inizializzazione. + +Accodamento +----------- + +Mettersi in una coda d'attesa è piuttosto complesso, perché dovete +mettervi in coda prima di verificare la condizione. Esiste una macro +a questo scopo: :c:func:`wait_event_interruptible()` (``include/linux/wait.h``). +Il primo argomento è la testa della coda d'attesa, e il secondo è +un'espressione che dev'essere valutata; la macro ritorna 0 quando questa +espressione è vera, altrimenti ``-ERESTARTSYS`` se è stato ricevuto un segnale. +La versione :c:func:`wait_event()` ignora i segnali. + +Svegliare una procedura in coda +------------------------------- + +Chiamate :c:func:`wake_up()` (``include/linux/wait.h``); questa attiverà tutti +i processi in coda. Ad eccezione se uno di questi è impostato come +``TASK_EXCLUSIVE``, in questo caso i rimanenti non verranno svegliati. +Nello stesso header file esistono altre varianti di questa funzione. + +Operazioni atomiche +=================== + +Certe operazioni sono garantite come atomiche su tutte le piattaforme. +Il primo gruppo di operazioni utilizza :c:type:`atomic_t` +(``include/asm/atomic.h``); questo contiene un intero con segno (minimo 32bit), +e dovete utilizzare queste funzione per modificare o leggere variabili di tipo +:c:type:`atomic_t`. :c:func:`atomic_read()` e :c:func:`atomic_set()` leggono ed +impostano il contatore, :c:func:`atomic_add()`, :c:func:`atomic_sub()`, +:c:func:`atomic_inc()`, :c:func:`atomic_dec()`, e +:c:func:`atomic_dec_and_test()` (ritorna vero se raggiunge zero dopo essere +stata decrementata). + +Sì. Ritorna vero (ovvero != 0) se la variabile atomica è zero. + +Da notare che queste funzioni sono più lente rispetto alla normale aritmetica, +e quindi non dovrebbero essere usate a sproposito. + +Il secondo gruppo di operazioni atomiche sono definite in +``include/linux/bitops.h`` ed agiscono sui bit d'una variabile di tipo +``unsigned long``. Queste operazioni prendono come argomento un puntatore +alla variabile, e un numero di bit dove 0 è quello meno significativo. +:c:func:`set_bit()`, :c:func:`clear_bit()` e :c:func:`change_bit()` +impostano, cancellano, ed invertono il bit indicato. +:c:func:`test_and_set_bit()`, :c:func:`test_and_clear_bit()` e +:c:func:`test_and_change_bit()` fanno la stessa cosa, ad eccezione che +ritornano vero se il bit era impostato; queste sono particolarmente +utili quando si vuole impostare atomicamente dei flag. + +Con queste operazioni è possibile utilizzare indici di bit che eccedono +il valore ``BITS_PER_LONG``. Il comportamento è strano sulle piattaforme +big-endian quindi è meglio evitarlo. + +Simboli +======= + +All'interno del kernel, si seguono le normali regole del linker (ovvero, +a meno che un simbolo non venga dichiarato con visibilita limitata ad un +file con la parola chiave ``static``, esso può essere utilizzato in qualsiasi +parte del kernel). Nonostante ciò, per i moduli, esiste una tabella dei +simboli esportati che limita i punti di accesso al kernel. Anche i moduli +possono esportare simboli. + +:c:func:`EXPORT_SYMBOL()` +------------------------- + +Definita in ``include/linux/export.h`` + +Questo è il classico metodo per esportare un simbolo: i moduli caricati +dinamicamente potranno utilizzare normalmente il simbolo. + +:c:func:`EXPORT_SYMBOL_GPL()` +----------------------------- + +Definita in ``include/linux/export.h`` + +Essa è simile a :c:func:`EXPORT_SYMBOL()` ad eccezione del fatto che i +simboli esportati con :c:func:`EXPORT_SYMBOL_GPL()` possono essere +utilizzati solo dai moduli che hanno dichiarato una licenza compatibile +con la GPL attraverso :c:func:`MODULE_LICENSE()`. Questo implica che la +funzione esportata è considerata interna, e non una vera e propria interfaccia. +Alcuni manutentori e sviluppatori potrebbero comunque richiedere +:c:func:`EXPORT_SYMBOL_GPL()` quando si aggiungono nuove funzionalità o +interfacce. + +:c:func:`EXPORT_SYMBOL_NS()` +---------------------------- + +Definita in ``include/linux/export.h`` + +Questa è una variate di `EXPORT_SYMBOL()` che permette di specificare uno +spazio dei nomi. Lo spazio dei nomi è documentato in +Documentation/translations/it_IT/core-api/symbol-namespaces.rst. + +:c:func:`EXPORT_SYMBOL_NS_GPL()` +-------------------------------- + +Definita in ``include/linux/export.h`` + +Questa è una variate di `EXPORT_SYMBOL_GPL()` che permette di specificare uno +spazio dei nomi. Lo spazio dei nomi è documentato in +Documentation/translations/it_IT/core-api/symbol-namespaces.rst. + +Procedure e convenzioni +======================= + +Liste doppiamente concatenate ``include/linux/list.h`` +------------------------------------------------------ + +Un tempo negli header del kernel c'erano tre gruppi di funzioni per +le liste concatenate, ma questa è stata la vincente. Se non avete particolari +necessità per una semplice lista concatenata, allora questa è una buona scelta. + +In particolare, :c:func:`list_for_each_entry()` è utile. + +Convenzione dei valori di ritorno +--------------------------------- + +Per codice chiamato in contesto utente, è molto comune sfidare le convenzioni +C e ritornare 0 in caso di successo, ed un codice di errore negativo +(eg. ``-EFAULT``) nei casi fallimentari. Questo potrebbe essere controintuitivo +a prima vista, ma è abbastanza diffuso nel kernel. + +Utilizzate :c:func:`ERR_PTR()` (``include/linux/err.h``) per codificare +un numero d'errore negativo in un puntatore, e :c:func:`IS_ERR()` e +:c:func:`PTR_ERR()` per recuperarlo di nuovo: così si evita d'avere un +puntatore dedicato per il numero d'errore. Da brividi, ma in senso positivo. + +Rompere la compilazione +----------------------- + +Linus e gli altri sviluppatori a volte cambiano i nomi delle funzioni e +delle strutture nei kernel in sviluppo; questo non è solo per tenere +tutti sulle spine: questo riflette cambiamenti fondamentati (eg. la funzione +non può più essere chiamata con le funzioni attive, o fa controlli aggiuntivi, +o non fa più controlli che venivano fatti in precedenza). Solitamente a questo +s'accompagna un'adeguata e completa nota sulla lista di discussone +più adatta; cercate negli archivi. Solitamente eseguire una semplice +sostituzione su tutto un file rendere le cose **peggiori**. + +Inizializzazione dei campi d'una struttura +------------------------------------------ + +Il metodo preferito per l'inizializzazione delle strutture è quello +di utilizzare gli inizializzatori designati, come definiti nello +standard ISO C99, eg:: + + static struct block_device_operations opt_fops = { + .open = opt_open, + .release = opt_release, + .ioctl = opt_ioctl, + .check_media_change = opt_media_change, + }; + +Questo rende più facile la ricerca con grep, e rende più chiaro quale campo +viene impostato. Dovreste fare così perché si mostra meglio. + +Estensioni GNU +-------------- + +Le estensioni GNU sono esplicitamente permesse nel kernel Linux. Da notare +che alcune delle più complesse non sono ben supportate, per via dello scarso +sviluppo, ma le seguenti sono da considerarsi la norma (per maggiori dettagli, +leggete la sezione "C Extensions" nella pagina info di GCC - Sì, davvero +la pagina info, la pagina man è solo un breve riassunto delle cose nella +pagina info). + +- Funzioni inline + +- Istruzioni in espressioni (ie. il costrutto ({ and }) ). + +- Dichiarate attributi di una funzione / variabile / tipo + (__attribute__) + +- typeof + +- Array con lunghezza zero + +- Macro varargs + +- Aritmentica sui puntatori void + +- Inizializzatori non costanti + +- Istruzioni assembler (non al di fuori di 'arch/' e 'include/asm/') + +- Nomi delle funzioni come stringhe (__func__). + +- __builtin_constant_p() + +Siate sospettosi quando utilizzate long long nel kernel, il codice generato +da gcc è orribile ed anche peggio: le divisioni e le moltiplicazioni non +funzionano sulle piattaforme i386 perché le rispettive funzioni di runtime +di GCC non sono incluse nell'ambiente del kernel. + +C++ +--- + +Solitamente utilizzare il C++ nel kernel è una cattiva idea perché +il kernel non fornisce il necessario ambiente di runtime e gli header file +non sono stati verificati. Rimane comunque possibile, ma non consigliato. +Se davvero volete usarlo, almeno evitate le eccezioni. + +NUMif +----- + +Viene generalmente considerato più pulito l'uso delle macro negli header file +(o all'inizio dei file .c) per astrarre funzioni piuttosto che utlizzare +l'istruzione di pre-processore \`#if' all'interno del codice sorgente. + +Mettere le vostre cose nel kernel +================================= + +Al fine d'avere le vostre cose in ordine per l'inclusione ufficiale, o +anche per avere patch pulite, c'è del lavoro amministrativo da fare: + +- Trovare chi è responsabile del codice che state modificando. Guardare in cima + ai file sorgenti, all'interno del file ``MAINTAINERS``, ed alla fine + di tutti nel file ``CREDITS``. Dovreste coordinarvi con queste persone + per evitare di duplicare gli sforzi, o provare qualcosa che è già stato + rigettato. + + Assicuratevi di mettere il vostro nome ed indirizzo email in cima a + tutti i file che create o che maneggiate significativamente. Questo è + il primo posto dove le persone guarderanno quando troveranno un baco, + o quando **loro** vorranno fare una modifica. + +- Solitamente vorrete un'opzione di configurazione per la vostra modifica + al kernel. Modificate ``Kconfig`` nella cartella giusta. Il linguaggio + Config è facile con copia ed incolla, e c'è una completa documentazione + nel file ``Documentation/kbuild/kconfig-language.rst``. + + Nella descrizione della vostra opzione, assicuratevi di parlare sia agli + utenti esperti sia agli utente che non sanno nulla del vostro lavoro. + Menzionate qui le incompatibilità ed i problemi. Chiaramente la + descrizione deve terminare con “if in doubt, say N” (se siete in dubbio, + dite N) (oppure, occasionalmente, \`Y'); questo è per le persone che non + hanno idea di che cosa voi stiate parlando. + +- Modificate il file ``Makefile``: le variabili CONFIG sono esportate qui, + quindi potete solitamente aggiungere una riga come la seguete + "obj-$(CONFIG_xxx) += xxx.o". La sintassi è documentata nel file + ``Documentation/kbuild/makefiles.rst``. + +- Aggiungete voi stessi in ``CREDITS`` se credete di aver fatto qualcosa di + notevole, solitamente qualcosa che supera il singolo file (comunque il vostro + nome dovrebbe essere all'inizio dei file sorgenti). ``MAINTAINERS`` significa + che volete essere consultati quando vengono fatte delle modifiche ad un + sottosistema, e quando ci sono dei bachi; questo implica molto di più di un + semplice impegno su una parte del codice. + +- Infine, non dimenticatevi di leggere + ``Documentation/process/submitting-patches.rst``. + +Trucchetti del kernel +===================== + +Dopo una rapida occhiata al codice, questi sono i preferiti. Sentitevi liberi +di aggiungerne altri. + +``arch/x86/include/asm/delay.h``:: + + #define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ + __ndelay(n)) + + +``include/linux/fs.h``:: + + /* + * Kernel pointers have redundant information, so we can use a + * scheme where we can return either an error code or a dentry + * pointer with the same return value. + * + * This should be a per-architecture thing, to allow different + * error and pointer decisions. + */ + #define ERR_PTR(err) ((void *)((long)(err))) + #define PTR_ERR(ptr) ((long)(ptr)) + #define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000)) + +``arch/x86/include/asm/uaccess_32.h:``:: + + #define copy_to_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_to_user((to),(from),(n)) : \ + __generic_copy_to_user((to),(from),(n))) + + +``arch/sparc/kernel/head.S:``:: + + /* + * Sun people can't spell worth damn. "compatability" indeed. + * At least we *know* we can't spell, and use a spell-checker. + */ + + /* Uh, actually Linus it is I who cannot spell. Too much murky + * Sparc assembly will do this to ya. + */ + C_LABEL(cputypvar): + .asciz "compatibility" + + /* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ + .align 4 + C_LABEL(cputypvar_sun4m): + .asciz "compatible" + + +``arch/sparc/lib/checksum.S:``:: + + /* Sun, you just can't beat me, you just can't. Stop trying, + * give up. I'm serious, I am going to kick the living shit + * out of you, game over, lights out. + */ + + +Ringraziamenti +============== + +Ringrazio Andi Kleen per le sue idee, le risposte alle mie domande, +le correzioni dei miei errori, l'aggiunta di contenuti, eccetera. +Philipp Rumpf per l'ortografia e per aver reso più chiaro il testo, e +per alcuni eccellenti punti tutt'altro che ovvi. Werner Almesberger +per avermi fornito un ottimo riassunto di :c:func:`disable_irq()`, +e Jes Sorensen e Andrea Arcangeli per le precisazioni. Michael Elizabeth +Chastain per aver verificato ed aggiunto la sezione configurazione. +Telsa Gwynne per avermi insegnato DocBook. diff --git a/Documentation/translations/it_IT/kernel-hacking/index.rst b/Documentation/translations/it_IT/kernel-hacking/index.rst new file mode 100644 index 0000000000..50228380bd --- /dev/null +++ b/Documentation/translations/it_IT/kernel-hacking/index.rst @@ -0,0 +1,16 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/kernel-hacking/index.rst <kernel_hacking>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_kernel_hacking: + +============================ +Guida all'hacking del kernel +============================ + +.. toctree:: + :maxdepth: 2 + + hacking + locking diff --git a/Documentation/translations/it_IT/kernel-hacking/locking.rst b/Documentation/translations/it_IT/kernel-hacking/locking.rst new file mode 100644 index 0000000000..4c21cf60f7 --- /dev/null +++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst @@ -0,0 +1,1498 @@ +.. include:: ../disclaimer-ita.rst + +.. c:namespace:: it_IT + +:Original: :ref:`Documentation/kernel-hacking/locking.rst <kernel_hacking_lock>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_kernel_hacking_lock: + +========================================== +L'inaffidabile guida alla sincronizzazione +========================================== + +:Author: Rusty Russell + +Introduzione +============ + +Benvenuto, alla notevole ed inaffidabile guida ai problemi di sincronizzazione +(locking) nel kernel. Questo documento descrive il sistema di sincronizzazione +nel kernel Linux 2.6. + +Dato il largo utilizzo del multi-threading e della prelazione nel kernel +Linux, chiunque voglia dilettarsi col kernel deve conoscere i concetti +fondamentali della concorrenza e della sincronizzazione nei sistemi +multi-processore. + +Il problema con la concorrenza +============================== + +(Saltatelo se sapete già cos'è una corsa critica). + +In un normale programma, potete incrementare un contatore nel seguente modo: + +:: + + contatore++; + +Questo è quello che vi aspettereste che accada sempre: + + +.. table:: Risultati attesi + + +------------------------------------+------------------------------------+ + | Istanza 1 | Istanza 2 | + +====================================+====================================+ + | leggi contatore (5) | | + +------------------------------------+------------------------------------+ + | aggiungi 1 (6) | | + +------------------------------------+------------------------------------+ + | scrivi contatore (6) | | + +------------------------------------+------------------------------------+ + | | leggi contatore (6) | + +------------------------------------+------------------------------------+ + | | aggiungi 1 (7) | + +------------------------------------+------------------------------------+ + | | scrivi contatore (7) | + +------------------------------------+------------------------------------+ + +Questo è quello che potrebbe succedere in realtà: + +.. table:: Possibile risultato + + +------------------------------------+------------------------------------+ + | Istanza 1 | Istanza 2 | + +====================================+====================================+ + | leggi contatore (5) | | + +------------------------------------+------------------------------------+ + | | leggi contatore (5) | + +------------------------------------+------------------------------------+ + | aggiungi 1 (6) | | + +------------------------------------+------------------------------------+ + | | aggiungi 1 (6) | + +------------------------------------+------------------------------------+ + | scrivi contatore (6) | | + +------------------------------------+------------------------------------+ + | | scrivi contatore (6) | + +------------------------------------+------------------------------------+ + + +Corse critiche e sezioni critiche +--------------------------------- + +Questa sovrapposizione, ovvero quando un risultato dipende dal tempo che +intercorre fra processi diversi, è chiamata corsa critica. La porzione +di codice che contiene questo problema è chiamata sezione critica. +In particolar modo da quando Linux ha incominciato a girare su +macchine multi-processore, le sezioni critiche sono diventate uno dei +maggiori problemi di progettazione ed implementazione del kernel. + +La prelazione può sortire gli stessi effetti, anche se c'è una sola CPU: +interrompendo un processo nella sua sezione critica otterremo comunque +la stessa corsa critica. In questo caso, il thread che si avvicenda +nell'esecuzione potrebbe eseguire anch'esso la sezione critica. + +La soluzione è quella di riconoscere quando avvengono questi accessi +simultanei, ed utilizzare i *lock* per accertarsi che solo un'istanza +per volta possa entrare nella sezione critica. Il kernel offre delle buone +funzioni a questo scopo. E poi ci sono quelle meno buone, ma farò finta +che non esistano. + +Sincronizzazione nel kernel Linux +================================= + +Se dovessi darvi un suggerimento sulla sincronizzazione: **mantenetela +semplice**. + +Siate riluttanti nell'introduzione di nuovi *lock*. + +I due principali tipi di *lock* nel kernel: spinlock e mutex +------------------------------------------------------------ + +Ci sono due tipi principali di *lock* nel kernel. Il tipo fondamentale è lo +spinlock (``include/asm/spinlock.h``), un semplice *lock* che può essere +trattenuto solo da un processo: se non si può trattenere lo spinlock, allora +rimane in attesa attiva (in inglese *spinning*) finché non ci riesce. +Gli spinlock sono molto piccoli e rapidi, possono essere utilizzati ovunque. + +Il secondo tipo è il mutex (``include/linux/mutex.h``): è come uno spinlock, +ma potreste bloccarvi trattenendolo. Se non potete trattenere un mutex +il vostro processo si auto-sospenderà; verrà riattivato quando il mutex +verrà rilasciato. Questo significa che il processore potrà occuparsi d'altro +mentre il vostro processo è in attesa. Esistono molti casi in cui non potete +permettervi di sospendere un processo (vedere +`Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni?`_) +e quindi dovrete utilizzare gli spinlock. + +Nessuno di questi *lock* è ricorsivo: vedere +`Stallo: semplice ed avanzato`_ + +I *lock* e i kernel per sistemi monoprocessore +---------------------------------------------- + +Per i kernel compilati senza ``CONFIG_SMP`` e senza ``CONFIG_PREEMPT`` +gli spinlock non esistono. Questa è un'ottima scelta di progettazione: +quando nessun altro processo può essere eseguito in simultanea, allora +non c'è la necessità di avere un *lock*. + +Se il kernel è compilato senza ``CONFIG_SMP`` ma con ``CONFIG_PREEMPT``, +allora gli spinlock disabilitano la prelazione; questo è sufficiente a +prevenire le corse critiche. Nella maggior parte dei casi, possiamo considerare +la prelazione equivalente ad un sistema multi-processore senza preoccuparci +di trattarla indipendentemente. + +Dovreste verificare sempre la sincronizzazione con le opzioni ``CONFIG_SMP`` e +``CONFIG_PREEMPT`` abilitate, anche quando non avete un sistema +multi-processore, questo vi permetterà di identificare alcuni problemi +di sincronizzazione. + +Come vedremo di seguito, i mutex continuano ad esistere perché sono necessari +per la sincronizzazione fra processi in contesto utente. + +Sincronizzazione in contesto utente +----------------------------------- + +Se avete una struttura dati che verrà utilizzata solo dal contesto utente, +allora, per proteggerla, potete utilizzare un semplice mutex +(``include/linux/mutex.h``). Questo è il caso più semplice: inizializzate il +mutex; invocate mutex_lock_interruptible() per trattenerlo e +mutex_unlock() per rilasciarlo. C'è anche mutex_lock() +ma questa dovrebbe essere evitata perché non ritorna in caso di segnali. + +Per esempio: ``net/netfilter/nf_sockopt.c`` permette la registrazione +di nuove chiamate per setsockopt() e getsockopt() +usando la funzione nf_register_sockopt(). La registrazione e +la rimozione vengono eseguite solamente quando il modulo viene caricato +o scaricato (e durante l'avvio del sistema, qui non abbiamo concorrenza), +e la lista delle funzioni registrate viene consultata solamente quando +setsockopt() o getsockopt() sono sconosciute al sistema. +In questo caso ``nf_sockopt_mutex`` è perfetto allo scopo, in particolar modo +visto che setsockopt e getsockopt potrebbero dormire. + +Sincronizzazione fra il contesto utente e i softirq +--------------------------------------------------- + +Se un softirq condivide dati col contesto utente, avete due problemi. +Primo, il contesto utente corrente potrebbe essere interroto da un softirq, +e secondo, la sezione critica potrebbe essere eseguita da un altro +processore. Questo è quando spin_lock_bh() +(``include/linux/spinlock.h``) viene utilizzato. Questo disabilita i softirq +sul processore e trattiene il *lock*. Invece, spin_unlock_bh() fa +l'opposto. (Il suffisso '_bh' è un residuo storico che fa riferimento al +"Bottom Halves", il vecchio nome delle interruzioni software. In un mondo +perfetto questa funzione si chiamerebbe 'spin_lock_softirq()'). + +Da notare che in questo caso potete utilizzare anche spin_lock_irq() +o spin_lock_irqsave(), queste fermano anche le interruzioni hardware: +vedere `Contesto di interruzione hardware`_. + +Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock +svaniscono e questa macro diventa semplicemente local_bh_disable() +(``include/linux/interrupt.h``), la quale impedisce ai softirq d'essere +eseguiti. + +Sincronizzazione fra contesto utente e i tasklet +------------------------------------------------ + +Questo caso è uguale al precedente, un tasklet viene eseguito da un softirq. + +Sincronizzazione fra contesto utente e i timer +---------------------------------------------- + +Anche questo caso è uguale al precedente, un timer viene eseguito da un +softirq. +Dal punto di vista della sincronizzazione, tasklet e timer sono identici. + +Sincronizzazione fra tasklet e timer +------------------------------------ + +Qualche volta un tasklet od un timer potrebbero condividere i dati con +un altro tasklet o timer + +Lo stesso tasklet/timer +~~~~~~~~~~~~~~~~~~~~~~~ + +Dato che un tasklet non viene mai eseguito contemporaneamente su due +processori, non dovete preoccuparvi che sia rientrante (ovvero eseguito +più volte in contemporanea), perfino su sistemi multi-processore. + +Differenti tasklet/timer +~~~~~~~~~~~~~~~~~~~~~~~~ + +Se un altro tasklet/timer vuole condividere dati col vostro tasklet o timer, +allora avrete bisogno entrambe di spin_lock() e +spin_unlock(). Qui spin_lock_bh() è inutile, siete già +in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo +stesso processore. + +Sincronizzazione fra softirq +---------------------------- + +Spesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer. + +Lo stesso softirq +~~~~~~~~~~~~~~~~~ + +Lo stesso softirq può essere eseguito su un diverso processore: allo scopo +di migliorare le prestazioni potete utilizzare dati riservati ad ogni +processore (vedere `Dati per processore`_). Se siete arrivati +fino a questo punto nell'uso dei softirq, probabilmente tenete alla scalabilità +delle prestazioni abbastanza da giustificarne la complessità aggiuntiva. + +Dovete utilizzare spin_lock() e spin_unlock() per +proteggere i dati condivisi. + +Diversi Softirqs +~~~~~~~~~~~~~~~~ + +Dovete utilizzare spin_lock() e spin_unlock() per +proteggere i dati condivisi, che siano timer, tasklet, diversi softirq o +lo stesso o altri softirq: uno qualsiasi di essi potrebbe essere in esecuzione +su un diverso processore. + +.. _`it_hardirq-context`: + +Contesto di interruzione hardware +================================= + +Solitamente le interruzioni hardware comunicano con un tasklet o un softirq. +Spesso questo si traduce nel mettere in coda qualcosa da fare che verrà +preso in carico da un softirq. + +Sincronizzazione fra interruzioni hardware e softirq/tasklet +------------------------------------------------------------ + +Se un gestore di interruzioni hardware condivide dati con un softirq, allora +avrete due preoccupazioni. Primo, il softirq può essere interrotto da +un'interruzione hardware, e secondo, la sezione critica potrebbe essere +eseguita da un'interruzione hardware su un processore diverso. Questo è il caso +dove spin_lock_irq() viene utilizzato. Disabilita le interruzioni +sul processore che l'esegue, poi trattiene il lock. spin_unlock_irq() +fa l'opposto. + +Il gestore d'interruzione hardware non ha bisogno di usare spin_lock_irq() +perché i softirq non possono essere eseguiti quando il gestore d'interruzione +hardware è in esecuzione: per questo si può usare spin_lock(), che è un po' +più veloce. L'unica eccezione è quando un altro gestore d'interruzioni +hardware utilizza lo stesso *lock*: spin_lock_irq() impedirà a questo +secondo gestore di interrompere quello in esecuzione. + +Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock +svaniscono e questa macro diventa semplicemente local_irq_disable() +(``include/asm/smp.h``), la quale impedisce a softirq/tasklet/BH d'essere +eseguiti. + +spin_lock_irqsave() (``include/linux/spinlock.h``) è una variante che +salva lo stato delle interruzioni in una variabile, questa verrà poi passata +a spin_unlock_irqrestore(). Questo significa che lo stesso codice +potrà essere utilizzato in un'interruzione hardware (dove le interruzioni sono +già disabilitate) e in un softirq (dove la disabilitazione delle interruzioni +è richiesta). + +Da notare che i softirq (e quindi tasklet e timer) sono eseguiti al ritorno +da un'interruzione hardware, quindi spin_lock_irq() interrompe +anche questi. Tenuto conto di questo si può dire che +spin_lock_irqsave() è la funzione di sincronizzazione più generica +e potente. + +Sincronizzazione fra due gestori d'interruzioni hardware +-------------------------------------------------------- + +Condividere dati fra due gestori di interruzione hardware è molto raro, ma se +succede, dovreste usare spin_lock_irqsave(): è una specificità +dell'architettura il fatto che tutte le interruzioni vengano interrotte +quando si eseguono di gestori di interruzioni. + +Bigino della sincronizzazione +============================= + +Pete Zaitcev ci offre il seguente riassunto: + +- Se siete in un contesto utente (una qualsiasi chiamata di sistema) + e volete sincronizzarvi con altri processi, usate i mutex. Potete trattenere + il mutex e dormire (``copy_from_user(`` o ``kmalloc(x,GFP_KERNEL)``). + +- Altrimenti (== i dati possono essere manipolati da un'interruzione) usate + spin_lock_irqsave() e spin_unlock_irqrestore(). + +- Evitate di trattenere uno spinlock per più di 5 righe di codice incluse + le chiamate a funzione (ad eccezione di quell per l'accesso come + readb()). + +Tabella dei requisiti minimi +---------------------------- + +La tabella seguente illustra i requisiti **minimi** per la sincronizzazione fra +diversi contesti. In alcuni casi, lo stesso contesto può essere eseguito solo +da un processore per volta, quindi non ci sono requisiti per la +sincronizzazione (per esempio, un thread può essere eseguito solo su un +processore alla volta, ma se deve condividere dati con un altro thread, allora +la sincronizzazione è necessaria). + +Ricordatevi il suggerimento qui sopra: potete sempre usare +spin_lock_irqsave(), che è un sovrainsieme di tutte le altre funzioni +per spinlock. + +============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== +. IRQ Handler A IRQ Handler B Softirq A Softirq B Tasklet A Tasklet B Timer A Timer B User Context A User Context B +============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== +IRQ Handler A None +IRQ Handler B SLIS None +Softirq A SLI SLI SL +Softirq B SLI SLI SL SL +Tasklet A SLI SLI SL SL None +Tasklet B SLI SLI SL SL SL None +Timer A SLI SLI SL SL SL SL None +Timer B SLI SLI SL SL SL SL SL None +User Context A SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH None +User Context B SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH MLI None +============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== + +Table: Tabella dei requisiti per la sincronizzazione + ++--------+----------------------------+ +| SLIS | spin_lock_irqsave | ++--------+----------------------------+ +| SLI | spin_lock_irq | ++--------+----------------------------+ +| SL | spin_lock | ++--------+----------------------------+ +| SLBH | spin_lock_bh | ++--------+----------------------------+ +| MLI | mutex_lock_interruptible | ++--------+----------------------------+ + +Table: Legenda per la tabella dei requisiti per la sincronizzazione + +Le funzioni *trylock* +===================== + +Ci sono funzioni che provano a trattenere un *lock* solo una volta e +ritornano immediatamente comunicato il successo od il fallimento +dell'operazione. Posso essere usate quando non serve accedere ai dati +protetti dal *lock* quando qualche altro thread lo sta già facendo +trattenendo il *lock*. Potrete acquisire il *lock* più tardi se vi +serve accedere ai dati protetti da questo *lock*. + +La funzione spin_trylock() non ritenta di acquisire il *lock*, +se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti +se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque +contesto, ma come spin_lock(): dovete disabilitare i contesti che +potrebbero interrompervi e quindi trattenere lo spinlock. + +La funzione mutex_trylock() invece di sospendere il vostro processo +ritorna un valore diverso da zero se è possibile trattenere il lock al primo +colpo, altrimenti se fallisce ritorna 0. Nonostante non dorma, questa funzione +non può essere usata in modo sicuro in contesti di interruzione hardware o +software. + +Esempi più comuni +================= + +Guardiamo un semplice esempio: una memoria che associa nomi a numeri. +La memoria tiene traccia di quanto spesso viene utilizzato ogni oggetto; +quando è piena, l'oggetto meno usato viene eliminato. + +Tutto in contesto utente +------------------------ + +Nel primo esempio, supponiamo che tutte le operazioni avvengano in contesto +utente (in soldoni, da una chiamata di sistema), quindi possiamo dormire. +Questo significa che possiamo usare i mutex per proteggere la nostra memoria +e tutti gli oggetti che contiene. Ecco il codice:: + + #include <linux/list.h> + #include <linux/slab.h> + #include <linux/string.h> + #include <linux/mutex.h> + #include <asm/errno.h> + + struct object + { + struct list_head list; + int id; + char name[32]; + int popularity; + }; + + /* Protects the cache, cache_num, and the objects within it */ + static DEFINE_MUTEX(cache_lock); + static LIST_HEAD(cache); + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + + /* Must be holding cache_lock */ + static struct object *__cache_find(int id) + { + struct object *i; + + list_for_each_entry(i, &cache, list) + if (i->id == id) { + i->popularity++; + return i; + } + return NULL; + } + + /* Must be holding cache_lock */ + static void __cache_delete(struct object *obj) + { + BUG_ON(!obj); + list_del(&obj->list); + kfree(obj); + cache_num--; + } + + /* Must be holding cache_lock */ + static void __cache_add(struct object *obj) + { + list_add(&obj->list, &cache); + if (++cache_num > MAX_CACHE_SIZE) { + struct object *i, *outcast = NULL; + list_for_each_entry(i, &cache, list) { + if (!outcast || i->popularity < outcast->popularity) + outcast = i; + } + __cache_delete(outcast); + } + } + + int cache_add(int id, const char *name) + { + struct object *obj; + + if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) + return -ENOMEM; + + strscpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; + + mutex_lock(&cache_lock); + __cache_add(obj); + mutex_unlock(&cache_lock); + return 0; + } + + void cache_delete(int id) + { + mutex_lock(&cache_lock); + __cache_delete(__cache_find(id)); + mutex_unlock(&cache_lock); + } + + int cache_find(int id, char *name) + { + struct object *obj; + int ret = -ENOENT; + + mutex_lock(&cache_lock); + obj = __cache_find(id); + if (obj) { + ret = 0; + strcpy(name, obj->name); + } + mutex_unlock(&cache_lock); + return ret; + } + +Da notare che ci assicuriamo sempre di trattenere cache_lock quando +aggiungiamo, rimuoviamo od ispezioniamo la memoria: sia la struttura +della memoria che il suo contenuto sono protetti dal *lock*. Questo +caso è semplice dato che copiamo i dati dall'utente e non permettiamo +mai loro di accedere direttamente agli oggetti. + +C'è una piccola ottimizzazione qui: nella funzione cache_add() +impostiamo i campi dell'oggetto prima di acquisire il *lock*. Questo è +sicuro perché nessun altro potrà accedervi finché non lo inseriremo +nella memoria. + +Accesso dal contesto utente +--------------------------- + +Ora consideriamo il caso in cui cache_find() può essere invocata +dal contesto d'interruzione: sia hardware che software. Un esempio potrebbe +essere un timer che elimina oggetti dalla memoria. + +Qui di seguito troverete la modifica nel formato *patch*: le righe ``-`` +sono quelle rimosse, mentre quelle ``+`` sono quelle aggiunte. + +:: + + --- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 + +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 + @@ -12,7 +12,7 @@ + int popularity; + }; + + -static DEFINE_MUTEX(cache_lock); + +static DEFINE_SPINLOCK(cache_lock); + static LIST_HEAD(cache); + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + @@ -55,6 +55,7 @@ + int cache_add(int id, const char *name) + { + struct object *obj; + + unsigned long flags; + + if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) + return -ENOMEM; + @@ -63,30 +64,33 @@ + obj->id = id; + obj->popularity = 0; + + - mutex_lock(&cache_lock); + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); + - mutex_unlock(&cache_lock); + + spin_unlock_irqrestore(&cache_lock, flags); + return 0; + } + + void cache_delete(int id) + { + - mutex_lock(&cache_lock); + + unsigned long flags; + + + + spin_lock_irqsave(&cache_lock, flags); + __cache_delete(__cache_find(id)); + - mutex_unlock(&cache_lock); + + spin_unlock_irqrestore(&cache_lock, flags); + } + + int cache_find(int id, char *name) + { + struct object *obj; + int ret = -ENOENT; + + unsigned long flags; + + - mutex_lock(&cache_lock); + + spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); + if (obj) { + ret = 0; + strcpy(name, obj->name); + } + - mutex_unlock(&cache_lock); + + spin_unlock_irqrestore(&cache_lock, flags); + return ret; + } + +Da notare che spin_lock_irqsave() disabiliterà le interruzioni +se erano attive, altrimenti non farà niente (quando siamo già in un contesto +d'interruzione); dunque queste funzioni possono essere chiamante in +sicurezza da qualsiasi contesto. + +Sfortunatamente, cache_add() invoca kmalloc() con +l'opzione ``GFP_KERNEL`` che è permessa solo in contesto utente. Ho supposto +che cache_add() venga chiamata dal contesto utente, altrimenti +questa opzione deve diventare un parametro di cache_add(). + +Esporre gli oggetti al di fuori del file +---------------------------------------- + +Se i vostri oggetti contengono più informazioni, potrebbe non essere +sufficiente copiare i dati avanti e indietro: per esempio, altre parti del +codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli +ogni volta. Questo introduce due problemi. + +Il primo problema è che utilizziamo ``cache_lock`` per proteggere gli oggetti: +dobbiamo renderlo dinamico così che il resto del codice possa usarlo. Questo +rende la sincronizzazione più complicata dato che non avviene più in un unico +posto. + +Il secondo problema è il problema del ciclo di vita: se un'altra struttura +mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo +puntatore rimanga valido. Sfortunatamente, questo è garantito solo mentre +si trattiene il *lock*, altrimenti qualcuno potrebbe chiamare +cache_delete() o peggio, aggiungere un oggetto che riutilizza lo +stesso indirizzo. + +Dato che c'è un solo *lock*, non potete trattenerlo a vita: altrimenti +nessun altro potrà eseguire il proprio lavoro. + +La soluzione a questo problema è l'uso di un contatore di riferimenti: +chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo +quando il puntatore non viene più usato. Quando il contatore raggiunge lo zero +significa che non è più usato e l'oggetto può essere rimosso. + +Ecco il codice:: + + --- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 + +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 + @@ -7,6 +7,7 @@ + struct object + { + struct list_head list; + + unsigned int refcnt; + int id; + char name[32]; + int popularity; + @@ -17,6 +18,35 @@ + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + + +static void __object_put(struct object *obj) + +{ + + if (--obj->refcnt == 0) + + kfree(obj); + +} + + + +static void __object_get(struct object *obj) + +{ + + obj->refcnt++; + +} + + + +void object_put(struct object *obj) + +{ + + unsigned long flags; + + + + spin_lock_irqsave(&cache_lock, flags); + + __object_put(obj); + + spin_unlock_irqrestore(&cache_lock, flags); + +} + + + +void object_get(struct object *obj) + +{ + + unsigned long flags; + + + + spin_lock_irqsave(&cache_lock, flags); + + __object_get(obj); + + spin_unlock_irqrestore(&cache_lock, flags); + +} + + + /* Must be holding cache_lock */ + static struct object *__cache_find(int id) + { + @@ -35,6 +65,7 @@ + { + BUG_ON(!obj); + list_del(&obj->list); + + __object_put(obj); + cache_num--; + } + + @@ -63,6 +94,7 @@ + strscpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; + + obj->refcnt = 1; /* The cache holds a reference */ + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); + @@ -79,18 +111,15 @@ + spin_unlock_irqrestore(&cache_lock, flags); + } + + -int cache_find(int id, char *name) + +struct object *cache_find(int id) + { + struct object *obj; + - int ret = -ENOENT; + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); + - if (obj) { + - ret = 0; + - strcpy(name, obj->name); + - } + + if (obj) + + __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); + - return ret; + + return obj; + } + +Abbiamo incapsulato il contatore di riferimenti nelle tipiche funzioni +di 'get' e 'put'. Ora possiamo ritornare l'oggetto da cache_find() +col vantaggio che l'utente può dormire trattenendo l'oggetto (per esempio, +copy_to_user() per copiare il nome verso lo spazio utente). + +Un altro punto da notare è che ho detto che il contatore dovrebbe incrementarsi +per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1 +quando l'oggetto viene inserito nella memoria. In altre versione il framework +non trattiene un riferimento per se, ma diventa più complicato. + +Usare operazioni atomiche per il contatore di riferimenti +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In sostanza, :c:type:`atomic_t` viene usato come contatore di riferimenti. +Ci sono un certo numbero di operazioni atomiche definite +in ``include/asm/atomic.h``: queste sono garantite come atomiche su qualsiasi +processore del sistema, quindi non sono necessari i *lock*. In questo caso è +più semplice rispetto all'uso degli spinlock, benché l'uso degli spinlock +sia più elegante per casi non banali. Le funzioni atomic_inc() e +atomic_dec_and_test() vengono usate al posto dei tipici operatori di +incremento e decremento, e i *lock* non sono più necessari per proteggere il +contatore stesso. + +:: + + --- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 + +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 + @@ -7,7 +7,7 @@ + struct object + { + struct list_head list; + - unsigned int refcnt; + + atomic_t refcnt; + int id; + char name[32]; + int popularity; + @@ -18,33 +18,15 @@ + static unsigned int cache_num = 0; + #define MAX_CACHE_SIZE 10 + + -static void __object_put(struct object *obj) + -{ + - if (--obj->refcnt == 0) + - kfree(obj); + -} + - + -static void __object_get(struct object *obj) + -{ + - obj->refcnt++; + -} + - + void object_put(struct object *obj) + { + - unsigned long flags; + - + - spin_lock_irqsave(&cache_lock, flags); + - __object_put(obj); + - spin_unlock_irqrestore(&cache_lock, flags); + + if (atomic_dec_and_test(&obj->refcnt)) + + kfree(obj); + } + + void object_get(struct object *obj) + { + - unsigned long flags; + - + - spin_lock_irqsave(&cache_lock, flags); + - __object_get(obj); + - spin_unlock_irqrestore(&cache_lock, flags); + + atomic_inc(&obj->refcnt); + } + + /* Must be holding cache_lock */ + @@ -65,7 +47,7 @@ + { + BUG_ON(!obj); + list_del(&obj->list); + - __object_put(obj); + + object_put(obj); + cache_num--; + } + + @@ -94,7 +76,7 @@ + strscpy(obj->name, name, sizeof(obj->name)); + obj->id = id; + obj->popularity = 0; + - obj->refcnt = 1; /* The cache holds a reference */ + + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); + @@ -119,7 +101,7 @@ + spin_lock_irqsave(&cache_lock, flags); + obj = __cache_find(id); + if (obj) + - __object_get(obj); + + object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); + return obj; + } + +Proteggere l'oggetto stesso +--------------------------- + +In questo esempio, assumiamo che gli oggetti (ad eccezione del contatore +di riferimenti) non cambino mai dopo la loro creazione. Se vogliamo permettere +al nome di cambiare abbiamo tre possibilità: + +- Si può togliere static da ``cache_lock`` e dire agli utenti che devono + trattenere il *lock* prima di modificare il nome di un oggetto. + +- Si può fornire una funzione cache_obj_rename() che prende il + *lock* e cambia il nome per conto del chiamante; si dirà poi agli utenti + di usare questa funzione. + +- Si può decidere che ``cache_lock`` protegge solo la memoria stessa, ed + un altro *lock* è necessario per la protezione del nome. + +Teoricamente, possiamo avere un *lock* per ogni campo e per ogni oggetto. +In pratica, le varianti più comuni sono: + +- un *lock* che protegge l'infrastruttura (la lista ``cache`` di questo + esempio) e gli oggetti. Questo è quello che abbiamo fatto finora. + +- un *lock* che protegge l'infrastruttura (inclusi i puntatori alla lista + negli oggetti), e un *lock* nell'oggetto per proteggere il resto + dell'oggetto stesso. + +- *lock* multipli per proteggere l'infrastruttura (per esempio un *lock* + per ogni lista), possibilmente con un *lock* per oggetto. + +Qui di seguito un'implementazione con "un lock per oggetto": + +:: + + --- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 + +++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 + @@ -6,11 +6,17 @@ + + struct object + { + + /* These two protected by cache_lock. */ + struct list_head list; + + int popularity; + + + atomic_t refcnt; + + + + /* Doesn't change once created. */ + int id; + + + + spinlock_t lock; /* Protects the name */ + char name[32]; + - int popularity; + }; + + static DEFINE_SPINLOCK(cache_lock); + @@ -77,6 +84,7 @@ + obj->id = id; + obj->popularity = 0; + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + + spin_lock_init(&obj->lock); + + spin_lock_irqsave(&cache_lock, flags); + __cache_add(obj); + +Da notare che ho deciso che il contatore di popolarità dovesse essere +protetto da ``cache_lock`` piuttosto che dal *lock* dell'oggetto; questo +perché è logicamente parte dell'infrastruttura (come +:c:type:`struct list_head <list_head>` nell'oggetto). In questo modo, +in __cache_add(), non ho bisogno di trattenere il *lock* di ogni +oggetto mentre si cerca il meno popolare. + +Ho anche deciso che il campo id è immutabile, quindi non ho bisogno di +trattenere il lock dell'oggetto quando si usa __cache_find() +per leggere questo campo; il *lock* dell'oggetto è usato solo dal chiamante +che vuole leggere o scrivere il campo name. + +Inoltre, da notare che ho aggiunto un commento che descrive i dati che sono +protetti dal *lock*. Questo è estremamente importante in quanto descrive il +comportamento del codice, che altrimenti sarebbe di difficile comprensione +leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”. + +Problemi comuni +=============== + +Stallo: semplice ed avanzato +---------------------------- + +Esiste un tipo di baco dove un pezzo di codice tenta di trattenere uno +spinlock due volte: questo rimarrà in attesa attiva per sempre aspettando che +il *lock* venga rilasciato (in Linux spinlocks, rwlocks e mutex non sono +ricorsivi). +Questo è facile da diagnosticare: non è uno di quei problemi che ti tengono +sveglio 5 notti a parlare da solo. + +Un caso un pochino più complesso; immaginate d'avere una spazio condiviso +fra un softirq ed il contesto utente. Se usate spin_lock() per +proteggerlo, il contesto utente potrebbe essere interrotto da un softirq +mentre trattiene il lock, da qui il softirq rimarrà in attesa attiva provando +ad acquisire il *lock* già trattenuto nel contesto utente. + +Questi casi sono chiamati stalli (*deadlock*), e come mostrato qui sopra, +può succedere anche con un solo processore (Ma non sui sistemi +monoprocessore perché gli spinlock spariscano quando il kernel è compilato +con ``CONFIG_SMP``\ =n. Nonostante ciò, nel secondo caso avrete comunque +una corruzione dei dati). + +Questi casi sono facili da diagnosticare; sui sistemi multi-processore +il supervisione (*watchdog*) o l'opzione di compilazione ``DEBUG_SPINLOCK`` +(``include/linux/spinlock.h``) permettono di scovare immediatamente quando +succedono. + +Esiste un caso più complesso che è conosciuto come l'abbraccio della morte; +questo coinvolge due o più *lock*. Diciamo che avete un vettore di hash in cui +ogni elemento è uno spinlock a cui è associata una lista di elementi con lo +stesso hash. In un gestore di interruzioni software, dovete modificare un +oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock +del vecchio hash e di quello nuovo, quindi rimuovere l'oggetto dal vecchio ed +inserirlo nel nuovo. + +Qui abbiamo due problemi. Primo, se il vostro codice prova a spostare un +oggetto all'interno della stessa lista, otterrete uno stallo visto che +tenterà di trattenere lo stesso *lock* due volte. Secondo, se la stessa +interruzione software su un altro processore sta tentando di spostare +un altro oggetto nella direzione opposta, potrebbe accadere quanto segue: + ++---------------------------------+---------------------------------+ +| CPU 1 | CPU 2 | ++=================================+=================================+ +| Trattiene *lock* A -> OK | Trattiene *lock* B -> OK | ++---------------------------------+---------------------------------+ +| Trattiene *lock* B -> attesa | Trattiene *lock* A -> attesa | ++---------------------------------+---------------------------------+ + +Table: Conseguenze + +Entrambe i processori rimarranno in attesa attiva sul *lock* per sempre, +aspettando che l'altro lo rilasci. Sembra e puzza come un blocco totale. + +Prevenire gli stalli +-------------------- + +I libri di testo vi diranno che se trattenete i *lock* sempre nello stesso +ordine non avrete mai un simile stallo. La pratica vi dirà che questo +approccio non funziona all'ingrandirsi del sistema: quando creo un nuovo +*lock* non ne capisco abbastanza del kernel per dire in quale dei 5000 *lock* +si incastrerà. + +I *lock* migliori sono quelli incapsulati: non vengono esposti nei file di +intestazione, e non vengono mai trattenuti fuori dallo stesso file. Potete +rileggere questo codice e vedere che non ci sarà mai uno stallo perché +non tenterà mai di trattenere un altro *lock* quando lo ha già. +Le persone che usano il vostro codice non devono nemmeno sapere che voi +state usando dei *lock*. + +Un classico problema deriva dall'uso di *callback* e di *hook*: se li +chiamate mentre trattenete un *lock*, rischiate uno stallo o un abbraccio +della morte (chi lo sa cosa farà una *callback*?). + +Ossessiva prevenzione degli stalli +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Gli stalli sono un problema, ma non così terribile come la corruzione dei dati. +Un pezzo di codice trattiene un *lock* di lettura, cerca in una lista, +fallisce nel trovare quello che vuole, quindi rilascia il *lock* di lettura, +trattiene un *lock* di scrittura ed inserisce un oggetto; questo genere di +codice presenta una corsa critica. + +corsa fra temporizzatori: un passatempo del kernel +-------------------------------------------------- + +I temporizzatori potrebbero avere dei problemi con le corse critiche. +Considerate una collezione di oggetti (liste, hash, eccetera) dove ogni oggetto +ha un temporizzatore che sta per distruggerlo. + +Se volete eliminare l'intera collezione (diciamo quando rimuovete un modulo), +potreste fare come segue:: + + /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE + HUNGARIAN NOTATION */ + spin_lock_bh(&list_lock); + + while (list) { + struct foo *next = list->next; + timer_delete(&list->timer); + kfree(list); + list = next; + } + + spin_unlock_bh(&list_lock); + +Primo o poi, questo esploderà su un sistema multiprocessore perché un +temporizzatore potrebbe essere già partiro prima di spin_lock_bh(), +e prenderà il *lock* solo dopo spin_unlock_bh(), e cercherà +di eliminare il suo oggetto (che però è già stato eliminato). + +Questo può essere evitato controllando il valore di ritorno di +timer_delete(): se ritorna 1, il temporizzatore è stato già +rimosso. Se 0, significa (in questo caso) che il temporizzatore è in +esecuzione, quindi possiamo fare come segue:: + + retry: + spin_lock_bh(&list_lock); + + while (list) { + struct foo *next = list->next; + if (!timer_delete(&list->timer)) { + /* Give timer a chance to delete this */ + spin_unlock_bh(&list_lock); + goto retry; + } + kfree(list); + list = next; + } + + spin_unlock_bh(&list_lock); + +Un altro problema è l'eliminazione dei temporizzatori che si riavviano +da soli (chiamando add_timer() alla fine della loro esecuzione). +Dato che questo è un problema abbastanza comune con una propensione +alle corse critiche, dovreste usare timer_delete_sync() +(``include/linux/timer.h``) per gestire questo caso. + +Prima di rilasciare un temporizzatore dovreste chiamare la funzione +timer_shutdown() o timer_shutdown_sync() di modo che non venga più riarmato. +Ogni successivo tentativo di riarmare il temporizzatore verrà silenziosamente +ignorato. + +Velocità della sincronizzazione +=============================== + +Ci sono tre cose importanti da tenere in considerazione quando si valuta +la velocità d'esecuzione di un pezzo di codice che necessita di +sincronizzazione. La prima è la concorrenza: quante cose rimangono in attesa +mentre qualcuno trattiene un *lock*. La seconda è il tempo necessario per +acquisire (senza contese) e rilasciare un *lock*. La terza è di usare meno +*lock* o di più furbi. Immagino che i *lock* vengano usati regolarmente, +altrimenti, non sareste interessati all'efficienza. + +La concorrenza dipende da quanto a lungo un *lock* è trattenuto: dovreste +trattenere un *lock* solo il tempo minimo necessario ma non un istante in più. +Nella memoria dell'esempio precedente, creiamo gli oggetti senza trattenere +il *lock*, poi acquisiamo il *lock* quando siamo pronti per inserirlo nella +lista. + +Il tempo di acquisizione di un *lock* dipende da quanto danno fa +l'operazione sulla *pipeline* (ovvero stalli della *pipeline*) e quant'è +probabile che il processore corrente sia stato anche l'ultimo ad acquisire +il *lock* (in pratica, il *lock* è nella memoria cache del processore +corrente?): su sistemi multi-processore questa probabilità precipita +rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo +esegue un'istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire +un *lock* che è nella memoria cache del processore richiede 160ns, e un +trasferimento dalla memoria cache di un altro processore richiede altri +170/360ns (Leggetevi l'articolo di Paul McKenney's `Linux Journal RCU +article <http://www.linuxjournal.com/article.php?sid=6993>`__). + +Questi due obiettivi sono in conflitto: trattenere un *lock* per il minor +tempo possibile potrebbe richiedere la divisione in più *lock* per diverse +parti (come nel nostro ultimo esempio con un *lock* per ogni oggetto), +ma questo aumenta il numero di acquisizioni di *lock*, ed il risultato +spesso è che tutto è più lento che con un singolo *lock*. Questo è un altro +argomento in favore della semplicità quando si parla di sincronizzazione. + +Il terzo punto è discusso di seguito: ci sono alcune tecniche per ridurre +il numero di sincronizzazioni che devono essere fatte. + +Read/Write Lock Variants +------------------------ + +Sia gli spinlock che i mutex hanno una variante per la lettura/scrittura +(read/write): ``rwlock_t`` e :c:type:`struct rw_semaphore <rw_semaphore>`. +Queste dividono gli utenti in due categorie: i lettori e gli scrittori. +Se state solo leggendo i dati, potete acquisire il *lock* di lettura, ma +per scrivere avrete bisogno del *lock* di scrittura. Molti possono trattenere +il *lock* di lettura, ma solo uno scrittore alla volta può trattenere +quello di scrittura. + +Se il vostro codice si divide chiaramente in codice per lettori e codice +per scrittori (come nel nostro esempio), e il *lock* dei lettori viene +trattenuto per molto tempo, allora l'uso di questo tipo di *lock* può aiutare. +Questi sono leggermente più lenti rispetto alla loro versione normale, quindi +nella pratica l'uso di ``rwlock_t`` non ne vale la pena. + +Evitare i *lock*: Read Copy Update +-------------------------------------------- + +Esiste un metodo di sincronizzazione per letture e scritture detto +Read Copy Update. Con l'uso della tecnica RCU, i lettori possono scordarsi +completamente di trattenere i *lock*; dato che nel nostro esempio ci +aspettiamo d'avere più lettore che scrittori (altrimenti questa memoria +sarebbe uno spreco) possiamo dire che questo meccanismo permette +un'ottimizzazione. + +Come facciamo a sbarazzarci dei *lock* di lettura? Sbarazzarsi dei *lock* di +lettura significa che uno scrittore potrebbe cambiare la lista sotto al naso +dei lettori. Questo è abbastanza semplice: possiamo leggere una lista +concatenata se lo scrittore aggiunge elementi alla fine e con certe +precauzioni. Per esempio, aggiungendo ``new`` ad una lista concatenata +chiamata ``list``:: + + new->next = list->next; + wmb(); + list->next = new; + +La funzione wmb() è una barriera di sincronizzazione delle +scritture. Questa garantisce che la prima operazione (impostare l'elemento +``next`` del nuovo elemento) venga completata e vista da tutti i processori +prima che venga eseguita la seconda operazione (che sarebbe quella di mettere +il nuovo elemento nella lista). Questo è importante perché i moderni +compilatori ed i moderni processori possono, entrambe, riordinare le istruzioni +se non vengono istruiti altrimenti: vogliamo che i lettori non vedano +completamente il nuovo elemento; oppure che lo vedano correttamente e quindi +il puntatore ``next`` deve puntare al resto della lista. + +Fortunatamente, c'è una funzione che fa questa operazione sulle liste +:c:type:`struct list_head <list_head>`: list_add_rcu() +(``include/linux/list.h``). + +Rimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore +al vecchio elemento con quello del suo successore, e i lettori vedranno +l'elemento o lo salteranno. + +:: + + list->next = old->next; + +La funzione list_del_rcu() (``include/linux/list.h``) fa esattamente +questo (la versione normale corrompe il vecchio oggetto, e non vogliamo che +accada). + +Anche i lettori devono stare attenti: alcuni processori potrebbero leggere +attraverso il puntatore ``next`` il contenuto dell'elemento successivo +troppo presto, ma non accorgersi che il contenuto caricato è sbagliato quando +il puntatore ``next`` viene modificato alla loro spalle. Ancora una volta +c'è una funzione che viene in vostro aiuto list_for_each_entry_rcu() +(``include/linux/list.h``). Ovviamente, gli scrittori possono usare +list_for_each_entry() dato che non ci possono essere due scrittori +in contemporanea. + +Il nostro ultimo dilemma è il seguente: quando possiamo realmente distruggere +l'elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo +elemento proprio ora: se eliminiamo questo elemento ed il puntatore ``next`` +cambia, il lettore salterà direttamente nella spazzatura e scoppierà. Dobbiamo +aspettare finché tutti i lettori che stanno attraversando la lista abbiano +finito. Utilizziamo call_rcu() per registrare una funzione di +richiamo che distrugga l'oggetto quando tutti i lettori correnti hanno +terminato. In alternative, potrebbe essere usata la funzione +synchronize_rcu() che blocca l'esecuzione finché tutti i lettori +non terminano di ispezionare la lista. + +Ma come fa l'RCU a sapere quando i lettori sono finiti? Il meccanismo è +il seguente: innanzi tutto i lettori accedono alla lista solo fra la coppia +rcu_read_lock()/rcu_read_unlock() che disabilita la +prelazione così che i lettori non vengano sospesi mentre stanno leggendo +la lista. + +Poi, l'RCU aspetta finché tutti i processori non abbiano dormito almeno +una volta; a questo punto, dato che i lettori non possono dormire, possiamo +dedurre che un qualsiasi lettore che abbia consultato la lista durante la +rimozione abbia già terminato, quindi la *callback* viene eseguita. Il vero +codice RCU è un po' più ottimizzato di così, ma questa è l'idea di fondo. + +:: + + --- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 + +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 + @@ -1,15 +1,18 @@ + #include <linux/list.h> + #include <linux/slab.h> + #include <linux/string.h> + +#include <linux/rcupdate.h> + #include <linux/mutex.h> + #include <asm/errno.h> + + struct object + { + - /* These two protected by cache_lock. */ + + /* This is protected by RCU */ + struct list_head list; + int popularity; + + + struct rcu_head rcu; + + + atomic_t refcnt; + + /* Doesn't change once created. */ + @@ -40,7 +43,7 @@ + { + struct object *i; + + - list_for_each_entry(i, &cache, list) { + + list_for_each_entry_rcu(i, &cache, list) { + if (i->id == id) { + i->popularity++; + return i; + @@ -49,19 +52,25 @@ + return NULL; + } + + +/* Final discard done once we know no readers are looking. */ + +static void cache_delete_rcu(void *arg) + +{ + + object_put(arg); + +} + + + /* Must be holding cache_lock */ + static void __cache_delete(struct object *obj) + { + BUG_ON(!obj); + - list_del(&obj->list); + - object_put(obj); + + list_del_rcu(&obj->list); + cache_num--; + + call_rcu(&obj->rcu, cache_delete_rcu); + } + + /* Must be holding cache_lock */ + static void __cache_add(struct object *obj) + { + - list_add(&obj->list, &cache); + + list_add_rcu(&obj->list, &cache); + if (++cache_num > MAX_CACHE_SIZE) { + struct object *i, *outcast = NULL; + list_for_each_entry(i, &cache, list) { + @@ -104,12 +114,11 @@ + struct object *cache_find(int id) + { + struct object *obj; + - unsigned long flags; + + - spin_lock_irqsave(&cache_lock, flags); + + rcu_read_lock(); + obj = __cache_find(id); + if (obj) + object_get(obj); + - spin_unlock_irqrestore(&cache_lock, flags); + + rcu_read_unlock(); + return obj; + } + +Da notare che i lettori modificano il campo popularity nella funzione +__cache_find(), e ora non trattiene alcun *lock*. Una soluzione +potrebbe essere quella di rendere la variabile ``atomic_t``, ma per l'uso +che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un +risultato approssimativo è comunque accettabile, quindi non l'ho cambiato. + +Il risultato è che la funzione cache_find() non ha bisogno di alcuna +sincronizzazione con le altre funzioni, quindi è veloce su un sistema +multi-processore tanto quanto lo sarebbe su un sistema mono-processore. + +Esiste un'ulteriore ottimizzazione possibile: vi ricordate il codice originale +della nostra memoria dove non c'erano contatori di riferimenti e il chiamante +semplicemente tratteneva il *lock* prima di accedere ad un oggetto? Questo è +ancora possibile: se trattenete un *lock* nessuno potrà cancellare l'oggetto, +quindi non avete bisogno di incrementare e decrementare il contatore di +riferimenti. + +Ora, dato che il '*lock* di lettura' di un RCU non fa altro che disabilitare +la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le +chiamate cache_find() e object_put() non necessita +di incrementare e decrementare il contatore di riferimenti. Potremmo +esporre la funzione __cache_find() dichiarandola non-static, +e quel chiamante potrebbe usare direttamente questa funzione. + +Il beneficio qui sta nel fatto che il contatore di riferimenti no +viene scritto: l'oggetto non viene alterato in alcun modo e quindi diventa +molto più veloce su sistemi molti-processore grazie alla loro memoria cache. + + +Dati per processore +------------------- + +Un'altra tecnica comunemente usata per evitare la sincronizzazione è quella +di duplicare le informazioni per ogni processore. Per esempio, se volete +avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un +singolo contatore. Facile e pulito. + +Se questo dovesse essere troppo lento (solitamente non lo è, ma se avete +dimostrato che lo è devvero), potreste usare un contatore per ogni processore +e quindi non sarebbe più necessaria la mutua esclusione. Vedere +DEFINE_PER_CPU(), get_cpu_var() e put_cpu_var() +(``include/linux/percpu.h``). + +Il tipo di dato ``local_t``, la funzione cpu_local_inc() e tutte +le altre funzioni associate, sono di particolare utilità per semplici contatori +per-processore; su alcune architetture sono anche più efficienti +(``include/asm/local.h``). + +Da notare che non esiste un modo facile ed affidabile per ottenere il valore +di un simile contatore senza introdurre altri *lock*. In alcuni casi questo +non è un problema. + +Dati che sono usati prevalentemente dai gestori d'interruzioni +-------------------------------------------------------------- + +Se i dati vengono utilizzati sempre dallo stesso gestore d'interruzioni, +allora i *lock* non vi servono per niente: il kernel già vi garantisce che +il gestore d'interruzione non verrà eseguito in contemporanea su diversi +processori. + +Manfred Spraul fa notare che potreste comunque comportarvi così anche +se i dati vengono occasionalmente utilizzati da un contesto utente o +da un'interruzione software. Il gestore d'interruzione non utilizza alcun +*lock*, e tutti gli altri accessi verranno fatti così:: + + mutex_lock(&lock); + disable_irq(irq); + ... + enable_irq(irq); + mutex_unlock(&lock); + +La funzione disable_irq() impedisce al gestore d'interruzioni +d'essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su +un altro processore). Lo spinlock, invece, previene accessi simultanei. +Naturalmente, questo è più lento della semplice chiamata +spin_lock_irq(), quindi ha senso solo se questo genere di accesso +è estremamente raro. + + +Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? +========================================================================= + +Molte funzioni del kernel dormono (in sostanza, chiamano schedule()) +direttamente od indirettamente: non potete chiamarle se trattenere uno +spinlock o avete la prelazione disabilitata, mai. Questo significa che +dovete necessariamente essere nel contesto utente: chiamarle da un +contesto d'interruzione è illegale. + +Alcune funzioni che dormono +--------------------------- + +Le più comuni sono elencate qui di seguito, ma solitamente dovete leggere +il codice per scoprire se altre chiamate sono sicure. Se chiunque altro +le chiami dorme, allora dovreste poter dormire anche voi. In particolar +modo, le funzioni di registrazione e deregistrazione solitamente si +aspettano d'essere chiamante da un contesto utente e quindi che possono +dormire. + +- Accessi allo spazio utente: + + - copy_from_user() + + - copy_to_user() + + - get_user() + + - put_user() + +- kmalloc(GFP_KERNEL) <kmalloc>` + +- mutex_lock_interruptible() and + mutex_lock() + + C'è anche mutex_trylock() che però non dorme. + Comunque, non deve essere usata in un contesto d'interruzione dato + che la sua implementazione non è sicura in quel contesto. + Anche mutex_unlock() non dorme mai. Non può comunque essere + usata in un contesto d'interruzione perché un mutex deve essere rilasciato + dallo stesso processo che l'ha acquisito. + +Alcune funzioni che non dormono +------------------------------- + +Alcune funzioni possono essere chiamate tranquillamente da qualsiasi +contesto, o trattenendo un qualsiasi *lock*. + +- printk() + +- kfree() + +- add_timer() e timer_delete() + +Riferimento per l'API dei Mutex +=============================== + +.. kernel-doc:: include/linux/mutex.h + :internal: + +.. kernel-doc:: kernel/locking/mutex.c + :export: + +Riferimento per l'API dei Futex +=============================== + +.. kernel-doc:: kernel/futex/core.c + :internal: + +.. kernel-doc:: kernel/futex/futex.h + :internal: + +.. kernel-doc:: kernel/futex/pi.c + :internal: + +.. kernel-doc:: kernel/futex/requeue.c + :internal: + +.. kernel-doc:: kernel/futex/waitwake.c + :internal: + +Approfondimenti +=============== + +- ``Documentation/locking/spinlocks.rst``: la guida di Linus Torvalds agli + spinlock del kernel. + +- Unix Systems for Modern Architectures: Symmetric Multiprocessing and + Caching for Kernel Programmers. + + L'introduzione alla sincronizzazione a livello di kernel di Curt Schimmel + è davvero ottima (non è scritta per Linux, ma approssimativamente si adatta + a tutte le situazioni). Il libro è costoso, ma vale ogni singolo spicciolo + per capire la sincronizzazione nei sistemi multi-processore. + [ISBN: 0201633388] + +Ringraziamenti +============== + +Grazie a Telsa Gwynne per aver formattato questa guida in DocBook, averla +pulita e aggiunto un po' di stile. + +Grazie a Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, +Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, +James Morris, Robert Love, Paul McKenney, John Ashby per aver revisionato, +corretto, maledetto e commentato. + +Grazie alla congrega per non aver avuto alcuna influenza su questo documento. + +Glossario +========= + +prelazione + Prima del kernel 2.5, o quando ``CONFIG_PREEMPT`` non è impostato, i processi + in contesto utente non si avvicendano nell'esecuzione (in pratica, il + processo userà il processore fino al proprio termine, a meno che non ci siano + delle interruzioni). Con l'aggiunta di ``CONFIG_PREEMPT`` nella versione + 2.5.4 questo è cambiato: quando si è in contesto utente, processi con una + priorità maggiore possono subentrare nell'esecuzione: gli spinlock furono + cambiati per disabilitare la prelazioni, anche su sistemi monoprocessore. + +bh + Bottom Half: per ragioni storiche, le funzioni che contengono '_bh' nel + loro nome ora si riferiscono a qualsiasi interruzione software; per esempio, + spin_lock_bh() blocca qualsiasi interuzione software sul processore + corrente. I *Bottom Halves* sono deprecati, e probabilmente verranno + sostituiti dai tasklet. In un dato momento potrà esserci solo un + *bottom half* in esecuzione. + +contesto d'interruzione + Non è il contesto utente: qui si processano le interruzioni hardware e + software. La macro in_interrupt() ritorna vero. + +contesto utente + Il kernel che esegue qualcosa per conto di un particolare processo (per + esempio una chiamata di sistema) o di un thread del kernel. Potete + identificare il processo con la macro ``current``. Da non confondere + con lo spazio utente. Può essere interrotto sia da interruzioni software + che hardware. + +interruzione hardware + Richiesta di interruzione hardware. in_hardirq() ritorna vero in un + gestore d'interruzioni hardware. + +interruzione software / softirq + Gestore di interruzioni software: in_hardirq() ritorna falso; + in_softirq() ritorna vero. I tasklet e le softirq sono entrambi + considerati 'interruzioni software'. + + In soldoni, un softirq è uno delle 32 interruzioni software che possono + essere eseguite su più processori in contemporanea. A volte si usa per + riferirsi anche ai tasklet (in pratica tutte le interruzioni software). + +monoprocessore / UP + (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``). + +multi-processore / SMP + (Symmetric Multi-Processor) kernel compilati per sistemi multi-processore + (``CONFIG_SMP=y``). + +spazio utente + Un processo che esegue il proprio codice fuori dal kernel. + +tasklet + Un'interruzione software registrabile dinamicamente che ha la garanzia + d'essere eseguita solo su un processore alla volta. + +timer + Un'interruzione software registrabile dinamicamente che viene eseguita + (circa) in un determinato momento. Quando è in esecuzione è come un tasklet + (infatti, sono chiamati da ``TIMER_SOFTIRQ``). diff --git a/Documentation/translations/it_IT/maintainer/configure-git.rst b/Documentation/translations/it_IT/maintainer/configure-git.rst new file mode 100644 index 0000000000..8316fa5394 --- /dev/null +++ b/Documentation/translations/it_IT/maintainer/configure-git.rst @@ -0,0 +1,10 @@ +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/process/botching-up-ioctls.rst + +.. _it_configuregit: + +Configurare Git +=============== + +.. note:: To be translated diff --git a/Documentation/translations/it_IT/networking/netdev-FAQ.rst b/Documentation/translations/it_IT/networking/netdev-FAQ.rst new file mode 100644 index 0000000000..8a1e049585 --- /dev/null +++ b/Documentation/translations/it_IT/networking/netdev-FAQ.rst @@ -0,0 +1,13 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/maintainer-netdev.rst <netdev-FAQ>` + +.. _it_netdev-FAQ: + +========== +netdev FAQ +========== + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/process/1.Intro.rst b/Documentation/translations/it_IT/process/1.Intro.rst new file mode 100644 index 0000000000..c1be6dc398 --- /dev/null +++ b/Documentation/translations/it_IT/process/1.Intro.rst @@ -0,0 +1,297 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/1.Intro.rst <development_process_intro>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_intro: + +Introduzione +============ + +Riepilogo generale +------------------ + +Il resto di questa sezione riguarda il processo di sviluppo del kernel e +quella sorta di frustrazione che gli sviluppatori e i loro datori di lavoro +potrebbero dover affrontare. Ci sono molte ragioni per le quali del codice +per il kernel debba essere incorporato nel kernel ufficiale, fra le quali: +disponibilità immediata agli utilizzatori, supporto della comunità in +differenti modalità, e la capacità di influenzare la direzione dello sviluppo +del kernel. +Il codice che contribuisce al kernel Linux deve essere reso disponibile sotto +una licenza GPL-compatibile. + +La sezione :ref:`it_development_process` introduce il processo di sviluppo, +il ciclo di rilascio del kernel, ed i meccanismi della finestra +d'incorporazione. Il capitolo copre le varie fasi di una modifica: sviluppo, +revisione e ciclo d'incorporazione. Ci sono alcuni dibattiti su strumenti e +liste di discussione. Gli sviluppatori che sono in attesa di poter sviluppare +qualcosa per il kernel sono invitati ad individuare e sistemare bachi come +esercizio iniziale. + +La sezione :ref:`it_development_early_stage` copre i primi stadi della +pianificazione di un progetto di sviluppo, con particolare enfasi sul +coinvolgimento della comunità, il prima possibile. + +La sezione :ref:`it_development_coding` riguarda il processo di scrittura +del codice. Qui, sono esposte le diverse insidie che sono state già affrontate +da altri sviluppatori. Il capitolo copre anche alcuni dei requisiti per le +modifiche, ed esiste un'introduzione ad alcuni strumenti che possono aiutarvi +nell'assicurarvi che le modifiche per il kernel siano corrette. + +La sezione :ref:`it_development_posting` parla del processo di pubblicazione +delle modifiche per la revisione. Per essere prese in considerazione dalla +comunità di sviluppo, le modifiche devono essere propriamente formattate ed +esposte, e devono essere inviate nel posto giusto. Seguire i consigli presenti +in questa sezione dovrebbe essere d'aiuto nell'assicurare la migliore +accoglienza possibile del vostro lavoro. + +La sezione :ref:`it_development_followthrough` copre ciò che accade dopo +la pubblicazione delle modifiche; a questo punto il lavoro è lontano +dall'essere concluso. Lavorare con i revisori è una parte cruciale del +processo di sviluppo; questa sezione offre una serie di consigli su come +evitare problemi in questa importante fase. Gli sviluppatori sono diffidenti +nell'affermare che il lavoro è concluso quando una modifica è incorporata nei +sorgenti principali. + +La sezione :ref:`it_development_advancedtopics` introduce un paio di argomenti +"avanzati": gestire le modifiche con git e controllare le modifiche pubblicate +da altri. + +La sezione :ref:`it_development_conclusion` chiude il documento con dei +riferimenti ad altre fonti che forniscono ulteriori informazioni sullo sviluppo +del kernel. + +Di cosa parla questo documento +------------------------------ + +Il kernel Linux, ha oltre 8 milioni di linee di codice e ben oltre 1000 +contributori ad ogni rilascio; è uno dei più vasti e più attivi software +liberi progettati mai esistiti. Sin dal sul modesto inizio nel 1991, +questo kernel si è evoluto nel miglior componente per sistemi operativi +che fanno funzionare piccoli riproduttori musicali, PC, grandi super computer +e tutte le altre tipologie di sistemi fra questi estremi. È una soluzione +robusta, efficiente ed adattabile a praticamente qualsiasi situazione. + +Con la crescita di Linux è arrivato anche un aumento di sviluppatori +(ed aziende) desiderosi di partecipare a questo sviluppo. I produttori di +hardware vogliono assicurarsi che il loro prodotti siano supportati da Linux, +rendendo questi prodotti attrattivi agli utenti Linux. I produttori di +sistemi integrati, che usano Linux come componente di un prodotto integrato, +vogliono che Linux sia capace ed adeguato agli obiettivi ed il più possibile +alla mano. Fornitori ed altri produttori di software che basano i propri +prodotti su Linux hanno un chiaro interesse verso capacità, prestazioni ed +affidabilità del kernel Linux. E gli utenti finali, anche, spesso vorrebbero +cambiare Linux per renderlo più aderente alle proprie necessità. + +Una delle caratteristiche più coinvolgenti di Linux è quella dell'accessibilità +per gli sviluppatori; chiunque con le capacità richieste può migliorare +Linux ed influenzarne la direzione di sviluppo. Prodotti non open-source non +possono offrire questo tipo di apertura, che è una caratteristica del software +libero. Ma, anzi, il kernel è persino più aperto rispetto a molti altri +progetti di software libero. Un classico ciclo di sviluppo trimestrale può +coinvolgere 1000 sviluppatori che lavorano per più di 100 differenti aziende +(o per nessuna azienda). + +Lavorare con la comunità di sviluppo del kernel non è particolarmente +difficile. Ma, ciononostante, diversi potenziali contributori hanno trovato +delle difficoltà quando hanno cercato di lavorare sul kernel. La comunità del +kernel utilizza un proprio modo di operare che gli permette di funzionare +agevolmente (e genera un prodotto di alta qualità) in un ambiente dove migliaia +di stringhe di codice sono modificate ogni giorni. Quindi non deve sorprendere +che il processo di sviluppo del kernel differisca notevolmente dai metodi di +sviluppo privati. + +Il processo di sviluppo del Kernel può, dall'altro lato, risultare +intimidatorio e strano ai nuovi sviluppatori, ma ha dietro di se buone ragioni +e solide esperienze. Uno sviluppatore che non comprende i modi della comunità +del kernel (o, peggio, che cerchi di aggirarli o violarli) avrà un'esperienza +deludente nel proprio bagaglio. La comunità di sviluppo, sebbene sia utile +a coloro che cercano di imparare, ha poco tempo da dedicare a coloro che non +ascoltano o coloro che non sono interessati al processo di sviluppo. + +Si spera che coloro che leggono questo documento saranno in grado di evitare +queste esperienze spiacevoli. C'è molto materiale qui, ma lo sforzo della +lettura sarà ripagato in breve tempo. La comunità di sviluppo ha sempre +bisogno di sviluppatori che vogliano aiutare a rendere il kernel migliore; +il testo seguente potrebbe esservi d'aiuto - o essere d'aiuto ai vostri +collaboratori- per entrare a far parte della nostra comunità. + +Crediti +------- + +Questo documento è stato scritto da Jonathan Corbet, corbet@lwn.net. +È stato migliorato da Johannes Berg, James Berry, Alex Chiang, Roland +Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh, +Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata e Jochen Voß. + +Questo lavoro è stato supportato dalla Linux Foundation; un ringraziamento +speciale ad Amanda McPherson, che ha visto il valore di questo lavoro e lo ha +reso possibile. + +L'importanza d'avere il codice nei sorgenti principali +------------------------------------------------------ + +Alcune aziende e sviluppatori ogni tanto si domandano perché dovrebbero +preoccuparsi di apprendere come lavorare con la comunità del kernel e di +inserire il loro codice nel ramo di sviluppo principale (per ramo principale +s'intende quello mantenuto da Linus Torvalds e usato come base dai +distributori Linux). Nel breve termine, contribuire al codice può sembrare +un costo inutile; può sembra più facile tenere separato il proprio codice e +supportare direttamente i suoi utilizzatori. La verità è che il tenere il +codice separato ("fuori dai sorgenti", *"out-of-tree"*) è un falso risparmio. + +Per dimostrare i costi di un codice "fuori dai sorgenti", eccovi +alcuni aspetti rilevanti del processo di sviluppo kernel; la maggior parte +di essi saranno approfonditi dettagliatamente più avanti in questo documento. +Considerate: + +- Il codice che è stato inserito nel ramo principale del kernel è disponibile + a tutti gli utilizzatori Linux. Sarà automaticamente presente in tutte le + distribuzioni che lo consentono. Non c'è bisogno di: driver per dischi, + scaricare file, o della scocciatura del dover supportare diverse versioni di + diverse distribuzioni; funziona già tutto, per gli sviluppatori e per gli + utilizzatori. L'inserimento nel ramo principale risolve un gran numero di + problemi di distribuzione e di supporto. + +- Nonostante gli sviluppatori kernel si sforzino di tenere stabile + l'interfaccia dello spazio utente, quella interna al kernel è in continuo + cambiamento. La mancanza di un'interfaccia interna è deliberatamente una + decisione di progettazione; ciò permette che i miglioramenti fondamentali + vengano fatti in un qualsiasi momento e che risultino fatti con un codice di + alta qualità. Ma una delle conseguenze di questa politica è che qualsiasi + codice "fuori dai sorgenti" richiede costante manutenzione per renderlo + funzionante coi kernel più recenti. Tenere un codice "fuori dai sorgenti" + richiede una mole di lavoro significativa solo per farlo funzionare. + + Invece, il codice che si trova nel ramo principale non necessita di questo + tipo di lavoro poiché ad ogni sviluppatore che faccia una modifica alle + interfacce viene richiesto di sistemare anche il codice che utilizza + quell'interfaccia. Quindi, il codice che è stato inserito nel ramo principale + ha dei costi di mantenimento significativamente più bassi. + +- Oltre a ciò, spesso il codice che è all'interno del kernel sarà migliorato da + altri sviluppatori. Dare pieni poteri alla vostra comunità di utenti e ai + clienti può portare a sorprendenti risultati che migliorano i vostri + prodotti. + +- Il codice kernel è soggetto a revisioni, sia prima che dopo l'inserimento + nel ramo principale. Non importa quanto forti fossero le abilità dello + sviluppatore originale, il processo di revisione troverà il modo di migliore + il codice. Spesso la revisione trova bachi importanti e problemi di + sicurezza. Questo è particolarmente vero per il codice che è stato + sviluppato in un ambiente chiuso; tale codice ottiene un forte beneficio + dalle revisioni provenienti da sviluppatori esteri. Il codice + "fuori dai sorgenti", invece, è un codice di bassa qualità. + +- La partecipazione al processo di sviluppo costituisce la vostra via per + influenzare la direzione di sviluppo del kernel. Gli utilizzatori che + "reclamano da bordo campo" sono ascoltati, ma gli sviluppatori attivi + hanno una voce più forte - e la capacità di implementare modifiche che + renderanno il kernel più funzionale alle loro necessità. + +- Quando il codice è gestito separatamente, esiste sempre la possibilità che + terze parti contribuiscano con una differente implementazione che fornisce + le stesse funzionalità. Se dovesse accadere, l'inserimento del codice + diventerà molto più difficile - fino all'impossibilità. Poi, dovrete far + fronte a delle alternative poco piacevoli, come: (1) mantenere un elemento + non standard "fuori dai sorgenti" per un tempo indefinito, o (2) abbandonare + il codice e far migrare i vostri utenti alla versione "nei sorgenti". + +- Contribuire al codice è l'azione fondamentale che fa funzionare tutto il + processo. Contribuendo attraverso il vostro codice potete aggiungere nuove + funzioni al kernel e fornire competenze ed esempi che saranno utili ad + altri sviluppatori. Se avete sviluppato del codice Linux (o state pensando + di farlo), avete chiaramente interesse nel far proseguire il successo di + questa piattaforma. Contribuire al codice è une delle migliori vie per + aiutarne il successo. + +Il ragionamento sopra citato si applica ad ogni codice "fuori dai sorgenti" +dal kernel, incluso il codice proprietario distribuito solamente in formato +binario. Ci sono, comunque, dei fattori aggiuntivi che dovrebbero essere +tenuti in conto prima di prendere in considerazione qualsiasi tipo di +distribuzione binaria di codice kernel. Questo include che: + +- Le questioni legali legate alla distribuzione di moduli kernel proprietari + sono molto nebbiose; parecchi detentori di copyright sul kernel credono che + molti moduli binari siano prodotti derivati del kernel e che, come risultato, + la loro diffusione sia una violazione della licenza generale di GNU (della + quale si parlerà più avanti). L'autore qui non è un avvocato, e + niente in questo documento può essere considerato come un consiglio legale. + Il vero stato legale dei moduli proprietari può essere determinato + esclusivamente da un giudice. Ma l'incertezza che perseguita quei moduli + è lì comunque. + +- I moduli binari aumentano di molto la difficoltà di fare debugging del + kernel, al punto che la maggior parte degli sviluppatori del kernel non + vorranno nemmeno tentare. Quindi la diffusione di moduli esclusivamente + binari renderà difficile ai vostri utilizzatori trovare un supporto dalla + comunità. + +- Il supporto è anche difficile per i distributori di moduli binari che devono + fornire una versione del modulo per ogni distribuzione e per ogni versione + del kernel che vogliono supportate. Per fornire una copertura ragionevole e + comprensiva, può essere richiesto di produrre dozzine di singoli moduli. + E inoltre i vostri utilizzatori dovranno aggiornare il vostro modulo + separatamente ogni volta che aggiornano il loro kernel. + +- Tutto ciò che è stato detto prima riguardo alla revisione del codice si + applica doppiamente al codice proprietario. Dato che questo codice non è + del tutto disponibile, non può essere revisionato dalla comunità e avrà, + senza dubbio, seri problemi. + +I produttori di sistemi integrati, in particolare, potrebbero esser tentati +dall'evitare molto di ciò che è stato detto in questa sezione, credendo che +stiano distribuendo un prodotto finito che utilizza una versione del kernel +immutabile e che non richiede un ulteriore sviluppo dopo il rilascio. Questa +idea non comprende il valore di una vasta revisione del codice e il valore +del permettere ai propri utenti di aggiungere funzionalità al vostro prodotto. +Ma anche questi prodotti, hanno una vita commerciale limitata, dopo la quale +deve essere rilasciata una nuova versione. A quel punto, i produttori il cui +codice è nel ramo principale di sviluppo avranno un codice ben mantenuto e +saranno in una posizione migliore per ottenere velocemente un nuovo prodotto +pronto per essere distribuito. + + +Licenza +------- + +IL codice Linux utilizza diverse licenze, ma il codice completo deve essere +compatibile con la seconda versione della licenza GNU General Public License +(GPLv2), che è la licenza che copre la distribuzione del kernel. +Nella pratica, ciò significa che tutti i contributi al codice sono coperti +anche'essi dalla GPLv2 (con, opzionalmente, una dicitura che permette la +possibilità di distribuirlo con licenze più recenti di GPL) o dalla licenza +three-clause BSD. Qualsiasi contributo che non è coperto da una licenza +compatibile non verrà accettata nel kernel. + +Per il codice sottomesso al kernel non è necessario (o richiesto) la +concessione del Copyright. Tutto il codice inserito nel ramo principale del +kernel conserva la sua proprietà originale; ne risulta che ora il kernel abbia +migliaia di proprietari. + +Una conseguenza di questa organizzazione della proprietà è che qualsiasi +tentativo di modifica della licenza del kernel è destinata ad un quasi sicuro +fallimento. Esistono alcuni scenari pratici nei quali il consenso di tutti +i detentori di copyright può essere ottenuto (o il loro codice verrà rimosso +dal kernel). Quindi, in sostanza, non esiste la possibilità che si giunga ad +una versione 3 della licenza GPL nel prossimo futuro. + +È imperativo che tutto il codice che contribuisce al kernel sia legittimamente +software libero. Per questa ragione, un codice proveniente da un contributore +anonimo (o sotto pseudonimo) non verrà accettato. È richiesto a tutti i +contributori di firmare il proprio codice, attestando così che quest'ultimo +può essere distribuito insieme al kernel sotto la licenza GPL. Il codice che +non è stato licenziato come software libero dal proprio creatore, o che +potrebbe creare problemi di copyright per il kernel (come il codice derivante +da processi di ingegneria inversa senza le opportune tutele), non può essere +diffuso. + +Domande relative a questioni legate al copyright sono frequenti nelle liste +di discussione dedicate allo sviluppo di Linux. Tali quesiti, normalmente, +non riceveranno alcuna risposta, ma una cosa deve essere tenuta presente: +le persone che risponderanno a quelle domande non sono avvocati e non possono +fornire supporti legali. Se avete questioni legali relative ai sorgenti +del codice Linux, non esiste alternativa che quella di parlare con un +avvocato esperto nel settore. Fare affidamento sulle risposte ottenute da +una lista di discussione tecnica è rischioso. diff --git a/Documentation/translations/it_IT/process/2.Process.rst b/Documentation/translations/it_IT/process/2.Process.rst new file mode 100644 index 0000000000..25cd00351c --- /dev/null +++ b/Documentation/translations/it_IT/process/2.Process.rst @@ -0,0 +1,527 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/2.Process.rst <development_process>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_process: + +Come funziona il processo di sviluppo +===================================== + +Lo sviluppo del Kernel agli inizi degli anno '90 era abbastanza libero, con +un numero di utenti e sviluppatori relativamente basso. Con una base +di milioni di utenti e con 2000 sviluppatori coinvolti nel giro di un anno, +il kernel da allora ha messo in atto un certo numero di procedure per rendere +lo sviluppo più agevole. È richiesta una solida conoscenza di come tale +processo si svolge per poter esserne parte attiva. + +Il quadro d'insieme +------------------- + +Gli sviluppatori kernel utilizzano un calendario di rilascio generico, dove +ogni due o tre mesi viene effettuata un rilascio importante del kernel. +I rilasci più recenti sono stati: + + ====== ================= + 5.0 3 marzo, 2019 + 5.1 5 maggio, 2019 + 5.2 7 luglio, 2019 + 5.3 15 settembre, 2019 + 5.4 24 novembre, 2019 + 5.5 6 gennaio, 2020 + ====== ================= + +Ciascun rilascio 5.x è un importante rilascio del kernel con nuove +funzionalità, modifiche interne dell'API, e molto altro. Un tipico +rilascio contiene quasi 13,000 gruppi di modifiche con ulteriori +modifiche a parecchie migliaia di linee di codice. La 5.x. è pertanto la +linea di confine nello sviluppo del kernel Linux; il kernel utilizza un sistema +di sviluppo continuo che integra costantemente nuove importanti modifiche. + +Viene seguita una disciplina abbastanza lineare per l'inclusione delle +patch di ogni rilascio. All'inizio di ogni ciclo di sviluppo, la +"finestra di inclusione" viene dichiarata aperta. In quel momento il codice +ritenuto sufficientemente stabile(e che è accettato dalla comunità di sviluppo) +viene incluso nel ramo principale del kernel. La maggior parte delle +patch per un nuovo ciclo di sviluppo (e tutte le più importanti modifiche) +saranno inserite durante questo periodo, ad un ritmo che si attesta sulle +1000 modifiche ("patch" o "gruppo di modifiche") al giorno. + +(per inciso, vale la pena notare che i cambiamenti integrati durante la +"finestra di inclusione" non escono dal nulla; questi infatti, sono stati +raccolti e, verificati in anticipo. Il funzionamento di tale procedimento +verrà descritto dettagliatamente più avanti). + +La finestra di inclusione resta attiva approssimativamente per due settimane. +Al termine di questo periodo, Linus Torvald dichiarerà che la finestra è +chiusa e rilascerà il primo degli "rc" del kernel. +Per il kernel che è destinato ad essere 5.6, per esempio, il rilascio +che emerge al termine della finestra d'inclusione si chiamerà 5.6-rc1. +Questo rilascio indica che il momento di aggiungere nuovi componenti è +passato, e che è iniziato il periodo di stabilizzazione del prossimo kernel. + +Nelle successive sei/dieci settimane, potranno essere sottoposte solo modifiche +che vanno a risolvere delle problematiche. Occasionalmente potrà essere +consentita una modifica più consistente, ma tali occasioni sono rare. +Gli sviluppatori che tenteranno di aggiungere nuovi elementi al di fuori della +finestra di inclusione, tendenzialmente, riceveranno un accoglienza poco +amichevole. Come regola generale: se vi perdete la finestra di inclusione per +un dato componente, la cosa migliore da fare è aspettare il ciclo di sviluppo +successivo (un'eccezione può essere fatta per i driver per hardware non +supportati in precedenza; se toccano codice non facente parte di quello +attuale, che non causino regressioni e che potrebbero essere aggiunti in +sicurezza in un qualsiasi momento) + +Mentre le correzioni si aprono la loro strada all'interno del ramo principale, +il ritmo delle modifiche rallenta col tempo. Linus rilascia un nuovo +kernel -rc circa una volta alla settimana; e ne usciranno circa 6 o 9 prima +che il kernel venga considerato sufficientemente stabile e che il rilascio +finale venga fatto. A quel punto tutto il processo ricomincerà. + +Esempio: ecco com'è andato il ciclo di sviluppo della versione 5.4 +(tutte le date si collocano nel 2018) + + + ============== ======================================= + 15 settembre 5.3 rilascio stabile + 30 settembre 5.4-rc1, finestra di inclusione chiusa + 6 ottobre 5.4-rc2 + 13 ottobre 5.4-rc3 + 20 ottobre 5.4-rc4 + 27 ottobre 5.4-rc5 + 3 novembre 5.4-rc6 + 10 novembre 5.4-rc7 + 17 novembre 5.4-rc8 + 24 novembre 5.4 rilascio stabile + ============== ======================================= + +In che modo gli sviluppatori decidono quando chiudere il ciclo di sviluppo e +creare quindi una rilascio stabile? Un metro valido è il numero di regressioni +rilevate nel precedente rilascio. Nessun baco è il benvenuto, ma quelli che +procurano problemi su sistemi che hanno funzionato in passato sono considerati +particolarmente seri. Per questa ragione, le modifiche che portano ad una +regressione sono viste sfavorevolmente e verranno quasi sicuramente annullate +durante il periodo di stabilizzazione. + +L'obiettivo degli sviluppatori è quello di aggiustare tutte le regressioni +conosciute prima che avvenga il rilascio stabile. Nel mondo reale, questo +tipo di perfezione difficilmente viene raggiunta; esistono troppe variabili +in un progetto di questa portata. Arriva un punto dove ritardare il rilascio +finale peggiora la situazione; la quantità di modifiche in attesa della +prossima finestra di inclusione crescerà enormemente, creando ancor più +regressioni al giro successivo. Quindi molti kernel 5.x escono con una +manciata di regressioni delle quali, si spera, nessuna è grave. + +Una volta che un rilascio stabile è fatto, il suo costante mantenimento è +affidato al "squadra stabilità", attualmente composta da Greg Kroah-Hartman. +Questa squadra rilascia occasionalmente degli aggiornamenti relativi al +rilascio stabile usando la numerazione 5.x.y. Per essere presa in +considerazione per un rilascio d'aggiornamento, una modifica deve: +(1) correggere un baco importante (2) essere già inserita nel ramo principale +per il prossimo sviluppo del kernel. Solitamente, passato il loro rilascio +iniziale, i kernel ricevono aggiornamenti per più di un ciclo di sviluppo. +Quindi, per esempio, la storia del kernel 5.2 appare così (anno 2019): + + ============== =============================== + 7 luglio 5.2 rilascio stabile + 14 luglio 5.2.1 + 21 luglio 5.2.2 + 26 luglio 5.2.3 + 28 luglio 5.2.4 + 31 luglio 5.2.5 + ... ... + 11 ottobre 5.2.21 + ============== =============================== + +La 5.2.21 fu l'aggiornamento finale per la versione 5.2. + +Alcuni kernel sono destinati ad essere kernel a "lungo termine"; questi +riceveranno assistenza per un lungo periodo di tempo. Consultate il seguente +collegamento per avere la lista delle versioni attualmente supportate e i +relativi manutentori: + + https://www.kernel.org/category/releases.html + +Questa selezione di kernel di lungo periodo sono puramente dovuti ai loro +manutentori, alla loro necessità e al tempo per tenere aggiornate proprio +quelle versioni. Non ci sono altri kernel a lungo termine in programma per +alcun rilascio in arrivo. + +Il ciclo di vita di una patch +----------------------------- + +Le patch non passano direttamente dalla tastiera dello sviluppatori +al ramo principale del kernel. Esiste, invece, una procedura disegnata +per assicurare che ogni patch sia di buona qualità e desiderata nel +ramo principale. Questo processo avviene velocemente per le correzioni +meno importanti, o, nel caso di patch ampie e controverse, va avanti per anni. +Per uno sviluppatore la maggior frustrazione viene dalla mancanza di +comprensione di questo processo o dai tentativi di aggirarlo. + +Nella speranza di ridurre questa frustrazione, questo documento spiegherà +come una patch viene inserita nel kernel. Ciò che segue è un'introduzione +che descrive il processo ideale. Approfondimenti verranno invece trattati +più avanti. + +Una patch attraversa, generalmente, le seguenti fasi: + + - Progetto. In questa fase sono stabilite quelli che sono i requisiti + della modifica - e come verranno soddisfatti. Il lavoro di progettazione + viene spesso svolto senza coinvolgere la comunità, ma è meglio renderlo + il più aperto possibile; questo può far risparmiare molto tempo evitando + eventuali riprogettazioni successive. + + - Prima revisione. Le patch vengono pubblicate sulle liste di discussione + interessate, e gli sviluppatori in quella lista risponderanno coi loro + commenti. Se si svolge correttamente, questo procedimento potrebbe far + emergere problemi rilevanti in una patch. + + - Revisione più ampia. Quando la patch è quasi pronta per essere inserita + nel ramo principale, un manutentore importante del sottosistema dovrebbe + accettarla - anche se, questa accettazione non è una garanzia che la + patch arriverà nel ramo principale. La patch sarà visibile nei sorgenti + del sottosistema in questione e nei sorgenti -next (descritti sotto). + Quando il processo va a buon fine, questo passo porta ad una revisione + più estesa della patch e alla scoperta di problemi d'integrazione + con il lavoro altrui. + +- Per favore, tenete da conto che la maggior parte dei manutentori ha + anche un lavoro quotidiano, quindi integrare le vostre patch potrebbe + non essere la loro priorità più alta. Se una vostra patch riceve + dei suggerimenti su dei cambiamenti necessari, dovreste applicare + quei cambiamenti o giustificare perché non sono necessari. Se la vostra + patch non riceve alcuna critica ma non è stata integrata dal + manutentore del driver o sottosistema, allora dovreste continuare con + i necessari aggiornamenti per mantenere la patch aggiornata al kernel + più recente cosicché questa possa integrarsi senza problemi; continuate + ad inviare gli aggiornamenti per essere revisionati e integrati. + + - Inclusione nel ramo principale. Eventualmente, una buona patch verrà + inserita all'interno nel repositorio principale, gestito da + Linus Torvalds. In questa fase potrebbero emergere nuovi problemi e/o + commenti; è importante che lo sviluppatore sia collaborativo e che sistemi + ogni questione che possa emergere. + + - Rilascio stabile. Ora, il numero di utilizzatori che sono potenzialmente + toccati dalla patch è aumentato, quindi, ancora una volta, potrebbero + emergere nuovi problemi. + + - Manutenzione di lungo periodo. Nonostante sia possibile che uno sviluppatore + si dimentichi del codice dopo la sua integrazione, questo comportamento + lascia una brutta impressione nella comunità di sviluppo. Integrare il + codice elimina alcuni degli oneri facenti parte della manutenzione, in + particolare, sistemerà le problematiche causate dalle modifiche all'API. + Ma lo sviluppatore originario dovrebbe continuare ad assumersi la + responsabilità per il codice se quest'ultimo continua ad essere utile + nel lungo periodo. + +Uno dei più grandi errori fatti dagli sviluppatori kernel (o dai loro datori +di lavoro) è quello di cercare di ridurre tutta la procedura ad una singola +"integrazione nel remo principale". Questo approccio inevitabilmente conduce +a una condizione di frustrazione per tutti coloro che sono coinvolti. + +Come le modifiche finiscono nel Kernel +-------------------------------------- + +Esiste una sola persona che può inserire le patch nel repositorio principale +del kernel: Linus Torvalds. Ma, per esempio, di tutte le 9500 patch +che entrarono nella versione 2.6.38 del kernel, solo 112 (circa +l'1,3%) furono scelte direttamente da Linus in persona. Il progetto +del kernel è cresciuto fino a raggiungere una dimensione tale per cui +un singolo sviluppatore non può controllare e selezionare +indipendentemente ogni modifica senza essere supportato. La via +scelta dagli sviluppatori per indirizzare tale crescita è stata quella +di utilizzare un sistema di "sottotenenti" basato sulla fiducia. + +Il codice base del kernel è spezzato in una serie si sottosistemi: rete, +supporto per specifiche architetture, gestione della memoria, video e +strumenti, etc. Molti sottosistemi hanno un manutentore designato: ovvero uno +sviluppatore che ha piena responsabilità di tutto il codice presente in quel +sottosistema. Tali manutentori di sottosistema sono i guardiani +(in un certo senso) della parte di kernel che gestiscono; sono coloro che +(solitamente) accetteranno una patch per l'inclusione nel ramo principale +del kernel. + +I manutentori di sottosistema gestiscono ciascuno la propria parte dei sorgenti +del kernel, utilizzando abitualmente (ma certamente non sempre) git. +Strumenti come git (e affini come quilt o mercurial) permettono ai manutentori +di stilare una lista delle patch, includendo informazioni sull'autore ed +altri metadati. In ogni momento, il manutentore può individuare quale patch +nel sua repositorio non si trova nel ramo principale. + +Quando la "finestra di integrazione" si apre, i manutentori di alto livello +chiederanno a Linus di "prendere" dai loro repositori le modifiche che hanno +selezionato per l'inclusione. Se Linus acconsente, il flusso di patch si +convoglierà nel repositorio di quest ultimo, divenendo così parte del ramo +principale del kernel. La quantità d'attenzione che Linus presta alle +singole patch ricevute durante l'operazione di integrazione varia. +È chiaro che, qualche volta, guardi più attentamente. Ma, come regola +generale, Linus confida nel fatto che i manutentori di sottosistema non +selezionino pessime patch. + +I manutentori di sottosistemi, a turno, possono "prendere" patch +provenienti da altri manutentori. Per esempio, i sorgenti per la rete rete +sono costruiti da modifiche che si sono accumulate inizialmente nei sorgenti +dedicati ai driver per dispositivi di rete, rete senza fili, ecc. Tale +catena di repositori può essere più o meno lunga, benché raramente ecceda +i due o tre collegamenti. Questo processo è conosciuto come +"la catena della fiducia", perché ogni manutentore all'interno della +catena si fida di coloro che gestiscono i livelli più bassi. + +Chiaramente, in un sistema come questo, l'inserimento delle patch all'interno +del kernel si basa sul trovare il manutentore giusto. Di norma, inviare +patch direttamente a Linus non è la via giusta. + + +Sorgenti -next +-------------- + +La catena di sottosistemi guida il flusso di patch all'interno del kernel, +ma solleva anche un interessante quesito: se qualcuno volesse vedere tutte le +patch pronte per la prossima finestra di integrazione? +Gli sviluppatori si interesseranno alle patch in sospeso per verificare +che non ci siano altri conflitti di cui preoccuparsi; una modifica che, per +esempio, cambia il prototipo di una funzione fondamentale del kernel andrà in +conflitto con qualsiasi altra modifica che utilizzi la vecchia versione di +quella funzione. Revisori e tester vogliono invece avere accesso alle +modifiche nella loro totalità prima che approdino nel ramo principale del +kernel. Uno potrebbe prendere le patch provenienti da tutti i sottosistemi +d'interesse, ma questo sarebbe un lavoro enorme e fallace. + +La risposta ci viene sotto forma di sorgenti -next, dove i sottosistemi sono +raccolti per essere testati e controllati. Il più vecchio di questi sorgenti, +gestito da Andrew Morton, è chiamato "-mm" (memory management, che è l'inizio +di tutto). L'-mm integra patch proveniente da una lunga lista di sottosistemi; +e ha, inoltre, alcune patch destinate al supporto del debugging. + +Oltre a questo, -mm contiene una raccolta significativa di patch che sono +state selezionate da Andrew direttamente. Queste patch potrebbero essere +state inviate in una lista di discussione, o possono essere applicate ad una +parte del kernel per la quale non esiste un sottosistema dedicato. +Di conseguenza, -mm opera come una specie di sottosistema "ultima spiaggia"; +se per una patch non esiste una via chiara per entrare nel ramo principale, +allora è probabile che finirà in -mm. Le patch passate per -mm +eventualmente finiranno nel sottosistema più appropriato o saranno inviate +direttamente a Linus. In un tipico ciclo di sviluppo, circa il 5-10% delle +patch andrà nel ramo principale attraverso -mm. + +La patch -mm correnti sono disponibili nella cartella "mmotm" (-mm of +the moment) all'indirizzo: + + http://www.ozlabs.org/~akpm/mmotm/ + +È molto probabile che l'uso dei sorgenti MMOTM diventi un'esperienza +frustrante; ci sono buone probabilità che non compili nemmeno. + +I sorgenti principali per il prossimo ciclo d'integrazione delle patch +è linux-next, gestito da Stephen Rothwell. I sorgenti linux-next sono, per +definizione, un'istantanea di come dovrà apparire il ramo principale dopo che +la prossima finestra di inclusione si chiuderà. I linux-next sono annunciati +sulla lista di discussione linux-kernel e linux-next nel momento in cui +vengono assemblati; e possono essere scaricate da: + + http://www.kernel.org/pub/linux/kernel/next/ + +Linux-next è divenuto parte integrante del processo di sviluppo del kernel; +tutte le patch incorporate durante una finestra di integrazione dovrebbero +aver trovato la propria strada in linux-next, a volte anche prima dell'apertura +della finestra di integrazione. + + +Sorgenti in preparazione +------------------------ + +Nei sorgenti del kernel esiste la cartella drivers/staging/, dove risiedono +molte sotto-cartelle per i driver o i filesystem che stanno per essere aggiunti +al kernel. Questi restano nella cartella drivers/staging fintanto che avranno +bisogno di maggior lavoro; una volta completato, possono essere spostate +all'interno del kernel nel posto più appropriato. Questo è il modo di tener +traccia dei driver che non sono ancora in linea con gli standard di codifica +o qualità, ma che le persone potrebbero voler usare ugualmente e tracciarne +lo sviluppo. + +Greg Kroah-Hartman attualmente gestisce i sorgenti in preparazione. I driver +che non sono completamente pronti vengono inviati a lui, e ciascun driver avrà +la propria sotto-cartella in drivers/staging/. Assieme ai file sorgenti +dei driver, dovrebbe essere presente nella stessa cartella anche un file TODO. +Il file TODO elenca il lavoro ancora da fare su questi driver per poter essere +accettati nel kernel, e indica anche la lista di persone da inserire in copia +conoscenza per ogni modifica fatta. Le regole attuali richiedono che i +driver debbano, come minimo, compilare adeguatamente. + +La *preparazione* può essere una via relativamente facile per inserire nuovi +driver all'interno del ramo principale, dove, con un po' di fortuna, saranno +notati da altri sviluppatori e migliorati velocemente. Entrare nella fase +di preparazione non è però la fine della storia, infatti, il codice che si +trova nella cartella staging che non mostra regolari progressi potrebbe +essere rimosso. Le distribuzioni, inoltre, tendono a dimostrarsi relativamente +riluttanti nell'attivare driver in preparazione. Quindi lo preparazione è, +nel migliore dei casi, una tappa sulla strada verso il divenire un driver +del ramo principale. + + +Strumenti +--------- + +Come è possibile notare dal testo sopra, il processo di sviluppo del kernel +dipende pesantemente dalla capacità di guidare la raccolta di patch in +diverse direzioni. L'intera cosa non funzionerebbe se non venisse svolta +con l'uso di strumenti appropriati e potenti. Spiegare l'uso di tali +strumenti non è lo scopo di questo documento, ma c'è spazio per alcuni +consigli. + +In assoluto, nella comunità del kernel, predomina l'uso di git come sistema +di gestione dei sorgenti. Git è una delle diverse tipologie di sistemi +distribuiti di controllo versione che sono stati sviluppati nella comunità +del software libero. Esso è calibrato per lo sviluppo del kernel, e si +comporta abbastanza bene quando ha a che fare con repositori grandi e con un +vasto numero di patch. Git ha inoltre la reputazione di essere difficile +da imparare e utilizzare, benché stia migliorando. Agli sviluppatori +del kernel viene richiesta un po' di familiarità con git; anche se non lo +utilizzano per il proprio lavoro, hanno bisogno di git per tenersi al passo +con il lavoro degli altri sviluppatori (e con il ramo principale). + +Git è ora compreso in quasi tutte le distribuzioni Linux. Esiste una sito che +potete consultare: + + http://git-scm.com/ + +Qui troverete i riferimenti alla documentazione e alle guide passo-passo. + +Tra gli sviluppatori Kernel che non usano git, la scelta alternativa più +popolare è quasi sicuramente Mercurial: + + http://www.selenic.com/mercurial/ + +Mercurial condivide diverse caratteristiche con git, ma fornisce +un'interfaccia che potrebbe risultare più semplice da utilizzare. + +L'altro strumento che vale la pena conoscere è Quilt: + + http://savannah.nongnu.org/projects/quilt/ + + +Quilt è un sistema di gestione delle patch, piuttosto che un sistema +di gestione dei sorgenti. Non mantiene uno storico degli eventi; ma piuttosto +è orientato verso il tracciamento di uno specifico insieme di modifiche +rispetto ad un codice in evoluzione. Molti dei più grandi manutentori di +sottosistema utilizzano quilt per gestire le patch che dovrebbero essere +integrate. Per la gestione di certe tipologie di sorgenti (-mm, per esempio), +quilt è il miglior strumento per svolgere il lavoro. + + +Liste di discussione +-------------------- + +Una grossa parte del lavoro di sviluppo del Kernel Linux viene svolto tramite +le liste di discussione. È difficile essere un membro della comunità +pienamente coinvolto se non si partecipa almeno ad una lista da qualche +parte. Ma, le liste di discussione di Linux rappresentano un potenziale +problema per gli sviluppatori, che rischiano di venir sepolti da un mare di +email, restare incagliati nelle convenzioni in vigore nelle liste Linux, +o entrambi. + +Molte delle liste di discussione del Kernel girano su vger.kernel.org; +l'elenco principale lo si trova sul sito: + + http://vger.kernel.org/vger-lists.html + +Esistono liste gestite altrove; un certo numero di queste sono in +redhat.com/mailman/listinfo. + +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. diff --git a/Documentation/translations/it_IT/process/3.Early-stage.rst b/Documentation/translations/it_IT/process/3.Early-stage.rst new file mode 100644 index 0000000000..0809de3910 --- /dev/null +++ b/Documentation/translations/it_IT/process/3.Early-stage.rst @@ -0,0 +1,242 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/3.Early-stage.rst <development_early_stage>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_early_stage: + +I primi passi della pianificazione +================================== + +Osservando un progetto di sviluppo per il kernel Linux, si potrebbe essere +tentati dal saltare tutto e iniziare a codificare. Tuttavia, come ogni +progetto significativo, molta della preparazione per giungere al successo +viene fatta prima che una sola linea di codice venga scritta. Il tempo speso +nella pianificazione e la comunicazione può far risparmiare molto +tempo in futuro. + +Specificare il problema +----------------------- + +Come qualsiasi progetto ingegneristico, un miglioramento del kernel di +successo parte con una chiara descrizione del problema da risolvere. +In alcuni casi, questo passaggio è facile: ad esempio quando un driver è +richiesto per un particolare dispositivo. In altri casi invece, si +tende a confondere il problema reale con le soluzioni proposte e questo +può portare all'emergere di problemi. + +Facciamo un esempio: qualche anno fa, gli sviluppatori che lavoravano con +linux audio cercarono un modo per far girare le applicazioni senza dropouts +o altri artefatti dovuti all'eccessivo ritardo nel sistema. La soluzione +alla quale giunsero fu un modulo del kernel destinato ad agganciarsi al +framework Linux Security Module (LSM); questo modulo poteva essere +configurato per dare ad una specifica applicazione accesso allo +schedulatore *realtime*. Tale modulo fu implementato e inviato nella +lista di discussione linux-kernel, dove incontrò subito dei problemi. + +Per gli sviluppatori audio, questo modulo di sicurezza era sufficiente a +risolvere il loro problema nell'immediato. Per l'intera comunità kernel, +invece, era un uso improprio del framework LSM (che non è progettato per +conferire privilegi a processi che altrimenti non avrebbero potuto ottenerli) +e un rischio per la stabilità del sistema. Le loro soluzioni di punta nel +breve periodo, comportavano un accesso alla schedulazione realtime attraverso +il meccanismo rlimit, e nel lungo periodo un costante lavoro nella riduzione +dei ritardi. + +La comunità audio, comunque, non poteva vedere al di là della singola +soluzione che avevano implementato; erano riluttanti ad accettare alternative. +Il conseguente dissenso lasciò in quegli sviluppatori un senso di +disillusione nei confronti dell'intero processo di sviluppo; uno di loro +scrisse questo messaggio: + + Ci sono numerosi sviluppatori del kernel Linux davvero bravi, ma + rischiano di restare sovrastati da una vasta massa di stolti arroganti. + Cercare di comunicare le richieste degli utenti a queste persone è + una perdita di tempo. Loro sono troppo "intelligenti" per stare ad + ascoltare dei poveri mortali. + + (http://lwn.net/Articles/131776/). + +La realtà delle cose fu differente; gli sviluppatori del kernel erano molto +più preoccupati per la stabilità del sistema, per la manutenzione di lungo +periodo e cercavano la giusta soluzione alla problematica esistente con uno +specifico modulo. La morale della storia è quella di concentrarsi sul +problema - non su di una specifica soluzione- e di discuterne con la comunità +di sviluppo prima di investire tempo nella scrittura del codice. + +Quindi, osservando un progetto di sviluppo del kernel, si dovrebbe +rispondere a questa lista di domande: + +- Qual'è, precisamente, il problema che dev'essere risolto? + +- Chi sono gli utenti coinvolti da tal problema? A quale caso dovrebbe + essere indirizzata la soluzione? + +- In che modo il kernel risulta manchevole nell'indirizzare il problema + in questione? + +Solo dopo ha senso iniziare a considerare le possibili soluzioni. + +Prime discussioni +----------------- + +Quando si pianifica un progetto di sviluppo per il kernel, sarebbe quanto meno +opportuno discuterne inizialmente con la comunità prima di lanciarsi +nell'implementazione. Una discussione preliminare può far risparmiare sia +tempo che problemi in svariati modi: + + - Potrebbe essere che il problema sia già stato risolto nel kernel in + una maniera che non avete ancora compreso. Il kernel Linux è grande e ha + una serie di funzionalità e capacità che non sono scontate nell'immediato. + Non tutte le capacità del kernel sono documentate così bene come ci + piacerebbe, ed è facile perdersi qualcosa. Il vostro autore ha assistito + alla pubblicazione di un driver intero che duplica un altro driver + esistente di cui il nuovo autore era ignaro. Il codice che rinnova + ingranaggi già esistenti non è soltanto dispendioso; non verrà nemmeno + accettato nel ramo principale del kernel. + + - Potrebbero esserci proposte che non sono considerate accettabili per + l'integrazione all'interno del ramo principale. È meglio affrontarle + prima di scrivere il codice. + + - È possibile che altri sviluppatori abbiano pensato al problema; potrebbero + avere delle idee per soluzioni migliori, e potrebbero voler contribuire + alla loro creazione. + +Anni di esperienza con la comunità di sviluppo del kernel hanno impartito una +chiara lezione: il codice per il kernel che è pensato e sviluppato a porte +chiuse, inevitabilmente, ha problematiche che si rivelano solo quando il +codice viene rilasciato pubblicamente. Qualche volta tali problemi sono +importanti e richiedono mesi o anni di sforzi prima che il codice possa +raggiungere gli standard richiesti della comunità. +Alcuni esempi possono essere: + + - La rete Devicescape è stata creata e implementata per sistemi + mono-processore. Non avrebbe potuto essere inserita nel ramo principale + fino a che non avesse supportato anche i sistemi multi-processore. + Riadattare i meccanismi di sincronizzazione e simili è un compito difficile; + come risultato, l'inserimento di questo codice (ora chiamato mac80211) + fu rimandato per più di un anno. + + - Il filesystem Reiser4 include una seria di funzionalità che, secondo + l'opinione degli sviluppatori principali del kernel, avrebbero dovuto + essere implementate a livello di filesystem virtuale. Comprende + anche funzionalità che non sono facilmente implementabili senza esporre + il sistema al rischio di uno stallo. La scoperta tardiva di questi + problemi - e il diniego a risolverne alcuni - ha avuto come conseguenza + il fatto che Raiser4 resta fuori dal ramo principale del kernel. + + - Il modulo di sicurezza AppArmor utilizzava strutture dati del + filesystem virtuale interno in modi che sono stati considerati rischiosi e + inattendibili. Questi problemi (tra le altre cose) hanno tenuto AppArmor + fuori dal ramo principale per anni. + +Ciascuno di questi casi è stato un travaglio e ha richiesto del lavoro +straordinario, cose che avrebbero potuto essere evitate con alcune +"chiacchierate" preliminari con gli sviluppatori kernel. + +Con chi parlare? +---------------- + +Quando gli sviluppatori hanno deciso di rendere pubblici i propri progetti, la +domanda successiva sarà: da dove partiamo? La risposta è quella di trovare +la giusta lista di discussione e il giusto manutentore. Per le liste di +discussione, il miglior approccio è quello di cercare la lista più adatta +nel file MAINTAINERS. Se esiste una lista di discussione di sottosistema, +è preferibile pubblicare lì piuttosto che sulla lista di discussione generale +del kernel Linux; avrete maggiori probabilità di trovare sviluppatori con +esperienza sul tema, e l'ambiente che troverete potrebbe essere più +incoraggiante. + +Trovare manutentori può rivelarsi un po' difficoltoso. Ancora, il file +MAINTAINERS è il posto giusto da dove iniziare. Il file potrebbe non essere +sempre aggiornato, inoltre, non tutti i sottosistemi sono rappresentati qui. +Coloro che sono elencati nel file MAINTAINERS potrebbero, in effetti, non +essere le persone che attualmente svolgono quel determinato ruolo. Quindi, +quando c'è un dubbio su chi contattare, un trucco utile è quello di usare +git (git log in particolare) per vedere chi attualmente è attivo all'interno +del sottosistema interessato. Controllate chi sta scrivendo le patch, +e chi, se non ci fosse nessuno, sta aggiungendo la propria firma +(Signed-off-by) a quelle patch. Quelle sono le persone maggiormente +qualificate per aiutarvi con lo sviluppo di nuovo progetto. + +Il compito di trovare il giusto manutentore, a volte, è una tale sfida che +ha spinto gli sviluppatori del kernel a scrivere uno script che li aiutasse +in questa ricerca: + +:: + + .../scripts/get_maintainer.pl + +Se questo script viene eseguito con l'opzione "-f" ritornerà il manutentore(i) +attuale per un dato file o cartella. Se viene passata una patch sulla linea di +comando, lo script elencherà i manutentori che dovrebbero riceverne una copia. +Questo è la maniera raccomandata (non quella con "-f") per ottenere la lista di +persone da aggiungere a Cc per le vostre patch. Ci sono svariate opzioni che +regolano quanto a fondo get_maintainer.pl debba cercare i manutentori; siate +quindi prudenti nell'utilizzare le opzioni più aggressive poiché potreste finire +per includere sviluppatori che non hanno un vero interesse per il codice che +state modificando. + +Se tutto ciò dovesse fallire, parlare con Andrew Morton potrebbe essere +un modo efficace per capire chi è il manutentore di un dato pezzo di codice. + +Quando pubblicare +----------------- + +Se potete, pubblicate i vostri intenti durante le fasi preliminari, sarà +molto utile. Descrivete il problema da risolvere e ogni piano che è stato +elaborato per l'implementazione. Ogni informazione fornita può aiutare +la comunità di sviluppo a fornire spunti utili per il progetto. + +Un evento che potrebbe risultare scoraggiate e che potrebbe accadere in +questa fase non è il ricevere una risposta ostile, ma, invece, ottenere +una misera o inesistente reazione. La triste verità è che: (1) gli +sviluppatori del kernel tendono ad essere occupati, (2) ci sono tante persone +con grandi progetti e poco codice (o anche solo la prospettiva di +avere un codice) a cui riferirsi e (3) nessuno è obbligato a revisionare +o a fare osservazioni in merito ad idee pubblicate da altri. Oltre a +questo, progetti di alto livello spesso nascondono problematiche che si +rivelano solo quando qualcuno cerca di implementarle; per questa ragione +gli sviluppatori kernel preferirebbero vedere il codice. + +Quindi, se una richiesta pubblica di commenti riscuote poco successo, non +pensate che ciò significhi che non ci sia interesse nel progetto. +Sfortunatamente, non potete nemmeno assumere che non ci siano problemi con +la vostra idea. La cosa migliore da fare in questa situazione è quella di +andare avanti e tenere la comunità informata mentre procedete. + +Ottenere riscontri ufficiali +---------------------------- + +Se il vostro lavoro è stato svolto in un ambiente aziendale - come molto +del lavoro fatto su Linux - dovete, ovviamente, avere il permesso dei +dirigenti prima che possiate pubblicare i progetti, o il codice aziendale, +su una lista di discussione pubblica. La pubblicazione di codice che non +è stato rilascio espressamente con licenza GPL-compatibile può rivelarsi +problematico; prima la dirigenza, e il personale legale, troverà una decisione +sulla pubblicazione di un progetto, meglio sarà per tutte le persone coinvolte. + +A questo punto, alcuni lettori potrebbero pensare che il loro lavoro sul +kernel è preposto a supportare un prodotto che non è ancora ufficialmente +riconosciuto. Rivelare le intenzioni dei propri datori di lavori in una +lista di discussione pubblica potrebbe non essere una soluzione valida. +In questi casi, vale la pena considerare se la segretezza sia necessaria +o meno; spesso non c'è una reale necessità di mantenere chiusi i progetti di +sviluppo. + +Detto ciò, ci sono anche casi dove l'azienda legittimamente non può rivelare +le proprie intenzioni in anticipo durante il processo di sviluppo. Le aziende +che hanno sviluppatori kernel esperti possono scegliere di procedere a +carte coperte partendo dall'assunto che saranno in grado di evitare, o gestire, +in futuro, eventuali problemi d'integrazione. Per le aziende senza questo tipo +di esperti, la migliore opzione è spesso quella di assumere uno sviluppatore +esterno che revisioni i progetti con un accordo di segretezza. +La Linux Foundation applica un programma di NDA creato appositamente per +aiutare le aziende in questa particolare situazione; potrete trovare più +informazioni sul sito: + + http://www.linuxfoundation.org/en/NDA_program + +Questa tipologia di revisione è spesso sufficiente per evitare gravi problemi +senza che sia richiesta l'esposizione pubblica del progetto. diff --git a/Documentation/translations/it_IT/process/4.Coding.rst b/Documentation/translations/it_IT/process/4.Coding.rst new file mode 100644 index 0000000000..54fd255b77 --- /dev/null +++ b/Documentation/translations/it_IT/process/4.Coding.rst @@ -0,0 +1,446 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/4.Coding.rst <development_coding>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_coding: + +Scrivere codice corretto +======================== + +Nonostante ci sia molto da dire sul processo di creazione, sulla sua solidità +e sul suo orientamento alla comunità, la prova di ogni progetto di sviluppo +del kernel si trova nel codice stesso. È il codice che sarà esaminato dagli +altri sviluppatori ed inserito (o no) nel ramo principale. Quindi è la +qualità di questo codice che determinerà il successo finale del progetto. + +Questa sezione esaminerà il processo di codifica. Inizieremo con uno sguardo +sulle diverse casistiche nelle quali gli sviluppatori kernel possono +sbagliare. Poi, l'attenzione si sposterà verso "il fare le cose +correttamente" e sugli strumenti che possono essere utili in questa missione. + +Trappole +-------- + +Lo stile del codice +******************* + +Il kernel ha da tempo delle norme sullo stile di codifica che sono descritte in +:ref:`Documentation/translations/it_IT/process/coding-style.rst <codingstyle>`. +Per la maggior parte del tempo, la politica descritta in quel file è stata +praticamente informativa. Ne risulta che ci sia una quantità sostanziale di +codice nel kernel che non rispetta le linee guida relative allo stile. +La presenza di quel codice conduce a due distinti pericoli per gli +sviluppatori kernel. + +Il primo di questi è credere che gli standard di codifica del kernel +non sono importanti e possono non essere applicati. La verità è che +aggiungere nuovo codice al kernel è davvero difficile se questo non +rispetta le norme; molti sviluppatori richiederanno che il codice sia +riformulato prima che anche solo lo revisionino. Una base di codice larga +quanto il kernel richiede una certa uniformità, in modo da rendere possibile +per gli sviluppatori una comprensione veloce di ogni sua parte. Non ci sono, +quindi, più spazi per un codice formattato alla carlona. + +Occasionalmente, lo stile di codifica del kernel andrà in conflitto con lo +stile richiesto da un datore di lavoro. In alcuni casi, lo stile del kernel +dovrà prevalere prima che il codice venga inserito. Mettere il codice +all'interno del kernel significa rinunciare a un certo grado di controllo +in differenti modi - incluso il controllo sul come formattare il codice. + +L’altra trappola è quella di pensare che il codice già presente nel kernel +abbia urgentemente bisogno di essere sistemato. Gli sviluppatori potrebbero +iniziare a generare patch che correggono lo stile come modo per prendere +famigliarità con il processo, o come modo per inserire i propri nomi nei +changelog del kernel – o entrambe. La comunità di sviluppo vede un attività +di codifica puramente correttiva come "rumore"; queste attività riceveranno +una fredda accoglienza. Di conseguenza è meglio evitare questo tipo di patch. +Mentre si lavora su un pezzo di codice è normale correggerne anche lo stile, +ma le modifiche di stile non dovrebbero essere fatte fini a se stesse. + +Il documento sullo stile del codice non dovrebbe essere letto come una legge +assoluta che non può mai essere trasgredita. Se c’è un a buona ragione +(per esempio, una linea che diviene poco leggibile se divisa per rientrare +nel limite di 80 colonne), fatelo e basta. + +Notate che potete utilizzare lo strumento “clang-format” per aiutarvi con +le regole, per una riformattazione automatica e veloce del vostro codice +e per revisionare interi file per individuare errori nello stile di codifica, +refusi e possibili miglioramenti. Inoltre è utile anche per classificare gli +``#includes``, per allineare variabili/macro, per testi derivati ed altri +compiti del genere. Consultate il file +:ref:`Documentation/translations/it_IT/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 KCFLAGS=-W" per ottenerli tutti. + +Il kernel fornisce differenti opzioni che abilitano funzionalità di debugging; +molti di queste sono trovano all'interno del sotto menu "kernel hacking". +La maggior parte di queste opzioni possono essere attivate per qualsiasi +kernel utilizzato per lo sviluppo o a scopo di test. In particolare dovreste +attivare: + + - FRAME_WARN per ottenere degli avvertimenti su stack frame più + grandi di un dato valore. Il risultato generato da questi + avvertimenti può risultare verboso, ma non bisogna preoccuparsi per + gli avvertimenti provenienti da altre parti del kernel. + + - DEBUG_OBJECTS aggiungerà un codice per tracciare il ciclo di vita di + diversi oggetti creati dal kernel e avvisa quando qualcosa viene eseguito + fuori controllo. Se state aggiungendo un sottosistema che crea (ed + esporta) oggetti complessi propri, considerate l'aggiunta di un supporto + al debugging dell'oggetto. + + - DEBUG_SLAB può trovare svariati errori di uso e di allocazione di memoria; + esso dovrebbe esser usato dalla maggior parte dei kernel di sviluppo. + + - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP, e DEBUG_MUTEXES troveranno un certo + numero di errori comuni di sincronizzazione. + +Esistono ancora delle altre opzioni di debugging, di alcune di esse +discuteremo qui sotto. Alcune di esse hanno un forte impatto e non dovrebbero +essere usate tutte le volte. Ma qualche volta il tempo speso nell'capire +le opzioni disponibili porterà ad un risparmio di tempo nel breve termine. + +Uno degli strumenti di debugging più tosti è il *locking checker*, o +"lockdep". Questo strumento traccerà qualsiasi acquisizione e rilascio di +ogni *lock* (spinlock o mutex) nel sistema, l'ordine con il quale i *lock* +sono acquisiti in relazione l'uno con l'altro, l'ambiente corrente di +interruzione, eccetera. Inoltre esso può assicurare che i *lock* vengano +acquisiti sempre nello stesso ordine, che le stesse assunzioni sulle +interruzioni si applichino in tutte le occasioni, e così via. In altre parole, +lockdep può scovare diversi scenari nei quali il sistema potrebbe, in rari +casi, trovarsi in stallo. Questa tipologia di problema può essere grave +(sia per gli sviluppatori che per gli utenti) in un sistema in uso; lockdep +permette di trovare tali problemi automaticamente e in anticipo. + +In qualità di programmatore kernel diligente, senza dubbio, dovrete controllare +il valore di ritorno di ogni operazione (come l'allocazione della memoria) +poiché esso potrebbe fallire. Il nocciolo della questione è che i percorsi +di gestione degli errori, con grande probabilità, non sono mai stati +collaudati del tutto. Il codice collaudato tende ad essere codice bacato; +potrete quindi essere più a vostro agio con il vostro codice se tutti questi +percorsi fossero stati verificati un po' di volte. + +Il kernel fornisce un framework per l'inserimento di fallimenti che fa +esattamente al caso, specialmente dove sono coinvolte allocazioni di memoria. +Con l'opzione per l'inserimento dei fallimenti abilitata, una certa percentuale +di allocazione di memoria sarà destinata al fallimento; questi fallimenti +possono essere ridotti ad uno specifico pezzo di codice. Procedere con +l'inserimento dei fallimenti attivo permette al programmatore di verificare +come il codice risponde quando le cose vanno male. Consultate: +Documentation/fault-injection/fault-injection.rst per avere maggiori +informazioni su come utilizzare questo strumento. + +Altre tipologie di errori possono essere riscontrati con lo strumento di +analisi statica "sparse". Con Sparse, il programmatore può essere avvisato +circa la confusione tra gli indirizzi dello spazio utente e dello spazio +kernel, un miscuglio fra quantità big-endian e little-endian, il passaggio +di un valore intero dove ci sia aspetta un gruppo di flag, e così via. +Sparse deve essere installato separatamente (se il vostra distribuzione non +lo prevede, potete trovarlo su https://sparse.wiki.kernel.org/index.php/Main_Page); +può essere attivato sul codice aggiungendo "C=1" al comando make. + +Lo strumento "Coccinelle" (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. diff --git a/Documentation/translations/it_IT/process/5.Posting.rst b/Documentation/translations/it_IT/process/5.Posting.rst new file mode 100644 index 0000000000..a7e2a32384 --- /dev/null +++ b/Documentation/translations/it_IT/process/5.Posting.rst @@ -0,0 +1,367 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/5.Posting.rst <development_posting>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_development_posting: + +Pubblicare modifiche +==================== + +Prima o poi arriva il momento in cui il vostro lavoro è pronto per essere +presentato alla comunità per una revisione ed eventualmente per la sua +inclusione nel ramo principale del kernel. Com'era prevedibile, +la comunità di sviluppo del kernel ha elaborato un insieme di convenzioni +e di procedure per la pubblicazione delle patch; seguirle renderà la vita +più facile a tutti quanti. Questo documento cercherà di coprire questi +argomenti con un ragionevole livello di dettaglio; più informazioni possono +essere trovare nella cartella 'Documentation', nei file +:ref:`translations/it_IT/process/submitting-patches.rst <it_submittingpatches>` +e :ref:`translations/it_IT/process/submit-checklist.rst <it_submitchecklist>`. + + +Quando pubblicarle +------------------ + +C'è sempre una certa resistenza nel pubblicare patch finché non sono +veramente "pronte". Per semplici patch questo non è un problema. +Ma quando il lavoro è di una certa complessità, c'è molto da guadagnare +dai riscontri che la comunità può darvi prima che completiate il lavoro. +Dovreste considerare l'idea di pubblicare un lavoro incompleto, o anche +preparare un ramo git disponibile agli sviluppatori interessati, cosicché +possano stare al passo col vostro lavoro in qualunque momento. + +Quando pubblicate del codice che non è considerato pronto per l'inclusione, +è bene che lo diciate al momento della pubblicazione. Inoltre, aggiungete +informazioni sulle cose ancora da sviluppare e sui problemi conosciuti. +Poche persone guarderanno delle patch che si sa essere fatte a metà, +ma quelli che lo faranno penseranno di potervi aiutare a condurre il vostro +sviluppo nella giusta direzione. + + +Prima di creare patch +--------------------- + +Ci sono un certo numero di cose che dovreste fare prima di considerare +l'invio delle patch alla comunità di sviluppo. Queste cose includono: + + - Verificare il codice fino al massimo che vi è consentito. Usate gli + strumenti di debug del kernel, assicuratevi che il kernel compili con + tutte le più ragionevoli combinazioni d'opzioni, usate cross-compilatori + per compilare il codice per differenti architetture, eccetera. + + - Assicuratevi che il vostro codice sia conforme alla linee guida del + kernel sullo stile del codice. + + - La vostra patch ha delle conseguenze in termini di prestazioni? + Se è così, dovreste eseguire dei *benchmark* che mostrino il loro + impatto (anche positivo); un riassunto dei risultati dovrebbe essere + incluso nella patch. + + - Siate certi d'avere i diritti per pubblicare il codice. Se questo + lavoro è stato fatto per un datore di lavoro, egli avrà dei diritti su + questo lavoro e dovrà quindi essere d'accordo alla sua pubblicazione + con una licenza GPL + +Come regola generale, pensarci un po' di più prima di inviare il codice +ripaga quasi sempre lo sforzo. + + +Preparazione di una patch +------------------------- + +La preparazione delle patch per la pubblicazione può richiedere una quantità +di lavoro significativa, ma, ripetiamolo ancora, generalmente sconsigliamo +di risparmiare tempo in questa fase, anche sul breve periodo. + +Le patch devono essere preparate per una specifica versione del kernel. +Come regola generale, una patch dovrebbe basarsi sul ramo principale attuale +così come lo si trova nei sorgenti git di Linus. Quando vi basate sul ramo +principale, cominciate da un punto di rilascio ben noto - uno stabile o +un -rc - piuttosto che creare il vostro ramo da quello principale in un punto +a caso. + +Per facilitare una revisione e una verifica più estesa, potrebbe diventare +necessaria la produzione di versioni per -mm, linux-next o i sorgenti di un +sottosistema. Basare questa patch sui suddetti sorgenti potrebbe richiedere +un lavoro significativo nella risoluzione dei conflitti e nella correzione dei +cambiamenti di API; questo potrebbe variare a seconda dell'area d'interesse +della vostra patch e da quello che succede altrove nel kernel. + +Solo le modifiche più semplici dovrebbero essere preparate come una singola +patch; tutto il resto dovrebbe essere preparato come una serie logica di +modifiche. Spezzettare le patch è un po' un'arte; alcuni sviluppatori +passano molto tempo nel capire come farlo in modo che piaccia alla comunità. +Ci sono alcune regole spannometriche, che comunque possono aiutare +considerevolmente: + + - La serie di patch che pubblicherete, quasi sicuramente, non sarà + come quella che trovate nel vostro sistema di controllo di versione. + Invece, le vostre modifiche dovranno essere considerate nella loro forma + finale, e quindi separate in parti che abbiano un senso. Gli sviluppatori + sono interessati in modifiche che siano discrete e indipendenti, non + alla strada che avete percorso per ottenerle. + + - Ogni modifica logicamente indipendente dovrebbe essere preparata come una + patch separata. Queste modifiche possono essere piccole ("aggiunto un + campo in questa struttura") o grandi (l'aggiunta di un driver nuovo, + per esempio), ma dovrebbero essere concettualmente piccole da permettere + una descrizione in una sola riga. Ogni patch dovrebbe fare modifiche + specifiche che si possano revisionare indipendentemente e di cui si possa + verificare la veridicità. + + - Giusto per riaffermare quando detto sopra: non mischiate diversi tipi di + modifiche nella stessa patch. Se una modifica corregge un baco critico + per la sicurezza, riorganizza alcune strutture, e riformatta il codice, + ci sono buone probabilità che venga ignorata e che la correzione importante + venga persa. + + - Ogni modifica dovrebbe portare ad un kernel che compila e funziona + correttamente; se la vostra serie di patch si interrompe a metà il + risultato dovrebbe essere comunque un kernel funzionante. L'applicazione + parziale di una serie di patch è uno scenario comune nel quale il + comando "git bisect" viene usato per trovare delle regressioni; se il + risultato è un kernel guasto, renderete la vita degli sviluppatori più + difficile così come quella di chi s'impegna nel nobile lavoro di + scovare i problemi. + + - Però, non strafate. Una volta uno sviluppatore pubblicò una serie di 500 + patch che modificavano un unico file - un atto che non lo rese la persona + più popolare sulla lista di discussione del kernel. Una singola patch + può essere ragionevolmente grande fintanto che contenga un singolo + cambiamento *logico*. + + - Potrebbe essere allettante l'idea di aggiungere una nuova infrastruttura + come una serie di patch, ma di lasciare questa infrastruttura inutilizzata + finché l'ultima patch della serie non abilita tutto quanto. Quando è + possibile, questo dovrebbe essere evitato; se questa serie aggiunge delle + regressioni, "bisect" indicherà quest'ultima patch come causa del + problema anche se il baco si trova altrove. Possibilmente, quando una + patch aggiunge del nuovo codice dovrebbe renderlo attivo immediatamente. + +Lavorare per creare la serie di patch perfetta potrebbe essere frustrante +perché richiede un certo tempo e soprattutto dopo che il "vero lavoro" è +già stato fatto. Quando ben fatto, comunque, è tempo ben speso. + + +Formattazione delle patch e i changelog +--------------------------------------- + +Quindi adesso avete una serie perfetta di patch pronte per la pubblicazione, +ma il lavoro non è davvero finito. Ogni patch deve essere preparata con +un messaggio che spieghi al resto del mondo, in modo chiaro e veloce, +il suo scopo. Per ottenerlo, ogni patch sarà composta dai seguenti elementi: + + - Un campo opzionale "From" col nome dell'autore della patch. Questa riga + è necessaria solo se state passando la patch di qualcun altro via email, + ma nel dubbio non fa di certo male aggiungerlo. + + - Una descrizione di una riga che spieghi cosa fa la patch. Questo + messaggio dovrebbe essere sufficiente per far comprendere al lettore lo + scopo della patch senza altre informazioni. Questo messaggio, + solitamente, presenta in testa il nome del sottosistema a cui si riferisce, + seguito dallo scopo della patch. Per esempio: + + :: + + gpio: fix build on CONFIG_GPIO_SYSFS=n + + - Una riga bianca seguita da una descrizione dettagliata della patch. + Questa descrizione può essere lunga tanto quanto serve; dovrebbe spiegare + cosa fa e perché dovrebbe essere aggiunta al kernel. + + - Una o più righe etichette, con, minimo, una riga *Signed-off-by:* + col nome dall'autore della patch. Queste etichette verranno descritte + meglio più avanti. + +Gli elementi qui sopra, assieme, formano il changelog di una patch. +Scrivere un buon changelog è cruciale ma è spesso un'arte trascurata; +vale la pena spendere qualche parola in più al riguardo. Quando scrivete +un changelog dovreste tenere ben presente che molte persone leggeranno +le vostre parole. Queste includono i manutentori di un sotto-sistema, e i +revisori che devono decidere se la patch debba essere inclusa o no, +le distribuzioni e altri manutentori che cercano di valutare se la patch +debba essere applicata su kernel più vecchi, i cacciatori di bachi che si +chiederanno se la patch è la causa di un problema che stanno cercando, +gli utenti che vogliono sapere com'è cambiato il kernel, e molti altri. +Un buon changelog fornisce le informazioni necessarie a tutte queste +persone nel modo più diretto e conciso possibile. + +A questo scopo, la riga riassuntiva dovrebbe descrivere gli effetti della +modifica e la motivazione della patch nel modo migliore possibile nonostante +il limite di una sola riga. La descrizione dettagliata può spiegare meglio +i temi e fornire maggiori informazioni. Se una patch corregge un baco, +citate, se possibile, il commit che lo introdusse (e per favore, quando +citate un commit aggiungete sia il suo identificativo che il titolo), +Se il problema è associabile ad un file di log o all' output del compilatore, +includeteli al fine d'aiutare gli altri a trovare soluzioni per lo stesso +problema. Se la modifica ha lo scopo di essere di supporto a sviluppi +successivi, ditelo. Se le API interne vengono cambiate, dettagliate queste +modifiche e come gli altri dovrebbero agire per applicarle. In generale, +più riuscirete ad entrare nei panni di tutti quelli che leggeranno il +vostro changelog, meglio sarà il changelog (e il kernel nel suo insieme). + +Non serve dirlo, un changelog dovrebbe essere il testo usato nel messaggio +di commit in un sistema di controllo di versione. Sarà seguito da: + + - La patch stessa, nel formato unificato per patch ("-u"). Usare + l'opzione "-p" assocerà alla modifica il nome della funzione alla quale + si riferisce, rendendo il risultato più facile da leggere per gli altri. + +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 sopracitate danno un'idea di come una patch prende vita e sono +descritte nel dettaglio nel documento +:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`. +Qui di seguito un breve riassunto. + +Un'etichetta ci può dire quale commit ha introdotto il problema che viene corretto nella patch:: + + Fixes: 1f2e3d4c5b6a ("The first line of the commit specified by the first 12 characters of its SHA-1 ID") + +Un'altra etichetta viene usata per fornire collegamenti a pagine web contenenti +maggiori informazioni, per esempio un rapporto circa il baco risolto dalla +patch, oppure un documento con le specifiche implementate dalla patch:: + + Link: https://example.com/somewhere.html optional-other-stuff + +Alcuni manutentori aggiungono quest'etichetta alla patch per fare riferimento +alla più recente discussione pubblica. A volte questo è fatto automaticamente da +alcuni strumenti come b4 or un *hook* git come quello descritto qui +'Documentation/translations/it_IT/maintainer/configure-git.rst' + +Un terzo tipo di etichetta viene usato per indicare chi ha contribuito allo +sviluppo della patch. Tutte queste etichette seguono il formato:: + + tag: Full Name <email address> optional-other-stuff + +Le etichette in uso più comuni sono: + + - Signed-off-by: questa è la certificazione che lo sviluppatore ha il diritto + di sottomettere la patch per l'integrazione nel kernel. Questo rappresenta + il consenso verso il certificato d'origine degli sviluppatori, il testo + completo potrà essere trovato in + :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`. + Codice che non presenta una firma appropriata non potrà essere integrato. + + - Co-developed-by: indica che la patch è stata cosviluppata da diversi + sviluppatori; viene usato per assegnare più autori (in aggiunta a quello + associato all'etichetta From:) quando più persone lavorano ad una patch. + Ogni Co-developed-by: dev'essere seguito immediatamente da un Signed-off-by: + del corrispondente coautore. Maggiori dettagli ed esempi sono disponibili + in :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`. + + - Acked-by: indica il consenso di un altro sviluppatore (spesso il manutentore + del codice in oggetto) all'integrazione della patch nel kernel. + + - Tested-by: menziona la persona che ha verificato la patch e l'ha trovata + funzionante. + + - Reviwed-by: menziona lo sviluppatore che ha revisionato la patch; per + maggiori dettagli leggete la dichiarazione dei revisori in + :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>` + + - Reported-by: menziona l'utente che ha riportato il problema corretto da + questa patch; quest'etichetta viene usata per dare credito alle persone che + hanno verificato il codice e ci hanno fatto sapere quando le cose non + funzionavano correttamente. Se esiste un rapporto disponibile sul web, allora + L'etichetta dovrebbe essere seguita da un collegamento al suddetto rapporto. + + - Cc: la persona menzionata ha ricevuto una copia della patch ed ha avuto + l'opportunità di commentarla. + +State attenti ad aggiungere queste etichette alla vostra patch: solo "Cc:" può +essere aggiunta senza il permesso esplicito della persona menzionata. Il più +delle volte anche Reported-by: va bene, ma è sempre meglio chiedere specialmente +se il baco è stato riportato in una comunicazione privata. + +Inviare la modifica +------------------- + +Prima di inviare la vostra patch, ci sarebbero ancora un paio di cose di cui +dovreste aver cura: + + - Siete sicuri che il vostro programma di posta non corromperà le patch? + Le patch che hanno spazi bianchi in libertà o andate a capo aggiunti + dai programmi di posta non funzioneranno per chi le riceve, e spesso + non verranno nemmeno esaminate in dettaglio. Se avete un qualsiasi dubbio, + inviate la patch a voi stessi e verificate che sia integra. + + :ref:`Documentation/translations/it_IT/process/email-clients.rst <it_email_clients>` + contiene alcuni suggerimenti utili sulla configurazione dei programmi + di posta al fine di inviare patch. + + - Siete sicuri che la vostra patch non contenga sciocchi errori? Dovreste + sempre processare le patch con scripts/checkpatch.pl e correggere eventuali + problemi riportati. Per favore tenete ben presente che checkpatch.pl non è + più intelligente di voi, nonostante sia il risultato di un certa quantità di + ragionamenti su come debba essere una patch per il kernel. Se seguire + i suggerimenti di checkpatch.pl rende il codice peggiore, allora non fatelo. + +Le patch dovrebbero essere sempre inviate come testo puro. Per favore non +inviatele come allegati; questo rende molto più difficile, per i revisori, +citare parti della patch che si vogliono commentare. Invece, mettete la vostra +patch direttamente nel messaggio. + +Quando inviate le patch, è importante inviarne una copia a tutte le persone che +potrebbero esserne interessate. Al contrario di altri progetti, il kernel +incoraggia le persone a peccare nell'invio di tante copie; non presumente che +le persone interessate vedano i vostri messaggi sulla lista di discussione. +In particolare le copie dovrebbero essere inviate a: + + - I manutentori dei sottosistemi affetti della modifica. Come descritto + in precedenza, il file MAINTAINERS è il primo luogo dove cercare i nomi + di queste persone. + + - Altri sviluppatori che hanno lavorato nello stesso ambiente - specialmente + quelli che potrebbero lavorarci proprio ora. Usate git potrebbe essere + utile per vedere chi altri ha modificato i file su cui state lavorando. + + - Se state rispondendo a un rapporto su un baco, o a una richiesta di + funzionalità, includete anche gli autori di quei rapporti/richieste. + + - Inviate una copia alle liste di discussione interessate, o, se nient'altro + è adatto, alla lista linux-kernel + + - Se state correggendo un baco, pensate se la patch dovrebbe essere inclusa + nel prossimo rilascio stabile. Se è così, la lista di discussione + stable@vger.kernel.org dovrebbe riceverne una copia. Aggiungete anche + l'etichetta "Cc: stable@vger.kernel.org" nella patch stessa; questo + permetterà alla squadra *stable* di ricevere una notifica quando questa + correzione viene integrata nel ramo principale. + +Quando scegliete i destinatari della patch, è bene avere un'idea di chi +pensiate che sia colui che, eventualmente, accetterà la vostra patch e +la integrerà. Nonostante sia possibile inviare patch direttamente a +Linus Torvalds, e lasciare che sia lui ad integrarle,solitamente non è la +strada migliore da seguire. Linus è occupato, e ci sono dei manutentori di +sotto-sistema che controllano una parte specifica del kernel. Solitamente, +vorreste che siano questi manutentori ad integrare le vostre patch. Se non +c'è un chiaro manutentore, l'ultima spiaggia è spesso Andrew Morton. + +Le patch devono avere anche un buon oggetto. Il tipico formato per l'oggetto +di una patch assomiglia a questo: + +:: + + [PATCH nn/mm] subsys: one-line description of the patch + +dove "nn" è il numero ordinale della patch, "mm" è il numero totale delle patch +nella serie, e "subsys" è il nome del sottosistema interessato. Chiaramente, +nn/mm può essere omesso per una serie composta da una singola patch. + +Se avete una significative serie di patch, è prassi inviare una descrizione +introduttiva come parte zero. Tuttavia questa convenzione non è universalmente +seguita; se la usate, ricordate che le informazioni nell'introduzione non +faranno parte del changelog del kernel. Quindi per favore, assicuratevi che +ogni patch abbia un changelog completo. + +In generale, la seconda parte e quelle successive di una patch "composta" +dovrebbero essere inviate come risposta alla prima, cosicché vengano viste +come un unico *thread*. Strumenti come git e quilt hanno comandi per inviare +gruppi di patch con la struttura appropriata. Se avete una serie lunga +e state usando git, per favore state alla larga dall'opzione --chain-reply-to +per evitare di creare un annidamento eccessivo. diff --git a/Documentation/translations/it_IT/process/6.Followthrough.rst b/Documentation/translations/it_IT/process/6.Followthrough.rst new file mode 100644 index 0000000000..df7d5fb288 --- /dev/null +++ b/Documentation/translations/it_IT/process/6.Followthrough.rst @@ -0,0 +1,240 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/6.Followthrough.rst <development_followthrough>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_followthrough: + +============= +Completamento +============= + +A questo punto, avete seguito le linee guida fino a questo punto e, con +l'aggiunta delle vostre capacità ingegneristiche, avete pubblicato una serie +perfetta di patch. Uno dei più grandi errori che possono essere commessi +persino da sviluppatori kernel esperti è quello di concludere che il +lavoro sia ormai finito. In verità, la pubblicazione delle patch +simboleggia una transizione alla fase successiva del processo, con, +probabilmente, ancora un po' di lavoro da fare. + +È raro che una modifica sia così bella alla sua prima pubblicazione che non +ci sia alcuno spazio di miglioramento. Il programma di sviluppo del kernel +riconosce questo fatto e quindi, è fortemente orientato al miglioramento +del codice pubblicato. Voi, in qualità di autori del codice, dovrete +lavorare con la comunità del kernel per assicurare che il vostro codice +mantenga gli standard qualitativi richiesti. Un fallimento in questo +processo è quasi come impedire l'inclusione delle vostre patch nel +ramo principale. + +Lavorare con i revisori +======================= + +Una patch che abbia una certa rilevanza avrà ricevuto numerosi commenti +da parte di altri sviluppatori dato che avranno revisionato il codice. +Lavorare con i revisori può rivelarsi, per molti sviluppatori, la parte +più intimidatoria del processo di sviluppo del kernel. La vita può esservi +resa molto più facile se tenete presente alcuni dettagli: + + - Se avete descritto la vostra modifica correttamente, i revisori ne + comprenderanno il valore e il perché vi siete presi il disturbo di + scriverla. Ma tale valore non li tratterrà dal porvi una domanda + fondamentale: come verrà mantenuto questo codice nel kernel nei prossimi + cinque o dieci anni? Molti dei cambiamenti che potrebbero esservi + richiesti - da piccoli problemi di stile a sostanziali ristesure - + vengono dalla consapevolezza che Linux resterà in circolazione e in + continuo sviluppo ancora per diverse decadi. + + - La revisione del codice è un duro lavoro, ed è un mestiere poco + riconosciuto; le persone ricordano chi ha scritto il codice, ma meno + fama è attribuita a chi lo ha revisionato. Quindi i revisori potrebbero + divenire burberi, specialmente quando vendono i medesimi errori venire + fatti ancora e ancora. Se ricevete una revisione che vi sembra abbia + un tono arrabbiato, insultante o addirittura offensivo, resistente alla + tentazione di rispondere a tono. La revisione riguarda il codice e non + la persona, e i revisori non vi stanno attaccando personalmente. + + - Similarmente, i revisori del codice non stanno cercando di promuovere + i loro interessi a vostre spese. Gli sviluppatori del kernel spesso si + aspettano di lavorare sul kernel per anni, ma sanno che il loro datore + di lavoro può cambiare. Davvero, senza praticamente eccezioni, loro + stanno lavorando per la creazione del miglior kernel possibile; non + stanno cercando di creare un disagio ad aziende concorrenti. + +Quello che si sta cercando di dire è che, quando i revisori vi inviano degli +appunti dovete fare attenzione alle osservazioni tecniche che vi stanno +facendo. Non lasciate che il loro modo di esprimersi o il vostro orgoglio +impediscano che ciò accada. Quando avete dei suggerimenti sulla revisione, +prendetevi il tempo per comprendere cosa il revisore stia cercando di +comunicarvi. Se possibile, sistemate le cose che il revisore vi chiede di +modificare. E rispondete al revisore ringraziandolo e spiegando come +intendete fare. + +Notate che non dovete per forza essere d'accordo con ogni singola modifica +suggerita dai revisori. Se credete che il revisore non abbia compreso +il vostro codice, spiegateglielo. Se avete un'obiezione tecnica da fargli +su di una modifica suggerita, spiegatela inserendo anche la vostra soluzione +al problema. Se la vostra spiegazione ha senso, il revisore la accetterà. +Tuttavia, la vostra motivazione potrebbe non essere del tutto persuasiva, +specialmente se altri iniziano ad essere d'accordo con il revisore. +Prendetevi quindi un po' di tempo per pensare ancora alla cosa. Può risultare +facile essere accecati dalla propria soluzione al punto che non realizzate che +c'è qualcosa di fondamentalmente sbagliato o, magari, non state nemmeno +risolvendo il problema giusto. + +Andrew Morton suggerisce che ogni suggerimento di revisione che non è +presente nella modifica del codice dovrebbe essere inserito in un commento +aggiuntivo; ciò può essere d'aiuto ai futuri revisori nell'evitare domande +che sorgono al primo sguardo. + +Un errore fatale è quello di ignorare i commenti di revisione nella speranza +che se ne andranno. Non andranno via. Se pubblicherete nuovamente il +codice senza aver risposto ai commenti ricevuti, probabilmente le vostre +modifiche non andranno da nessuna parte. + +Parlando di ripubblicazione del codice: per favore tenete a mente che i +revisori non ricorderanno tutti i dettagli del codice che avete pubblicato +l'ultima volta. Quindi è sempre una buona idea quella di ricordare ai +revisori le questioni sollevate precedetemene e come le avete risolte. +I revisori non dovrebbero star lì a cercare all'interno degli archivi per +famigliarizzare con ciò che è stato detto l'ultima volta; se li aiutate +in questo senso, saranno di umore migliore quando riguarderanno il vostro +codice. + +Se invece avete cercato di far tutto correttamente ma le cose continuano +a non andar bene? Molti disaccordi di natura tecnica possono essere risolti +attraverso la discussione, ma ci sono volte dove qualcuno deve prendere +una decisione. Se credete veramente che tale decisione andrà contro di voi +ingiustamente, potete sempre tentare di rivolgervi a qualcuno più +in alto di voi. Per cose di questo genere la persona con più potere è +Andrew Morton. Andrew è una figura molto rispettata all'interno della +comunità di sviluppo del kernel; lui può spesso sbrogliare situazioni che +sembrano irrimediabilmente bloccate. Rivolgersi ad Andrew non deve essere +fatto alla leggera, e non deve essere fatto prima di aver esplorato tutte +le altre alternative. E tenete a mente, ovviamente, che nemmeno lui +potrebbe non essere d'accordo con voi. + +Cosa accade poi +=============== + +Se la modifica è ritenuta un elemento valido da essere aggiunta al kernel, +e una volta che la maggior parte degli appunti dei revisori sono stati +sistemati, il passo successivo solitamente è quello di entrare in un +sottosistema gestito da un manutentore. Come ciò avviene dipende dal +sottosistema medesimo; ogni manutentore ha il proprio modo di fare le cose. +In particolare, ci potrebbero essere diversi sorgenti - uno, magari, dedicato +alle modifiche pianificate per la finestra di fusione successiva, e un altro +per il lavoro di lungo periodo. + +Per le modifiche proposte in aree per le quali non esiste un sottosistema +preciso (modifiche di gestione della memoria, per esempio), i sorgenti di +ripiego finiscono per essere -mm. Ed anche le modifiche che riguardano +più sottosistemi possono finire in quest'ultimo. + +L'inclusione nei sorgenti di un sottosistema può comportare per una patch, +un alto livello di visibilità. Ora altri sviluppatori che stanno lavorando +in quei medesimi sorgenti avranno le vostre modifiche. I sottosistemi +solitamente riforniscono anche Linux-next, rendendo i propri contenuti +visibili all'intera comunità di sviluppo. A questo punto, ci sono buone +possibilità per voi di ricevere ulteriori commenti da un nuovo gruppo di +revisori; anche a questi commenti dovrete rispondere come avete già fatto per +gli altri. + +Ciò che potrebbe accadere a questo punto, in base alla natura della vostra +modifica, riguarda eventuali conflitti con il lavoro svolto da altri. +Nella peggiore delle situazioni, i conflitti più pesanti tra modifiche possono +concludersi con la messa a lato di alcuni dei lavori svolti cosicché le +modifiche restanti possano funzionare ed essere integrate. Altre volte, la +risoluzione dei conflitti richiederà del lavoro con altri sviluppatori e, +possibilmente, lo spostamento di alcune patch da dei sorgenti a degli altri +in modo da assicurare che tutto sia applicato in modo pulito. Questo lavoro +può rivelarsi una spina nel fianco, ma consideratevi fortunati: prima +dell'avvento dei sorgenti linux-next, questi conflitti spesso emergevano solo +durante l'apertura della finestra di integrazione e dovevano essere smaltiti +in fretta. Ora essi possono essere risolti comodamente, prima dell'apertura +della finestra. + +Un giorno, se tutto va bene, vi collegherete e vedrete che la vostra patch +è stata inserita nel ramo principale de kernel. Congratulazioni! Terminati +i festeggiamenti (nel frattempo avrete inserito il vostro nome nel file +MAINTAINERS) vale la pena ricordare una piccola cosa, ma importante: il +lavoro non è ancora finito. L'inserimento nel ramo principale porta con se +nuove sfide. + +Cominciamo con il dire che ora la visibilità della vostra modifica è +ulteriormente cresciuta. Ci potrebbe portare ad una nuova fase di +commenti dagli sviluppatori che non erano ancora a conoscenza della vostra +patch. Ignorarli potrebbe essere allettante dato che non ci sono più +dubbi sull'integrazione della modifica. Resistete a tale tentazione, dovete +mantenervi disponibili agli sviluppatori che hanno domande o suggerimenti +per voi. + +Ancora più importante: l'inclusione nel ramo principale mette il vostro +codice nelle mani di un gruppo di *tester* molto più esteso. Anche se avete +contribuito ad un driver per un hardware che non è ancora disponibile, sarete +sorpresi da quante persone inseriranno il vostro codice nei loro kernel. +E, ovviamente, dove ci sono *tester*, ci saranno anche dei rapporti su +eventuali bachi. + +La peggior specie di rapporti sono quelli che indicano delle regressioni. +Se la vostra modifica causa una regressione, avrete un gran numero di +occhi puntati su di voi; la regressione deve essere sistemata il prima +possibile. Se non vorrete o non sarete capaci di sistemarla (e nessuno +lo farà per voi), la vostra modifica sarà quasi certamente rimossa durante +la fase di stabilizzazione. Oltre alla perdita di tutto il lavoro svolto +per far si che la vostra modifica fosse inserita nel ramo principale, +l'avere una modifica rimossa a causa del fallimento nel sistemare una +regressione, potrebbe rendere più difficile per voi far accettare +il vostro lavoro in futuro. + +Dopo che ogni regressione è stata affrontata, ci potrebbero essere altri +bachi ordinari da "sconfiggere". Il periodo di stabilizzazione è la +vostra migliore opportunità per sistemare questi bachi e assicurarvi che +il debutto del vostro codice nel ramo principale del kernel sia il più solido +possibile. Quindi, per favore, rispondete ai rapporti sui bachi e ponete +rimedio, se possibile, a tutti i problemi. È a questo che serve il periodo +di stabilizzazione; potete iniziare creando nuove fantastiche modifiche +una volta che ogni problema con le vecchie sia stato risolto. + +Non dimenticate che esistono altre pietre miliari che possono generare +rapporti sui bachi: il successivo rilascio stabile, quando una distribuzione +importante usa una versione del kernel nel quale è presente la vostra +modifica, eccetera. Il continuare a rispondere a questi rapporti è fonte di +orgoglio per il vostro lavoro. Se questa non è una sufficiente motivazione, +allora, è anche consigliabile considera che la comunità di sviluppo ricorda +gli sviluppatori che hanno perso interesse per il loro codice una volta +integrato. La prossima volta che pubblicherete una patch, la comunità +la valuterà anche sulla base del fatto che non sarete disponibili a +prendervene cura anche nel futuro. + + +Altre cose che posso accadere +============================= + +Un giorno, potreste aprire la vostra email e vedere che qualcuno vi ha +inviato una patch per il vostro codice. Questo, dopo tutto, è uno dei +vantaggi di avere il vostro codice "là fuori". Se siete d'accordo con +la modifica, potrete anche inoltrarla ad un manutentore di sottosistema +(assicuratevi di includere la riga "From:" cosicché l'attribuzione sia +corretta, e aggiungete una vostra firma "Signed-off-by"), oppure inviate +un "Acked-by:" e lasciate che l'autore originale la invii. + +Se non siete d'accordo con la patch, inviate una risposta educata +spiegando il perché. Se possibile, dite all'autore quali cambiamenti +servirebbero per rendere la patch accettabile da voi. C'è una certa +riluttanza nell'inserire modifiche con un conflitto fra autore +e manutentore del codice, ma solo fino ad un certo punto. Se siete visti +come qualcuno che blocca un buon lavoro senza motivo, quelle patch vi +passeranno oltre e andranno nel ramo principale in ogni caso. Nel kernel +Linux, nessuno ha potere di veto assoluto su alcun codice. Eccezione +fatta per Linus, forse. + +In rarissime occasioni, potreste vedere qualcosa di completamente diverso: +un altro sviluppatore che pubblica una soluzione differente al vostro +problema. A questo punto, c'è una buona probabilità che una delle due +modifiche non verrà integrata, e il "c'ero prima io" non è considerato +un argomento tecnico rilevante. Se la modifica di qualcun'altro rimpiazza +la vostra ed entra nel ramo principale, esiste un unico modo di reagire: +siate contenti che il vostro problema sia stato risolto e andate avanti con +il vostro lavoro. L'avere un vostro lavoro spintonato da parte in questo +modo può essere avvilente e scoraggiante, ma la comunità ricorderà come +avrete reagito anche dopo che avrà dimenticato quale fu la modifica accettata. diff --git a/Documentation/translations/it_IT/process/7.AdvancedTopics.rst b/Documentation/translations/it_IT/process/7.AdvancedTopics.rst new file mode 100644 index 0000000000..dffd813a09 --- /dev/null +++ b/Documentation/translations/it_IT/process/7.AdvancedTopics.rst @@ -0,0 +1,191 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_development_advancedtopics: + +Argomenti avanzati +================== + +A questo punto, si spera, dovreste avere un'idea su come funziona il processo +di sviluppo. Ma rimane comunque molto da imparare! Questo capitolo copre +alcuni argomenti che potrebbero essere utili per gli sviluppatori che stanno +per diventare parte integrante del processo di sviluppo del kernel. + +Gestire le modifiche con git +----------------------------- + +L'uso di un sistema distribuito per il controllo delle versioni del kernel +ebbe iniziò nel 2002 quando Linux iniziò a provare il programma proprietario +BitKeeper. Nonostante l'uso di BitKeeper fosse opinabile, di certo il suo +approccio alla gestione dei sorgenti non lo era. Un sistema distribuito per +il controllo delle versioni accelerò immediatamente lo sviluppo del kernel. +Oggigiorno, ci sono diverse alternative libere a BitKeeper. Per il meglio o il +peggio, il progetto del kernel ha deciso di usare git per gestire i sorgenti. + +Gestire le modifiche con git può rendere la vita dello sviluppatore molto +più facile, specialmente quando il volume delle modifiche cresce. +Git ha anche i suoi lati taglienti che possono essere pericolosi; è uno +strumento giovane e potente che è ancora in fase di civilizzazione da parte +dei suoi sviluppatori. Questo documento non ha lo scopo di insegnare l'uso +di git ai suoi lettori; ci sarebbe materiale a sufficienza per un lungo +documento al riguardo. Invece, qui ci concentriamo in particolare su come +git è parte del processo di sviluppo del kernel. Gli sviluppatori che +desiderassero diventare agili con git troveranno più informazioni ai +seguenti indirizzi: + + https://git-scm.com/ + + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + +e su varie guide che potrete trovare su internet. + +La prima cosa da fare prima di usarlo per produrre patch che saranno +disponibili ad altri, è quella di leggere i siti qui sopra e di acquisire una +base solida su come funziona git. Uno sviluppatore che sappia usare git +dovrebbe essere capace di ottenere una copia del repositorio principale, +esplorare la storia della revisione, registrare le modifiche, usare i rami, +eccetera. Una certa comprensione degli strumenti git per riscrivere la storia +(come ``rebase``) è altrettanto utile. Git ha i propri concetti e la propria +terminologia; un nuovo utente dovrebbe conoscere *refs*, *remote branch*, +*index*, *fast-forward merge*, *push* e *pull*, *detached head*, eccetera. +Il tutto potrebbe essere un po' intimidatorio visto da fuori, ma con un po' +di studio i concetti non saranno così difficili da capire. + +Utilizzare git per produrre patch da sottomettere via email può essere +un buon esercizio da fare mentre si sta prendendo confidenza con lo strumento. + +Quando sarete in grado di creare rami git che siano guardabili da altri, +vi servirà, ovviamente, un server dal quale sia possibile attingere le vostre +modifiche. Se avete un server accessibile da Internet, configurarlo per +eseguire git-daemon è relativamente semplice . Altrimenti, iniziano a +svilupparsi piattaforme che offrono spazi pubblici, e gratuiti (Github, +per esempio). Gli sviluppatori permanenti possono ottenere un account +su kernel.org, ma non è proprio facile da ottenere; per maggiori informazioni +consultate la pagina web https://kernel.org/faq/. + +In git è normale avere a che fare con tanti rami. Ogni linea di sviluppo +può essere separata in "rami per argomenti" e gestiti indipendentemente. +In git i rami sono facilissimi, per cui non c'è motivo per non usarli +in libertà. In ogni caso, non dovreste sviluppare su alcun ramo dal +quale altri potrebbero attingere. I rami disponibili pubblicamente dovrebbero +essere creati con attenzione; integrate patch dai rami di sviluppo +solo quando sono complete e pronte ad essere consegnate - non prima. + +Git offre alcuni strumenti che vi permettono di riscrivere la storia del +vostro sviluppo. Una modifica errata (diciamo, una che rompe la bisezione, +oppure che ha un qualche tipo di baco evidente) può essere corretta sul posto +o fatta sparire completamente dalla storia. Una serie di patch può essere +riscritta come se fosse stata scritta in cima al ramo principale di oggi, +anche se ci avete lavorato per mesi. Le modifiche possono essere spostate +in modo trasparente da un ramo ad un altro. E così via. Un uso giudizioso +di git per revisionare la storia può aiutare nella creazione di una serie +di patch pulite e con meno problemi. + +Un uso eccessivo può portare ad altri tipi di problemi, tuttavia, oltre +alla semplice ossessione per la creazione di una storia del progetto che sia +perfetta. Riscrivere la storia riscriverà le patch contenute in quella +storia, trasformando un kernel verificato (si spera) in uno da verificare. +Ma, oltre a questo, gli sviluppatori non possono collaborare se non condividono +la stessa vista sulla storia del progetto; se riscrivete la storia dalla quale +altri sviluppatori hanno attinto per i loro repositori, renderete la loro vita +molto più difficile. Quindi tenete conto di questa semplice regola generale: +la storia che avete esposto ad altri, generalmente, dovrebbe essere vista come +immutabile. + +Dunque, una volta che il vostro insieme di patch è stato reso disponibile +pubblicamente non dovrebbe essere più sovrascritto. Git tenterà di imporre +questa regola, e si rifiuterà di pubblicare nuove patch che non risultino +essere dirette discendenti di quelle pubblicate in precedenza (in altre parole, +patch che non condividono la stessa storia). È possibile ignorare questo +controllo, e ci saranno momenti in cui sarà davvero necessario riscrivere +un ramo già pubblicato. Un esempio è linux-next dove le patch vengono +spostate da un ramo all'altro al fine di evitare conflitti. Ma questo tipo +d'azione dovrebbe essere un'eccezione. Questo è uno dei motivi per cui lo +sviluppo dovrebbe avvenire in rami privati (che possono essere sovrascritti +quando lo si ritiene necessario) e reso pubblico solo quando è in uno stato +avanzato. + +Man mano che il ramo principale (o altri rami su cui avete basato le +modifiche) avanza, diventa allettante l'idea di integrare tutte le patch +per rimanere sempre aggiornati. Per un ramo privato, il *rebase* può essere +un modo semplice per rimanere aggiornati, ma questa non è un'opzione nel +momento in cui il vostro ramo è stato esposto al mondo intero. +*Merge* occasionali possono essere considerati di buon senso, ma quando +diventano troppo frequenti confondono inutilmente la storia. La tecnica +suggerita in questi casi è quella di fare *merge* raramente, e più in generale +solo nei momenti di rilascio (per esempio gli -rc del ramo principale). +Se siete nervosi circa alcune patch in particolare, potete sempre fare +dei *merge* di test in un ramo privato. In queste situazioni git "rerere" +può essere utile; questo strumento si ricorda come i conflitti di *merge* +furono risolti in passato cosicché non dovrete fare lo stesso lavoro due volte. + +Una delle lamentele più grosse e ricorrenti sull'uso di strumenti come git +è il grande movimento di patch da un repositorio all'altro che rende +facile l'integrazione nel ramo principale di modifiche mediocri, il tutto +sotto il naso dei revisori. Gli sviluppatori del kernel tendono ad essere +scontenti quando vedono succedere queste cose; preparare un ramo git con +patch che non hanno ricevuto alcuna revisione o completamente avulse, potrebbe +influire sulla vostra capacita di proporre, in futuro, l'integrazione dei +vostri rami. Citando Linus + +:: + + Potete inviarmi le vostre patch, ma per far si che io integri una + vostra modifica da git, devo sapere che voi sappiate cosa state + facendo, e ho bisogno di fidarmi *senza* dover passare tutte + le modifiche manualmente una per una. + +(https://lwn.net/Articles/224135/). + +Per evitare queste situazioni, assicuratevi che tutte le patch in un ramo +siano strettamente correlate al tema delle modifiche; un ramo "driver fixes" +non dovrebbe fare modifiche al codice principale per la gestione della memoria. +E, più importante ancora, non usate un repositorio git per tentare di +evitare il processo di revisione. Pubblicate un sommario di quello che il +vostro ramo contiene sulle liste di discussione più opportune, e , quando +sarà il momento, richiedete che il vostro ramo venga integrato in linux-next. + +Se e quando altri inizieranno ad inviarvi patch per essere incluse nel +vostro repositorio, non dovete dimenticare di revisionarle. Inoltre +assicuratevi di mantenerne le informazioni di paternità; al riguardo git "am" +fa del suo meglio, ma potreste dover aggiungere una riga "From:" alla patch +nel caso in cui sia arrivata per vie traverse. + +Quando richiedete l'integrazione, siate certi di fornire tutte le informazioni: +dov'è il vostro repositorio, quale ramo integrare, e quali cambiamenti si +otterranno dall'integrazione. Il comando git request-pull può essere d'aiuto; +preparerà una richiesta nel modo in cui gli altri sviluppatori se l'aspettano, +e verificherà che vi siate ricordati di pubblicare quelle patch su un +server pubblico. + +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. diff --git a/Documentation/translations/it_IT/process/8.Conclusion.rst b/Documentation/translations/it_IT/process/8.Conclusion.rst new file mode 100644 index 0000000000..32659ff467 --- /dev/null +++ b/Documentation/translations/it_IT/process/8.Conclusion.rst @@ -0,0 +1,84 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/8.Conclusion.rst <development_conclusion>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_conclusion: + +Per maggiori informazioni +========================= + +Esistono numerose fonti di informazioni sullo sviluppo del kernel Linux +e argomenti correlati. Primo tra questi sarà sempre la cartella Documentation +che si trova nei sorgenti kernel. + +Il file :ref:`process/howto.rst <it_process_howto>` è un punto di partenza +importante; :ref:`process/submitting-patches.rst <it_submittingpatches>` è +anch'esso qualcosa che tutti gli sviluppatori del kernel dovrebbero leggere. +Molte API interne al kernel sono documentate utilizzando il meccanismo +kerneldoc; "make htmldocs" o "make pdfdocs" possono essere usati per generare +quei documenti in HTML o PDF (sebbene le versioni di TeX di alcune +distribuzioni hanno dei limiti interni e fallisce nel processare +appropriatamente i documenti). + +Diversi siti web approfondiscono lo sviluppo del kernel ad ogni livello +di dettaglio. Il vostro autore vorrebbe umilmente suggerirvi +http://lwn.net/ come fonte; usando l'indice 'kernel' su LWN troverete +molti argomenti specifici sul kernel: + + http://lwn.net/Kernel/Index/ + +Oltre a ciò, una risorsa valida per gli sviluppatori kernel è: + + http://kernelnewbies.org/ + +E, ovviamente, una fonte da non dimenticare è http://kernel.org/, il luogo +definitivo per le informazioni sui rilasci del kernel. + +Ci sono numerosi libri sullo sviluppo del kernel: + + Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro + Rubini, and Greg Kroah-Hartman). In linea all'indirizzo + http://lwn.net/Kernel/LDD3/. + + Linux Kernel Development (Robert Love). + + Understanding the Linux Kernel (Daniel Bovet and Marco Cesati). + +Tutti questi libri soffrono di un errore comune: tendono a risultare in un +certo senso obsoleti dal momento che si trovano in libreria da diverso +tempo. Comunque contengono informazioni abbastanza buone. + +La documentazione per git la troverete su: + + http://www.kernel.org/pub/software/scm/git/docs/ + + http://www.kernel.org/pub/software/scm/git/docs/user-manual.html + + + +Conclusioni +=========== + +Congratulazioni a chiunque ce l'abbia fatta a terminare questo documento di +lungo-respiro. Si spera che abbia fornito un'utile comprensione d'insieme +di come il kernel Linux viene sviluppato e di come potete partecipare a +tale processo. + +Infine, quello che conta è partecipare. Qualsiasi progetto software +open-source non è altro che la somma di quello che i suoi contributori +mettono al suo interno. Il kernel Linux è cresciuto velocemente e bene +perché ha ricevuto il supporto di un impressionante gruppo di sviluppatori, +ognuno dei quali sta lavorando per renderlo migliore. Il kernel è un esempio +importante di cosa può essere fatto quando migliaia di persone lavorano +insieme verso un obiettivo comune. + +Il kernel può sempre beneficiare di una larga base di sviluppatori, tuttavia, +c'è sempre molto lavoro da fare. Ma, cosa non meno importante, molti degli +altri partecipanti all'ecosistema Linux possono trarre beneficio attraverso +il contributo al kernel. Inserire codice nel ramo principale è la chiave +per arrivare ad una qualità del codice più alta, bassa manutenzione e +bassi prezzi di distribuzione, alti livelli d'influenza sulla direzione +dello sviluppo del kernel, e molto altro. È una situazione nella quale +tutti coloro che sono coinvolti vincono. Mollate il vostro editor e +raggiungeteci; sarete più che benvenuti. diff --git a/Documentation/translations/it_IT/process/adding-syscalls.rst b/Documentation/translations/it_IT/process/adding-syscalls.rst new file mode 100644 index 0000000000..df8c652d00 --- /dev/null +++ b/Documentation/translations/it_IT/process/adding-syscalls.rst @@ -0,0 +1,643 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_addsyscalls: + +Aggiungere una nuova chiamata di sistema +======================================== + +Questo documento descrive quello che è necessario sapere per aggiungere +nuove chiamate di sistema al kernel Linux; questo è da considerarsi come +un'aggiunta ai soliti consigli su come proporre nuove modifiche +:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`. + + +Alternative alle chiamate di sistema +------------------------------------ + +La prima considerazione da fare quando si aggiunge una nuova chiamata di +sistema è quella di valutare le alternative. Nonostante le chiamate di sistema +siano il punto di interazione fra spazio utente e kernel più tradizionale ed +ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle +vostra interfaccia. + + - Se le operazioni coinvolte possono rassomigliare a quelle di un filesystem, + allora potrebbe avere molto più senso la creazione di un nuovo filesystem o + dispositivo. Inoltre, questo rende più facile incapsulare la nuova + funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore + del kernel. + + - Se la nuova funzionalità prevede operazioni dove il kernel notifica + lo spazio utente su un avvenimento, allora restituire un descrittore + di file all'oggetto corrispondente permette allo spazio utente di + utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche. + - Tuttavia, le operazioni che non si sposano bene con operazioni tipo + :manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate + come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in + un qualche modo opaca. + + - Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in + sysfs (vedere ``Documentation/filesystems/sysfs.rst``) o + in procfs potrebbe essere sufficiente. Tuttavia, l'accesso a questi + meccanismi richiede che il filesystem sia montato, il che potrebbe non + essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot). + Evitate d'aggiungere nuove API in debugfs perché questo non viene + considerata un'interfaccia di 'produzione' verso lo spazio utente. + - Se l'operazione è specifica ad un particolare file o descrittore, allora + potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`. + Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che + nasconde una notevole complessità, quindi è ottima solo quando la nuova + funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure + la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere + un semplice flag associato ad un descrittore di file). + - Se l'operazione è specifica ad un particolare processo, allora + potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`. + Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso + multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti + nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo + al processo. + + +Progettare l'API: pianificare le estensioni +------------------------------------------- + +Una nuova chiamata di sistema diventerà parte dell'API del kernel, e +dev'essere supportata per un periodo indefinito. Per questo, è davvero +un'ottima idea quella di discutere apertamente l'interfaccia sulla lista +di discussione del kernel, ed è altrettanto importante pianificarne eventuali +estensioni future. + +(Nella tabella delle chiamate di sistema sono disseminati esempi dove questo +non fu fatto, assieme ai corrispondenti aggiornamenti - +``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``, +``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia +del kernel e pianificate le estensioni fin dall'inizio) + +Per semplici chiamate di sistema che accettano solo un paio di argomenti, +il modo migliore di permettere l'estensibilità è quello di includere un +argomento *flags* alla chiamata di sistema. Per assicurarsi che i programmi +dello spazio utente possano usare in sicurezza *flags* con diverse versioni +del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto, +in qual caso rifiutate la chiamata di sistema (con ``EINVAL``):: + + if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3)) + return -EINVAL; + +(Se *flags* non viene ancora utilizzato, verificate che l'argomento sia zero) + +Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di +argomenti, il modo migliore è quello di incapsularne la maggior parte in una +struttura dati che verrà passata per puntatore. Questa struttura potrà +funzionare con future estensioni includendo un campo *size*:: + + struct xyzzy_params { + u32 size; /* userspace sets p->size = sizeof(struct xyzzy_params) */ + u32 param_1; + u64 param_2; + u64 param_3; + }; + +Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per +offrire il comportamento precedente quando vale zero, allora questo permetterà +di gestire un conflitto di versione in entrambe le direzioni: + + - un vecchio kernel può gestire l'accesso di una versione moderna di un + programma in spazio utente verificando che la memoria oltre la dimensione + della struttura dati attesa sia zero (in pratica verificare che + ``param_4 == 0``). + - un nuovo kernel può gestire l'accesso di una versione vecchia di un + programma in spazio utente estendendo la struttura dati con zeri (in pratica + ``param_4 = 0``). + +Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in +``kernel/events/core.c``) per un esempio pratico di questo approccio. + + +Progettare l'API: altre considerazioni +-------------------------------------- + +Se la vostra nuova chiamata di sistema permette allo spazio utente di fare +riferimento ad un oggetto del kernel, allora questa dovrebbe usare un +descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di +accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica +ben definita per utilizzare i descrittori di file. + +Se la vostra nuova chiamata di sistema :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 ``ksys_xyzzy()``). Questa funzione potrà +essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile +(``compat_sys_xyzzy()``), e/o da altri parti del kernel. + +Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito +fondamentale quello di non invocare chiamate di sistema all'interno del kernel. +Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove +``struct pt_regs`` viene decodificata al volo in una funzione che racchiude +la chiamata di sistema la quale verrà eseguita successivamente. +Questo significa che verranno passati solo i parametri che sono davvero +necessari ad una specifica chiamata di sistema, invece che riempire ogni volta +6 registri del processore con contenuti presi dallo spazio utente (potrebbe +causare seri problemi nella sequenza di chiamate). + +Inoltre, le regole su come i dati possano essere usati potrebbero differire +fra il kernel e l'utente. Questo è un altro motivo per cui invocare +``sys_xyzzy()`` è generalmente una brutta idea. + +Eccezioni a questa regola vengono accettate solo per funzioni d'architetture +che surclassano quelle generiche, per funzioni d'architettura di compatibilità, +o per altro codice in arch/ + + +Riferimenti e fonti +------------------- + + - Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle + chiamate di sistema: https://lwn.net/Articles/585415/ + - Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in + una chiamata di sistema: https://lwn.net/Articles/588444/ + - Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit + delle chiamate di sistema: https://lwn.net/Articles/311630/ + - Una coppia di articoli di David Drysdale che descrivono i dettagli del + percorso implementativo di una chiamata di sistema per la versione v3.14: + + - https://lwn.net/Articles/604287/ + - https://lwn.net/Articles/604515/ + + - Requisiti specifici alle architetture sono discussi nella pagina man + :manpage:`syscall(2)` : + http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES + - Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``: + http://yarchive.net/comp/linux/ioctl.html + - "Come non inventare interfacce del kernel", Arnd Bergmann, + http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf + - Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN: + https://lwn.net/Articles/486306/ + - Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni + su una nuova chiamata di sistema dovrebbero essere contenute nello stesso + filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org + - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di + sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com + - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura + x86 dovrebbe avvenire in un *commit* differente: + https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos + - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un + programma di auto-verifica per le nuove chiamate di sistema: + https://lore.kernel.org/r/20140320025530.GA25469@kroah.com + - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro + le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com + - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti + dovrebbero incapsularli in una struttura che includa un argomento + *size* per garantire l'estensibilità futura: + https://lore.kernel.org/r/20150730083831.GA22182@gmail.com + - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*: + + - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness + check") + - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc + conflict") + - commit bb458c644a59 ("Safer ABI for O_TMPFILE") + + - Discussion from Matthew Wilcox about restrictions on 64-bit arguments: + https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org + - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero + essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com + - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero + favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit: + https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com diff --git a/Documentation/translations/it_IT/process/applying-patches.rst b/Documentation/translations/it_IT/process/applying-patches.rst new file mode 100644 index 0000000000..1d30e5cd2a --- /dev/null +++ b/Documentation/translations/it_IT/process/applying-patches.rst @@ -0,0 +1,15 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/applying-patches.rst <applying_patches>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_applying_patches: + +Applicare patch al kernel Linux ++++++++++++++++++++++++++++++++ + +.. note:: + + Questo documento è obsoleto. Nella maggior parte dei casi, piuttosto + che usare ``patch`` manualmente, vorrete usare Git. Per questo motivo + il documento non verrà tradotto. diff --git a/Documentation/translations/it_IT/process/botching-up-ioctls.rst b/Documentation/translations/it_IT/process/botching-up-ioctls.rst new file mode 100644 index 0000000000..91732cdf80 --- /dev/null +++ b/Documentation/translations/it_IT/process/botching-up-ioctls.rst @@ -0,0 +1,249 @@ +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/process/botching-up-ioctls.rst + +========================================== +(Come evitare di) Raffazzonare delle ioctl +========================================== + +Preso da: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html + +Scritto da : Daniel Vetter, Copyright © 2013 Intel Corporation + +Una cosa che gli sviluppatori del sottosistema grafico del kernel Linux hanno +imparato negli ultimi anni è l'inutilità di cercare di creare un'interfaccia +unificata per gestire la memoria e le unità esecutive di diverse GPU. Dunque, +oggigiorno ogni driver ha il suo insieme di ioctl per allocare memoria ed +inviare dei programmi alla GPU. Il che è va bene dato che non c'è più un insano +sistema che finge di essere generico, ma al suo posto ci sono interfacce +dedicate. Ma al tempo stesso è più facile incasinare le cose. + +Per evitare di ripetere gli stessi errori ho preso nota delle lezioni imparate +mentre raffazzonavo il driver drm/i915. La maggior parte di queste lezioni si +focalizzano sui tecnicismi e non sulla visione d'insieme, come le discussioni +riguardo al modo migliore per implementare una ioctl per inviare compiti alla +GPU. Probabilmente, ogni sviluppatore di driver per GPU dovrebbe imparare queste +lezioni in autonomia. + + +Prerequisiti +------------ + +Prima i prerequisiti. Seguite i seguenti suggerimenti se non volete fallire in +partenza e ritrovarvi ad aggiungere un livello di compatibilità a 32-bit. + +* Usate solamente interi a lunghezza fissa. Per evitare i conflitti coi tipi + definiti nello spazio utente, il kernel definisce alcuni tipi speciali, come: + ``__u32``, ``__s64``. Usateli. + +* Allineate tutto alla lunghezza naturale delle piattaforma in uso e riempite + esplicitamente i vuoti. Non necessariamente le piattaforme a 32-bit allineano + i valori a 64-bit rispettandone l'allineamento, ma le piattaforme a 64-bit lo + fanno. Dunque, per farlo correttamente in entrambe i casi dobbiamo sempre + riempire i vuoti. + +* Se una struttura dati contiene valori a 64-bit, allora fate si che la sua + dimensione sia allineata a 64-bit, altrimenti la sua dimensione varierà su + sistemi a 32-bit e 64-bit. Avere una dimensione differente causa problemi + quando si passano vettori di strutture dati al kernel, o quando il kernel + effettua verifiche sulla dimensione (per esempio il sistema drm lo fa). + +* I puntatori sono di tipo ``__u64``, con un *cast* da/a ``uintptr_t`` da lato + spazio utente e da/a ``void __user *`` nello spazio kernel. Sforzatevi il più + possibile per non ritardare la conversione, o peggio maneggiare ``__u64`` nel + vostro codice perché questo riduce le verifiche che strumenti come sparse + possono effettuare. La macro u64_to_user_ptr() può essere usata nel kernel + per evitare avvisi riguardo interi e puntatori di dimensioni differenti. + + +Le Basi +------- + +Con la gioia d'aver evitato un livello di compatibilità, possiamo ora dare uno +sguardo alle basi. Trascurare questi punti renderà difficile la gestione della +compatibilità all'indietro ed in avanti. E dato che sbagliare al primo colpo è +garantito, dovrete rivisitare il codice o estenderlo per ogni interfaccia. + +* Abbiate un modo chiaro per capire dallo spazio utente se una nuova ioctl, o + l'estensione di una esistente, sia supportata dal kernel in esecuzione. Se non + potete fidarvi del fatto che un vecchio kernel possa rifiutare correttamente + un nuovo *flag*, modalità, o ioctl, (probabilmente perché avevate raffazzonato + qualcosa nel passato) allora dovrete implementare nel driver un meccanismo per + notificare quali funzionalità sono supportate, o in alternativa un numero di + versione. + +* Abbiate un piano per estendere le ioctl con nuovi *flag* o campi alla fine di + una struttura dati. Il sistema drm verifica la dimensione di ogni ioctl in + arrivo, ed estende con zeri ogni incongruenza fra kernel e spazio utente. + Questo aiuta, ma non è una soluzione completa dato che uno spazio utente nuovo + su un kernel vecchio non noterebbe che i campi nuovi alla fine della struttura + vengono ignorati. Dunque, anche questo avrà bisogno di essere notificato dal + driver allo spazio utente. + +* Verificate tutti i campi e *flag* inutilizzati ed i riempimenti siano a 0, + altrimenti rifiutare la ioctl. Se non lo fate il vostro bel piano per + estendere le ioctl andrà a rotoli dato che qualcuno userà delle ioctl con + strutture dati con valori casuali dallo stack nei campi inutilizzati. Il che + si traduce nell'avere questi campi nell'ABI, e la cui unica utilità sarà + quella di contenere spazzatura. Per questo dovrete esplicitamente riempire i + vuoti di tutte le vostre strutture dati, anche se non le userete in un + vettore. Il riempimento fatto dal compilatore potrebbe contenere valori + casuali. + +* Abbiate un semplice codice di test per ognuno dei casi sopracitati. + + +Divertirsi coi percorsi d'errore +-------------------------------- + +Oggigiorno non ci sono più scuse rimaste per permettere ai driver drm di essere +sfruttati per diventare root. Questo significa che dobbiamo avere una completa +validazione degli input e gestire in modo robusto i percorsi - tanto le GPU +moriranno comunque nel più strano dei casi particolari: + + * Le ioctl devono verificare l'overflow dei vettori. Inoltre, per i valori + interi si devono verificare *overflow*, *underflow*, e *clamping*. Il + classico esempio è l'inserimento direttamente nell'hardware di valori di + posizionamento di un'immagine *sprite* quando l'hardware supporta giusto 12 + bit, o qualcosa del genere. Tutto funzionerà finché qualche strano *display + server* non decide di preoccuparsi lui stesso del *clamping* e il cursore + farà il giro dello schermo. + + * Avere un test semplice per ogni possibile fallimento della vostra ioctl. + Verificate che il codice di errore rispetti le aspettative. Ed infine, + assicuratevi che verifichiate un solo percorso sbagliato per ogni sotto-test + inviando comunque dati corretti. Senza questo, verifiche precedenti + potrebbero rigettare la ioctl troppo presto, impedendo l'esecuzione del + codice che si voleva effettivamente verificare, rischiando quindi di + mascherare bachi e regressioni. + + * Fate si che tutte le vostre ioctl siano rieseguibili. Prima di tutto X adora + i segnali; secondo questo vi permetterà di verificare il 90% dei percorsi + d'errore interrompendo i vostri test con dei segnali. Grazie all'amore di X + per i segnali, otterrete gratuitamente un eccellente copertura di base per + tutti i vostri percorsi d'errore. Inoltre, siate consistenti sul modo di + gestire la riesecuzione delle ioctl - per esempio, drm ha una piccola + funzione di supporto `drmIoctl` nella sua librerie in spazio utente. Il + driver i915 l'abbozza con l'ioctl `set_tiling`, ed ora siamo inchiodati per + sempre con una semantica arcana sia nel kernel che nello spazio utente. + + + * Se non potete rendere un pezzo di codice rieseguibile, almeno rendete + possibile la sua interruzione. Le GPU moriranno e i vostri utenti non vi + apprezzeranno affatto se tenete in ostaggio il loro scatolotto (mediante un + processo X insopprimibile). Se anche recuperare lo stato è troppo complicato, + allora implementate una scadenza oppure come ultima spiaggia una rete di + sicurezza per rilevare situazioni di stallo quando l'hardware da di matto. + + * Preparate dei test riguardo ai casi particolarmente estremi nel codice di + recupero del sistema - è troppo facile create uno stallo fra il vostro codice + anti-stallo e un processo scrittore. + + +Tempi, attese e mancate scadenze +-------------------------------- + +Le GPU fanno quasi tutto in modo asincrono, dunque dobbiamo regolare le +operazioni ed attendere quelle in sospeso. Questo è davvero difficile; al +momento nessuna delle ioctl supportante dal driver drm/i915 riesce a farlo +perfettamente, il che significa che qui ci sono ancora una valanga di lezioni da +apprendere. + + * Per fare riferimento al tempo usate sempre ``CLOCK_MONOTONIC``. Oggigiorno + questo è quello che viene usato di base da alsa, drm, e v4l. Tuttavia, + lasciate allo spazio utente la possibilità di capire quali *timestamp* + derivano da domini temporali diversi come il vostro orologio di sistema + (fornito dal kernel) oppure un contatore hardware indipendente da qualche + parte. Gli orologi divergeranno, ma con questa informazione gli strumenti di + analisi delle prestazioni possono compensare il problema. Se il vostro spazio + utente può ottenere i valori grezzi degli orologi, allora considerate di + esporre anch'essi. + + * Per descrivere il tempo, usate ``__s64`` per i secondi e ``__u64`` per i + nanosecondi. Non è il modo migliore per specificare il tempo, ma è + praticamente uno standard. + + * Verificate che gli input di valori temporali siano normalizzati, e se non lo + sono scartateli. Fate attenzione perché la struttura dati ``struct ktime`` + del kernel usa interi con segni sia per i secondi che per i nanosecondi. + + * Per le scadenze (*timeout*) usate valori temporali assoluti. Se siete dei + bravi ragazzi e avete reso la vostra ioctl rieseguibile, allora i tempi + relativi tendono ad essere troppo grossolani e a causa degli arrotondamenti + potrebbero estendere in modo indefinito i tempi di attesa ad ogni + riesecuzione. Particolarmente vero se il vostro orologio di riferimento è + qualcosa di molto lento come il contatore di *frame*. Con la giacca da + avvocato delle specifiche diremmo che questo non è un baco perché tutte le + scadenze potrebbero essere estese - ma sicuramente gli utenti vi odieranno + quando le animazioni singhiozzano. + + * Considerate l'idea di eliminare tutte le ioctl sincrone con scadenze, e di + sostituirle con una versione asincrona il cui stato può essere consultato + attraverso il descrittore di file mediante ``poll``. Questo approccio si + sposa meglio in un applicazione guidata dagli eventi. + + * Sviluppate dei test per i casi estremi, specialmente verificate che i valori + di ritorno per gli eventi già completati, le attese terminate con successo, e + le attese scadute abbiano senso e servano ai vostri scopi. + + +Non perdere risorse +------------------- +Nel suo piccolo il driver drm implementa un sistema operativo specializzato per +certe GPU. Questo significa che il driver deve esporre verso lo spazio +utente tonnellate di agganci per accedere ad oggetti e altre risorse. Farlo +correttamente porterà con se alcune insidie: + + * Collegate sempre la vita di una risorsa creata dinamicamente, a quella del + descrittore di file. Considerate una mappatura 1:1 se la vostra risorsa + dev'essere condivisa fra processi - passarsi descrittori di file sul socket + unix semplifica la gestione anche per lo spazio utente. + + * Dev'esserci sempre Il supporto ``O_CLOEXEC``. + + * Assicuratevi di avere abbastanza isolamento fra utenti diversi. Di base + impostate uno spazio dei nomi riservato per ogni descrittore di file, il che + forzerà ogni condivisione ad essere esplicita. Usate uno spazio più globale + per dispositivo solo se gli oggetti sono effettivamente unici per quel + dispositivo. Un controesempio viene dall'interfaccia drm modeset, dove + oggetti specifici di dispositivo, come i connettori, condividono uno spazio + dei nomi con oggetti per il *framebuffer*, ma questi non sono per niente + condivisi. Uno spazio separato, privato di base, per i *framebuffer* sarebbe + stato meglio. + + * Pensate all'identificazione univoca degli agganci verso lo spazio utente. Per + esempio, per la maggior parte dei driver drm, si considera fallace la doppia + sottomissione di un oggetto allo stesso comando ioctl. Ma per evitarlo, se + gli oggetti sono condivisibili, lo spazio utente ha bisogno di sapere se il + driver ha importato un oggetto da un altro processo. Non l'ho ancora provato, + ma considerate l'idea di usare il numero di inode come identificatore per i + descrittori di file condivisi - che poi è come si distinguono i veri file. + Sfortunatamente, questo richiederebbe lo sviluppo di un vero e proprio + filesystem virtuale nel kernel. + + +Ultimo, ma non meno importante +------------------------------ + +Non tutti i problemi si risolvono con una nuova ioctl: + +* Pensateci su due o tre volte prima di implementare un'interfaccia privata per + un driver. Ovviamente è molto più veloce seguire questa via piuttosto che + buttarsi in lunghe discussioni alla ricerca di una soluzione più generica. Ed + a volte un'interfaccia privata è quello che serve per sviluppare un nuovo + concetto. Ma alla fine, una volta che c'è un'interfaccia generica a + disposizione finirete per mantenere due interfacce. Per sempre. + +* Considerate interfacce alternative alle ioctl. Gli attributi sysfs sono molto + meglio per impostazioni che sono specifiche di un dispositivo, o per + sotto-oggetti con una vita piuttosto statica (come le uscite dei connettori in + drm con tutti gli attributi per la sovrascrittura delle rilevazioni). O magari + solo il vostro sistema di test ha bisogno di una certa interfaccia, e allora + debugfs (che non ha un'interfaccia stabile) sarà la soluzione migliore. + +Per concludere. Questo gioco consiste nel fare le cose giuste fin da subito, +dato che se il vostro driver diventa popolare e la piattaforma hardware longeva +finirete per mantenere le vostre ioctl per sempre. Potrete tentare di deprecare +alcune orribili ioctl, ma ci vorranno anni per riuscirci effettivamente. E +ancora, altri anni prima che sparisca l'ultimo utente capace di lamentarsi per +una regressione. diff --git a/Documentation/translations/it_IT/process/changes.rst b/Documentation/translations/it_IT/process/changes.rst new file mode 100644 index 0000000000..f37c53f8b5 --- /dev/null +++ b/Documentation/translations/it_IT/process/changes.rst @@ -0,0 +1,528 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/changes.rst <changes>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_changes: + +Requisiti minimi per compilare il kernel +++++++++++++++++++++++++++++++++++++++++ + +Introduzione +============ + +Questo documento fornisce una lista dei software necessari per eseguire questa +versione del kernel. + +Questo documento è basato sul file "Changes" del kernel 2.0.x e quindi le +persone che lo scrissero meritano credito (Jared Mauch, Axel Boldt, +Alessandro Sigala, e tanti altri nella rete). + +Requisiti minimi correnti +************************* + +Prima di pensare d'avere trovato un baco, aggiornate i seguenti programmi +**almeno** alla versione indicata! Se non siete certi della versione che state +usando, il comando indicato dovrebbe dirvelo. + +Questa lista presume che abbiate già un kernel Linux funzionante. In aggiunta, +non tutti gli strumenti sono necessari ovunque; ovviamente, se non avete una +PC Card, per esempio, probabilmente non dovreste preoccuparvi di pcmciautils. + +====================== ================= ======================================== + Programma Versione minima Comando per verificare la versione +====================== ================= ======================================== +GNU C 5.1 gcc --version +Clang/LLVM (optional) 11.0.0 clang --version +GNU make 3.81 make --version +bash 4.2 bash --version +binutils 2.25 ld -v +flex 2.5.35 flex --version +bison 2.0 bison --version +pahole 1.16 pahole --version +util-linux 2.10o fdformat --version +kmod 13 depmod -V +e2fsprogs 1.41.4 e2fsck -V +jfsutils 1.1.3 fsck.jfs -V +reiserfsprogs 3.6.3 reiserfsck -V +xfsprogs 2.6.0 xfs_db -V +squashfs-tools 4.0 mksquashfs -version +btrfs-progs 0.18 btrfsck +pcmciautils 004 pccardctl -V +quota-tools 3.09 quota -V +PPP 2.4.0 pppd --version +nfs-utils 1.0.5 showmount --version +procps 3.2.0 ps --version +udev 081 udevd --version +grub 0.93 grub --version || grub-install --version +mcelog 0.6 mcelog --version +iptables 1.4.2 iptables -V +openssl & libcrypto 1.0.0 openssl version +bc 1.06.95 bc --version +Sphinx\ [#f1]_ 1.7 sphinx-build --version +cpio any cpio --version +====================== ================= ======================================== + +.. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel + +Compilazione del kernel +*********************** + +GCC +--- + +La versione necessaria di gcc potrebbe variare a seconda del tipo di CPU nel +vostro calcolatore. + +Clang/LLVM (opzionale) +---------------------- + +L'ultima versione di clang e *LLVM utils* (secondo `releases.llvm.org +<https://releases.llvm.org>`_) sono supportati per la generazione del +kernel. Non garantiamo che anche i rilasci più vecchi funzionino, inoltre +potremmo rimuovere gli espedienti che abbiamo implementato per farli +funzionare. Per maggiori informazioni +:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`. + +Make +---- + +Per compilare il kernel vi servirà GNU make 3.81 o successivo. + +Bash +---- +Per generare il kernel vengono usati alcuni script per bash. +Questo richiede bash 4.2 o successivo. + +Binutils +-------- + +Per generare il kernel è necessario avere Binutils 2.25 o superiore. + +pkg-config +---------- + +Il sistema di compilazione, dalla versione 4.18, richiede pkg-config per +verificare l'esistenza degli strumenti kconfig e per determinare le +impostazioni da usare in 'make {g,x}config'. Precedentemente pkg-config +veniva usato ma non verificato o documentato. + +Flex +---- + +Dalla versione 4.16, il sistema di compilazione, durante l'esecuzione, genera +un analizzatore lessicale. Questo richiede flex 2.5.35 o successivo. + +Bison +----- + +Dalla versione 4.16, il sistema di compilazione, durante l'esecuzione, genera +un parsificatore. Questo richiede bison 2.0 o successivo. + +pahole +------ + +Dalla versione 5.2, quando viene impostato CONFIG_DEBUG_INFO_BTF, il sistema di +compilazione genera BTF (BPF Type Format) a partire da DWARF per vmlinux. Più +tardi anche per i moduli. Questo richiede pahole v1.16 o successivo. + +A seconda della distribuzione, lo si può trovare nei pacchetti 'dwarves' o +'pahole'. Oppure lo si può trovare qui: https://fedorapeople.org/~acme/dwarves/. + +Perl +---- + +Per compilare il kernel vi servirà perl 5 e i seguenti moduli ``Getopt::Long``, +``Getopt::Std``, ``File::Basename``, e ``File::Find``. + +BC +-- + +Vi servirà bc per compilare i kernel dal 3.10 in poi. + +OpenSSL +------- + +Il programma OpenSSL e la libreria crypto vengono usati per la firma dei moduli +e la gestione dei certificati; sono usati per la creazione della chiave e +la generazione della firma. + +Se la firma dei moduli è abilitata, allora vi servirà openssl per compilare il +kernel 3.7 e successivi. Vi serviranno anche i pacchetti di sviluppo di +openssl per compilare il kernel 4.3 o successivi. + + +Strumenti di sistema +******************** + +Modifiche architetturali +------------------------ + +DevFS è stato reso obsoleto da udev +(http://www.kernel.org/pub/linux/utils/kernel/hotplug/) + +Il supporto per UID a 32-bit è ora disponibile. Divertitevi! + +La documentazione delle funzioni in Linux è una fase di transizione +verso una documentazione integrata nei sorgenti stessi usando dei commenti +formattati in modo speciale e posizionati vicino alle funzioni che descrivono. +Al fine di arricchire la documentazione, questi commenti possono essere +combinati con i file ReST presenti in Documentation/; questi potranno +poi essere convertiti in formato PostScript, HTML, LaTex, ePUB o PDF. +Per convertire i documenti da ReST al formato che volete, avete bisogno di +Sphinx. + +Util-linux +---------- + +Le versioni più recenti di util-linux: forniscono il supporto a ``fdisk`` per +dischi di grandi dimensioni; supportano le nuove opzioni di mount; riconoscono +più tipi di partizioni; hanno un fdformat che funziona con i kernel 2.4; +e altre chicche. Probabilmente vorrete aggiornarlo. + +Ksymoops +-------- + +Se l'impensabile succede e il kernel va in oops, potrebbe servirvi lo strumento +ksymoops per decodificarlo, ma nella maggior parte dei casi non vi servirà. +Generalmente è preferibile compilare il kernel con l'opzione ``CONFIG_KALLSYMS`` +cosicché venga prodotto un output più leggibile che può essere usato così com'è +(produce anche un output migliore di ksymoops). Se per qualche motivo il +vostro kernel non è stato compilato con ``CONFIG_KALLSYMS`` e non avete modo di +ricompilarlo e riprodurre l'oops con quell'opzione abilitata, allora potete +usare ksymoops per decodificare l'oops. + +Mkinitrd +-------- + +I cambiamenti della struttura in ``/lib/modules`` necessita l'aggiornamento di +mkinitrd. + +E2fsprogs +--------- + +L'ultima versione di ``e2fsprogs`` corregge diversi bachi in fsck e debugfs. +Ovviamente, aggiornarlo è una buona idea. + +JFSutils +-------- + +Il pacchetto ``jfsutils`` contiene programmi per il file-system JFS. +Sono disponibili i seguenti strumenti: + +- ``fsck.jfs`` - avvia la ripetizione del log delle transizioni, e verifica e + ripara una partizione formattata secondo JFS + +- ``mkfs.jfs`` - crea una partizione formattata secondo JFS + +- sono disponibili altri strumenti per il file-system. + +Reiserfsprogs +------------- + +Il pacchetto reiserfsprogs dovrebbe essere usato con reiserfs-3.6.x (Linux +kernel 2.4.x). Questo è un pacchetto combinato che contiene versioni +funzionanti di ``mkreiserfs``, ``resize_reiserfs``, ``debugreiserfs`` e +``reiserfsck``. Questi programmi funzionano sulle piattaforme i386 e alpha. + +Xfsprogs +-------- + +L'ultima versione di ``xfsprogs`` contiene, fra i tanti, i programmi +``mkfs.xfs``, ``xfs_db`` e ``xfs_repair`` per il file-system XFS. +Dipendono dell'architettura e qualsiasi versione dalla 2.0.0 in poi +dovrebbe funzionare correttamente con la versione corrente del codice +XFS nel kernel (sono raccomandate le versioni 2.6.0 o successive per via +di importanti miglioramenti). + +PCMCIAutils +----------- + +PCMCIAutils sostituisce ``pcmica-cs``. Serve ad impostare correttamente i +connettori PCMCIA all'avvio del sistema e a caricare i moduli necessari per +i dispositivi a 16-bit se il kernel è stato modularizzato e il sottosistema +hotplug è in uso. + +Quota-tools +----------- + +Il supporto per uid e gid a 32 bit richiedono l'uso della versione 2 del +formato quota. La versione 3.07 e successive di quota-tools supportano +questo formato. Usate la versione raccomandata nella lista qui sopra o una +successiva. + +Micro codice per Intel IA32 +--------------------------- + +Per poter aggiornare il micro codice per Intel IA32, è stato aggiunto un +apposito driver; il driver è accessibile come un normale dispositivo a +caratteri (misc). Se non state usando udev probabilmente sarà necessario +eseguire i seguenti comandi come root prima di poterlo aggiornare:: + + mkdir /dev/cpu + mknod /dev/cpu/microcode c 10 184 + chmod 0644 /dev/cpu/microcode + +Probabilmente, vorrete anche il programma microcode_ctl da usare con questo +dispositivo. + +udev +---- + +``udev`` è un programma in spazio utente il cui scopo è quello di popolare +dinamicamente la cartella ``/dev`` coi dispositivi effettivamente presenti. +``udev`` sostituisce le funzionalità base di devfs, consentendo comunque +nomi persistenti per i dispositivi. + +FUSE +---- + +Serve libfuse 2.4.0 o successiva. Il requisito minimo assoluto è 2.3.0 ma +le opzioni di mount ``direct_io`` e ``kernel_cache`` non funzioneranno. + + +Rete +**** + +Cambiamenti generali +-------------------- + +Se per quanto riguarda la configurazione di rete avete esigenze di un certo +livello dovreste prendere in considerazione l'uso degli strumenti in ip-route2. + +Filtro dei pacchetti / NAT +-------------------------- + +Il codice per filtraggio dei pacchetti e il NAT fanno uso degli stessi +strumenti come nelle versioni del kernel antecedenti la 2.4.x (iptables). +Include ancora moduli di compatibilità per 2.2.x ipchains e 2.0.x ipdwadm. + +PPP +--- + +Il driver per PPP è stato ristrutturato per supportare collegamenti multipli e +per funzionare su diversi livelli. Se usate PPP, aggiornate pppd almeno alla +versione 2.4.0. + +Se non usate udev, dovete avere un file /dev/ppp che può essere creato da root +col seguente comando:: + + mknod /dev/ppp c 108 0 + + +NFS-utils +--------- + +Nei kernel più antichi (2.4 e precedenti), il server NFS doveva essere +informato sui clienti ai quali si voleva fornire accesso via NFS. Questa +informazione veniva passata al kernel quando un cliente montava un file-system +mediante ``mountd``, oppure usando ``exportfs`` all'avvio del sistema. +exportfs prende le informazioni circa i clienti attivi da ``/var/lib/nfs/rmtab``. + +Questo approccio è piuttosto delicato perché dipende dalla correttezza di +rmtab, che non è facile da garantire, in particolare quando si cerca di +implementare un *failover*. Anche quando il sistema funziona bene, ``rmtab`` +ha il problema di accumulare vecchie voci inutilizzate. + +Sui kernel più recenti il kernel ha la possibilità di informare mountd quando +arriva una richiesta da una macchina sconosciuta, e mountd può dare al kernel +le informazioni corrette per l'esportazione. Questo rimuove la dipendenza con +``rmtab`` e significa che il kernel deve essere al corrente solo dei clienti +attivi. + +Per attivare questa funzionalità, dovete eseguire il seguente comando prima di +usare exportfs o mountd:: + + mount -t nfsd nfsd /proc/fs/nfsd + +Dove possibile, raccomandiamo di proteggere tutti i servizi NFS dall'accesso +via internet mediante un firewall. + +mcelog +------ + +Quando ``CONFIG_x86_MCE`` è attivo, il programma mcelog processa e registra +gli eventi *machine check*. Gli eventi *machine check* sono errori riportati +dalla CPU. Incoraggiamo l'analisi di questi errori. + + +Documentazione del kernel +************************* + +Sphinx +------ + +Per i dettaglio sui requisiti di Sphinx, fate riferimento a :ref:`it_sphinx_install` +in :ref:`Documentation/translations/it_IT/doc-guide/sphinx.rst <it_sphinxdoc>` + +Ottenere software aggiornato +============================ + +Compilazione del kernel +*********************** + +gcc +--- + +- <ftp://ftp.gnu.org/gnu/gcc/> + +Clang/LLVM +---------- + +- :ref:`Getting LLVM <getting_llvm>`. + +Make +---- + +- <ftp://ftp.gnu.org/gnu/make/> + +Bash +---- + +- <ftp://ftp.gnu.org/gnu/bash/> + +Binutils +-------- + +- <https://www.kernel.org/pub/linux/devel/binutils/> + +Flex +---- + +- <https://github.com/westes/flex/releases> + +Bison +----- + +- <ftp://ftp.gnu.org/gnu/bison/> + +OpenSSL +------- + +- <https://www.openssl.org/> + +Strumenti di sistema +******************** + +Util-linux +---------- + +- <https://www.kernel.org/pub/linux/utils/util-linux/> + +Kmod +---- + +- <https://www.kernel.org/pub/linux/utils/kernel/kmod/> +- <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git> + +Ksymoops +-------- + +- <https://www.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/> + +Mkinitrd +-------- + +- <https://code.launchpad.net/initrd-tools/main> + +E2fsprogs +--------- + +- <https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/> +- <https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/> + +JFSutils +-------- + +- <http://jfs.sourceforge.net/> + +Reiserfsprogs +------------- + +- <https://git.kernel.org/pub/scm/linux/kernel/git/jeffm/reiserfsprogs.git/> + +Xfsprogs +-------- + +- <https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git> +- <https://www.kernel.org/pub/linux/utils/fs/xfs/xfsprogs/> + +Pcmciautils +----------- + +- <https://www.kernel.org/pub/linux/utils/kernel/pcmcia/> + +Quota-tools +----------- + +- <http://sourceforge.net/projects/linuxquota/> + + +Microcodice Intel P6 +-------------------- + +- <https://downloadcenter.intel.com/> + +udev +---- + +- <http://www.freedesktop.org/software/systemd/man/udev.html> + +FUSE +---- + +- <https://github.com/libfuse/libfuse/releases> + +mcelog +------ + +- <http://www.mcelog.org/> + +cpio +---- + +- <https://www.gnu.org/software/cpio/> + +Rete +**** + +PPP +--- + +- <https://download.samba.org/pub/ppp/> +- <https://git.ozlabs.org/?p=ppp.git> +- <https://github.com/paulusmack/ppp/> + + +NFS-utils +--------- + +- <http://sourceforge.net/project/showfiles.php?group_id=14> + +Iptables +-------- + +- <https://netfilter.org/projects/iptables/index.html> + +Ip-route2 +--------- + +- <https://www.kernel.org/pub/linux/utils/net/iproute2/> + +OProfile +-------- + +- <http://oprofile.sf.net/download/> + +NFS-Utils +--------- + +- <http://nfs.sourceforge.net/> + +Documentazione del kernel +************************* + +Sphinx +------ + +- <http://www.sphinx-doc.org/> diff --git a/Documentation/translations/it_IT/process/clang-format.rst b/Documentation/translations/it_IT/process/clang-format.rst new file mode 100644 index 0000000000..29f83c1980 --- /dev/null +++ b/Documentation/translations/it_IT/process/clang-format.rst @@ -0,0 +1,197 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/clang-format.rst <clangformat>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_clangformat: + +clang-format +============ +``clang-format`` è uno strumento per formattare codice C/C++/... secondo +un gruppo di regole ed euristiche. Come tutti gli strumenti, non è perfetto +e non copre tutti i singoli casi, ma è abbastanza buono per essere utile. + +``clang-format`` può essere usato per diversi fini: + + - Per riformattare rapidamente un blocco di codice secondo lo stile del + kernel. Particolarmente utile quando si sposta del codice e lo si + allinea/ordina. Vedere it_clangformatreformat_. + + - Identificare errori di stile, refusi e possibili miglioramenti nei + file che mantieni, le modifiche che revisioni, le differenze, + eccetera. Vedere it_clangformatreview_. + + - Ti aiuta a seguire lo stile del codice, particolarmente utile per i + nuovi arrivati o per coloro che lavorano allo stesso tempo su diversi + progetti con stili di codifica differenti. + +Il suo file di configurazione è ``.clang-format`` e si trova nella cartella +principale dei sorgenti del kernel. Le regole scritte in quel file tentano +di approssimare le lo stile di codifica del kernel. Si tenta anche di seguire +il più possibile +:ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`. +Dato che non tutto il kernel segue lo stesso stile, potreste voler aggiustare +le regole di base per un particolare sottosistema o cartella. Per farlo, +potete sovrascriverle scrivendole in un altro file ``.clang-format`` in +una sottocartella. + +Questo strumento è già stato incluso da molto tempo nelle distribuzioni +Linux più popolari. Cercate ``clang-format`` nel vostro repositorio. +Altrimenti, potete scaricare una versione pre-generata dei binari di LLVM/clang +oppure generarlo dai codici sorgenti: + + https://releases.llvm.org/download.html + +Troverete più informazioni ai seguenti indirizzi: + + https://clang.llvm.org/docs/ClangFormat.html + + https://clang.llvm.org/docs/ClangFormatStyleOptions.html + + +.. _it_clangformatreview: + +Revisionare lo stile di codifica per file e modifiche +----------------------------------------------------- + +Eseguendo questo programma, potrete revisionare un intero sottosistema, +cartella o singoli file alla ricerca di errori di stile, refusi o +miglioramenti. + +Per farlo, potete eseguire qualcosa del genere:: + + # Make sure your working directory is clean! + clang-format -i kernel/*.[ch] + +E poi date un'occhiata a *git diff*. + +Osservare le righe di questo diff è utile a migliorare/aggiustare +le opzioni di stile nel file di configurazione; così come per verificare +le nuove funzionalità/versioni di ``clang-format``. + +``clang-format`` è in grado di leggere diversi diff unificati, quindi +potrete revisionare facilmente delle modifiche e *git diff*. +La documentazione si trova al seguente indirizzo: + + https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting + +Per evitare che ``clang-format`` formatti alcune parti di un file, potete +scrivere nel codice:: + + int formatted_code; + // clang-format off + void unformatted_code ; + // clang-format on + void formatted_code_again; + +Nonostante si attraente l'idea di utilizzarlo per mantenere un file +sempre in sintonia con ``clang-format``, specialmente per file nuovi o +se siete un manutentore, ricordatevi che altre persone potrebbero usare +una versione diversa di ``clang-format`` oppure non utilizzarlo del tutto. +Quindi, dovreste trattenervi dall'usare questi marcatori nel codice del +kernel; almeno finché non vediamo che ``clang-format`` è diventato largamente +utilizzato. + + +.. _it_clangformatreformat: + +Riformattare blocchi di codice +------------------------------ + +Utilizzando dei plugin per il vostro editor, potete riformattare una +blocco (selezione) di codice con una singola combinazione di tasti. +Questo è particolarmente utile: quando si riorganizza il codice, per codice +complesso, macro multi-riga (e allineare le loro "barre"), eccetera. + +Ricordatevi che potete sempre aggiustare le modifiche in quei casi dove +questo strumento non ha fatto un buon lavoro. Ma come prima approssimazione, +può essere davvero molto utile. + +Questo programma si integra con molti dei più popolari editor. Alcuni di +essi come vim, emacs, BBEdit, Visaul Studio, lo supportano direttamente. +Al seguente indirizzo troverete le istruzioni: + + https://clang.llvm.org/docs/ClangFormat.html + +Per Atom, Eclipse, Sublime Text, Visual Studio Code, XCode e altri editor +e IDEs dovreste essere in grado di trovare dei plugin pronti all'uso. + +Per questo caso d'uso, considerate l'uso di un secondo ``.clang-format`` +che potete personalizzare con le vostre opzioni. +Consultare it_clangformatextra_. + + +.. _it_clangformatmissing: + +Cose non supportate +------------------- + +``clang-format`` non ha il supporto per alcune cose che sono comuni nel +codice del kernel. Sono facili da ricordare; quindi, se lo usate +regolarmente, imparerete rapidamente a evitare/ignorare certi problemi. + +In particolare, quelli più comuni che noterete sono: + + - Allineamento di ``#define`` su una singola riga, per esempio:: + + #define TRACING_MAP_BITS_DEFAULT 11 + #define TRACING_MAP_BITS_MAX 17 + #define TRACING_MAP_BITS_MIN 7 + + contro:: + + #define TRACING_MAP_BITS_DEFAULT 11 + #define TRACING_MAP_BITS_MAX 17 + #define TRACING_MAP_BITS_MIN 7 + + - Allineamento dei valori iniziali, per esempio:: + + static const struct file_operations uprobe_events_ops = { + .owner = THIS_MODULE, + .open = probes_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = probes_write, + }; + + contro:: + + static const struct file_operations uprobe_events_ops = { + .owner = THIS_MODULE, + .open = probes_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = probes_write, + }; + + +.. _it_clangformatextra: + +Funzionalità e opzioni aggiuntive +--------------------------------- + +Al fine di minimizzare le differenze fra il codice attuale e l'output +del programma, alcune opzioni di stile e funzionalità non sono abilitate +nella configurazione base. In altre parole, lo scopo è di rendere le +differenze le più piccole possibili, permettendo la semplificazione +della revisione di file, differenze e modifiche. + +In altri casi (per esempio un particolare sottosistema/cartella/file), lo +stile del kernel potrebbe essere diverso e abilitare alcune di queste +opzioni potrebbe dare risultati migliori. + +Per esempio: + + - Allineare assegnamenti (``AlignConsecutiveAssignments``). + + - Allineare dichiarazioni (``AlignConsecutiveDeclarations``). + + - Riorganizzare il testo nei commenti (``ReflowComments``). + + - Ordinare gli ``#include`` (``SortIncludes``). + +Piuttosto che per interi file, solitamente sono utili per la riformattazione +di singoli blocchi. In alternativa, potete creare un altro file +``.clang-format`` da utilizzare con il vostro editor/IDE. diff --git a/Documentation/translations/it_IT/process/code-of-conduct.rst b/Documentation/translations/it_IT/process/code-of-conduct.rst new file mode 100644 index 0000000000..7dbd7f55f3 --- /dev/null +++ b/Documentation/translations/it_IT/process/code-of-conduct.rst @@ -0,0 +1,12 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/code-of-conduct.rst <code_of_conduct>` + +.. _it_code_of_conduct: + +Accordo dei contributori sul codice di condotta ++++++++++++++++++++++++++++++++++++++++++++++++ + +.. warning:: + + TODO ancora da tradurre diff --git a/Documentation/translations/it_IT/process/coding-style.rst b/Documentation/translations/it_IT/process/coding-style.rst new file mode 100644 index 0000000000..5f244e16f5 --- /dev/null +++ b/Documentation/translations/it_IT/process/coding-style.rst @@ -0,0 +1,1213 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_codingstyle: + +Stile del codice per il kernel Linux +==================================== + +Questo è un breve documento che descrive lo stile di codice preferito per +il kernel Linux. Lo stile di codifica è molto personale e non voglio +**forzare** nessuno ad accettare il mio, ma questo stile è quello che +dev'essere usato per qualsiasi cosa che io sia in grado di mantenere, e l'ho +preferito anche per molte altre cose. Per favore, almeno tenete in +considerazione le osservazioni espresse qui. + +La prima cosa che suggerisco è quella di stamparsi una copia degli standard +di codifica GNU e di NON leggerla. Bruciatela, è un grande gesto simbolico. + +Comunque, ecco i punti: + +1) Indentazione +--------------- + +La tabulazione (tab) è di 8 caratteri e così anche le indentazioni. Ci sono +alcuni movimenti di eretici che vorrebbero l'indentazione a 4 (o perfino 2!) +caratteri di profondità, che è simile al tentativo di definire il valore del +pi-greco a 3. + +Motivazione: l'idea dell'indentazione è di definire chiaramente dove un blocco +di controllo inizia e finisce. Specialmente quando siete rimasti a guardare lo +schermo per 20 ore a file, troverete molto più facile capire i livelli di +indentazione se questi sono larghi. + +Ora, alcuni rivendicano che un'indentazione da 8 caratteri sposta il codice +troppo a destra e che quindi rende difficile la lettura su schermi a 80 +caratteri. La risposta a questa affermazione è che se vi servono più di 3 +livelli di indentazione, siete comunque fregati e dovreste correggere il vostro +programma. + +In breve, l'indentazione ad 8 caratteri rende più facile la lettura, e in +aggiunta vi avvisa quando state annidando troppo le vostre funzioni. +Tenete ben a mente questo avviso. + +Al fine di facilitare l'indentazione del costrutto switch, si preferisce +allineare sulla stessa colonna la parola chiave ``switch`` e i suoi +subordinati ``case``. In questo modo si evita una doppia indentazione per +i ``case``. Un esempio.: + +.. code-block:: c + + switch (suffix) { + case 'G': + case 'g': + mem <<= 30; + break; + case 'M': + case 'm': + mem <<= 20; + break; + case 'K': + case 'k': + mem <<= 10; + fallthrough; + default: + break; + } + +A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla +stessa riga: + +.. code-block:: c + + if (condition) do_this; + do_something_everytime; + +Non usate le virgole per evitare le parentesi: + +.. code-block:: c + + if (condition) + do_this(), do_that(); + +Invece, usate sempre le parentesi per racchiudere più istruzioni. + +.. code-block:: c + + if (condition) { + do_this(); + do_that(); + } + +Non mettete nemmeno più assegnamenti sulla stessa riga. Lo stile del kernel +è ultrasemplice. Evitate espressioni intricate. + + +Al di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli +spazi non vengono mai usati per l'indentazione, e l'esempio qui sopra è +volutamente errato. + +Procuratevi un buon editor di testo e non lasciate spazi bianchi alla fine +delle righe. + + +2) Spezzare righe lunghe e stringhe +----------------------------------- + +Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando +strumenti comuni. + +Come limite di riga si preferiscono le 80 colonne. + +Espressioni più lunghe di 80 colonne dovrebbero essere spezzettate in +pezzi più piccoli, a meno che eccedere le 80 colonne non aiuti ad +aumentare la leggibilità senza nascondere informazioni. + +I nuovi pezzi derivati sono sostanzialmente più corti degli originali +e vengono posizionati più a destra. Uno stile molto comune è quello di +allineare i nuovi pezzi alla parentesi aperta di una funzione. + +Lo stesso si applica, nei file d'intestazione, alle funzioni con una +lista di argomenti molto lunga. + +Tuttavia, non spezzettate mai le stringhe visibili agli utenti come i +messaggi di printk, questo perché inibireste la possibilità +d'utilizzare grep per cercarle. + +3) Posizionamento di parentesi graffe e spazi +--------------------------------------------- + +Un altro problema che s'affronta sempre quando si parla di stile in C è +il posizionamento delle parentesi graffe. Al contrario della dimensione +dell'indentazione, non ci sono motivi tecnici sulla base dei quali scegliere +una strategia di posizionamento o un'altra; ma il modo qui preferito, +come mostratoci dai profeti Kernighan e Ritchie, è quello di +posizionare la parentesi graffa di apertura per ultima sulla riga, e quella +di chiusura per prima su una nuova riga, così: + +.. code-block:: c + + if (x is true) { + we do y + } + +Questo è valido per tutte le espressioni che non siano funzioni (if, switch, +for, while, do). Per esempio: + +.. code-block:: c + + switch (action) { + case KOBJ_ADD: + return "add"; + case KOBJ_REMOVE: + return "remove"; + case KOBJ_CHANGE: + return "change"; + default: + return NULL; + } + +Tuttavia, c'è il caso speciale, le funzioni: queste hanno la parentesi graffa +di apertura all'inizio della riga successiva, quindi: + +.. code-block:: c + + int function(int x) + { + body of function + } + +Eretici da tutto il mondo affermano che questa incoerenza è ... +insomma ... incoerente, ma tutte le persone ragionevoli sanno che (a) +K&R hanno **ragione** e (b) K&R hanno ragione. A parte questo, le funzioni +sono comunque speciali (non potete annidarle in C). + +Notate che la graffa di chiusura è da sola su una riga propria, ad +**eccezione** di quei casi dove è seguita dalla continuazione della stessa +espressione, in pratica ``while`` nell'espressione do-while, oppure ``else`` +nell'espressione if-else, come questo: + +.. code-block:: c + + do { + body of do-loop + } while (condition); + +e + +.. code-block:: c + + if (x == y) { + .. + } else if (x > y) { + ... + } else { + .... + } + +Motivazione: K&R. + +Inoltre, notate che questo posizionamento delle graffe minimizza il numero +di righe vuote senza perdere di leggibilità. In questo modo, dato che le +righe sul vostro schermo non sono una risorsa illimitata (pensate ad uno +terminale con 25 righe), avrete delle righe vuote da riempire con dei +commenti. + +Non usate inutilmente le graffe dove una singola espressione è sufficiente. + +.. code-block:: c + + if (condition) + action(); + +e + +.. code-block:: none + + if (condition) + do_this(); + else + do_that(); + +Questo non vale nel caso in cui solo un ramo dell'espressione if-else +contiene una sola espressione; in quest'ultimo caso usate le graffe per +entrambe i rami: + +.. code-block:: c + + if (condition) { + do_this(); + do_that(); + } else { + otherwise(); + } + +Inoltre, usate le graffe se un ciclo contiene più di una semplice istruzione: + +.. code-block:: c + + while (condition) { + if (test) + do_something(); + } + +3.1) Spazi +********** + +Lo stile del kernel Linux per quanto riguarda gli spazi, dipende +(principalmente) dalle funzioni e dalle parole chiave. Usate una spazio dopo +(quasi tutte) le parole chiave. L'eccezioni più evidenti sono sizeof, typeof, +alignof, e __attribute__, il cui aspetto è molto simile a quello delle +funzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il +linguaggio non lo richiede; come ``sizeof info`` dopo aver dichiarato +``struct fileinfo info``). + +Quindi utilizzate uno spazio dopo le seguenti parole chiave:: + + if, switch, case, for, do, while + +ma non con sizeof, typeof, alignof, o __attribute__. Ad esempio, + +.. code-block:: c + + + s = sizeof(struct file); + +Non aggiungete spazi attorno (dentro) ad un'espressione fra parentesi. Questo +esempio è **brutto**: + +.. code-block:: c + + + s = sizeof( struct file ); + +Quando dichiarate un puntatore ad una variabile o una funzione che ritorna un +puntatore, il posto suggerito per l'asterisco ``*`` è adiacente al nome della +variabile o della funzione, e non adiacente al nome del tipo. Esempi: + +.. code-block:: c + + + char *linux_banner; + unsigned long long memparse(char *ptr, char **retptr); + char *match_strdup(substring_t *s); + +Usate uno spazio attorno (da ogni parte) alla maggior parte degli operatori +binari o ternari, come i seguenti:: + + = + - < > * / % | & ^ <= >= == != ? : + +ma non mettete spazi dopo gli operatori unari:: + + & * + - ~ ! sizeof typeof alignof __attribute__ defined + +nessuno spazio dopo l'operatore unario suffisso di incremento o decremento:: + + ++ -- + +nessuno spazio dopo l'operatore unario prefisso di incremento o decremento:: + + ++ -- + +e nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e +``->``. + +Non lasciate spazi bianchi alla fine delle righe. Alcuni editor con +l'indentazione ``furba`` inseriranno gli spazi bianchi all'inizio di una nuova +riga in modo appropriato, quindi potrete scrivere la riga di codice successiva +immediatamente. Tuttavia, alcuni di questi stessi editor non rimuovono +questi spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio +perché volete lasciare una riga vuota. Il risultato è che finirete per avere +delle righe che contengono spazi bianchi in coda. + +Git vi avviserà delle modifiche che aggiungono questi spazi vuoti di fine riga, +e può opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando +una serie di modifiche, questo potrebbe far fallire delle modifiche successive +perché il contesto delle righe verrà cambiato. + +4) Assegnare nomi +----------------- + +C è un linguaggio spartano, e così dovrebbero esserlo i vostri nomi. Al +contrario dei programmatori Modula-2 o Pascal, i programmatori C non usano +nomi graziosi come ThisVariableIsATemporaryCounter. Un programmatore C +chiamerebbe questa variabile ``tmp``, che è molto più facile da scrivere e +non è una delle più difficili da capire. + +TUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi +descrittivi per variabili globali sono un dovere. Chiamare una funzione +globale ``pippo`` è un insulto. + +Le variabili GLOBALI (da usare solo se vi servono **davvero**) devono avere +dei nomi descrittivi, così come le funzioni globali. Se avete una funzione +che conta gli utenti attivi, dovreste chiamarla ``count_active_users()`` o +qualcosa di simile, **non** dovreste chiamarla ``cntusr()``. + +Codificare il tipo di funzione nel suo nome (quella cosa chiamata notazione +ungherese) è stupido - il compilatore conosce comunque il tipo e +può verificarli, e inoltre confonde i programmatori. + +Le variabili LOCALI dovrebbero avere nomi corti, e significativi. Se avete +un qualsiasi contatore di ciclo, probabilmente sarà chiamato ``i``. +Chiamarlo ``loop_counter`` non è produttivo, non ci sono possibilità che +``i`` possa non essere capito. Analogamente, ``tmp`` può essere una qualsiasi +variabile che viene usata per salvare temporaneamente un valore. + +Se avete paura di fare casino coi nomi delle vostre variabili locali, allora +avete un altro problema che è chiamato sindrome dello squilibrio dell'ormone +della crescita delle funzioni. Vedere il capitolo 6 (funzioni). + +5) Definizione di tipi (typedef) +-------------------------------- + +Per favore non usate cose come ``vps_t``. +Usare il typedef per strutture e puntatori è uno **sbaglio**. Quando vedete: + +.. code-block:: c + + vps_t a; + +nei sorgenti, cosa significa? +Se, invece, dicesse: + +.. code-block:: c + + struct virtual_container *a; + +potreste dire cos'è effettivamente ``a``. + +Molte persone pensano che la definizione dei tipi ``migliori la leggibilità``. +Non molto. Sono utili per: + + (a) gli oggetti completamente opachi (dove typedef viene proprio usato allo + scopo di **nascondere** cosa sia davvero l'oggetto). + + Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente + con le loro funzioni accessorie. + + .. note:: + Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se, + una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è + che davvero non c'è alcuna informazione portabile. + + (b) i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare + confusione sul fatto che siano ``int`` oppure ``long``. + + u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono + nella categoria (d) piuttosto che in questa. + + .. note:: + + Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è + ``unsigned long``, non c'è alcun bisogno di avere: + + typedef unsigned long myfalgs_t; + + ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int`` + e in altre configurazioni ``unsigned long``, allora certamente typedef + è una buona scelta. + + (c) quando di rado create letteralmente dei **nuovi** tipi su cui effettuare + verifiche. + + (d) circostanze eccezionali, in cui si definiscono nuovi tipi identici a + quelli definiti dallo standard C99. + + Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei + tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso. + + Perciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti + con segno, identici ai tipi standard, sono permessi- tuttavia, non sono + obbligatori per il nuovo codice. + + (e) i tipi sicuri nella spazio utente. + + In alcune strutture dati visibili dallo spazio utente non possiamo + richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima. + Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati + condivise con lo spazio utente. + +Magari ci sono altri casi validi, ma la regola di base dovrebbe essere di +non usare MAI MAI un typedef a meno che non rientri in una delle regole +descritte qui. + +In generale, un puntatore, o una struttura a cui si ha accesso diretto in +modo ragionevole, non dovrebbero **mai** essere definite con un typedef. + +6) Funzioni +----------- + +Le funzioni dovrebbero essere brevi e carine, e fare una cosa sola. Dovrebbero +occupare uno o due schermi di testo (come tutti sappiamo, la dimensione +di uno schermo secondo ISO/ANSI è di 80x24), e fare una cosa sola e bene. + +La massima lunghezza di una funziona è inversamente proporzionale alla sua +complessità e al livello di indentazione di quella funzione. Quindi, se avete +una funzione che è concettualmente semplice ma che è implementata come un +lunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose +per molti casi differenti, allora va bene avere funzioni più lunghe. + +Comunque, se avete una funzione complessa e sospettate che uno studente +non particolarmente dotato del primo anno delle scuole superiori potrebbe +non capire cosa faccia la funzione, allora dovreste attenervi strettamente ai +limiti. Usate funzioni di supporto con nomi descrittivi (potete chiedere al +compilatore di renderle inline se credete che sia necessario per le +prestazioni, e probabilmente farà un lavoro migliore di quanto avreste potuto +fare voi). + +Un'altra misura delle funzioni sono il numero di variabili locali. Non +dovrebbero eccedere le 5-10, oppure state sbagliando qualcosa. Ripensate la +funzione, e dividetela in pezzettini. Generalmente, un cervello umano può +seguire facilmente circa 7 cose diverse, di più lo confonderebbe. Lo sai +d'essere brillante, ma magari vorresti riuscire a capire cos'avevi fatto due +settimane prima. + +Nei file sorgenti, separate le funzioni con una riga vuota. Se la funzione è +esportata, la macro **EXPORT** per questa funzione deve seguire immediatamente +la riga della parentesi graffa di chiusura. Ad esempio: + +.. code-block:: c + + int system_is_up(void) + { + return system_state == SYSTEM_RUNNING; + } + EXPORT_SYMBOL(system_is_up); + +6.1) Prototipi di funzione +************************** + +Nei prototipi di funzione, includete i nomi dei parametri e i loro tipi. +Nonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito +perché è un modo semplice per aggiungere informazioni importanti per il +lettore. + +Non usate la parola chiave ``extern`` con le dichiarazioni di funzione perché +rende le righe più lunghe e non è strettamente necessario. + +Quando scrivete i prototipi di funzione mantenete `l'ordine degli elementi <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_. + +Prendiamo questa dichiarazione di funzione come esempio:: + + __init void * __must_check action(enum magic value, size_t size, u8 count, + char *fmt, ...) __printf(4, 5) __malloc; + +L'ordine suggerito per gli elementi di un prototipo di funzione è il seguente: + +- classe d'archiviazione (in questo caso ``static __always_inline``. Da notare + che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come + ``inline``) +- attributi della classe di archiviazione (in questo caso ``__init``, in altre + parole la sezione, ma anche cose tipo ``__cold``) +- il tipo di ritorno (in questo caso, ``void *``) +- attributi per il valore di ritorno (in questo caso, ``__must_check``) +- il nome della funzione (in questo caso, ``action``) +- i parametri della funzione(in questo caso, + ``(enum magic value, size_t size, u8 count, char *fmt, ...)``, + da notare che va messo anche il nome del parametro) +- attributi dei parametri (in questo caso, ``__printf(4, 5)``) +- attributi per il comportamento della funzione (in questo caso, ``__malloc_``) + +Notate che per la **definizione** di una funzione (il altre parole il corpo +della funzione), il compilatore non permette di usare gli attributi per i +parametri dopo i parametri. In questi casi, devono essere messi dopo gli +attributi della classe d'archiviazione (notate che la posizione di +``__printf(4,5)`` cambia rispetto alla **dichiarazione**):: + + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, + size_t size, u8 count, char *fmt, ...) __malloc + { + ... + }*)**``)**``)``)``*)``)``)``)``*``)``)``)*) + +7) Centralizzare il ritorno delle funzioni +------------------------------------------ + +Sebbene sia deprecata da molte persone, l'istruzione goto è impiegata di +frequente dai compilatori sotto forma di salto incondizionato. + +L'istruzione goto diventa utile quando una funzione ha punti d'uscita multipli +e vanno eseguite alcune procedure di pulizia in comune. Se non è necessario +pulire alcunché, allora ritornate direttamente. + +Assegnate un nome all'etichetta di modo che suggerisca cosa fa la goto o +perché esiste. Un esempio di un buon nome potrebbe essere ``out_free_buffer:`` +se la goto libera (free) un ``buffer``. Evitate l'uso di nomi GW-BASIC come +``err1:`` ed ``err2:``, potreste doverli riordinare se aggiungete o rimuovete +punti d'uscita, e inoltre rende difficile verificarne la correttezza. + +I motivo per usare le goto sono: + +- i salti incondizionati sono più facili da capire e seguire +- l'annidamento si riduce +- si evita di dimenticare, per errore, di aggiornare un singolo punto d'uscita +- aiuta il compilatore ad ottimizzare il codice ridondante ;) + +.. code-block:: c + + int fun(int a) + { + int result = 0; + char *buffer; + + buffer = kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result = 1; + goto out_free_buffer; + } + ... + out_free_buffer: + kfree(buffer); + return result; + } + +Un baco abbastanza comune di cui bisogna prendere nota è il ``one err bugs`` +che assomiglia a questo: + +.. code-block:: c + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +Il baco in questo codice è che in alcuni punti d'uscita la variabile ``foo`` è +NULL. Normalmente si corregge questo baco dividendo la gestione dell'errore in +due parti ``err_free_bar:`` e ``err_free_foo:``: + +.. code-block:: c + + err_free_bar: + kfree(foo->bar); + err_free_foo: + kfree(foo); + return ret; + +Idealmente, dovreste simulare condizioni d'errore per verificare i vostri +percorsi d'uscita. + + +8) Commenti +----------- + +I commenti sono una buona cosa, ma c'è anche il rischio di esagerare. MAI +spiegare COME funziona il vostro codice in un commento: è molto meglio +scrivere il codice di modo che il suo funzionamento sia ovvio, inoltre +spiegare codice scritto male è una perdita di tempo. + +Solitamente, i commenti devono dire COSA fa il codice, e non COME lo fa. +Inoltre, cercate di evitare i commenti nel corpo della funzione: se la +funzione è così complessa che dovete commentarla a pezzi, allora dovreste +tornare al punto 6 per un momento. Potete mettere dei piccoli commenti per +annotare o avvisare il lettore circa un qualcosa di particolarmente arguto +(o brutto), ma cercate di non esagerare. Invece, mettete i commenti in +testa alla funzione spiegando alle persone cosa fa, e possibilmente anche +il PERCHÉ. + +Per favore, quando commentate una funzione dell'API del kernel usate il +formato kernel-doc. Per maggiori dettagli, leggete i file in +:ref::ref:`Documentation/translations/it_IT/doc-guide/ <it_doc_guide>` e in +``script/kernel-doc``. + +Lo stile preferito per i commenti più lunghi (multi-riga) è: + +.. code-block:: c + + /* + * This is the preferred style for multi-line + * comments in the Linux kernel source code. + * Please use it consistently. + * + * Description: A column of asterisks on the left side, + * with beginning and ending almost-blank lines. + */ + +Per i file in net/ e in drivers/net/ lo stile preferito per i commenti +più lunghi (multi-riga) è leggermente diverso. + +.. code-block:: c + + /* The preferred comment style for files in net/ and drivers/net + * looks like this. + * + * It is nearly the same as the generally preferred comment style, + * but there is no initial almost-blank line. + */ + +È anche importante commentare i dati, sia per i tipi base che per tipi +derivati. A questo scopo, dichiarate un dato per riga (niente virgole +per una dichiarazione multipla). Questo vi lascerà spazio per un piccolo +commento per spiegarne l'uso. + + +9) Avete fatto un pasticcio +--------------------------- + +Va bene, li facciamo tutti. Probabilmente vi è stato detto dal vostro +aiutante Unix di fiducia che ``GNU emacs`` formatta automaticamente il +codice C per conto vostro, e avete notato che sì, in effetti lo fa, ma che +i modi predefiniti non sono proprio allettanti (infatti, sono peggio che +premere tasti a caso - un numero infinito di scimmie che scrivono in +GNU emacs non faranno mai un buon programma). + +Quindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più +sensati. Per fare quest'ultima cosa, potete appiccicare il codice che +segue nel vostro file .emacs: + +.. code-block:: none + + (defun c-lineup-arglist-tabs-only (ignored) + "Line up argument lists by tabs, not spaces" + (let* ((anchor (c-langelem-pos c-syntactic-element)) + (column (c-langelem-2nd-pos c-syntactic-element)) + (offset (- (1+ column) anchor)) + (steps (floor offset c-basic-offset))) + (* (max steps 1) + c-basic-offset))) + + (dir-locals-set-class-variables + 'linux-kernel + '((c-mode . ( + (c-basic-offset . 8) + (c-label-minimum-indentation . 0) + (c-offsets-alist . ( + (arglist-close . c-lineup-arglist-tabs-only) + (arglist-cont-nonempty . + (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) + (arglist-intro . +) + (brace-list-intro . +) + (c . c-lineup-C-comments) + (case-label . 0) + (comment-intro . c-lineup-comment) + (cpp-define-intro . +) + (cpp-macro . -1000) + (cpp-macro-cont . +) + (defun-block-intro . +) + (else-clause . 0) + (func-decl-cont . +) + (inclass . +) + (inher-cont . c-lineup-multi-inher) + (knr-argdecl-intro . 0) + (label . -1000) + (statement . 0) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-cont . +) + (substatement . +) + )) + (indent-tabs-mode . t) + (show-trailing-whitespace . t) + )))) + + (dir-locals-set-directory-class + (expand-file-name "~/src/linux-trees") + 'linux-kernel) + +Questo farà funzionare meglio emacs con lo stile del kernel per i file che +si trovano nella cartella ``~/src/linux-trees``. + +Ma anche se doveste fallire nell'ottenere una formattazione sensata in emacs +non tutto è perduto: usate ``indent``. + +Ora, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs, +ed è per questo che dovete passargli alcune opzioni da riga di comando. +Tuttavia, non è così terribile, perché perfino i creatori di GNU indent +riconoscono l'autorità di K&R (le persone del progetto GNU non sono cattive, +sono solo mal indirizzate sull'argomento), quindi date ad indent le opzioni +``-kr -i8`` (che significa ``K&R, 8 caratteri di indentazione``), o utilizzate +``scripts/Lindent`` che indenterà usando l'ultimo stile. + +``indent`` ha un sacco di opzioni, e specialmente quando si tratta di +riformattare i commenti dovreste dare un'occhiata alle pagine man. +Ma ricordatevi: ``indent`` non è un correttore per una cattiva programmazione. + +Da notare che potete utilizzare anche ``clang-format`` per aiutarvi con queste +regole, per riformattare rapidamente ad automaticamente alcune parti del +vostro codice, e per revisionare interi file al fine di identificare errori +di stile, refusi e possibilmente anche delle migliorie. È anche utile per +ordinare gli ``#include``, per allineare variabili/macro, per ridistribuire +il testo e altre cose simili. +Per maggiori dettagli, consultate il file +:ref:`Documentation/translations/it_IT/process/clang-format.rst <it_clangformat>`. + + +10) File di configurazione Kconfig +---------------------------------- + +Per tutti i file di configurazione Kconfig* che si possono trovare nei +sorgenti, l'indentazione è un po' differente. Le linee dopo un ``config`` +sono indentate con un tab, mentre il testo descrittivo è indentato di +ulteriori due spazi. Esempio:: + + config AUDIT + bool "Auditing support" + depends on NET + help + Enable auditing infrastructure that can be used with another + kernel subsystem, such as SELinux (which requires this for + logging of avc messages output). Does not do system-call + auditing without CONFIG_AUDITSYSCALL. + +Le funzionalità davvero pericolose (per esempio il supporto alla scrittura +per certi filesystem) dovrebbero essere dichiarate chiaramente come tali +nella stringa di titolo:: + + config ADFS_FS_RW + bool "ADFS write support (DANGEROUS)" + depends on ADFS_FS + ... + +Per la documentazione completa sui file di configurazione, consultate +il documento Documentation/kbuild/kconfig-language.rst + + +11) Strutture dati +------------------ + +Le strutture dati che hanno una visibilità superiore al contesto del +singolo thread in cui vengono create e distrutte, dovrebbero sempre +avere un contatore di riferimenti. Nel kernel non esiste un +*garbage collector* (e fuori dal kernel i *garbage collector* sono lenti +e inefficienti), questo significa che **dovete** assolutamente avere un +contatore di riferimenti per ogni cosa che usate. + +Avere un contatore di riferimenti significa che potete evitare la +sincronizzazione e permette a più utenti di accedere alla struttura dati +in parallelo - e non doversi preoccupare di una struttura dati che +improvvisamente sparisce dalla loro vista perché il loro processo dormiva +o stava facendo altro per un attimo. + +Da notare che la sincronizzazione **non** si sostituisce al conteggio dei +riferimenti. La sincronizzazione ha lo scopo di mantenere le strutture +dati coerenti, mentre il conteggio dei riferimenti è una tecnica di gestione +della memoria. Solitamente servono entrambe le cose, e non vanno confuse fra +di loro. + +Quando si hanno diverse classi di utenti, le strutture dati possono avere +due livelli di contatori di riferimenti. Il contatore di classe conta +il numero dei suoi utenti, e il contatore globale viene decrementato una +sola volta quando il contatore di classe va a zero. + +Un esempio di questo tipo di conteggio dei riferimenti multi-livello può +essere trovato nella gestore della memoria (``struct mm_sturct``: mm_user e +mm_count), e nel codice dei filesystem (``struct super_block``: s_count e +s_active). + +Ricordatevi: se un altro thread può trovare la vostra struttura dati, e non +avete un contatore di riferimenti per essa, quasi certamente avete un baco. + +12) Macro, enumerati e RTL +--------------------------- + +I nomi delle macro che definiscono delle costanti e le etichette degli +enumerati sono scritte in maiuscolo. + +.. code-block:: c + + #define CONSTANT 0x12345 + +Gli enumerati sono da preferire quando si definiscono molte costanti correlate. + +I nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano +a delle funzioni possono essere scritte in minuscolo. + +Generalmente, le funzioni inline sono preferibili rispetto alle macro che +sembrano funzioni. + +Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un +blocco do - while: + +.. code-block:: c + + #define macrofun(a, b, c) \ + do { \ + if (a == 5) \ + do_this(b, c); \ + } while (0) + +Cose da evitare quando si usano le macro: + +1) le macro che hanno effetti sul flusso del codice: + +.. code-block:: c + + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) + +sono **proprio** una pessima idea. Sembra una chiamata a funzione ma termina +la funzione chiamante; non cercate di rompere il decodificatore interno di +chi legge il codice. + +2) le macro che dipendono dall'uso di una variabile locale con un nome magico: + +.. code-block:: c + + #define FOO(val) bar(index, val) + +potrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno +legge il codice e potrebbe romperlo con una cambiamento che sembra innocente. + +3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe +ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione +inline. + +4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono +essere racchiuse fra parentesi. State attenti a problemi simili con le macro +parametrizzate. + +.. code-block:: c + + #define CONSTANT 0x4000 + #define CONSTEXP (CONSTANT | 3) + +5) collisione nello spazio dei nomi quando si definisce una variabile locale in +una macro che sembra una funzione: + +.. code-block:: c + + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret = calc_ret(x); \ + (ret); \ + }) + +ret è un nome comune per una variabile locale - __foo_ret difficilmente +andrà in conflitto con una variabile già esistente. + +Il manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo +di gcc copre anche l'RTL che viene usato frequentemente nel kernel per il +linguaggio assembler. + +13) Visualizzare i messaggi del kernel +-------------------------------------- + +Agli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio +di riguardo per l'ortografia e farete una belle figura. In inglese, evitate +l'uso incorretto di abbreviazioni come ``dont``: usate ``do not`` oppure +``don't``. Scrivete messaggi concisi, chiari, e inequivocabili. + +I messaggi del kernel non devono terminare con un punto fermo. + +Scrivere i numeri fra parentesi (%d) non migliora alcunché e per questo +dovrebbero essere evitati. + +Ci sono alcune macro per la diagnostica in <linux/dev_printk.h> che dovreste +usare per assicurarvi che i messaggi vengano associati correttamente ai +dispositivi e ai driver, e che siano etichettati correttamente: dev_err(), +dev_warn(), dev_info(), e così via. Per messaggi che non sono associati ad +alcun dispositivo, <linux/printk.h> definisce pr_info(), pr_warn(), pr_err(), +eccetera. + +Tirar fuori un buon messaggio di debug può essere una vera sfida; e quando +l'avete può essere d'enorme aiuto per risolvere problemi da remoto. +Tuttavia, i messaggi di debug sono gestiti differentemente rispetto agli +altri. Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no; +essa non viene compilata nella configurazione predefinita, a meno che +DEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati. Questo vale anche per +dev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg(). + +Molti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono +-DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG +in specifici file. Infine, quando un messaggio di debug dev'essere stampato +incondizionatamente, per esempio perché siete già in una sezione di debug +racchiusa in #ifdef, potete usare printk(KERN_DEBUG ...). + +14) Assegnare memoria +--------------------- + +Il kernel fornisce i seguenti assegnatori ad uso generico: +kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc(). +Per maggiori informazioni, consultate la documentazione dell'API: +:ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst <it_memory_allocation>` + +Il modo preferito per passare la dimensione di una struttura è il seguente: + +.. code-block:: c + + p = kmalloc(sizeof(*p), ...); + +La forma alternativa, dove il nome della struttura viene scritto interamente, +peggiora la leggibilità e introduce possibili bachi quando il tipo di +puntatore cambia tipo ma il corrispondente sizeof non viene aggiornato. + +Il valore di ritorno è un puntatore void, effettuare un cast su di esso è +ridondante. La conversione fra un puntatore void e un qualsiasi altro tipo +di puntatore è garantito dal linguaggio di programmazione C. + +Il modo preferito per assegnare un vettore è il seguente: + +.. code-block:: c + + p = kmalloc_array(n, sizeof(...), ...); + +Il modo preferito per assegnare un vettore a zero è il seguente: + +.. code-block:: c + + p = kcalloc(n, sizeof(...), ...); + +Entrambe verificano la condizione di overflow per la dimensione +d'assegnamento n * sizeof(...), se accade ritorneranno NULL. + +Questi allocatori generici producono uno *stack dump* in caso di fallimento +a meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella +maggior parte dei casi, è inutile stampare messaggi aggiuntivi quando uno di +questi allocatori ritornano un puntatore NULL. + +15) Il morbo inline +------------------- + +Sembra che ci sia la percezione errata che gcc abbia una qualche magica +opzione "rendimi più veloce" chiamata ``inline``. In alcuni casi l'uso di +inline è appropriato (per esempio in sostituzione delle macro, vedi +capitolo 12), ma molto spesso non lo è. L'uso abbondante della parola chiave +inline porta ad avere un kernel più grande, che si traduce in un sistema nel +suo complesso più lento per via di una cache per le istruzioni della CPU più +grande e poi semplicemente perché ci sarà meno spazio disponibile per una +pagina di cache. Pensateci un attimo; una fallimento nella cache causa una +ricerca su disco che può tranquillamente richiedere 5 millisecondi. Ci sono +TANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi. + +Spesso le persone dicono che aggiungere inline a delle funzioni dichiarate +static e utilizzare una sola volta è sempre una scelta vincente perché non +ci sono altri compromessi. Questo è tecnicamente vero ma gcc è in grado di +trasformare automaticamente queste funzioni in inline; i problemi di +manutenzione del codice per rimuovere gli inline quando compare un secondo +utente surclassano il potenziale vantaggio nel suggerire a gcc di fare una +cosa che avrebbe fatto comunque. + +16) Nomi e valori di ritorno delle funzioni +------------------------------------------- + +Le funzioni possono ritornare diversi tipi di valori, e uno dei più comuni +è quel valore che indica se una funzione ha completato con successo o meno. +Questo valore può essere rappresentato come un codice di errore intero +(-Exxx = fallimento, 0 = successo) oppure un booleano di successo +(0 = fallimento, non-zero = successo). + +Mischiare questi due tipi di rappresentazioni è un terreno fertile per +i bachi più insidiosi. Se il linguaggio C includesse una forte distinzione +fra gli interi e i booleani, allora il compilatore potrebbe trovare questi +errori per conto nostro ... ma questo non c'è. Per evitare di imbattersi +in questo tipo di baco, seguite sempre la seguente convenzione:: + + Se il nome di una funzione è un'azione o un comando imperativo, + essa dovrebbe ritornare un codice di errore intero. Se il nome + è un predicato, la funzione dovrebbe ritornare un booleano di + "successo" + +Per esempio, ``add work`` è un comando, e la funzione add_work() ritorna 0 +in caso di successo o -EBUSY in caso di fallimento. Allo stesso modo, +``PCI device present`` è un predicato, e la funzione pci_dev_present() ritorna +1 se trova il dispositivo corrispondente con successo, altrimenti 0. + +Tutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e +così dovrebbero anche tutte le funzioni pubbliche. Le funzioni private +(static) possono non seguire questa convenzione, ma è comunque raccomandato +che lo facciano. + +Le funzioni il cui valore di ritorno è il risultato di una computazione, +piuttosto che l'indicazione sul successo di tale computazione, non sono +soggette a questa regola. Solitamente si indicano gli errori ritornando un +qualche valore fuori dai limiti. Un tipico esempio è quello delle funzioni +che ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo +di notifica degli errori. + +17) L'uso di bool +----------------- + +Nel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99. +Un valore bool può assumere solo i valori 0 o 1, e implicitamente o +esplicitamente la conversione a bool converte i valori in vero (*true*) o +falso (*false*). Quando si usa un tipo bool il costrutto !! non sarà più +necessario, e questo va ad eliminare una certa serie di bachi. + +Quando si usano i valori booleani, dovreste utilizzare le definizioni di true +e false al posto dei valori 1 e 0. + +Per il valore di ritorno delle funzioni e per le variabili sullo stack, l'uso +del tipo bool è sempre appropriato. L'uso di bool viene incoraggiato per +migliorare la leggibilità e spesso è molto meglio di 'int' nella gestione di +valori booleani. + +Non usate bool se per voi sono importanti l'ordine delle righe di cache o +la loro dimensione; la dimensione e l'allineamento cambia a seconda +dell'architettura per la quale è stato compilato. Le strutture che sono state +ottimizzate per l'allineamento o la dimensione non dovrebbero usare bool. + +Se una struttura ha molti valori true/false, considerate l'idea di raggrupparli +in un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa, +come u8. + +Come per gli argomenti delle funzioni, molti valori true/false possono essere +raggruppati in un singolo argomento a bit denominato 'flags'; spesso 'flags' è +un'alternativa molto più leggibile se si hanno valori costanti per true/false. + +Detto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti +può migliorare la leggibilità. + +18) Non reinventate le macro del kernel +--------------------------------------- + +Il file di intestazione include/linux/kernel.h contiene un certo numero +di macro che dovreste usare piuttosto che implementarne una qualche variante. +Per esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la +macro: + +.. code-block:: c + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +Analogamente, se dovete calcolare la dimensione di un qualche campo di una +struttura, usate + +.. code-block:: c + + #define sizeof_field(t, f) (sizeof(((t*)0)->f)) + +Ci sono anche le macro min() e max() che, se vi serve, effettuano un controllo +rigido sui tipi. Sentitevi liberi di leggere attentamente questo file +d'intestazione per scoprire cos'altro è stato definito che non dovreste +reinventare nel vostro codice. + +19) Linee di configurazione degli editor e altre schifezze +----------------------------------------------------------- + +Alcuni editor possono interpretare dei parametri di configurazione integrati +nei file sorgenti e indicati con dai marcatori speciali. Per esempio, emacs +interpreta le linee marcate nel seguente modo: + +.. code-block:: c + + -*- mode: c -*- + +O come queste: + +.. code-block:: c + + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ + +Vim interpreta i marcatori come questi: + +.. code-block:: c + + /* vim:set sw=8 noet */ + +Non includete nessuna di queste cose nei file sorgenti. Le persone hanno le +proprie configurazioni personali per l'editor, e i vostri sorgenti non +dovrebbero sovrascrivergliele. Questo vale anche per i marcatori +d'indentazione e di modalità d'uso. Le persone potrebbero aver configurato una +modalità su misura, oppure potrebbero avere qualche altra magia per far +funzionare bene l'indentazione. + +20) Inline assembly +------------------- + +Nel codice specifico per un'architettura, potreste aver bisogno di codice +*inline assembly* per interfacciarvi col processore o con una funzionalità +specifica della piattaforma. Non esitate a farlo quando è necessario. +Comunque, non usatele gratuitamente quando il C può fare la stessa cosa. +Potete e dovreste punzecchiare l'hardware in C quando è possibile. + +Considerate la scrittura di una semplice funzione che racchiude pezzi comuni +di codice assembler piuttosto che continuare a riscrivere delle piccole +varianti. Ricordatevi che l' *inline assembly* può utilizzare i parametri C. + +Il codice assembler più corposo e non banale dovrebbe andare nei file .S, +coi rispettivi prototipi C definiti nei file d'intestazione. I prototipi C +per le funzioni assembler dovrebbero usare ``asmlinkage``. + +Potreste aver bisogno di marcare il vostro codice asm come volatile al fine +d'evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali. +Non c'è sempre bisogno di farlo, e farlo quando non serve limita le +ottimizzazioni. + +Quando scrivete una singola espressione *inline assembly* contenente più +istruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa; +ad eccezione dell'ultima stringa/istruzione, ognuna deve terminare con ``\n\t`` +al fine di allineare correttamente l'assembler che verrà generato: + +.. code-block:: c + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + +21) Compilazione sotto condizione +--------------------------------- + +Ovunque sia possibile, non usate le direttive condizionali del preprocessore +(#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da +seguire. Invece, usate queste direttive nei file d'intestazione per definire +le funzioni usate nei file .c, fornendo i relativi stub nel caso #else, +e quindi chiamate queste funzioni senza condizioni di preprocessore. Il +compilatore non produrrà alcun codice per le funzioni stub, produrrà gli +stessi risultati, e la logica rimarrà semplice da seguire. + +È preferibile non compilare intere funzioni piuttosto che porzioni d'esse o +porzioni d'espressioni. Piuttosto che mettere una ifdef in un'espressione, +fattorizzate parte dell'espressione, o interamente, in funzioni e applicate +la direttiva condizionale su di esse. + +Se avete una variabile o funzione che potrebbe non essere usata in alcune +configurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione +inutilizzata, marcate questa definizione come __maybe_unused piuttosto che +racchiuderla in una direttiva condizionale del preprocessore. (Comunque, +se una variabile o funzione è *sempre* inutilizzata, rimuovetela). + +Nel codice, dov'è possibile, usate la macro IS_ENABLED per convertire i +simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche +condizioni C: + +.. code-block:: c + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +Il compilatore valuterà la condizione come costante (constant-fold), e quindi +includerà o escluderà il blocco di codice come se fosse in un #ifdef, quindi +non ne aumenterà il tempo di esecuzione. Tuttavia, questo permette al +compilatore C di vedere il codice nel blocco condizionale e verificarne la +correttezza (sintassi, tipi, riferimenti ai simboli, eccetera). Quindi +dovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste +solo quando la condizione è soddisfatta. + +Alla fine di un blocco corposo di #if o #ifdef (più di alcune linee), +mettete un commento sulla stessa riga di #endif, annotando la condizione +che termina. Per esempio: + +.. code-block:: c + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + +Appendice I) riferimenti +------------------------ + +The C Programming Language, Second Edition +by Brian W. Kernighan and Dennis M. Ritchie. +Prentice Hall, Inc., 1988. +ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback). + +The Practice of Programming +by Brian W. Kernighan and Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. + +Manuali GNU - nei casi in cui sono compatibili con K&R e questo documento - +per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui +https://www.gnu.org/manual/ + +WG14 è il gruppo internazionale di standardizzazione per il linguaggio C, +URL: https://www.open-std.org/JTC1/SC22/WG14/ + +Kernel CodingStyle, by greg@kroah.com at OLS 2002: +http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ diff --git a/Documentation/translations/it_IT/process/deprecated.rst b/Documentation/translations/it_IT/process/deprecated.rst new file mode 100644 index 0000000000..ba0ed7dc15 --- /dev/null +++ b/Documentation/translations/it_IT/process/deprecated.rst @@ -0,0 +1,409 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/deprecated.rst <deprecated>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_deprecated: + +============================================================================== +Interfacce deprecate, caratteristiche del linguaggio, attributi, e convenzioni +============================================================================== + +In un mondo perfetto, sarebbe possibile prendere tutti gli usi di +un'interfaccia deprecata e convertirli in quella nuova, e così sarebbe +possibile rimuovere la vecchia interfaccia in un singolo ciclo di sviluppo. +Tuttavia, per via delle dimensioni del kernel, la gerarchia dei manutentori e +le tempistiche, non è sempre possibile fare questo tipo di conversione tutta +in una volta. Questo significa che nuove istanze di una vecchia interfaccia +potrebbero aggiungersi al kernel proprio quando si sta cercando di rimuoverle, +aumentando così il carico di lavoro. Al fine di istruire gli sviluppatori su +cosa è considerato deprecato (e perché), è stata create la seguente lista a cui +fare riferimento quando qualcuno propone modifiche che usano cose deprecate. + +__deprecated +------------ +Nonostante questo attributo marchi visibilmente un interfaccia come deprecata, +`non produce più alcun avviso durante la compilazione +<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_ +perché uno degli obiettivi del kernel è quello di compilare senza avvisi; +inoltre, nessuno stava agendo per rimuovere queste interfacce. Nonostante l'uso +di `__deprecated` in un file d'intestazione sia opportuno per segnare una +interfaccia come 'vecchia', questa non è una soluzione completa. L'interfaccia +deve essere rimossa dal kernel, o aggiunta a questo documento per scoraggiarne +l'uso. + +BUG() e BUG_ON() +---------------- +Al loro posto usate WARN() e WARN_ON() per gestire le +condizioni "impossibili" e gestitele come se fosse possibile farlo. +Nonostante le funzioni della famiglia BUG() siano state progettate +per asserire "situazioni impossibili" e interrompere in sicurezza un +thread del kernel, queste si sono rivelate essere troppo rischiose +(per esempio, in quale ordine rilasciare i *lock*? Ci sono stati che +sono stati ripristinati?). Molto spesso l'uso di BUG() +destabilizza il sistema o lo corrompe del tutto, il che rende +impossibile un'attività di debug o anche solo leggere un rapporto +circa l'errore. Linus ha un'opinione molto critica al riguardo: +`email 1 +<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_, +`email 2 +<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_ + +Tenete presente che la famiglia di funzioni WARN() dovrebbe essere +usato solo per situazioni che si suppone siano "impossibili". Se +volete avvisare gli utenti riguardo a qualcosa di possibile anche se +indesiderato, usare le funzioni della famiglia pr_warn(). Chi +amministra il sistema potrebbe aver attivato l'opzione sysctl +*panic_on_warn* per essere sicuri che il sistema smetta di funzionare +in caso si verifichino delle condizioni "inaspettate". (per esempio, +date un'occhiata al questo `commit +<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_) + +Calcoli codificati negli argomenti di un allocatore +---------------------------------------------------- +Il calcolo dinamico delle dimensioni (specialmente le moltiplicazioni) non +dovrebbero essere fatto negli argomenti di funzioni di allocazione di memoria +(o simili) per via del rischio di overflow. Questo può portare a valori più +piccoli di quelli che il chiamante si aspettava. L'uso di questo modo di +allocare può portare ad un overflow della memoria di heap e altri +malfunzionamenti. (Si fa eccezione per valori numerici per i quali il +compilatore può generare avvisi circa un potenziale overflow. Tuttavia, anche in +questi casi è preferibile riscrivere il codice come suggerito di seguito). + +Per esempio, non usate ``count * size`` come argomento:: + + foo = kmalloc(count * size, GFP_KERNEL); + +Al suo posto, si dovrebbe usare l'allocatore a due argomenti:: + + foo = kmalloc_array(count, size, GFP_KERNEL); + +Nello specifico, kmalloc() può essere sostituta da kmalloc_array(), e kzalloc() +da kcalloc(). + +Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate +le funzioni del tipo *saturate-on-overflow*:: + + bar = vmalloc(array_size(count, size)); + +Un altro tipico caso da evitare è quello di calcolare la dimensione di una +struttura seguita da un vettore di altre strutture, come nel seguente caso:: + + header = kzalloc(sizeof(*header) + count * sizeof(*header->item), + GFP_KERNEL); + +Invece, usate la seguente funzione:: + + header = kzalloc(struct_size(header, item, count), GFP_KERNEL); + +.. note:: Se per caso state usando struct_size() su una struttura dati che + in coda contiene un array di lunghezza zero o uno, allora siete + invitati a riorganizzare il vostro codice usando il + `flexible array member <#zero-length-and-one-element-arrays>`_. + +Per altri calcoli, usate le funzioni size_mul(), size_add(), e size_sub(). Per +esempio, al posto di:: + + foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL); + +dovreste scrivere: + + foo = krealloc(size_add(current_size, + size_mul(chunk_size, + size_sub(count, 3))), GFP_KERNEL); + +Per maggiori dettagli fate riferimento a array3_size() e flex_array_size(), ma +anche le funzioni della famiglia check_mul_overflow(), check_add_overflow(), +check_sub_overflow(), e check_shl_overflow(). + +simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull() +---------------------------------------------------------------------- +Le funzioni simple_strtol(), simple_strtoll(), +simple_strtoul(), e simple_strtoull() ignorano volutamente +i possibili overflow, e questo può portare il chiamante a generare risultati +inaspettati. Le rispettive funzioni kstrtol(), kstrtoll(), +kstrtoul(), e kstrtoull() sono da considerarsi le corrette +sostitute; tuttavia va notato che queste richiedono che la stringa sia +terminata con il carattere NUL o quello di nuova riga. + +strcpy() +-------- +La funzione strcpy() non fa controlli agli estremi del buffer +di destinazione. Questo può portare ad un overflow oltre i limiti del +buffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione +`CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano +a ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare +questa funzione. La versione sicura da usare è strscpy(), tuttavia va +prestata attenzione a tutti quei casi dove viene usato il valore di +ritorno di strcpy(). La funzione strscpy() non ritorna un puntatore +alla destinazione, ma un contatore dei byte non NUL copiati (oppure +un errno negativo se la stringa è stata troncata). + +strncpy() su stringe terminate con NUL +-------------------------------------- +L'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che +il buffer di destinazione verrà terminato con il carattere NUL. Questo +potrebbe portare a diversi overflow di lettura o altri malfunzionamenti +causati, appunto, dalla mancanza del terminatore. Questa estende la +terminazione nel buffer di destinazione quando la stringa d'origine è più +corta; questo potrebbe portare ad una penalizzazione delle prestazioni per +chi usa solo stringe terminate. La versione sicura da usare è +strscpy(), tuttavia va prestata attenzione a tutti quei casi dove +viene usato il valore di ritorno di strncpy(). La funzione strscpy() +non ritorna un puntatore alla destinazione, ma un contatore dei byte +non NUL copiati (oppure un errno negativo se la stringa è stata +troncata). Tutti i casi che necessitano di estendere la +terminazione con NUL dovrebbero usare strscpy_pad(). + +Se il chiamate no usa stringhe terminate con NUL, allore strncpy() +può continuare ad essere usata, ma i buffer di destinazione devono essere +marchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_ +per evitare avvisi durante la compilazione. + +strlcpy() +--------- +La funzione strlcpy(), per prima cosa, legge interamente il buffer di +origine, magari leggendo più di quanto verrà effettivamente copiato. Questo +è inefficiente e può portare a overflow di lettura quando la stringa non è +terminata con NUL. La versione sicura da usare è strscpy(), tuttavia +va prestata attenzione a tutti quei casi dove viene usato il valore di +ritorno di strlcpy(), dato che strscpy() ritorna un valore di errno +negativo quanto la stringa viene troncata. + +Segnaposto %p nella stringa di formato +-------------------------------------- + +Tradizionalmente, l'uso del segnaposto "%p" nella stringa di formato +esponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera. Per +evitare che questi indirizzi vengano sfruttati da malintenzionati, +tutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo, +rendendolo di fatto inutilizzabile. Nuovi usi di "%p" non dovrebbero +essere aggiunti al kernel. Per una rappresentazione testuale di un +indirizzo usate "%pS", l'output è migliore perché mostrerà il nome del +simbolo. Per tutto il resto, semplicemente non usate "%p". + +Parafrasando la `guida +<https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_ +di Linus: + +- Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso + è importante. Forse dovrebbe essere rimosso del tutto? +- Se credi davvero che il vero valore del puntatore sia importante, + perché alcuni stati del sistema o i livelli di privilegi di un + utente sono considerati "special"? Se pensi di poterlo giustificare + (in un commento e nel messaggio del commit) abbastanza bene da + affrontare il giudizio di Linus, allora forse potrai usare "%px", + assicurandosi anche di averne il permesso. + +Potete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa +funzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo +aggiungete l'opzione di debug "`no_hash_pointers +<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_" alla +riga di comando del kernel. + +Vettori a dimensione variabile (VLA) +------------------------------------ + +Usare VLA sullo stack produce codice molto peggiore rispetto a quando si usano +vettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_, +tutt'altro che banali, sono già un motivo valido per eliminare i VLA; in +aggiunta sono anche un problema per la sicurezza. La crescita dinamica di un +vettore nello stack potrebbe eccedere la memoria rimanente in tale segmento. +Questo può portare a dei malfunzionamenti, potrebbe sovrascrivere +dati importanti alla fine dello stack (quando il kernel è compilato senza +`CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente +allo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`). + +Salto implicito nell'istruzione switch-case +------------------------------------------- + +Il linguaggio C permette ai casi di un'istruzione `switch` di saltare al +prossimo caso quando l'istruzione "break" viene omessa alla fine del caso +corrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se +l'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio, +osservando il seguente pezzo di codice non è chiaro se lo stato +`STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`:: + + switch (value) { + case STATE_ONE: + do_something(); + case STATE_TWO: + do_other(); + break; + default: + WARN("unknown state"); + } + +Dato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione +"break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non +permettiamo più che vi sia un "salto implicito" (*fall-through*). Per +identificare un salto implicito intenzionale abbiamo adottato la pseudo +parola chiave 'fallthrough' che viene espansa nell'estensione di gcc +`__attribute__((fallthrough))` `Statement Attributes +<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_. +(Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente +supportata dai compilatori C, analizzatori statici, e dagli IDE, +allora potremo usare quella sintassi per la pseudo parola chiave) + +Quando la sintassi [[fallthrough]] sarà più comunemente supportata dai +compilatori, analizzatori statici, e ambienti di sviluppo IDE, +allora potremo usarla anche noi. + +Ne consegue che tutti i blocchi switch/case devono finire in uno dei seguenti +modi: + +* ``break;`` +* `fallthrough;`` +* ``continue;`` +* ``goto <label>;`` +* ``return [expression];`` + +Array di lunghezza zero o con un solo elemento +---------------------------------------------- +All'interno del kernel ricorre spesso la necessita di avere membri +di dimensione variabile all'interno di una struttura dati. In questi +casi il codice del kernel dovrebbe usare sempre i `"flexible array +member" <https://en.wikipedia.org/wiki/Flexible_array_member>`_. La +tecnica degli array a lunghezza nulla o di un solo elemento non +dovrebbe essere più usata. + +Nel codice C più vecchio, la dichiarazione di un membro di dimensione +variabile in coda ad una struttura dati veniva fatto dichiarando un +array di un solo elemento posizionato alla fine della struttura dati:: + + struct something { + size_t count; + struct foo items[1]; + }; + +Questo ha portato ad un calcolo di sizeof() traballante (dovrebbe +rimuovere la dimensione del singolo elemento in coda per calcolare la +dimensione esatta dell' "intestazione"). Per evitare questi problemi è +stata introdotta un' `estensione a GNU C +<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ che +permettesse la dichiarazione di array a lungezza zero:: + + struct something { + size_t count; + struct foo items[0]; + }; + +Ma questo ha portato nuovi problemi, e non ha risolto alcuni dei +problemi che affliggono entrambe le tecniche: per esempio +l'impossibilità di riconoscere se un array di quel tipo viene usato +nel mezzo di una struttura dati e _non_ alla fine (potrebbe accadere +sia direttamente, sia indirettamente quando si usano le unioni o le +strutture di strutture). + +Lo standard C99 introduce i "flexible array members". Questi array non +hanno una dimensione nella loro dichiarazione:: + + struct something { + size_t count; + struct foo items[]; + }; + +Questo è il modo con cui ci si aspetta che vengano dichiarati gli +elementi di lunghezza variabile in coda alle strutture dati. Permette +al compilatore di produrre errori quando gli array flessibili non si +trovano alla fine della struttura dati, il che permette di prevenire +alcuni tipi di bachi dovuti a `comportamenti inaspettati +<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_. +Inoltre, permette al compilatore di analizzare correttamente le +dimensioni degli array (attraverso sizeof(), `CONFIG_FORTIFY_SOURCE`, +e `CONFIG_UBSAN_BOUNDS`). Per esempio, non esiste alcun meccanismo in +grado di avvisarci che il seguente uso di sizeof() dia sempre come +zero come risultato:: + + struct something { + size_t count; + struct foo items[0]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL); + instance->count = count; + + size = sizeof(instance->items) * instance->count; + memcpy(instance->items, source, size); + +Il valore di ``size`` nell'ultima riga sarà ``zero``, quando uno +invece si aspetterebbe che il suo valore sia la dimensione totale in +byte dell'allocazione dinamica che abbiamo appena fatto per l'array +``items``. Qui un paio di esempi reali del problema: `collegamento 1 +<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_, +`collegamento 2 +<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_. +Invece, `i flexible array members hanno un tipo incompleto, e quindi +sizeof() non può essere applicato +<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_; dunque ogni +uso scorretto di questo operatore verrà identificato immediatamente +durante la compilazione. + +Per quanto riguarda gli array di un solo elemento, bisogna essere +consapevoli che `questi array occupano almeno quanto lo spazio di un +singolo oggetti dello stesso tipo +<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, e quindi +contribuiscono al calcolo della dimensione della struttura che li +contiene. In questo caso è facile commettere errori quando si vuole +calcolare la dimensione totale della memoria totale da allocare per +una struttura dati:: + + struct something { + size_t count; + struct foo items[1]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL); + instance->count = count; + + size = sizeof(instance->items) * instance->count; + memcpy(instance->items, source, size); + +In questo esempio ci siamo dovuti ricordare di usare ``count - 1`` in +struct_size(), altrimenti avremmo --inavvertitamente-- allocato +memoria per un oggetti ``items`` in più. Il modo più pulito e meno +propenso agli errori è quello di usare i `flexible array member`, in +combinazione con struct_size() e flex_array_size():: + + struct something { + size_t count; + struct foo items[]; + }; + + struct something *instance; + + instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL); + instance->count = count; + + memcpy(instance->items, source, flex_array_size(instance, items, instance->count)); + +Ci sono due casi speciali dove è necessario usare la macro DECLARE_FLEX_ARRAY() +(da notare che la stessa macro è chiamata __DECLARE_FLEX_ARRAY() nei file di +intestazione UAPI). Uno è quando l'array flessibile è l'unico elemento di una +struttura, e l'altro quando è parte di un unione. Per motivi non tecnici, entrambi +i casi d'uso non sono permessi dalla specifica C99. Per esempio, per +convertire il seguente codice:: + + struct something { + ... + union { + struct type1 one[0]; + struct type2 two[0]; + }; + }; + +La macro di supporto dev'essere usata:: + + struct something { + ... + union { + DECLARE_FLEX_ARRAY(struct type1, one); + DECLARE_FLEX_ARRAY(struct type2, two); + }; + }; diff --git a/Documentation/translations/it_IT/process/development-process.rst b/Documentation/translations/it_IT/process/development-process.rst new file mode 100644 index 0000000000..f1a6eca308 --- /dev/null +++ b/Documentation/translations/it_IT/process/development-process.rst @@ -0,0 +1,33 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/development-process.rst <development_process_main>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_development_process_main: + +Una guida al processo di sviluppo del Kernel +============================================ + +Contenuti: + +.. toctree:: + :numbered: + :maxdepth: 2 + + 1.Intro + 2.Process + 3.Early-stage + 4.Coding + 5.Posting + 6.Followthrough + 7.AdvancedTopics + 8.Conclusion + +Lo scopo di questo documento è quello di aiutare gli sviluppatori (ed i loro +supervisori) a lavorare con la communità di sviluppo con il minimo sforzo. È +un tentativo di documentare il funzionamento di questa communità in modo che +sia accessibile anche a coloro che non hanno famigliarità con lo sviluppo del +Kernel Linux (o, anzi, con lo sviluppo di software libero in generale). Benchè +qui sia presente del materiale tecnico, questa è una discussione rivolta in +particolare al procedimento, e quindi per essere compreso non richiede una +conoscenza approfondità sullo sviluppo del kernel. diff --git a/Documentation/translations/it_IT/process/email-clients.rst b/Documentation/translations/it_IT/process/email-clients.rst new file mode 100644 index 0000000000..76ca3226c8 --- /dev/null +++ b/Documentation/translations/it_IT/process/email-clients.rst @@ -0,0 +1,391 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :doc:`../../../process/email-clients` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_email_clients: + +Informazioni sui programmi di posta elettronica per Linux +========================================================= + +Git +--- + +Oggigiorno, la maggior parte degli sviluppatori utilizza ``git send-email`` +al posto dei classici programmi di posta elettronica. Le pagine man sono +abbastanza buone. Dal lato del ricevente, i manutentori utilizzano ``git am`` +per applicare le patch. + +Se siete dei novelli utilizzatori di ``git`` allora inviate la patch a voi +stessi. Salvatela come testo includendo tutte le intestazioni. Poi eseguite +il comando ``git am messaggio-formato-testo.txt`` e revisionatene il risultato +con ``git log``. Quando tutto funziona correttamente, allora potete inviare +la patch alla lista di discussione più appropriata. + +Panoramica delle opzioni +------------------------ + +Le patch per il kernel vengono inviate per posta elettronica, preferibilmente +come testo integrante del messaggio. Alcuni manutentori accettano gli +allegati, ma in questo caso gli allegati devono avere il *content-type* +impostato come ``text/plain``. Tuttavia, generalmente gli allegati non sono +ben apprezzati perché rende più difficile citare porzioni di patch durante il +processo di revisione. + +Inoltre, è vivamente raccomandato l'uso di puro testo nel corpo del +messaggio, sia per la patch che per qualsiasi altro messaggio. Il sito +https://useplaintext.email/ può esservi d'aiuto per configurare il +vostro programma di posta elettronica. + +I programmi di posta elettronica che vengono usati per inviare le patch per il +kernel Linux dovrebbero inviarle senza alterazioni. Per esempio, non +dovrebbero modificare o rimuovere tabulazioni o spazi, nemmeno all'inizio o +alla fine delle righe. + +Non inviate patch con ``format=flowed``. Questo potrebbe introdurre +interruzioni di riga inaspettate e indesiderate. + +Non lasciate che il vostro programma di posta vada a capo automaticamente. +Questo può corrompere le patch. + +I programmi di posta non dovrebbero modificare la codifica dei caratteri nel +testo. Le patch inviate per posta elettronica dovrebbero essere codificate in +ASCII o UTF-8. +Se configurate il vostro programma per inviare messaggi codificati con UTF-8 +eviterete possibili problemi di codifica. + +I programmi di posta dovrebbero generare e mantenere le intestazioni +"References" o "In-Reply-To:" cosicché la discussione non venga interrotta. + +Di solito, il copia-e-incolla (o taglia-e-incolla) non funziona con le patch +perché le tabulazioni vengono convertite in spazi. Usando xclipboard, xclip +e/o xcutsel potrebbe funzionare, ma è meglio che lo verifichiate o meglio +ancora: non usate il copia-e-incolla. + +Non usate firme PGP/GPG nei messaggi che contengono delle patch. Questo +impedisce il corretto funzionamento di alcuni script per leggere o applicare +patch (questo si dovrebbe poter correggere). + +Prima di inviare le patch sulle liste di discussione Linux, può essere una +buona idea quella di inviare la patch a voi stessi, salvare il messaggio +ricevuto, e applicarlo ai sorgenti con successo. + + +Alcuni suggerimenti per i programmi di posta elettronica (MUA) +-------------------------------------------------------------- + +Qui troverete alcuni suggerimenti per configurare i vostri MUA allo scopo +di modificare ed inviare patch per il kernel Linux. Tuttavia, questi +suggerimenti non sono da considerarsi come un riassunto di una configurazione +completa. + +Legenda: + +- TUI = interfaccia utente testuale (*text-based user interface*) +- GUI = interfaccia utente grafica (*graphical user interface*) + +Alpine (TUI) +************ + +Opzioni per la configurazione: + +Nella sezione :menuselection:`Sending Preferences`: + +- :menuselection:`Do Not Send Flowed Text` deve essere ``enabled`` +- :menuselection:`Strip Whitespace Before Sending` deve essere ``disabled`` + +Quando state scrivendo un messaggio, il cursore dev'essere posizionato +dove volete che la patch inizi, poi premendo :kbd:`CTRL-R` vi verrà chiesto +di selezionare il file patch da inserire nel messaggio. + +Claws Mail (GUI) +**************** + +Funziona. Alcune persone riescono ad usarlo con successo per inviare le patch. + +Per inserire una patch usate :menuselection:`Messaggio-->Inserisci file` +(:kbd:`CTRL-I`) oppure un editor esterno. + +Se la patch che avete inserito dev'essere modificata usando la finestra di +scrittura di Claws, allora assicuratevi che l'"auto-interruzione" sia +disabilitata :menuselection:`Configurazione-->Preferenze-->Composizione-->Interruzione riga`. + +Evolution (GUI) +*************** + +Alcune persone riescono ad usarlo con successo per inviare le patch. + +Quando state scrivendo una lettera selezionate: Preformattato + da :menuselection:`Formato-->Stile del paragrafo-->Preformattato` + (:kbd:`CTRL-7`) o dalla barra degli strumenti + +Poi per inserire la patch usate: +:menuselection:`Inserisci--> File di testo...` (:kbd:`ALT-N x`) + +Potete anche eseguire ``diff -Nru old.c new.c | xclip``, selezionare +:menuselection:`Preformattato`, e poi usare il tasto centrale del mouse. + +Kmail (GUI) +*********** + +Alcune persone riescono ad usarlo con successo per inviare le patch. + +La configurazione base che disabilita la composizione di messaggi HTML è +corretta; non abilitatela. + +Quando state scrivendo un messaggio, nel menu opzioni, togliete la selezione a +"A capo automatico". L'unico svantaggio sarà che qualsiasi altra cosa scriviate +nel messaggio non verrà mandata a capo in automatico ma dovrete farlo voi. +Il modo più semplice per ovviare a questo problema è quello di scrivere il +messaggio con l'opzione abilitata e poi di salvarlo nelle bozze. Riaprendo ora +il messaggio dalle bozze le andate a capo saranno parte integrante del +messaggio, per cui togliendo l'opzione "A capo automatico" non perderete nulla. + +Alla fine del vostro messaggio, appena prima di inserire la vostra patch, +aggiungete il delimitatore di patch: tre trattini (``---``). + +Ora, dal menu :menuselection:`Messaggio`, selezionate :menuselection:`Inserisci file di testo...` +quindi scegliete la vostra patch. +Come soluzione aggiuntiva potreste personalizzare la vostra barra degli +strumenti aggiungendo un'icona per :menuselection:`Inserisci file di testo...`. + +Allargate la finestra di scrittura abbastanza da evitare andate a capo. +Questo perché in Kmail 1.13.5 (KDE 4.5.4), Kmail aggiunge andate a capo +automaticamente al momento dell'invio per tutte quelle righe che graficamente, +nella vostra finestra di composizione, si sono estete su una riga successiva. +Disabilitare l'andata a capo automatica non è sufficiente. Dunque, se la vostra +patch contiene delle righe molto lunghe, allora dovrete allargare la finestra +di composizione per evitare che quelle righe vadano a capo. Vedere: +https://bugs.kde.org/show_bug.cgi?id=174034 + +Potete firmare gli allegati con GPG, ma per le patch si preferisce aggiungerle +al testo del messaggio per cui non usate la firma GPG. Firmare le patch +inserite come testo del messaggio le rende più difficili da estrarre dalla loro +codifica a 7-bit. + +Se dovete assolutamente inviare delle patch come allegati invece di integrarle +nel testo del messaggio, allora premete il tasto destro sull'allegato e +selezionate :menuselection:`Proprietà`, e poi attivate +:menuselection:`Suggerisci visualizzazione automatica` per far si che +l'allegato sia più leggibile venendo visualizzato come parte del messaggio. + +Per salvare le patch inviate come parte di un messaggio, selezionate il +messaggio che la contiene, premete il tasto destro e selezionate +:menuselection:`Salva come`. Se il messaggio fu ben preparato, allora potrete +usarlo interamente senza alcuna modifica. +I messaggi vengono salvati con permessi di lettura-scrittura solo per l'utente, +nel caso in cui vogliate copiarli altrove per renderli disponibili ad altri +gruppi o al mondo, ricordatevi di usare ``chmod`` per cambiare i permessi. + +Lotus Notes (GUI) +***************** + +Scappate finché potete. + +IBM Verse (Web GUI) +******************* + +Vedi il commento per Lotus Notes. + +Mutt (TUI) +********** + +Un sacco di sviluppatori Linux usano ``mutt``, per cui deve funzionare +abbastanza bene. + +Mutt non ha un proprio editor, quindi qualunque sia il vostro editor dovrete +configurarlo per non aggiungere automaticamente le andate a capo. Molti +editor hanno un'opzione :menuselection:`Inserisci file` che inserisce il +contenuto di un file senza alterarlo. + +Per usare ``vim`` come editor per mutt:: + + set editor="vi" + +Se per inserire la patch nel messaggio usate xclip, scrivete il comando:: + + :set paste + +prima di premere il tasto centrale o shift-insert. Oppure usate il +comando:: + + :r filename + +(a)llega funziona bene senza ``set paste`` + +Potete generare le patch con ``git format-patch`` e usare Mutt per inviarle:: + + $ mutt -H 0001-some-bug-fix.patch + +Opzioni per la configurazione: + +Tutto dovrebbe funzionare già nella configurazione base. +Tuttavia, è una buona idea quella di impostare ``send_charset``:: + + set send_charset="us-ascii:utf-8" + +Mutt è molto personalizzabile. Qui di seguito trovate la configurazione minima +per iniziare ad usare Mutt per inviare patch usando Gmail:: + + # .muttrc + # ================ IMAP ==================== + set imap_user = 'yourusername@gmail.com' + set imap_pass = 'yourpassword' + set spoolfile = imaps://imap.gmail.com/INBOX + set folder = imaps://imap.gmail.com/ + set record="imaps://imap.gmail.com/[Gmail]/Sent Mail" + set postponed="imaps://imap.gmail.com/[Gmail]/Drafts" + set mbox="imaps://imap.gmail.com/[Gmail]/All Mail" + + # ================ SMTP ==================== + set smtp_url = "smtp://username@smtp.gmail.com:587/" + set smtp_pass = $imap_pass + set ssl_force_tls = yes # Require encrypted connection + + # ================ Composition ==================== + set editor = `echo \$EDITOR` + set edit_headers = yes # See the headers when editing + set charset = UTF-8 # value of $LANG; also fallback for send_charset + # Sender, email address, and sign-off line must match + unset use_domain # because joe@localhost is just embarrassing + set realname = "YOUR NAME" + set from = "username@gmail.com" + set use_from = yes + +La documentazione di Mutt contiene molte più informazioni: + + https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail + + http://www.mutt.org/doc/manual/ + +Pine (TUI) +********** + +Pine aveva alcuni problemi con gli spazi vuoti, ma questi dovrebbero essere +stati risolti. + +Se potete usate alpine (il successore di pine). + +Opzioni di configurazione: + +- Nelle versioni più recenti è necessario avere ``quell-flowed-text`` +- l'opzione ``no-strip-whitespace-before-send`` è necessaria + +Sylpheed (GUI) +************** + +- funziona bene per aggiungere testo in linea (o usando allegati) +- permette di utilizzare editor esterni +- è lento su cartelle grandi +- non farà l'autenticazione TSL SMTP su una connessione non SSL +- ha un utile righello nella finestra di scrittura +- la rubrica non comprende correttamente il nome da visualizzare e + l'indirizzo associato + +Thunderbird (GUI) +***************** + +Thunderbird è un clone di Outlook a cui piace maciullare il testo, ma esistono +modi per impedirglielo. + +Dopo la configurazione, inclusa l'installazione delle estenzioni, dovrete +riavviare Thunderbird. + +- permettere l'uso di editor esterni: + + La cosa più semplice da fare con Thunderbird e le patch è quello di usare + estensioni che permettano di aprire il vostro editor preferito. + + Di seguito alcune estensioni che possono essere utili al caso. + + - "External Editor Revived" + + https://github.com/Frederick888/external-editor-revived + + https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/ + + L'estensione richiede l'installazione di "native messaging host". Date + un'occhiata alla seguente wiki: + https://github.com/Frederick888/external-editor-revived/wiki + + - "External Editor" + + https://github.com/exteditor/exteditor + + Per usarlo, scaricate ed installate l'applicazione. Poi aprite la finestra + :menuselection:`Scrivi` e a seguire aggiungete un bottone per eseguirlo + `Visualizza-->Barra degli strumenti-->Personalizza...`. Infine, premente + questo nuovo bottone tutte le volte che volete usare l'editor esterno. + + Tenete presente che "external editor" richiede che il vostro editor non + faccia alcun fork, in altre parole, l'editor non deve ritornare prima di + essere stato chiuso. Potreste dover passare dei parametri aggiuntivi al + vostro editor oppure cambiargli la configurazione. Per esempio, usando + gvim dovrete aggiungere l'opzione -f ``/usr/bin/gvim -f`` (Se il binario + si trova in ``/usr/bin``) nell'apposito campo nell'interfaccia di + configurazione di :menuselection:`external editor`. Se usate altri editor + consultate il loro manuale per sapere come configurarli.``)`` + +Per rendere l'editor interno un po' più sensato, fate così: + +- Modificate le impostazioni di Thunderbird per far si che non usi ``format=flowed``! + Andate sulla finestra principale e cercate il bottone per il menu a tendina principale. + Poi :menuselection:`Modifica-->Preferenze-->Avanzate-->Editor di configurazione` + per invocare il registro delle impostazioni. + + - impostate ``mailnews.send_plaintext_flowed`` a ``false`` + + - impostate ``mailnews.wraplength`` da ``72`` a ``0`` + +- Non scrivete messaggi HTML! Andate sulla finestra principale ed aprite la + schermata :menuselection:`Menu principale-->Impostazioni account-->nome@unserver.ovunque-->Composizioni e indirizzi`. + Qui potrete disabilitare l'opzione "Componi i messaggi in HTML" + +- Aprite i messaggi solo in formato testo! Andate sulla finestra principale e + selezionate + :menuselection:`Menu principale-->Visualizza-->Copro del messaggio come-->Testo semplice` + + +TkRat (GUI) +*********** + +Funziona. Usare "Inserisci file..." o un editor esterno. + +Gmail (Web GUI) +*************** + +Non funziona per inviare le patch. + +Il programma web Gmail converte automaticamente i tab in spazi. + +Allo stesso tempo aggiunge andata a capo ogni 78 caratteri. Comunque +il problema della conversione fra spazi e tab può essere risolto usando +un editor esterno. + +Un altro problema è che Gmail usa la codifica base64 per tutti quei messaggi +che contengono caratteri non ASCII. Questo include cose tipo i nomi europei. + +Proton Mail +*********** + +Il servizio Proton Mail ha una funzionalità che cripta tutti i messaggi verso +ogni destinatario per cui è possibile trovare una chiave usando il *Web Key +Directory* (WKD). Il servizio kernel.org pubblica il WKD per ogni sviluppatore +in possesso di un conto kernel.org. Di conseguenza, tutti i messaggi inviati +usando Proton Mail verso indirizzi kernel.org verranno criptati. + +Proton Mail non fornisce alcun meccanismo per disabilitare questa funzionalità +perché verrebbe considerato un problema per la riservatezza. Questa funzionalità +è attiva anche quando si inviano messaggi usando il Proton Mail Bridge. Dunque +tutta la posta in uscita verrà criptata, incluse le patch inviate con ``git +send-email``. + +I messaggi criptati sono una fonte di problemi; altri sviluppatori potrebbero +non aver configurato i loro programmi, o strumenti, per gestire messaggi +criptati; inoltre, alcuni programmi di posta elettronica potrebbero criptare le +risposte a messaggi criptati per tutti i partecipanti alla discussione, inclusa +la lista di discussione stessa. + +A meno che non venga introdotta una maniera per disabilitare questa +funzionalità, non è consigliato usare Proton Mail per contribuire allo sviluppo +del kernel. diff --git a/Documentation/translations/it_IT/process/howto.rst b/Documentation/translations/it_IT/process/howto.rst new file mode 100644 index 0000000000..052f1b3610 --- /dev/null +++ b/Documentation/translations/it_IT/process/howto.rst @@ -0,0 +1,642 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/howto.rst <process_howto>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_process_howto: + +Come partecipare allo sviluppo del kernel Linux +=============================================== + +Questo è il documento fulcro di quanto trattato sull'argomento. +Esso contiene le istruzioni su come diventare uno sviluppatore +del kernel Linux e spiega come lavorare con la comunità di +sviluppo kernel Linux. Il documento non tratterà alcun aspetto +tecnico relativo alla programmazione del kernel, ma vi aiuterà +indirizzandovi sulla corretta strada. + +Se qualsiasi cosa presente in questo documento diventasse obsoleta, +vi preghiamo di inviare le correzioni agli amministratori di questo +file, indicati in fondo al presente documento. + +Introduzione +------------ +Dunque, volete imparare come diventare sviluppatori del kernel Linux? +O vi è stato detto dal vostro capo, "Vai, scrivi un driver Linux per +questo dispositivo". Bene, l'obbiettivo di questo documento è quello +di insegnarvi tutto ciò che dovete sapere per raggiungere il vostro +scopo descrivendo il procedimento da seguire e consigliandovi +su come lavorare con la comunità. Il documento cercherà, inoltre, +di spiegare alcune delle ragioni per le quali la comunità lavora in un +modo suo particolare. + +Il kernel è scritto prevalentemente nel linguaggio C con alcune parti +specifiche dell'architettura scritte in linguaggio assembly. +Per lo sviluppo kernel è richiesta una buona conoscenza del linguaggio C. +L'assembly (di qualsiasi architettura) non è richiesto, a meno che non +pensiate di fare dello sviluppo di basso livello per un'architettura. +Sebbene essi non siano un buon sostituto ad un solido studio del +linguaggio C o ad anni di esperienza, i seguenti libri sono, se non +altro, utili riferimenti: + +- "The C Programming Language" di Kernighan e Ritchie [Prentice Hall] +- "Practical C Programming" di Steve Oualline [O'Reilly] +- "C: A Reference Manual" di Harbison and Steele [Prentice Hall] + +Il kernel è stato scritto usando GNU C e la toolchain GNU. +Sebbene si attenga allo standard ISO C11, esso utilizza una serie di +estensioni che non sono previste in questo standard. Il kernel è un +ambiente C indipendente, che non ha alcuna dipendenza dalle librerie +C standard, così alcune parti del C standard non sono supportate. +Le divisioni ``long long`` e numeri in virgola mobile non sono permessi. +Qualche volta è difficile comprendere gli assunti che il kernel ha +riguardo gli strumenti e le estensioni in uso, e sfortunatamente non +esiste alcuna indicazione definitiva. Per maggiori informazioni, controllate, +la pagina `info gcc`. + +Tenete a mente che state cercando di apprendere come lavorare con la comunità +di sviluppo già esistente. Questo è un gruppo eterogeneo di persone, con alti +standard di codifica, di stile e di procedura. Questi standard sono stati +creati nel corso del tempo basandosi su quanto hanno riscontrato funzionare al +meglio per un squadra così grande e geograficamente sparsa. Cercate di +imparare, in anticipo, il più possibile circa questi standard, poichè ben +spiegati; non aspettatevi che gli altri si adattino al vostro modo di fare +o a quello della vostra azienda. + +Note legali +------------ +Il codice sorgente del kernel Linux è rilasciato sotto GPL. Siete pregati +di visionare il file, COPYING, presente nella cartella principale dei +sorgente, per eventuali dettagli sulla licenza. Se avete ulteriori domande +sulla licenza, contattate un avvocato, non chiedete sulle liste di discussione +del kernel Linux. Le persone presenti in queste liste non sono avvocati, +e non dovreste basarvi sulle loro dichiarazioni in materia giuridica. + +Per domande più frequenti e risposte sulla licenza GPL, guardare: + + https://www.gnu.org/licenses/gpl-faq.html + +Documentazione +-------------- +I sorgenti del kernel Linux hanno una vasta base di documenti che vi +insegneranno come interagire con la comunità del kernel. Quando nuove +funzionalità vengono aggiunte al kernel, si raccomanda di aggiungere anche i +relativi file di documentatione che spiegano come usarele. +Quando un cambiamento del kernel genera anche un cambiamento nell'interfaccia +con lo spazio utente, è raccomandabile che inviate una notifica o una +correzione alle pagine *man* spiegando tale modifica agli amministratori di +queste pagine all'indirizzo mtk.manpages@gmail.com, aggiungendo +in CC la lista linux-api@vger.kernel.org. + +Di seguito una lista di file che sono presenti nei sorgente del kernel e che +è richiesto che voi leggiate: + + :ref:`Documentation/translations/it_IT/admin-guide/README.rst <it_readme>` + Questo file da una piccola anteprima del kernel Linux e descrive il + minimo necessario per configurare e generare il kernel. I novizi + del kernel dovrebbero iniziare da qui. + + :ref:`Documentation/translations/it_IT/process/changes.rst <it_changes>` + + Questo file fornisce una lista dei pacchetti software necessari + a compilare e far funzionare il kernel con successo. + + :ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>` + + Questo file descrive lo stile della codifica per il kernel Linux, + e parte delle motivazioni che ne sono alla base. Tutto il nuovo codice deve + seguire le linee guida in questo documento. Molti amministratori + accetteranno patch solo se queste osserveranno tali regole, e molte + persone revisioneranno il codice solo se scritto nello stile appropriato. + + :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>` + + Questo file descrive dettagliatamente come creare ed inviare una patch + con successo, includendo (ma non solo questo): + + - Contenuto delle email + - Formato delle email + - I destinatari delle email + + Seguire tali regole non garantirà il successo (tutte le patch sono soggette + a controlli realitivi a contenuto e stile), ma non seguirle lo precluderà + sempre. + + Altre ottime descrizioni di come creare buone patch sono: + + "The Perfect Patch" + https://www.ozlabs.org/~akpm/stuff/tpp.txt + + "Linux kernel patch submission format" + https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html + + :ref:`Documentation/translations/it_IT/process/stable-api-nonsense.rst <it_stable_api_nonsense>` + + Questo file descrive la motivazioni sottostanti la conscia decisione di + non avere un API stabile all'interno del kernel, incluso cose come: + + - Sottosistemi shim-layers (per compatibilità?) + - Portabilità fra Sistemi Operativi dei driver. + - Attenuare i rapidi cambiamenti all'interno dei sorgenti del kernel + (o prevenirli) + + Questo documento è vitale per la comprensione della filosifia alla base + dello sviluppo di Linux ed è molto importante per le persone che arrivano + da esperienze con altri Sistemi Operativi. + + :ref:`Documentation/translations/it_IT/admin-guide/security-bugs.rst <it_securitybugs>` + Se ritenete di aver trovato un problema di sicurezza nel kernel Linux, + seguite i passaggi scritti in questo documento per notificarlo agli + sviluppatori del kernel, ed aiutare la risoluzione del problema. + + :ref:`Documentation/translations/it_IT/process/management-style.rst <it_managementstyle>` + Questo documento descrive come i manutentori del kernel Linux operano + e la filosofia comune alla base del loro metodo. Questa è un'importante + lettura per tutti coloro che sono nuovi allo sviluppo del kernel (o per + chi è semplicemente curioso), poiché risolve molti dei più comuni + fraintendimenti e confusioni dovuti al particolare comportamento dei + manutentori del kernel. + + :ref:`Documentation/translations/it_IT/process/stable-kernel-rules.rst <it_stable_kernel_rules>` + Questo file descrive le regole sulle quali vengono basati i rilasci del + kernel, e spiega cosa fare se si vuole che una modifica venga inserita + in uno di questi rilasci. + + :ref:`Documentation/translations/it_IT/process/kernel-docs.rst <it_kernel_docs>` + Una lista di documenti pertinenti allo sviluppo del kernel. + Per favore consultate questa lista se non trovate ciò che cercate nella + documentazione interna del kernel. + + :ref:`Documentation/translations/it_IT/process/applying-patches.rst <it_applying_patches>` + Una buona introduzione che descrivere esattamente cos'è una patch e come + applicarla ai differenti rami di sviluppo del kernel. + +Il kernel inoltre ha un vasto numero di documenti che possono essere +automaticamente generati dal codice sorgente stesso o da file +ReStructuredText (ReST), come questo. Esso include una completa +descrizione dell'API interna del kernel, e le regole su come gestire la +sincronizzazione (locking) correttamente + +Tutte queste tipologie di documenti possono essere generati in PDF o in +HTML utilizzando:: + + make pdfdocs + make htmldocs + +rispettivamente dalla cartella principale dei sorgenti del kernel. + +I documenti che impiegano ReST saranno generati nella cartella +Documentation/output. +Questi posso essere generati anche in formato LaTex e ePub con:: + + make latexdocs + make epubdocs + +Diventare uno sviluppatore del kernel +------------------------------------- +Se non sapete nulla sullo sviluppo del kernel Linux, dovreste dare uno +sguardo al progetto *Linux KernelNewbies*: + + https://kernelnewbies.org + +Esso prevede un'utile lista di discussione dove potete porre più o meno ogni +tipo di quesito relativo ai concetti fondamentali sullo sviluppo del kernel +(assicuratevi di cercare negli archivi, prima di chiedere qualcosa alla +quale è già stata fornita risposta in passato). Esistono inoltre, un canale IRC +che potete usare per formulare domande in tempo reale, e molti documenti utili +che vi faciliteranno nell'apprendimento dello sviluppo del kernel Linux. + +Il sito internet contiene informazioni di base circa l'organizzazione del +codice, sottosistemi e progetti attuali (sia interni che esterni a Linux). +Esso descrive, inoltre, informazioni logistiche di base, riguardanti ad esempio +la compilazione del kernel e l'applicazione di una modifica. + +Se non sapete dove cominciare, ma volete cercare delle attività dalle quali +partire per partecipare alla comunità di sviluppo, andate al progetto Linux +Kernel Janitor's. + + https://kernelnewbies.org/KernelJanitors + +È un buon posto da cui iniziare. Esso presenta una lista di problematiche +relativamente semplici da sistemare e pulire all'interno della sorgente del +kernel Linux. Lavorando con gli sviluppatori incaricati di questo progetto, +imparerete le basi per l'inserimento delle vostre modifiche all'interno dei +sorgenti del kernel Linux, e possibilmente, sarete indirizzati al lavoro +successivo da svolgere, se non ne avrete ancora idea. + +Prima di apportare una qualsiasi modifica al codice del kernel Linux, +è imperativo comprendere come tale codice funziona. A questo scopo, non c'è +nulla di meglio che leggerlo direttamente (la maggior parte dei bit più +complessi sono ben commentati), eventualmente anche con l'aiuto di strumenti +specializzati. Uno degli strumenti che è particolarmente raccomandato è +il progetto Linux Cross-Reference, che è in grado di presentare codice +sorgente in un formato autoreferenziale ed indicizzato. Un eccellente ed +aggiornata fonte di consultazione del codice del kernel la potete trovare qui: + + https://elixir.bootlin.com/ + + +Il processo di sviluppo +----------------------- +Il processo di sviluppo del kernel Linux si compone di pochi "rami" principali +e di molti altri rami per specifici sottosistemi. Questi rami sono: + + - I sorgenti kernel 4.x + - I sorgenti stabili del kernel 4.x.y -stable + - Sorgenti dei sottosistemi del kernel e le loro modifiche + - Il kernel 4.x -next per test d'integrazione + +I sorgenti kernel 4.x +~~~~~~~~~~~~~~~~~~~~~ + +I kernel 4.x sono amministrati da Linus Torvald, e possono essere trovati +su https://kernel.org nella cartella pub/linux/kernel/v4.x/. Il processo +di sviluppo è il seguente: + + - Non appena un nuovo kernel viene rilasciato si apre una finestra di due + settimane. Durante questo periodo i manutentori possono proporre a Linus + dei grossi cambiamenti; solitamente i cambiamenti che sono già stati + inseriti nel ramo -next del kernel per alcune settimane. Il modo migliore + per sottoporre dei cambiamenti è attraverso git (lo strumento usato per + gestire i sorgenti del kernel, più informazioni sul sito + https://git-scm.com/) ma anche delle patch vanno bene. + + - Al termine delle due settimane un kernel -rc1 viene rilasciato e + l'obbiettivo ora è quello di renderlo il più solido possibile. A questo + punto la maggior parte delle patch dovrebbero correggere un'eventuale + regressione. I bachi che sono sempre esistiti non sono considerabili come + regressioni, quindi inviate questo tipo di cambiamenti solo se sono + importanti. Notate che un intero driver (o filesystem) potrebbe essere + accettato dopo la -rc1 poiché non esistono rischi di una possibile + regressione con tale cambiamento, fintanto che quest'ultimo è + auto-contenuto e non influisce su aree esterne al codice che è stato + aggiunto. git può essere utilizzato per inviare le patch a Linus dopo che + la -rc1 è stata rilasciata, ma è anche necessario inviare le patch ad + una lista di discussione pubblica per un'ulteriore revisione. + + - Una nuova -rc viene rilasciata ogni volta che Linus reputa che gli attuali + sorgenti siano in uno stato di salute ragionevolmente adeguato ai test. + L'obiettivo è quello di rilasciare una nuova -rc ogni settimana. + + - Il processo continua fino a che il kernel è considerato "pronto"; tale + processo dovrebbe durare circa in 6 settimane. + +È utile menzionare quanto scritto da Andrew Morton sulla lista di discussione +kernel-linux in merito ai rilasci del kernel: + + *"Nessuno sa quando un kernel verrà rilasciato, poichè questo è + legato allo stato dei bachi e non ad una cronologia preventiva."* + +I sorgenti stabili del kernel 4.x.y -stable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I kernel con versioni in 3-parti sono "kernel stabili". Essi contengono +correzioni critiche relativamente piccole nell'ambito della sicurezza +oppure significative regressioni scoperte in un dato 4.x kernel. + +Questo è il ramo raccomandato per gli utenti che vogliono un kernel recente +e stabile e non sono interessati a dare il proprio contributo alla verifica +delle versioni di sviluppo o sperimentali. + +Se non è disponibile alcun kernel 4.x.y., quello più aggiornato e stabile +sarà il kernel 4.x con la numerazione più alta. + +4.x.y sono amministrati dal gruppo "stable" <stable@vger.kernel.org>, e sono +rilasciati a seconda delle esigenze. Il normale periodo di rilascio è +approssimativamente di due settimane, ma può essere più lungo se non si +verificano problematiche urgenti. Un problema relativo alla sicurezza, invece, +può determinare un rilascio immediato. + +Il file Documentation/process/stable-kernel-rules.rst (nei sorgenti) documenta +quali tipologie di modifiche sono accettate per i sorgenti -stable, e come +avviene il processo di rilascio. + + +Sorgenti dei sottosistemi del kernel e le loro patch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I manutentori dei diversi sottosistemi del kernel --- ed anche molti +sviluppatori di sottosistemi --- mostrano il loro attuale stato di sviluppo +nei loro repositori. In questo modo, altri possono vedere cosa succede nelle +diverse parti del kernel. In aree dove lo sviluppo è rapido, potrebbe essere +chiesto ad uno sviluppatore di basare le proprie modifiche su questi repositori +in modo da evitare i conflitti fra le sottomissioni ed altri lavori in corso + +La maggior parte di questi repositori sono git, ma esistono anche altri SCM +in uso, o file di patch pubblicate come una serie quilt. +Gli indirizzi dei repositori di sottosistema sono indicati nel file +MAINTAINERS. Molti di questi posso essere trovati su https://git.kernel.org/. + +Prima che una modifica venga inclusa in questi sottosistemi, sarà soggetta ad +una revisione che inizialmente avviene tramite liste di discussione (vedere la +sezione dedicata qui sotto). Per molti sottosistemi del kernel, tale processo +di revisione è monitorato con lo strumento patchwork. +Patchwork offre un'interfaccia web che mostra le patch pubblicate, inclusi i +commenti o le revisioni fatte, e gli amministratori possono indicare le patch +come "in revisione", "accettate", o "rifiutate". Diversi siti Patchwork sono +elencati al sito https://patchwork.kernel.org/. + +Il kernel 4.x -next per test d'integrazione +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Prima che gli aggiornamenti dei sottosistemi siano accorpati nel ramo +principale 4.x, sarà necessario un test d'integrazione. +A tale scopo, esiste un repositorio speciale di test nel quale virtualmente +tutti i rami dei sottosistemi vengono inclusi su base quotidiana: + + https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git + +In questo modo, i kernel -next offrono uno sguardo riassuntivo su quello che +ci si aspetterà essere nel kernel principale nel successivo periodo +d'incorporazione. +Coloro che vorranno fare dei test d'esecuzione del kernel -next sono più che +benvenuti. + + +Riportare Bug +------------- + +Il file 'Documentation/admin-guide/reporting-issues.rst' nella +cartella principale del kernel spiega come segnalare un baco nel +kernel, e fornisce dettagli su quali informazioni sono necessarie agli +sviluppatori del kernel per poter studiare il problema. + +Gestire i rapporti sui bug +-------------------------- + +Uno dei modi migliori per mettere in pratica le vostre capacità di hacking è +quello di riparare bachi riportati da altre persone. Non solo aiuterete a far +diventare il kernel più stabile, ma imparerete a riparare problemi veri dal +mondo ed accrescerete le vostre competenze, e gli altri sviluppatori saranno +al corrente della vostra presenza. Riparare bachi è una delle migliori vie per +acquisire meriti tra gli altri sviluppatori, perchè non a molte persone piace +perdere tempo a sistemare i bachi di altri. + +Per lavorare sui bachi già segnalati, per prima cosa cercate il +sottosistema che vi interessa. Poi, verificate nel file MAINTAINERS +dove vengono collezionati solitamente i bachi per quel sottosistema; +spesso sarà una lista di discussione, raramente un bugtracker. Cercate +bachi nell'archivio e aiutate dove credete di poterlo fare. Potete +anche consultare https://bugzilla.kernel.org; però, solo una manciata di +sottosistemi lo usano attivamente, ciò nonostante i bachi che +coinvolgono l'intero kernel sono sempre riportati lì. + +Liste di discussione +-------------------- + +Come descritto in molti dei documenti qui sopra, la maggior parte degli +sviluppatori del kernel partecipano alla lista di discussione Linux Kernel. +I dettagli su come iscriversi e disiscriversi dalla lista possono essere +trovati al sito: + + http://vger.kernel.org/vger-lists.html#linux-kernel + +Ci sono diversi archivi della lista di discussione. Usate un qualsiasi motore +di ricerca per trovarli. Per esempio: + + https://lore.kernel.org/lkml/ + +É caldamente consigliata una ricerca in questi archivi sul tema che volete +sollevare, prima di pubblicarlo sulla lista. Molte cose sono già state +discusse in dettaglio e registrate negli archivi della lista di discussione. + +Molti dei sottosistemi del kernel hanno anche una loro lista di discussione +dedicata. Guardate nel file MAINTAINERS per avere una lista delle liste di +discussione e il loro uso. + +Molte di queste liste sono gestite su kernel.org. Per informazioni consultate +la seguente pagina: + + http://vger.kernel.org/vger-lists.html + +Per favore ricordatevi della buona educazione quando utilizzate queste liste. +Sebbene sia un pò dozzinale, il seguente URL contiene alcune semplici linee +guida per interagire con la lista (o con qualsiasi altra lista): + + http://www.albion.com/netiquette/ + +Se diverse persone rispondo alla vostra mail, la lista dei riceventi (copia +conoscenza) potrebbe diventare abbastanza lunga. Non cancellate nessuno dalla +lista di CC: senza un buon motivo, e non rispondete solo all'indirizzo +della lista di discussione. Fateci l'abitudine perché capita spesso di +ricevere la stessa email due volte: una dal mittente ed una dalla lista; e non +cercate di modificarla aggiungendo intestazioni stravaganti, agli altri non +piacerà. + +Ricordate di rimanere sempre in argomento e di mantenere le attribuzioni +delle vostre risposte invariate; mantenete il "John Kernelhacker wrote ...:" +in cima alla vostra replica e aggiungete le vostre risposte fra i singoli +blocchi citati, non scrivete all'inizio dell'email. + +Se aggiungete patch alla vostra mail, assicuratevi che siano del tutto +leggibili come indicato in Documentation/process/submitting-patches.rst. +Gli sviluppatori kernel non vogliono avere a che fare con allegati o patch +compresse; vogliono invece poter commentare le righe dei vostri cambiamenti, +il che può funzionare solo in questo modo. +Assicuratevi di utilizzare un gestore di mail che non alterì gli spazi ed i +caratteri. Un ottimo primo test è quello di inviare a voi stessi una mail e +cercare di sottoporre la vostra stessa patch. Se non funziona, sistemate il +vostro programma di posta, o cambiatelo, finché non funziona. + +Ed infine, per favore ricordatevi di mostrare rispetto per gli altri +sottoscriventi. + +Lavorare con la comunità +------------------------ + +L'obiettivo di questa comunità è quello di fornire il miglior kernel possibile. +Quando inviate una modifica che volete integrare, sarà valutata esclusivamente +dal punto di vista tecnico. Quindi, cosa dovreste aspettarvi? + + - critiche + - commenti + - richieste di cambiamento + - richieste di spiegazioni + - nulla + +Ricordatevi che questo fa parte dell'integrazione della vostra modifica +all'interno del kernel. Dovete essere in grado di accettare le critiche, +valutarle a livello tecnico ed eventualmente rielaborare nuovamente le vostre +modifiche o fornire delle chiare e concise motivazioni per le quali le +modifiche suggerite non dovrebbero essere fatte. +Se non riceverete risposte, aspettate qualche giorno e riprovate ancora, +qualche volta le cose si perdono nell'enorme mucchio di email. + +Cosa non dovreste fare? + + - aspettarvi che la vostra modifica venga accettata senza problemi + - mettervi sulla difensiva + - ignorare i commenti + - sottomettere nuovamente la modifica senza fare nessuno dei cambiamenti + richiesti + +In una comunità che è alla ricerca delle migliori soluzioni tecniche possibili, +ci saranno sempre opinioni differenti sull'utilità di una modifica. +Siate cooperativi e vogliate adattare la vostra idea in modo che sia inserita +nel kernel. O almeno vogliate dimostrare che la vostra idea vale. +Ricordatevi, sbagliare è accettato fintanto che siate disposti a lavorare verso +una soluzione che è corretta. + +È normale che le risposte alla vostra prima modifica possa essere +semplicemente una lista con dozzine di cose che dovreste correggere. +Questo **non** implica che la vostra patch non sarà accettata, e questo +**non** è contro di voi personalmente. +Semplicemente correggete tutte le questioni sollevate contro la vostra modifica +ed inviatela nuovamente. + +Differenze tra la comunità del kernel e le strutture aziendali +-------------------------------------------------------------- + +La comunità del kernel funziona diversamente rispetto a molti ambienti di +sviluppo aziendali. Qui di seguito una lista di cose che potete provare a +fare per evitare problemi: + + Cose da dire riguardanti le modifiche da voi proposte: + + - "Questo risolve più problematiche." + - "Questo elimina 2000 stringhe di codice." + - "Qui una modifica che spiega cosa sto cercando di fare." + - "L'ho testato su 5 diverse architetture.." + - "Qui una serie di piccole modifiche che.." + - "Questo aumenta le prestazioni di macchine standard..." + + Cose che dovreste evitare di dire: + + - "Lo abbiamo fatto in questo modo in AIX/ptx/Solaris, di conseguenza + deve per forza essere giusto..." + - "Ho fatto questo per 20 anni, quindi.." + - "Questo è richiesto dalla mia Azienda per far soldi" + - "Questo è per la linea di prodotti della nostra Azienda" + - "Ecco il mio documento di design di 1000 pagine che descrive ciò che ho + in mente" + - "Ci ho lavorato per 6 mesi..." + - "Ecco una patch da 5000 righe che.." + - "Ho riscritto il pasticcio attuale, ed ecco qua.." + - "Ho una scadenza, e questa modifica ha bisogno di essere approvata ora" + +Un'altra cosa nella quale la comunità del kernel si differenzia dai più +classici ambienti di ingegneria del software è la natura "senza volto" delle +interazioni umane. Uno dei benefici dell'uso delle email e di irc come forma +primordiale di comunicazione è l'assenza di discriminazione basata su genere e +razza. L'ambienti di lavoro Linux accetta donne e minoranze perchè tutto quello +che sei è un indirizzo email. Aiuta anche l'aspetto internazionale nel +livellare il terreno di gioco perchè non è possibile indovinare il genere +basandosi sul nome di una persona. Un uomo può chiamarsi Andrea ed una donna +potrebbe chiamarsi Pat. Gran parte delle donne che hanno lavorato al kernel +Linux e che hanno espresso una personale opinione hanno avuto esperienze +positive. + +La lingua potrebbe essere un ostacolo per quelle persone che non si trovano +a loro agio con l'inglese. Una buona padronanza del linguaggio può essere +necessaria per esporre le proprie idee in maniera appropiata all'interno +delle liste di discussione, quindi è consigliabile che rileggiate le vostre +email prima di inviarle in modo da essere certi che abbiano senso in inglese. + + +Spezzare le vostre modifiche +---------------------------- + +La comunità del kernel Linux non accetta con piacere grossi pezzi di codice +buttati lì tutti in una volta. Le modifiche necessitano di essere +adeguatamente presentate, discusse, e suddivise in parti più piccole ed +indipendenti. Questo è praticamente l'esatto opposto di quello che le +aziende fanno solitamente. La vostra proposta dovrebbe, inoltre, essere +presentata prestissimo nel processo di sviluppo, così che possiate ricevere +un riscontro su quello che state facendo. Lasciate che la comunità +senta che state lavorando con loro, e che non li stiate sfruttando come +discarica per le vostre aggiunte. In ogni caso, non inviate 50 email nello +stesso momento in una lista di discussione, il più delle volte la vostra serie +di modifiche dovrebbe essere più piccola. + +I motivi per i quali dovreste frammentare le cose sono i seguenti: + +1) Piccole modifiche aumentano le probabilità che vengano accettate, + altrimenti richiederebbe troppo tempo o sforzo nel verificarne + la correttezza. Una modifica di 5 righe può essere accettata da un + manutentore con a mala pena una seconda occhiata. Invece, una modifica da + 500 linee può richiedere ore di rilettura per verificarne la correttezza + (il tempo necessario è esponenzialmente proporzionale alla dimensione della + modifica, o giù di lì) + + Piccole modifiche sono inoltre molto facili da debuggare quando qualcosa + non va. È molto più facile annullare le modifiche una per una che + dissezionare una patch molto grande dopo la sua sottomissione (e rompere + qualcosa). + +2) È importante non solo inviare piccole modifiche, ma anche riscriverle e + semplificarle (o più semplicemente ordinarle) prima di sottoporle. + +Qui un'analogia dello sviluppatore kernel Al Viro: + + *"Pensate ad un insegnante di matematica che corregge il compito + di uno studente (di matematica). L'insegnante non vuole vedere le + prove e gli errori commessi dallo studente prima che arrivi alla + soluzione. Vuole vedere la risposta più pulita ed elegante + possibile. Un buono studente lo sa, e non presenterebbe mai le + proprie bozze prima prima della soluzione finale"* + + *"Lo stesso vale per lo sviluppo del kernel. I manutentori ed i + revisori non vogliono vedere il procedimento che sta dietro al + problema che uno sta risolvendo. Vogliono vedere una soluzione + semplice ed elegante."* + +Può essere una vera sfida il saper mantenere l'equilibrio fra una presentazione +elegante della vostra soluzione, lavorare insieme ad una comunità e dibattere +su un lavoro incompleto. Pertanto è bene entrare presto nel processo di +revisione per migliorare il vostro lavoro, ma anche per riuscire a tenere le +vostre modifiche in pezzettini che potrebbero essere già accettate, nonostante +la vostra intera attività non lo sia ancora. + +In fine, rendetevi conto che non è accettabile inviare delle modifiche +incomplete con la promessa che saranno "sistemate dopo". + + +Giustificare le vostre modifiche +-------------------------------- + +Insieme alla frammentazione delle vostre modifiche, è altrettanto importante +permettere alla comunità Linux di capire perché dovrebbero accettarle. +Nuove funzionalità devono essere motivate come necessarie ed utili. + + +Documentare le vostre modifiche +------------------------------- + +Quando inviate le vostre modifiche, fate particolare attenzione a quello che +scrivete nella vostra email. Questa diventerà il *ChangeLog* per la modifica, +e sarà visibile a tutti per sempre. Dovrebbe descrivere la modifica nella sua +interezza, contenendo: + + - perchè la modifica è necessaria + - l'approccio d'insieme alla patch + - dettagli supplementari + - risultati dei test + +Per maggiori dettagli su come tutto ciò dovrebbe apparire, riferitevi alla +sezione ChangeLog del documento: + + "The Perfect Patch" + http://www.ozlabs.org/~akpm/stuff/tpp.txt + +A volte tutto questo è difficile da realizzare. Il perfezionamento di queste +pratiche può richiedere anni (eventualmente). È un processo continuo di +miglioramento che richiede molta pazienza e determinazione. Ma non mollate, +si può fare. Molti lo hanno fatto prima, ed ognuno ha dovuto iniziare dove +siete voi ora. + + + + +---------- + +Grazie a Paolo Ciarrocchi che ha permesso che la sezione "Development Process" +(https://lwn.net/Articles/94386/) fosse basata sui testi da lui scritti, ed a +Randy Dunlap e Gerrit Huizenga per la lista di cose che dovreste e non +dovreste dire. Grazie anche a Pat Mochel, Hanna Linder, Randy Dunlap, +Kay Sievers, Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, +Andi Kleen, Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop, +David A. Wheeler, Junio Hamano, Michael Kerrisk, e Alex Shepard per le +loro revisioni, commenti e contributi. Senza il loro aiuto, questo documento +non sarebbe stato possibile. + +Manutentore: Greg Kroah-Hartman <greg@kroah.com> diff --git a/Documentation/translations/it_IT/process/index.rst b/Documentation/translations/it_IT/process/index.rst new file mode 100644 index 0000000000..cd7977905f --- /dev/null +++ b/Documentation/translations/it_IT/process/index.rst @@ -0,0 +1,71 @@ +.. raw:: latex + + \renewcommand\thesection* + \renewcommand\thesubsection* + +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/index.rst <process_index>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_process_index: + +=============================================== +Lavorare con la comunità di sviluppo del kernel +=============================================== + +Quindi volete diventare sviluppatori del kernel? Benvenuti! C'è molto da +imparare sul lato tecnico del kernel, ma è anche importante capire come +funziona la nostra comunità. Leggere questi documenti renderà più facile +l'accettazione delle vostre modifiche con il minimo sforzo. + +Di seguito le guide che ogni sviluppatore dovrebbe leggere. + +.. toctree:: + :maxdepth: 1 + + howto + code-of-conduct + development-process + submitting-patches + programming-language + coding-style + maintainer-pgp-guide + email-clients + kernel-enforcement-statement + kernel-driver-statement + +Poi ci sono altre guide sulla comunità che sono di interesse per molti +degli sviluppatori: + +.. toctree:: + :maxdepth: 1 + + changes + stable-api-nonsense + management-style + stable-kernel-rules + submit-checklist + kernel-docs + maintainers + +Ed infine, qui ci sono alcune guide più tecniche che son state messe qua solo +perché non si è trovato un posto migliore. + +.. toctree:: + :maxdepth: 1 + + applying-patches + adding-syscalls + magic-number + volatile-considered-harmful + botching-up-ioctls + clang-format + ../riscv/patch-acceptance + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` diff --git a/Documentation/translations/it_IT/process/kernel-docs.rst b/Documentation/translations/it_IT/process/kernel-docs.rst new file mode 100644 index 0000000000..eadcbf50a1 --- /dev/null +++ b/Documentation/translations/it_IT/process/kernel-docs.rst @@ -0,0 +1,18 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/kernel-docs.rst <kernel_docs>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + + +.. _it_kernel_docs: + +Ulteriore Documentazione Del Kernel Linux +========================================= + +.. note:: + Questo documento contiene riferimenti a documenti in lingua inglese; inoltre + utilizza dai campi *ReStructuredText* di supporto alla ricerca e che per + questo motivo è meglio non tradurre al fine di garantirne un corretto + utilizzo. + Per questi motivi il documento non verrà tradotto. Per favore fate + riferimento al documento originale in lingua inglese. diff --git a/Documentation/translations/it_IT/process/kernel-driver-statement.rst b/Documentation/translations/it_IT/process/kernel-driver-statement.rst new file mode 100644 index 0000000000..f016a75a9d --- /dev/null +++ b/Documentation/translations/it_IT/process/kernel-driver-statement.rst @@ -0,0 +1,211 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/kernel-driver-statement.rst <process_statement_driver>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_process_statement_driver: + +Dichiarazioni sui driver per il kernel +====================================== + +Presa di posizione sui moduli per il kernel Linux +------------------------------------------------- + +Noi, i sottoscritti sviluppatori del kernel, consideriamo pericoloso +o indesiderato qualsiasi modulo o driver per il kernel Linux di tipo +*a sorgenti chiusi* (*closed-source*). Ripetutamente, li abbiamo +trovati deleteri per gli utenti Linux, le aziende, ed in generale +l'ecosistema Linux. Questi moduli impediscono l'apertura, la stabilità, +la flessibilità, e la manutenibilità del modello di sviluppo di Linux +e impediscono ai loro utenti di beneficiare dell'esperienza dalla +comunità Linux. I fornitori che distribuiscono codice a sorgenti chiusi +obbligano i propri utenti a rinunciare ai principali vantaggi di Linux +o a cercarsi nuovi fornitori. +Perciò, al fine di sfruttare i vantaggi che codice aperto ha da offrire, +come l'abbattimento dei costi e un supporto condiviso, spingiamo i +fornitori ad adottare una politica di supporto ai loro clienti Linux +che preveda il rilascio dei sorgenti per il kernel. + +Parliamo solo per noi stessi, e non per una qualsiasi azienda per la +quale lavoriamo oggi, o abbiamo lavorato in passato, o lavoreremo in +futuro. + + + - Dave Airlie + - Nick Andrew + - Jens Axboe + - Ralf Baechle + - Felipe Balbi + - Ohad Ben-Cohen + - Muli Ben-Yehuda + - Jiri Benc + - Arnd Bergmann + - Thomas Bogendoerfer + - Vitaly Bordug + - James Bottomley + - Josh Boyer + - Neil Brown + - Mark Brown + - David Brownell + - Michael Buesch + - Franck Bui-Huu + - Adrian Bunk + - François Cami + - Ralph Campbell + - Luiz Fernando N. Capitulino + - Mauro Carvalho Chehab + - Denis Cheng + - Jonathan Corbet + - Glauber Costa + - Alan Cox + - Magnus Damm + - Ahmed S. Darwish + - Robert P. J. Day + - Hans de Goede + - Arnaldo Carvalho de Melo + - Helge Deller + - Jean Delvare + - Mathieu Desnoyers + - Sven-Thorsten Dietrich + - Alexey Dobriyan + - Daniel Drake + - Alex Dubov + - Randy Dunlap + - Michael Ellerman + - Pekka Enberg + - Jan Engelhardt + - Mark Fasheh + - J. Bruce Fields + - Larry Finger + - Jeremy Fitzhardinge + - Mike Frysinger + - Kumar Gala + - Robin Getz + - Liam Girdwood + - Jan-Benedict Glaw + - Thomas Gleixner + - Brice Goglin + - Cyrill Gorcunov + - Andy Gospodarek + - Thomas Graf + - Krzysztof Halasa + - Harvey Harrison + - Stephen Hemminger + - Michael Hennerich + - Tejun Heo + - Benjamin Herrenschmidt + - Kristian Høgsberg + - Henrique de Moraes Holschuh + - Marcel Holtmann + - Mike Isely + - Takashi Iwai + - Olof Johansson + - Dave Jones + - Jesper Juhl + - Matthias Kaehlcke + - Kenji Kaneshige + - Jan Kara + - Jeremy Kerr + - Russell King + - Olaf Kirch + - Roel Kluin + - Hans-Jürgen Koch + - Auke Kok + - Peter Korsgaard + - Jiri Kosina + - Aaro Koskinen + - Mariusz Kozlowski + - Greg Kroah-Hartman + - Michael Krufky + - Aneesh Kumar + - Clemens Ladisch + - Christoph Lameter + - Gunnar Larisch + - Anders Larsen + - Grant Likely + - John W. Linville + - Yinghai Lu + - Tony Luck + - Pavel Machek + - Matt Mackall + - Paul Mackerras + - Roland McGrath + - Patrick McHardy + - Kyle McMartin + - Paul Menage + - Thierry Merle + - Eric Miao + - Akinobu Mita + - Ingo Molnar + - James Morris + - Andrew Morton + - Paul Mundt + - Oleg Nesterov + - Luca Olivetti + - S.Çağlar Onur + - Pierre Ossman + - Keith Owens + - Venkatesh Pallipadi + - Nick Piggin + - Nicolas Pitre + - Evgeniy Polyakov + - Richard Purdie + - Mike Rapoport + - Sam Ravnborg + - Gerrit Renker + - Stefan Richter + - David Rientjes + - Luis R. Rodriguez + - Stefan Roese + - Francois Romieu + - Rami Rosen + - Stephen Rothwell + - Maciej W. Rozycki + - Mark Salyzyn + - Yoshinori Sato + - Deepak Saxena + - Holger Schurig + - Amit Shah + - Yoshihiro Shimoda + - Sergei Shtylyov + - Kay Sievers + - Sebastian Siewior + - Rik Snel + - Jes Sorensen + - Alexey Starikovskiy + - Alan Stern + - Timur Tabi + - Hirokazu Takata + - Eliezer Tamir + - Eugene Teo + - Doug Thompson + - FUJITA Tomonori + - Dmitry Torokhov + - Marcelo Tosatti + - Steven Toth + - Theodore Tso + - Matthias Urlichs + - Geert Uytterhoeven + - Arjan van de Ven + - Ivo van Doorn + - Rik van Riel + - Wim Van Sebroeck + - Hans Verkuil + - Horst H. von Brand + - Dmitri Vorobiev + - Anton Vorontsov + - Daniel Walker + - Johannes Weiner + - Harald Welte + - Matthew Wilcox + - Dan J. Williams + - Darrick J. Wong + - David Woodhouse + - Chris Wright + - Bryan Wu + - Rafael J. Wysocki + - Herbert Xu + - Vlad Yasevich + - Peter Zijlstra + - Bartlomiej Zolnierkiewicz + diff --git a/Documentation/translations/it_IT/process/kernel-enforcement-statement.rst b/Documentation/translations/it_IT/process/kernel-enforcement-statement.rst new file mode 100644 index 0000000000..1f62da622e --- /dev/null +++ b/Documentation/translations/it_IT/process/kernel-enforcement-statement.rst @@ -0,0 +1,175 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/kernel-enforcement-statement.rst <process_statement_kernel>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_process_statement_kernel: + +Applicazione della licenza sul kernel Linux +=========================================== + +Come sviluppatori del kernel Linux, abbiamo un certo interessa su come il +nostro software viene usato e su come la sua licenza viene fatta rispettare. +Il rispetto reciproco degli obblighi di condivisione della GPL-2.0 è +fondamentale per la sostenibilità di lungo periodo del nostro software e +della nostra comunità. + +Benché ognuno abbia il diritto a far rispettare il diritto d'autore per i +propri contributi alla nostra comunità, condividiamo l'interesse a far si che +ogni azione individuale nel far rispettare i propri diritti sia condotta in +modo da portare beneficio alla comunità e che non abbia, involontariamente, +impatti negativi sulla salute e la crescita del nostro ecosistema software. +Al fine di scoraggiare l'esecuzione di azioni inutili, concordiamo che è nel +migliore interesse della nostra comunità di sviluppo di impegnarci nel +rispettare i seguenti obblighi nei confronti degli utenti del kernel Linux +per conto nostro e di qualsiasi successore ai nostri interessi sul diritto +d'autore: + + Malgrado le clausole di risoluzione della licenza GPL-2.0, abbiamo + concordato che è nel migliore interesse della nostra comunità di sviluppo + adottare le seguenti disposizioni della GPL-3.0 come permessi aggiuntivi + alla nostra licenza nei confronti di qualsiasi affermazione non difensiva + di diritti sulla licenza. + + In ogni caso, se cessano tutte le violazioni di questa Licenza, allora + la tua licenza da parte di un dato detentore del copyright viene + ripristinata (a) in via cautelativa, a meno che e fino a quando il + detentore del copyright non cessa esplicitamente e definitivamente + la tua licenza, e (b) in via permanente se il detentore del copyright + non ti notifica in alcun modo la violazione entro 60 giorni dalla + cessazione della licenza. + + Inoltre, la tua licenza da parte di un dato detentore del copyright + viene ripristinata in maniera permanente se il detentore del copyright + ti notifica la violazione in maniera adeguata, se questa è la prima + volta che ricevi una notifica di violazione di questa Licenza (per + qualunque Programma) dallo stesso detentore di copyright, e se rimedi + alla violazione entro 30 giorni dalla data di ricezione della notifica + di violazione. + +Fornendo queste garanzie, abbiamo l'intenzione di incoraggiare l'uso del +software. Vogliamo che le aziende e le persone usino, modifichino e +distribuiscano a questo software. Vogliamo lavorare con gli utenti in modo +aperto e trasparente per eliminare ogni incertezza circa le nostre aspettative +sul rispetto o l'ottemperanza alla licenza che possa limitare l'uso del nostro +software. Vediamo l'azione legale come ultima spiaggia, da avviare solo quando +gli altri sforzi della comunità hanno fallito nel risolvere il problema. + +Per finire, una volta che un problema di non rispetto della licenza viene +risolto, speriamo che gli utenti si sentano i benvenuti ad aggregarsi a noi +nello sviluppo di questo progetto. Lavorando assieme, saremo più forti. + +Ad eccezione deve specificato, parliamo per noi stessi, e non per una qualsiasi +azienda per la quale lavoriamo oggi, o per cui abbiamo lavorato in passato, o +lavoreremo in futuro. + + + - Laura Abbott + - Bjorn Andersson (Linaro) + - Andrea Arcangeli + - Neil Armstrong + - Jens Axboe + - Pablo Neira Ayuso + - Khalid Aziz + - Ralf Baechle + - Felipe Balbi + - Arnd Bergmann + - Ard Biesheuvel + - Tim Bird + - Paolo Bonzini + - Christian Borntraeger + - Mark Brown (Linaro) + - Paul Burton + - Javier Martinez Canillas + - Rob Clark + - Kees Cook (Google) + - Jonathan Corbet + - Dennis Dalessandro + - Vivien Didelot (Savoir-faire Linux) + - Hans de Goede + - Mel Gorman (SUSE) + - Sven Eckelmann + - Alex Elder (Linaro) + - Fabio Estevam + - Larry Finger + - Bhumika Goyal + - Andy Gross + - Juergen Gross + - Shawn Guo + - Ulf Hansson + - Stephen Hemminger (Microsoft) + - Tejun Heo + - Rob Herring + - Masami Hiramatsu + - Michal Hocko + - Simon Horman + - Johan Hovold (Hovold Consulting AB) + - Christophe JAILLET + - Olof Johansson + - Lee Jones (Linaro) + - Heiner Kallweit + - Srinivas Kandagatla + - Jan Kara + - Shuah Khan (Samsung) + - David Kershner + - Jaegeuk Kim + - Namhyung Kim + - Colin Ian King + - Jeff Kirsher + - Greg Kroah-Hartman (Linux Foundation) + - Christian König + - Vinod Koul + - Krzysztof Kozlowski + - Viresh Kumar + - Aneesh Kumar K.V + - Julia Lawall + - Doug Ledford + - Chuck Lever (Oracle) + - Daniel Lezcano + - Shaohua Li + - Xin Long + - Tony Luck + - Catalin Marinas (Arm Ltd) + - Mike Marshall + - Chris Mason + - Paul E. McKenney + - Arnaldo Carvalho de Melo + - David S. Miller + - Ingo Molnar + - Kuninori Morimoto + - Trond Myklebust + - Martin K. Petersen (Oracle) + - Borislav Petkov + - Jiri Pirko + - Josh Poimboeuf + - Sebastian Reichel (Collabora) + - Guenter Roeck + - Joerg Roedel + - Leon Romanovsky + - Steven Rostedt (VMware) + - Frank Rowand + - Ivan Safonov + - Anna Schumaker + - Jes Sorensen + - K.Y. Srinivasan + - David Sterba (SUSE) + - Heiko Stuebner + - Jiri Kosina (SUSE) + - Willy Tarreau + - Dmitry Torokhov + - Linus Torvalds + - Thierry Reding + - Rik van Riel + - Luis R. Rodriguez + - Geert Uytterhoeven (Glider bvba) + - Eduardo Valentin (Amazon.com) + - Daniel Vetter + - Linus Walleij + - Richard Weinberger + - Dan Williams + - Rafael J. Wysocki + - Arvind Yadav + - Masahiro Yamada + - Wei Yongjun + - Lv Zheng + - Marc Zyngier (Arm Ltd) diff --git a/Documentation/translations/it_IT/process/license-rules.rst b/Documentation/translations/it_IT/process/license-rules.rst new file mode 100644 index 0000000000..4cd87a3a7b --- /dev/null +++ b/Documentation/translations/it_IT/process/license-rules.rst @@ -0,0 +1,500 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/license-rules.rst <kernel_licensing>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_kernel_licensing: + +Regole per licenziare il kernel Linux +===================================== + +Il kernel Linux viene rilasciato sotto i termini definiti dalla seconda +versione della licenza *GNU General Public License* (GPL-2.0), di cui una +copia è disponibile nel file LICENSES/preferred/GPL-2.0; a questo si +aggiunge eccezione per le chiamate di sistema come descritto in +LICENSES/exceptions/Linux-syscall-note; tutto ciò è descritto nel file COPYING. + +Questo documento fornisce una descrizione su come ogni singolo file sorgente +debba essere licenziato per far si che sia chiaro e non ambiguo. Questo non +sostituisce la licenza del kernel. + +La licenza descritta nel file COPYING si applica ai sorgenti del kernel nella +loro interezza, quindi i singoli file sorgenti possono avere diverse licenze ma +devono essere compatibili con la GPL-2.0:: + + GPL-1.0+ : GNU General Public License v1.0 o successiva + GPL-2.0+ : GNU General Public License v2.0 o successiva + LGPL-2.0 : GNU Library General Public License v2 + LGPL-2.0+ : GNU Library General Public License v2 o successiva + LGPL-2.1 : GNU Lesser General Public License v2.1 + LGPL-2.1+ : GNU Lesser General Public License v2.1 o successiva + +A parte questo, i singolo file possono essere forniti con una doppia licenza, +per esempio con una delle varianti compatibili della GPL e alternativamente con +una licenza permissiva come BSD, MIT eccetera. + +I file d'intestazione per l'API verso lo spazio utente (UAPI) descrivono +le interfacce usate dai programmi, e per questo sono un caso speciale. +Secondo le note nel file COPYING, le chiamate di sistema sono un chiaro +confine oltre il quale non si estendono i requisiti della GPL per quei +programmi che le usano per comunicare con il kernel. Dato che i file +d'intestazione UAPI devono poter essere inclusi nei sorgenti di un +qualsiasi programma eseguibile sul kernel Linux, questi meritano +un'eccezione documentata da una clausola speciale. + +Il modo più comune per indicare la licenza dei file sorgenti è quello di +aggiungere il corrispondente blocco di testo come commento in testa a detto +file. Per via della formattazione, dei refusi, eccetera, questi blocchi di +testo sono difficili da identificare dagli strumenti usati per verificare il +rispetto delle licenze. + +Un'alternativa ai blocchi di testo è data dall'uso degli identificatori +*Software Package Data Exchange* (SPDX) in ogni file sorgente. Gli +identificatori di licenza SPDX sono analizzabili dalle macchine e sono precisi +simboli stenografici che identificano la licenza sotto la quale viene +licenziato il file che lo include. Gli identificatori di licenza SPDX sono +gestiti del gruppo di lavoro SPDX presso la Linux Foundation e sono stati +concordati fra i soci nell'industria, gli sviluppatori di strumenti, e i +rispettivi gruppi legali. Per maggiori informazioni, consultate +https://spdx.org/ + +Il kernel Linux richiede un preciso identificatore SPDX in tutti i file +sorgenti. Gli identificatori validi verranno spiegati nella sezione +`Identificatori di licenza`_ e sono stati copiati dalla lista ufficiale di +licenze SPDX assieme al rispettivo testo come mostrato in +https://spdx.org/licenses/. + +Sintassi degli identificatori di licenza +---------------------------------------- + +1. Posizionamento: + + L'identificativo di licenza SPDX dev'essere posizionato come prima riga + possibile di un file che possa contenere commenti. Per la maggior parte + dei file questa è la prima riga, fanno eccezione gli script che richiedono + come prima riga '#!PATH_TO_INTERPRETER'. Per questi script l'identificativo + SPDX finisce nella seconda riga. + +| + +2. Stile: + + L'identificativo di licenza SPDX viene aggiunto sotto forma di commento. + Lo stile del commento dipende dal tipo di file:: + + sorgenti C: // SPDX-License-Identifier: <SPDX License Expression> + intestazioni C: /* SPDX-License-Identifier: <SPDX License Expression> */ + ASM: /* SPDX-License-Identifier: <SPDX License Expression> */ + scripts: # SPDX-License-Identifier: <SPDX License Expression> + .rst: .. SPDX-License-Identifier: <SPDX License Expression> + .dts{i}: // SPDX-License-Identifier: <SPDX License Expression> + + Se un particolare programma non dovesse riuscire a gestire lo stile + principale per i commenti, allora dev'essere usato il meccanismo accettato + dal programma. Questo è il motivo per cui si ha "/\* \*/" nei file + d'intestazione C. Notammo che 'ld' falliva nell'analizzare i commenti del + C++ nei file .lds che venivano prodotti. Oggi questo è stato corretto, + ma ci sono in giro ancora vecchi programmi che non sono in grado di + gestire lo stile dei commenti del C++. + +| + +3. Sintassi: + + Una <espressione di licenza SPDX> può essere scritta usando l'identificatore + SPDX della licenza come indicato nella lista di licenze SPDX, oppure la + combinazione di due identificatori SPDX separati da "WITH" per i casi + eccezionali. Quando si usano più licenze l'espressione viene formata da + sottoespressioni separate dalle parole chiave "AND", "OR" e racchiuse fra + parentesi tonde "(", ")". + + Gli identificativi di licenza per licenze come la [L]GPL che si avvalgono + dell'opzione 'o successive' si formano aggiungendo alla fine il simbolo "+" + per indicare l'opzione 'o successive'.:: + + // SPDX-License-Identifier: GPL-2.0+ + // SPDX-License-Identifier: LGPL-2.1+ + + WITH dovrebbe essere usato quando sono necessarie delle modifiche alla + licenza. Per esempio, la UAPI del kernel linux usa l'espressione:: + + // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note + // SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note + + Altri esempi di usi di WITH all'interno del kernel sono:: + + // SPDX-License-Identifier: GPL-2.0 WITH mif-exception + // SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0 + + Le eccezioni si possono usare solo in combinazione con identificatori di + licenza. Gli identificatori di licenza riconosciuti sono elencati nei + corrispondenti file d'eccezione. Per maggiori dettagli consultate + `Eccezioni`_ nel capitolo `Identificatori di licenza`_ + + La parola chiave OR dovrebbe essere usata solo quando si usa una doppia + licenza e solo una dev'essere scelta. Per esempio, alcuni file dtsi sono + disponibili con doppia licenza:: + + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + + Esempi dal kernel di espressioni per file licenziati con doppia licenza + sono:: + + // SPDX-License-Identifier: GPL-2.0 OR MIT + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause + // SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 + // SPDX-License-Identifier: GPL-2.0 OR MPL-1.1 + // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT + // SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause OR OpenSSL + + La parola chiave AND dovrebbe essere usata quando i termini di più licenze + si applicano ad un file. Per esempio, quando il codice viene preso da + un altro progetto il quale da i permessi per aggiungerlo nel kernel ma + richiede che i termini originali della licenza rimangano intatti:: + + // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT + + Di seguito, un altro esempio dove entrambe i termini di licenza devono + essere rispettati:: + + // SPDX-License-Identifier: GPL-1.0+ AND LGPL-2.1+ + +Identificatori di licenza +------------------------- + +Le licenze attualmente in uso, così come le licenze aggiunte al kernel, possono +essere categorizzate in: + +1. _`Licenze raccomandate`: + + Ovunque possibile le licenze qui indicate dovrebbero essere usate perché + pienamente compatibili e molto usate. Queste licenze sono disponibile nei + sorgenti del kernel, nella cartella:: + + LICENSES/preferred/ + + I file in questa cartella contengono il testo completo della licenza e i + `Metatag`_. Il nome di questi file è lo stesso usato come identificatore + di licenza SPDX e che deve essere usato nei file sorgenti. + + Esempi:: + + LICENSES/preferred/GPL-2.0 + + Contiene il testo della seconda versione della licenza GPL e i metatag + necessari:: + + LICENSES/preferred/MIT + + Contiene il testo della licenza MIT e i metatag necessari. + + _`Metatag`: + + I seguenti metatag devono essere presenti in un file di licenza: + + - Valid-License-Identifier: + + Una o più righe che dichiarano quali identificatori di licenza sono validi + all'interno del progetto per far riferimento alla licenza in questione. + Solitamente, questo è un unico identificatore valido, ma per esempio le + licenze che permettono l'opzione 'o successive' hanno due identificatori + validi. + + - SPDX-URL: + + L'URL della pagina SPDX che contiene informazioni aggiuntive riguardanti + la licenza. + + - Usage-Guidance: + + Testo in formato libero per dare suggerimenti agli utenti. Il testo deve + includere degli esempi su come usare gli identificatori di licenza SPDX + in un file sorgente in conformità con le linea guida in + `Sintassi degli identificatori di licenza`_. + + - License-Text: + + Tutto il testo che compare dopo questa etichetta viene trattato + come se fosse parte del testo originale della licenza. + + Esempi:: + + Valid-License-Identifier: GPL-2.0 + Valid-License-Identifier: GPL-2.0+ + SPDX-URL: https://spdx.org/licenses/GPL-2.0.html + Usage-Guide: + To use this license in source code, put one of the following SPDX + tag/value pairs into a comment according to the placement + guidelines in the licensing rules documentation. + For 'GNU General Public License (GPL) version 2 only' use: + SPDX-License-Identifier: GPL-2.0 + For 'GNU General Public License (GPL) version 2 or any later version' use: + SPDX-License-Identifier: GPL-2.0+ + License-Text: + Full license text + + :: + + SPDX-License-Identifier: MIT + SPDX-URL: https://spdx.org/licenses/MIT.html + Usage-Guide: + To use this license in source code, put the following SPDX + tag/value pair into a comment according to the placement + guidelines in the licensing rules documentation. + SPDX-License-Identifier: MIT + License-Text: + Full license text + +| + +2. Licenze deprecate: + + Questo tipo di licenze dovrebbero essere usate solo per codice già esistente + o quando si prende codice da altri progetti. Le licenze sono disponibili + nei sorgenti del kernel nella cartella:: + + LICENSES/deprecated/ + + I file in questa cartella contengono il testo completo della licenza e i + `Metatag`_. Il nome di questi file è lo stesso usato come identificatore + di licenza SPDX e che deve essere usato nei file sorgenti. + + Esempi:: + + LICENSES/deprecated/ISC + + Contiene il testo della licenza Internet System Consortium e i suoi + metatag:: + + LICENSES/deprecated/GPL-1.0 + + Contiene il testo della versione 1 della licenza GPL e i suoi metatag. + + Metatag: + + I metatag necessari per le 'altre' ('other') licenze sono gli stessi + di usati per le `Licenze raccomandate`_. + + Esempio del formato del file:: + + Valid-License-Identifier: ISC + SPDX-URL: https://spdx.org/licenses/ISC.html + Usage-Guide: + Usage of this license in the kernel for new code is discouraged + and it should solely be used for importing code from an already + existing project. + To use this license in source code, put the following SPDX + tag/value pair into a comment according to the placement + guidelines in the licensing rules documentation. + SPDX-License-Identifier: ISC + License-Text: + Full license text + +| + +3. Solo per doppie licenze + + Queste licenze dovrebbero essere usate solamente per codice licenziato in + combinazione con un'altra licenza che solitamente è quella preferita. + Queste licenze sono disponibili nei sorgenti del kernel nella cartella:: + + LICENSES/dual + + I file in questa cartella contengono il testo completo della rispettiva + licenza e i suoi `Metatag`_. I nomi dei file sono identici agli + identificatori di licenza SPDX che dovrebbero essere usati nei file + sorgenti. + + Esempi:: + + LICENSES/dual/MPL-1.1 + + Questo file contiene il testo della versione 1.1 della licenza *Mozilla + Pulic License* e i metatag necessari:: + + LICENSES/dual/Apache-2.0 + + Questo file contiene il testo della versione 2.0 della licenza Apache e i + metatag necessari. + + Metatag: + + I requisiti per le 'altre' ('*other*') licenze sono identici a quelli per le + `Licenze raccomandate`_. + + Esempio del formato del file:: + + Valid-License-Identifier: MPL-1.1 + SPDX-URL: https://spdx.org/licenses/MPL-1.1.html + Usage-Guide: + Do NOT use. The MPL-1.1 is not GPL2 compatible. It may only be used for + dual-licensed files where the other license is GPL2 compatible. + If you end up using this it MUST be used together with a GPL2 compatible + license using "OR". + To use the Mozilla Public License version 1.1 put the following SPDX + tag/value pair into a comment according to the placement guidelines in + the licensing rules documentation: + SPDX-License-Identifier: MPL-1.1 + License-Text: + Full license text + +| + +4. _`Eccezioni`: + + Alcune licenze possono essere corrette con delle eccezioni che forniscono + diritti aggiuntivi. Queste eccezioni sono disponibili nei sorgenti del + kernel nella cartella:: + + LICENSES/exceptions/ + + I file in questa cartella contengono il testo completo dell'eccezione e i + `Metatag per le eccezioni`_. + + Esempi:: + + LICENSES/exceptions/Linux-syscall-note + + Contiene la descrizione dell'eccezione per le chiamate di sistema Linux + così come documentato nel file COPYING del kernel Linux; questo viene usato + per i file d'intestazione per la UAPI. Per esempio + /\* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note \*/:: + + LICENSES/exceptions/GCC-exception-2.0 + + Contiene la 'eccezione di linking' che permette di collegare qualsiasi + binario, indipendentemente dalla sua licenza, con un compilato il cui file + sorgente è marchiato con questa eccezione. Questo è necessario per creare + eseguibili dai sorgenti che non sono compatibili con la GPL. + + _`Metatag per le eccezioni`: + + Un file contenente un'eccezione deve avere i seguenti metatag: + + - SPDX-Exception-Identifier: + + Un identificatore d'eccezione che possa essere usato in combinazione con + un identificatore di licenza SPDX. + + - SPDX-URL: + + L'URL della pagina SPDX che contiene informazioni aggiuntive riguardanti + l'eccezione. + + - SPDX-Licenses: + + Una lista di licenze SPDX separate da virgola, che possono essere usate + con l'eccezione. + + - Usage-Guidance: + + Testo in formato libero per dare suggerimenti agli utenti. Il testo deve + includere degli esempi su come usare gli identificatori di licenza SPDX + in un file sorgente in conformità con le linea guida in + `Sintassi degli identificatori di licenza`_. + + - Exception-Text: + + Tutto il testo che compare dopo questa etichetta viene trattato + come se fosse parte del testo originale della licenza. + + Esempi:: + + SPDX-Exception-Identifier: Linux-syscall-note + SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html + SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+ + Usage-Guidance: + This exception is used together with one of the above SPDX-Licenses + to mark user-space API (uapi) header files so they can be included + into non GPL compliant user-space application code. + To use this exception add it with the keyword WITH to one of the + identifiers in the SPDX-Licenses tag: + SPDX-License-Identifier: <SPDX-License> WITH Linux-syscall-note + Exception-Text: + Full exception text + + :: + + SPDX-Exception-Identifier: GCC-exception-2.0 + SPDX-URL: https://spdx.org/licenses/GCC-exception-2.0.html + SPDX-Licenses: GPL-2.0, GPL-2.0+ + Usage-Guidance: + The "GCC Runtime Library exception 2.0" is used together with one + of the above SPDX-Licenses for code imported from the GCC runtime + library. + To use this exception add it with the keyword WITH to one of the + identifiers in the SPDX-Licenses tag: + SPDX-License-Identifier: <SPDX-License> WITH GCC-exception-2.0 + Exception-Text: + Full exception text + +Per ogni identificatore di licenza SPDX e per le eccezioni dev'esserci un file +nella sotto-cartella LICENSES. Questo è necessario per permettere agli +strumenti di effettuare verifiche (come checkpatch.pl), per avere le licenze +disponibili per la lettura e per estrarre i diritti dai sorgenti, così come +raccomandato da diverse organizzazioni FOSS, per esempio l'`iniziativa FSFE +REUSE <https://reuse.software/>`_. + +_`MODULE_LICENSE` +----------------- + + I moduli del kernel necessitano di un'etichetta MODULE_LICENSE(). Questa + etichetta non sostituisce le informazioni sulla licenza del codice sorgente + (SPDX-License-Identifier) né fornisce informazioni che esprimono o + determinano l'esatta licenza sotto la quale viene rilasciato. + + Il solo scopo di questa etichetta è quello di fornire sufficienti + informazioni al caricatore di moduli del kernel, o agli strumenti in spazio + utente, per capire se il modulo è libero o proprietario. + + Le stringe di licenza valide per MODULE_LICENSE() sono: + + ============================= ============================================= + "GPL" Il modulo è licenziato con la GPL versione 2. + Questo non fa distinzione fra GPL'2.0-only o + GPL-2.0-or-later. L'esatta licenza può essere + determinata solo leggendo i corrispondenti + file sorgenti. + + "GPL v2" Stesso significato di "GPL". Esiste per + motivi storici. + + "GPL and additional rights" Questa è una variante che esiste per motivi + storici che indica che i sorgenti di un + modulo sono rilasciati sotto una variante + della licenza GPL v2 e quella MIT. Per favore + non utilizzatela per codice nuovo. + + "Dual MIT/GPL" Questo è il modo corretto per esprimere il + il fatto che il modulo è rilasciato con + doppia licenza a scelta fra: una variante + della GPL v2 o la licenza MIT. + + "Dual BSD/GPL" Questo modulo è rilasciato con doppia licenza + a scelta fra: una variante della GPL v2 o la + licenza BSD. La variante esatta della licenza + BSD può essere determinata solo attraverso i + corrispondenti file sorgenti. + + "Dual MPL/GPL" Questo modulo è rilasciato con doppia licenza + a scelta fra: una variante della GPL v2 o la + Mozilla Public License (MPL). La variante + esatta della licenza MPL può essere + determinata solo attraverso i corrispondenti + file sorgenti. + + "Proprietary" Questo modulo è rilasciato con licenza + proprietaria. Questa stringa è solo per i + moduli proprietari di terze parti e non può + essere usata per quelli che risiedono nei + sorgenti del kernel. I moduli etichettati in + questo modo stanno contaminando il kernel e + gli viene assegnato un flag 'P'; quando + vengono caricati, il caricatore di moduli del + kernel si rifiuterà di collegare questi + moduli ai simboli che sono stati esportati + con EXPORT_SYMBOL_GPL(). + + ============================= ============================================= diff --git a/Documentation/translations/it_IT/process/magic-number.rst b/Documentation/translations/it_IT/process/magic-number.rst new file mode 100644 index 0000000000..ae92ab633c --- /dev/null +++ b/Documentation/translations/it_IT/process/magic-number.rst @@ -0,0 +1,90 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/magic-number.rst <magicnumbers>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_magicnumbers: + +I numeri magici di Linux +======================== + +Questo documento è un registro dei numeri magici in uso. Quando +aggiungete un numero magico ad una struttura, dovreste aggiungerlo anche +a questo documento; la cosa migliore è che tutti i numeri magici usati +dalle varie strutture siano unici. + +È **davvero** un'ottima idea proteggere le strutture dati del kernel con +dei numeri magici. Questo vi permette in fase d'esecuzione di (a) verificare +se una struttura è stata malmenata, o (b) avete passato a una procedura la +struttura errata. Quest'ultimo è molto utile - particolarmente quando si passa +una struttura dati tramite un puntatore void \*. Il codice tty, per esempio, +effettua questa operazione con regolarità passando avanti e indietro le +strutture specifiche per driver e discipline. + +Per utilizzare un numero magico, dovete dichiararlo all'inizio della struttura +dati, come di seguito:: + + struct tty_ldisc { + int magic; + ... + }; + +Per favore, seguite questa direttiva quando aggiungerete migliorie al kernel! +Mi ha risparmiato un numero illimitato di ore di debug, specialmente nei casi +più ostici dove si è andati oltre la dimensione di un vettore e la struttura +dati che lo seguiva in memoria è stata sovrascritta. Seguendo questa +direttiva, questi casi vengono identificati velocemente e in sicurezza. + +Registro dei cambiamenti:: + + Theodore Ts'o + 31 Mar 94 + + La tabella magica è aggiornata a Linux 2.1.55. + + Michael Chastain + <mailto:mec@shout.net> + 22 Sep 1997 + + Ora dovrebbe essere aggiornata a Linux 2.1.112. Dato che + siamo in un momento di congelamento delle funzionalità + (*feature freeze*) è improbabile che qualcosa cambi prima + della versione 2.2.x. Le righe sono ordinate secondo il + campo numero. + + Krzysztof G. Baranowski + <mailto: kgb@knm.org.pl> + 29 Jul 1998 + + Aggiornamento della tabella a Linux 2.5.45. Giusti nel congelamento + delle funzionalità ma è comunque possibile che qualche nuovo + numero magico s'intrufoli prima del kernel 2.6.x. + + Petr Baudis + <pasky@ucw.cz> + 03 Nov 2002 + + Aggiornamento della tabella magica a Linux 2.5.74. + + Fabian Frederick + <ffrederick@users.sourceforge.net> + 09 Jul 2003 + + +===================== ================ ======================== ========================================== +Nome magico Numero Struttura File +===================== ================ ======================== ========================================== +PG_MAGIC 'P' pg_{read,write}_hdr ``include/linux/pg.h`` +APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c`` +FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h`` +SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h`` +BAYCOM_MAGIC 0x19730510 baycom_state ``drivers/net/baycom_epp.c`` +HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state ``include/linux/hdlcdrv.h`` +KV_MAGIC 0x5f4b565f kernel_vars_s ``arch/mips/include/asm/sn/klkernvars.h`` +CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h`` +YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c`` +CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c`` +QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c`` +QUEUE_MAGIC_USED 0xf7e1cc33 queue_entry ``drivers/scsi/arm/queue.c`` +NMI_MAGIC 0x48414d4d455201 nmi_s ``arch/mips/include/asm/sn/nmi.h`` +===================== ================ ======================== ========================================== diff --git a/Documentation/translations/it_IT/process/maintainer-handbooks.rst b/Documentation/translations/it_IT/process/maintainer-handbooks.rst new file mode 100644 index 0000000000..d840145bcc --- /dev/null +++ b/Documentation/translations/it_IT/process/maintainer-handbooks.rst @@ -0,0 +1,24 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/process/maintainer-handbooks.rst +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_maintainer_handbooks_main: + +Note sul processo di sviluppo dei sottosistemi e dei sorgenti dei manutentori +============================================================================= + +Lo scopo di questo documento è quello di fornire informazioni sul processo di +sviluppo dedicate ai sottosistemi che vanno ad integrare quelle più generali +descritte in :ref:`Documentation/translations/it_IT/process +<it_development_process_main>`. + +Indice: + +.. toctree:: + :numbered: + :maxdepth: 2 + + maintainer-tip diff --git a/Documentation/translations/it_IT/process/maintainer-pgp-guide.rst b/Documentation/translations/it_IT/process/maintainer-pgp-guide.rst new file mode 100644 index 0000000000..cdc43c4a9b --- /dev/null +++ b/Documentation/translations/it_IT/process/maintainer-pgp-guide.rst @@ -0,0 +1,941 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/maintainer-pgp-guide.rst <pgpguide>` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_pgpguide: + +========================================= +La guida a PGP per manutentori del kernel +========================================= + +:Author: Konstantin Ryabitsev <konstantin@linuxfoundation.org> + +Questo documento è destinato agli sviluppatori del kernel Linux, in particolar +modo ai manutentori. Contiene degli approfondimenti riguardo informazioni che +sono state affrontate in maniera più generale nella sezione +"`Protecting Code Integrity`_" pubblicata dalla Linux Foundation. +Per approfondire alcuni argomenti trattati in questo documento è consigliato +leggere il documento sopraindicato + +.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md + +Il ruolo di PGP nello sviluppo del kernel Linux +=============================================== + +PGP aiuta ad assicurare l'integrità del codice prodotto dalla comunità +di sviluppo del kernel e, in secondo luogo, stabilisce canali di comunicazione +affidabili tra sviluppatori attraverso lo scambio di email firmate con PGP. + +Il codice sorgente del kernel Linux è disponibile principalmente in due +formati: + +- repositori distribuiti di sorgenti (git) +- rilasci periodici di istantanee (archivi tar) + +Sia i repositori git che gli archivi tar portano le firme PGP degli +sviluppatori che hanno creato i rilasci ufficiali del kernel. Queste firme +offrono una garanzia crittografica che le versioni scaricabili rese disponibili +via kernel.org, o altri portali, siano identiche a quelle che gli sviluppatori +hanno sul loro posto di lavoro. A tal scopo: + +- i repositori git forniscono firme PGP per ogni tag +- gli archivi tar hanno firme separate per ogni archivio + +.. _it_devs_not_infra: + +Fidatevi degli sviluppatori e non dell'infrastruttura +----------------------------------------------------- + +Fin dal 2011, quando i sistemi di kernel.org furono compromessi, il principio +generale del progetto Kernel Archives è stato quello di assumere che qualsiasi +parte dell'infrastruttura possa essere compromessa in ogni momento. Per questa +ragione, gli amministratori hanno intrapreso deliberatemene dei passi per +enfatizzare che la fiducia debba risiedere sempre negli sviluppatori e mai nel +codice che gestisce l'infrastruttura, indipendentemente da quali che siano le +pratiche di sicurezza messe in atto. + +Il principio sopra indicato è la ragione per la quale è necessaria questa +guida. Vogliamo essere sicuri che il riporre la fiducia negli sviluppatori +non sia fatto semplicemente per incolpare qualcun'altro per future falle di +sicurezza. L'obiettivo è quello di fornire una serie di linee guida che gli +sviluppatori possano seguire per creare un ambiente di lavoro sicuro e +salvaguardare le chiavi PGP usate nello stabilire l'integrità del kernel Linux +stesso. + +.. _it_pgp_tools: + +Strumenti PGP +============= + +Usare GnuPG 2.2 o successivo +---------------------------- + +La vostra distribuzione potrebbe avere già installato GnuPG, dovete solo +verificare che stia utilizzando la versione abbastanza recente. Per controllate +usate:: + + $ gpg --version | head -n1 + +Se state utilizzando la version 2.2 o successiva, allora siete pronti a partire. +Se invece state usando una versione precedente, allora alcuni comandi elencati +in questa guida potrebbero non funzionare. + +Configurare le opzioni di gpg-agent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +L'agente GnuPG è uno strumento di aiuto che partirà automaticamente ogni volta +che userete il comando ``gpg`` e funzionerà in *background* con l'obiettivo di +individuare la passphrase. Ci sono due opzioni che dovreste conoscere +per personalizzare la scadenza della passphrase nella cache: + +- ``default-cache-ttl`` (secondi): Se usate ancora la stessa chiave prima + che il time-to-live termini, il conto alla rovescia si resetterà per un + altro periodo. Di base è di 600 (10 minuti). + +- ``max-cache-ttl`` (secondi): indipendentemente da quanto sia recente l'ultimo + uso della chiave da quando avete inserito la passphrase, se il massimo + time-to-live è scaduto, dovrete reinserire nuovamente la passphrase. + Di base è di 30 minuti. + +Se ritenete entrambe questi valori di base troppo corti (o troppo lunghi), +potete creare il vostro file ``~/.gnupg/gpg-agent.conf`` ed impostare i vostri +valori:: + + # set to 30 minutes for regular ttl, and 2 hours for max ttl + default-cache-ttl 1800 + max-cache-ttl 7200 + +.. note:: + + Non è più necessario far partire l'agente gpg manualmente all'inizio della + vostra sessione. Dovreste controllare i file rc per rimuovere tutto ciò che + riguarda vecchie le versioni di GnuPG, poiché potrebbero non svolgere più + bene il loro compito. + +.. _it_protect_your_key: + +Proteggere la vostra chiave PGP primaria +======================================== + +Questa guida parte dal presupposto che abbiate già una chiave PGP che usate +per lo sviluppo del kernel Linux. Se non ne avete ancora una, date uno sguardo +al documento "`Protecting Code Integrity`_" che abbiamo menzionato prima. + +Dovreste inoltre creare una nuova chiave se quella attuale è inferiore a 2048 +bit (RSA). + +Le sottochiavi PGP +------------------ + +Raramente le chiavi PGP sono composte da una singola coppia -- solitamente, sono +una collezione di sottochiavi indipendenti usate per diversi scopi in funzione +delle capacità assegnate al momento della creazione. Una chiave PGP può avere +quattro capacità: + +- **[S]** può essere usata per firmare +- **[E]** può essere usata per criptare +- **[A]** può essere usata per autenticare +- **[C]** può essere usata per certificare altre chiavi + +La chiave con la capacità **[C]** viene spesso chiamata chiave "passepartout" +(*master key*), ma è una terminologia fuorviante perché lascia intendere che la +chiave di certificato possa essere usate in sostituzione delle altre (proprio +come le vere chiavi passpartout in grado di aprire diverse serrature). Dato che +questo non è il caso, per evitare fraintendimenti, in questa guida ci riferiremo +a questa chiave chiamandola "La chiave di certificazione". + +I seguenti punti sono molto importanti: + +1. Tutte le sottochiavi sono indipendenti. Se perdete una sottochiave privata + non potrete recuperarla usando le altre. +2. Ad eccezione della chiave di certificazione, ci possono essere più + sottochiavi con le stesse capacità (per esempio, potete avere 2 sottochiavi + per criptare, 3 per firmare, ma solo una per una sola per certificare). Tutte + le sottochiavi sono indipendenti -- un messaggio criptato usando una chiave + **[E]** non può essere decriptato usano altre sottochiavi **[E]**. +3. Una sottochiave può avere più capacità (per esempio, la chiave **[C]** può + anche essere una chiave **[S]**). + +La chiave con capacità **[C]** (certificazione) è la sola che può essere usata +per indicare relazioni fra chiavi. Solo la chiave **[C]** può essere usata per: + +- aggiungere o revocare altre chiavi (sottochiavi) che hanno capacità S/E/A; +- aggiungere, modificare o eliminare le identità (unids) associate alla chiave; +- aggiungere o modificare la propria data di scadenza o delle sottochiavi; +- firmare le chiavi di altre persone a scopo di creare una rete di fiducia. + +Di base, alla creazione di nuove chiavi, GnuPG genera quanto segue: + +- Una chiave la capacità di certificazione che quella di firma (**[SC]**) +- Una sottochiave separata con capacità di criptare (**[E]**) + + + + +Se avete usato i parametri predefiniti per generare la vostra chiave, quello +sarà il risultato. Potete verificarlo utilizzando ``gpg --list-secret-keys``, +per esempio:: + + sec ed25519 2022-12-20 [SC] [expires: 2024-12-19] + 000000000000000000000000AAAABBBBCCCCDDDD + uid [ultimate] Alice Dev <adev@kernel.org> + ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] + +La lunga riga sotto la voce ``sec`` è la vostra impronta digitale -- +negli esempi che seguono, quando vedere ``[fpr]`` ci si riferisce a questa +stringa di 40 caratteri. + +Assicuratevi che la vostra passphrase sia forte +----------------------------------------------- + +GnuPG utilizza le passphrases per criptare la vostra chiave privata prima +di salvarla sul disco. In questo modo, anche se il contenuto della vostra +cartella ``.gnupg`` venisse letto o trafugato nella sia interezza, gli +attaccanti non potrebbero comunque utilizzare le vostre chiavi private senza +aver prima ottenuto la passphrase per decriptarle. + +È assolutamente essenziale che le vostre chiavi private siano protette da +una passphrase forte. Per impostarla o cambiarla, usate:: + + $ gpg --change-passphrase [fpr] + +Create una sottochiave di firma separata +---------------------------------------- + +Il nostro obiettivo è di proteggere la chiave primaria spostandola su un +dispositivo sconnesso dalla rete, dunque se avete solo una chiave combinata +**[SC]** allora dovreste creare una sottochiave di firma separata:: + + $ gpg --quick-add-key [fpr] ed25519 sign + +Ricordate di informare il keyserver del vostro cambiamento, cosicché altri +possano ricevere la vostra nuova sottochiave:: + + $ gpg --send-key [fpr] + +.. note:: Supporto ECC in GnuPG + + Tenete presente che se avete intenzione di usare un dispositivo che non + supporta chiavi ED25519 ECC, allora dovreste usare "nistp256" al posto di + "ed25519". Più avanti ci sono alcune raccomandazioni per i dispositivi. + +Copia di riserva della chiave primaria per gestire il recupero da disastro +-------------------------------------------------------------------------- + +Maggiori sono le firme di altri sviluppatori che vengono applicate alla vostra, +maggiori saranno i motivi per avere una copia di riserva che non sia digitale, +al fine di effettuare un recupero da disastro. + +Il modo migliore per creare una copia fisica della vostra chiave privata è +l'uso del programma ``paperkey``. Consultate ``man paperkey`` per maggiori +dettagli sul formato dell'output ed i suoi punti di forza rispetto ad altre +soluzioni. Paperkey dovrebbe essere già pacchettizzato per la maggior parte +delle distribuzioni. + +Eseguite il seguente comando per creare una copia fisica di riserva della +vostra chiave privata:: + + $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt + +Stampate il file (o fate un pipe direttamente verso lpr), poi prendete +una penna e scrivete la passphare sul margine del foglio. **Questo è +caldamente consigliato** perché la copia cartacea è comunque criptata con +la passphrase, e se mai doveste cambiarla non vi ricorderete qual'era al +momento della creazione di quella copia -- *garantito*. + +Mettete la copia cartacea e la passphrase scritta a mano in una busta e +mettetela in un posto sicuro e ben protetto, preferibilmente fuori casa, +magari in una cassetta di sicurezza in banca. + +.. note:: + + Probabilmente la vostra stampante non è più quello stupido dispositivo + connesso alla porta parallela, ma dato che il suo output è comunque + criptato con la passphrase, eseguire la stampa in un sistema "cloud" + moderno dovrebbe essere comunque relativamente sicuro. + +Copia di riserva di tutta la cartella GnuPG +------------------------------------------- + +.. warning:: + + **!!!Non saltate questo passo!!!** + +Quando avete bisogno di recuperare le vostre chiavi PGP è importante avere +una copia di riserva pronta all'uso. Questo sta su un diverso piano di +prontezza rispetto al recupero da disastro che abbiamo risolto con +``paperkey``. Vi affiderete a queste copie esterne quando dovreste usare la +vostra chiave Certify -- ovvero quando fate modifiche alle vostre chiavi o +firmate le chiavi di altre persone ad una conferenza o ad un gruppo d'incontro. + +Incominciate con una piccola chiavetta di memoria USB (preferibilmente due) +che userete per le copie di riserva. Dovrete criptarle usando LUKS -- fate +riferimento alla documentazione della vostra distribuzione per capire come +fare. + +Per la passphrase di criptazione, potete usare la stessa della vostra chiave +primaria. + +Una volta che il processo di criptazione è finito, reinserite il disco USB ed +assicurativi che venga montato correttamente. Copiate interamente la cartella +``.gnugp`` nel disco criptato:: + + $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup + +Ora dovreste verificare che tutto continui a funzionare:: + + $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr] + +Se non vedete errori, allora dovreste avere fatto tutto con successo. +Smontate il disco USB, etichettatelo per bene di modo da evitare di +distruggerne il contenuto non appena vi serve una chiavetta USB a caso, ed +infine mettetelo in un posto sicuro -- ma non troppo lontano, perché vi servirà +di tanto in tanto per modificare le identità, aggiungere o revocare +sottochiavi, o firmare le chiavi di altre persone. + +Togliete la chiave primaria dalla vostra home +--------------------------------------------- + +I file che si trovano nella vostra cartella home non sono poi così ben protetti +come potreste pensare. Potrebbero essere letti o trafugati in diversi modi: + +- accidentalmente quando fate una rapida copia della cartella home per + configurare una nuova postazione +- da un amministratore di sistema negligente o malintenzionato +- attraverso copie di riserva insicure +- attraverso malware installato in alcune applicazioni (browser, lettori PDF, + eccetera) +- attraverso coercizione quando attraversate confini internazionali + +Proteggere la vostra chiave con una buona passphare aiuta notevolmente a +ridurre i rischi elencati qui sopra, ma le passphrase possono essere scoperte +attraverso i keylogger, il shoulder-surfing, o altri modi. Per questi motivi, +nella configurazione si raccomanda di rimuove la chiave primaria dalla vostra +cartella home e la si archivia su un dispositivo disconnesso. + +.. warning:: + + Per favore, fate riferimento alla sezione precedente e assicuratevi + di aver fatto una copia di riserva totale della cartella GnuPG. Quello + che stiamo per fare renderà la vostra chiave inutile se non avete delle + copie di riserva utilizzabili! + +Per prima cosa, identificate il keygrip della vostra chiave primaria:: + + $ gpg --with-keygrip --list-key [fpr] + +L'output assomiglierà a questo:: + + pub ed25519 2022-12-20 [SC] [expires: 2022-12-19] + 000000000000000000000000AAAABBBBCCCCDDDD + Keygrip = 1111000000000000000000000000000000000000 + uid [ultimate] Alice Dev <adev@kernel.org> + sub cv25519 2022-12-20 [E] [expires: 2022-12-19] + Keygrip = 2222000000000000000000000000000000000000 + sub ed25519 2022-12-20 [S] + Keygrip = 3333000000000000000000000000000000000000 + +Trovate la voce keygrid che si trova sotto alla riga ``pub`` (appena sotto +all'impronta digitale della chiave primaria). Questo corrisponderà direttamente +ad un file nella cartella ``~/.gnupg``:: + + $ cd ~/.gnupg/private-keys-v1.d + $ ls + 1111000000000000000000000000000000000000.key + 2222000000000000000000000000000000000000.key + 3333000000000000000000000000000000000000.key + +Quello che dovrete fare è rimuovere il file .key che corrisponde al keygrip +della chiave primaria:: + + $ cd ~/.gnupg/private-keys-v1.d + $ rm 1111000000000000000000000000000000000000.key + +Ora, se eseguite il comando ``--list-secret-keys``, vedrete che la chiave +primaria non compare più (il simbolo ``#`` indica che non è disponibile):: + + $ gpg --list-secret-keys + sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] + 000000000000000000000000AAAABBBBCCCCDDDD + uid [ultimate] Alice Dev <adev@kernel.org> + ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] + ssb ed25519 2022-12-20 [S] + +Dovreste rimuovere anche i file ``secring.gpg`` che si trovano nella cartella +``~/.gnupg``, in quanto rimasugli delle versioni precedenti di GnuPG. + +Se non avete la cartella "private-keys-v1.d" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Se non avete la cartella ``~/.gnupg/private-keys-v1.d``, allora le vostre +chiavi segrete sono ancora salvate nel vecchio file ``secring.gpg`` usato +da GnuPG v1. Effettuare una qualsiasi modifica alla vostra chiave, come +cambiare la passphare o aggiungere una sottochiave, dovrebbe convertire +automaticamente il vecchio formato ``secring.gpg``nel nuovo +``private-keys-v1.d``. + +Una volta che l'avete fatto, assicuratevi di rimuovere il file ``secring.gpg``, +che continua a contenere la vostra chiave privata. + +.. _it_smartcards: + +Spostare le sottochiavi in un apposito dispositivo criptato +=========================================================== + +Nonostante la chiave primaria sia ora al riparo da occhi e mani indiscrete, +le sottochiavi si trovano ancora nella vostra cartella home. Chiunque riesca +a mettere le sue mani su quelle chiavi riuscirà a decriptare le vostre +comunicazioni o a falsificare le vostre firme (se conoscono la passphrase). +Inoltre, ogni volta che viene fatta un'operazione con GnuPG, le chiavi vengono +caricate nella memoria di sistema e potrebbero essere rubate con l'uso di +malware sofisticati (pensate a Meltdown e a Spectre). + +Il miglior modo per proteggere le proprie chiave è di spostarle su un +dispositivo specializzato in grado di effettuare operazioni smartcard. + +I benefici di una smartcard +--------------------------- + +Una smartcard contiene un chip crittografico che è capace di immagazzinare +le chiavi private ed effettuare operazioni crittografiche direttamente sulla +carta stessa. Dato che la chiave non lascia mai la smartcard, il sistema +operativo usato sul computer non sarà in grado di accedere alle chiavi. +Questo è molto diverso dai dischi USB criptati che abbiamo usato allo scopo di +avere una copia di riserva sicura -- quando il dispositivo USB è connesso e +montato, il sistema operativo potrà accedere al contenuto delle chiavi private. + +L'uso di un disco USB criptato non può sostituire le funzioni di un dispositivo +capace di operazioni di tipo smartcard. + +Dispositivi smartcard disponibili +--------------------------------- + +A meno che tutti i vostri computer dispongano di lettori smartcard, il modo +più semplice è equipaggiarsi di un dispositivo USB specializzato che +implementi le funzionalità delle smartcard. Sul mercato ci sono diverse +soluzioni disponibili: + +- `Nitrokey Start`_: è Open hardware e Free Software, è basata sul progetto + `GnuK`_ della FSIJ. Questo è uno dei pochi dispositivi a supportare le chiavi + ECC ED25519, ma offre meno funzionalità di sicurezza (come la resistenza + alla manomissione o alcuni attacchi ad un canale laterale). +- `Nitrokey Pro 2`_: è simile alla Nitrokey Start, ma è più resistente alla + manomissione e offre più funzionalità di sicurezza. La Pro 2 supporta la + crittografia ECC (NISTP). +- `Yubikey 5`_: l'hardware e il software sono proprietari, ma è più economica + della Nitrokey Pro ed è venduta anche con porta USB-C il che è utile con i + computer portatili più recenti. In aggiunta, offre altre funzionalità di + sicurezza come FIDO, U2F, e ora supporta anche le chiavi ECC (NISTP) + +La vostra scelta dipenderà dal costo, la disponibilità nella vostra regione, e +sulla scelta fra dispositivi aperti e proprietari. + +.. note:: + + Se siete nella lista MAINTAINERS o avete un profilo su kernel.org, allora + `potrete avere gratuitamente una Nitrokey Start`_ grazie alla fondazione + Linux. + +.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6 +.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nitrokey-pro-2-3 +.. _`Yubikey 5`: https://www.yubico.com/product/yubikey-5-overview/ +.. _Gnuk: https://www.fsij.org/doc-gnuk/ +.. _`potrete avere gratuitamente una Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html + +Configurare il vostro dispositivo smartcard +------------------------------------------- + +Il vostro dispositivo smartcard dovrebbe iniziare a funzionare non appena +lo collegate ad un qualsiasi computer Linux moderno. Potete verificarlo +eseguendo:: + + $ gpg --card-status + +Se vedete tutti i dettagli della smartcard, allora ci siamo. Sfortunatamente, +affrontare tutti i possibili motivi per cui le cose potrebbero non funzionare +non è lo scopo di questa guida. Se avete problemi nel far funzionare la carta +con GnuPG, cercate aiuto attraverso i soliti canali di supporto. + +Per configurare la vostra smartcard, dato che non c'è una via facile dalla +riga di comando, dovrete usate il menu di GnuPG:: + + $ gpg --card-edit + [...omitted...] + gpg/card> admin + Admin commands are allowed + gpg/card> passwd + +Dovreste impostare il PIN dell'utente (1), quello dell'amministratore (3) e il +codice di reset (4). Assicuratevi di annotare e salvare questi codici in un +posto sicuro -- specialmente il PIN dell'amministratore e il codice di reset +(che vi permetterà di azzerare completamente la smartcard). Il PIN +dell'amministratore viene usato così raramente che è inevitabile dimenticarselo +se non lo si annota. + +Tornando al nostro menu, potete impostare anche altri valori (come il nome, +il sesso, informazioni d'accesso, eccetera), ma non sono necessari e aggiunge +altre informazioni sulla carta che potrebbero trapelare in caso di smarrimento. + +.. note:: + + A dispetto del nome "PIN", né il PIN utente né quello dell'amministratore + devono essere esclusivamente numerici. + +.. warning:: + + Alcuni dispositivi richiedono la presenza delle sottochiavi nel dispositivo + stesso prima che possiate cambiare la passphare. Verificate la + documentazione del produttore. + +Spostare le sottochiavi sulla smartcard +--------------------------------------- + +Uscite dal menu (usando "q") e salverete tutte le modifiche. Poi, spostiamo +tutte le sottochiavi sulla smartcard. Per la maggior parte delle operazioni +vi serviranno sia la passphrase della chiave PGP che il PIN +dell'amministratore:: + + $ gpg --edit-key [fpr] + + Secret subkeys are available. + + pub ed25519/AAAABBBBCCCCDDDD + created: 2022-12-20 expires: 2024-12-19 usage: SC + trust: ultimate validity: ultimate + ssb cv25519/1111222233334444 + created: 2022-12-20 expires: never usage: E + ssb ed25519/5555666677778888 + created: 2017-12-07 expires: never usage: S + [ultimate] (1). Alice Dev <adev@kernel.org> + + gpg> + +Usando ``--edit-key`` si tornerà alla modalità menu e noterete che +la lista delle chiavi è leggermente diversa. Da questo momento in poi, +tutti i comandi saranno eseguiti nella modalità menu, come indicato +da ``gpg>``. + +Per prima cosa, selezioniamo la chiave che verrà messa sulla carta -- +potete farlo digitando ``key 1`` (è la prima della lista, la sottochiave +**[E]**):: + + gpg> key 1 + +Nel'output dovreste vedere ``ssb*`` associato alla chiave **[E]**. Il simbolo +``*`` indica che la chiave è stata "selezionata". Funziona come un +interruttore, ovvero se scrivete nuovamente ``key 1``, il simbolo ``*`` sparirà +e la chiave non sarà più selezionata. + +Ora, spostiamo la chiave sulla smartcard:: + + gpg> keytocard + Please select where to store the key: + (2) Encryption key + Your selection? 2 + +Dato che è la nostra chiave **[E]**, ha senso metterla nella sezione criptata. +Quando confermerete la selezione, vi verrà chiesta la passphrase della vostra +chiave PGP, e poi il PIN dell'amministratore. Se il comando ritorna senza +errori, allora la vostra chiave è stata spostata con successo. + +**Importante**: digitate nuovamente ``key 1`` per deselezionare la prima chiave +e selezionate la seconda chiave **[S]** con ``key 2``:: + + gpg> key 1 + gpg> key 2 + gpg> keytocard + Please select where to store the key: + (1) Signature key + (3) Authentication key + Your selection? 1 + +Potete usare la chiave **[S]** sia per firmare che per autenticare, ma vogliamo +che sia nella sezione di firma, quindi scegliete (1). Ancora una volta, se il +comando ritorna senza errori, allora l'operazione è avvenuta con successo:: + + gpg> q + Save changes? (y/N) y + +Salvando le modifiche cancellerete dalla vostra cartella home tutte le chiavi +che avete spostato sulla carta (ma questo non è un problema, perché abbiamo +fatto delle copie di sicurezza nel caso in cui dovessimo configurare una +nuova smartcard). + +Verificare che le chiavi siano state spostate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ora, se doveste usare l'opzione ``--list-secret-keys``, vedrete una +sottile differenza nell'output:: + + $ gpg --list-secret-keys + sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] + 000000000000000000000000AAAABBBBCCCCDDDD + uid [ultimate] Alice Dev <adev@kernel.org> + ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19] + ssb> ed25519 2022-12-20 [S] + +Il simbolo ``>`` in ``ssb>`` indica che la sottochiave è disponibile solo +nella smartcard. Se tornate nella vostra cartella delle chiavi segrete e +guardate al suo contenuto, noterete che i file ``.key`` sono stati sostituiti +con degli stub:: + + $ cd ~/.gnupg/private-keys-v1.d + $ strings *.key | grep 'private-key' + +Per indicare che i file sono solo degli stub e che in realtà il contenuto è +sulla smartcard, l'output dovrebbe mostrarvi ``shadowed-private-key``. + +Verificare che la smartcard funzioni +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per verificare che la smartcard funzioni come dovuto, potete creare +una firma:: + + $ echo "Hello world" | gpg --clearsign > /tmp/test.asc + $ gpg --verify /tmp/test.asc + +Col primo comando dovrebbe chiedervi il PIN della smartcard, e poi dovrebbe +mostrare "Good signature" dopo l'esecuzione di ``gpg --verify``. + +Complimenti, siete riusciti a rendere estremamente difficile il furto della +vostra identità digitale di sviluppatore. + +Altre operazioni possibili con GnuPG +------------------------------------ + +Segue un breve accenno ad alcune delle operazioni più comuni che dovrete +fare con le vostre chiavi PGP. + +Montare il disco con la chiave primaria +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Vi servirà la vostra chiave principale per tutte le operazioni che seguiranno, +per cui per prima cosa dovrete accedere ai vostri backup e dire a GnuPG di +usarli:: + + $ export GNUPGHOME=/media/disk/foo/gnupg-backup + $ gpg --list-secret-keys + +Dovete assicurarvi di vedere ``sec`` e non ``sec#`` nell'output del programma +(il simbolo ``#`` significa che la chiave non è disponibile e che state ancora +utilizzando la vostra solita cartella di lavoro). + +Estendere la data di scadenza di una chiave +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +La chiave principale ha una data di scadenza di 2 anni dal momento della sua +creazione. Questo per motivi di sicurezza e per rendere obsolete le chiavi +che, eventualmente, dovessero sparire dai keyserver. + +Per estendere di un anno, dalla data odierna, la scadenza di una vostra chiave, +eseguite:: + + $ gpg --quick-set-expire [fpr] 1y + +Se per voi è più facile da memorizzare, potete anche utilizzare una data +specifica (per esempio, il vostro compleanno o capodanno):: + + $ gpg --quick-set-expire [fpr] 2025-07-01 + +Ricordatevi di inviare l'aggiornamento ai keyserver:: + + $ gpg --send-key [fpr] + +Aggiornare la vostra cartella di lavoro dopo ogni modifica +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Dopo aver fatto delle modifiche alle vostre chiavi usando uno spazio a parte, +dovreste importarle nella vostra cartella di lavoro abituale:: + + $ gpg --export | gpg --homedir ~/.gnupg --import + $ unset GNUPGHOME + +Usare gpg-agent con ssh +~~~~~~~~~~~~~~~~~~~~~~~ + +Se dovete firmare tag o commit su un sistema remoto, potete ridirezionare il +vostro gpg-agent attraverso ssh. Consultate le istruzioni disponibili nella wiki +GnuPG: + +- `Agent Forwarding over SSH`_ + +Funziona senza troppi intoppi se avete la possibilità di modificare le +impostazioni di sshd sul sistema remoto. + +.. _`Agent Forwarding over SSH`: https://wiki.gnupg.org/AgentForwarding + +.. _it_pgp_with_git: + +Usare PGP con Git +================= + +Una delle caratteristiche fondanti di Git è la sua natura decentralizzata -- +una volta che il repositorio è stato clonato sul vostro sistema, avete la +storia completa del progetto, inclusi i suoi tag, i commit ed i rami. Tuttavia, +con i centinaia di repositori clonati che ci sono in giro, come si fa a +verificare che la loro copia di linux.git non è stata manomessa da qualcuno? + +Oppure, cosa succede se viene scoperta una backdoor nel codice e la riga +"Autore" dice che sei stato tu, mentre tu sei abbastanza sicuro di +`non averci niente a che fare`_? + +Per risolvere entrambi i problemi, Git ha introdotto l'integrazione con PGP. +I tag firmati dimostrano che il repositorio è integro assicurando che il suo +contenuto è lo stesso che si trova sulle macchine degli sviluppatori che hanno +creato il tag; mentre i commit firmati rendono praticamente impossibile +ad un malintenzionato di impersonarvi senza avere accesso alle vostre chiavi +PGP. + +.. _`non averci niente a che fare`: https://github.com/jayphelps/git-blame-someone-else + +Configurare git per usare la vostra chiave PGP +---------------------------------------------- + +Se avete solo una chiave segreta nel vostro portachiavi, allora non avete nulla +da fare in più dato che sarà la vostra chiave di base. Tuttavia, se doveste +avere più chiavi segrete, potete dire a git quale dovrebbe usare (``[fpg]`` +è la vostra impronta digitale):: + + $ git config --global user.signingKey [fpr] + +Come firmare i tag +------------------ + +Per creare un tag firmato, passate l'opzione ``-s`` al comando tag:: + + $ git tag -s [tagname] + +La nostra raccomandazione è quella di firmare sempre i tag git, perché +questo permette agli altri sviluppatori di verificare che il repositorio +git dal quale stanno prendendo il codice non è stato alterato intenzionalmente. + +Come verificare i tag firmati +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per verificare un tag firmato, potete usare il comando ``verify-tag``:: + + $ git verify-tag [tagname] + +Se state prendendo un tag da un fork del repositorio del progetto, git +dovrebbe verificare automaticamente la firma di quello che state prendendo +e vi mostrerà il risultato durante l'operazione di merge:: + + $ git pull [url] tags/sometag + +Il merge conterrà qualcosa di simile:: + + Merge tag 'sometag' of [url] + + [Tag message] + + # gpg: Signature made [...] + # gpg: Good signature from [...] + +Se state verificando il tag di qualcun altro, allora dovrete importare +la loro chiave PGP. Fate riferimento alla sezione ":ref:`it_verify_identities`" +che troverete più avanti. + +Configurare git per firmare sempre i tag con annotazione +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Se state creando un tag con annotazione è molto probabile che vogliate +firmarlo. Per imporre a git di firmare sempre un tag con annotazione, +dovete impostare la seguente opzione globale:: + + $ git config --global tag.forceSignAnnotated true + +Come usare commit firmati +------------------------- + +Creare dei commit firmati è facile, ma è molto più difficile utilizzarli +nello sviluppo del kernel linux per via del fatto che ci si affida alle +liste di discussione e questo modo di procedere non mantiene le firme PGP +nei commit. In aggiunta, quando si usa *rebase* nel proprio repositorio +locale per allinearsi al kernel anche le proprie firme PGP verranno scartate. +Per questo motivo, la maggior parte degli sviluppatori del kernel non si +preoccupano troppo di firmare i propri commit ed ignoreranno quelli firmati +che si trovano in altri repositori usati per il proprio lavoro. + +Tuttavia, se avete il vostro repositorio di lavoro disponibile al pubblico +su un qualche servizio di hosting git (kernel.org, infradead.org, ozlabs.org, +o altri), allora la raccomandazione è di firmare tutti i vostri commit +anche se gli sviluppatori non ne beneficeranno direttamente. + +Vi raccomandiamo di farlo per i seguenti motivi: + +1. Se dovesse mai esserci la necessità di fare delle analisi forensi o + tracciare la provenienza di un codice, anche sorgenti mantenuti + esternamente che hanno firme PGP sui commit avranno un certo valore a + questo scopo. +2. Se dovesse mai capitarvi di clonare il vostro repositorio locale (per + esempio dopo un danneggiamento del disco), la firma vi permetterà di + verificare l'integrità del repositorio prima di riprendere il lavoro. +3. Se qualcuno volesse usare *cherry-pick* sui vostri commit, allora la firma + permetterà di verificare l'integrità dei commit prima di applicarli. + +Creare commit firmati +~~~~~~~~~~~~~~~~~~~~~ + +Per creare un commit firmato, dovete solamente aggiungere l'opzione ``-S`` +al comando ``git commit`` (si usa la lettera maiuscola per evitare +conflitti con un'altra opzione):: + + $ git commit -S + +Configurare git per firmare sempre i commit +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Potete dire a git di firmare sempre i commit:: + + git config --global commit.gpgSign true + +.. note:: + + Assicuratevi di aver configurato ``gpg-agent`` prima di abilitare + questa opzione. + +.. _it_verify_identities: + +Come lavorare con patch firmate +------------------------------- + +Esiste la possibilità di usare la vostra chiave PGP per firmare le patch che +invierete alla liste di discussione del kernel. I meccanismi esistenti per la +firma delle email (PGP-Mime o PGP-inline) tendono a causare problemi +nell'attività di revisione del codice. Si suggerisce, invece, di utilizare lo +strumento sviluppato da kernel.org che mette nell'intestazione del messaggio +un'attestazione delle firme crittografiche (tipo DKIM): + +- `Patatt Patch Attestation`_ + +.. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/ + +Installare e configurate patatt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Lo strumento patatt è disponibile per diverse distribuzioni, dunque cercatelo +prima lì. Oppure potete installarlo usano pypi "``pip install patatt``" + +Se avete già configurato git con la vostra chiave PGP (usando +``user.signingKey``), allora patatt non ha bisogno di alcuna configurazione +aggiuntiva. Potete iniziare a firmare le vostre patch aggiungendo un aggancio a +git-send-email nel vostro repositorio:: + + patatt install-hook + +Ora, qualsiasi patch che invierete con ``git send-email`` verrà automaticamente +firmata usando la vostra firma crittografica. + +Verificare le firme di patatt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Se usate ``b4`` per verificare ed applicare le patch, allora tenterà +automaticamente di verificare tutte le firme DKIM e patatt disponibili. Per +esempio:: + + $ b4 am 20220720205013.890942-1-broonie@kernel.org + [...] + Checking attestation on all messages, may take a moment... + --- + ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers + ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall + ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls + --- + ✓ Signed: openpgp/broonie@kernel.org + ✓ Signed: DKIM/kernel.org + +.. note:: + + Lo sviluppo di patatt e b4 è piuttosto attivo. Si consiglia di verificare la + documentazione più recente. + +.. _it_kernel_identities: + +Come verificare l'identità degli sviluppatori del kernel +======================================================== + +Firmare i tag e i commit è facile, ma come si fa a verificare che la chiave +usata per firmare qualcosa appartenga davvero allo sviluppatore e non ad un +impostore? + +Configurare l'auto-key-retrieval usando WKD e DANE +-------------------------------------------------- + +Se non siete ancora in possesso di una vasta collezione di chiavi pubbliche +di altri sviluppatori, allora potreste iniziare il vostro portachiavi +affidandovi ai servizi di auto-scoperta e auto-recupero. GnuPG può affidarsi +ad altre tecnologie di delega della fiducia, come DNSSEC e TLS, per sostenervi +nel caso in cui iniziare una propria rete di fiducia da zero sia troppo +scoraggiante. + +Aggiungete il seguente testo al vostro file ``~/.gnupg/gpg.conf``:: + + auto-key-locate wkd,dane,local + auto-key-retrieve + +La *DNS-Based Authentication of Named Entities* ("DANE") è un metodo +per la pubblicazione di chiavi pubbliche su DNS e per renderle sicure usando +zone firmate con DNSSEC. Il *Web Key Directory* ("WKD") è un metodo +alternativo che usa https a scopo di ricerca. Quando si usano DANE o WKD +per la ricerca di chiavi pubbliche, GnuPG validerà i certificati DNSSEC o TLS +prima di aggiungere al vostro portachiavi locale le eventuali chiavi trovate. + +Kernel.org pubblica la WKD per tutti gli sviluppatori che hanno un account +kernel.org. Una volta che avete applicato le modifiche al file ``gpg.conf``, +potrete auto-recuperare le chiavi di Linus Torvalds e Greg Kroah-Hartman +(se non le avete già):: + + $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org + +Se avete un account kernel.org, al fine di rendere più utile l'uso di WKD +da parte di altri sviluppatori del kernel, dovreste `aggiungere alla vostra +chiave lo UID di kernel.org`_. + +.. _`aggiungere alla vostra chiave lo UID di kernel.org`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key + +Web of Trust (WOT) o Trust on First Use (TOFU) +---------------------------------------------- + +PGP incorpora un meccanismo di delega della fiducia conosciuto come +"Web of Trust". Di base, questo è un tentativo di sostituire la necessità +di un'autorità certificativa centralizzata tipica del mondo HTTPS/TLS. +Invece di avere svariati produttori software che decidono chi dovrebbero +essere le entità di certificazione di cui dovreste fidarvi, PGP lascia +la responsabilità ad ogni singolo utente. + +Sfortunatamente, solo poche persone capiscono come funziona la rete di fiducia. +Nonostante sia un importante aspetto della specifica OpenPGP, recentemente +le versioni di GnuPG (2.2 e successive) hanno implementato un meccanisco +alternativo chiamato "Trust on First Use" (TOFU). Potete pensare a TOFU come +"ad un approccio all fidicia simile ad SSH". In SSH, la prima volta che vi +connettete ad un sistema remoto, l'impronta digitale della chiave viene +registrata e ricordata. Se la chiave dovesse cambiare in futuro, il programma +SSH vi avviserà e si rifiuterà di connettersi, obbligandovi a prendere una +decisione circa la fiducia che riponete nella nuova chiave. In modo simile, +la prima volta che importate la chiave PGP di qualcuno, si assume sia valida. +Se ad un certo punto GnuPG trova un'altra chiave con la stessa identità, +entrambe, la vecchia e la nuova, verranno segnate come invalide e dovrete +verificare manualmente quale tenere. + +Vi raccomandiamo di usare il meccanisco TOFU+PGP (che è la nuova configurazione +di base di GnuPG v2). Per farlo, aggiungete (o modificate) l'impostazione +``trust-model`` in ``~/.gnupg/gpg.conf``:: + + trust-model tofu+pgp + +Usare il repositorio kernel.org per il web of trust +--------------------------------------------------- + +Il progetto kernel.org mantiene un repositorio git con le chiavi pubbliche degli sviluppatori in alternativa alla replica dei server di chiavi che negli ultimi anni sono spariti. La documentazione completa su come impostare il repositorio come vostra sorgente di chiavi pubbliche può essere trovato qui: + +- `Kernel developer PGP Keyring`_ + +Se siete uno sviluppatore del kernel, per favore valutate l'idea di inviare la +vostra chiave per l'inclusione in quel portachiavi. + + +If you are a kernel developer, please consider submitting your key for +inclusion into that keyring. + +.. _`Kernel developer PGP Keyring`: https://korg.docs.kernel.org/pgpkeys.html diff --git a/Documentation/translations/it_IT/process/maintainer-tip.rst b/Documentation/translations/it_IT/process/maintainer-tip.rst new file mode 100644 index 0000000000..126f17ee54 --- /dev/null +++ b/Documentation/translations/it_IT/process/maintainer-tip.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-ita.rst + +:Original: Documentation/process/maintainer-tip.rst + +Il tascabile dei sorgenti tip +============================= + +.. note:: To be translated diff --git a/Documentation/translations/it_IT/process/maintainers.rst b/Documentation/translations/it_IT/process/maintainers.rst new file mode 100644 index 0000000000..3225f7c89f --- /dev/null +++ b/Documentation/translations/it_IT/process/maintainers.rst @@ -0,0 +1,13 @@ +:Original: Documentation/process/maintainers.rst + +Lista dei manutentori e come inviare modifiche al kernel +======================================================== + +Questa pagina non verrà tradotta. Fate riferimento alla versione originale in +inglese. + +.. note:: La pagina originale usa una direttiva speciale per integrare il file + `MAINTAINERS` in sphinx. La parte di quel documento che si potrebbe + tradurre contiene comunque informazioni già presenti in + :ref:`Documentation/translations/it_IT/process/submitting-patches.rst + <it_submittingpatches>`. diff --git a/Documentation/translations/it_IT/process/management-style.rst b/Documentation/translations/it_IT/process/management-style.rst new file mode 100644 index 0000000000..76ed074082 --- /dev/null +++ b/Documentation/translations/it_IT/process/management-style.rst @@ -0,0 +1,295 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :doc:`../../../process/management-style` +:Translator: Alessia Mantegazza <amantegazza@vaga.pv.it> + +.. _it_managementstyle: + +Il modello di gestione del kernel Linux +======================================= + +Questo breve documento descrive il modello di gestione del kernel Linux. +Per certi versi, esso rispecchia il documento +:ref:`translations/it_IT/process/coding-style.rst <it_codingstyle>`, +ed è principalmente scritto per evitare di rispondere [#f1]_ in continuazione +alle stesse identiche (o quasi) domande. + +Il modello di gestione è qualcosa di molto personale e molto più difficile da +qualificare rispetto a delle semplici regole di codifica, quindi questo +documento potrebbe avere più o meno a che fare con la realtà. È cominciato +come un gioco, ma ciò non significa che non possa essere vero. +Lo dovrete decidere voi stessi. + +In ogni caso, quando si parla del "dirigente del kernel", ci si riferisce +sempre alla persona che dirige tecnicamente, e non a coloro che +tradizionalmente hanno un ruolo direttivo all'interno delle aziende. Se vi +occupate di convalidare acquisti o avete una qualche idea sul budget del vostro +gruppo, probabilmente non siete un dirigente del kernel. Quindi i suggerimenti +qui indicati potrebbero fare al caso vostro, oppure no. + +Prima di tutto, suggerirei di acquistare "Le sette regole per avere successo", +e di non leggerlo. Bruciatelo, è un grande gesto simbolico. + +.. [#f1] Questo documento non fa molto per risponde alla domanda, ma rende + così dannatamente ovvio a chi la pone che non abbiamo la minima idea + di come rispondere. + +Comunque, partiamo: + +.. _it_decisions: + +1) Le decisioni +--------------- + +Tutti pensano che i dirigenti decidano, e che questo prendere decisioni +sia importante. Più grande e dolorosa è la decisione, più importante deve +essere il dirigente che la prende. Questo è molto profondo ed ovvio, ma non è +del tutto vero. + +Il gioco consiste nell'"evitare" di dover prendere decisioni. In particolare +se qualcuno vi chiede di "Decidere" tra (a) o (b), e vi dice che ha +davvero bisogno di voi per questo, come dirigenti siete nei guai. +Le persone che gestite devono conoscere i dettagli più di quanto li conosciate +voi, quindi se vengono da voi per una decisione tecnica, siete fottuti. +Non sarete chiaramente competente per prendere quella decisione per loro. + +(Corollario: se le persone che gestite non conoscono i dettagli meglio di voi, +anche in questo caso sarete fregati, tuttavia per altre ragioni. Ossia state +facendo il lavoro sbagliato, e che invece dovrebbero essere "loro" a gestirvi) + +Quindi il gioco si chiama "evitare" decisioni, almeno le più grandi e +difficili. Prendere decisioni piccoli e senza conseguenze va bene, e vi fa +sembrare competenti in quello che state facendo, quindi quello che un dirigente +del kernel ha bisogno di fare è trasformare le decisioni grandi e difficili +in minuzie delle quali nessuno importa. + +Ciò aiuta a capire che la differenza chiave tra una grande decisione ed una +piccola sta nella possibilità di modificare tale decisione in seguito. +Qualsiasi decisione importante può essere ridotta in decisioni meno importanti, +ma dovete assicurarvi che possano essere reversibili in caso di errori +(presenti o futuri). Improvvisamente, dovrete essere doppiamente dirigenti +per **due** decisioni non sequenziali - quella sbagliata **e** quella giusta. + +E le persone vedranno tutto ciò come prova di vera capacità di comando +(*cough* cavolata *cough*) + +Così la chiave per evitare le decisioni difficili diviene l'evitare +di fare cose che non possono essere disfatte. Non infilatevi in un angolo +dal quale non potrete sfuggire. Un topo messo all'angolo può rivelarsi +pericoloso - un dirigente messo all'angolo è solo pietoso. + +**In ogni caso** dato che nessuno è stupido al punto da lasciare veramente ad +un dirigente del kernel un enorme responsabilità, solitamente è facile fare +marcia indietro. Annullare una decisione è molto facile: semplicemente dite a +tutti che siete stati degli scemi incompetenti, dite che siete dispiaciuti, ed +annullate tutto l'inutile lavoro sul quale gli altri hanno lavorato nell'ultimo +anno. Improvvisamente la decisione che avevate preso un anno fa non era poi +così grossa, dato che può essere facilmente annullata. + +È emerso che alcune persone hanno dei problemi con questo tipo di approccio, +questo per due ragioni: + + - ammettere di essere degli idioti è più difficile di quanto sembri. A tutti + noi piace mantenere le apparenze, ed uscire allo scoperto in pubblico per + ammettere che ci si è sbagliati è qualcosa di davvero impegnativo. + - avere qualcuno che ti dice che ciò su cui hai lavorato nell'ultimo anno + non era del tutto valido, può rivelarsi difficile anche per un povero ed + umile ingegnere, e mentre il **lavoro** vero era abbastanza facile da + cancellare, dall'altro canto potreste aver irrimediabilmente perso la + fiducia di quell'ingegnere. E ricordate che l'"irrevocabile" era quello + che avevamo cercato di evitare fin dall'inizio, e la vostra decisione + ha finito per esserlo. + +Fortunatamente, entrambe queste ragioni posso essere mitigate semplicemente +ammettendo fin dal principio che non avete una cavolo di idea, dicendo +agli altri in anticipo che la vostra decisione è puramente ipotetica, e che +potrebbe essere sbagliata. Dovreste sempre riservarvi il diritto di cambiare +la vostra opinione, e rendere gli altri ben **consapevoli** di ciò. +Ed è molto più facile ammettere di essere stupidi quando non avete **ancora** +fatto quella cosa stupida. + +Poi, quando è realmente emersa la vostra stupidità, le persone semplicemente +roteeranno gli occhi e diranno "Uffa, no, ancora". + +Questa ammissione preventiva di incompetenza potrebbe anche portare le persone +che stanno facendo il vero lavoro, a pensarci due volte. Dopo tutto, se +**loro** non sono certi se sia una buona idea, voi, sicuro come la morte, +non dovreste incoraggiarli promettendogli che ciò su cui stanno lavorando +verrà incluso. Fate si che ci pensino due volte prima che si imbarchino in un +grosso lavoro. + +Ricordate: loro devono sapere più cose sui dettagli rispetto a voi, e +solitamente pensano di avere già la risposta a tutto. La miglior cosa che +potete fare in qualità di dirigente è di non instillare troppa fiducia, ma +invece fornire una salutare dose di pensiero critico su quanto stanno facendo. + +Comunque, un altro modo di evitare una decisione è quello di lamentarsi +malinconicamente dicendo : "non possiamo farli entrambi e basta?" e con uno +sguardo pietoso. Fidatevi, funziona. Se non è chiaro quale sia il miglior +approccio, lo scopriranno. La risposta potrebbe essere data dal fatto che +entrambe i gruppi di lavoro diventano frustati al punto di rinunciarvi. + +Questo può suonare come un fallimento, ma di solito questo è un segno che +c'era qualcosa che non andava in entrambe i progetti, e il motivo per +il quale le persone coinvolte non abbiano potuto decidere era che entrambe +sbagliavano. Voi ne uscirete freschi come una rosa, e avrete evitato un'altra +decisione con la quale avreste potuto fregarvi. + + +2) Le persone +------------- + +Ci sono molte persone stupide, ed essere un dirigente significa che dovrete +scendere a patti con questo, e molto più importate, che **loro** devono avere +a che fare con **voi**. + +Ne emerge che mentre è facile annullare degli errori tecnici, non è invece +così facile rimuovere i disordini della personalità. Dovrete semplicemente +convivere con i loro, ed i vostri, problemi. + +Comunque, al fine di preparavi in qualità di dirigenti del kernel, è meglio +ricordare di non abbattere alcun ponte, bombardare alcun paesano innocente, +o escludere troppi sviluppatori kernel. Ne emerge che escludere le persone +è piuttosto facile, mentre includerle nuovamente è difficile. Così +"l'esclusione" immediatamente cade sotto il titolo di "non reversibile", e +diviene un no-no secondo la sezione :ref:`it_decisions`. + +Esistono alcune semplici regole qui: + + (1) non chiamate le persone teste di c*** (al meno, non in pubblico) + (2) imparate a scusarvi quando dimenticate la regola (1) + +Il problema del punto numero 1 è che è molto facile da rispettare, dato che +è possibile dire "sei una testa di c***" in milioni di modi differenti [#f2]_, +a volte senza nemmeno pensarci, e praticamente sempre con la calda convinzione +di essere nel giusto. + +E più convinti sarete che avete ragione (e diciamolo, potete chiamare +praticamente **tutti** testa di c**, e spesso **sarete** nel giusto), più +difficile sarà scusarvi successivamente. + +Per risolvere questo problema, avete due possibilità: + + - diventare davvero bravi nello scusarsi + - essere amabili così che nessuno finirà col sentirsi preso di mira. Siate + creativi abbastanza, e potrebbero esserne divertiti. + +L'opzione dell'essere immancabilmente educati non esiste proprio. Nessuno +si fiderà di qualcuno che chiaramente sta nascondendo il suo vero carattere. + +.. [#f2] Paul Simon cantava: "50 modi per lasciare il vostro amante", perché, + molto francamente, "Un milione di modi per dire ad uno sviluppatore + Testa di c***" non avrebbe funzionato. Ma sono sicuro che ci abbia + pensato. + + +3) Le persone II - quelle buone +------------------------------- + +Mentre emerge che la maggior parte delle persone sono stupide, il corollario +a questo è il triste fatto che anche voi siete fra queste, e che mentre +possiamo tutti crogiolarci nella sicurezza di essere migliori della media +delle persone (diciamocelo, nessuno crede di essere nelle media o sotto di +essa), dovremmo anche ammettere che non siamo il "coltello più affilato" del +circondario, e che ci saranno altre persone che sono meno stupide di quanto +lo siete voi. + +Molti reagiscono male davanti alle persone intelligenti. Altri le usano a +proprio vantaggio. + +Assicuratevi che voi, in qualità di manutentori del kernel, siate nel secondo +gruppo. Inchinatevi dinanzi a loro perché saranno le persone che vi renderanno +il lavoro più facile. In particolare, prenderanno le decisioni per voi, che è +l'oggetto di questo gioco. + +Quindi quando trovate qualcuno più sveglio di voi, prendetevela comoda. +Le vostre responsabilità dirigenziali si ridurranno in gran parte nel dire +"Sembra una buona idea - Vai", oppure "Sembra buono, ma invece circa questo e +quello?". La seconda versione in particolare è una gran modo per imparare +qualcosa di nuovo circa "questo e quello" o di sembrare **extra** dirigenziali +sottolineando qualcosa alla quale i più svegli non avevano pensato. In +entrambe i casi, vincete. + +Una cosa alla quale dovete fare attenzione è che l'essere grandi in qualcosa +non si traduce automaticamente nell'essere grandi anche in altre cose. Quindi +dovreste dare una spintarella alle persone in una specifica direzione, ma +diciamocelo, potrebbero essere bravi in ciò che fanno e far schifo in tutto +il resto. La buona notizia è che le persone tendono a gravitare attorno a ciò +in cui sono bravi, quindi non state facendo nulla di irreversibile quando li +spingete verso una certa direzione, solo non spingete troppo. + + +4) Addossare le colpe +--------------------- + +Le cose andranno male, e le persone vogliono qualcuno da incolpare. Sarete voi. + +Non è poi così difficile accettare la colpa, specialmente se le persone +riescono a capire che non era **tutta** colpa vostra. Il che ci porta +sulla miglior strada per assumersi la colpa: fatelo per qualcun'altro. +Vi sentirete bene nel assumervi la responsabilità, e loro si sentiranno +bene nel non essere incolpati, e coloro che hanno perso i loro 36GB di +pornografia a causa della vostra incompetenza ammetteranno a malincuore che +almeno non avete cercato di fare il furbetto. + +Successivamente fate in modo che gli sviluppatori che in realtà hanno fallito +(se riuscite a trovarli) sappiano **in privato** che sono "fottuti". +Questo non per fargli sapere che la prossima volta possono evitarselo ma per +fargli capire che sono in debito. E, forse cosa più importante, sono loro che +devono sistemare la cosa. Perché, ammettiamolo, è sicuro non sarete voi a +farlo. + +Assumersi la colpa è anche ciò che vi rendere dirigenti in prima battuta. +È parte di ciò che spinge gli altri a fidarsi di voi, e vi garantisce +la gloria potenziale, perché siete gli unici a dire "Ho fatto una cavolata". +E se avete seguito le regole precedenti, sarete decisamente bravi nel dirlo. + + +5) Le cose da evitare +--------------------- + +Esiste una cosa che le persone odiano più che essere chiamate "teste di c****", +ed è essere chiamate "teste di c****" con fare da bigotto. Se per il primo +caso potrete comunque scusarvi, per il secondo non ve ne verrà data nemmeno +l'opportunità. Probabilmente smetteranno di ascoltarvi anche se tutto sommato +state svolgendo un buon lavoro. + +Tutti crediamo di essere migliori degli altri, il che significa che quando +qualcuno inizia a darsi delle arie, ci da **davvero** fastidio. Potreste anche +essere moralmente ed intellettualmente superiore a tutti quelli attorno a voi, +ma non cercate di renderlo ovvio per gli altri a meno che non **vogliate** +veramente far arrabbiare qualcuno [#f3]_. + +Allo stesso modo evitate di essere troppo gentili e pacati. Le buone maniere +facilmente finiscono per strabordare e nascondere i problemi, e come si usa +dire, "su internet nessuno può sentire la vostra pacatezza". Usate argomenti +diretti per farvi capire, non potete sperare che la gente capisca in altro +modo. + +Un po' di umorismo può aiutare a smorzare sia la franchezza che la moralità. +Andare oltre i limiti al punto d'essere ridicolo può portare dei punti a casa +senza renderlo spiacevole per i riceventi, i quali penseranno che stavate +facendo gli scemi. Può anche aiutare a lasciare andare quei blocchi mentali +che abbiamo nei confronti delle critiche. + +.. [#f3] Suggerimento: i forum di discussione su internet, che non sono + collegati col vostro lavoro, sono ottimi modi per sfogare la frustrazione + verso altre persone. Di tanto in tanto scrivete messaggi offensivi col ghigno + in faccia per infiammare qualche discussione: vi sentirete purificati. Solo + cercate di non cagare troppo vicino a casa. + +6) Perché io? +------------- + +Dato che la vostra responsabilità principale è quella di prendervi le colpe +d'altri, e rendere dolorosamente ovvio a tutti che siete degli incompetenti, +la domanda naturale che ne segue sarà : perché dovrei fare tutto ciò? + +Innanzitutto, potreste diventare o no popolari al punto da avere la fila di +ragazzine (o ragazzini, evitiamo pregiudizi o sessismo) che gridano e bussano +alla porta del vostro camerino, ma comunque **proverete** un immenso senso di +realizzazione personale dall'essere "in carica". Dimenticate il fatto che voi +state discutendo con tutti e che cercate di inseguirli il più velocemente che +potete. Tutti continueranno a pensare che voi siete la persona in carica. + +È un bel lavoro se riuscite ad adattarlo a voi. diff --git a/Documentation/translations/it_IT/process/programming-language.rst b/Documentation/translations/it_IT/process/programming-language.rst new file mode 100644 index 0000000000..5bc5b9d42f --- /dev/null +++ b/Documentation/translations/it_IT/process/programming-language.rst @@ -0,0 +1,68 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/programming-language.rst <programming_language>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_programming_language: + +Linguaggio di programmazione +============================ + +Il kernel è scritto nel linguaggio di programmazione C [it-c-language]_. +Più precisamente, il kernel viene compilato con ``gcc`` [it-gcc]_ usando +l'opzione ``-std=gnu11`` [it-gcc-c-dialect-options]_: il dialetto GNU +dello standard ISO C11. +Linux supporta anche ``clang`` [it-clang]_, leggete la documentazione +:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`. + +Questo dialetto contiene diverse estensioni al linguaggio [it-gnu-extensions]_, +e molte di queste vengono usate sistematicamente dal kernel. + +Attributi +--------- + +Una delle estensioni più comuni e usate nel kernel sono gli attributi +[it-gcc-attribute-syntax]_. Gli attributi permettono di aggiungere una semantica, +definita dell'implementazione, alle entità del linguaggio (come le variabili, +le funzioni o i tipi) senza dover fare importanti modifiche sintattiche al +linguaggio stesso (come l'aggiunta di nuove parole chiave) [it-n2049]_. + +In alcuni casi, gli attributi sono opzionali (ovvero un compilatore che non +dovesse supportarli dovrebbe produrre comunque codice corretto, anche se +più lento o che non esegue controlli aggiuntivi durante la compilazione). + +Il kernel definisce alcune pseudo parole chiave (per esempio ``__pure``) +in alternativa alla sintassi GNU per gli attributi (per esempio +``__attribute__((__pure__))``) allo scopo di mostrare quali funzionalità si +possono usare e/o per accorciare il codice. + +Per maggiori informazioni consultate il file d'intestazione +``include/linux/compiler_attributes.h``. + +Rust +---- + +Il kernel supporta sperimentalmente il linguaggio di programmazione Rust +[it-rust-language]_ abilitando l'opzione di configurazione ``CONFIG_RUST``. Il +codice verrà compilato usando ``rustc`` [it-rustc]_ con l'opzione +``--edition=2021`` [it-rust-editions]_. Le edizioni Rust sono un modo per +introdurre piccole modifiche senza compatibilità all'indietro._ + +In aggiunta, nel kernel vengono utilizzate alcune funzionalità considerate +instabili [it-rust-unstable-features]_. Queste funzionalità potrebbero cambiare +in futuro, dunque è un'obiettivo importante è quello di far uso solo di +funzionalità stabili. + +Per maggiori informazioni fate riferimento a Documentation/rust/index.rst . + +.. [it-c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards +.. [it-gcc] https://gcc.gnu.org +.. [it-clang] https://clang.llvm.org +.. [it-gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html +.. [it-gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html +.. [it-gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html +.. [it-n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf +.. [it-rust-language] https://www.rust-lang.org +.. [it-rustc] https://doc.rust-lang.org/rustc/ +.. [it-rust-editions] https://doc.rust-lang.org/edition-guide/editions/ +.. [it-rust-unstable-features] https://github.com/Rust-for-Linux/linux/issues/2 diff --git a/Documentation/translations/it_IT/process/stable-api-nonsense.rst b/Documentation/translations/it_IT/process/stable-api-nonsense.rst new file mode 100644 index 0000000000..cdfc509b85 --- /dev/null +++ b/Documentation/translations/it_IT/process/stable-api-nonsense.rst @@ -0,0 +1,209 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/stable-api-nonsense.rst <stable_api_nonsense>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_stable_api_nonsense: + +L'interfaccia dei driver per il kernel Linux +============================================ + +(tutte le risposte alle vostre domande e altro) + +Greg Kroah-Hartman <greg@kroah.com> + +Questo è stato scritto per cercare di spiegare perché Linux **non ha +un'interfaccia binaria, e non ha nemmeno un'interfaccia stabile**. + +.. note:: + + Questo articolo parla di interfacce **interne al kernel**, non delle + interfacce verso lo spazio utente. + + L'interfaccia del kernel verso lo spazio utente è quella usata dai + programmi, ovvero le chiamate di sistema. Queste interfacce sono **molto** + stabili nel tempo e non verranno modificate. Ho vecchi programmi che sono + stati compilati su un kernel 0.9 (circa) e tuttora funzionano sulle versioni + 2.6 del kernel. Queste interfacce sono quelle che gli utenti e i + programmatori possono considerare stabili. + +Riepilogo generale +------------------ + +Pensate di volere un'interfaccia del kernel stabile, ma in realtà non la +volete, e nemmeno sapete di non volerla. Quello che volete è un driver +stabile che funzioni, e questo può essere ottenuto solo se il driver si trova +nei sorgenti del kernel. Ci sono altri vantaggi nell'avere il proprio driver +nei sorgenti del kernel, ognuno dei quali hanno reso Linux un sistema operativo +robusto, stabile e maturo; questi sono anche i motivi per cui avete scelto +Linux. + +Introduzione +------------ + +Solo le persone un po' strambe vorrebbero scrivere driver per il kernel con +la costante preoccupazione per i cambiamenti alle interfacce interne. Per il +resto del mondo, queste interfacce sono invisibili o non di particolare +interesse. + +Innanzitutto, non tratterò **alcun** problema legale riguardante codice +chiuso, nascosto, avvolto, blocchi binari, o qualsia altra cosa che descrive +driver che non hanno i propri sorgenti rilasciati con licenza GPL. Per favore +fate riferimento ad un avvocato per qualsiasi questione legale, io sono un +programmatore e perciò qui vi parlerò soltanto delle questioni tecniche (non +per essere superficiali sui problemi legali, sono veri e dovete esserne a +conoscenza in ogni circostanza). + +Dunque, ci sono due tematiche principali: interfacce binarie del kernel e +interfacce stabili nei sorgenti. Ognuna dipende dall'altra, ma discuteremo +prima delle cose binarie per toglierle di mezzo. + +Interfaccia binaria del kernel +------------------------------ + +Supponiamo d'avere un'interfaccia stabile nei sorgenti del kernel, di +conseguenza un'interfaccia binaria dovrebbe essere anche'essa stabile, giusto? +Sbagliato. Prendete in considerazione i seguenti fatti che riguardano il +kernel Linux: + + - A seconda della versione del compilatore C che state utilizzando, diverse + strutture dati del kernel avranno un allineamento diverso, e possibilmente + un modo diverso di includere le funzioni (renderle inline oppure no). + L'organizzazione delle singole funzioni non è poi così importante, ma la + spaziatura (*padding*) nelle strutture dati, invece, lo è. + + - In base alle opzioni che sono state selezionate per generare il kernel, + un certo numero di cose potrebbero succedere: + + - strutture dati differenti potrebbero contenere campi differenti + - alcune funzioni potrebbero non essere implementate (per esempio, + alcuni *lock* spariscono se compilati su sistemi mono-processore) + - la memoria interna del kernel può essere allineata in differenti modi + a seconda delle opzioni di compilazione. + + - Linux funziona su una vasta gamma di architetture di processore. Non esiste + alcuna possibilità che il binario di un driver per un'architettura funzioni + correttamente su un'altra. + +Alcuni di questi problemi possono essere risolti compilando il proprio modulo +con la stessa identica configurazione del kernel, ed usando la stessa versione +del compilatore usato per compilare il kernel. Questo è sufficiente se volete +fornire un modulo per uno specifico rilascio su una specifica distribuzione +Linux. Ma moltiplicate questa singola compilazione per il numero di +distribuzioni Linux e il numero dei rilasci supportati da quest'ultime e vi +troverete rapidamente in un incubo fatto di configurazioni e piattaforme +hardware (differenti processori con differenti opzioni); dunque, anche per il +singolo rilascio di un modulo, dovreste creare differenti versioni dello +stesso. + +Fidatevi, se tenterete questa via, col tempo, diventerete pazzi; l'ho imparato +a mie spese molto tempo fa... + + +Interfaccia stabile nei sorgenti del kernel +------------------------------------------- + +Se parlate con le persone che cercano di mantenere aggiornato un driver per +Linux ma che non si trova nei sorgenti, allora per queste persone l'argomento +sarà "ostico". + +Lo sviluppo del kernel Linux è continuo e viaggia ad un ritmo sostenuto, e non +rallenta mai. Perciò, gli sviluppatori del kernel trovano bachi nelle +interfacce attuali, o trovano modi migliori per fare le cose. Se le trovano, +allora le correggeranno per migliorarle. In questo frangente, i nomi delle +funzioni potrebbero cambiare, le strutture dati potrebbero diventare più grandi +o più piccole, e gli argomenti delle funzioni potrebbero essere ripensati. +Se questo dovesse succedere, nello stesso momento, tutte le istanze dove questa +interfaccia viene utilizzata verranno corrette, garantendo che tutto continui +a funzionare senza problemi. + +Portiamo ad esempio l'interfaccia interna per il sottosistema USB che ha subito +tre ristrutturazioni nel corso della sua vita. Queste ristrutturazioni furono +fatte per risolvere diversi problemi: + + - È stato fatto un cambiamento da un flusso di dati sincrono ad uno + asincrono. Questo ha ridotto la complessità di molti driver e ha + aumentato la capacità di trasmissione di tutti i driver fino a raggiungere + quasi la velocità massima possibile. + - È stato fatto un cambiamento nell'allocazione dei pacchetti da parte del + sottosistema USB per conto dei driver, cosicché ora i driver devono fornire + più informazioni al sottosistema USB al fine di correggere un certo numero + di stalli. + +Questo è completamente l'opposto di quello che succede in alcuni sistemi +operativi proprietari che hanno dovuto mantenere, nel tempo, il supporto alle +vecchie interfacce USB. I nuovi sviluppatori potrebbero usare accidentalmente +le vecchie interfacce e sviluppare codice nel modo sbagliato, portando, di +conseguenza, all'instabilità del sistema. + +In entrambe gli scenari, gli sviluppatori hanno ritenuto che queste importanti +modifiche erano necessarie, e quindi le hanno fatte con qualche sofferenza. +Se Linux avesse assicurato di mantenere stabile l'interfaccia interna, si +sarebbe dovuto procedere alla creazione di una nuova, e quelle vecchie, e +mal funzionanti, avrebbero dovuto ricevere manutenzione, creando lavoro +aggiuntivo per gli sviluppatori del sottosistema USB. Dato che gli +sviluppatori devono dedicare il proprio tempo a questo genere di lavoro, +chiedergli di dedicarne dell'altro, senza benefici, magari gratuitamente, non +è contemplabile. + +Le problematiche relative alla sicurezza sono molto importanti per Linux. +Quando viene trovato un problema di sicurezza viene corretto in breve tempo. +A volte, per prevenire il problema di sicurezza, si sono dovute cambiare +delle interfacce interne al kernel. Quando è successo, allo stesso tempo, +tutti i driver che usavano quelle interfacce sono stati aggiornati, garantendo +la correzione definitiva del problema senza doversi preoccupare di rivederlo +per sbaglio in futuro. Se non si fossero cambiate le interfacce interne, +sarebbe stato impossibile correggere il problema e garantire che non si sarebbe +più ripetuto. + +Nel tempo le interfacce del kernel subiscono qualche ripulita. Se nessuno +sta più usando un'interfaccia, allora questa verrà rimossa. Questo permette +al kernel di rimanere il più piccolo possibile, e garantisce che tutte le +potenziali interfacce sono state verificate nel limite del possibile (le +interfacce inutilizzate sono impossibili da verificare). + + +Cosa fare +--------- + +Dunque, se avete un driver per il kernel Linux che non si trova nei sorgenti +principali del kernel, come sviluppatori, cosa dovreste fare? Rilasciare un +file binario del driver per ogni versione del kernel e per ogni distribuzione, +è un incubo; inoltre, tenere il passo con tutti i cambiamenti del kernel è un +brutto lavoro. + +Semplicemente, fate sì che il vostro driver per il kernel venga incluso nei +sorgenti principali (ricordatevi, stiamo parlando di driver rilasciati secondo +una licenza compatibile con la GPL; se il vostro codice non ricade in questa +categoria: buona fortuna, arrangiatevi, siete delle sanguisughe) + +Se il vostro driver è nei sorgenti del kernel e un'interfaccia cambia, il +driver verrà corretto immediatamente dalla persona che l'ha modificata. Questo +garantisce che sia sempre possibile compilare il driver, che funzioni, e tutto +con un minimo sforzo da parte vostra. + +Avere il proprio driver nei sorgenti principali del kernel ha i seguenti +vantaggi: + + - La qualità del driver aumenterà e i costi di manutenzione (per lo + sviluppatore originale) diminuiranno. + - Altri sviluppatori aggiungeranno nuove funzionalità al vostro driver. + - Altri persone troveranno e correggeranno bachi nel vostro driver. + - Altri persone troveranno degli aggiustamenti da fare al vostro driver. + - Altri persone aggiorneranno il driver quando è richiesto da un cambiamento + di un'interfaccia. + - Il driver sarà automaticamente reso disponibile in tutte le distribuzioni + Linux senza dover chiedere a nessuna di queste di aggiungerlo. + +Dato che Linux supporta più dispositivi di qualsiasi altro sistema operativo, +e che girano su molti più tipi di processori di qualsiasi altro sistema +operativo; ciò dimostra che questo modello di sviluppo qualcosa di giusto, +dopo tutto, lo fa :) + + + +------ + +Dei ringraziamenti vanno a Randy Dunlap, Andrew Morton, David Brownell, +Hanna Linder, Robert Love, e Nishanth Aravamudan per la loro revisione +e per i loro commenti sulle prime bozze di questo articolo. diff --git a/Documentation/translations/it_IT/process/stable-kernel-rules.rst b/Documentation/translations/it_IT/process/stable-kernel-rules.rst new file mode 100644 index 0000000000..248bf1e4b1 --- /dev/null +++ b/Documentation/translations/it_IT/process/stable-kernel-rules.rst @@ -0,0 +1,222 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_stable_kernel_rules: + +Tutto quello che volevate sapere sui rilasci -stable di Linux +============================================================== + +Regole sul tipo di patch che vengono o non vengono accettate nei sorgenti +"-stable": + + - Ovviamente dev'essere corretta e verificata. + - Non dev'essere più grande di 100 righe, incluso il contesto. + - Deve correggere una cosa sola. + - Deve correggere un baco vero che sta disturbando gli utenti (non cose del + tipo "Questo potrebbe essere un problema ..."). + - Deve correggere un problema di compilazione (ma non per cose già segnate + con CONFIG_BROKEN), un kernel oops, un blocco, una corruzione di dati, + un vero problema di sicurezza, o problemi del tipo "oh, questo non va bene". + In pratica, qualcosa di critico. + - Problemi importanti riportati dagli utenti di una distribuzione potrebbero + essere considerati se correggono importanti problemi di prestazioni o di + interattività. Dato che questi problemi non sono così ovvi e la loro + correzione ha un'alta probabilità d'introdurre una regressione, dovrebbero + essere sottomessi solo dal manutentore della distribuzione includendo un + link, se esiste, ad un rapporto su bugzilla, e informazioni aggiuntive + sull'impatto che ha sugli utenti. + - Non deve correggere problemi relativi a una "teorica sezione critica", + a meno che non venga fornita anche una spiegazione su come questa si + possa verificare. + - Non deve includere alcuna correzione "banale" (correzioni grammaticali, + pulizia dagli spazi bianchi, eccetera). + - Deve rispettare le regole scritte in + :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>` + - Questa patch o una equivalente deve esistere già nei sorgenti principali di + Linux + + +Procedura per sottomettere patch per i sorgenti -stable +------------------------------------------------------- + +.. note:: + Una patch di sicurezza non dovrebbe essere gestita (solamente) dal processo + di revisione -stable, ma dovrebbe seguire le procedure descritte in + :ref:`Documentation/translations/it_IT/admin-guide/security-bugs.rst <it_securitybugs>`. + +Per tutte le altre sottomissioni, scegliere una delle seguenti procedure +------------------------------------------------------------------------ + +.. _it_option_1: + +Opzione 1 +********* + +Per far sì che una patch venga automaticamente inclusa nei sorgenti stabili, +aggiungete l'etichetta + +.. code-block:: none + + Cc: stable@vger.kernel.org + +nell'area dedicata alla firme. Una volta che la patch è stata inclusa, verrà +applicata anche sui sorgenti stabili senza che l'autore o il manutentore +del sottosistema debba fare qualcosa. + +.. _it_option_2: + +Opzione 2 +********* + +Dopo che la patch è stata inclusa nei sorgenti Linux, inviate una mail a +stable@vger.kernel.org includendo: il titolo della patch, l'identificativo +del commit, il perché pensate che debba essere applicata, e in quale versione +del kernel la vorreste vedere. + +.. _it_option_3: + +Opzione 3 +********* + +Inviata la patch, dopo aver verificato che rispetta le regole descritte in +precedenza, a stable@vger.kernel.org. Dovete annotare nel changelog +l'identificativo del commit nei sorgenti principali, così come la versione +del kernel nel quale vorreste vedere la patch. + +L':ref:`it_option_1` è fortemente raccomandata; è il modo più facile e usato. +L':ref:`it_option_2` e l':ref:`it_option_3` sono più utili quando, al momento +dell'inclusione dei sorgenti principali, si ritiene che non debbano essere +incluse anche in quelli stabili (per esempio, perché si crede che si dovrebbero +fare più verifiche per eventuali regressioni). L':ref:`it_option_3` è +particolarmente utile se una patch dev'essere riportata su una versione +precedente (per esempio la patch richiede modifiche a causa di cambiamenti di +API). + +Notate che per l':ref:`it_option_3`, se la patch è diversa da quella nei +sorgenti principali (per esempio perché è stato necessario un lavoro di +adattamento) allora dev'essere ben documentata e giustificata nella descrizione +della patch. + +L'identificativo del commit nei sorgenti principali dev'essere indicato sopra +al messaggio della patch, così: + +.. code-block:: none + + commit <sha1> upstream. + +o in alternativa: + +.. code-block:: none + + [ Upstream commit <sha1> ] + +In aggiunta, alcune patch inviate attraverso l':ref:`it_option_1` potrebbero +dipendere da altre che devo essere incluse. Questa situazione può essere +indicata nel seguente modo nell'area dedicata alle firme: + +.. code-block:: none + + Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle + Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle + Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic + Cc: <stable@vger.kernel.org> # 3.3.x + Signed-off-by: Ingo Molnar <mingo@elte.hu> + +La sequenza di etichette ha il seguente significato: + +.. code-block:: none + + git cherry-pick a1f84a3 + git cherry-pick 1b9508f + git cherry-pick fd21073 + git cherry-pick <this commit> + +Inoltre, alcune patch potrebbero avere dei requisiti circa la versione del +kernel. Questo può essere indicato usando il seguente formato nell'area +dedicata alle firme: + +.. code-block:: none + + Cc: <stable@vger.kernel.org> # 3.3.x + +L'etichetta ha il seguente significato: + +.. code-block:: none + + git cherry-pick <this commit> + +per ogni sorgente "-stable" che inizia con la versione indicata. + +Dopo la sottomissione: + + - Il mittente riceverà un ACK quando la patch è stata accettata e messa in + coda, oppure un NAK se la patch è stata rigettata. A seconda degli impegni + degli sviluppatori, questa risposta potrebbe richiedere alcuni giorni. + - Se accettata, la patch verrà aggiunta alla coda -stable per essere + revisionata dal altri sviluppatori e dal principale manutentore del + sottosistema. + + +Ciclo di una revisione +---------------------- + + - Quando i manutentori -stable decidono di fare un ciclo di revisione, le + patch vengono mandate al comitato per la revisione, ai manutentori soggetti + alle modifiche delle patch (a meno che il mittente non sia anche il + manutentore di quell'area del kernel) e in CC: alla lista di discussione + linux-kernel. + - La commissione per la revisione ha 48 ore per dare il proprio ACK o NACK + alle patch. + - Se una patch viene rigettata da un membro della commissione, o un membro + della lista linux-kernel obietta la bontà della patch, sollevando problemi + che i manutentori ed i membri non avevano compreso, allora la patch verrà + rimossa dalla coda. + - Le patch che hanno ricevuto un ACK verranno inviate nuovamente come parte di + un rilascio candidato (-rc) al fine di essere verificate dagli sviluppatori e + dai testatori. + - Solitamente si pubblica solo una -rc, tuttavia se si riscontrano problemi + importanti, alcune patch potrebbero essere modificate o essere scartate, + oppure nuove patch potrebbero essere messe in coda. Dunque, verranno pubblicate + nuove -rc e così via finché non si ritiene che non vi siano più problemi. + - Si può rispondere ad una -rc scrivendo sulla lista di discussione un'email + con l'etichetta "Tested-by:". Questa etichetta verrà raccolta ed aggiunta al + commit rilascio. + - Alla fine del ciclo di revisione il nuovo rilascio -stable conterrà tutte le + patch che erano in coda e sono state verificate. + - Le patch di sicurezza verranno accettate nei sorgenti -stable direttamente + dalla squadra per la sicurezza del kernel, e non passerà per il normale + ciclo di revisione. Contattate la suddetta squadra per maggiori dettagli + su questa procedura. + +Sorgenti +-------- + + - La coda delle patch, sia quelle già applicate che in fase di revisione, + possono essere trovate al seguente indirizzo: + + https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git + + - Il rilascio definitivo, e marchiato, di tutti i kernel stabili può essere + trovato in rami distinti per versione al seguente indirizzo: + + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git + + - I rilasci candidati di tutti i kernel stabili possono essere trovati al + seguente indirizzo: + + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/ + + + .. warning:: + I sorgenti -stable-rc sono un'istantanea dei sorgenti stable-queue e + subirà frequenti modifiche, dunque verrà anche trapiantato spesso. + Dovrebbe essere usato solo allo scopo di verifica (per esempio in un + sistema di CI) + +Comitato per la revisione +------------------------- + + - Questo comitato è fatto di sviluppatori del kernel che si sono offerti + volontari per questo lavoro, e pochi altri che non sono proprio volontari. diff --git a/Documentation/translations/it_IT/process/submit-checklist.rst b/Documentation/translations/it_IT/process/submit-checklist.rst new file mode 100644 index 0000000000..2fc09cc1f0 --- /dev/null +++ b/Documentation/translations/it_IT/process/submit-checklist.rst @@ -0,0 +1,132 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/submit-checklist.rst <submitchecklist>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_submitchecklist: + +Lista delle verifiche da fare prima di inviare una patch per il kernel Linux +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Qui troverete una lista di cose che uno sviluppatore dovrebbe fare per +vedere le proprie patch accettate più rapidamente. + +Tutti questi punti integrano la documentazione fornita riguardo alla +sottomissione delle patch, in particolare +:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`. + +1) Se state usando delle funzionalità del kernel allora includete (#include) + i file che le dichiarano/definiscono. Non dipendente dal fatto che un file + d'intestazione include anche quelli usati da voi. + +2) Compilazione pulita: + + a) con le opzioni ``CONFIG`` negli stati ``=y``, ``=m`` e ``=n``. Nessun + avviso/errore di ``gcc`` e nessun avviso/errore dal linker. + + b) con ``allnoconfig``, ``allmodconfig`` + + c) quando si usa ``O=builddir`` + + d) Qualsiasi modifica in Documentation/ deve compilare con successo senza + avvisi o errori. Usare ``make htmldocs`` o ``make pdfdocs`` per verificare + e correggere i problemi + +3) Compilare per diverse architetture di processore usando strumenti per + la cross-compilazione o altri. + +4) Una buona architettura per la verifica della cross-compilazione è la ppc64 + perché tende ad usare ``unsigned long`` per le quantità a 64-bit. + +5) Controllate lo stile del codice della vostra patch secondo le direttive + scritte in :ref:`Documentation/translations/it_IT/process/coding-style.rst <it_codingstyle>`. + Prima dell'invio della patch, usate il verificatore di stile + (``script/checkpatch.pl``) per scovare le violazioni più semplici. + Dovreste essere in grado di giustificare tutte le violazioni rimanenti nella + vostra patch. + +6) Le opzioni ``CONFIG``, nuove o modificate, non scombussolano il menu + di configurazione e sono preimpostate come disabilitate a meno che non + soddisfino i criteri descritti in ``Documentation/kbuild/kconfig-language.rst`` + alla punto "Voci di menu: valori predefiniti". + +7) Tutte le nuove opzioni ``Kconfig`` hanno un messaggio di aiuto. + +8) La patch è stata accuratamente revisionata rispetto alle più importanti + configurazioni ``Kconfig``. Questo è molto difficile da fare + correttamente - un buono lavoro di testa sarà utile. + +9) Verificare con sparse. + +10) Usare ``make checkstack`` e correggere tutti i problemi rilevati. + + .. note:: + + ``checkstack`` non evidenzia esplicitamente i problemi, ma una funzione + che usa più di 512 byte sullo stack è una buona candidata per una + correzione. + +11) Includete commenti :ref:`kernel-doc <kernel_doc>` per documentare API + globali del kernel. Usate ``make htmldocs`` o ``make pdfdocs`` per + verificare i commenti :ref:`kernel-doc <kernel_doc>` ed eventualmente + correggerli. + +12) La patch è stata verificata con le seguenti opzioni abilitate + contemporaneamente: ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``, + ``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``, + ``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``, + ``CONFIG_PROVE_RCU`` e ``CONFIG_DEBUG_OBJECTS_RCU_HEAD``. + +13) La patch è stata compilata e verificata in esecuzione con, e senza, + le opzioni ``CONFIG_SMP`` e ``CONFIG_PREEMPT``. + +14) Se la patch ha effetti sull'IO dei dischi, eccetera: allora dev'essere + verificata con, e senza, l'opzione ``CONFIG_LBDAF``. + +15) Tutti i percorsi del codice sono stati verificati con tutte le funzionalità + di lockdep abilitate. + +16) Tutti i nuovi elementi in ``/proc`` sono documentati in ``Documentation/``. + +17) Tutti i nuovi parametri d'avvio del kernel sono documentati in + ``Documentation/admin-guide/kernel-parameters.rst``. + +18) Tutti i nuovi parametri dei moduli sono documentati con ``MODULE_PARM_DESC()``. + +19) Tutte le nuove interfacce verso lo spazio utente sono documentate in + ``Documentation/ABI/``. Leggete ``Documentation/ABI/README`` per maggiori + informazioni. Le patch che modificano le interfacce utente dovrebbero + essere inviate in copia anche a linux-api@vger.kernel.org. + +20) La patch è stata verificata con l'iniezione di fallimenti in slab e + nell'allocazione di pagine. Vedere ``Documentation/fault-injection/``. + + Se il nuovo codice è corposo, potrebbe essere opportuno aggiungere + l'iniezione di fallimenti specifici per il sottosistema. + +21) Il nuovo codice è stato compilato con ``gcc -W`` (usate + ``make KCFLAGS=-W``). Questo genererà molti avvisi, ma è ottimo + per scovare bachi come "warning: comparison between signed and unsigned". + +22) La patch è stata verificata dopo essere stata inclusa nella serie di patch + -mm; questo al fine di assicurarsi che continui a funzionare assieme a + tutte le altre patch in coda e i vari cambiamenti nei sottosistemi VM, VFS + e altri. + +23) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``, + ``rmb()``, ``wmb()``} devono essere accompagnate da un commento nei + sorgenti che ne spieghi la logica: cosa fanno e perché. + +24) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate + ``Documentation/userspace-api/ioctl/ioctl-number.rst``. + +25) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o + funzionalità del kernel che è associata a uno dei seguenti simboli + ``Kconfig``, allora verificate che il kernel compili con diverse + configurazioni dove i simboli sono disabilitati e/o ``=m`` (se c'è la + possibilità) [non tutti contemporaneamente, solo diverse combinazioni + casuali]: + + ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, + ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``, + ``CONFIG_NET``, ``CONFIG_INET=n`` (ma l'ultimo con ``CONFIG_NET=y``). diff --git a/Documentation/translations/it_IT/process/submitting-patches.rst b/Documentation/translations/it_IT/process/submitting-patches.rst new file mode 100644 index 0000000000..f91c809284 --- /dev/null +++ b/Documentation/translations/it_IT/process/submitting-patches.rst @@ -0,0 +1,817 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_submittingpatches: + +Inviare patch: la guida essenziale per vedere il vostro codice nel kernel +========================================================================= + +Una persona o un'azienda che volesse inviare una patch al kernel potrebbe +sentirsi scoraggiata dal processo di sottomissione, specialmente quando manca +una certa familiarità col "sistema". Questo testo è una raccolta di +suggerimenti che aumenteranno significativamente le probabilità di vedere le +vostre patch accettate. + +Questo documento contiene un vasto numero di suggerimenti concisi. Per maggiori +dettagli su come funziona il processo di sviluppo del kernel leggete +Documentation/translations/it_IT/process/development-process.rst. Leggete anche +Documentation/translations/it_IT/process/submit-checklist.rst per una lista di +punti da verificare prima di inviare del codice. +Per delle patch relative alle associazioni per Device Tree leggete +Documentation/translations/it_IT/process/submitting-patches.rst. + +Questa documentazione assume che sappiate usare ``git`` per preparare le patch. +Se non siete pratici di ``git``, allora è bene che lo impariate; +renderà la vostra vita di sviluppatore del kernel molto più semplice. + +I sorgenti di alcuni sottosistemi e manutentori contengono più informazioni +riguardo al loro modo di lavorare ed aspettative. Consultate +:ref:`Documentation/translations/it_IT/process/maintainer-handbooks.rst <it_maintainer_handbooks_main>` + +Ottenere i sorgenti attuali +--------------------------- + +Se non avete un repositorio coi sorgenti del kernel più recenti, allora usate +``git`` per ottenerli. Vorrete iniziare col repositorio principale che può +essere recuperato col comando:: + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + +Notate, comunque, che potreste non voler sviluppare direttamente coi sorgenti +principali del kernel. La maggior parte dei manutentori hanno i propri +sorgenti e desiderano che le patch siano preparate basandosi su di essi. +Guardate l'elemento **T:** per un determinato sottosistema nel file MAINTANERS +che troverete nei sorgenti, o semplicemente chiedete al manutentore nel caso +in cui i sorgenti da usare non siano elencati il quel file. + +.. _it_describe_changes: + +Descrivete le vostre modifiche +------------------------------ + +Descrivete il vostro problema. Esiste sempre un problema che via ha spinto +ha fare il vostro lavoro, che sia la correzione di un baco da una riga o una +nuova funzionalità da 5000 righe di codice. Convincete i revisori che vale +la pena risolvere il vostro problema e che ha senso continuare a leggere oltre +al primo paragrafo. + +Descrivete ciò che sarà visibile agli utenti. Chiari incidenti nel sistema +e blocchi sono abbastanza convincenti, ma non tutti i bachi sono così evidenti. +Anche se il problema è stato scoperto durante la revisione del codice, +descrivete l'impatto che questo avrà sugli utenti. Tenete presente che +la maggior parte delle installazioni Linux usa un kernel che arriva dai +sorgenti stabili o dai sorgenti di una distribuzione particolare che prende +singolarmente le patch dai sorgenti principali; quindi, includete tutte +le informazioni che possono essere utili a capire le vostre modifiche: +le circostanze che causano il problema, estratti da dmesg, descrizioni di +un incidente di sistema, prestazioni di una regressione, picchi di latenza, +blocchi, eccetera. + +Quantificare le ottimizzazioni e i compromessi. Se affermate di aver +migliorato le prestazioni, il consumo di memoria, l'impatto sollo stack, +o la dimensione del file binario, includete dei numeri a supporto della +vostra dichiarazione. Ma ricordatevi di descrivere anche eventuali costi +che non sono ovvi. Solitamente le ottimizzazioni non sono gratuite, ma sono +un compromesso fra l'uso di CPU, la memoria e la leggibilità; o, quando si +parla di ipotesi euristiche, fra differenti carichi. Descrivete i lati +negativi che vi aspettate dall'ottimizzazione cosicché i revisori possano +valutare i costi e i benefici. + +Una volta che il problema è chiaro, descrivete come lo risolvete andando +nel dettaglio tecnico. È molto importante che descriviate la modifica +in un inglese semplice cosicché i revisori possano verificare che il codice si +comporti come descritto. + +I manutentori vi saranno grati se scrivete la descrizione della patch in un +formato che sia compatibile con il gestore dei sorgenti usato dal kernel, +``git``, come un "commit log". Leggete :ref:`it_the_canonical_patch_format`. + +Risolvete solo un problema per patch. Se la vostra descrizione inizia ad +essere lunga, potrebbe essere un segno che la vostra patch necessita d'essere +divisa. Leggete :ref:`it_split_changes`. + +Quando inviate o rinviate una patch o una serie, includete la descrizione +completa delle modifiche e la loro giustificazione. Non limitatevi a dire che +questa è la versione N della patch (o serie). Non aspettatevi che i +manutentori di un sottosistema vadano a cercare le versioni precedenti per +cercare la descrizione da aggiungere. In pratica, la patch (o serie) e la sua +descrizione devono essere un'unica cosa. Questo aiuta i manutentori e i +revisori. Probabilmente, alcuni revisori non hanno nemmeno ricevuto o visto +le versioni precedenti della patch. + +Descrivete le vostro modifiche usando l'imperativo, per esempio "make xyzzy +do frotz" piuttosto che "[This patch] makes xyzzy do frotz" or "[I] changed +xyzzy to do frotz", come se steste dando ordini al codice di cambiare il suo +comportamento. + +Se ci sono delle discussioni, o altre informazioni d'interesse, che fanno +riferimento alla patch, allora aggiungete l'etichetta 'Link:' per farvi +riferimento. Per esempio, se la vostra patch corregge un baco potete aggiungere +quest'etichetta per fare riferimento ad un rapporto su una lista di discussione +o un *bug tracker*. Un altro esempio; potete usare quest'etichetta per far +riferimento ad una discussione precedentemente avvenuta su una lista di +discussione, o qualcosa di documentato sul web, da cui poi è nata la patch in +questione. + +Quando volete fare riferimento ad una lista di discussione, preferite il +servizio d'archiviazione lore.kernel.org. Per create un collegamento URL è +sufficiente usare il campo ``Message-Id``, presente nell'intestazione del +messaggio, senza parentesi angolari. Per esempio:: + + Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/ + +Prima d'inviare il messaggio ricordatevi di verificare che il collegamento così +creato funzioni e che indirizzi verso il messaggio desiderato. + +Tuttavia, provate comunque a dare una spiegazione comprensibile anche senza +accedere alle fonti esterne. Inoltre, riassumente i punti più salienti che hanno +condotto all'invio della patch. + +Se volete far riferimento a uno specifico commit, non usate solo +l'identificativo SHA-1. Per cortesia, aggiungete anche la breve riga +riassuntiva del commit per rendere la chiaro ai revisori l'oggetto. +Per esempio:: + + Commit e21d2170f36602ae2708 ("video: remove unnecessary + platform_set_drvdata()") removed the unnecessary + platform_set_drvdata(), but left the variable "dev" unused, + delete it. + +Dovreste anche assicurarvi di usare almeno i primi 12 caratteri +dell'identificativo SHA-1. Il repositorio del kernel ha *molti* oggetti e +questo rende possibile la collisione fra due identificativi con pochi +caratteri. Tenete ben presente che anche se oggi non ci sono collisioni con il +vostro identificativo a 6 caratteri, potrebbero essercene fra 5 anni da oggi. + +Se la vostra patch corregge un baco in un commit specifico, per esempio avete +trovato un problema usando ``git bisect``, per favore usate l'etichetta +'Fixes:' indicando i primi 12 caratteri dell'identificativo SHA-1 seguiti +dalla riga riassuntiva. Per esempio:: + + Fixes: e21d2170f366 ("video: remove unnecessary platform_set_drvdata()") + +La seguente configurazione di ``git config`` può essere usata per formattare +i risultati dei comandi ``git log`` o ``git show`` come nell'esempio +precedente:: + + [core] + abbrev = 12 + [pretty] + fixes = Fixes: %h (\"%s\") + +Un esempio:: + + $ git log -1 --pretty=fixes 54a4f0239f2e + Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed") + +.. _it_split_changes: + +Separate le vostre modifiche +---------------------------- + +Separate ogni **cambiamento logico** in patch distinte. + +Per esempio, se i vostri cambiamenti per un singolo driver includono +sia delle correzioni di bachi che miglioramenti alle prestazioni, +allora separateli in due o più patch. Se i vostri cambiamenti includono +un aggiornamento dell'API e un nuovo driver che lo sfrutta, allora separateli +in due patch. + +D'altro canto, se fate una singola modifica su più file, raggruppate tutte +queste modifiche in una singola patch. Dunque, un singolo cambiamento logico +è contenuto in una sola patch. + +Il punto da ricordare è che ogni modifica dovrebbe fare delle modifiche +che siano facilmente comprensibili e che possano essere verificate dai revisori. +Ogni patch dovrebbe essere giustificabile di per sé. + +Se al fine di ottenere un cambiamento completo una patch dipende da un'altra, +va bene. Semplicemente scrivete una nota nella descrizione della patch per +farlo presente: **"this patch depends on patch X"**. + +Quando dividete i vostri cambiamenti in una serie di patch, prestate +particolare attenzione alla verifica di ogni patch della serie; per ognuna +il kernel deve compilare ed essere eseguito correttamente. Gli sviluppatori +che usano ``git bisect`` per scovare i problemi potrebbero finire nel mezzo +della vostra serie in un punto qualsiasi; non vi saranno grati se nel mezzo +avete introdotto dei bachi. + +Se non potete condensare la vostra serie di patch in una più piccola, allora +pubblicatene una quindicina alla volta e aspettate che vengano revisionate +ed integrate. + + +4) Verificate lo stile delle vostre modifiche +--------------------------------------------- + +Controllate che la vostra patch non violi lo stile del codice, maggiori +dettagli sono disponibili in Documentation/translations/it_IT/process/coding-style.rst. +Non farlo porta semplicemente a una perdita di tempo da parte dei revisori e +voi vedrete la vostra patch rifiutata, probabilmente senza nemmeno essere stata +letta. + +Un'eccezione importante si ha quando del codice viene spostato da un file +ad un altro -- in questo caso non dovreste modificare il codice spostato +per nessun motivo, almeno non nella patch che lo sposta. Questo separa +chiaramente l'azione di spostare il codice e il vostro cambiamento. +Questo aiuta enormemente la revisione delle vere differenze e permette agli +strumenti di tenere meglio la traccia della storia del codice. + +Prima di inviare una patch, verificatene lo stile usando l'apposito +verificatore (scripts/checkpatch.pl). Da notare, comunque, che il verificator +di stile dovrebbe essere visto come una guida, non come un sostituto al +giudizio umano. Se il vostro codice è migliore nonostante una violazione +dello stile, probabilmente è meglio lasciarlo com'è. + +Il verificatore ha tre diversi livelli di severità: + - ERROR: le cose sono molto probabilmente sbagliate + - WARNING: le cose necessitano d'essere revisionate con attenzione + - CHECK: le cose necessitano di un pensierino + +Dovreste essere in grado di giustificare tutte le eventuali violazioni rimaste +nella vostra patch. + + +5) Selezionate i destinatari della vostra patch +----------------------------------------------- + +Dovreste sempre inviare una copia della patch ai manutentori dei sottosistemi +interessati dalle modifiche; date un'occhiata al file MAINTAINERS e alla storia +delle revisioni per scoprire chi si occupa del codice. Lo script +scripts/get_maintainer.pl può esservi d'aiuto (passategli il percorso alle +vostre patch). Se non riuscite a trovare un manutentore per il sottosistema su +cui state lavorando, allora Andrew Morton (akpm@linux-foundation.org) sarà la +vostra ultima possibilità. + +Normalmente, dovreste anche scegliere una lista di discussione a cui inviare la +vostra serie di patch. La lista di discussione linux-kernel@vger.kernel.org +dovrebbe essere usata per inviare tutte le patch, ma il traffico è tale per cui +diversi sviluppatori la trascurano. Guardate nel file MAINTAINERS per trovare la +lista di discussione dedicata ad un sottosistema; probabilmente lì la vostra +patch riceverà molta più attenzione. Tuttavia, per favore, non spammate le liste +di discussione che non sono interessate al vostro lavoro. + +Molte delle liste di discussione relative al kernel vengono ospitate su +vger.kernel.org; potete trovare un loro elenco alla pagina +http://vger.kernel.org/vger-lists.html. Tuttavia, ci sono altre liste di +discussione ospitate altrove. + +Non inviate più di 15 patch alla volta sulle liste di discussione vger!!! + +L'ultimo giudizio sull'integrazione delle modifiche accettate spetta a +Linux Torvalds. Il suo indirizzo e-mail è <torvalds@linux-foundation.org>. +Riceve moltissime e-mail, e, a questo punto, solo poche patch passano +direttamente attraverso il suo giudizio; quindi, dovreste fare del vostro +meglio per -evitare di- inviargli e-mail. + +Se avete una patch che corregge un baco di sicurezza che potrebbe essere +sfruttato, inviatela a security@kernel.org. Per bachi importanti, un breve +embargo potrebbe essere preso in considerazione per dare il tempo alle +distribuzioni di prendere la patch e renderla disponibile ai loro utenti; +in questo caso, ovviamente, la patch non dovrebbe essere inviata su alcuna +lista di discussione pubblica. Leggete anche +Documentation/process/security-bugs.rst. + +Patch che correggono bachi importanti su un kernel già rilasciato, dovrebbero +essere inviate ai manutentori dei kernel stabili aggiungendo la seguente riga:: + + Cc: stable@vger.kernel.org + +nella vostra patch, nell'area dedicata alle firme (notate, NON come destinatario +delle e-mail). In aggiunta a questo file, dovreste leggere anche +Documentation/translations/it_IT/process/stable-kernel-rules.rst. + +Se le modifiche hanno effetti sull'interfaccia con lo spazio utente, per favore +inviate una patch per le pagine man ai manutentori di suddette pagine (elencati +nel file MAINTAINERS), o almeno una notifica circa la vostra modifica, +cosicché l'informazione possa trovare la sua strada nel manuale. Le modifiche +all'API dello spazio utente dovrebbero essere inviate in copia anche a +linux-api@vger.kernel.org. + +Niente: MIME, links, compressione, allegati. Solo puro testo +------------------------------------------------------------- + +Linus e gli altri sviluppatori del kernel devono poter commentare +le modifiche che sottomettete. Per uno sviluppatore è importante +essere in grado di "citare" le vostre modifiche, usando normali +programmi di posta elettronica, cosicché sia possibile commentare +una porzione specifica del vostro codice. + +Per questa ragione tutte le patch devono essere inviate via e-mail +come testo. Il modo più facile, e quello raccomandato, è con ``git +send-email``. Al sito https://git-send-email.io è disponibile una +guida interattiva sull'uso di ``git send-email``. + +Se decidete di non usare ``git send-email``: + +.. warning:: + + Se decidete di copiare ed incollare la patch nel corpo dell'e-mail, state + attenti che il vostro programma non corrompa il contenuto con andate + a capo automatiche. + +La patch non deve essere un allegato MIME, compresso o meno. Molti +dei più popolari programmi di posta elettronica non trasmettono un allegato +MIME come puro testo, e questo rende impossibile commentare il vostro codice. +Inoltre, un allegato MIME rende l'attività di Linus più laboriosa, diminuendo +così la possibilità che il vostro allegato-MIME venga accettato. + +Eccezione: se il vostro servizio di posta storpia le patch, allora qualcuno +potrebbe chiedervi di rinviarle come allegato MIME. + +Leggete Documentation/translations/it_IT/process/email-clients.rst +per dei suggerimenti sulla configurazione del programmi di posta elettronica +per l'invio di patch intatte. + +Rispondere ai commenti di revisione +----------------------------------- + +In risposta alla vostra email, quasi certamente i revisori vi +invieranno dei commenti su come migliorare la vostra patch. Dovete +rispondere a questi commenti; ignorare i revisori è un ottimo modo per +essere ignorati. Riscontri o domande che non conducono ad una +modifica del codice quasi certamente dovrebbero portare ad un commento +nel changelog cosicché il prossimo revisore potrà meglio comprendere +cosa stia accadendo. + +Assicuratevi di dire ai revisori quali cambiamenti state facendo e di +ringraziarli per il loro tempo. Revisionare codice è un lavoro faticoso e che +richiede molto tempo, e a volte i revisori diventano burberi. Tuttavia, anche in +questo caso, rispondete con educazione e concentratevi sul problema che hanno +evidenziato. Quando inviate una versione successiva ricordatevi di aggiungere un +``patch changelog`` alla email di intestazione o ad ogni singola patch spiegando +le differenze rispetto a sottomissioni precedenti (vedere +:ref:`it_the_canonical_patch_format`). + +Leggete Documentation/translations/it_IT/process/email-clients.rst per +le raccomandazioni sui programmi di posta elettronica e l'etichetta da usare +sulle liste di discussione. + +.. _it_resend_reminders: + +Non scoraggiatevi - o impazientitevi +------------------------------------ + +Dopo che avete inviato le vostre modifiche, siate pazienti e aspettate. +I revisori sono persone occupate e potrebbero non ricevere la vostra patch +immediatamente. + +Un tempo, le patch erano solite scomparire nel vuoto senza alcun commento, +ma ora il processo di sviluppo funziona meglio. Dovreste ricevere commenti +in una settimana o poco più; se questo non dovesse accadere, assicuratevi di +aver inviato le patch correttamente. Aspettate almeno una settimana prima di +rinviare le modifiche o sollecitare i revisori - probabilmente anche di più +durante la finestra d'integrazione. + +Potete anche rinviare la patch, o la serie di patch, dopo un paio di settimane +aggiungendo la parola "RESEND" nel titolo:: + + [PATCH Vx RESEND] sub/sys: Condensed patch summary + +Ma non aggiungete "RESEND" quando state sottomettendo una versione modificata +della vostra patch, o serie di patch - "RESEND" si applica solo alla +sottomissione di patch, o serie di patch, che non hanno subito modifiche +dall'ultima volta che sono state inviate. + +Aggiungete PATCH nell'oggetto +----------------------------- + +Dato l'alto volume di e-mail per Linus, e la lista linux-kernel, è prassi +prefiggere il vostro oggetto con [PATCH]. Questo permette a Linus e agli +altri sviluppatori del kernel di distinguere facilmente le patch dalle altre +discussioni. + +``git send-email`` lo fa automaticamente. + + +Firmate il vostro lavoro - Il certificato d'origine dello sviluppatore +---------------------------------------------------------------------- + +Per migliorare la tracciabilità su "chi ha fatto cosa", specialmente per +quelle patch che per raggiungere lo stadio finale passano attraverso +diversi livelli di manutentori, abbiamo introdotto la procedura di "firma" +delle patch che vengono inviate per e-mail. + +La firma è una semplice riga alla fine della descrizione della patch che +certifica che l'avete scritta voi o che avete il diritto di pubblicarla +come patch open-source. Le regole sono abbastanza semplici: se potete +certificare quanto segue: + +Il certificato d'origine dello sviluppatore 1.1 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Contribuendo a questo progetto, io certifico che: + + (a) Il contributo è stato creato interamente, o in parte, da me e che + ho il diritto di inviarlo in accordo con la licenza open-source + indicata nel file; oppure + + (b) Il contributo è basato su un lavoro precedente che, nei limiti + della mia conoscenza, è coperto da un'appropriata licenza + open-source che mi da il diritto di modificarlo e inviarlo, + le cui modifiche sono interamente o in parte mie, in accordo con + la licenza open-source (a meno che non abbia il permesso di usare + un'altra licenza) indicata nel file; oppure + + (c) Il contributo mi è stato fornito direttamente da qualcuno che + ha certificato (a), (b) o (c) e non l'ho modificata. + + (d) Capisco e concordo col fatto che questo progetto e i suoi + contributi sono pubblici e che un registro dei contributi (incluse + tutte le informazioni personali che invio con essi, inclusa la mia + firma) verrà mantenuto indefinitamente e che possa essere + ridistribuito in accordo con questo progetto o le licenze + open-source coinvolte. + +poi dovete solo aggiungere una riga che dice:: + + Signed-off-by: Random J Developer <random@developer.example.org> + +usando il vostro vero nome (spiacenti, non si accettano +contributi anonimi). Questo verrà fatto automaticamente se usate +``git commit -s``. Anche il ripristino di uno stato precedente dovrebbe +includere "Signed-off-by", se usate ``git revert -s`` questo verrà +fatto automaticamente. + +Alcune persone aggiungono delle etichette alla fine. Per ora queste verranno +ignorate, ma potete farlo per meglio identificare procedure aziendali interne o +per aggiungere dettagli circa la firma. + +In seguito al SoB (Signed-off-by:) dell'autore ve ne sono altri da +parte di tutte quelle persone che si sono occupate della gestione e +del trasporto della patch. Queste però non sono state coinvolte nello +sviluppo, ma la loro sequenza d'apparizione ci racconta il percorso +**reale** che una patch a intrapreso dallo sviluppatore, fino al +manutentore, per poi giungere a Linus. + + +Quando utilizzare Acked-by:, Cc:, e Co-developed-by: +---------------------------------------------------- + +L'etichetta Signed-off-by: indica che il firmatario è stato coinvolto nello +sviluppo della patch, o che era nel suo percorso di consegna. + +Se una persona non è direttamente coinvolta con la preparazione o gestione +della patch ma desidera firmare e mettere agli atti la loro approvazione, +allora queste persone possono chiedere di aggiungere al changelog della patch +una riga Acked-by:. + +Acked-by: viene spesso utilizzato dai manutentori del sottosistema in oggetto +quando quello stesso manutentore non ha contribuito né trasmesso la patch. + +Acked-by: non è formale come Signed-off-by:. Questo indica che la persona ha +revisionato la patch e l'ha trovata accettabile. Per cui, a volte, chi +integra le patch convertirà un "sì, mi sembra che vada bene" in un Acked-by: +(ma tenete presente che solitamente è meglio chiedere esplicitamente). + +Acked-by: non indica l'accettazione di un'intera patch. Per esempio, quando +una patch ha effetti su diversi sottosistemi e ha un Acked-by: da un +manutentore di uno di questi, significa che il manutentore accetta quella +parte di codice relativa al sottosistema che mantiene. Qui dovremmo essere +giudiziosi. Quando si hanno dei dubbi si dovrebbe far riferimento alla +discussione originale negli archivi della lista di discussione. + +Se una persona ha avuto l'opportunità di commentare la patch, ma non lo ha +fatto, potete aggiungere l'etichetta ``Cc:`` alla patch. Questa è l'unica +etichetta che può essere aggiunta senza che la persona in questione faccia +alcunché - ma dovrebbe indicare che la persona ha ricevuto una copia della +patch. Questa etichetta documenta che terzi potenzialmente interessati sono +stati inclusi nella discussione. + +Co-developed-by: indica che la patch è stata cosviluppata da diversi +sviluppatori; viene usato per assegnare più autori (in aggiunta a quello +associato all'etichetta From:) quando più persone lavorano ad una patch. Dato +che Co-developed-by: implica la paternità della patch, ogni Co-developed-by: +dev'essere seguito immediatamente dal Signed-off-by: del corrispondente +coautore. Qui si applica la procedura di base per sign-off, in pratica +l'ordine delle etichette Signed-off-by: dovrebbe riflettere il più possibile +l'ordine cronologico della storia della patch, indipendentemente dal fatto che +la paternità venga assegnata via From: o Co-developed-by:. Da notare che +l'ultimo Signed-off-by: dev'essere quello di colui che ha sottomesso la patch. + +Notate anche che l'etichetta From: è opzionale quando l'autore in From: è +anche la persona (e indirizzo email) indicato nel From: dell'intestazione +dell'email. + +Esempio di una patch sottomessa dall'autore in From::: + + <changelog> + + Co-developed-by: First Co-Author <first@coauthor.example.org> + Signed-off-by: First Co-Author <first@coauthor.example.org> + Co-developed-by: Second Co-Author <second@coauthor.example.org> + Signed-off-by: Second Co-Author <second@coauthor.example.org> + Signed-off-by: From Author <from@author.example.org> + +Esempio di una patch sottomessa dall'autore Co-developed-by::: + + From: From Author <from@author.example.org> + + <changelog> + + Co-developed-by: Random Co-Author <random@coauthor.example.org> + Signed-off-by: Random Co-Author <random@coauthor.example.org> + Signed-off-by: From Author <from@author.example.org> + Co-developed-by: Submitting Co-Author <sub@coauthor.example.org> + Signed-off-by: Submitting Co-Author <sub@coauthor.example.org> + +Utilizzare Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: e Fixes: +------------------------------------------------------------------------- + +L'etichetta Reported-by da credito alle persone che trovano e riportano i bachi +e si spera che questo possa ispirarli ad aiutarci nuovamente in futuro. +Rammentate che se il baco è stato riportato in privato, dovrete chiedere il +permesso prima di poter utilizzare l'etichetta Reported-by. Questa etichetta va +usata per i bachi, dunque non usatela per richieste di nuove funzionalità. + +L'etichetta Tested-by: indica che la patch è stata verificata con successo +(su un qualche sistema) dalla persona citata. Questa etichetta informa i +manutentori che qualche verifica è stata fatta, fornisce un mezzo per trovare +persone che possano verificare il codice in futuro, e garantisce che queste +stesse persone ricevano credito per il loro lavoro. + +Reviewed-by:, invece, indica che la patch è stata revisionata ed è stata +considerata accettabile in accordo con la dichiarazione dei revisori: + +Dichiarazione di svista dei revisori +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Offrendo la mia etichetta Reviewed-by, dichiaro quanto segue: + + (a) Ho effettuato una revisione tecnica di questa patch per valutarne + l'adeguatezza ai fini dell'inclusione nel ramo principale del + kernel. + + (b) Tutti i problemi e le domande riguardanti la patch sono stati + comunicati al mittente. Sono soddisfatto dalle risposte + del mittente. + + (c) Nonostante ci potrebbero essere cose migliorabili in queste + sottomissione, credo che sia, in questo momento, (1) una modifica + di interesse per il kernel, e (2) libera da problemi che + potrebbero metterne in discussione l'integrazione. + + (d) Nonostante abbia revisionato la patch e creda che vada bene, + non garantisco (se non specificato altrimenti) che questa + otterrà quello che promette o funzionerà correttamente in tutte + le possibili situazioni. + +L'etichetta Reviewed-by è la dichiarazione di un parere sulla bontà di +una modifica che si ritiene appropriata e senza alcun problema tecnico +importante. Qualsiasi revisore interessato (quelli che lo hanno fatto) +possono offrire il proprio Reviewed-by per la patch. Questa etichetta serve +a dare credito ai revisori e a informare i manutentori sul livello di revisione +che è stato fatto sulla patch. L'etichetta Reviewed-by, quando fornita da +revisori conosciuti per la loro conoscenza sulla materia in oggetto e per la +loro serietà nella revisione, accrescerà le probabilità che la vostra patch +venga integrate nel kernel. + +Quando si riceve una email sulla lista di discussione da un tester o +un revisore, le etichette Tested-by o Reviewed-by devono essere +aggiunte dall'autore quando invierà nuovamente la patch. Tuttavia, se +la patch è cambiata in modo significativo, queste etichette potrebbero +non avere più senso e quindi andrebbero rimosse. Solitamente si tiene traccia +della rimozione nel changelog della patch (subito dopo il separatore '---'). + +L'etichetta Suggested-by: indica che l'idea della patch è stata suggerita +dalla persona nominata e le da credito. Tenete a mente che questa etichetta +non dovrebbe essere aggiunta senza un permesso esplicito, specialmente se +l'idea non è stata pubblicata in un forum pubblico. Detto ciò, dando credito +a chi ci fornisce delle idee, si spera di poterli ispirare ad aiutarci +nuovamente in futuro. + +L'etichetta Fixes: indica che la patch corregge un problema in un commit +precedente. Serve a chiarire l'origine di un baco, il che aiuta la revisione +del baco stesso. Questa etichetta è di aiuto anche per i manutentori dei +kernel stabili al fine di capire quale kernel deve ricevere la correzione. +Questo è il modo suggerito per indicare che un baco è stato corretto nella +patch. Per maggiori dettagli leggete :ref:`it_describe_changes` + +Da notare che aggiungere un tag "Fixes:" non esime dalle regole +previste per i kernel stabili, e nemmeno dalla necessità di aggiungere +in copia conoscenza stable@vger.kernel.org su tutte le patch per +suddetti kernel. + +.. _it_the_canonical_patch_format: + +Il formato canonico delle patch +------------------------------- + +Questa sezione descrive il formato che dovrebbe essere usato per le patch. +Notate che se state usando un repositorio ``git`` per salvare le vostre patch +potere usare il comando ``git format-patch`` per ottenere patch nel formato +appropriato. Lo strumento non crea il testo necessario, per cui, leggete +le seguenti istruzioni. + +L'oggetto di una patch canonica è la riga:: + + Subject: [PATCH 001/123] subsystem: summary phrase + +Il corpo di una patch canonica contiene i seguenti elementi: + + - Una riga ``from`` che specifica l'autore della patch, seguita + da una riga vuota (necessaria soltanto se la persona che invia la + patch non ne è l'autore). + + - Il corpo della spiegazione, con linee non più lunghe di 75 caratteri, + che verrà copiato permanentemente nel changelog per descrivere la patch. + + - Una riga vuota + + - Le righe ``Signed-off-by:``, descritte in precedenza, che finiranno + anch'esse nel changelog. + + - Una linea di demarcazione contenente semplicemente ``---``. + + - Qualsiasi altro commento che non deve finire nel changelog. + + - Le effettive modifiche al codice (il prodotto di ``diff``). + +Il formato usato per l'oggetto permette ai programmi di posta di usarlo +per ordinare le patch alfabeticamente - tutti i programmi di posta hanno +questa funzionalità - dato che al numero sequenziale si antepongono degli zeri; +in questo modo l'ordine numerico ed alfabetico coincidono. + +Il ``subsystem`` nell'oggetto dell'email dovrebbe identificare l'area +o il sottosistema modificato dalla patch. + +La ``summary phrase`` nell'oggetto dell'email dovrebbe descrivere brevemente +il contenuto della patch. La ``summary phrase`` non dovrebbe essere un nome +di file. Non utilizzate la stessa ``summary phrase`` per tutte le patch in +una serie (dove una ``serie di patch`` è una sequenza ordinata di diverse +patch correlate). + +Ricordatevi che la ``summary phrase`` della vostra email diventerà un +identificatore globale ed unico per quella patch. Si propaga fino al +changelog ``git``. La ``summary phrase`` potrà essere usata in futuro +dagli sviluppatori per riferirsi a quella patch. Le persone vorranno +cercare la ``summary phrase`` su internet per leggere le discussioni che la +riguardano. Potrebbe anche essere l'unica cosa che le persone vedranno +quando, in due o tre mesi, riguarderanno centinaia di patch usando strumenti +come ``gitk`` o ``git log --oneline``. + +Per queste ragioni, dovrebbe essere lunga fra i 70 e i 75 caratteri, e deve +descrivere sia cosa viene modificato, sia il perché sia necessario. Essere +brevi e descrittivi è una bella sfida, ma questo è quello che fa un riassunto +ben scritto. + +La ``summary phrase`` può avere un'etichetta (*tag*) di prefisso racchiusa fra +le parentesi quadre "Subject: [PATCH <tag>...] <summary phrase>". +Le etichette non verranno considerate come parte della frase riassuntiva, ma +indicano come la patch dovrebbe essere trattata. Fra le etichette più comuni +ci sono quelle di versione che vengono usate quando una patch è stata inviata +più volte (per esempio, "v1, v2, v3"); oppure "RFC" per indicare che si +attendono dei commenti (*Request For Comments*). + +Se ci sono quattro patch nella serie, queste dovrebbero essere +enumerate così: 1/4, 2/4, 3/4, 4/4. Questo assicura che gli +sviluppatori capiranno l'ordine in cui le patch dovrebbero essere +applicate, e per tracciare quelle che hanno revisionate o che hanno +applicato. + +Un paio di esempi di oggetti:: + + Subject: [PATCH 2/5] ext2: improve scalability of bitmap searching + Subject: [PATCH v2 01/27] x86: fix eflags tracking + Subject: [PATCH v2] sub/sys: Condensed patch summary + Subject: [PATCH v2 M/N] sub/sys: Condensed patch summary + +La riga ``from`` dev'essere la prima nel corpo del messaggio ed è nel +formato: + + From: Patch Author <author@example.com> + +La riga ``from`` indica chi verrà accreditato nel changelog permanente come +l'autore della patch. Se la riga ``from`` è mancante, allora per determinare +l'autore da inserire nel changelog verrà usata la riga ``From`` +nell'intestazione dell'email. + +Il corpo della spiegazione verrà incluso nel changelog permanente, per cui +deve aver senso per un lettore esperto che è ha dimenticato i dettagli della +discussione che hanno portato alla patch. L'inclusione di informazioni +sui problemi oggetto dalla patch (messaggi del kernel, messaggi di oops, +eccetera) è particolarmente utile per le persone che potrebbero cercare fra +i messaggi di log per la patch che li tratta. Il testo dovrebbe essere scritto +con abbastanza dettagli da far capire al lettore **perché** quella +patch fu creata, e questo a distanza di settimane, mesi, o addirittura +anni. + +Se la patch corregge un errore di compilazione, non sarà necessario +includere proprio _tutto_ quello che è uscito dal compilatore; +aggiungete solo quello che è necessario per far si che la vostra patch +venga trovata. Come nella ``summary phrase``, è importante essere sia +brevi che descrittivi. + +La linea di demarcazione ``---`` serve essenzialmente a segnare dove finisce +il messaggio di changelog. + +Aggiungere il ``diffstat`` dopo ``---`` è un buon uso di questo spazio, per +mostrare i file che sono cambiati, e il numero di file aggiunto o rimossi. +Un ``diffstat`` è particolarmente utile per le patch grandi. Se +includete un ``diffstat`` dopo ``---``, usate le opzioni ``-p 1 -w70`` +cosicché i nomi dei file elencati non occupino troppo spazio +(facilmente rientreranno negli 80 caratteri, magari con qualche +indentazione). (``git`` genera di base dei diffstat adatti). + +I commenti che sono importanti solo per i manutentori, quindi +inadatti al changelog permanente, dovrebbero essere messi qui. Un +buon esempio per questo tipo di commenti potrebbe essere il cosiddetto +``patch changelogs`` che descrivere le differenze fra le versioni +della patch. + +Queste informazioni devono andare **dopo** la linea ``---`` che separa +il *changelog* dal resto della patch. Le informazioni riguardanti la +versione di una patch non sono parte del *chagelog* che viene incluso +in git. Queste sono informazioni utili solo ai revisori. Se venissero +messe sopra la riga, qualcuno dovrà fare del lavoro manuale per +rimuoverle; cosa che invece viene fatta automaticamente quando vengono +messe correttamente oltre la riga.:: + + <commit message> + ... + Signed-off-by: Author <author@mail> + --- + V2 -> V3: Removed redundant helper function + V1 -> V2: Cleaned up coding style and addressed review comments + + path/to/file | 5+++-- + ... + +Maggiori dettagli sul formato delle patch nei riferimenti qui di seguito. + +.. _it_backtraces: + +Aggiungere i *backtrace* nei messaggi di commit +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +I *backtrace* aiutano a documentare la sequenza di chiamate a funzione +che portano ad un problema. Tuttavia, non tutti i *backtrace* sono +davvero utili. Per esempio, le sequenze iniziali di avvio sono uniche +e ovvie. Copiare integralmente l'output di ``dmesg`` aggiunge tante +informazioni che distraggono dal vero problema (per esempio, i +marcatori temporali, la lista dei moduli, la lista dei registri, lo +stato dello stack). + +Quindi, per rendere utile un *backtrace* dovreste eliminare le +informazioni inutili, cosicché ci si possa focalizzare sul +problema. Ecco un esempio di un *backtrace* essenziale:: + + unchecked MSR access error: WRMSR to 0xd51 (tried to write 0x0000000000000064) + at rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20) + Call Trace: + mba_wrmsr + update_domains + rdtgroup_mkdir + +.. _it_explicit_in_reply_to: + +Usare esplicitamente In-Reply-To nell'intestazione +-------------------------------------------------- + +Aggiungere manualmente In-Reply-To: nell'intestazione dell'e-mail +potrebbe essere d'aiuto per associare una patch ad una discussione +precedente, per esempio per collegare la correzione di un baco con l'e-mail +che lo riportava. Tuttavia, per serie di patch multiple è generalmente +sconsigliato l'uso di In-Reply-To: per collegare precedenti versioni. +In questo modo versioni multiple di una patch non diventeranno un'ingestibile +giungla di riferimenti all'interno dei programmi di posta. Se un collegamento +è utile, potete usare https://lore.kernel.org/ per ottenere i collegamenti +ad una versione precedente di una serie di patch (per esempio, potete usarlo +per l'email introduttiva alla serie). + +Riferimenti +----------- + +Andrew Morton, "La patch perfetta" (tpp). + <https://www.ozlabs.org/~akpm/stuff/tpp.txt> + +Jeff Garzik, "Formato per la sottomissione di patch per il kernel Linux" + <https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html> + +Greg Kroah-Hartman, "Come scocciare un manutentore di un sottosistema" + <http://www.kroah.com/log/linux/maintainer.html> + + <http://www.kroah.com/log/linux/maintainer-02.html> + + <http://www.kroah.com/log/linux/maintainer-03.html> + + <http://www.kroah.com/log/linux/maintainer-04.html> + + <http://www.kroah.com/log/linux/maintainer-05.html> + + <http://www.kroah.com/log/linux/maintainer-06.html> + +No!!!! Basta gigantesche bombe patch alle persone sulla lista linux-kernel@vger.kernel.org! + <https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net> + +Kernel Documentation/translations/it_IT/process/coding-style.rst. + +E-mail di Linus Torvalds sul formato canonico di una patch: + <https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org> + +Andi Kleen, "Su come sottomettere patch del kernel" + Alcune strategie su come sottomettere modifiche toste o controverse. + + http://halobates.de/on-submitting-patches.pdf diff --git a/Documentation/translations/it_IT/process/volatile-considered-harmful.rst b/Documentation/translations/it_IT/process/volatile-considered-harmful.rst new file mode 100644 index 0000000000..4fff9a59b5 --- /dev/null +++ b/Documentation/translations/it_IT/process/volatile-considered-harmful.rst @@ -0,0 +1,134 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :ref:`Documentation/process/volatile-considered-harmful.rst <volatile_considered_harmful>` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +.. _it_volatile_considered_harmful: + +Perché la parola chiave "volatile" non dovrebbe essere usata +------------------------------------------------------------ + +Spesso i programmatori C considerano volatili quelle variabili che potrebbero +essere cambiate al di fuori dal thread di esecuzione corrente; come risultato, +a volte saranno tentati dall'utilizzare *volatile* nel kernel per le +strutture dati condivise. In altre parole, gli è stato insegnato ad usare +*volatile* come una variabile atomica di facile utilizzo, ma non è così. +L'uso di *volatile* nel kernel non è quasi mai corretto; questo documento ne +descrive le ragioni. + +Il punto chiave da capire su *volatile* è che il suo scopo è quello di +sopprimere le ottimizzazioni, che non è quasi mai quello che si vuole. +Nel kernel si devono proteggere le strutture dati condivise contro accessi +concorrenti e indesiderati: questa è un'attività completamente diversa. +Il processo di protezione contro gli accessi concorrenti indesiderati eviterà +anche la maggior parte dei problemi relativi all'ottimizzazione in modo più +efficiente. + +Come *volatile*, le primitive del kernel che rendono sicuro l'accesso ai dati +(spinlock, mutex, barriere di sincronizzazione, ecc) sono progettate per +prevenire le ottimizzazioni indesiderate. Se vengono usate opportunamente, +non ci sarà bisogno di utilizzare *volatile*. Se vi sembra che *volatile* sia +comunque necessario, ci dev'essere quasi sicuramente un baco da qualche parte. +In un pezzo di codice kernel scritto a dovere, *volatile* può solo servire a +rallentare le cose. + +Considerate questo tipico blocco di codice kernel:: + + spin_lock(&the_lock); + do_something_on(&shared_data); + do_something_else_with(&shared_data); + spin_unlock(&the_lock); + +Se tutto il codice seguisse le regole di sincronizzazione, il valore di un +dato condiviso non potrebbe cambiare inaspettatamente mentre si trattiene un +lock. Un qualsiasi altro blocco di codice che vorrà usare quel dato rimarrà +in attesa del lock. Gli spinlock agiscono come barriere di sincronizzazione +- sono stati esplicitamente scritti per agire così - il che significa che gli +accessi al dato condiviso non saranno ottimizzati. Quindi il compilatore +potrebbe pensare di sapere cosa ci sarà nel dato condiviso ma la chiamata +spin_lock(), che agisce come una barriera di sincronizzazione, gli imporrà di +dimenticarsi tutto ciò che sapeva su di esso. + +Se il dato condiviso fosse stato dichiarato come *volatile*, la +sincronizzazione rimarrebbe comunque necessaria. Ma verrà impedito al +compilatore di ottimizzare gli accessi al dato anche _dentro_ alla sezione +critica, dove sappiamo che in realtà nessun altro può accedervi. Mentre si +trattiene un lock, il dato condiviso non è *volatile*. Quando si ha a che +fare con dei dati condivisi, un'opportuna sincronizzazione rende inutile +l'uso di *volatile* - anzi potenzialmente dannoso. + +L'uso di *volatile* fu originalmente pensato per l'accesso ai registri di I/O +mappati in memoria. All'interno del kernel, l'accesso ai registri, dovrebbe +essere protetto dai lock, ma si potrebbe anche desiderare che il compilatore +non "ottimizzi" l'accesso ai registri all'interno di una sezione critica. +Ma, all'interno del kernel, l'accesso alla memoria di I/O viene sempre fatto +attraverso funzioni d'accesso; accedere alla memoria di I/O direttamente +con i puntatori è sconsigliato e non funziona su tutte le architetture. +Queste funzioni d'accesso sono scritte per evitare ottimizzazioni indesiderate, +quindi, di nuovo, *volatile* è inutile. + +Un'altra situazione dove qualcuno potrebbe essere tentato dall'uso di +*volatile*, è nel caso in cui il processore è in un'attesa attiva sul valore +di una variabile. Il modo giusto di fare questo tipo di attesa è il seguente:: + + while (my_variable != what_i_want) + cpu_relax(); + +La chiamata cpu_relax() può ridurre il consumo di energia del processore +o cedere il passo ad un processore hyperthreaded gemello; funziona anche come +una barriera per il compilatore, quindi, ancora una volta, *volatile* non è +necessario. Ovviamente, tanto per puntualizzare, le attese attive sono +generalmente un atto antisociale. + +Ci sono comunque alcune rare situazioni dove l'uso di *volatile* nel kernel +ha senso: + + - Le funzioni d'accesso sopracitate potrebbero usare *volatile* su quelle + architetture che supportano l'accesso diretto alla memoria di I/O. + In pratica, ogni chiamata ad una funzione d'accesso diventa una piccola + sezione critica a se stante, e garantisce che l'accesso avvenga secondo + le aspettative del programmatore. + + - I codice *inline assembly* che fa cambiamenti nella memoria, ma che non + ha altri effetti espliciti, rischia di essere rimosso da GCC. Aggiungere + la parola chiave *volatile* a questo codice ne previene la rimozione. + + - La variabile jiffies è speciale in quanto assume un valore diverso ogni + volta che viene letta ma può essere lette senza alcuna sincronizzazione. + Quindi jiffies può essere *volatile*, ma l'aggiunta ad altre variabili di + questo è sconsigliata. Jiffies è considerata uno "stupido retaggio" + (parole di Linus) in questo contesto; correggerla non ne varrebbe la pena e + causerebbe più problemi. + + - I puntatori a delle strutture dati in una memoria coerente che potrebbe + essere modificata da dispositivi di I/O può, a volte, essere legittimamente + *volatile*. Un esempio pratico può essere quello di un adattatore di rete + che utilizza un puntatore ad un buffer circolare, questo viene cambiato + dall'adattatore per indicare quali descrittori sono stati processati. + +Per la maggior parte del codice, nessuna delle giustificazioni sopracitate può +essere considerata. Di conseguenza, l'uso di *volatile* è probabile che venga +visto come un baco e porterà a verifiche aggiuntive. Gli sviluppatori tentati +dall'uso di *volatile* dovrebbero fermarsi e pensare a cosa vogliono davvero +ottenere. + +Le modifiche che rimuovono variabili *volatile* sono generalmente ben accette +- purché accompagnate da una giustificazione che dimostri che i problemi di +concorrenza siano stati opportunamente considerati. + +Riferimenti +=========== + +[1] https://lwn.net/Articles/233481/ + +[2] https://lwn.net/Articles/233482/ + +Crediti +======= + +Impulso e ricerca originale di Randy Dunlap + +Scritto da Jonathan Corbet + +Migliorato dai commenti di Satyam Sharma, Johannes Stezenbach, Jesper +Juhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, e Stefan Richter. diff --git a/Documentation/translations/it_IT/riscv/patch-acceptance.rst b/Documentation/translations/it_IT/riscv/patch-acceptance.rst new file mode 100644 index 0000000000..edf67252b3 --- /dev/null +++ b/Documentation/translations/it_IT/riscv/patch-acceptance.rst @@ -0,0 +1,40 @@ +.. include:: ../disclaimer-ita.rst + +:Original: :doc:`../../../riscv/patch-acceptance` +:Translator: Federico Vaga <federico.vaga@vaga.pv.it> + +arch/riscv linee guida alla manutenzione per gli sviluppatori +============================================================= + +Introduzione +------------ + +L'insieme di istruzioni RISC-V sono sviluppate in modo aperto: le +bozze in fase di sviluppo sono disponibili a tutti per essere +revisionate e per essere sperimentare nelle implementazioni. Le bozze +dei nuovi moduli o estensioni possono cambiare in fase di sviluppo - a +volte in modo incompatibile rispetto a bozze precedenti. Questa +flessibilità può portare a dei problemi di manutenzioni per il +supporto RISC-V nel kernel Linux. I manutentori Linux non amano +l'abbandono del codice, e il processo di sviluppo del kernel +preferisce codice ben revisionato e testato rispetto a quello +sperimentale. Desideriamo estendere questi stessi principi al codice +relativo all'architettura RISC-V che verrà accettato per l'inclusione +nel kernel. + +In aggiunta alla lista delle verifiche da fare prima di inviare una patch +------------------------------------------------------------------------- + +Accetteremo le patch per un nuovo modulo o estensione se la fondazione +RISC-V li classifica come "Frozen" o "Retified". (Ovviamente, gli +sviluppatori sono liberi di mantenere una copia del kernel Linux +contenente il codice per una bozza di estensione). + +In aggiunta, la specifica RISC-V permette agli implementatori di +creare le proprie estensioni. Queste estensioni non passano +attraverso il processo di revisione della fondazione RISC-V. Per +questo motivo, al fine di evitare complicazioni o problemi di +prestazioni, accetteremo patch solo per quelle estensioni che sono +state ufficialmente accettate dalla fondazione RISC-V. (Ovviamente, +gli implementatori sono liberi di mantenere una copia del kernel Linux +contenente il codice per queste specifiche estensioni). |