<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>The Linux Kernel HOWTO: Applicare una patch al kernel </TITLE> <LINK HREF="Kernel-HOWTO-7.html" REL=next> <LINK HREF="Kernel-HOWTO-5.html" REL=previous> <LINK HREF="Kernel-HOWTO.html#toc6" REL=contents> </HEAD> <BODY> <A HREF="Kernel-HOWTO-7.html">Avanti</A> <A HREF="Kernel-HOWTO-5.html">Indietro</A> <A HREF="Kernel-HOWTO.html#toc6">Indice</A> <HR> <H2><A NAME="s6">6. Applicare una patch al kernel </A></H2> <P> <P> <H2><A NAME="ss6.1">6.1 Applicare una patch </A> </H2> <P> <P>Gli aggiornamenti incrementali del kernel sono distribuiti come patch (NdT letteralmente "toppe"). Per esempio, se si ha la versione 1.1.45 e si ha notizia che c'è una "<CODE>patch46.gz</CODE>" in giro, significa che si può aggiornare alla versione 1.1.46 applicando quella patch. Prima può essere una buona idea fare una copia di backup dell'albero dei sorgenti ("<CODE>make clean</CODE>" e poi "<CODE>cd /usr/src; tar zcvf old-tree.tar.gz linux</CODE>" creerà un archivio compresso). <P> <P>Così, continuando con l'esempio precedente, si supponga di avere "<CODE>patch46.gz</CODE>" in <CODE>/usr/src</CODE>. Si dia "<CODE>cd /usr/src</CODE>" e si esegua "<CODE>zcat patch46.gz | patch -p0</CODE>" (o "<CODE>patch -p0 < patch46</CODE>" se la patch non è compressa). Si vedranno sfrecciare (o fluttuare, se il proprio sistema è abbastanza lento) delle scritte che dicono che sta provando ad applicare dei pezzi ("hunk") e quando ha o meno successo. Solitamente questa azione è troppo veloce per poterla leggere ed è difficile essere sicuri se ha funzionato o meno, quindi può essere un'idea usare l'opzione <CODE>-s</CODE>, che dice a <CODE>patch</CODE> di riportare solo i messaggi d'errore. Per cercare le parti che non sono andate a buon fine, si passi in <CODE>/usr/src/linux</CODE> e si cerchino i file con estensione <CODE>.rej</CODE>. Alcune versioni di <CODE>patch</CODE> (versioni più vecchie che possono essere state compilate con un filesystem inferiore) lasciano scarti con un'estensione <CODE>#</CODE>. Si può usare "<CODE>find</CODE>" per la ricerca: <PRE> find . -name '*.rej' -print </PRE> mostrerà nello standard output tutti i file residenti nella directory corrente e in ogni sottodirectory con estensione <CODE>.rej</CODE>. <P> <P>Se tutto va a buon fine, si faccia "<CODE>make clean</CODE>", "<CODE>config</CODE>" e "<CODE>dep</CODE>" come descritto nelle sezioni 3 e 4. <P> <P>Ci sono alcune altre opzioni per il comando <CODE>patch</CODE>. Come menzionato prima, <CODE>patch -s</CODE> sopprimerà tutti messaggi tranne quelli d'errore. Se si conservano i sorgenti del kernel in un posto diverso da <CODE>/usr/src/linux</CODE>, <CODE>patch -p1</CODE> (in quella directory) applicherà correttamente la patch. Altre opzioni di <CODE>patch</CODE> sono ben documentate nella pagina di man. <P> <P> <H2><A NAME="ss6.2">6.2 Se qualcosa va storto </A> </H2> <P> <P>(Nota: questa sezione fa riferimento principalmente a kernel piuttosto vecchi) <P> <P>Il problema più frequente che solitamente compariva quando una patch modificava un file chiamato "<CODE>config.in</CODE>" e questo non sembrava più essere a posto, perché lo si era modificato per adattarlo alla propria macchina. Di questo ora si tiene conto, ma si potrebbe ancora incontrare con vecchie release. Per correggerlo, si veda il file <CODE>config.in.rej</CODE> e si veda cosa rimane della patch originale. Le modifiche saranno tipicamente marcate con "<CODE>+</CODE>" e "<CODE>-</CODE>" all'inizio di ciascuna riga. Si vedano le righe là attorno e si ricordi se erano state impostate a "<CODE>y</CODE>" o "<CODE>n</CODE>". Ora si modifichi il <CODE>config.in</CODE>, e si cambi "<CODE>y</CODE>" in "<CODE>n</CODE>" e "<CODE>n</CODE>" in "<CODE>y</CODE>" quando appropriato. Si faccia un <PRE> patch -p0 < config.in.rej </PRE> e, se finisce con successo, si può continuare con la configurazione e la compilazione. Il file <CODE>config.in.rej</CODE> rimarrà, ma si può cancellarlo. <P> <P>Se si incontrano ulteriori problemi, si può aver installato una patch "fuori uso". Se patch dice "<CODE>previously applied patch detected: Assume -R?</CODE>" (rilevata una patch applicata precedentemente: assumo -R?), probabilmente si sta provando ad applicare una patch precedente al numero di versione corrente; se si risponde "<CODE>y</CODE>" proverà a degradare i sorgenti e molto probabilmente fallirà; sarà quindi necessario prendere in blocco un nuovo albero dei sorgenti (poteva non essere una cattiva idea sin dall'inizio). <P> <P>Per tornare indietro di una patch, disapplicandola, si usi "<CODE>patch -R</CODE>" sulla patch originale. <P> <P>La miglior cosa da fare quando le patch fanno realmente casino è di ripartire da un albero dei sorgenti nuovo di zecca (per esempio, da uno dei file <CODE>linux-x.y.z.tar.gz</CODE>) e ricominciare. <P> <P> <H2><A NAME="ss6.3">6.3 Sbarazzarsi dei file .orig </A> </H2> <P> <P>Già dopo poche patch, i file <CODE>.orig</CODE> cominciano ad ammucchiarsi. Per esempio, un albero 1.1.51 che ho ripulito l'ultima volta quand'era 1.1.48: rimuovendo i file .orig ho recuperato oltre 500 Kbyte. <PRE> find . -name '*.orig' -exec rm -f {} ';' </PRE> se ne occuperà al vostro posto. Le versioni di <CODE>patch</CODE> che usano <CODE>#</CODE> per gli scarti usano una tilde invece di <CODE>.orig</CODE>. <P>Ci sono modi migliori per sbarazzarsi dei file <CODE>.orig</CODE>, che dipendono da GNU <CODE>xargs</CODE>: <PRE> find . -name '*.orig' | xargs rm </PRE> o il metodo "piuttosto sicuro ma un po' più prolisso": <PRE> find . -name '*.orig' -print0 | xargs --null rm -- </PRE> <P> <P> <H2><A NAME="ss6.4">6.4 Altre patch </A> </H2> <P> <P>Esistono altre patch (io le chiamo "non standard") oltre a quelle che distribuisce Linus. Se le si applica, le patch di Linus potrebbero non funzionare correttamente e si dovrà o tornare indietro, correggere i sorgenti o la patch, installare un nuovo albero dei sorgenti o una combinazione di queste cose. Ciò può divenire abbastanza frustrante, se non si vogliono modificare i sorgenti (con il rischio di ottenere pessimi risultati), si rimuovano le patch non standard prima di applicare quelle di Linus, o semplicemente si installi un nuovo albero. Poi, si può provare a vedere se le patch non standard funzionano ancora. Se non lo fanno, o si resta con il vecchio kernel, giochicchiando con la patch e i sorgenti per farli funzionare, o si aspetta (probabilmente elemosinando) che esca una nuova versione della patch. <P> <P>Quanto comuni sono le patch che non sono nella distribuzione standard? Probabilmente se n'è sentito parlare. Ero avvezzo ad usare la patch noblink per le mie console virtuali perché odio il cursore lampeggiante (questa patch è, o almeno era, aggiornata frequentemente per le nuove release del kernel). Con la maggior parte dei device driver sviluppati come moduli caricabili, la frequenza di patch "non standard" è diminuita significativamente. <P> <P> <HR> <A HREF="Kernel-HOWTO-7.html">Avanti</A> <A HREF="Kernel-HOWTO-5.html">Indietro</A> <A HREF="Kernel-HOWTO.html#toc6">Indice</A> </BODY> </HTML>