Gentoo Logo

Guida al Prelink in Gentoo Linux

Indice:

1.  Introduzione

Cos'è il prelink e come può essermi d'aiuto?

Le più comuni applicazioni utilizzano librerie condivise. Queste librerie condivise devono essere caricate in memoria durante l'esecuzione ed i vari simboli e riferimenti devono essere risolti. Per la maggior parte dei piccoli programmi tale linking dinamico è molto veloce, ma per i programmi scritti in C++ che dipendono da molte librerie, il linking dinamico può richiedere una discreta quantità di tempo.

Nella maggior parte dei sistemi le librerie non vengono modificate molto spesso e, quando un programma è avviato, le operazioni effettuate per il linking sono sempre le stesse. Il prelink sfrutta questa particolarità estraendo le informazioni relative al linking e memorizzandole nell'eseguibile, prelinkandolo, appunto.

Il prelinking può accorciare il tempo di apertura delle applicazioni. Ad esempio, il tempo di caricamento di un qualsiasi programma KDE può essere abbreviato fino al 50%. Le uniche operazioni di manutenzione richieste prevedono di lanciare prelink ogni volta che una libreria di un eseguibile prelinkato viene aggiornata.

Avvertenza: Prelink non funzionerà con Gentoo Hardened. Questo avviene perchè entrambi i progetti tentano di cambiare la mappatura dello spazio di indirizzamento delle librerie condivise. Tuttavia prelink, tramite l'opzione -R, rende casuale gli indirizzi di base delle librerie, fornendo un livello minimo di blindatura e protezione.

In breve

  • Il prelinking viene effettuato attraverso un programma chiamato, sorprendentemente, prelink, che modifica gli eseguibili per farli partire più velocemente.
  • Se una libreria da cui dipende un'applicazione viene modificata dopo il prelink, è necessario prelinkare nuovamente l'eseguibile, altrimenti si perdono i vantaggi in termini di prestazioni. In altre parole, ogni volta che viene aggiornato con portage un pacchetto che aggiorna delle librerie, è necessario effettuare nuovamente il prelink.
  • I cambiamenti agli eseguibili sono completamente reversibili. prelink ha una funzione di "undo" (annullamento dei cambiamenti, ndt).
  • Le versione corrente di Portage tratta correttamente, attraverso prelink, i cambiamenti di MD5sum e mtime degli eseguibili.
  • Non è necessario impostare FEATURES="prelink" in make.conf: Portage si appoggerà automaticamente a prelink se troverà il file binario 'prelinkato'.

2.  Impostare il Prelink

Installare i programmi

Per iniziare è necessario installare prelink. Durante l'esecuzione, emerge verifica automaticamente che prelink sia supportato dal proprio sistema.

Codice 2.1: Installazione di prelink

# emerge prelink

Molte persone hanno problemi effettuando l'emerge di prelink perché i test effettuati falliscono. I test sono stati inseriti per motivi di sicurezza e il comportamento di prelink è imprevedibile se vengono disabilitati. Gli errori di emerge sono di solito relativi a pacchetti fondamentali come binutils, gcc e glibc. Provare ad effettuare l'emerge di questi pacchetti in tale ordine.

Nota: Consiglio: Se si ottengono degli errori provare a compilare e testare prelink manualmente (./configure ; make ; make check ). In caso di problemi consultare i file *.log nella directory testsuite, che potrebbero fornire alcuni utili suggerimenti.

Se si può riprodurre passo passo un errore di emerge su un altro sistema controllare Bugzilla e creare un nuovo bug report, nel caso non ce ne fossero di già esistenti.

Preparare il sistema

Assicurarsi anche di non avere -fPIC nelle CFLAGS/CXXFLAGS. Se così fosse, bisognerà togliere -fPIC e ricompilare l'intero sistema.

Configurazione

L'esecuzione di env-update genera il file /etc/prelink.conf da cui prelink rileva i file da prelinkare.

Codice 2.2: Eseguire env-update

# env-update

Purtroppo non è possibile abilitare il prelink per file compilati con vecchie versioni di binutils. La maggior parte di queste applicazioni proviene da pacchetti precompilati o binary-only, che sono installati in /opt. Creando il seguente file è possibile evitare che prelink tenti di prelinkarli.

Codice 2.3: /etc/env.d/60prelink

PRELINK_PATH_MASK="/opt"

Nota: È possibile aggiungere altre directory separandole con i due punti (:).

3.  Prelinking

Utilizzo di prelink

L'autore di queesto documento utilizza il seguente comando per prelinkare tutti gli eseguibili nelle directory elencate da /etc/prelink.conf.

Codice 3.1: Prelink dei file elencati

# prelink -amR

Avvertenza: È stato osservato che se si dispone di poco spazio libero su disco e si prelinka l'intero sistema è possibile che gli eseguibili vengano troncati. Il risultato finale è un sistema corrotto. Utilizzare i comandi file o readelf per verificare lo stato dei file binari. In alternativa, controllare lo spazio libero su disco con df -h prima di procedere.

La spiegazione delle opzioni:
-a "All": prelinka tutti i binari.
-m Conserva lo spazio in memoria virtuale. È necessario se ci sono molte librerie che hanno bisogno di essere prelinkate.
-R Random -- rende casuale l'ordinamento degli indirizzi, in modo da aumentare la sicurezza verso i buffer overflow.

Nota: Per maggiori opzioni e gli altri dettagli, utilizzare man prelink.

Prelink Cron Job

