Стресс-тестирование SD-карт с использованием Linux


19

Вчера я вступил в небольшую дискуссию с кем-то относительно логики и / или правдивости моего ответа здесь , в том смысле, что регистрация и ведение метаданных fs на SD-карте достойного размера (ГБ +) никогда не может быть достаточно значительной, чтобы носить карту. в разумные сроки (годы и годы). Суть контраргумента состояла в том, что я, должно быть, ошибаюсь, поскольку в Интернете очень много историй о людях, носящих SD-карты.

Поскольку у меня есть устройства с SD-картами, содержащими корневые файловые системы rw, которые работают 24 часа в сутки, я проверил эту предпосылку раньше, к своему собственному удовлетворению. Я немного подправил этот тест, повторил его (фактически используя ту же карту) и представляю его здесь. У меня есть два центральных вопроса:

  1. Является ли метод, который я использовал, чтобы попытаться уничтожить карту, жизнеспособным, имея в виду, что он предназначен для воспроизведения эффектов непрерывного перезаписи небольших объемов данных?
  2. Является ли метод, который я использовал, чтобы убедиться, что карта все еще в порядке?

Я ставлю вопрос здесь, а не на 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 миллиона записей буквально в то же физическое место; из-за выравнивания износа «первый блок» будет постоянно перемещаться контроллером во время теста, чтобы, как говорит сам термин, выровнять износ.


Это ненадежный тест по причинам, изложенным ниже. Также вы не можете использовать, badblocksчтобы показать сбои страниц на флешке (и утверждают, что это очень вводит в заблуждение). Они обрабатываются контроллером и отображаются на резервное пространство при обнаружении. Физическое расположение данных на диске не совпадает с физическим расположением, которое вы видите при выполнении операций ввода-вывода, поэтому выравнивание износа поддерживает его прозрачность. Ничего из этого не видно во время ввода / вывода. Самое большее, если накопитель поддерживает SMART, вы можете получить небольшую информацию о сбоях и оставшемся зарезервированном пространстве от контроллера.
Джейсон С

Что касается /dev/sdb1vs, /dev/sdbто для вашей программы это не имеет значения , но разница (как описано ниже) заключается в том, что состояние неиспользуемых блоков на вашем устройстве неизвестно и не учтено в вашем тесте, и если вы не заполнили все устройство (например, /dev/sdb) с данными в первую очередь, объем выравнивания износа пространства должен работать с является основной переменной. Таким образом, хотя устройство и раздел не имеет значения для вашего теста, это в основном является следствием некорректного теста, так как после правильного заполнения устройства данными, разделение не будет доступным вариантом (если вы не отформатировали после).
Джейсон C

Еще один момент, который делает ваш тест нереалистичным, заключается в том, что страница может (и довольно часто) не работает, но все равно после этого SD-карта остается пригодной для использования на 100%. В случае, когда контроллер обнаруживает и маскирует сбой, но данные не могут быть прочитаны, данные файловой системы могут быть повреждены, когда контроллер пытается скопировать блок.
Джейсон C

Я говорю вам , что - опиши мне в конкретных условиях на воспроизводимый тест , который делает носить SD - карту, а затем я буду принимать вас всерьез. Непонятные «претензии от власти» и личные анекдоты - вот только что. Argumentum ab auctoritate
goldilocks

1
Я не знаю об этой конкретной карте, но большинство из них, по крайней мере, уже немного мертвы. Эти парни взломали микроконтроллер, по крайней мере, на одной карте SD: bunniestudios.com/blog/?p=3554 Часовой разговор, который они провели по этому вопросу, был довольно хорошим.
mikeserv

Ответы:


11

Я думаю, что стресс-тестирование SD-карты в целом проблематично, учитывая две вещи:

  1. Выравнивание износа Нет никаких гарантий, что одна запись в другую фактически использует те же физические местоположения на SD. Помните, что большинство существующих систем SD активно занимают блок в том виде, в котором мы его знаем, и перемещают физическое местоположение, которое поддерживает его, на основе воспринимаемого «износа», которому подвергалось каждое местоположение.

  2. разные технологии (MLC против SLC) Другая проблема, с которой я сталкиваюсь, это разница в технологиях. SLC-типы SSD Я бы ожидал, что их продолжительность жизни будет намного больше, чем у MLC. Также есть много более жестких допусков на MLC, с которыми вам просто не нужно иметь дело на SLC, или, по крайней мере, они гораздо более терпимы к таким сбоям.

    • MLC - многоуровневая ячейка
    • SLC - одноуровневая ячейка

