Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > f1098342ec4a2b28475e34123ce17201 > files > 531

howto-html-it-9.1-0.5mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>KernelAnalysis-HOWTO: Peculiarita' di Linux</TITLE>
 <LINK HREF="KernelAnalysis-HOWTO-6.html" REL=next>
 <LINK HREF="KernelAnalysis-HOWTO-4.html" REL=previous>
 <LINK HREF="KernelAnalysis-HOWTO.html#toc5" REL=contents>
</HEAD>
<BODY>
<A HREF="KernelAnalysis-HOWTO-6.html">Avanti</A>
<A HREF="KernelAnalysis-HOWTO-4.html">Indietro</A>
<A HREF="KernelAnalysis-HOWTO.html#toc5">Indice</A>
<HR>
<H2><A NAME="s5">5. Peculiarita' di Linux</A></H2>

<H2><A NAME="ss5.1">5.1 Introduzione</A>
</H2>

<P>Linux possiede alcune caratteristiche pressoche' uniche rispetto agli altri
OSs. These peculiarities include:
<P>
<OL>
<LI>Utilizzo della sola Paginazione</LI>
<LI>Softirq</LI>
<LI>Kernel Threads</LI>
<LI>Kernel Modules</LI>
<LI>Directory ''Proc'' </LI>
</OL>
<H3>Elementi di flessibilita'</H3>

<P>I punti 4 e 5 danno agli ammistratori un'enorme flessibilita' sulla configurazione
del sistema in User Mode permettendo loro di risolvere anche problemi critici
(come kernel bugs) senza dover riavviare la macchina
<P>Ad esempio se si vuol cambiare qualcosa nel Kernel di un grosso server
non e' necessario riavviarlo, bastera' preparare la prima volta il kernel ad
accogliere un modulo e, in seguito, creare il modulo per effettuare le modifiche
volute.
<H2><A NAME="ss5.2">5.2 Solo Paginazione</A>
</H2>

<P>Linux non utilizza la Segmentazione per distinguere i Tasks l'uno dall'altro,
usa soltanto la Paginazione (solo 2 segmenti vengono utilizzati in tutti i
Tasks, CODE e DATA/STACK).
<P>Possiamo anche dire che una ''Page Fault'' tra Task non puo' mai avvenire
(cioe' quell'evento scatenato quando un Task vuole scrivere sull'area di memoria
di un altro Task), poiche' ogni Task utilizza un set di Page Tables (Tabelle
di Paginazione) differenti per ogni Processo: queste tabelle non possono mai
puntare allo stesso indirizzo fisico (per costruzione).
<H3>Segmenti Linux</H3>

<P>Sotto Linux vengono utilizzati soltanto 4 segmenti: 
<P>
<OL>
<LI>Kernel Code [0x10]</LI>
<LI>Kernel Data / Stack [0x18]</LI>
<LI>User Code [0x23]</LI>
<LI>User Data / Stack [0x2b]</LI>
</OL>
<P>[La sintassi e' ''Utilizzo [Segmento]'']
<P>Nell'architettura Intel, i registri di segmenti usati sono:
<P>
<UL>
<LI>CS per il Code Segment</LI>
<LI>DS per il Data Segment</LI>
<LI>SS per lo Stack Segment</LI>
<LI>ES per l'Alternative Segment (usato ad esempio quando si vuole effettuare
una copia tra 2 segmenti differenti)</LI>
</UL>
<P>Quindi ogni Task utilizza il segmenti 0x23 per il codice e il segmenti
0x2b per data/stack.
<H3>Paginazione di Linux</H3>

<P>Linux utilizza uno schema con 3 levelli di paginazione, a seconda dell'architecture.
<P>
<P>Intel permette di sfruttare solo 2 levelli. Per ottimizzare l'utilizzo
della memoria viene anche utilizzato il meccanismo della ''Copy on Write''
(si veda il Cap.10 per ulteriori informazioni).
<H3>Perche' esistono ''conflitti'' tra gli indirizzi relativi a Tasks diversi?</H3>

<P>La risposta e' molto molto semplice: i conflitti tra indirizzi sono impossibili.
<P>La mappatura tra indirizzi Lineari-&gt; Fisici viene gestita dalla Paginazione,
quindi e' sufficiente assegnare le pagine fisiche in modo univoco.
<H3>E' necessario deframmentare la memoria?</H3>

<P>No. L'assegnazione delle Pagine e' un processo dinamico: abbiamo bisogno
di allocare una pagina soltanto quando un Task lo richiede e quindi possiamo
sceglierlo tra le pagine di memoria libere in modo ordinato. Quando vogliamo
rilasciare una pagina dobbiamo soltanto aggiungerla nella ''free page list''.
<H3>E le pagine del Kernel?</H3>

