きちんとした(GB +)サイズのSDカードでのfsメタデータのロギングと維持は、カードを装着するほど重要ではないということについて、昨日ここでの答えの論理および/または信regarding性について誰かと少し議論しました妥当な期間(年および年)でアウト。反論の要点は、SDカードを身に着けている人々のオンラインの物語が非常に多いため、私は間違っているに違いないということのように思えました。
私は24時間年中無休のrwルートファイルシステムを含むSDカードを備えたデバイスを持っているので、私は自分の満足する前に前提をテストしました。このテストを少し調整し、実際に同じカードを使用して繰り返し、ここで紹介します。私が持っている2つの中心的な質問は次のとおりです。
- 私はそれを再書き込み連続の効果を再現することを意図しています念頭に置いて、実行可能なカードを破壊しようとするために使用される方法で、小さなデータの量は?
- カードを確認するために使用した方法はまだ実行可能ですか?
最初の部分への異議はおそらく私のテストが実際にカードに書き込みをしなかったと断言する必要があるため、SOまたはスーパーユーザーではなくここに質問を入れていますLinuxの特別な知識。
[SDカードが何らかのスマートバッファリングまたはキャッシュを使用し、同じ場所への繰り返し書き込みが摩耗しにくい場所でバッファリング/キャッシュされることも考えられます。私はどこにもこれの兆候を見つけていませんが、SUでそれについて尋ねています]
テストの背後にある考え方は、カード上の同じ小さなブロックに何百万回も書き込むことです。これは、そのようなデバイスが何回の書き込みサイクルを維持できるかという主張をはるかに超えていますが、ウェアレベリングが有効であると仮定すると、カードがまともなサイズであれば、「同じブロック」がそうであるように、何百万ものそのような書き込みはまだ重要ではありません文字通り同じ物理ブロックではありません。これを行うには、すべての書き込みがハードウェアと同じ見かけの場所に本当にフラッシュされるようにする必要がありました。
ハードウェアにフラッシュするために、私はPOSIXライブラリ呼び出しに依存しました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;
}
パーティションの先頭に200万回以上の書き込みを蓄積するまで、これを8時間ほど実行しました/dev/sdb1
。1 簡単に使用できました/dev/sdb
(パーティションではなくrawデバイス)が、これによってどのような違いが生じるかわかりません。
次に、ファイルシステムを作成してマウントしようとしてカードをチェックしました/dev/sdb1
。これは機能し、私が一晩中書いていた特定のブロックが実行可能であったことを示しています。ただし、カードの一部の領域が摩耗レベリングによって摩耗および変位していなかったが、アクセス可能なままであったことを意味するものではありません。
それをテストするためbadblocks -v -w
に、パーティションで使用しました。これは破壊的な読み書きテストですが、ウェアレベリングの有無にかかわらず、ローリング書き込みごとにスペースを提供する必要があるため、カードの実行可能性を強く示す必要があります。言い換えれば、それは文字通りカードを完全に埋めてから、すべてが大丈夫であることを確認することと同じです。数回、badblocksにいくつかのパターンを機能させたので。
[以下のContra Jason Cのコメント、このようにbadblocksを使用することに関して、何も悪いことも間違っていることもありません。SDカードの性質上、実際に不良ブロックを識別するのには役立ちませんが、修正されたテストが行われた-b
and -c
スイッチを使用して、任意のサイズの破壊的な読み取り/書き込みテストを行うことは問題ありません(私自身の答えを参照してください) )。カードのコントローラーによる魔法やキャッシュの量は、数メガバイトのデータをハードウェアに書き込み、再び正しく読み戻すことができるテストを欺くことはできません。ジェイソンの他のコメントは誤読に基づいているように見えます-IMOは意図的なものです。だから、私は議論する気になりませんでした。その頭を上げて、何が理にかなっていて、何がそうでないかを決めるのは読者に任せます。]
1このカードは、私がかろうじて使用した古い4 GB Sandiskカード(「クラス」番号がない)です。繰り返しますが、これは文字通り同じ物理的な場所への200万回の書き込みではないことに注意してください。ウェアレベリングにより、テスト中にコントローラーによって「最初のブロック」が絶えず移動され、用語が示すように、ウェアを平準化します。
/dev/sdb1
対/dev/sdb
それはあなたのプログラムの違いはありませんが、何ん(後述のように)違いを作るあなたのデバイス上の未使用ブロックの状態がテスト中のため不明と行方不明で、ということですあなたは、デバイス全体を埋めない限り(たとえば、/dev/sdb
)データを最初に使用する場合、使用する必要があるスペースウェアレベリングの量は大きな変数です。そのため、デバイスとパーティションはテストには関係ありませんが、これは主に欠陥のあるテストの結果です。デバイスにデータを適切に入力した後、パーティションごとは利用可能なオプションではありません(フォーマットしない限り)。
badblocks
、フラッシュドライブでページエラーを表示するために使用することはできません(それが非常に誤解を招くと主張します)。これらはコントローラーによって処理され、検出されたときにスペースを予約するためにマッピングされます。ドライブ上のデータの物理レイアウトは、I / Oを実行するときに表示される物理レイアウトと同じではありません。これが、ウェアレベリングが透明性を維持する方法です。どれもこれのは、I / Oの間にあなたに表示されません。ドライブがSMARTをサポートしている場合、せいぜい、コントローラーから障害と残りの予約済みスペースに関する小さな情報を取得できます。