Проблема с MLC состоит в том, что в данной ячейке могут храниться несколько значений, биты, по существу, составлены с использованием напряжения, а не просто, например, физического + 5 В или 0 В, так что это может привести к гораздо более высокому потенциалу частоты отказов, чем их SLC. эквивалент.

Продолжительность жизни

Я нашел эту ссылку, которая немного обсуждает, как долго может работать аппаратное обеспечение. Это называется: Знай свои SSD - SLC против MLC .

SLC

Ssds SLC можно рассчитать, по большей части, чтобы жить в среднем от 49 до 149 лет, по самым лучшим оценкам. Тестирование Memoright позволяет проверить твердотельный накопитель емкостью 128 ГБ, имеющий срок службы записи, превышающий 200 лет, при средней записи 100 ГБ в день.

MLC

Вот где дизайн MLC терпит неудачу. Ни один еще не был выпущен. Никто на самом деле не исследовал, какая продолжительность жизни гарантируется с помощью MLC, за исключением того, что она будет значительно ниже. Я получил несколько разных мнений, которые в среднем соответствуют 10-1 жизни в пользу дизайна SLC. Консервативное предположение состоит в том, что большинство оценок продолжительности жизни будет составлять от 7 до 10 лет, в зависимости от продвижения «алгоритмов выравнивания износа» в контроллерах каждого производителя.

Сравнения

Чтобы провести сравнение с помощью циклов записи, у slc будет время жизни 100 000 полных циклов записи по сравнению с mlc, который имеет время жизни 10000 циклов записи. Это может значительно увеличиться в зависимости от используемой конструкции «выравнивания износа».


1
Выравнивание износа WRT «Нет никаких гарантий, что одна запись в другую фактически использует те же физические местоположения на SD» - это предполагается в вопросе slm! Я думаю, очень явно ... Без выравнивания износа я бы никогда не ожидал, что этот тест пройдёт, так как я иду далеко за пределы любого заявленного максимума срока службы цикла записи. Тест призван доказать эффективность выравнивания износа , а не игнорировать его. Тот факт , что я могу написать 2 миллиона раз в то же кажущееся место указует выравнивания износа в силе.
Златовласка

WRT # 2, качество и технология, конечно, будут отличать одну карту от другой. Я хочу сказать, что обычная дешевая карта Sandisk будет работать дольше, чем кому-либо на самом деле, если объем записываемых данных за день относительно невелик.
Златовласка

@goldilocks - Хорошо, хорошо, не бей меня об этом. 8-), так что вы говорите, если я напишу достаточно большой объем данных, чтобы эффективно исключить выравнивание износа из уравнения и запустить на нем плохие блоки, этого достаточно, чтобы показать эффективность выравнивания износа?
SLM

1
@goldilocks - я только что открыл ящик Пандоры?
SLM

1
(Например: если вы клонируете SD-карту, записывая на нее изображение и fstrimвпоследствии не / не можете , вы полностью отключили динамическое выравнивание износа [вам будет сложно найти потребительскую SD-карту с статическим выравниванием износа] отмечая каждую страницу как использованную.)
Джейсон С

6

Есть ряд проблем с вашим тестом, некоторые нечеткие, некоторые нет. Это также зависит от вашей цели. Две тонкие, нечеткие проблемы:

  • Вы не читаете из той же области, в которую пишете, ваш тест на чтение эффективно ничего не делает (если только контроллер не исправил нарушение чтения, в этом случае он может иногда перемещать читаемую страницу куда-то еще, но это все равно делает не влияет на ваш тест).
  • Вы предполагаете (и вполне вероятно, но не гарантировано), что чтение / запись в плохой блок обнаружен и сообщен контроллером - вы хотели бы записать данные, прочитать их обратно и сравнить их для гарантированной проверки.