<P>Lo spazio del Kernel ha una caratteristica: lo spazio Lineare coincide
con quello Fisico (questo per semplificare la vita!). Questa peculiarita' comporta
che sia necessario allocare una volta per tutte un blocco di memoria senza
poi possibilita' alcuna di aggiungere un altro blocco in modo CONTIGUO (non
lo si puo' garantire perche' vi possono essere altre pagine in User Mode in
mezzo!).
<P>Tutto cio' non porta a grossi problemi per quanto riguarda il CODICE in
quanto esso non modifica a Run-Time la propria dimensione (si intende la dimensione
in maniera CONTIGUA), bastera' quindi allocare la prima volta uno spazio di
memoria sufficiente e non si avranno problemi.
<P>Il problema vero si ha nel caso dello STACK, in quanto ogni processo (in
Kernel Mode) utilizza 1 pagina di Kernel Stack: com'e' noto lo Stack e' una
struttura dati che richiede di essere CONTIGUA, quindi, una volta stabilito
il limite massimo per lo stack (come detto 1 pagina) non lo si potra' piu'
aumentare.
<P>Se si dovesse utilizzare lo Stack oltre lo spazio consentito vi sarebbe
una scrittura sulle strutture dati relative al processo in questione (in Kernel
Mode).
<P>Fortunatamente la struttura del Kernel ci aiuta, in quanto le funzioni
del sistema:
<P>
<UL>
<LI>Non sono mai Ricorsive</LI>
<LI>Non si chiamano mai piu' di N volte l'una con l'altra</LI>
</UL>
<P>Una volta noto N, e una volta noto il massimo utilizzo di stack da parte
delle funzioni del Kernel chiamate si potra' avere la giusta stima per lo Stack.
<P>Per verificare il problema e' sufficiente creare un modulo che abbiam una
funzione ricorsiva che si richiami un certo numero di volte. Dopo un certo
numero di volte il Kernel si blocchera' generando una eccezione di page fault.
<H2><A NAME="ss5.3">5.3 SoftIrq</A>
</H2>

<P>Quando arriva un IRQ, il ''Task Switching'' viene posticipato per non intaccare
le prestazioni del sistema. 
<P>Alcuni lavori (che possono essere eseguiti tranquillamente anche dopo l'IRQ
e che consumano molta CPU, come la costruzione di un pacchetto TCP/IP) vengono
accodati per essere poi eseguiti durante lo scheduling (una volta cioe' che
il TimeSlice dell'attuale processo e' terminato).
<P>Nei Kernels recenti (2.4.x) il meccanismo "SoftIrq'' viene gestito da un
Kernel Thread: ''ksoftirqd_CPUn'', dove n sta' per il numero di CPU che sta
eseguendo il tale Thread (in un sistema monoprocessore il nome e' ''ksoftirqd_CPU0''
avente PID 3).
<H3>Preparazione dei SoftIrq</H3>

<H3>Abilitazione dei SoftIrq</H3>

<P>''cpu_raise_softirq'' e' la routine che sveglia il Kernel Thread ''ksoftirqd_CPU0''
che gestira' poi il lavoro accodato:
<P>
<PRE>
|cpu_raise_softirq
   |__cpu_raise_softirq
   |wakeup_softirqd
      |wake_up_process
</PRE>
<P>
<UL>
<LI>cpu_raise_softirq [kernel/softirq.c]</LI>
<LI>__cpu_raise_softirq [include/linux/interrupt.h]</LI>
<LI>wakeup_softirq [kernel/softirq.c]</LI>
<LI>wake_up_process [kernel/sched.c]</LI>
</UL>
<P>La routine ''__cpu_raise_softirq'' attiva il bit giusto relativo a lavoro
in questione sul vettore della coda SoftIrq.
<P>''wakeup_softirq'' usa ''wakeup_process'' per svegliare il Kernel Thread
''ksoftirqd_CPU0''.
<H3>Esecuzione dei Softirq</H3>

<P>DAFARE: descrivere la struttura dati del meccanismo SoftIrq.
<P>Quando ''ksoftirqd_CPU0'' si sveglia, andra' ad eseguire i lavori accodati.
<P>Il codice di ''ksoftirqd_CPU0'' (ciclo principale) e':
<P>
<PRE>
for (;;) {
   if (!softirq_pending(cpu)) 
      schedule();
      __set_current_state(TASK_RUNNING);
   while (softirq_pending(cpu)) { 
      do_softirq(); 
      if (current-&gt;need_resched) 
         schedule 
   }
   __set_current_state(TASK_INTERRUPTIBLE)
}
</PRE>
<P>
<UL>
<LI>ksoftirqd [kernel/softirq.c]</LI>
</UL>
<H2><A NAME="ss5.4">5.4 Kernel Threads</A>
</H2>

