Вчера я вступил в небольшую дискуссию с кем-то относительно логики и / или правдивости моего ответа здесь , в том смысле, что регистрация и ведение метаданных fs на SD-карте достойного размера (ГБ +) никогда не может быть достаточно значительной, чтобы носить карту. в разумные сроки (годы и годы). Суть контраргумента состояла в том, что я, должно быть, ошибаюсь, поскольку в Интернете очень много историй о людях, носящих SD-карты.
Поскольку у меня есть устройства с SD-картами, содержащими корневые файловые системы rw, которые работают 24 часа в сутки, я проверил эту предпосылку раньше, к своему собственному удовлетворению. Я немного подправил этот тест, повторил его (фактически используя ту же карту) и представляю его здесь. У меня есть два центральных вопроса:
- Является ли метод, который я использовал, чтобы попытаться уничтожить карту, жизнеспособным, имея в виду, что он предназначен для воспроизведения эффектов непрерывного перезаписи небольших объемов данных?
- Является ли метод, который я использовал, чтобы убедиться, что карта все еще в порядке?
Я ставлю вопрос здесь, а не на SO или SuperUser, потому что возражение против первой части, вероятно, должно было бы утверждать, что мой тест на самом деле не записывал на карту так, как я уверен, и утверждать, что это потребует некоторого специальные знания 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;
}
Я запускал это в течение ~ 8 часов, пока я не набрал более 2 миллионов записей в начало /dev/sdb1
раздела. 1 Я мог бы просто использовать /dev/sdb
(исходное устройство, а не раздел), но я не вижу, как это повлияет.
Затем я проверил карту, пытаясь создать и смонтировать файловую систему /dev/sdb1
. Это сработало, указав, что конкретный блок, который я писал на всю ночь, выполним. Однако это не означает, что некоторые области карты не были изношены и смещены в результате выравнивания износа, а оставлены доступными.
Чтобы проверить это, я использовал badblocks -v -w
раздел. Это разрушительный тест чтения-записи, но выравнивание износа или нет, это должно быть четким показателем осуществимости карты, так как она должна по-прежнему обеспечивать место для каждой непрерывной записи. Другими словами, это буквальный эквивалент полного заполнения карты, а затем проверки того, что все в порядке. Несколько раз, поскольку я позволил бадблоку работать через несколько шаблонов.
[Contra Jason C комментарии ниже, нет ничего плохого или ложного в использовании плохих блоков таким способом. Хотя это не было бы полезно на самом деле выявления плохих блоков из - за характера SD карты, это прекрасно для выполнения деструктивных тестов для чтения и записи произвольного размера с использованием -b
и -c
переключателей, который где пересмотренная тест пошел (см мой собственный ответ ). Никакое количество магии или кеширования контроллером карты не может обмануть тест, при котором несколько мегабайт данных могут быть записаны на аппаратное обеспечение и правильно считаны обратно. Другие комментарии Джейсона, похоже, основаны на неправильном прочтении - ИМО преднамеренное , поэтому я не стал спорить. Подняв голову, я оставляю читателю решать, что имеет смысл, а что нет .]
1 Карта была старой 4 ГБ картой Sandisk (на ней нет номера «класса»), которую я почти не использовал. Еще раз, имейте в виду, что это не 2 миллиона записей буквально в то же физическое место; из-за выравнивания износа «первый блок» будет постоянно перемещаться контроллером во время теста, чтобы, как говорит сам термин, выровнять износ.
/dev/sdb1
vs, /dev/sdb
то для вашей программы это не имеет значения , но разница (как описано ниже) заключается в том, что состояние неиспользуемых блоков на вашем устройстве неизвестно и не учтено в вашем тесте, и если вы не заполнили все устройство (например, /dev/sdb
) с данными в первую очередь, объем выравнивания износа пространства должен работать с является основной переменной. Таким образом, хотя устройство и раздел не имеет значения для вашего теста, это в основном является следствием некорректного теста, так как после правильного заполнения устройства данными, разделение не будет доступным вариантом (если вы не отформатировали после).
badblocks
чтобы показать сбои страниц на флешке (и утверждают, что это очень вводит в заблуждение). Они обрабатываются контроллером и отображаются на резервное пространство при обнаружении. Физическое расположение данных на диске не совпадает с физическим расположением, которое вы видите при выполнении операций ввода-вывода, поэтому выравнивание износа поддерживает его прозрачность. Ничего из этого не видно во время ввода / вывода. Самое большее, если накопитель поддерживает SMART, вы можете получить небольшую информацию о сбоях и оставшемся зарезервированном пространстве от контроллера.