Тем не менее, они, возможно, педантичны. Более серьезным является:

  • Вы не можете использовать badblocksдля отображения неудачных страниц во флэш-памяти; все обнаружения сбоев и последующие отображения страниц выполняются контроллером и прозрачны для ОС. Вы могли бы получить некоторую информацию от SMART, если привод поддерживает ее (я не знаю ни одной SD-карты, которая бы поддерживала ее, возможно, есть более мощные флэшки).
  • Выравнивание износа, осложненное тестом без учета предыдущих команд TRIM, свободного / использованного состояния накопителя во время теста и зарезервированного пространства.

Выравнивание износа: основная проблема заключается в том, что выравнивание износа является основной переменной в вашем тесте. Это происходит на контроллере (обычно), и в любом случае его прозрачно даже для прямого поиска устройства + чтение / запись. В вашем примере вы на самом деле не знаете состояние выравнивания износа (в частности, были ли недавно введены команды TRIM для свободных блоков?) ...

Для динамического выравнивания износа (присутствующего практически на всех устройствах хранения потребительского уровня) на вашем устройстве оно может находиться в любом состоянии: с одной стороны, ни одна из страниц не помечена как свободная, и поэтому единственные страницы, которые должен работать контроллер с те, которые находятся в зарезервированном пространстве (если есть). Обратите внимание , что если это зарезервированное пространство на устройстве, он будет иметь на провал полностью , прежде чем начать получать гарантированно не будет работать на записи страниц (предполагая , нет других страниц помечаются как свободные остальные). С другой стороны, каждая страница помечается как свободная, и в этом случае теоретически вам необходимо, чтобы каждая страница на устройстве не работала до того, как вы начнете видеть ошибки записи.

Для статического выравнивания износа (который, как правило, имеют SSD, SD-карты, как правило, не имеют, а флэш-накопители различаются): на самом деле нет никакого способа обойти это, кроме многократной записи на каждую страницу устройства.

... Другими словами, существуют детали выравнивания износа, которые вы не можете знать и, конечно, не можете контролировать - в частности, используется ли динамическое выравнивание износа, используется ли статическое выравнивание износа, и объем пространства, зарезервированный на устройстве для выравнивания износа (который не виден за пределами контроллера [или драйвера в некоторых случаях, например M-Systems old DiskOnChip]).

SLC / MLC: Что касается SLC и MLC, это оказывает прямое влияние на пределы, которые вы ожидаете увидеть, но общая процедура выравнивания износа и процедура испытаний одинаковы для обоих. Многие поставщики не публикуют информацию о том, являются ли их устройства SLC или MLC для их более дешевых потребительских продуктов, хотя любая флешка, на которой заявлено ограничение в 100 000 циклов на страницу, скорее всего, SLC (упрощенный компромисс - SLC = выносливость, MLC = плотность).

Кеширование: Что касается кеширования, это немного сомнительно. На уровне ОС, в общем случае, конечно, fsync / fdatasync не гарантирует, что данные действительно записаны. Тем не менее, я думаю, что можно с уверенностью предположить, что это так (или, по крайней мере, контроллер это сделал, т. Е. Запись не будет поглощена в кеше) в этом случае, поскольку съемные диски обычно предназначены для общей схемы использования. «Извлечь» (unmount> sync), затем удалить (отключить питание). Хотя мы не знаем наверняка, образованное предположение говорит, что можно с уверенностью предположить, что синхронизация гарантирует, что запись будет иметь место, особенно при записи -> синхронизация -> обратное чтение (в противном случае диски были бы ненадежными. после извлечения). Нет никакой другой команды, кроме 'sync', которая может быть выдана при извлечении.

В контроллере все возможно, но вышеприведенное предположение также включает в себя предположение, что контроллер, по крайней мере, не делает ничего «сложного» достаточно, чтобы рисковать потерей данных после синхронизации. Возможно, что контроллер может, скажем, буферизовать и группировать записи, или не записывать данные, если одни и те же данные перезаписываются (в ограниченной степени). В приведенной ниже программе мы чередуем два разных блока данных и выполняем синхронизацию перед обратным чтением, чтобы победить разумный механизм кэширования контроллера. Тем не менее, конечно, нет никаких гарантий и способов узнать, но мы можем сделать разумные предположения, основанные на нормальном использовании этих устройств и нормальных / обычных механизмах кэширования.