<P>Sebbene Linux sia un OS Monolitico, esistono alcuni ''Kernel Threads''
per eseguire del lavoro di manutenzione del sistema.
<P>Questi Tasks non utilizzano memoria UTENTE, ma condividono quella del KERNEL;
operano al piu' alto privilegio (RING 0 su architettura 386+) come ogni altro
codice del Kernel.
<P>I Kernel Threads vengono creati dalla funzione ''kernel_thread [arch/i386/kernel/process]'',
che va poi a chiamare la System Call ''clone'' [arch/i386/kernel/process.c]
in assembler (che praticamente e' come la ''fork''):
<P>
<PRE>
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
        long retval, d0;
 
        __asm__ __volatile__(
                &quot;movl %%esp,%%esi\n\t&quot;
                &quot;int $0x80\n\t&quot;         /* Linux/i386 system call */
                &quot;cmpl %%esp,%%esi\n\t&quot;  /* child or parent? */
                &quot;je 1f\n\t&quot;             /* parent - jump */
                /* Load the argument into eax, and push it.  That way, it does
                 * not matter whether the called function is compiled with
                 * -mregparm or not.  */
                &quot;movl %4,%%eax\n\t&quot;
                &quot;pushl %%eax\n\t&quot;               
                &quot;call *%5\n\t&quot;          /* call fn */
                &quot;movl %3,%0\n\t&quot;        /* exit */
                &quot;int $0x80\n&quot;
                &quot;1:\t&quot;
                :&quot;=&amp;a&quot; (retval), &quot;=&amp;S&quot; (d0)
                :&quot;0&quot; (__NR_clone), &quot;i&quot; (__NR_exit),
                 &quot;r&quot; (arg), &quot;r&quot; (fn),
                 &quot;b&quot; (flags | CLONE_VM)
                : &quot;memory&quot;);
        return retval;
}
</PRE>
<P>Una volta chiamata, avremo un nuovo Task (di solito con PID molto basso,
come 2,3, ecc.) all'interno di un ciclo infinito in attesa di una risorsa molto
lenta, come lo swap o un evento usb (soltanto risorse lente altrimenti il tempo
di Task Switching potrebbe influenzare negativamente le prestazioni del sistema)
<P>Segue una lista dei piu' comuni Kernel Threads (dal comando ''ps x''):
<P>
<PRE>
PID      COMMAND
 1        init
 2        keventd
 3        kswapd
 4        kreclaimd
 5        bdflush
 6        kupdated
 7        kacpid
67        khubd
</PRE>
<P>'init' e' il primo processo creato, che chiamera' tutti gli altri Tasks
in User Modes (dal file /etc/inittab) come i demoni di console, di tty, di
rete e cosi' via (''rc'' scripts).
<H3>Esempio di Kernel Threads: kswapd [mm/vmscan.c].</H3>

<P>''kswapd'' viene creato dalla ''clone() [arch/i386/kernel/process.c]''
<P>Routines di inzializzazione:
<P>
<PRE>
|do_initcalls
   |kswapd_init
      |kernel_thread
         |syscall fork (in assembler)
</PRE>
<P>do_initcalls [init/main.c]
<P>kswapd_init [mm/vmscan.c]
<P>kernel_thread [arch/i386/kernel/process.c]
<H2><A NAME="ss5.5">5.5 Moduli del Kernel</A>
</H2>

<H3>Introduzione</H3>

<P>I Moduli del Kernel sono pezzi di codice (che gestiscono ad esempio fs,
net, e hw driver) che girano in Modo Kernel e che possono essere caricati in
qualunque momento.
<P>Quasi tutto il codice puo' essere modularizzato, tranne il core piu' interno
del Kernel, quello che gestisce scheduling, interrupt, core della rete, e cosi'
via.
<P>Nella directory "/lib/modules/KERNEL_VERSION/" si trovano tutti i moduli
installati nel sistema.
<H3>Inserimento e rimozione dei Moduli</H3>

<P>Per caricare un module, basta digitare:
<P>
<PRE>
insmod NOME_MODULO parametri

esempio: insmod ne io=0x300 irq=9
</PRE>
<P>NOTA: Si puo' utilizzare ''modprobe'' al posto di ''insmod'' per far caricare
alcuni parametri in automatico (come per le periferiche PCI, oppure quando
si specificano i parametri nel file /etc/conf.modules o nel nuovo /etc/modules.conf).
<P>Per rimuovere un modulo, digitare:
<P>
<PRE>
 rmmod NOME_MODULO
</PRE>
<H3>Definizione di un Modulo</H3>

