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.
1 De Marc Quinton -
je n'avais jamais vu cette manipulation ; je vais l'ajouter dans notre guide systeme. Merci.
2 De audreyl14 -
Bonjour,
Je tente de récupérer des secteurs défectueux d'un disque dur, je l'ai inséré dans mon dock qui lui même est branché sur mon pc portable qui est sous Linux. Quand je lance le terminal et que j'entre la commande # fdisk -l /dev/sdb il ne se passe rien et quand je tente la même commande sans le # cela m'indique "permission non accordée". Comment pourrais-je faire pour réparer les secteurs défectueux du disque vu que la commande ne fonctionne pas ?
Merci de votre aide...
3 De APLU -
Bonjour,
Les commandes qui commencent par un # sont à lancer en root, ce qui peut se faire avec la commande sudo (cf https://doc.ubuntu-fr.org/sudo).
Attention a être sur que le disque qui est concerné est bien sdb, ce n’est pas obligatoirement le cas (notamment si il y a déjà plusieurs disques dans la machine).
4 De renton -
chez moi cela ne fonctionne pas.
la commande --write-sector fonctionne bien mais lorsque je fais le test de lecture par la suite, j'ai toujours le même résultat ; à savoir input/output error
5 De LDVC@ -
Attention à corriger :
hdparm --read-sector 207205608 /dev/sda
en
hdparm --read-sector 207205608 /dev/sdb
;)
6 De LDVC@ -
La commande # badblocks -sv -b 512 /dev/sdb >/tmp/badblocks.txt m'a indiqué des blocs défectueux entre 117223144 et 117231407.
Alors j'ai fait un petit script qu'il faut lancer avec les droits administrateur :
#!/bin/bash
# script forblocs.sh qui répare automatiquement les blocs entre 117223144 et 117231407.
for i in `seq 117223144 117231407`;
do
clear
echo $i" / 117231407"
sleep 0.04
hdparm --yes-i-know-what-i-am-doing --write-sector $i /dev/sdb
hdparm --read-sector $i /dev/sdb
done
exit
Le script fonctionne mais le bloc 0 de ce SSD dysfonctionne…
7 De Je cherche -
wow ! mechante manupulation mais ca marche en partie