Тестирование:

К сожалению, правда в том, что, если вы не знаете, что устройство не имеет зарезервированного пространства и не выполняет статическое выравнивание, нет способа окончательно проверить ограничение цикла определенной страницы. Тем не менее, самое близкое, что вы можете получить, это следующее (предположим, нет статического выравнивания износа):

Первое , что вам нужно сделать , это заполнить всю карту с данными. Это важно и является основной переменной, которая была оставлена ​​в вашем исходном тесте. Это помечает столько блоков, сколько возможно, за исключением зарезервированного пространства (к которому у вас нет доступа). Обратите внимание, что мы работаем со всем устройством (на котором будут уничтожены все данные), поскольку работа с одним разделом влияет только на одну конкретную область на устройстве:

dd if=/dev/urandom bs=512k of=/dev/sdb conv=fsync oflag=sync

Если вы используете индикатор выполнения:

pv -pterb -s <device_size> /dev/urandom | dd bs=512k of=/dev/sdb conv=fsync oflag=sync

Изменить: Для карт с 4MB стереть блоки, попробуйте это для более быстрой записи:

dd if=/dev/urandom bs=4M of=/dev/sdb conv=fsync oflag=direct,sync iflag=fullblock

Затем вы можете написать программу циклического тестирования следующим образом, используя O_DIRECTи O_SYNC(и, возможно, параноидальное, избыточное использование fsync()) вырезать как можно больше буферизации и кэширования ОС из картинки и, теоретически, записывать напрямую в контроллер. и подождите, пока не появится сообщение о завершении операции:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>

using namespace std;

static const int BLOCK_SIZE = 512;
static const int ALIGNMENT = 512;
static const int OFFSET = 1024 * ALIGNMENT; // 1024 is arbitrary


