मैं कल किसी के साथ थोड़ी बहस में पड़ गया और / या मेरे उत्तर की सत्यता के बारे में यहाँ , विज़।, कि लॉगिंग और एफए मेटा डेटा को एक सभ्य (GB +) आकार के एसडी कार्ड पर पहनने के लिए पर्याप्त महत्वपूर्ण नहीं हो सकता है। समय (वर्ष और वर्ष) की एक उचित मात्रा में बाहर। प्रतिवाद के झटके से लग रहा था कि मुझे गलत होना चाहिए क्योंकि एसडी कार्ड पहनने वाले लोगों की ऑनलाइन कई कहानियां हैं।
चूंकि मेरे पास एसडी कार्ड वाले डिवाइस हैं जिनमें आरडब्ल्यू रूट फाइलसिस्टम हैं जो 24/7 पर बचे हैं, मैंने अपनी संतुष्टि से पहले आधार का परीक्षण किया था। मैंने इस परीक्षण को थोड़ा मोड़ दिया है, इसे दोहराया (उसी कार्ड का उपयोग करते हुए, वास्तव में) और इसे यहां प्रस्तुत कर रहा हूं। मेरे पास दो केंद्रीय प्रश्न हैं:
- क्या जिस विधि का उपयोग मैंने कार्ड को व्यवहार्य बनाने में करने की कोशिश की थी, उसे ध्यान में रखते हुए कि यह लगातार कम मात्रा में डेटा फिर से लिखने के प्रभावों को पुन: पेश करने के लिए है ?
- क्या मैंने कार्ड को सत्यापित करने के लिए जिस विधि का उपयोग किया था वह अभी भी ठीक है?
मैं यहाँ सवाल SO या SuperUser के बजाय यहाँ रख रहा हूँ क्योंकि पहले भाग पर आपत्ति करने से शायद यह दावा करना होगा कि मेरा परीक्षण वास्तव में उस कार्ड पर नहीं लिखा है जिस तरह से मुझे यकीन है कि यह करता है, और कुछ की आवश्यकता होती है linux का विशेष ज्ञान।
[यह भी हो सकता है कि एसडी कार्ड किसी तरह की स्मार्ट बफरिंग या कैशे का उपयोग करते हों, जैसे कि एक ही जगह पर बार-बार लिखने से कोई कमी हो सकती है / पहनने के लिए कम खतरा होता है। मुझे इसका कहीं भी कोई संकेत नहीं मिला है, लेकिन मैं इसके बारे में एसयू से पूछ रहा हूं ]
परीक्षण के पीछे का विचार लाखों बार कार्ड पर एक ही छोटे ब्लॉक को लिखना है। यह किसी भी दावे से परे है कि इस तरह के उपकरण कितने चक्र लिख सकते हैं, लेकिन अनुमान के अनुसार लेवलिंग प्रभावी है, अगर कार्ड एक सभ्य आकार का है, तो लाखों ऐसे लेखन अभी भी ज्यादा मायने नहीं रखते हैं, क्योंकि "एक ही ब्लॉक" वस्तुतः एक ही भौतिक खंड नहीं है। ऐसा करने के लिए, मुझे यह सुनिश्चित करने की ज़रूरत थी कि प्रत्येक लेखन वास्तव में हार्डवेयर के लिए, और उसी स्पष्ट स्थान पर वापस आ गया था।
हार्डवेयर में निस्तब्धता के लिए, मैं 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;
}
मैंने इसे ~ 8 घंटे तक चलाया, जब तक कि मैंने विभाजन की शुरुआत में 2 मिलियन + नहीं लिख लिए /dev/sdb1
। 1 मैं आसानी से इस्तेमाल कर सकता था /dev/sdb
(कच्चे उपकरण और विभाजन नहीं) लेकिन मैं यह नहीं देख सकता कि इससे क्या फर्क पड़ेगा।
फिर मैंने एक फाइल सिस्टम बनाने और माउंट करने की कोशिश करके कार्ड को चेक किया /dev/sdb1
। यह काम करता है, जो मुझे रात भर के लिए लिखी गई विशिष्ट ब्लॉक को इंगित करता है, संभव था। हालांकि, इसका मतलब यह नहीं है कि कार्ड के कुछ क्षेत्रों को खराब नहीं किया गया था और पहनने के स्तर से विस्थापित किया गया था, लेकिन सुलभ छोड़ दिया गया था।
परीक्षण करने के लिए, मैंने badblocks -v -w
विभाजन पर उपयोग किया । यह एक विनाशकारी रीड-राइट टेस्ट है, लेकिन लेवलिंग पहनें या नहीं, यह कार्ड की व्यवहार्यता का एक मजबूत संकेत होना चाहिए क्योंकि यह अभी भी प्रत्येक रोलिंग लेखन के लिए जगह प्रदान करना चाहिए। दूसरे शब्दों में, यह कार्ड को पूरी तरह से भरने के लिए शाब्दिक समकक्ष है, फिर यह जांचना कि वह सब ठीक था। कई बार, क्योंकि मैंने कुछ पैटर्न के माध्यम से बैडब्लॉक को काम करने दिया।
[कॉन्ट्रा जेसन सी की टिप्पणियों के नीचे, इस तरह से बैडब्लॉक का उपयोग करने के बारे में कुछ भी गलत या गलत नहीं है। हालांकि यह वास्तव में एसडी कार्ड की प्रकृति के कारण खराब ब्लॉकों की पहचान करने के लिए उपयोगी नहीं होगा, यह स्विच -b
और -c
स्विच का उपयोग करके एक मनमाने आकार के विनाशकारी पठन-लेखन परीक्षण करने के लिए ठीक है , जहां संशोधित परीक्षण चला गया (मेरा खुद का जवाब देखें) )। कार्ड के कंट्रोलर द्वारा कोई भी मैजिक या कैशिंग की मात्रा परीक्षण को मूर्ख नहीं बना सकती है, जिससे कई मेगाबाइट डेटा को हार्डवेयर में लिखा जा सके और फिर से सही तरीके से पढ़ा जा सके। जेसन की अन्य टिप्पणियां एक गलत धारणा पर आधारित हैं - IMO एक जानबूझकर , जिसके कारण मैंने बहस करने की जहमत नहीं उठाई। उस सिर के साथ, मैं पाठक को यह तय करने के लिए छोड़ देता हूं कि क्या समझ में आता है और क्या नहीं ।]
1 कार्ड एक पुराना 4 जीबी सैंडिस्क कार्ड था (इस पर इसका कोई "वर्ग" नंबर नहीं है) जो मैंने मुश्किल से इस्तेमाल किया है। एक बार फिर से, ध्यान रखें कि यह 2 मिलियन नहीं है जो शाब्दिक रूप से एक ही भौतिक स्थान पर लिखता है; पहनने के कारण "पहले ब्लॉक" को परीक्षण के दौरान नियंत्रक द्वारा लगातार ले जाया जाता है, क्योंकि शब्द बताता है, पहनने से बाहर।
/dev/sdb1
बनाम के रूप में /dev/sdb
यह आपके कार्यक्रम के लिए कोई फर्क नहीं पड़ता है, लेकिन क्या फर्क पड़ता है (जैसा कि नीचे वर्णित है) यह है कि आपके डिवाइस पर अप्रयुक्त ब्लॉक की स्थिति आपके परीक्षण के लिए अज्ञात और बेहिसाब है, और जब तक आप पूरे डिवाइस को नहीं भरते (उदाहरण के लिए) /dev/sdb
) पहले डेटा के साथ, स्पेस वियर लेवलिंग की मात्रा के साथ काम करना पड़ता है। इसलिए जब डिवाइस बनाम विभाजन आपके परीक्षण के लिए अप्रासंगिक है, तो यह ज्यादातर एक त्रुटिपूर्ण परीक्षण का परिणाम है, क्योंकि डिवाइस को डेटा के साथ ठीक से भरने के बाद, प्रति-विभाजन एक उपलब्ध विकल्प नहीं होगा (जब तक कि आप के बाद स्वरूपित नहीं किया जाता)।
badblocks
फ्लैश ड्राइव पर पृष्ठ विफलताओं को दिखाने के लिए उपयोग नहीं कर सकते हैं (और यह दावा करना कि बहुत भ्रामक है)। जिन्हें नियंत्रक द्वारा नियंत्रित किया जाता है और पता चलने पर स्थान आरक्षित करने के लिए मैप किया जाता है। ड्राइव पर डेटा का भौतिक लेआउट I / O करते समय आपके द्वारा देखे जाने वाले भौतिक लेआउट के समान नहीं है, यही कारण है कि पहनने का स्तर इसकी पारदर्शिता बनाए रखता है। इस में से कोई भी I / O के दौरान आपको दिखाई नहीं देता है। ज़्यादातर, अगर ड्राइव SMART का समर्थन करती है, तो आप नियंत्रक से विफलताओं और शेष आरक्षित स्थान के बारे में थोड़ी जानकारी प्राप्त कर सकते हैं।