Вчора я взяв дещо з кимось із дебатів щодо логіки та / або правдивості моєї відповіді тут , див., Що реєстрація та підтримка мета-даних fs на гідній (ГБ +) розмірі SD-картці ніколи не може бути достатньо вагомою для носіння карти. у розумну кількість часу (років і років). Суперечка зустрічного аргументу здавалася, що я маю помилку, оскільки в Інтернеті так багато історій людей, які носять SD-карти.
Оскільки у мене є пристрої зі SD-картами, що містять кореневі файлові системи rw, які залишились 24/7, я раніше перевіряв цю умову на власне задоволення. Я трохи переробив цей тест, повторив його (фактично використовуючи ту саму карту) і представляю його тут. У мене є два головних питання:
- Чи метод, який я використовував, щоб намагатися зірвати карту життєздатною, маючи на увазі, що вона призначена для відтворення ефектів постійного переписування невеликої кількості даних?
- Чи метод, який я використовував для перевірки картки, все ще був нормальним?
Я ставлю тут питання, а не 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, ви можете отримати трохи інформації про збої та залишений зарезервований простір від контролера.