0001 .. include:: ../disclaimer-ita.rst
0002
0003 :Original: :doc:`../../../core-api/symbol-namespaces`
0004 :Translator: Federico Vaga <federico.vaga@vaga.pv.it>
0005
0006 ===========================
0007 Spazio dei nomi dei simboli
0008 ===========================
0009
0010 Questo documento descrive come usare lo spazio dei nomi dei simboli
0011 per strutturare quello che viene esportato internamente al kernel
0012 grazie alle macro della famiglia EXPORT_SYMBOL().
0013
0014 1. Introduzione
0015 ===============
0016
0017 Lo spazio dei nomi dei simboli è stato introdotto come mezzo per strutturare
0018 l'API esposta internamente al kernel. Permette ai manutentori di un
0019 sottosistema di organizzare i simboli esportati in diversi spazi di
0020 nomi. Questo meccanismo è utile per la documentazione (pensate ad
0021 esempio allo spazio dei nomi SUBSYSTEM_DEBUG) così come per limitare
0022 la disponibilità di un gruppo di simboli in altre parti del kernel. Ad
0023 oggi, i moduli che usano simboli esportati da uno spazio di nomi
0024 devono prima importare detto spazio. Altrimenti il kernel, a seconda
0025 della configurazione, potrebbe rifiutare di caricare il modulo o
0026 avvisare l'utente di un'importazione mancante.
0027
0028 2. Come definire uno spazio dei nomi dei simboli
0029 ================================================
0030
0031 I simboli possono essere esportati in spazi dei nomi usando diversi
0032 meccanismi. Tutti questi meccanismi cambiano il modo in cui
0033 EXPORT_SYMBOL e simili vengono guidati verso la creazione di voci in ksymtab.
0034
0035 2.1 Usare le macro EXPORT_SYMBOL
0036 ================================
0037
0038 In aggiunta alle macro EXPORT_SYMBOL() e EXPORT_SYMBOL_GPL(), che permettono
0039 di esportare simboli del kernel nella rispettiva tabella, ci sono
0040 varianti che permettono di esportare simboli all'interno di uno spazio dei
0041 nomi: EXPORT_SYMBOL_NS() ed EXPORT_SYMBOL_NS_GPL(). Queste macro richiedono un
0042 argomento aggiuntivo: lo spazio dei nomi.
0043 Tenete presente che per via dell'espansione delle macro questo argomento deve
0044 essere un simbolo di preprocessore. Per esempio per esportare il
0045 simbolo ``usb_stor_suspend`` nello spazio dei nomi ``USB_STORAGE`` usate::
0046
0047 EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE);
0048
0049 Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce
0050 rappresentata dalla struttura ``kernel_symbol`` che avrà il campo
0051 ``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio
0052 dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi
0053 di base. Il programma ``modpost`` e il codice in kernel/module/main.c usano lo
0054 spazio dei nomi, rispettivamente, durante la compilazione e durante il
0055 caricamento di un modulo.
0056
0057 2.2 Usare il simbolo di preprocessore DEFAULT_SYMBOL_NAMESPACE
0058 ==============================================================
0059
0060 Definire lo spazio dei nomi per tutti i simboli di un sottosistema può essere
0061 logorante e di difficile manutenzione. Perciò è stato fornito un simbolo
0062 di preprocessore di base (DEFAULT_SYMBOL_NAMESPACE), che, se impostato,
0063 diventa lo spazio dei simboli di base per tutti gli usi di EXPORT_SYMBOL()
0064 ed EXPORT_SYMBOL_GPL() che non specificano esplicitamente uno spazio dei nomi.
0065
0066 Ci sono molti modi per specificare questo simbolo di preprocessore e il loro
0067 uso dipende dalle preferenze del manutentore di un sottosistema. La prima
0068 possibilità è quella di definire il simbolo nel ``Makefile`` del sottosistema.
0069 Per esempio per esportare tutti i simboli definiti in usb-common nello spazio
0070 dei nomi USB_COMMON, si può aggiungere la seguente linea in
0071 drivers/usb/common/Makefile::
0072
0073 ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON
0074
0075 Questo cambierà tutte le macro EXPORT_SYMBOL() ed EXPORT_SYMBOL_GPL(). Invece,
0076 un simbolo esportato con EXPORT_SYMBOL_NS() non verrà cambiato e il simbolo
0077 verrà esportato nello spazio dei nomi indicato.
0078
0079 Una seconda possibilità è quella di definire il simbolo di preprocessore
0080 direttamente nei file da compilare. L'esempio precedente diventerebbe::
0081
0082 #undef DEFAULT_SYMBOL_NAMESPACE
0083 #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON
0084
0085 Questo va messo prima di un qualsiasi uso di EXPORT_SYMBOL.
0086
0087 3. Come usare i simboli esportati attraverso uno spazio dei nomi
0088 ================================================================
0089
0090 Per usare i simboli esportati da uno spazio dei nomi, i moduli del
0091 kernel devono esplicitamente importare il relativo spazio dei nomi; altrimenti
0092 il kernel potrebbe rifiutarsi di caricare il modulo. Il codice del
0093 modulo deve usare la macro MODULE_IMPORT_NS per importare lo spazio
0094 dei nomi che contiene i simboli desiderati. Per esempio un modulo che
0095 usa il simbolo usb_stor_suspend deve importare lo spazio dei nomi
0096 USB_STORAGE usando la seguente dichiarazione::
0097
0098 MODULE_IMPORT_NS(USB_STORAGE);
0099
0100 Questo creerà un'etichetta ``modinfo`` per ogni spazio dei nomi
0101 importato. Un risvolto di questo fatto è che gli spazi dei
0102 nomi importati da un modulo possono essere ispezionati tramite
0103 modinfo::
0104
0105 $ modinfo drivers/usb/storage/ums-karma.ko
0106 [...]
0107 import_ns: USB_STORAGE
0108 [...]
0109
0110
0111 Si consiglia di posizionare la dichiarazione MODULE_IMPORT_NS() vicino
0112 ai metadati del modulo come MODULE_AUTHOR() o MODULE_LICENSE(). Fate
0113 riferimento alla sezione 5. per creare automaticamente le importazioni
0114 mancanti.
0115
0116 4. Caricare moduli che usano simboli provenienti da spazi dei nomi
0117 ==================================================================
0118
0119 Quando un modulo viene caricato (per esempio usando ``insmod``), il kernel
0120 verificherà la disponibilità di ogni simbolo usato e se lo spazio dei nomi
0121 che potrebbe contenerli è stato importato. Il comportamento di base del kernel
0122 è di rifiutarsi di caricare quei moduli che non importano tutti gli spazi dei
0123 nomi necessari. L'errore verrà annotato e il caricamento fallirà con l'errore
0124 EINVAL. Per caricare i moduli che non soddisfano questo requisito esiste
0125 un'opzione di configurazione: impostare
0126 MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y caricherà i moduli comunque ma
0127 emetterà un avviso.
0128
0129 5. Creare automaticamente la dichiarazione MODULE_IMPORT_NS
0130 ===========================================================
0131
0132 La mancanza di un'importazione può essere individuata facilmente al momento
0133 della compilazione. Infatti, modpost emetterà un avviso se il modulo usa
0134 un simbolo da uno spazio dei nomi che non è stato importato.
0135 La dichiarazione MODULE_IMPORT_NS() viene solitamente aggiunta in un posto
0136 ben definito (assieme agli altri metadati del modulo). Per facilitare
0137 la vita di chi scrive moduli (e i manutentori di sottosistemi), esistono uno
0138 script e un target make per correggere le importazioni mancanti. Questo può
0139 essere fatto con::
0140
0141 $ make nsdeps
0142
0143 Lo scenario tipico di chi scrive un modulo potrebbe essere::
0144
0145 - scrivere codice che dipende da un simbolo appartenente ad uno spazio
0146 dei nomi non importato
0147 - eseguire ``make``
0148 - aver notato un avviso da modpost che parla di un'importazione
0149 mancante
0150 - eseguire ``make nsdeps`` per aggiungere import nel posto giusto
0151
0152 Per i manutentori di sottosistemi che vogliono aggiungere uno spazio dei nomi,
0153 l'approccio è simile. Di nuovo, eseguendo ``make nsdeps`` aggiungerà le
0154 importazioni mancanti nei moduli inclusi nel kernel::
0155
0156 - spostare o aggiungere simboli ad uno spazio dei nomi (per esempio
0157 usando EXPORT_SYMBOL_NS())
0158 - eseguire ``make`` (preferibilmente con allmodconfig per coprire tutti
0159 i moduli del kernel)
0160 - aver notato un avviso da modpost che parla di un'importazione
0161 mancante
0162 - eseguire ``make nsdeps`` per aggiungere import nel posto giusto
0163
0164 Potete anche eseguire nsdeps per moduli esterni. Solitamente si usa così::
0165
0166 $ make -C <path_to_kernel_src> M=$PWD nsdeps