Oops del kernel all’avvio della VPN: prove che vale la pena conservare
Un crash all’avvio della VPN richiede la build del kernel corrispondente e la prima traccia, non uno screenshot dell’ultima riga. Decidete cosa salvare prima di riavviare di nuovo.
Avviare il client VPN è un timestamp comodo, non una causa, e questa distinzione decide cosa succede dopo. Quando un Oops del kernel cade vicino a quel momento, la scelta è tra raccogliere un rapporto di guasto utilizzabile e provocare lo stesso crash altre cinque volte su una macchina di produzione. Salvate quattro cose prima di riavviare: la build esatta del kernel, la prima traccia del guasto, lo stato di taint e una breve descrizione di tutto il resto che è cambiato nello stesso minuto. Il resto è interpretazione, e l’interpretazione può aspettare che le prove siano in un posto sicuro.
Catturate il primo guasto, non l’ultima riga
Il primo Oops nel registro è quello che conta, perché ogni guasto successivo può essere un danno collaterale di un kernel già malsano. Copiate l’intestazione insieme alla traccia delle chiamate, dato che l’intestazione porta l’istruzione guasta e lo stato dei registri che identificano il percorso del codice. Un rapporto che inizia dall’ultima riga vale molto poco per chi lo leggerà una settimana dopo.
Se la macchina si è già riavviata, il buffer del kernel dell’avvio precedente è spesso ancora nel journal, purché all’epoca fosse abilitata l’archiviazione persistente. Leggetelo dal file salvato invece di ricreare il carico di lavoro, perché una seconda riproduzione può sovrascrivere ciò che vi serve. Dove la macchina non può tenere un journal tra i riavvii, una console seriale o netconsole è l’unico modo per rendere il guasto visibile.
Fissate la build prima di leggere qualsiasi simbolo
I nomi delle funzioni e gli offset hanno senso solo rispetto al binario che li ha prodotti, quindi annotate insieme la stringa di versione del kernel e l’identificatore di build della distribuzione. Un file di simboli di un’altra build punta alla riga sbagliata con piena fiducia, il che è peggio che non avere alcun simbolo. Conservate la versione del pacchetto kernel, non solo il numero upstream, perché le distribuzioni fanno molti backport.
I moduli fuori dall’albero meritano una riga propria nel verbale, dato che un kernel marcato limita ciò che un manutentore può concludere. Leggete il valore di taint invece di dedurlo da un elenco di moduli.
Un taint diverso da zero non è un’accusa e non rende il rapporto inutile. Dice al lettore quali componenti erano caricati quando è avvenuto il guasto, e alcuni flag fanno sì che un rapporto venga declassato per politica e non per giudizio. Annotate il valore, i nomi dei moduli e se lo stesso hardware e lo stesso carico abbiano mai eseguito un kernel senza di essi. È proprio quest’ultimo confronto a separare una nuova regressione da un difetto di vecchia data.
Separiate un innesco da un difetto
Avviare il tunnel di solito esercita un percorso che esisteva già: un driver di rete, una disciplina di coda, una funzione di offload o uno stato di alimentazione. L’innesco spiega quando compare il guasto, non quale codice è sbagliato, e trattare l’innesco come la causa porta a una serie di modifiche di configurazione che non risolvono nulla.
Un’immagine precedente funzionante è una prova, non una dimostrazione. Cambiate un componente per avvio quando confrontate, e conservate i risultati in un posto che sopravviva alla macchina.
Verificate cosa può davvero usare il manutentore
Leggete il rapporto come lo leggerebbe un estraneo prima di inviarlo. Se la configurazione, la sequenza esatta e l’identità della build sono presenti, e le credenziali sono state rimosse, il rapporto è utilizzabile. Se è uno screenshot di una traccia di stack, tornerà con una richiesta delle stesse informazioni. La guida alla ricerca dei bug del kernel descrive come sono una traccia utile e simboli corrispondenti.
uname -r
cat /proc/sys/kernel/tainted
journalctl -k -b -1 --no-pager | sed -n '/BUG:/,/Call Trace/p'
dmesg -T | grep -A 40 'RIP:'
Ogni comando sopra legge solo lo stato, e i primi due dovrebbero essere eseguiti prima del prossimo riavvio se la macchina può ancora rispondervi. Dove il journal non è persistente, quei due sono gli unici che funzioneranno mai di nuovo.
Rimuovete chiavi, password e traffico non correlato, ma conservate i nomi delle funzioni e gli offset che servono a qualcuno per leggere la traccia. Inviate il materiale attraverso il canale di segnalazione che vale per la distribuzione o per il kernel, non con un incollaggio pubblico corredato di un nome host. Poi aspettate una domanda invece di raccogliere altri crash, perché un guasto localizzato contro una build corrispondente è l’unico risultato che fa avanzare il rapporto. Se non torna nulla, l’alternativa è una riproduzione controllata su hardware di riserva, mai sulla macchina da cui dipendono altre persone.