sys-devel/prelink-20060213 e successivi installano un cron job in /etc/cron.daily/prelink. Per abilitarlo, modificare il file di configurazione /etc/conf.d/prelink. Questo farà eseguire prelink giornalmente in background, facendo risparmiare all'utente il tempo di doverlo eseguire manualmente.

Incrementare le Prestazioni di KDE dopo il Prelinking

Dopo il prelinking è possibile ridurre il tempo di caricamento di KDE. Se KDE rileva di essere stato prelinkato allora disabiliterà il caricamento di kdeinit (visto che non è più necessario) con un incremento delle sue prestazioni.

Per fare in modo che KDE rilevi il prelinking impostare KDE_IS_PRELINKED=1 in /etc/env.d/*kdepaths*.

Rimuovere prelink

Se si cambia idea riguardo all'uso di prelink, prima di disinstallarlo bisogna prima rimuovere il cronjob di prelink da /etc/cron.daily e /etc/conf.d/prelink. Successivamente bisogna rimuovere il prelink da tutti i binari:

Codice 3.2: Rimuovere il prelink da tutti i binari

# prelink -au

Come ultima cosa, disinstallare il pacchetto prelink stesso:

Codice 3.3: Disinstallare prelink

# emerge -aC prelink

4.  Problemi Noti e Soluzioni

"Impossibile prelinkare con librerie condivise non-PIC"

La causa di questo problema è l'errata compilazione di librerie condivise, senza l'opzione -fPIC di gcc per tutti i relativi file oggetto.

Qui ci sono le librerie che non sono state corrette o non possono essere corrette:

  • Le librerie nel pacchetto wine, incluso winex. Il prelinking non velocizzerebbe comunque gli eseguibili MS Windows.
  • Le librerie in media-video/mjpegtools, /usr/lib/liblavfile-1.6.so.0.
  • Le librerie OpenGl Nvidia, /usr/lib/opengl/nvidia/lib/libGL.so.*. A causa di problemi prestazionali, saranno compilare senza il supporto a PIC.

Se le librerie che danno problemi non sono elencate, segnalarle tramite un bug report su Bugzilla ed allegare, preferibilmente, una patch per aggiungere -fPIC alle relative CFLAGS.

Quando prelinko il mio sistema alcuni binari statici non funzionano più

Quando si ha a che fare con le glibc, non si ottiene mai un binario statico al 100%. Anche se si compila staticamente un binario con glibc, potrebbe ancora dipendere da altri file di sistema. Ecco una spiegazione di Dick Howell,

"Generalmente si presuppone che tutto il necessario sia contenuto nel file scaricato, in modo che l'applicazione non dipenda da librerie installate sul sistema locale. Sfortunatamente in Linux, e credo in qualsiasi altro sistema usi le glibc, ciò non è del tutto vero. Ad esempio "libnss" (name service switch, chiamata da alcuni network security system), che fornisce delle funzioni per accedere a diversi database per l'autenticazione, informazioni di rete ed altro, dovrebbe creare applicazioni indipendenti dall'effettivo ambiente di rete di una macchina. Una bella idea, ma modifiche alle glibc possono generare problemi nel tentativo di caricarla. E non è possibile linkare staticamente "libnss", poiché è configurata per ogni macchina individualmente. Credo che il problema derivi principalmente dal linkare staticamente altre librerie glibc, in particolare "libpthread", "libm" e "libc", da cui provengono chiamate incompatibili a funzioni di "libnss"."

Prelink si blocca con l'errore "prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed."

Questo problema è noto e ben documentato qui. Prelink non funziona con eseguibili compressi in formato UPX. Per ora (prelink-20021213) non esiste alcuna soluzione eccetto quella di nascondere a prelink gli eseguibili in questione. Leggi la sezione Configurazione per sapere come farlo facilmente.

Uso grsecurity e sembra che il prelinking non funzioni.

Per prelinkare su un sistema con grsecurity che utilizza chiamate mmap() casuali è necessario disattivare "randomized mmap() base" per /lib/ld-2.3.*.so. Per fare ciò, utilizzare il tool chpax quando tali file non sono in uso (ad esempio, facendo il boot da un CD di ripristino).

Prelink fallisce con l'errore "prelink: Can't walk directory tree XXXX: Too many levels of symbolic links"

I propri link simbolici sono annidati troppo in profondità. Questo succede quando un link simbolico punta a sè stesso. Per esempio, /usr/lib/lib -> lib è il più comune. Per risolvere il problema, bisogna trovare manualmente il collegamento simbolico o usare lo strumento fornito dal pacchetto symlinks:

Codice 4.1: Correggere i collegamenti simbolici

# emerge symlinks
# symlinks -drv /

Ulteriori dettagli si trovano in Bugzilla e in questa discussione del forum.

5.  Conclusioni

Il prelinking può velocizzare notevolmente il tempo di avvio di numerose applicazioni complesse e portage supporta nativamente questa tecnologia. Inoltre il prelinking è sicuro, perché è sempre possibile annullarlo per i binari che presentano problemi. Ricordarsi che, se le glibc o altre librerie prelinkate vengono aggiornate, è necessario eseguire nuovamente prelink! Buona fortuna!



Stampa

Aggiornato il 12 gennaio 2010

La versione originale di questo documento non è più mantenuta

Oggetto: Questa guida documenta come utilizzare il supporto al prelink in portage 2.0.46 e successivi.

Stefan Jones
Autore

John P. Davis
Redazione

Jorge Paulo
Redazione

Sven Vermeulen
Redazione

Erwin
Redazione

Joshua Saddler
Redazione

Davide Cendron
Traduzione

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.