<P>Un Module contiene sempre le funzioni
<P>
<OL>
<LI>''init_module'', eseguita dal comando ''insmod'' (o ''modprobe'')</LI>
<LI>''cleanup_module'' function, executed dal comando ''rmmod''</LI>
</OL>
<P>In alternativa si possono specificare altre funzioni di inizializzazione
e chiusura tramite le macro:
<P>
<OL>
<LI>module_init(FUNCTION_NAME)</LI>
<LI>module_exit(FUNCTION_NAME)</LI>
</OL>
<P>NOTA: un modulo puo' ''vedere'' le variabili del Kernel solo se queste
sono state precedentemente esportate (nella loro dichiarazione (con la macro
EXPORT_SYMBOL).
<H3>Un trucco utile per rendere piu' flessibile il Kernel</H3>

<P>
<PRE>
// Parte kernel
void (*foo_function_pointer)(void *);
 
if (foo_function_pointer)
  (foo_function_pointer)(parameter);
  
 


// Parte modulo
extern void (*foo_function_pointer)(void *);

void my_function(void *parameter) {
  //My code
}
 
int init_module() {
  foo_function_pointer = &amp;my_function;
}

int cleanup_module() {
  foo_function_pointer = NULL;
}
</PRE>
<P>Questo artifizio permette di rendere il Kernel piu' flessibile, perche'
soltanto quando si carica il modulo, la funzione ''my_function'' verra' effettivamente
eseguita: questa routine potra' fare qualunque cosa vogliamo, ad esempio il
modulo ''rshaper'' (per limitare il traffico in entrata dalla rete) funziona
in questo modo.
<P>Si noti come l'intero meccanismo dei moduli sia possibile grazie ad alcune
variabili globali nel kernel che vengono esportate ai moduli, come puntatori
a liste (permettendo di estendere tali liste quanto si vuole): esempi tipici
sono i fs e i devices (char, block, net, telephony). 
<P>In definitiva, per caricare un modulo, bisogna in qualche modo ''preparare
il kernel'' perche' lo accetti (se si vuole fargli fare qualcosa di interessante):
in alcuni casi e' necessario creare una nuova infrastruttura che sia poi il
piu' standard possibile (come quella ''telephony'' creata di recente).
<H2><A NAME="ss5.6">5.6 Directory Proc</A>
</H2>

<P>Nella directory /proc e' presente il FS proc, che e' un sistema speciale
per consentire il dialogo diretto con il Kernel in user mode.
<P>Linux utilizza tale directory, ad esempio per dialogare con le strutture
dati dei processi, per gestire le opzioni di rete delle interfacce come il
''proxy-arp'', il massimo numero di Threads, o per controllare lo state dei
bus ISA o PCI, per sapere quali schede sono installate nel sistema e con quali
indirizzi di I/O e IRQs
<P>Segue l'elenco delle sottodirectory piu' importanti della directory proc:
<P>
<PRE>
|-- bus
|   |-- pci
|   |   |-- 00
|   |   |   |-- 00.0
|   |   |   |-- 01.0
|   |   |   |-- 07.0
|   |   |   |-- 07.1
|   |   |   |-- 07.2
|   |   |   |-- 07.3
|   |   |   |-- 07.4
|   |   |   |-- 07.5
|   |   |   |-- 09.0
|   |   |   |-- 0a.0
|   |   |   `-- 0f.0
|   |   |-- 01
|   |   |   `-- 00.0
|   |   `-- devices
|   `-- usb
|-- cmdline
|-- cpuinfo
|-- devices
|-- dma
|-- dri
|   `-- 0
|       |-- bufs
|       |-- clients
|       |-- mem
|       |-- name
|       |-- queues
|       |-- vm
|       `-- vma
|-- driver
|-- execdomains
|-- filesystems
|-- fs
|-- ide
|   |-- drivers
|   |-- hda -&gt; ide0/hda
|   |-- hdc -&gt; ide1/hdc
|   |-- ide0
|   |   |-- channel
|   |   |-- config
|   |   |-- hda
|   |   |   |-- cache
|   |   |   |-- capacity
|   |   |   |-- driver
|   |   |   |-- geometry
|   |   |   |-- identify
|   |   |   |-- media
|   |   |   |-- model
|   |   |   |-- settings
|   |   |   |-- smart_thresholds
|   |   |   `-- smart_values
|   |   |-- mate
|   |   `-- model
|   |-- ide1
|   |   |-- channel
|   |   |-- config
|   |   |-- hdc
|   |   |   |-- capacity
|   |   |   |-- driver
|   |   |   |-- identify
|   |   |   |-- media
|   |   |   |-- model
|   |   |   `-- settings
|   |   |-- mate
|   |   `-- model
|   `-- via
|-- interrupts
|-- iomem
|-- ioports
|-- irq
|   |-- 0
|   |-- 1
|   |-- 10
|   |-- 11
|   |-- 12
|   |-- 13
|   |-- 14
|   |-- 15
|   |-- 2
|   |-- 3
|   |-- 4
|   |-- 5
|   |-- 6
|   |-- 7
|   |-- 8
|   |-- 9
|   `-- prof_cpu_mask
|-- kcore
|-- kmsg
|-- ksyms
|-- loadavg
|-- locks
|-- meminfo
|-- misc
|-- modules
|-- mounts
|-- mtrr
|-- net
|   |-- arp
|   |-- dev
|   |-- dev_mcast
|   |-- ip_fwchains
|   |-- ip_fwnames
|   |-- ip_masquerade
|   |-- netlink
|   |-- netstat
|   |-- packet
|   |-- psched
|   |-- raw
|   |-- route
|   |-- rt_acct
|   |-- rt_cache
|   |-- rt_cache_stat
|   |-- snmp
|   |-- sockstat
|   |-- softnet_stat
|   |-- tcp
|   |-- udp
|   |-- unix
|   `-- wireless
|-- partitions
|-- pci
|-- scsi
|   |-- ide-scsi
|   |   `-- 0
|   `-- scsi
|-- self -&gt; 2069
|-- slabinfo
|-- stat
|-- swaps
|-- sys
|   |-- abi
|   |   |-- defhandler_coff
|   |   |-- defhandler_elf
|   |   |-- defhandler_lcall7
|   |   |-- defhandler_libcso
|   |   |-- fake_utsname
|   |   `-- trace
|   |-- debug
|   |-- dev
|   |   |-- cdrom
|   |   |   |-- autoclose
|   |   |   |-- autoeject
|   |   |   |-- check_media
|   |   |   |-- debug
|   |   |   |-- info
|   |   |   `-- lock
|   |   `-- parport
|   |       |-- default
|   |       |   |-- spintime
|   |       |   `-- timeslice
|   |       `-- parport0
|   |           |-- autoprobe
|   |           |-- autoprobe0
|   |           |-- autoprobe1
|   |           |-- autoprobe2
|   |           |-- autoprobe3
|   |           |-- base-addr
|   |           |-- devices
|   |           |   |-- active
|   |           |   `-- lp
|   |           |       `-- timeslice
|   |           |-- dma
|   |           |-- irq
|   |           |-- modes
|   |           `-- spintime
|   |-- fs
|   |   |-- binfmt_misc
|   |   |-- dentry-state
|   |   |-- dir-notify-enable
|   |   |-- dquot-nr
|   |   |-- file-max
|   |   |-- file-nr
|   |   |-- inode-nr
|   |   |-- inode-state
|   |   |-- jbd-debug
|   |   |-- lease-break-time
|   |   |-- leases-enable
|   |   |-- overflowgid
|   |   `-- overflowuid
|   |-- kernel
|   |   |-- acct
|   |   |-- cad_pid
|   |   |-- cap-bound
|   |   |-- core_uses_pid
|   |   |-- ctrl-alt-del
|   |   |-- domainname
|   |   |-- hostname
|   |   |-- modprobe
|   |   |-- msgmax
|   |   |-- msgmnb
|   |   |-- msgmni
|   |   |-- osrelease
|   |   |-- ostype
|   |   |-- overflowgid
|   |   |-- overflowuid
|   |   |-- panic
|   |   |-- printk
|   |   |-- random
|   |   |   |-- boot_id
|   |   |   |-- entropy_avail
|   |   |   |-- poolsize
|   |   |   |-- read_wakeup_threshold
|   |   |   |-- uuid
|   |   |   `-- write_wakeup_threshold
|   |   |-- rtsig-max
|   |   |-- rtsig-nr
|   |   |-- sem
|   |   |-- shmall
|   |   |-- shmmax
|   |   |-- shmmni
|   |   |-- sysrq
|   |   |-- tainted
|   |   |-- threads-max
|   |   `-- version
|   |-- net
|   |   |-- 802
|   |   |-- core
|   |   |   |-- hot_list_length
|   |   |   |-- lo_cong
|   |   |   |-- message_burst
|   |   |   |-- message_cost
|   |   |   |-- mod_cong
|   |   |   |-- netdev_max_backlog
|   |   |   |-- no_cong
|   |   |   |-- no_cong_thresh
|   |   |   |-- optmem_max
|   |   |   |-- rmem_default
|   |   |   |-- rmem_max
|   |   |   |-- wmem_default
|   |   |   `-- wmem_max
|   |   |-- ethernet
|   |   |-- ipv4
|   |   |   |-- conf
|   |   |   |   |-- all
|   |   |   |   |   |-- accept_redirects
|   |   |   |   |   |-- accept_source_route
|   |   |   |   |   |-- arp_filter
|   |   |   |   |   |-- bootp_relay
|   |   |   |   |   |-- forwarding
|   |   |   |   |   |-- log_martians
|   |   |   |   |   |-- mc_forwarding
|   |   |   |   |   |-- proxy_arp
|   |   |   |   |   |-- rp_filter
|   |   |   |   |   |-- secure_redirects
|   |   |   |   |   |-- send_redirects
|   |   |   |   |   |-- shared_media
|   |   |   |   |   `-- tag
|   |   |   |   |-- default
|   |   |   |   |   |-- accept_redirects
|   |   |   |   |   |-- accept_source_route
|   |   |   |   |   |-- arp_filter
|   |   |   |   |   |-- bootp_relay
|   |   |   |   |   |-- forwarding
|   |   |   |   |   |-- log_martians
|   |   |   |   |   |-- mc_forwarding
|   |   |   |   |   |-- proxy_arp
|   |   |   |   |   |-- rp_filter
|   |   |   |   |   |-- secure_redirects
|   |   |   |   |   |-- send_redirects
|   |   |   |   |   |-- shared_media
|   |   |   |   |   `-- tag
|   |   |   |   |-- eth0
|   |   |   |   |   |-- accept_redirects
|   |   |   |   |   |-- accept_source_route
|   |   |   |   |   |-- arp_filter
|   |   |   |   |   |-- bootp_relay
|   |   |   |   |   |-- forwarding
|   |   |   |   |   |-- log_martians
|   |   |   |   |   |-- mc_forwarding
|   |   |   |   |   |-- proxy_arp
|   |   |   |   |   |-- rp_filter
|   |   |   |   |   |-- secure_redirects
|   |   |   |   |   |-- send_redirects
|   |   |   |   |   |-- shared_media
|   |   |   |   |   `-- tag
|   |   |   |   |-- eth1
|   |   |   |   |   |-- accept_redirects
|   |   |   |   |   |-- accept_source_route
|   |   |   |   |   |-- arp_filter
|   |   |   |   |   |-- bootp_relay
|   |   |   |   |   |-- forwarding
|   |   |   |   |   |-- log_martians
|   |   |   |   |   |-- mc_forwarding
|   |   |   |   |   |-- proxy_arp
|   |   |   |   |   |-- rp_filter
|   |   |   |   |   |-- secure_redirects
|   |   |   |   |   |-- send_redirects
|   |   |   |   |   |-- shared_media
|   |   |   |   |   `-- tag
|   |   |   |   `-- lo
|   |   |   |       |-- accept_redirects
|   |   |   |       |-- accept_source_route
|   |   |   |       |-- arp_filter
|   |   |   |       |-- bootp_relay
|   |   |   |       |-- forwarding
|   |   |   |       |-- log_martians
|   |   |   |       |-- mc_forwarding
|   |   |   |       |-- proxy_arp
|   |   |   |       |-- rp_filter
|   |   |   |       |-- secure_redirects
|   |   |   |       |-- send_redirects
|   |   |   |       |-- shared_media
|   |   |   |       `-- tag
|   |   |   |-- icmp_echo_ignore_all
|   |   |   |-- icmp_echo_ignore_broadcasts
|   |   |   |-- icmp_ignore_bogus_error_responses
|   |   |   |-- icmp_ratelimit
|   |   |   |-- icmp_ratemask
|   |   |   |-- inet_peer_gc_maxtime
|   |   |   |-- inet_peer_gc_mintime
|   |   |   |-- inet_peer_maxttl
|   |   |   |-- inet_peer_minttl
|   |   |   |-- inet_peer_threshold
|   |   |   |-- ip_autoconfig
|   |   |   |-- ip_conntrack_max
|   |   |   |-- ip_default_ttl
|   |   |   |-- ip_dynaddr
|   |   |   |-- ip_forward
|   |   |   |-- ip_local_port_range
|   |   |   |-- ip_no_pmtu_disc
|   |   |   |-- ip_nonlocal_bind
|   |   |   |-- ipfrag_high_thresh
|   |   |   |-- ipfrag_low_thresh
|   |   |   |-- ipfrag_time
|   |   |   |-- neigh
|   |   |   |   |-- default
|   |   |   |   |   |-- anycast_delay
|   |   |   |   |   |-- app_solicit
|   |   |   |   |   |-- base_reachable_time
|   |   |   |   |   |-- delay_first_probe_time
|   |   |   |   |   |-- gc_interval
|   |   |   |   |   |-- gc_stale_time
|   |   |   |   |   |-- gc_thresh1
|   |   |   |   |   |-- gc_thresh2
|   |   |   |   |   |-- gc_thresh3
|   |   |   |   |   |-- locktime
|   |   |   |   |   |-- mcast_solicit
|   |   |   |   |   |-- proxy_delay
|   |   |   |   |   |-- proxy_qlen
|   |   |   |   |   |-- retrans_time
|   |   |   |   |   |-- ucast_solicit
|   |   |   |   |   `-- unres_qlen
|   |   |   |   |-- eth0
|   |   |   |   |   |-- anycast_delay
|   |   |   |   |   |-- app_solicit
|   |   |   |   |   |-- base_reachable_time
|   |   |   |   |   |-- delay_first_probe_time
|   |   |   |   |   |-- gc_stale_time
|   |   |   |   |   |-- locktime
|   |   |   |   |   |-- mcast_solicit
|   |   |   |   |   |-- proxy_delay
|   |   |   |   |   |-- proxy_qlen
|   |   |   |   |   |-- retrans_time
|   |   |   |   |   |-- ucast_solicit
|   |   |   |   |   `-- unres_qlen
|   |   |   |   |-- eth1
|   |   |   |   |   |-- anycast_delay
|   |   |   |   |   |-- app_solicit
|   |   |   |   |   |-- base_reachable_time
|   |   |   |   |   |-- delay_first_probe_time
|   |   |   |   |   |-- gc_stale_time
|   |   |   |   |   |-- locktime
|   |   |   |   |   |-- mcast_solicit
|   |   |   |   |   |-- proxy_delay
|   |   |   |   |   |-- proxy_qlen
|   |   |   |   |   |-- retrans_time
|   |   |   |   |   |-- ucast_solicit
|   |   |   |   |   `-- unres_qlen
|   |   |   |   `-- lo
|   |   |   |       |-- anycast_delay
|   |   |   |       |-- app_solicit
|   |   |   |       |-- base_reachable_time
|   |   |   |       |-- delay_first_probe_time
|   |   |   |       |-- gc_stale_time
|   |   |   |       |-- locktime
|   |   |   |       |-- mcast_solicit
|   |   |   |       |-- proxy_delay
|   |   |   |       |-- proxy_qlen
|   |   |   |       |-- retrans_time
|   |   |   |       |-- ucast_solicit
|   |   |   |       `-- unres_qlen
|   |   |   |-- route
|   |   |   |   |-- error_burst
|   |   |   |   |-- error_cost
|   |   |   |   |-- flush
|   |   |   |   |-- gc_elasticity
|   |   |   |   |-- gc_interval
|   |   |   |   |-- gc_min_interval
|   |   |   |   |-- gc_thresh
|   |   |   |   |-- gc_timeout
|   |   |   |   |-- max_delay
|   |   |   |   |-- max_size
|   |   |   |   |-- min_adv_mss
|   |   |   |   |-- min_delay
|   |   |   |   |-- min_pmtu
|   |   |   |   |-- mtu_expires
|   |   |   |   |-- redirect_load
|   |   |   |   |-- redirect_number
|   |   |   |   `-- redirect_silence
|   |   |   |-- tcp_abort_on_overflow
|   |   |   |-- tcp_adv_win_scale
|   |   |   |-- tcp_app_win
|   |   |   |-- tcp_dsack
|   |   |   |-- tcp_ecn
|   |   |   |-- tcp_fack
|   |   |   |-- tcp_fin_timeout
|   |   |   |-- tcp_keepalive_intvl
|   |   |   |-- tcp_keepalive_probes
|   |   |   |-- tcp_keepalive_time
|   |   |   |-- tcp_max_orphans
|   |   |   |-- tcp_max_syn_backlog
|   |   |   |-- tcp_max_tw_buckets
|   |   |   |-- tcp_mem
|   |   |   |-- tcp_orphan_retries
|   |   |   |-- tcp_reordering
|   |   |   |-- tcp_retrans_collapse
|   |   |   |-- tcp_retries1
|   |   |   |-- tcp_retries2
|   |   |   |-- tcp_rfc1337
|   |   |   |-- tcp_rmem
|   |   |   |-- tcp_sack
|   |   |   |-- tcp_stdurg
|   |   |   |-- tcp_syn_retries
|   |   |   |-- tcp_synack_retries
|   |   |   |-- tcp_syncookies
|   |   |   |-- tcp_timestamps
|   |   |   |-- tcp_tw_recycle
|   |   |   |-- tcp_window_scaling
|   |   |   `-- tcp_wmem
|   |   `-- unix
|   |       `-- max_dgram_qlen
|   |-- proc
|   `-- vm
|       |-- bdflush
|       |-- kswapd
|       |-- max-readahead
|       |-- min-readahead
|       |-- overcommit_memory
|       |-- page-cluster
|       `-- pagetable_cache
|-- sysvipc
|   |-- msg
|   |-- sem
|   `-- shm
|-- tty
|   |-- driver
|   |   `-- serial
|   |-- drivers
|   |-- ldisc
|   `-- ldiscs
|-- uptime
`-- version
</PRE>
<P>Nella directory sono presenti anche tutti i Tasks attivi tramite il PID
(che funge da nome della directory) tramite cui si puo' avere accesso alle
informazioni relative ai Tasks, come percorso del file binario, memoria usata
e cosi' via).
<P>Il punto piu' interessante e' che non e' soltanto possibile ''vedere''
alcuni valori, ma anche modificarli, come quelli nella sottodirectory /proc/sys:
<P>
<PRE>
/proc/sys/ 
          acpi
          dev
          debug
          fs
          proc
          net
          vm
          kernel
</PRE>
<H3>/proc/sys/kernel</H3>

<P>Sotto seguono alcuni file utili per modificare dei settaggi del kernel:
<P>
<PRE>
overflowgid
overflowuid
random
threads-max // Massimo numero dei Threads, tipicamente 16384
sysrq // kernel hack: per consultare istantaneamente i valori dei registri del processore
sem
msgmnb
msgmni
msgmax
shmmni
shmall
shmmax
rtsig-max
rtsig-nr
modprobe // percorso di modprobe
printk
ctrl-alt-del
cap-bound
panic
domainname // domain name del Linux box
hostname // host name del Linux box
version // data del Kernel
osrelease // versione del kernel (i.e. 2.4.5)
ostype // Linux!
</PRE>
<H3>/proc/sys/net</H3>

<P>Questa puo' essere cosiderate la piu' utile sottodirectory del kernel:
permette di cambiare alcuni importanti settaggi della rete del Kernel:
<P>
<PRE>
core
ipv4
ipv6
unix
ethernet
802
</PRE>
<H3>/proc/sys/net/core</H3>

<P>Sotto sono elencati alcuni settaggi di rete generali come "netdev_max_backlog"
(tipicamente) che indica la lunghezza massima della coda di tutti i pacchetti
di rete. Questo valore puo' limitare la banda della rete quando si ricevono
i pacchetti, perche' Linux deve attendere fino al successivo tempo di schedulazione
(1000/HZ ms) per poter svuotare tale buffer di pacchetti (per il meccanismo
del bottom half).
<P>
<PRE>
  300    *        100             =     30 000
pacchetti    HZ(freq Timeslice)         pacchetti/s
 
30 000   *       1000             =      30 M
pacchetti     Media(Bytes/packet)   throughput Bytes/s
</PRE>
<P>Per aumentare le prestazioni bisogna aumentare necessariamente il valore
di netdev_max_backlog, digitando:
<P>
<PRE>
echo 4000 &gt; /proc/sys/net/core/netdev_max_backlog
</PRE>
<P>Nota: Attenzione ai valori di HZ: alcune architetture (come alpha o arm-tbox)
utilizzano 1000, che permettono quindi di arrivare a 300 MBytes/s di banda
media.
<H3>/proc/sys/net/ipv4</H3>

<P>"ip_forward", abilita o disabilita l'ip forwarding nel Linux box: questo
e' un settaggio generale, ma e' possibile specificare per ogni interfaccia
un valore diverso.
<H3>/proc/sys/net/ipv4/conf/interface</H3>

<P>Ritengo questo sia la directory /proc piu' utile, in quanto permette di
cambiare molti settaggi di rete utili soprattutto in caso di reti wireless
(si veda il 
<A HREF="http://bertolinux.fatamorgana.com/wireless/italiano">Wireless-HOWTO</A> per maggiori informazioni).
<P>Ecco alcuni esempi di utilizzo:
<P>
<UL>
<LI>"forwarding", per abilitare l'ip forwarding per una singola interfaccia</LI>
<LI>"proxy_arp", to abilitare o disabilitare il proxy arp. Per ulteriori informazioni
sul Proxy arp si cerchi il Proxyarp-HOWTO su 
<A HREF="http://www.linuxdoc.org">Linux Documentation Project</A> e 
<A HREF="http://bertolinux.fatamorgana.com/wireless/italiano">Wireless-HOWTO</A> per l'utilizzo del proxy arp
nelli reti Wireless.</LI>
<LI>"send_redirects" per evitare che le interfacce mandino i pacchetti di tipo
ICMP_REDIRECT (come prima si veda 
<A HREF="http://bertolinux.fatamorgana.com/wireless/italiano">Wireless-HOWTO</A> per maggiori informazioni).</LI>
</UL>
<HR>
<A HREF="KernelAnalysis-HOWTO-6.html">Avanti</A>
<A HREF="KernelAnalysis-HOWTO-4.html">Indietro</A>
<A HREF="KernelAnalysis-HOWTO.html#toc5">Indice</A>
</BODY>
</HTML>