page header

juli 2010 Archieven

Op zoek naar de bron van de datacorruptie...


Geplaatst door jc op 2010-07-12 12:07:11 | Permanente link | Categorie: Systeembeheer | Reacties: 0

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.