int main (int argc, char **argv) {

    if (argc != 2) {
        fprintf(stderr, "usage: %s device\n", argv[0]);
        return 1;
    }

    int d = open(argv[1], O_RDWR | O_DIRECT | O_SYNC);
    if (d == -1) {
        perror(argv[1]);
        return 1;
    }

    char *block[2], *buffer;
    int index = 0, count = -1;

    // buffers must be aligned for O_DIRECT.
    posix_memalign((void **)&(block[0]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&(block[1]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&buffer, ALIGNMENT, BLOCK_SIZE);

    // different contents in each buffer
    memset(block[0], 0x55, BLOCK_SIZE);
    memset(block[1], 0xAA, BLOCK_SIZE);

    while (true) {

        // alternate buffers
        index = 1 - index;

        if (!((++ count) % 100)) {
            printf("%i\n", count);
            fflush(stdout);
        }

        // write -> sync -> read back -> compare
        if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(w)");
        else if (write(d, block[index], BLOCK_SIZE) != BLOCK_SIZE)
            perror("write");
        else if (fsync(d))
            perror("fsync");
        else if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(r)");
        else if (read(d, buffer, BLOCK_SIZE) != BLOCK_SIZE)
            perror("read");
        else if (memcmp(block[index], buffer, BLOCK_SIZE))
            fprintf(stderr, "memcmp: test failed\n");
        else
            continue;

        printf("failed after %i successful cycles.\n", count);
        break;

    }

}

Обратите внимание, что для O_DIRECT, буферы должны быть соответствующим образом выровнены. Границы 512 байт, как правило, достаточно. Вы можете скомпилировать с:

g++ -O0 test.cpp -o test

Добавьте, -D_POSIX_C_SOURCE=200112Lесли необходимо.

Затем, после заполнения устройства полностью, как указано выше, просто оставьте его работать на ночь:

./test /dev/sdb

512 байт, выровненные записи в порядке, что даст вам одну целую страницу, стертую и переписанную. Вы можете значительно ускорить тестирование, используя больший размер блока, но тогда становится сложно получить конкретные результаты.

В настоящее время я тестирую на довольно потрепанном 4ГБ флэш-накопителе PNY, который я обнаружил вчера на тротуаре (похоже, это то, что осталось от http://www3.pny.com/4GB-Micro-Sleek-Attach-- -Purple-P2990C418.aspx ).

Вышеуказанная программа по сути является ограниченной версией, badblocksи вы не увидите сбоев, пока не будет исчерпано все зарезервированное пространство. Следовательно, ожидание (с 1 страницей, записанной за каждую итерацию) состоит в том, что вышеупомянутая процедура, в среднем, должна завершиться неудачей в итерациях reserved_page_count * write_cycle_limit (опять же, выравнивание износа является основной переменной). Это очень плохо, флэш-накопители и SD-карты обычно не поддерживают SMART, который имеет возможность сообщать о зарезервированном размере пространства.

Кстати, fsyncvs fdatasyncне имеет значения для записей блочного устройства, которые вы делаете, для целей этого теста. Ваши open()моды важны.

Если вам интересно узнать о технических деталях; Здесь есть все, что вы хотели бы знать (и больше) о внутренней работе SD-карт: https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf

Изменить: байты против страниц: в контексте этих типов тестов важно думать о вещах в терминах страниц, а не байтов. Это может вводить в заблуждение противоположное. Например, на SanDisk 8GB SD размер страницы в соответствии с контроллером (доступный через /sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size) составляет целых 4 МБ. Запись 16 МБ (выровненных по границам 4 МБ), затем стирание / запись 4 страниц. Однако запись четырех отдельных байтов каждый со смещением 4 МБ друг от друга также стирает / записывает 4 страницы.

Тогда неточно сказать «я проверял с записью 16 МБ», так как это тот же уровень износа, что и «я проверял с 4-байтовой записью». Точнее, «я тестировал с 4 страницами пишет».


Я добавил комментарий относительно байтов и страниц.
Джейсон С

PNY кажется неразрушимым. Однако после ~ 8,1 млн итераций (более 8 часов) на новом SanDisk 8 ГБ MicroSD с последующим циклом включения питания максимальная скорость записи (первоначально 4 МБ / с) окончательно упала до ~ 410 КБ / с и ddзавершается с ошибкой после записи 250 МБ , Ущерб не появлялся до окончания цикла питания. Привод большого пальца PNY остается неизменным после ~ 30-миллиметровых итераций. Я изменил программу выше (однако, это не отражено в коде выше), чтобы записывать в случайные 16-килобайтные местоположения каждый раз вместо одного и того же, но я сделал это после ~ 4 миль на SD. Будет проведен повторный тест с новой картой.
Джейсон C

Третья попытка ddна этой карте преодолела отметку 250 МБ, и производительность записи снова возросла до полных 4 МБ / с в областях после этой точки. Я ожидаю, что производительность будет непредсказуемой, поскольку блоки продолжают перемешиваться. Я бы не сказал, что карта уничтожена, но это точно не на все 100%.
Джейсон C

5

Просто добавьте несколько пунктов к ответу slm - обратите внимание, что они больше подходят для твердотельных накопителей, чем для «тупых» SD-карт, поскольку твердотельные накопители играют с вашими данными гораздо более хитрые уловки (например, дедупликация):

  • Вы пишете 64KB в начале устройства - это само по себе имеет две проблемы:

    1. ячейки флэш-памяти обычно имеют блоки стирания размером от 16 КБ и выше (однако, более вероятно, в диапазоне 128-512 КБ). Это означает, что ему нужен кэш как минимум такого размера. Следовательно, написание 64KB мне кажется недостаточным.

    2. для бюджетных решений (читай «не для предприятий») (и я ожидаю, что для карт SD / CF это будет даже больше, чем для твердотельных накопителей), производители могут сделать начало устройства более устойчивым к износу, чем остальные, так как важные структуры - таблица разделов и FAT на одном разделе на устройстве (большинство карт памяти используют эту настройку) - находятся там. Таким образом, тестирование начала карты может быть предвзятым.

  • fdatasync() на самом деле не гарантирует, что данные будут записаны на физический носитель (хотя, вероятно, лучше всего работают под управлением ОС) - см. справочную страницу:

    Вызов блокируется, пока устройство не сообщит, что передача завершена

    Я не был бы слишком удивлен, если бы выяснилось, что есть небольшой конденсатор, который способен обеспечить энергию для записи кэшированных данных во флэш-память в случае потери внешнего питания.

    В любом случае, исходя из предположения о наличии кэша на карте (см. Мой ответ на ваш вопрос о SU ), запись 64 КБ и синхронизация (с fdatasync()) не кажутся достаточно убедительными для этой цели. Даже без какого-либо «резервного питания» микропрограмма может по-прежнему воспроизводить ее небезопасно и сохранять данные не записанными дольше, чем можно было ожидать (поскольку в типичных случаях использования это не должно создавать никаких проблем).

  • Возможно, вы захотите прочитать данные, прежде чем писать новый блок и сравнивать его, просто чтобы убедиться, что он действительно работает (и используйте очищенный буфер для чтения, если вы достаточно параноидальны).


+1 Для выделения возможности кеширования и значимости блока стирания в этом. Но ...
Златовласка

«тестирование начала карты может быть предвзятым» Помните, что из - за выравнивания износа (который должен быть в игре - я превышено любое разумное количество циклов записи в этой точке) - это только по- видимому , первый блок. То есть это первый виртуальный блок, а не первый физический блок.
Златовласка

«fdatasync () на самом деле не гарантирует, что данные будут записаны на физический носитель» IMO, устройство, сообщающее о завершении передачи, указывает, что запись должна была произойти, если устройство также прошло тесты на чтение и запись (оно не провалился еще один). Кэширование может усложнить это, но если мы используем достаточно большой кусок, чтобы обойти это, просто не может быть «ложных записей», когда устройство сообщило об успехе. Было бы бесполезно, если бы это было сделано.
Златовласка

1
@goldilocks нет, чтение данных с устройства ничего не гарантирует. Это разумно , чтобы ожидать , что данные , чтобы быть на физическом носителе, и он , вероятно , будет в большинстве случаев, но это не гарантировано - по крайней мере , если вы не выйти за пределы размера кэша.
Петер

1
@goldilocks Петер поднимает еще одну вещь, на которую я хотел указать; readв тесте не нужен, он не добавляет никакой информации и не относится к циклическому испытанию записи. Для истинного теста вы захотите прочитать только что записанный блок и проверить его, если только вы точно не знаете, что контроллер может обнаружить и сообщить обо всех режимах отказа.
Джейсон С

2

Ответ Петерфа заставил меня задуматься над вопросом возможного кеширования. Покопавшись, я все еще не могу точно сказать, делают ли это какие-либо, некоторые или все SD-карты, но я думаю, что это возможно.

Тем не менее, я не верю, что кеширование будет включать данные больше, чем блок стирания. Чтобы быть действительно уверенным, я повторил тест, используя блок 16 МБ вместо 64 КБ. Это составляет 1/250 от общего объема карты 4 ГБ. Это заняло ~ 8 часов, чтобы сделать это 10000 раз. Если выравнивание износа делает все возможное, чтобы распределить нагрузку, это означает, что каждый физический блок использовался бы 40 раз.

Это не так много, но первоначальная цель теста состояла в том, чтобы продемонстрировать эффективность выравнивания износа , показав, что я не мог легко повредить карту путем многократной записи небольших объемов данных в одно и то же (кажущееся) место. IMO предыдущий тест 64 КБ, вероятно, был реальным - но 16 МБ должен быть. Система сбросила данные на оборудование, и оборудование сообщило о записи без ошибки. Если бы это было обманом, карта ни к чему не годится, и она не может кэшировать 16 МБ нигде, кроме как в первичном хранилище, что и должно подчеркнуть тест.

Надеемся, что 10 000 операций записи по 16 МБ каждая достаточно, чтобы продемонстрировать, что даже на нижней фирменной карте (стоимость: $ 5 CDN), работающей с корневой файловой системой rw 24/7, которая ежедневно записывает небольшие объемы данных, карта не изнашивается в разумный период времени. 10000 дней - это 27 лет ... и карта все еще в порядке ...

Если бы мне платили за разработку систем, которые выполняли более тяжелую работу, чем это, я бы хотел сделать хотя бы несколько тестов, чтобы определить, как долго может работать карта . Я догадываюсь, что с таким, который имеет низкую скорость записи, это может занять недели, месяцы или годы непрерывной записи на максимальной скорости (тот факт, что нет сравнительных тестов такого рода в Интернете, говорит о Дело в том, что это было бы очень длительным делом).

Что касается подтверждения карты все еще в порядке, я больше не думаю, используя badblocks в ее конфигурации по умолчанию является подходящим. Вместо этого я сделал это так:

badblocks -v -w -b 524288 -c 8

Это означает, что тестирование с использованием блока 512 кБ повторяется 8 раз (= 4 МБ). Так как это разрушительный тест на тестирование, он, вероятно, будет лучше моего домашнего теста в отношении нагрузки на устройство, если он используется в непрерывном цикле.

Я также создал файловую систему, скопированную в файл размером 2 ГБ, diff сопоставил файл с оригиналом, а затем - поскольку этот файл представлял собой файл .iso - смонтировал его как образ и просмотрел внутри него файловую систему.

Карта все еще в порядке. Что, вероятно, следовало ожидать, в конце концов ...

;);)


Я не думаю, что ваша математика верна. Карта класса 2 имеет пропускную способность 2 МБ / с, что означает, что вы поместите 20 ТБ примерно через 4 месяца. Конечно, вы упомянули, что у вас есть неклассифицированная карта, но вы, кажется, действительно на несколько порядков ниже (как отметил тердон в unix.stackexchange.com/questions/84902/… ). В остальном я полностью согласен с slm.
Петер

Я полагаю, что мы можем быть достаточно уверены, что кэширование оказывает минимальное влияние, если оно вообще имеет место, после синхронизации для носителей, которые предназначены для частого удаления, а также с питанием от шины. Учтите, что эти устройства предназначены для надежного «извлечения» и удаления, и что синхронизация - это абсолютная последняя вещь, которую ОС может сделать с устройством, кроме отключения его питания (если это возможно). Разумно предположить, что, например, USB-накопитель или SD-карта либо физически записаны после синхронизации, либо, как минимум, выполняют запись в чрезвычайно короткий промежуток времени после отключения питания.
Джейсон С

Кроме того, кстати, badblocksне покажет вам сбой страниц на флэш-памяти. Это не правильный инструмент для этой работы, и вы не можете использовать его для поиска неисправных страниц на флэш-памяти. Когда контроллер обнаруживает сбой, он внутренне помечает страницу как плохую и переназначает ее на страницу в зарезервированном пространстве. Все это происходит за контроллером и вообще невидимо для вас, даже в необработанном дампе устройства . Вы можете получить некоторую информацию от контроллера, если поддерживается SMART. Физический порядок данных на устройстве не соответствует порядку байтов, который вы видите при выполнении ввода-вывода на устройстве.
Джейсон С

Еще один комментарий, больше к сведению: для MicroSD SanDisk 8GB, потребительского уровня, единица выделения (то есть размер страницы) составляет 4 МБ, как сообщает контроллер; это означает, что 16 МБ на этой карте составляет 4 страницы (5, если она не выровнена). Вы можете ускорить этот тест, записав 512 байт с смещением 4 МБ друг от друга вместо подачи 16 МБ на карту. Вы не проводите различий между байтами и количеством страниц, но вы должны это делать - в вашем примере, если бы он был на карте памяти SanDisk 8 ГБ, «16 МБ» изнашивал карту так же, как и «2 КБ». Весьма неверно ссылаться на байты, а не на страницы.
Джейсон С

После ~ 8,1 млн итераций (более 8 часов) в тестовой программе, которую я написал выше, с последующим циклом включения питания на новом MicroDD SanDisk 8 ГБ, скорость записи постоянно ограничена примерно 450 КБ / с и ddне удается выполнить запись до 250 МБ. отметка. С третьей ddпопытки он преодолел 250 МБ, и после этого производительность записи снова возросла в этих областях. Я бы не сказал, что карта уничтожена, но она точно не на 100%.
Джейсон С
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.