Ich habe gestern eine kleine Debatte mit jemandem über die Logik und / oder Richtigkeit meiner Antwort hier geführt , vis., Dass das Aufzeichnen und Verwalten von fs-Metadaten auf einer anständigen SD-Karte (GB +) niemals signifikant genug sein könnte, um die Karte zu tragen in einem angemessenen Zeitraum (Jahre und Jahre). Das Gegenargument schien zu sein, dass ich mich irren muss, da so viele Geschichten über Leute online sind, die SD-Karten tragen.
Da ich Geräte mit SD-Karten habe, die rund um die Uhr verfügbare RW-Root-Dateisysteme enthalten, hatte ich die Voraussetzung zuvor zu meiner eigenen Zufriedenheit getestet. Ich habe diesen Test ein wenig optimiert, ihn wiederholt (tatsächlich mit derselben Karte) und präsentiere ihn hier. Die zwei zentralen Fragen, die ich habe, sind:
- Ist die Methode, mit der ich versucht habe, die Karte zu zerstören, realisierbar, wenn ich bedenke, dass sie die Auswirkungen des fortlaufenden erneuten Schreibens kleiner Datenmengen reproduzieren soll ?
- Ist die Methode, mit der ich überprüft habe, ob die Karte noch in Ordnung ist, noch praktikabel?
Ich stelle die Frage hier eher als SO oder SuperUser, weil ein Einwand gegen den ersten Teil wahrscheinlich behaupten müsste, dass mein Test nicht wirklich so auf die Karte geschrieben hat, wie ich mir sicher bin, und dass dies einige erfordern würde Spezialkenntnisse in Linux.
[Es könnte auch sein, dass SD-Karten eine Art Smart Buffering oder Cache verwenden, sodass wiederholte Schreibvorgänge an derselben Stelle an einem Ort gepuffert / zwischengespeichert werden, der weniger anfällig für Abnutzung ist. Ich habe nirgendwo einen Hinweis darauf gefunden, aber ich frage im SU]
Die Idee hinter dem Test ist, millionenfach in denselben kleinen Block auf der Karte zu schreiben. Dies geht weit über jede Behauptung hinaus, wie viele Schreibzyklen solche Geräte aushalten können, aber vorausgesetzt, dass ein Verschleißausgleich effektiv ist, sollten Millionen solcher Schreibvorgänge, wenn die Karte eine anständige Größe hat, immer noch nicht viel ausmachen, wie "derselbe Block" nicht buchstäblich der gleiche physische Block sein. Um dies zu tun, musste ich sicherstellen, dass jeder Schreibvorgang wirklich auf die Hardware und an den gleichen offensichtlichen Ort übertragen wurde.
Für das Löschen auf Hardware habe ich mich auf den POSIX-Bibliotheksaufruf verlassen fdatasync()
:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
// Compile std=gnu99
#define BLOCK 1 << 16
int main (void) {
int in = open ("/dev/urandom", O_RDONLY);
if (in < 0) {
fprintf(stderr,"open in %s", strerror(errno));
exit(0);
}
int out = open("/dev/sdb1", O_WRONLY);
if (out < 0) {
fprintf(stderr,"open out %s", strerror(errno));
exit(0);
}
fprintf(stderr,"BEGIN\n");
char buffer[BLOCK];
unsigned int count = 0;
int thousands = 0;
for (unsigned int i = 1; i !=0; i++) {
ssize_t r = read(in, buffer, BLOCK);
ssize_t w = write(out, buffer, BLOCK);
if (r != w) {
fprintf(stderr, "r %d w %d\n", r, w);
if (errno) {
fprintf(stderr,"%s\n", strerror(errno));
break;
}
}
if (fdatasync(out) != 0) {
fprintf(stderr,"Sync failed: %s\n", strerror(errno));
break;
}
count++;
if (!(count % 1000)) {
thousands++;
fprintf(stderr,"%d000...\n", thousands);
}
lseek(out, 0, SEEK_SET);
}
fprintf(stderr,"TOTAL %lu\n", count);
close(in);
close(out);
return 0;
}
Ich habe dies ~ 8 Stunden lang ausgeführt, bis ich 2 Millionen + Schreibvorgänge am Anfang der /dev/sdb1
Partition gesammelt hatte . 1 Ich hätte es einfach benutzen können /dev/sdb
(das Raw-Gerät und nicht die Partition), aber ich kann nicht sehen, welchen Unterschied dies machen würde.
Ich habe dann die Karte überprüft, indem ich versucht habe, ein Dateisystem zu erstellen und darauf zu mounten /dev/sdb1
. Dies funktionierte und zeigte an, dass der spezifische Block, an den ich die ganze Nacht geschrieben hatte, machbar war. Dies bedeutet jedoch nicht, dass einige Bereiche der Karte nicht durch Abnutzungsnivellierung abgenutzt und verschoben wurden, sondern zugänglich bleiben.
Um das zu testen, habe ich badblocks -v -w
auf der Partition verwendet. Dies ist ein zerstörerischer Lese- / Schreibtest, der jedoch eine Abnutzungsbereinigung nach sich zieht oder nicht. Er sollte ein starkes Indiz für die Machbarkeit der Karte sein, da immer noch Platz für jedes rollierende Schreiben vorhanden sein muss. Mit anderen Worten, es ist das wörtliche Äquivalent, die Karte vollständig auszufüllen und dann zu überprüfen, ob alles in Ordnung war. Mehrmals, da ich Badblocks ein paar Muster durcharbeiten ließ.
[Gegen Jason Cs Kommentare unten, es ist nichts Falsches oder Falsches daran, Badblocks auf diese Weise zu benutzen. Es wäre zwar aufgrund der Art der SD-Karten nicht nützlich, um fehlerhafte Blöcke zu identifizieren, aber es ist in Ordnung, zerstörerische Lese- / Schreibtests beliebiger Größe mit den Schaltern -b
und durchzuführen. In diesem Fall wurde -c
der überarbeitete Test durchgeführt (siehe meine eigene Antwort) ). Keine Menge an Magie oder Zwischenspeicherung durch den Controller der Karte kann einen Test täuschen, bei dem mehrere Megabyte Daten auf die Hardware geschrieben und wieder korrekt zurückgelesen werden können. Die anderen Kommentare von Jason scheinen auf einem falschen Verständnis zu beruhen - IMO auf einem absichtlichen , weshalb ich mich nicht darum gekümmert habe, darüber zu streiten. Wenn dieser Kopf frei ist, überlasse ich es dem Leser zu entscheiden, was Sinn macht und was nicht .]
1 Die Karte war eine alte 4-GB-Sandisk-Karte (sie hat keine "Klassen" -Nummer), die ich kaum benutzt habe. Denken Sie noch einmal daran, dass dies nicht 2 Millionen Schreibvorgänge sind, die buchstäblich am selben physischen Ort abgelegt werden. Aufgrund der Abnutzungsnivellierung wurde der "erste Block" während des Tests ständig von der Steuerung bewegt, um, wie der Begriff besagt, die Abnutzung auszugleichen.
/dev/sdb1
vs betrifft , /dev/sdb
macht es keinen Unterschied für Ihr Programm, aber was den Unterschied ausmacht (wie unten beschrieben), ist, dass der Status nicht verwendeter Blöcke auf Ihrem Gerät unbekannt ist und in Ihrem Test nicht berücksichtigt wird, und es sei denn, Sie füllen das gesamte Gerät aus (z. B. ) Bei Daten ist zunächst die Größe des Raumverschleißniveaus, mit dem gearbeitet werden muss, eine Hauptvariable. Während Gerät und Partition für Ihren Test irrelevant sind, ist dies meistens eine Folge eines fehlerhaften Tests, da nach ordnungsgemäßem Füllen des Geräts mit Daten keine Option pro Partition verfügbar ist (es sei denn, Sie haben danach formatiert). /dev/sdb
badblocks
zum Anzeigen von Seitenfehlern auf einem Flash-Laufwerk verwenden (und behaupten, dass dies sehr irreführend ist). Diese werden vom Controller verarbeitet und reserviert, wenn sie erkannt werden. Das physische Layout der Daten auf dem Laufwerk stimmt nicht mit dem physischen Layout überein, das Sie bei E / A-Vorgängen sehen. Auf diese Weise wird die Transparenz beim Abnutzungsausgleich beibehalten. Nichts davon ist für Sie während der E / A sichtbar. Wenn das Laufwerk SMART unterstützt, können Sie höchstens ein paar Informationen zu Fehlern und dem verbleibenden reservierten Speicherplatz vom Controller abrufen.