Forcer un disque à réallouer des secteurs défectueux

Pour me souhaiter une bonne année, un disque dur a décidé de me faire une surprise avec des secteurs défectueux. Voici donc une méthode pour forcer le disque à se « réparer », mais d’abord, un peu d’histoire.

Au commencement…

Au tout début de l’informatique, on utilisait du support papier pour écrire les programmes et on faisait des trous pour coder les instructions pour l’ordinateur. Un programme faisait rapidement plusieurs centaines de cartes, lorsqu’il y avait une erreur de frappe sur une instruction, il suffisait de trouer l’ensemble de la ligne pour que l’ordinateur ignore l’instruction et continue comme si de rien n’était. Mais je n’ai pas l’intention de faire un cours d’histoire, alors tant pis pour les historiens, mais on va faire un gros saut.

Aujourd’hui, nos disques durs sont un peu plus intelligents et lorsque le logiciel du disque dur détecte des secteurs défectueux lors de la lecture, il tient à jour une liste et va essayer de les « corriger ». En vérité, ils sont déplacés — ou « réalloués » — dans une zone de réserve lors d’une opération d’écriture.

Cependant, tant que l’on n’aura pas réécrit sur ces secteurs, le disque continuera d’essayer de lire le contenu.

Le nombre de secteurs en attente de réallocation peut être visualisé par l’attribut 197 (Current_Pending_Sector) de la S.M.A.R.T..

Obtenir la liste des secteurs

On va ici utiliser deux commandes, fdisk pour avoir des informations sur la géométrie du disque, puis badblocks pour localiser les secteurs défectueux.

# fdisk -l /dev/sdb

Disque /dev/sdb : 698,7 GiB, 750156374016 octets, 1465149168 secteurs
Unités : secteur de 1 × 512 = 512 octets

Avec ces informations, nous savons que la taille d’un secteur est de 512 octets, on va donc demander à badblocks de lire le contenu du disque en précisant que la taille d’un block est de 512 octets. On en profite pour enregistrer le résultat dans un fichier texte.

Bien que ne s’agissant que d’un test en lecture, il est fortement recommandé de faire le test sur un disque non utilisé (pas de partition montée, depuis un livecd par exemple).

# badblocks -sv -b 512 /dev/sdb >/tmp/badblocks.txt

Une fois le test terminé, le fichier /tmp/badblocks.txt va contenir les numéros des secteurs qui rencontrent une erreur, a noter que badblocks teste 64 blocks d’un coup, donc ici 64 secteurs. Il est possible qu’il n’y en ait qu’un seul dans la liste en erreur.

# cat /tmp/badblocks.txt 
207205608
207205609
207205610
…

Corriger avec le marteau et le burin

Maintenant que nous avons la liste, on va forcer le disque à réallouer le secteur en inscrivant des données sur les secteurs en question.

Bien évidemment, cela entraîne de la corruption des données, mais primo les données sur le disque étaient déjà illisibles — puisque les secteurs sont marqués comme défectueux — puis secundo, vous aviez des sauvegardes, n’est-ce pas ?

Avant tout, on va vérifier que le secteur est bien illisible avec la commande hdparm.

# hdparm --read-sector 207205609 /dev/sdb

/dev/sdb:
reading sector 207205609: FAILED: Input/output error

Ici, nous avons une erreur d’entrée-sortie qui confirme que le secteur est illisble. Dans le cas où la lecture fonctionne, le résultat ressemblerait à ça :

# hdparm --read-sector 207205608 /dev/sdb

/dev/sda:
reading sector 207205608: succeeded
7b7d d740 31…

Nous avons identifié notre secteur défectueux, demandons à hdparm d’écrire dessus.

# hdparm --write-sector 207205609 /dev/sdb

/dev/sdb:
Use of --write-sector is VERY DANGEROUS.
You are trying to deliberately overwrite a low-level sector on the media.
This is a BAD idea, and can easily result in total data loss.
Please supply the --yes-i-know-what-i-am-doing flag if you really want this.
Program aborted.

Eh oui, c’est très dangereux, alors il faut explicitement dire que l’on est sûr de ce que l’on souhaite faire.

# hdparm --yes-i-know-what-i-am-doing --write-sector 207205609 /dev/sdb

/dev/sdb:
re-writing sector 207205609: succeeded

Il ne reste plus qu’à vérifier que le secteur est redevenu lisible, on utilisera ici la commande précédente, read-sector.

# hdparm --read-sector 207205609 /dev/sdb                                           

/dev/sdb:
reading sector 207205609: succeeded
0000 0000 0000…

La commande a réussi et va retourner le contenu du secteur, qui doit être composé de 0.

Il faut ensuite répéter cette opération pour tous les secteurs trouvés par la commande badblocks. Une fois terminé, il ne reste plus qu’à restaurer les sauvegardes, car vous ne pourrez pas savoir ce qui a été perdu.

Haut de page