juli 2010 Archieven
Op zoek naar de bron van de datacorruptie...
Thuis gebruik ik al jaren met veel plezier mythtv (http://www.mythtv.org) op een Linux systeem als videorecorder. We kijken bijna nooit meer live TV, het meest recente journaal staat altijd klaar, en reclames spoelen we zo door omdat mythtv die voor ons markeert.
Op een zeker moment begonnen nieuwe opnamen her en der "blokjes" te vertonen. Van die typische MPEG-artefacten die je ook wel eens bij satelliet-TV ziet als het weer erg slecht is, of bij DVB-T (Digitenne en dergelijke) als een slecht afgeschermde brommer voorbij komt rijden.
Toen ik als test een aantal video-files naar een andere machine
kopieerde om dáár het bestand beter te bekijken, gaf rsync af en
toe foutmeldingen dat het kopieren niet goed gelukt was: de checksum
aan beide zijden was niet hetzelfde.
Pardon?
Er leek dus iets mis met de hardware. Het geheugen is het makkelijkst te testen. Ik heb memtest86 (http://www.memtest86.com/) een dag laten draaien om het geheugen te testen. Geen enkel probleem.
Dan de disk. In de logfiles was niets te zien. Het viel het me wel op
(bij de vele keren rebooten) dat er af en toe een filesystem op de
disk corrupt was. smartctl wist me te vertellen dat de disk zelf
niet het idee had dat hij "bijna defect" zou zijn. En bij het
controleren van de disk gekoppeld aan een ander systeem vond ook
badblocks dat er niets aan de hand was. Ook andere intensieve tests
op de disk aan een ander systeem lieten geen disk-problemen zien.
Vreemd.
De laatste test die ik deed gaf uitsluitsel. Ik schreef een klein programmaatje dat willekeurige bytes in een file zet:
#include <stdlib.h>
#include <stdio.h>
int main() {
srandom(0);
const int n=1024;
short ar[n];
long long i;
int idx;
for (i=0, idx=0; i<2L*1024*1024*1024 / sizeof(ar[0]); ++i) {
ar[idx++]=random();
if (idx==n) {
write(1, ar, sizeof(ar));
idx=0;
}
}
}
Dit programma schrijft 2GiB aan pseudo-willekeurige bytes naar
standard output. Die gegenereerde random getallen zijn voorspelbaar
als je het begingetal kent. Ze zijn niet goed genoeg voor
cryptografische doeleinden, maar wel goed genoeg om reproduceerbaar,
min of meer willekeurige bytes te maken. Iedere keer dat het
programma start, krijg je bij hetzelfde begingetal dezelfde reeks.
Dat begingetal wordt gezet met de functie srandom. Hier gebruiken
we het begingetal 0. De 2GiB aan gegenereerde data kun je vervolgens
in een file zetten:
./randfile > OUT
Door het programma nogmaals te draaien (met hetzelfde begingetal 0), kun je vergelijken of wat er in de file staat, overeenkomt met wat er door het programma wordt geschreven:
./randfile | cmp OUT -
En wat bleek? In ongeveer één op de miljoen bytes, was het meest significante bit (met de waarde 128) van 1 op 0 gevallen (zo werd een byte met de hexadecimale waarde C3 nu 43, en een byte met de waarde F9 werd 79). Het leek dat bij het schrijven naar de disk, soms de data niet goed bij de disk aankwam. Het probleem zat niet in het lezen: nadat ik de file gemaakt had, en het programma op een andere machine startte, bleken de bytes ook echt fout op de disk te staan. Ook met andere disks trad dit probleem op. En op een andere machine met dezelfde disk, trad het verschijnsel niet op. Het probleem leek dus niet aan de disk zelf te liggen.
Het probleem werd opgelost door een ander moederbord te nemen, en daar de videorecorder weer mee op te bouwen. Toen dat gebeurd was, waren nieuwe opnamen weer vrij van blokjes, en traden filesystem problemen niet meer op.
