Малиновый Прог против Интернета Кирпичей, или Raspberry Pi с графикой на read-only microSD

    Аннотация


    Запуск Raspberry Pi с полной поддержкой графики на microSD, навсегда остающейся в режиме read-only после установки системы. Отсутствие какой-либо записи данных на флэш-память повышает надёжность устройства, приближая его к промышленному классу изделий. Пошаговая инструкция. Небольшой театр инженерного абсурда для развлечения аудитории.


    Мне понадобилось сетевое устройство с открытым кодом и выходом HDMI, и я решил попробовать Малиновый Прог. Да, я именно так предлагаю переводить Pi: Прог. Понятное дело, даже одноплатнику нужна операционка. И вот, захожу я на официальный сайт, ожидая встретить там подробное руководство по созданию суровой, неломаемой Вещи à la turnkey box. Но народ, как ни в чём не бывало, устанавливает Ubuntu (т.е. Raspbian Jessie) прямо на microSD, размещая и swap там же. Как обычный десктоп, face palm.

    Но то цветочки. Малиновые ягодки — это проекты фоторамок из МалинПрога, требующие обязательного выключения кнопкой. Иначе фоторамка после сбоя питания может не заработать, вместо картинок предлагая воспользоваться fsck. Но и это не предел, под катом читателя ждёт настоящий шедевр инженерного абсурда, найденный автором на просторах сети.

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

    Куда мир катится


    Прежде чем открывать спойлер, оденьте защитную маску, либо заранее возьмитесь руками за голову.

    Неплохой проект, который испортила одна рекомендация
    Представьте себе большой телевизор и демонстратор слайд-шоу на базе RPi, но с нейтрализацией скринсейвера аппаратным (!) имитатором ёрзающей мыши. Дескать, в оконном интерфейсе Raspbian тайм-аут скринсейвера больше 720 минут не выставляется. Поэтому, дабы каждые 12 часов не шевелить мышь вручную, народ автоматизирует процесс микроконтроллером, создающим виртуальные «ползки» USB-мыши каждые 4 минуты. Я не шучу, вот реальный проект на RPi, там же ссылка на микроконтроллер ECIO28P, и прошивка взбадривателя имеется.

    Ладно, не буду отрицать самостоятельной полезности аппаратного взбадривателя: это реальный лайф-хак для тех, у кого почасовая оплата идёт за сидение перед монитором. Или для поддержания в тонусе какого-нибудь особо тупого сурового промышленного терминала, из-под антивандальной брони которого торчит один разъём для мыши (для PS/2 должен подойти зелёный переходник). Да, если втиснуть раздутый десктоп в одноплатный компьютер, то в руках über-умельцев это грозное оружие, особенно с брутально торчащей из разъёма платой МК. Сразу видно: человек умеет работать руками. Но если нужен вечно включённый экран, на линуксе достаточно головы, резиденты данного ресурса прекрасно это знают. Для гостей портала я всё-таки дам инструкцию, мало ли чего.

    Отключение DPMS, скринсейвера и заодно всех GUI-элементов
    Для начала примем, что используется минималистичная оболочка LightDM, и отключим X-серверу DPMS в файле /etc/lightdm/lightdm.conf:
    ...
    xserver-command=X -s 0 -dpms -nocursor
    ...

    Флажок -nocursor убирает долой из центра экрана неподвижную стрелку курсора. А вместо нейтрализации скринсейвера можно просто закомментировать его запуск в файле ~/.config/lxsession/LXDE/autostart. Если это не помогает, можно повесить по cron(8) с интервалом 718 минут команду xscreensaver-command -deactivate (это уже стёб, дорогие читатели ;-)

    Я поступил просто: принял LightDM с автовходом, но оставил в файле ~/.config/lxsession/LXDE/autostart лишь вызов feh с префиксом '@' для перезапуска в случае аварии и соотв. параметрами. Т.е. как бы обычная графика, но без lxpanel, без pcmanfm, без xscreensaver, с отключённым DPMS и скрытым курсором несуществующей мыши.

    Минимальную графику очень легко получить командами apt-get и правкой файла autostart, причём в системе будет всё необходимое для жизнедеятельности стандартных приложений, включая X-сервер, менеджер окон, менеджер сеансов и менеджер дисплея с автовходом пользователя. Но пока это ещё не Вещь, а всего лишь одноплатный десктоп.

    UPD
    Пользователь Jaromir предлагает вообще отказаться от менеджера дисплея и использовать unclutter в тех случаях, когда мышь изредка требуется. Эта утилита скрывает курсор, если мышь находится в покое достаточно долго.
    Пользователь Spider55 рекомендует вместо LightDM использовать noDM. Считаю весьма разумным, но тогда пошаговая инструкция чуть меняется.

    Задача


    Сферический одноплатник в вакууме — это скучно. Не для того на Малиновом Проге целая гребёнка GPIO с I2C/PWM, а также всякие CSI-DSI и сторожевой таймер. Но я в качестве практического примера использую всё-таки сетевой демонстратор с HDMI-выходом, добавив возможность нескольким пользователям по очереди «захватывать» общий экран-табло и транслировать на него свой рабочий стол, не вставая с кресла. Экран повёрнут лицом в сторону гостей, в состоянии покоя тихонечко перебирает случайным образом картинки, выложенные в сети. Если надо показать гостю продукт, один из сидящих за стойкой администраторов временно превращает табло в «зеркало» своего монитора, но потом освобождает его для другого админинистратора. В моём случае это реальный бизнес-инструмент, висящий в реальном торговом зале. Кстати, благодарю пользователя Sauron за подсказку.

    Однако, глянув на размер этой публикации, я решил отложить описание прикладного решения (т.е. собственно видеомодуля) в отдельную статью. Пока позвольте сфокусироваться на изначальной задаче: заставить Raspberry Pi загружаться и работать с microSD в режиме read-only, не боясь отключения питания и не запиливая флэш-память мусором.

    Теория вопроса


    Даже очень серьёзная файловая система с журналом в конечном итоге не может проконтролировать процессы, происходящие внутри SD-носителя при отключении питания. Например, серьёзные SSD-накопители для использования в ЦОД имеют конденсаторы, разряда которых как раз хватает на закрытие последней транзакции записи, и даже остаётся ещё немного. А что с отключением питания в microSD? Я уверен, там конденсаторов достаточной ёмкости нет, зато есть ненулевая вероятность того, что запись страницы NAND-памяти не успеет завершиться. И потом драйвер файловой системы от прочитанного придёт в такое недоумение, что потребуется ручное вмешательство оператора. Вот вам и фоторамка с fsck.

    Насколько сложно перевести microSD Raspberry Pi в режим read-only методом Микеланджело, т.е. убирая лишние службы и пакеты? Достаточно просто, если нет графики (ссылка). Но стоит пустить в систему иксы с этими их многочисленными менеджерами всего, начинается долгий и нудный поединок с непредсказуемым результатом. Это вам не иголка в стоге сена, её хотя бы магнитом можно вытянуть. Представьте, что неизвестное количество иголок спрятаны в клубке из колючей проволоки, да ещё обильно присыпаны гвоздями. Какой там поиск иголок, не убиться бы насмерть.

    Лемма: для выполнения даже самой элементарной новой функции линукс-система всегда подтянет кучу ненужных зависимостей, причём даже с «лёгкой» графикой рост системной энтропии получается кратный.

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

    Решение: UnionFS


    Один немец несколько лет назад придумал очень красивый способ собрать все эти иголки в корыто с помощью UnionFS и просто сжигать их в печи при каждой перезагрузке. К сожалению, оригинальный пост уже погиб вместе с хостившим его доменом, но немец точно не одинок. Благодарные читатели сохранили идею, я считаю просто необходимым опубликовать её здесь.

    Суть в том, что поверх постоянной «подложки» (read-only файловой системы на microSD) при каждом включении создаётся временная «нашлёпка» в ОЗУ, поглощающая всю ненужную энтропию и «сгорающая» при выключении питания устройства. Файловая система на microSD всё время остаётся read-only, и потому риск её повреждения снижается почти до нуля, как и риск преждевременного износа флэшки. Почему не строго до нуля? Знатоки EXT4, поправьте меня, но драйвер файловой системы всё-таки что-то записывает на носитель при каждом монтировании-демонтировании файловой системы, даже если она монтируется в read-only. И noatime не поможет, нужен аппаратный ключ на microSD. Иначе как объяснить тот факт, что по /sys/block/mmcblk0/stat у меня оказалось считано 282612 секторов, а записано аж 96, и это в режиме read-only? Ладно, хоть соотношение почти 3000:1, на обычной системе оно 5:1. (виноват, соврал, но сути это не меняет)

    UPD:
    Пользователь gattopazzo83 указал мне на промышленную память Flash Media Kit производства известной фирмы Харлампий-Панкрат (теперь уже Эдуардович). Раз у неё 100,000 циклов записи, это точно SLC-память в формате microSD. Даже если уважаемый читатель использует файловую систему в read-only, для серьёзных проектов я настоятельно рекомендую потратиться на промышленную память, это практика крепсондо («до» по-японски означает «путь» ;-)


    UPD:
    В комментариях достаточно длинная дискуссия вышла у меня с пользователем doga, в результате которой я «открыл» для себя простой способ получать внутреннюю информацию об используемой SD-карточке прямо из командной строки RPi. Пользователь doga в долгу не остался и указал на пакет mmc-utils, который тоже читает внутренности SD-карточки, но готового порта для Raspbian я не увидел. Что-то помещаю в спойлер, который, видимо, будет пополняться и раздуваться.
    SD-внутренности
    Команда:
    udevadm info -a -n /dev/mmcblk0

    Можно увидеть «сырые» регистры CID и CSD, из них код изделия (name), серийный номер (serial), дату производства (date), идентификаторы производителя (hwrev, fwrev, oemid, manfid). Расшифровку можно найти на сайте www.sdcard.org в разделе загрузок «упрощённых» спецификаций (Simplified Specifications), см. Part 1 Simplified, Physical Layer Simplified Specification.
    Очень интересный объект stat, структура которого описана прямо на kernel.org. Эта информация сбрасывается при перезагрузке, но по ней можно оценить среднесуточную нагрузку на чтение и запись.
    Коды производителей где-то точно лежат, но я их нашёл только в исходниках lsmmc.c.
    «Пробить по базе» карточку можно хотя бы в разделе RPi SD cards на сайте Embedded Linux, это просто отзывы пользователей.
    Самое интересное — данных износа — пока не увидел, хотя утилиту mmc-utils собрал, но пока запустить её не удалось.


    Недостатки


    Какие минусы, помимо «сгорания» логов? Устройства без аппаратных часов при старте всегда считают, что на дворе 1 января 1970 года, и пребывают в этом заблуждении вплоть до подъёма сетевого стэка и доступности NTP. Поэтому на момент данной публикации целый ряд файловых объектов «нашлёпки» будут примерно на 46 лет моложе, чем им кажется. С другой стороны, несколько секунд от начала эпохи — уже не ноль.

    UPD: часы реального времени
    Пользователь st1373 в комментариях напомнил о наличии I2C-совместимых часов реального времени DS3231 (стоимостью примерно в полтора рулона туалетной бумаги). Есть и нехитрая инструкция на русском: Подключение RTC (часов реального времени) к Raspberry Pi.


    Безопасность


    Обновления безопасности накатывать на такую систему довольно неудобно. Но, опять же, взломать такую Вещь несколько сложнее, чем эксплуатировать уязвимость Adobe Flash в браузере обычного десктопа. Вредоносный код должен открыть файловую систему на запись, чтобы закрепиться в ней, иначе он «сгорит» при перезагрузке вместе с логами и мусором. Упомянутая ниже SquashFS усложняет изменения ещё больше. Однако все эти преимущества справедливы ровно до того момента, пока вся выпоняемая масса кода «замкнута» в read-only зонах, т.е. когда защищённая «подложка» не делает вызовов команд, расположенных в записываемых областях: именно это и есть (будет?) приоритетным вектором заражения в Интернете Вещей. Будьте внимательны со стартовыми скриптами, они выполняются с правами root, одно неверное движение — и это критическая уязвимость инфраструктуры домашнего очага, постоянно подключённой к Интернету.

    Пошаговая инструкция


    Поскольку я впервые в жизни установил Rasbian Jessie и особо не верю в долговечность microSD даже в read-only, то решил записать все шаги подробно. Вдруг понадобится повторить.

    DISCLAIMER
    Извините за переносы строк. Все команды запускаются с правами root, но аккуратный читатель может использовать каждый раз sudo. Честно говоря, я не понимаю, зачем каждую команду запускать через sudo, будто это защитит от чего-то. Вот скажите, когда вы в последний раз *не были* уверены, что хотите удалить данный файл в корзину? Это как выпить пять бокалов пива по пол-литра, но на дорожку ещё налейте один 0.33, пожалуйста, а то мне уже хватит… Я дам неправильный совет: если уж взялись за эти игрушки, выходите на root командой sudo bash, не занимайтесь самообманом.

    1. Инициализация

    Установите Raspbian Jessie Lite. Утилитой raspi-config задайте региональные настройки и пароль пользователя pi. Подключите сеть, Debian — дитя широкополосного доступа. Загрузку в графику пока не включайте.

    apt-key update
    apt-get update

    2. Установка и удаление программ

    С графикой, установка:

    apt-get install --no-install-recommends tightvncserver xtightvncviewer xserver-xorg xinit lxde-core lxappearance lightdm feh xprintidle policykit-1 busybox-syslogd ntpdate watchdog unionfs-fuse

    Удаление:

    dpkg --purge rsyslog
    apt-get remove --purge wolfram-engine triggerhappy cron anacron logrotate dphys-swapfile fake-hwclock
    apt-get autoremove --purge


    Пакеты tightvncserver, xtightvncviewer, xprintidle и feh понадобились мне для частной задачи, можете обойтись без них.

    Если без графики, вам *не* понадобятся также: xserver-xorg xinit lxde-core lxappearance lightdm policykit-1.

    3. Создание графического окружения

    Теперь утилитой raspi-config можно включить автозапуск в графическом режиме с автовходом, который будет с правами пользователя pi. Чем зацикливаться на sudo, лучше поставить сильный пароль пользователю pi, и не использовать pi для автоматического входа в графический интерфейс. Вместо этого создать пользователя pu и запускать «иксы» с его правами. Причём командный интерпретатор (default shell) этого пользователя лучше либо отключить совсем (поставив /usr/sbin/nologin), либо подменить специальным скриптом типа /usr/local/bin/pu. Об этом я намерен рассказать в другой публикации, посвящённой видеотабло с удалённым управлением по SSH, ради чего и создаётся отдельная учётная запись с пониженными правами. Ещё раз благодарю Sauron et al.

    adduser --home /home/pu --shell /usr/local/bin/pu --uid 990 --gecos "RPi p-u" --gid 1000 pu
    mkdir -p /home/pu/.config/lxsession/LXDE
    cp -p /etc/xdg/lxsession/LXDE/desktop.conf /home/pu/.config/lxsession/LXDE/desktop.conf
    touch /home/pu/.config/lxsession/LXDE/autostart
    chown -R pu:pi /home/pu
    sed -i 's/^#\?xserver-command=.*$/xserver-command=X -s 0 -dpms -nocursor/' /etc/lightdm/lightdm.conf
    sed -i 's/^#\?autologin-user=.*$/autologin-user=pu/' /etc/lightdm/lightdm.conf

    Вместо двух последних команд можете открыть редактором /etc/lightdm/lightdm.conf и задать значения двух параметров, первый я уже упоминал выше, второй говорит сам за себя:

    ...
    xserver-command=X -s 0 -dpms -nocursor
    ...
    autologin-user=pu
    ...

    4. Сторожевой таймер (по желанию)

    У меня Raspberry Pi 3 Model B, поэтому ядерный модуль сторожевого таймера зовут так:

    modprobe bcm2835_wdt
    echo "bcm2835_wdt " | sudo tee -a /etc/modules

    Затем добавляем следующую строку в секцию [Install] в конце файла /lib/systemd/system/watchdog.service:

    [Install]
    WantedBy=multi-user.target

    После этого включаем службу:

    systemctl enable watchdog.service

    Сторожевой таймер в минимальной конфигурации должен сработать, если зависло ядро. Но есть ещё много других вариантов, например, по чрезмерной нагрузке на систему, по истечению памяти, по перегреву системы, по отсутствию сигнального файла и т.д. См. также watchdog(8) и watchdog.conf(5)

    5. Параметры старта

    Я отключил отображение малинового лого и swap-файл, включил быструю загрузку. Для этого добавил в /boot/cmdline.txt буквально три слова logo.nologo fastboot noswap. У меня в итоге получилось так:

    logo.nologo dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fastboot noswap

    6. Запечатывание корневой файловой системы Raspberry Pi в read-only

    Вот теперь мы добрались, наконец, до главного.

    Ниже скрипт, который следует расположить под именем mount_unionfs где-нибудь в /usr/local/bin. Не забудьте включить биты выполнимости +x (chmod 755 или 555). Обратите внимание на суффиксы .orig и .rw, они должны совпадать с подготовкой (далее):

    #!/bin/sh
    DIR=$1
    ROOT_MOUNT=$(awk '$2=="/" {print substr($4,1,2)}' < /etc/fstab)
    if [ $ROOT_MOUNT = "rw" ]; then
    	/bin/mount --bind ${DIR}.orig ${DIR}
    else
    	/bin/mount -t tmpfs ramdisk ${DIR}.rw
    	/usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}.rw=RW:${DIR}.orig=RO ${DIR}
    fi

    Из других инструкций я решил воспользоваться советом и сделать следующее:

    insserv -r bootlogs
    insserv -r alsa-utils
    
    rm -rf /var/lib/dhcp/
    ln -s /tmp /var/lib/dhcp

    Графические приложения очень любят записывать в /home что-нибудь ненужное, поэтому в дополнение к /etc и /var я включил ещё и /home. Подготовим разделы к переключению в режим UnionFS (внимание на суффиксы .orig и .rw):

    
    cp -al /etc /etc.orig
    mv /var /var.orig
    mv /home /home.orig
    mkdir /etc.rw /var /var.rw /home /home.rw

    Наконец, файл fstab(5)

    proc            /proc           proc    defaults        0       0
    /dev/mmcblk0p1  /boot           vfat    ro              0       2
    /dev/mmcblk0p2  /               ext4    ro              0       1
    mount_unionfs   /etc            fuse    defaults        0       0
    mount_unionfs   /var            fuse    defaults        0       0
    mount_unionfs   /home           fuse    defaults        0       0
    none            /tmp            tmpfs   defaults        0       0

    7. Аудит системы и тест

    Окиньте взглядом систему, уберите за собой .bash_history, всякие лог-файлы и т.д. Учтите, что они сейчас могут находиться не там, где обычно (например, в /var.orig вместо var).

    Перезагрузите систему и посмотрите, что получилось. Если была допущена ошибка, есть большие шансы, что система уйдёт в single user и просто запустит консоль root. Если файловая система цела, перемонтировать её из read-only в read-write довольно просто:

    mount -o rw,remount /

    Если же система загрузилась нормально в read-only и выполняет все функции, поздравляю!
    Это родилась Интернет-Вещь.

    8. Распечатывание файловой системы

    Если нужно распечатать систему, сперва верните коневую систему в состояние read-write (см. выше). Затем закомментируйте в fstab(5) строки, начинающиеся со слова mount_unionfs, после чего *обязательно* верните на место каталог /var.orig со всем содержимым (и желательно /home.orig тоже). Если не восстановить /var, потеряете базу установленных пакетов, но ведь именно ради установки обновлений безопасности командой apt-get вы только что распечатали систему, не так ли? Перед apt-get перезагрузите систему и убедитесь в её адекватности. Как запечатывать обратно, знаете;)

    Альтернативы


    Уважаемых читателей, которые знают готовые промышленные образы операционных систем (с поддержкой read-only) для Raspberry Pi и других одноплатных компьютеров, приглашаю делиться в комментариях. Надеюсь, с вашей помощью я смогу информационно обогатить этот раздел и других читаталей, резидентов и гостей уважаемого портала Geektimes:)

    Что касается аппаратных альтернатив самому Малиновому Прогу в контексте прикладной задачи (сетевой HDMI-свисток), то я случайно наткнулся на один обзор, который, впрочем, можно обсудить отдельно. Чисто экономически Raspberry Pi весьма выгоден, это пока главное:)

    Итак, поехали.

    UPD: OverlayFS
    Уважаемый ValdikSS упомянул проект OverlayFS, который вошёл в ядро Linux в 2014г, уже после оригинального немецкого поста, а также initramfs. А спустя некоторое время art_gl прислал ссылку на пошаговую инструкцию: Raspbian with Read-only Root.
    Кстати, проект Domoticz, у которого есть и готовый образ для Малинового Прога, может использовать OverlayFS. И заодно ещё раз поблагодарю Sauron за комментарий про Domoticz.


    UPD: SquashFS
    Пользователи Vooon, Vcoderlab, av_in et al справедливо упомянули в комментариях SquashFS. И даже википедия отмечает, что данная система удачно ложится «под» union mount, также аккумулируя энтропию записи исключительно в ОЗУ для последующего уничтожения. Однако не стоит забывать, что SquashFS by-design всегда остаётся read-only, т.е. речь идёт скорее о серийном изготовлении firmware-прошивки, с соответствующим (длинным) циклом тестирования, но это не главное. Обновление критических уязвимостей, особенно на раздутых системах, очень сильно удорожает подобные проекты. И не только я считаю, что именно критические уязвимости в IoT будут определять ландшафт информационной безопасности в ближайшие лет десять. Нет ничего невозможного, но даже если уважаемый читатель настолько подкован, что может изготовить стабильный образ системы на SquashFS, стоит ли он двух-трёх Малиновых Прогов? Впрочем, это всего лишь вопрос времени, и мы с вами скоро увидим больше удачных community-проектов для Интернета Вещей на базе SquashFS, в т.ч. и для Raspberry Pi. Например, OpenELEC.


    UPD: F2FS
    Пользователь nlykl упомянул F2FS aka «Flash-Friendly File System», и на тему МалинПрога есть даже HOWTO: Replace the micro SD card's ext4 root partition by f2fs on the Raspberry PI. DISCLAIMER: мною не проверялось. См. также обзор F2FS в одном онлайн-журнале.


    UPD: Загрузка по сети
    Пользователь ilmarin77 указал на официальную возможность загружать Прог по сети: Network booting. Появляется зависимость от сервера. Пожалуй, интересно для группы устройств, например, та же система видеотабло на объекте, либо (не очень критичная к отказам) система распределённых датчиков. Диапазон работы проводного модуля USB-Ethernet LAN9514 составляет 0..70°C


    UPD: Загрузка с USB-накопителя
    Снова ilmarin77 указал на загрузку с USB: How to boot from a USB Mass Storage Device on a Raspberry Pi 3. Если загружаться и работать с SSD, подключённого по USB, это будет надёжнее, чем microSD, но со скоростью USB 2.0 (где-то 30-40Мбайт/с, да ещё и в полудуплексе). Мне такая идея не очень нравится, потому что превращает устройство в медленный десктоп. Возможно, лучше загружаться с read-only microSD, но логи и СУБД держать на SSD повышенной надёжности и небольшой ёмкости, чтобы не стоило как деталь самолёта. USB-флэшка потенциально обладает теми же проблемами, что и microSD, и принципиально ничего не меняет.


    UPD: Сторожевой таймер (watchdog)
    Пользователь homecreate указал на более простой способ включения сторожевого таймера через systemd, правда, с некоторыми ограничениями. См. также комментарий.


    UPD:

    Находится ли моя система в зоне риска?


    Именно этот вопрос и задаёт себе рациональный читатель. К сожалению, индустрия флэш-памяти для Интернета Вещей только начинает вырабатывать аппаратные механизмы, аналогичные S.M.A.R.T для HDD и SSD. SanDisk, кстати, уже пошёл по этому пути, встроив метрики износа в структуры EXTCSD. И когда нужные стандарты более-менее устаканятся, появится поддержка в ядре Linux и утилиты командной строки. А там, глядишь, и аналог smartd(8) для встраиваемых систем появится.

    Но получить ответ на вопрос «сколько моя Linux-система записывает на SD-карточку в сутки/неделю» можно уже сейчас, нужно только продержать систему включённой достаточно долго, чтобы статистика получилась точнее (т.е. желателен uptime порядка месяца, или хотя бы 10 дней). Итак, заходим в систему и делаем две команды (без sudo и root):

    uptime
    cat /sys/block/mmcblk0/stat | awk '{printf "Uptime read: %.3fMiB (%.1f%% I/Os merged) written: %.3f MiB (%.1f%% I/Os merged)\n", $3*512/1048576, $2/$1*100, $7*512/1048576, $6/$5*100}'

    Первая в комментариях не нуждается, а вторая напишет объёмы считанных и записанных данных с момента старта системы, в мегабайтах, а также «кучность» запросов. Например, пользователь Meklon в комментариях весьма любезно поделился цифрами медиа-центра, работающего на базе openELEC / KODI. Примерно за 6 дней система считала порядка 72Мб и записала менее 66Мб. Примечательно соотношение чтение/запись близкое к 1:1, что я связываю с использованием SquashFS (она распаковывает файловую систему в ОЗУ и потому SD-карточку почти не трогает даже на чтение). Классические же системы имеют показатель чтение/запись от 5:1 до 10:1, но он может сильно варьироваться. Однако главное в том, что 10Мб в сутки — это существенно меньше автомобильного регистратора, система с такими параметрами весьма долговечна.
    Но помимо статистического подвоха, в такой методике есть ещё один чисто технологический изъян: запись на флэшку производится не блоками по 512 байт, а страницами неизвестного размера, либо даже целыми erase-блоками мегабайтных размеров. В докладе Optimizations for Cheap Flash Media автора Arnd Bergmann (ссылка, англ.) сказано довольно много интересного по поводу внутренней «кухни» флэшек, в т.ч. упомянут размер страницы 32КБайт, размер erase-блока 4..8МБайт. И если принять самый неудачный сценарий «кучности» записи, то каждый блок 512 байт вынудит записать одну страницу целый erase-блок, т.е. объём фактически записанных данных получится в 64 раза тысячекратно больше, чем говорит stat. Пользователи в комментариях описывали систему с интенсивностью записи порядка 6ГБайт/мес, которая изнашивает microSD-карточку всего за несколько месяцев.
    Как только автор наберёт достаточно материала, будет продолжение в отдельной публикации.


    Ссылки


    Make Raspbian System Read-Only
    blog.pi3g.com/2014/04/make-raspbian-system-read-only
    (источник)

    How to make RaspberryPi truly read-only, reliable and trouble-free
    k3a.me/how-to-make-raspberrypi-truly-read-only-reliable-and-trouble-free
    (без графики)

    Protect your Raspberry PI SD card, use Read-Only filesystem
    hallard.me/raspberry-pi-read-only
    (прислал sisaenkov, улучшенная версия, но тоже без графики)

    Stopping SD Card Corruption on Raspberry Pi’s Raspbian
    ideaheap.com/2013/07/stopping-sd-card-corruption-on-a-raspberry-pi
    (без графики)

    Raspberry Pi как информационное табло — с помощью VNC на localhost
    habrahabr.ru/post/212661

    Подключение RTC (часы реального времени) к Raspberry Pi
    raspberrypi.ru/blog/598.html
    (использует I2C-совместимые часы DS3231)

    How to boot from a USB Mass Storage Device on a Raspberry Pi 3
    www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md

    Network booting
    www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/net.md

    ECIO(TM), a powerful USB programmable single chip computer based on PICmicro microcontroller technology
    www.matrixtsl.com/product.php?Prod=ECIO28P

    Easy Raspberry Pi Based Screensaver/Slideshow for Exhibitions/Store Front
    www.instructables.com/id/Easy-Raspberry-Pi-Based-ScreensaverSlideshow-for-E
    (у меня вызвал искреннее недоумение шаг 6)

    Flash memory card design (2013)
    wiki.linaro.org/WorkingGroups/KernelArchived/Projects/FlashCardSurvey
    (почему флэшка накрывается гораздо раньше, чем мы ожидаем? польза и вред от оптимизации внутренней логики под FAT; классификация контрафактных продуктов; каталог флэшек 2013г)

    Optimizing Linux with cheap flash drives, Arnd Bergmann, 2011
    lwn.net/Articles/428584
    (иллюстрированная статья)

    Optimizations for Cheap Flash Media, Arnd Bergmann, 2011
    free-electrons.com/blog/elce-2011-videos
    (видео выступления на английском, запись любительская, но интересная)

    SD Association, Simplified Specifications, Part 1 Simplified: Physical Layer Simplified Specification
    www.sdcard.org/downloads/pls/index.html

    Block layer statistics in /sys/block/<dev>/stat
    www.kernel.org/doc/Documentation/block/stat.txt
    (как оценить износ SD-карточки с момента запуска системы: запустите cat /sys/block/mmcblk0/stat и потом сразу uptime)

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Сколько примерно прожила загрузочная microSD в Вашей Raspberry Pi при регулярном использовании?
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 190
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        всего два месяца?? я даже не подозревал, что всё настолько фигово, добавлю-ка пункт в голосовалку
        • 0

          Эх малинку не имею и никогда не трогал, но кажется теперь я понял почему у меня в телефоне карта стала readonly после того как создал на ней раздел ext и смонтировал для установки программ. Продержалась кстати тоже около 2-3 месяцев. Как раз думал на тему износа по циклам записи, но гугл при поиске убедил меня, что износ — прерогатива usb flash, а на microsd еще никто не сталкивался. Рад что мое предположение оказалось верным. Теперь интересно стало сколько же андроид дергает фс в течении месяца/года и на сколько же хватит встроенной памяти в телефоне.

        • 0
          У меня жили по 2-3 месяца, даже без граф.обоочек.
          С readonly-root живут на улице уже более года, некоторые станции слеланы на «малине» — http://meteo38.ru/
          • +1
            Вот оно что, а я думал что это упавшее питание убивает карточки, и волосы на голове рвал с чего бы это.
            Т.е. работает оно пару месяцев, все ок, может какие-то проблемы пошли, но ОС загружена, а после выключения уже не поднимается. И естественно думал что раз выключение питания убивает карту, то никакое readonly не поможет. Никогда не знаешь каким боком баг вылезет.
            • 0
              Я так представляю процесс: размер записываемого блока 512 байт кратно меньше страницы NAND-памяти, которую микроконтроллер флэшки вынужден сперва «взять» целиком, заменить в ней эти 512 байт, после чего «пристроить» на новое место (всё происходит внутри флэшки, драйвер файловой системы ничего этого не видит). Причём сперва это новое место нужно ещё найти и очистить током (flash erase).

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

              Поэтому с точки зрения сбоя питания регулярная запись на флэшку резко увеличивает вероятность непокрываемой журналом файловой системы потери данных, однако не делает эту вероятность 100%. Но даже если карточка по-честному произведена, например, SanDisk, и имеет идеальные мозги, остаётся неконтролируемый электрический износ, который пока можно отслеживать только вручную (я поместил пару простых команд Linux в публикацию). Ждём новые отраслевые стандарты и аналоги HDD SMART для Интернета Вещей.

              Переход на read-only должен решать обе проблемы: при отсутствии записи не должно быть ни электрического износа NAND-памяти, ни «битых» транзакций. И даже на контрафактных носителях система будет себя вести гораздо стабильнее, но всё равно недолго:)
              • +1
                Это называется write amplification (коэффициент усиления записи).
          • +3
            Не знаю как для Raspberry Pi, а для микроконтроллеров проблема закрытия транзакции записи в flash-память решается например так: Детектор питания настраивается на такой порог, ниже которого в норме напряжение не должно опускаться, но при котором МК и флешка ещё должны нормально работать. Перед началом транзакции записи проверяется, не вышло ли питание за этот порог, и если вышло — начало записи откладывается до нормализации питания. При этом до завершение транзакции записи питание обеспечивается конденсаторами на плате. Если встроенного детектора нет (а в STM32 он есть) — используется внешняя микросхема монитора питания, обычно с жестко заданным порогом. Возможно в Raspberry Pi есть такой детектор? С SD-картами по-моему всё несколько сложнее чем с SPI-флешками — у них похоже есть внутренний кэш страницы с задержанной записью. Причём в тех открытых версиях стандарта, что мне попадались, команда принудительной выгрузки кэша не описаны, но она должна существовать, и её нужно выдавать при просадке питания.
            • +1
              благодарю, неплохо описано; я так понимаю, на рынке МК описанные внутренности просто must have, чтобы этот рынок не прое#@ть :)

              пока же у меня создалось ощущение, что на рынке любительских платформ для Вещей дела обстоят по-детски наивно; а что там с питанием SD-ридера в МалинПроге, я даже боюсь подумать
              • 0
                Так это относится к питанию изделия в целом. В той же Pi в цепи питания наверняка есть конденсаторы, а если нет — их можно добавить.

                В худшем случае, если нет возможности измерить напряжение на входе, можно поставить там компаратор с выходом на одну из ног GPIO: как только напряжение упадёт, ОС получит сигнал, на который отреагирует командой sync && mount / -o remount,ro.
                • +1
                  Жирный понадобится конденсатор, возможно даже Li-Ion, с учетом медлительности RP и потребления почти 5Вт.
                  • +1
                    нагруженная по ЦП и увешанная периферией USB модель 3 может и 10Вт потреблять: стандартная рекомендация — блок питания 5В 2.5А

                    конечно, всё это в железе должно быть, но есть или нет — я пока не знаю, в руки взял RPi меньше месяца назад, чисто попробовать; вот и напробовал на статью
                    • 0
                      Да, с таким потреблением ионистор на 1,5Ф даст примерно 0,75с, в течение которых напряжение питания упадёт до 4В. Обработка bash-команды может затупить, но если сэмулировать Alt+SysRq+U, ядро должно успеть.
            • +2
              Лет 8 назад развлекался с read-only centos для небольших телефонных станций на asterisk. Помню, что монтировалось в read-only и так же в памяти всякая временная хрень. Работали по года 2 без проблем. Использовался переходник с IDE на SD. Графики конечно не было никакой.
              Но потанцевать с бубном много пришлось. Практически академию бубна закончил.
              • 0

                да, тогда UnionFS весьма сырой был

                • +1
                  Да, эксперименты с астериском на малине быстро вернули меня в опенврт и роутерное железо, где ридонли фс — норма жизни. Теперь до этого додумались на малине…
                • 0
                  Наздоровье. Рад что пригодилось.
                • 0
                  Кстати, нашел тут кое-что по поводу RAM disk-а для Pi: https://www.domoticz.com/wiki/Setting_up_a_RAM_drive_on_Raspberry_Pi

                  Люди запускают не инфотабло/слайдшоу а domoticz (решение для «умного дома»), но проблему решают ту же — смерть SD при продолжительном использовании. Правда не так радикально — в RAM диске всего одна папка.

                  Возможно есть вариант расширить это на home папку пользователя (а также и на swap и что там еще), и при старте заполнять ее заранее заготовленной копией с SD карты.
                  • 0
                    + тема на форуме Распбери: https://www.raspberrypi.org/forums/viewtopic.php?f=37&t=63996
                    + вариант переноса большей части FS на USB носитель (SD карта все равно требуется, т.к. Распбери загружается ислючительно с SD, но писать на SD он уже не будет, насколько я понял): http://www.instructables.com/id/Boot-the-Raspberry-Pi-from-USB/
                    • 0

                      про swap шутка, видимо;)

                      • 0
                        Я на ночь глядя уже не соображу — вроде ж есть swap файл у raspbian: http://raspberrypi.stackexchange.com/questions/70/how-to-set-up-swap-space

                        P.S. Пишут что есть, включен по умолчанию
                        http://raspberrypimaker.com/adding-swap-to-the-raspberrypi/
                        Raspian uses a script dphys-swapfile to manage swap. The standard image includes this turned on by default. The configuration files is located at /etc/dphys-swapfile. Theonly parameter in the file is CONF_SWAPSIZE=100 which creates a 100MB swapfile in /var/swap.
                        • 0

                          да, но не в RAM же его

                          • 0
                            Хм, вроде как да — куда в RAM когда swap нужен когда RAM-а не хватает. Но и на SD ж не надо писать. Chicken and egg?

                            Но если еще подумать — допустим половину RAM-а мы отрезаем под RAM disk. Когда вторая половина (та, которая так сказать «RAM RAM») переолняется — пусть свопит в первую (ту, которая «RAM disk»), чего уж там. Так что таки swap в RAM, и «это норма» :D

                            Иначе прийдется совсем отключить swap. Вероятно наиболее логичный вариант, но надо нагуглить как.
                            • +1
                              P.S. Прочел что вообще по-хорошему для таких дел используется zRam.
                              • 0
                                отключить swap очень просто: в /boot/cmdline.txt добавить noswap и снести dphys-swapfile
                                • +1
                                  Ещё вариант для безумцев — zRam (Тотже рамдиск, куда можно всунуть Swap, но при этом с сжатием-на-лету).
                                  • +1
                                    Хороший вариант, на старом телефоне с Android 4.0.3 и 512 МБ памяти только им и спасался.
                                    • 0
                                      да, компрессия — это единственная причина делать swap в ОЗУ; медленно и энергоёмко, но хоть как-то
                                      • –1
                                        Ни чё се медленно. Очень даже быстро, компрессия к слову используется в графических платах для увеличения пропускной способности. А там гигабиты в секунду, пуская и энтропия чрезвычайно невелика. У самого archlinux и 8 гигов RAM, так половину в zram отправил, компрессия хрома достигает 10%, что практически снимает вопрос о его прожорливости.
                                        • 0
                                          Deerenaros, если верить примитивным тестам на Doom и Quake 2 и сопоставлять их с официальным источником, то производительность загруженного по всем ядрам ARM Cortex A53 получится в 2-3 раза меньше, чем у старого десктопного Core i3 3220 (выпуска 2012 года). А если работает одно ядро, то Model 3 примерно в десять раз медленнее 4-летнего десктопа нижнего ценового ряда.

                                          Когда я запустил слайд-шоу feh на фотках с паузой 7 секунд, сперва не мог понять, почему слайды меняются непредсказуемо каждые 10-12 секунд. Пока не глягул на загрузку ЦП: подгонка каждого фото профессиональной зеркалки под Full HD у BCM2837 как раз и занимает эти несколько секунд. Одно ядро пашет, три других курят, но это feh.

                                          Вы тут упоминаете 8 гигов RAM, но у десктопа только на один ЦП подводится 50..100Вт мощности, а на видео может подводиться вообще сколько угодно. Компрессия в графических ускорителях? Видимо, даже 16-рядный PCI Express является бутылочным горлышком, в которое дешевле закачивать поток под давлением, ибо электрическая мощность в избытке. Про энтропию не буду комментировать.

                                          У нас на весь одноплатный компьютер где-то 12Вт. Поэтому да, это будет медленнее, чем на десктопе, и когда у нас только 1Гб ОЗУ без возможности расширения, надо хорошо подумать, сколько на что отводить.

                                          Но за 10-кратное сжатие расхода Chrome спасибо, кому-то пригодится.
                                          • +1
                                            Про энтропию я имею в виду, что сжимать текстуры проще, тем более с потерями, чем любую информацию. И нет, не 16-разрядный PCI Express является горлышком. А высокая стоимость hispeed памяти неоправданно дорогой. Топовые карточки и без сжатия хорошо играются, а вот middle сегмент очень ограничен в пропускных возможностях.

                                            У малинки есть классный видеоускоритель, который можно использовать для быстрой работы с изображениями. Ясное дело, feh такого не умеет.

                                            Тут надо уточнить, что свапуется всё подряд, и отправить конкретно хром в свап не так то просто. Но в целом, хотя бы 40%-60% сжатие стабильно присутствует, что по сути как минимум удваивает количество RAM. А в случае интенсивного использования хрома, zram вероятнее утраивает, а порой даже удесятеряет. Меня порой удивляет, почему сами разработчики chromium не могут сами сжимать память различными методами, более эффективными.
                                  • 0
                                    Кстати, у малинки swapiness пи умолчанию стоит 60, т.e когда занято 40% RAM малинка начинает подумывать о сбросе данных в свап. Если поставить swapiness в 0, то он будет использоватся только когда по-другому никак.
                                    ( https://help.ubuntu.com/community/SwapFaq/#What_is_swappiness_and_how_do_I_change_it.3F )
                                    • 0
                                      спасибо за комментарий, но лично я считаю, что без SLC-памяти swap лучше отключить совсем, прописав noswap в /boot/cmdline.txt

                                      т.е. если без swap никак, надо сразу покупать HPE Flash Media Kit или аналог, в противном случае система может и полгода не протянуть
                                      • +1
                                        эта комманда по идее вляет только на автоматическое использование swap раздела из fstab — смотри код init.d/checkroot.sh
                                        А в малинке используется swap в файл /var/swap ( пакет dphys-swapfile ).
                                        • +1
                                          ага, именно dphys-swapfile и рекомендуют сносить авторы статей по ссылкам, которые я использовал:) но всё равно спасибо, для расширения кругозора полезно
                                          • 0
                                            sudo dphys-swapfile uninstall
                                            Ещё можно.
                            • 0
                              Sauron, благодарю за Domoticz, посмотрите вот это: Setting up overlayFS on Raspberry Pi
                              • 0

                                Использую Domoticz, и несчастная SD-карта от SanDisk рушилась чуть ли ни каждую неделю.
                                Купил Transcend, перевел ее в read-only по этой статье и всё стало отлично.
                                Единственное, надо для некоторых служб создавать логи на ram-диске до их загрузки.

                                • 0
                                  да, спасибо, но это чуть улучшенная версия варианта «без графики» в моих ссылках; тем не менее, я добавил Вашу ссылку, она полезна

                                  напомню, у меня-то идея как раз с графикой заставить работать

                                  по поводу же Domoticz — а не пробовали с OverlayFS? я ссылку на их wiki чуть выше уже дал
                                  • 0

                                    Пока не дошел до OverlayFS. Статью в вики видел еще когда только перешел на Domoticz.
                                    Исхожу из принципа: работает — не трогай. Тем более, что Domoticz живет на USB-флешке, на которую и производится вся запись. SD-карта целиком read-only.

                                  • 0
                                    Похожая картина с OpenHAB.

                                    Использование под, собственно, OpenHAB плюс самописный скрипт для записи с двух видеокамер. Jpeg-и с камер писались в память (tmpfs), склеивались аппаратным кодеком и кидались на внешний HDD. Для системных логов был сделан самописный скрипт по типу ramLog, только под systemd.

                                    Через примерно 5 месяцев начались глюки. Думал, умирает внешний SSD (из древних, что-то типа kingston/x25 40Gb). Оказалось, openHAB так «гадит» в свои логи, что всему raspbian-у и не снилось. Итог — «пафосный» sandisk на 32Гб от Юлмарта запилен до read-only

                                    Сейчас: загрузка с sd, запуск ramLog-а, перемонтирование /var/{cache,lib/mosquitto} и бо́льшей части openHAB-а на внешний HDD и запуск xeoma с него же. Соответственно, /tmp, /run, /var/log — в tmpfs. Месяц отработало. За 20 дней 10Мб прочитано, 3.8Мб записано, если верить iostat
                                • +4
                                  С августа 5 малин показывают браузер круглосуточно. Пока все живы. Из настроек только отключение в конфиге journald записи логов на диск и запуск браузера surf без кеширования. Когда одна из малин помрет, буду делать как у вас, unionfs. Спасибо за статью

                                  У себя обошелся без дисплейного менеджера. Добавил файл /etc/systemd/system/getty@tty1.service.d/override.conf с таким содержанием:
                                  [Service]
                                  ExecStart=
                                  ExecStart=-/usr/bin/agetty --autologin user --noclear %I $TERM


                                  Ну и мышь оставил, т.к. иногда нужно поуправлять работающей малиной напрямую. Программа unclutter скрывает указатель если его пару секунд не теребить

                                  Все изменения в управляющих скриптах подготавливаю в виде deb-пакета на большой машине, затем массово заливаю и инсталирую по ssh. ssh-agent рулит
                                  • 0
                                    спасибо, уважаемый читатель! а всё-таки чем собственно X-сервер запускается?
                                  • +1
                                    У меня RPi уже больше двух лет живет под Raspbian; сначала управлял роботом (пока не надоело), потом просто прозябает в виде веб-камеры через M-JPEG streamer (впрочем, еще использовал как сервер недолго, для эксперимента). Периодически апдейчу и апгрейжу (раз в квартал); все работает, как часы. Да, все с дешевой 4GB карточки (даже не помню, что туда засунул). Ничего в конфигах не отключал; X-ами не пользуюсь, все через ssh.

                                    Что я делаю не так, зачем мне read-only file system, и когда оно таки «сдохнет»? ;)
                                    • 0

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

                                      • 0
                                        Посмотрел специально: SONY, 16GB, 10 класса. Помню, были проблемы с более большей и скоростной карточкой (из-за какого-то бага в RPi или софте).

                                        Да, весьма возможно, что при моем сценарии swap сильно не используется, потому и живет долго.
                                        • 0
                                          sens_boston, если Вас не затруднит, что скажут эти две команды (без root)?
                                          uptime -p
                                          cat /sys/block/mmcblk0/stat | awk '{printf "Uptime read: %.3fMiB written: %.3f MiB\n", $3*512/1048576, $7*512/1048576}'
                                          • 0
                                            pi@raspberrypi ~ $ uptime -p
                                            uptime: invalid option -- 'p'
                                            
                                            Usage:
                                             uptime [options]
                                            
                                            Options:
                                             -h, --help     display this help and exit
                                             -V, --version  output version information and exit
                                            
                                            For more details see uptime(1).
                                            pi@raspberrypi ~ $ cat /sys/block/mmcblk0/stat | awk '{printf "Uptime read: %.3fMiB written: %.3f MiB\n", $3*512/1048576, $7*512/1048576}'
                                            Uptime read: 40.826MiB written: 0.484 MiB
                                            pi@raspberrypi ~ $
                                            
                                            
                                    • +1
                                      Вместо UnionFS можно использовать OverlayFS, он новее. Можно монтировать корень read-only, а поверх него монтировать OverlayFS в tmpfs, чтобы не приходилось монтировать отдельные директории.

                                      И вообще, в Debian уже есть пакет для этого — live-boot и live-boot-initramfs-tools
                                      • 0
                                        А вот это интересно, спасибо.
                                        • +2
                                          Респект, ValdikSS! OverlayFS вошёл в ядро Linux уже после того «погибшего» немецкого поста про UnionFS, что не отменяет ценности OverlayFS сегодня. Но меня удивляет (и немного раздражает) молчание официальной команды Raspberry Pi по теме read-only root. К сожалению, комментарии читателей (не все!) и статистика опроса по среднему времени жизни Малиновых Прогов пока подтверждает мои опасения. Либо мы дружно смотрим не туда:)

                                          Кстати, поисковики на запрос raspberry overlayfs выдают гораздо больше полезного, чем на raspberry read only root, в этом тоже есть профит от OverlayFS:)

                                          Из того, что можно считать «пошаговой инструкцией», я нашёл только проект Domoticz и вот эту форумную ветку. Есть ещё что-то, достойное внимания?

                                          Благодарю за ценный комментарий!
                                          • 0
                                            Я кстати тоже на OverlayFS построил свой read-only.
                                            Опирался в настройке на Domoticz, но немного иначе построил древо папок, запихав их все в /overlays, а не в корень как у автора. Ну ипо скриптам там есть изъяны.
                                            • +1
                                              OverlayFS используется повсеместно во всяких OpenWRT и их клонах.
                                          • +2
                                            Полезно, надо бы и мне такое написать, а то уже забываю что да как у себя делал. И начал делать именно по этому же, что умирают microSD карточки.
                                            У меня пирожки используются в качестве «мозгов» для информационных табло на базе HDMI мониторов/телевизоров. По сути там тольок Chrome выводящий страничку, которая по средствам JS обновляет внутри себя данные. Так вот эта, казалось бы тривиальная, задача убивает QUMO карточки на 8Gb (меньше в продаже у нас уже и не найти, да и эти стоили 400р.) в среднем за 2-3 месяца. Установка SNMP монитора (внешний сервер сбора статитика «Кактус») сразу открыла глаза на ситуацию. Raspberrian убивает карточку постоянной записью журнала и прочей ерунды типа логов и много чего ещё. При этом отключение журналирования не помогает, об этом есть целая ветка на linux.org.ru
                                            С переходом на RO файловую систему всё стало шикарным! Не нарадуюсь. rsync'ом синхрю «изменения» которые делаю в конфигах, кэши броузера и темпы в память, логи на внешний сервер с небольшим буфером в память. Работает уже 6 мес, тфу тфу тфу со 100% аптаймом.

                                            От текущеко решения отличатся разве, что тем, что я отказался от LightDM и поставил noDM, легче, проще, интуитивнее.
                                            • +1
                                              отлично, и благодарю за noDM!
                                            • 0
                                              6 лет назад то же самое делал на aufs2.
                                              • 0
                                                Я потому банану пи взял. У нее есть сата разьем. Я подключил жесткий диск и вот уже пол года все работает. До этого была расберри и проработала год без проблем. Я даже логгирование не отключал.
                                                • +1

                                                  Read only системный диск — это же liveCD в чистом виде! Быть может, самым простым решением окажется просто эмуляция LiveCD с соответствующими дебиановскими либами?

                                                  • +1
                                                    спасибо за комментарий, тогда уже SquashFS, с соотв. последствиями, я ответил в публикации, см. UPD: SquashFS
                                                    • +1
                                                      Спасибо (в частности, за то, что напомнили про Squash — мне он тоже пригодится).

                                                      Хабр Гиктаймс — торт!
                                                      • 0
                                                        ну что Вы, это ребятам спасибо за SquashFS :)
                                                  • 0

                                                    Посмотрите как делает OpenWRT: системный образ в squashfs, настройки поверх через overlayfs.
                                                    Его можно собрать для малины, хотя я не пробовал. Не уверен, что squash нужен на SD, места то полно, но будет точно RO.

                                                    • 0
                                                      благодарю, ответил Вам и другим читателям в тексте публикации, см. UPD: SquashFS
                                                    • +1
                                                      Раз уж подвернулась такая подходящая статья — расскажу свой «анекдот»
                                                      Была у меня малинка с установленной на ней RaspbianLite (без графики), и на ней маленькая программа, написанная на ноде, которая парсила некоторые сайты и отправляла результаты по сети в БД на удаленном сервере. Программа эта запускалась по крону каждый час.
                                                      Стояла себе моя малинка и работала себе, с почти полутора-годовым аптаймом.
                                                      В итоге в один прекрасный день я решил зайти на нее по ssh и проверить как у нее дела. Пробую зайти — нифига.
                                                      В итоге выяснилось что карта памяти полетела больше года назад (после e2fsck починилась), да еще и из разъема вылезла немного (он разболтан слегка был)
                                                      При этом служила мне верой и правдой все это время — просыпалась по крону, ходила в сеть и т.д.
                                                      В линуксе/юниксе я довольно-таки нуб, поэтому описать в техническом плане что именно там происходило не могу.

                                                      Но зато какой надежный девайс получился :)
                                                      • 0
                                                        У меня похожая ситуация с FreeNAS послужила поводом к написанию статьи на хабре, система тоже жила себе на «сдохшей» флэшке около недели. Я прекрасно отдавал себе отчёт, что это до первой перезагрузки, и в случае с файл-сервером вмешался почти сразу, как только узнал, от греха подальше.

                                                        Однако обе мини-флэшки я не выбросил, а просто записал по-новой. Одна до сих пор в автомагнитоле прекрасно служит MP3-архивом, воспроизводя мне эфиры давно закрытых, но до боли любимых радиостанций. Вторая трудится (ха-ха) загрузчиком тестового FreeNAS, на котором я отрабатываю проброс аппаратных USB-ключей жёлтой программы через jail и virtualbox прямо в установленный тут же Windows. И хорошо работает, но я так скажу: слава богу, что это хобби:)
                                                      • 0
                                                        Наверное, еще можно адаптироватъ старый способ создания Live CD: http://www.linuxfromscratch.org/hints/downloads/files/OLD/bootcd-2.6-udev-nptl.txt
                                                        • +2
                                                          Использую Flash Media Kits от HPE для загрузки ESXi и OpenIndiana.
                                                          Эти SD и microSD рассчитаны на большее количество циклов перезаписи (до 100 000) чем обычные консьюмерские флешки.
                                                          Стоимость — в несколько раз дороже, но для долгосрочного (обычно — 2-4 года) использования в продакшене оправдана.
                                                          • 0
                                                            вот, в том числе ради таких комментариев я и пишу свои публикации:)
                                                            теперь я знаю, под каким брэндом можно найти промышленную SLC-память в формате microSD, огромное спасибо!
                                                            • +1
                                                              зашел по Вашей ссылке ниже: разница в цене — 10+ раз для варианта 32 ГБ.
                                                              Если железка не будет расположена в каком-то труднообслуживаемом месте,
                                                              то имхо дешевле по регламенту менять дешевые карты чаще, чем надеяться на обещанную надежность такого дорогого варианта.
                                                              Причем память б0льшего размера позволит размазывать износ дольше и дальше — еще и поэтому меньший размер менее выгоден, а не только сами по себе мелкие карточки выходят дороже в пересчете на единицу памяти.
                                                          • +1
                                                            износ флэша даже в режиме ридонли — это потемки, например http://habrahabr.ru/post/214803/
                                                            Также интересуюсь командой TRIM для не-SSD.
                                                            У некоторых eMMC уже стал появляться SMART http://4pda.ru/forum/index.php?showtopic=170318&view=findpost&p=42683000
                                                            Заранее благодарю за любую информацию по этим темам.
                                                            • 0
                                                              Здравствуйте, дорогой читатель! Я очень хорошо знаю автора той статьи на хабре (это я и есть:)
                                                              На наше с Вами счастье буквально за минуту до Вашего комментария сюда зашёл пользователь gattopazzo83 и рассказал про SLC-память в формате microSD, которая является промышленной по своему назначению. А это означает, что подобных эффектов износа через read-only там быть не должно просто по определению. Конечно, космический корабль на этом не запустишь (радиация, вибрация, и всё такое), но для гражданских проектов вполне.
                                                              • 0
                                                                спасибо за пропуск АКА модерацию.

                                                                Если обе статьи за Вашим авторством, то странно, что никто больше не заметил странностей с таким режимом ридонли, который все равно приводит именно к быстрому износу флэша.

                                                                имхо SLC-память в формате microSD — не панацея до тех пор, пока не будет неких дополнительных гарантий в ее надежности, кроме ломовой цены и пафосного ценника.

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

                                                                И повторюсь насчет TRIM:
                                                                не попалось мне никаких намеков на то, что не любой контроллер не у всякой флеш поддерживает команду fstrim, которая появилась у Андроида 4.3
                                                                хотя про «взрослые» SSD море инфы о том, что многие ранние SSD не поддерживали эту фичу и требовали полного стирания для восстановления былых скоростей.

                                                                Буду благодарен за любые ссылки для чтения по всем этим смежным темам.
                                                                • 0
                                                                  * пафосного лебла
                                                                  • 0
                                                                    к Вашему комментарию выше про x10+ ценник да, всё в конечном итоге определяет экономика процесса обслуживания, дома дешевле перезалить систему, в бизнесе дешевле купить SLC-память

                                                                    странно, что никто больше не заметил странностей с таким режимом ридонли, который все равно приводит именно к быстрому износу флэша

                                                                    По моей теории, порча данных при чтении в результате read disturb возможна в результате слабого алгоритма расчёта контрольных сумм или багов в микроконтроллере, при этом флэшка остаётся работоспособной, т.е. перезапись восстанавливает «повреждённый» участок. Это вроде бы не противоречит тезисам доклада Jim Cooke в 2007г, но у меня нет ни оборудования, ни времени, ни навыков, чтобы доказать это на практическом примере.

                                                                    Когда я смотрю на характеристики памяти и вижу 100,000 циклов записи, второе место, куда я смотрю — это информация о длине контрольной суммы. И если она декларируется, это о многом говорит. А принятие решения о правдивости всей этой информации проще при наличии брэнда, которому репутационные издержки утопят выгоду от вранья. Поэтому если новый HP начал продавать такие флэшки, то я охрененно рад, если честно:) И да, износ 32Гб при прочих равных должен идти в четыре раза медленнее, чем 8Гб.

                                                                    Вижу, Вам TRIM на SD просто не даёт покоя:) Даже если команды Линукса что-то там отрабатывают и показывают на SD-карточке, это не SSD, тут наличие реального физического процесса вызывает гораздо больше сомнений, чем обещанная надёжность изделий от HPE. Искали, кстати, «fstrim sd card»? Вот, например: https://www.raspberrypi.org/forums/viewtopic.php?t=19554. Народ сходится на том, что отправка на запись полного нулей блока должна иметь только эффект ERASE, т.е. без записи самих нулей. Микроконтроллер понимает, что это затёртый блок, и в следующий раз при чтении быстро «напечатает» порцию нулей и выдаст хосту. Я в это готов поверить, тем более, что логика гипервизоров аналогична. Например, VMware с thin-provisioned дисками работает именно так. Но, поскольку это прошивка микроконтроллера, что происходит на самом деле, зависит от честности вендора, т.е. приходим к тому же выводу, что и в моей публикации 2014г.

                                                                    So even if the SDHC cards don't support the trim command the erase block command of the SDHC card might actually do quite the same, since it's too fast for a real physical erase procedure but it still results in a block being reread as zero.
                                                                    Note that this might well be device and or vendor specific behaviour, its what i saw while working with sandisc SDHC cards on a dataloggger project with a microcontroller using SPI protocoll for communication.
                                                                    • 0
                                                                      > порча данных при чтении в результате read disturb возможна в результате…

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

                                                                      TRIM на SD не даёт мне покоя по простой причине: это предельно наглядный метод проверки продвинутости или даже вообще наличия мозгов у контроллера.
                                                                      Все же, для дешевых и левых флешей я бы предположил просто полное отсутствие алгоритмов размазывания износа: такой вариант легко объяснил бы обсуждаемый 2-месячный износ без привлечения излишних сущностей вроде SLC/MLC/TLC.

                                                                      имхо ламера: логику гипервизоров неверно сравнивать с производством предельно дешевых флэш карт\свистков.

                                                                      а «честность вендоров» давно подмочена подменой «1024 мегабайт» на «1000 мегабайт». Я тут выше уже приводил ссылку, что у некоторых еММС появился SMART — вот только в это можно будет как-то поверить…
                                                                      • 0
                                                                        * имхо ламера: логику гипервизоров неверно сравнивать с производством предельно дешевых флэш карт\свистков. Т.е., очевидно, что контроллер без размазывания износа выйдет драматически дешевле и проще, чем интеллектуальный. А ведь на таких масштабах производства и при таких ценах экономия даже долей цента оборачивается большими суммами.
                                                                        • 0
                                                                          либо в режиме ридонли все равно что-то пишется — и это Ваша же гипотеза про ехт4,
                                                                          либо описание «механизма износа» флэша в паблике не раскрывает всех тонкостей этого самого износа
                                                                          NAND read disturb «на пальцах» — это постепенная порча данных в каком-то месте, вызванное чтением из «соседнего» участка, исправляется перезаписью, и следить за этим достаточно просто, чтобы обычный микроконтроллер справился (только прошивка нужна без багов, а это и есть интеллектуальная собственность корпораций). Для меня сочетание SLC, длинной контрольной суммы и хорошего брэнда как раз означает, что в прошивку залит достаточно продвинутый софт, чтобы флэшка даже с записью жила долго, а в режиме read-only — очень долго, без всяких намёков на read disturb…

                                                                          Мы же с Вами ищем одно и то же, верно? Вы также пытаетесь оценивать «продвинутость» софта микроконтроллера, но только по критерию наличия TRIM, я правильно понял? В примитивном (относительно SSD) интерфейсе SD-карточек нет такой функции, так википедия утверждает:
                                                                          The MultiMediaCard and SD ERASE (CMD38) command provides similar functionality to the ATA TRIM command, although it requires that erased blocks be overwritten with either zeroes or ones. eMMC 4.5 further defines a «discard» sub-operation that more closely matches ATA TRIM in that the contents of discarded blocks can be considered indeterminate (i.e., «don't care»).

                                                                          Так что тут вопрос и к драйверам (ядру) Linux, и к железу, и к userland командам…

                                                                          Как бы там ни было, причина, побудившая меня написать эту статью — наплевательское отношение к культуре использования ограниченного ресурса SD-карточек со стороны «готовых» образов систем для RPi. Проблему явно надо с двух концов решать.

                                                                          У Вас есть МалинПрог под рукой? Можете поставить hdparm и запустить одну команду?
                                                                          hdparm -I /dev/mmcblk0

                                                                          Я просто не хочу до нового года вообще трогать торговое оборудование…

                                                                          Про гипервизоры: я имел в виду, что «раздутый» шлаком (стёртыми файлами) Thin Provisioned Disk VMware «сдувается» обратно при помощи записанных поверх стёртых файлов «нулей», блоки которых гипервизор считает пустыми. См. ссылку про vmkfstools --punchzero. У некоторых SD-карточек «нулевые» блоки означают для микроконтроллера то же самое, что «нулевые» блоки для команды vmkfstools. Просто неслучайная аналогия, для Thin Provisioned Disk команда TRIM была бы тоже полезна.
                                                                          • +1
                                                                            википедии нельзя верить в областях, где прогресс быстр, а инфа все еще не устоялась: даже про HDD с их черепичной записью и гелием нельзя верить вики, потому что такой опыт еще не наработан, а грабли не хожены.
                                                                            Т.е., признание отсутствия TRIM лишь еще сильнее намекает и на полное отсутствие алгоритма размазывания износа, хотя для SD про последнее никто не пишет прямо ни «за», ни «против».

                                                                            наплевательское отношение к культуре использования ограниченного ресурса SD-карточек со стороны «готовых» образов систем для RPi — имхо явное следствие дешевизны карт памяти и тупости основного контингента, которые приучены к этому фреймворками и прочими улучшателями и упрощателями.

                                                                            вопросы и к драйверам (ядру) Linux, и к железу, и к userland командам хотя бы имеют ответы, а вот про кишки карт памяти неизвестно ничего, например
                                                                            https://habrahabr.ru/post/273425/
                                                                            > во встроенном в eMMC уровне FTL тоже реализованы алгоритмы выравнивания износа, но это «черный ящик».

                                                                            > у некоторых SD-карточек «нулевые» блоки означают для микроконтроллера

                                                                            да, кроме неафишируемого использования SLC, также возможно, что некоторые карты не рекламируют но имеют и продвинутые контроллеры

                                                                            у меня нет МалинПрог под рукой — я ламер и просто собираю инфу по некоторым волнующим меня темам.
                                                                            • 0
                                                                              RPi B+, Raspbian jessie: hdparm не хочет показывать информацию об SD-карте:
                                                                              # hdparm -I /dev/mmcblk0
                                                                              /dev/mmcblk0:
                                                                               HDIO_DRIVE_CMD(identify) failed: Invalid argument
                                                                              
                                                                              • 0
                                                                                всё верно, SD-карточка не диск, я был неправ, вот команда:
                                                                                udevadm info -a -n /dev/mmcblk0

                                                                                см. также спойлер в публикации
                                                                                • 0
                                                                                  Raspi B+, Transcend 8GB class 10
                                                                                  # udevadm info -a -n /dev/mmcblk0
                                                                                  
                                                                                  Udevadm info starts with the device specified by the devpath and then
                                                                                  walks up the chain of parent devices. It prints for every device
                                                                                  found, all possible attributes in the udev rules key format.
                                                                                  A rule to match, can be composed by the attributes of the device
                                                                                  and the attributes from one single parent device.
                                                                                  
                                                                                    looking at device '/devices/platform/soc/20202000.sdhost/mmc_host/mmc0/mmc0:aaaa/block/mmcblk0':
                                                                                      KERNEL=="mmcblk0"
                                                                                      SUBSYSTEM=="block"
                                                                                      DRIVER==""
                                                                                      ATTR{ro}=="0"
                                                                                      ATTR{size}=="15523840"
                                                                                      ATTR{stat}=="    4491     1914   202850    16300     1386     1625    24289    26390        0    13340    42620"
                                                                                      ATTR{range}=="32"
                                                                                      ATTR{discard_alignment}=="0"
                                                                                      ATTR{force_ro}=="0"
                                                                                      ATTR{ext_range}=="32"
                                                                                      ATTR{alignment_offset}=="0"
                                                                                      ATTR{inflight}=="       0        0"
                                                                                      ATTR{removable}=="0"
                                                                                      ATTR{capability}=="10"
                                                                                  
                                                                                    looking at parent device '/devices/platform/soc/20202000.sdhost/mmc_host/mmc0/mmc0:aaaa':
                                                                                      KERNELS=="mmc0:aaaa"
                                                                                      SUBSYSTEMS=="mmc"
                                                                                      DRIVERS=="mmcblk"
                                                                                      ATTRS{cid}=="035344534c303847803da92ee4010481"
                                                                                      ATTRS{csd}=="400e00325b5900003b377f800a4040af"
                                                                                      ATTRS{scr}=="0235800100000000"
                                                                                      ATTRS{date}=="04/2016"
                                                                                      ATTRS{name}=="SL08G"
                                                                                      ATTRS{type}=="SD"
                                                                                      ATTRS{preferred_erase_size}=="4194304"
                                                                                      ATTRS{fwrev}=="0x0"
                                                                                      ATTRS{hwrev}=="0x8"
                                                                                      ATTRS{oemid}=="0x5344"
                                                                                      ATTRS{manfid}=="0x000003"
                                                                                      ATTRS{serial}=="0x3da92ee4"
                                                                                      ATTRS{erase_size}=="512"
                                                                                  
                                                                                    looking at parent device '/devices/platform/soc/20202000.sdhost/mmc_host/mmc0':
                                                                                      KERNELS=="mmc0"
                                                                                      SUBSYSTEMS=="mmc_host"
                                                                                      DRIVERS==""
                                                                                  
                                                                                    looking at parent device '/devices/platform/soc/20202000.sdhost':
                                                                                      KERNELS=="20202000.sdhost"
                                                                                      SUBSYSTEMS=="platform"
                                                                                      DRIVERS=="sdhost-bcm2835"
                                                                                      ATTRS{driver_override}=="(null)"
                                                                                  
                                                                                    looking at parent device '/devices/platform/soc':
                                                                                      KERNELS=="soc"
                                                                                      SUBSYSTEMS=="platform"
                                                                                      DRIVERS==""
                                                                                      ATTRS{driver_override}=="(null)"
                                                                                  
                                                                                    looking at parent device '/devices/platform':
                                                                                      KERNELS=="platform"
                                                                                      SUBSYSTEMS==""
                                                                                      DRIVERS==""
                                                                                  
                                                                                  


                                                                                  Olimex A13, SanDisk Ultra 8GB class 10
                                                                                  # udevadm info -a -n /dev/mmcblk0
                                                                                  
                                                                                  Udevadm info starts with the device specified by the devpath and then
                                                                                  walks up the chain of parent devices. It prints for every device
                                                                                  found, all possible attributes in the udev rules key format.
                                                                                  A rule to match, can be composed by the attributes of the device
                                                                                  and the attributes from one single parent device.
                                                                                  
                                                                                    looking at device '/devices/platform/sunxi-mmc.0/mmc_host/mmc0/mmc0:aaaa/block/mmcblk0':
                                                                                      KERNEL=="mmcblk0"
                                                                                      SUBSYSTEM=="block"
                                                                                      DRIVER==""
                                                                                      ATTR{ro}=="0"
                                                                                      ATTR{size}=="15523840"
                                                                                      ATTR{stat}=="    5839     3033   327488    15840     1378      801    17850     7150        0    13780    22900"
                                                                                      ATTR{range}=="8"
                                                                                      ATTR{discard_alignment}=="0"
                                                                                      ATTR{force_ro}=="0"
                                                                                      ATTR{ext_range}=="256"
                                                                                      ATTR{alignment_offset}=="0"
                                                                                      ATTR{inflight}=="       0        0"
                                                                                      ATTR{removable}=="0"
                                                                                      ATTR{capability}=="50"
                                                                                  
                                                                                    looking at parent device '/devices/platform/sunxi-mmc.0/mmc_host/mmc0/mmc0:aaaa':
                                                                                      KERNELS=="mmc0:aaaa"
                                                                                      SUBSYSTEMS=="mmc"
                                                                                      DRIVERS=="mmcblk"
                                                                                      ATTRS{cid}=="035344534c30384780657324d401078b"
                                                                                      ATTRS{csd}=="400e00325b5900003b377f800a4040af"
                                                                                      ATTRS{scr}=="0235800100000000"
                                                                                      ATTRS{date}=="07/2016"
                                                                                      ATTRS{name}=="SL08G"
                                                                                      ATTRS{type}=="SD"
                                                                                      ATTRS{preferred_erase_size}=="4194304"
                                                                                      ATTRS{fwrev}=="0x0"
                                                                                      ATTRS{hwrev}=="0x8"
                                                                                      ATTRS{oemid}=="0x5344"
                                                                                      ATTRS{manfid}=="0x000003"
                                                                                      ATTRS{serial}=="0x657324d4"
                                                                                      ATTRS{erase_size}=="512"
                                                                                  
                                                                                    looking at parent device '/devices/platform/sunxi-mmc.0/mmc_host/mmc0':
                                                                                      KERNELS=="mmc0"
                                                                                      SUBSYSTEMS=="mmc_host"
                                                                                      DRIVERS==""
                                                                                  
                                                                                    looking at parent device '/devices/platform/sunxi-mmc.0':
                                                                                      KERNELS=="sunxi-mmc.0"
                                                                                      SUBSYSTEMS=="platform"
                                                                                      DRIVERS=="sunxi-mmc"
                                                                                  
                                                                                    looking at parent device '/devices/platform':
                                                                                      KERNELS=="platform"
                                                                                      SUBSYSTEMS==""
                                                                                      DRIVERS==""
                                                                                  
                                                                                  


                                                                                  • 0
                                                                                    Raspi B+, Transcend 8GB class 10
                                                                                    если верить CID, память производена SanDisk в апреле 2016
                                                                                    с момента запуска системы прочитано 202850 блоков, записано 24289 (соотношение 8:1)

                                                                                    Olimex A13, SanDisk Ultra 8GB class 10
                                                                                    если верить CID, память произведена SanDisk в июле 2016
                                                                                    с момента запуска системы прочитано 327488 блоков, записано 17850 (соотношение 18:1)

                                                                                    обе файловых системы явно работают в режиме read-write (у меня на «read-only» соотношение 3000:1)

                                                                                    Можно выполнить uptime -p и разделить записанные блоки на часы (точнее, сутки), получите средесуточный износ флэшки. Умножаете на количество дней работы устройства. Предел у MLC памяти 3000..5000 циклов записи, т.е. примерно после 32Тб записанных данных флэшка должна сдохнуть. Блок 512 байт, с момента запуска системы записали 11Мб на первую флэшку и 8Мб на вторую.

                                                                                    Вот если бы скомпилировать утилиты для IOCTL-вызовов, из SanDisk можно было бы вытащить аналог S.M.A.R.T., см. ссылку пользователя doga. Мой МалинПрог трудится в production, я второй пока не завёл:) Вы работаете с исходным кодом? Умеете пакеты под Debian собирать?
                                                                  • 0
                                                                    А почему не SquashFS?
                                                                    • 0
                                                                      благодарю за комментарий, ответил Вам и другим читателям в публикации, см. UPD: SquashFS
                                                                      • 0
                                                                        Благодарю за ответ. Согласен, невозможность изменить внутренности SquashFS может затруднить устранение ошибок на этапе эксплуатации.

                                                                        Но можно взглянуть на это и с другой стороны: неизменимость образа SquashFS может быть и достоинством — никакой вирус или троян не сможет закрепиться в системе, после перезагрузки система гарантированно вернётся в исходное состояние. Обновления же можно распространять в виде готового squashfs-образа. В тех же роутерах, например, новую прошивку тоже в виде целого образа распространяют. Не берусь утверждать, возможно ли подменить образ из загруженной с него системы, но полагаю, что даже если и нет, можно что-нибудь придумать.
                                                                        • 0
                                                                          полностью согласен, я это и имел в виду, когда писал публикацию:
                                                                          Обновления безопасности накатывать на такую систему довольно неудобно. Но, опять же, взломать такую Вещь несколько сложнее, чем эксплуатировать уязвимость Adobe Flash в браузере обычного десктопа.
                                                                    • +2
                                                                      Занимаемся счетчиками пассажиров на транспорте, используются как раз малинки (1,2.3). Есть с аптаймом по полгода, есть такие, которые перезагружаются каждые несколько минут (в таком режиме сдох роутер, малина с системой жива). Считают пассажиров, объявляют остановки, выполняют функции бортового компьютера. Вся ОС грузится в память, карточка не смонтирована совсем, потому что даже при монтировании в рид-онли система жила не больше месяца
                                                                      • 0
                                                                        Приветствую, очень приятно видеть здесь представителей отраслей! По поводу износа через чтение я как-то писал статью на хабре, смысл которой сводится к простой рекомендации: с учётом «физики» NAND-памяти не стоит использовать бытовые изделия для промышленных задач, потому что сэкономить можно и на софте для управляющего микроконтроллера флэшки. И mount read-only не означает, что драйвер файловой системы не попытается отметить дату и время последнего успешного монтажа. Отучить его от этой привычки можно, пожалуй, только аппаратным переключателем записи, но вот где на microSD он встречается?

                                                                        Тем не менее, благодаря пользователю gattopazzo83 я теперь знаю про флэшки Flash Media Kit пр-ва известной фирмы Харлампий-Панкрат (Эдуардович), и для Ваших задач определённо их рекомендую. Стоят дорого, но зато это SLC microSD.
                                                                        • 0
                                                                          «аппаратный переключатель записи» расположен в слоте, а на карте если и есть, то только механический движок, не связанный ни с чем более
                                                                          • 0
                                                                            К слову эти «бытовые изделия для промышленных задач» используются несколько лет компанией FlightAware http://flightaware.com/adsb/flightfeeder/

                                                                            Софт тут — https://github.com/flightaware
                                                                            • 0

                                                                              я про "бытовые" флэшки в смысле consumer product


                                                                              у самого же Прога рабочий диапазон 0..70 с Ethenet (или -40..85 без него), плюс сторожевой таймер — это уже черты пром. изделия, так что рад за flightaware:)

                                                                              • 0
                                                                                Флешки у них 32Гб, вроде бы SanDisk.
                                                                                • +1
                                                                                  Как говорил мне один продавец пару лет назад, SanDisk — это вендор, который полученные деньги полностью отрабатывает. Я у Cruzer Contour за 8 лет даже механический «затвор» не смог сломать. Щелкает, блин, как зажигалка Zippo, хоть бы что ему:)
                                                                                  SanDisk Cruzer Contour (2008)
                                                                                  SanDisk Cruzer Contour (2008)
                                                                                  High durability item:)
                                                                        • 0
                                                                          Так-то для read-only можно было собрать ту же бубунту в squashfs
                                                                          • 0
                                                                            спасибо, ответил Вам и другим читателям в публикации, см. UPD: SquashFS
                                                                          • +2
                                                                            Блин. У меня openELEC с KODI пару месяцев работает. Тоже сдохнет?
                                                                            • 0
                                                                              может, вот так прямо и не сдохнет, особенно если Вы установили это на дорогую флэшку типа HPE Flash Media Kit

                                                                              но зато какая интрига! :))
                                                                              • 0
                                                                                Transcend на 16 ГБ. Из приличных вроде. Буду смотреть) в openELEC все гвоздями изрядно прибито. У них даже apt-get закрыт. Образ не трогал)
                                                                                • 0
                                                                                  Уважаемый Meklon, можете отдать две команды из-под root и показать нам результат?
                                                                                  Надо, чтобы система была на ходу несколько дней, с Вашей штатной нагрузкой, без резких бросков.
                                                                                  udevadm info -a -n /dev/mmcblk0
                                                                                  uptime -p

                                                                                  Можете ответ в личку отправить, если сюда — то обязательно в спойлер.
                                                                                  Я попробую оценить суточный износ и остаток ресурса, на большее пока не готов:)
                                                                                  • 0
                                                                                    Брошу, ок) я сам линуксоид, просто лень ковырять исходный образ было)
                                                                                    • 0
                                                                                      udevadm info -a -n /dev/mmcblk0
                                                                                      Meklon-Kitchen:~ # udevadm info -a -n /dev/mmcblk0
                                                                                      
                                                                                      Udevadm info starts with the device specified by the devpath and then
                                                                                      walks up the chain of parent devices. It prints for every device
                                                                                      found, all possible attributes in the udev rules key format.
                                                                                      A rule to match, can be composed by the attributes of the device
                                                                                      and the attributes from one single parent device.
                                                                                      
                                                                                        looking at device '/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:59b4/block/mmcblk0':
                                                                                          KERNEL=="mmcblk0"
                                                                                          SUBSYSTEM=="block"
                                                                                          DRIVER==""
                                                                                          ATTR{ro}=="0"
                                                                                          ATTR{size}=="31586304"
                                                                                          ATTR{stat}=="    2250      740   147420     8920     8963     7499   134874   273290        0    49473   282233"
                                                                                          ATTR{range}=="32"
                                                                                          ATTR{discard_alignment}=="0"
                                                                                          ATTR{force_ro}=="0"
                                                                                          ATTR{ext_range}=="32"
                                                                                          ATTR{alignment_offset}=="0"
                                                                                          ATTR{inflight}=="       0        0"
                                                                                          ATTR{removable}=="0"
                                                                                          ATTR{capability}=="10"
                                                                                      
                                                                                        looking at parent device '/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:59b4':
                                                                                          KERNELS=="mmc0:59b4"
                                                                                          SUBSYSTEMS=="mmc"
                                                                                          DRIVERS=="mmcblk"
                                                                                          ATTRS{cid}=="744a605553445531203ba13fbd00f573"
                                                                                          ATTRS{csd}=="400e00325b590000787d7f800a400005"
                                                                                          ATTRS{scr}=="0235800300000000"
                                                                                          ATTRS{date}=="05/2015"
                                                                                          ATTRS{name}=="USDU1"
                                                                                          ATTRS{type}=="SD"
                                                                                          ATTRS{preferred_erase_size}=="4194304"
                                                                                          ATTRS{fwrev}=="0x0"
                                                                                          ATTRS{hwrev}=="0x2"
                                                                                          ATTRS{oemid}=="0x4a60"
                                                                                          ATTRS{manfid}=="0x000074"
                                                                                          ATTRS{serial}=="0x3ba13fbd"
                                                                                          ATTRS{erase_size}=="512"
                                                                                      
                                                                                        looking at parent device '/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0':
                                                                                          KERNELS=="mmc0"
                                                                                          SUBSYSTEMS=="mmc_host"
                                                                                          DRIVERS==""
                                                                                      
                                                                                        looking at parent device '/devices/platform/soc/3f202000.sdhost':
                                                                                          KERNELS=="3f202000.sdhost"
                                                                                          SUBSYSTEMS=="platform"
                                                                                          DRIVERS=="sdhost-bcm2835"
                                                                                          ATTRS{driver_override}=="(null)"
                                                                                      
                                                                                        looking at parent device '/devices/platform/soc':
                                                                                          KERNELS=="soc"
                                                                                          SUBSYSTEMS=="platform"
                                                                                          DRIVERS==""
                                                                                          ATTRS{driver_override}=="(null)"
                                                                                      
                                                                                        looking at parent device '/devices/platform':
                                                                                          KERNELS=="platform"
                                                                                          SUBSYSTEMS==""
                                                                                          DRIVERS==""
                                                                                      
                                                                                      


                                                                                      Meklon-Kitchen:~ # uptime -p
                                                                                      00:00:44 up 6 days, 14:22, load average: 0.05, 0.08, 0.07
                                                                                      • +1
                                                                                        Meklon, Ваш кухонный прибор за 158 часов прочитал примерно 71Мб и записал около 66Мб, т.е. он подпиливал SD-карточку со скоростью порядка 10Мб/сутки, это *на порядки* меньше, чем автомобильный регистратор. Если такой режим записи сохраняется всегда, то карточка должна прослужить достаточно долго, панику можно отложить:) Но недельная статистика может врать, попробуйте продержать систему месяц без перезагрузки и выполнить команду:
                                                                                        cat /sys/block/mmcblk0/stat | awk '{printf "Uptime read: %.3fMiB written: %.3f MiB\n", $3*512/1048576, $7*512/1048576}'
                                                                                        У Вас получилось бы так:

                                                                                        Uptime read: 71.982 MiB written: 65.856 MiB

                                                                                        Делите на количество дней (часов), получаете среднесуточный износ, всё просто.

                                                                                        Я ещё обратил внимание, что соотношение чтение/запись почти 1:1 (т.е. карта «почти» не читается), что я считаю признаком SquashFS (она загружает содержимое ф/с в ОЗУ). У классических систем без SquashFS, как я понял из общения с другими читателями, соотношение где-то от 5:1 до 10:1. Чем бы там девайс не был занят на кухне, желаю приятного аппетита;))
                                                                                        • 0
                                                                                          Благодарю. Постараюсь позже запустить. Девайс Джейми Оливера крутит и Гордона Рамзи) фон для готовки.
                                                                                    • 0
                                                                                      Из приличных вроде

                                                                                      что-то последнее время хочется им добавить «не-». По крайней мере, купленным в более-менее крупных торговых сетях :(

                                                                                      На предмет «прибивания»: Консоль/root доступны? Для своего openHAB-а решил проблему через
                                                                                      mount --bind /opt/openhab/logs /mnt/sda/oh-logs
                                                                                      

                                                                                      точнее — аналог этой строчки в fstab. Ну или симлинков наделать, но по мне, это менее надёжно при «отваливании» внешнего диска. Если памяти много и хранить не надо — tmpfs плюс пред-создание нужной структуры папок
                                                                                      • 0
                                                                                        Консоль доступна. fstab допилю, наверное. Логи я могу и в /dev/null, в принципе отправить. Это же не мой основной домашний сервер)
                                                                                        • 0
                                                                                          /dev/null хорошо для выбрасывания лишних логов.
                                                                                          Некоторые же утилиты хотят видеть конкретный файл и/или структуру папок на момент старта и начинают «чудить», если это не так.

                                                                                          у меня логи хранятся (не знаю зачем, привычка наверно), но /var/log живет на tmpfs с периодическим архивированием на флешку…

                                                                                          как-то так
                                                                                          сам «сервис»
                                                                                          #!/bin/sh
                                                                                          . /lib/lsb/init-functions
                                                                                          
                                                                                          start() {
                                                                                              log_begin_msg "RAMLOG: Read files from disk.."
                                                                                              tar xfz /var/ram_log.tar.gz -C /
                                                                                              log_end_msg 0
                                                                                          }
                                                                                          
                                                                                          stop() {
                                                                                              log_begin_msg "RAMLOG: Write files to disk.."
                                                                                              tar cfz /var/ram_log.tar.gz --directory=/ var/log/
                                                                                              log_end_msg 0
                                                                                          }
                                                                                          
                                                                                          case "$1" in
                                                                                              start)
                                                                                                  start
                                                                                                  ;;
                                                                                              stop)
                                                                                                  stop
                                                                                                  ;;
                                                                                              flush)
                                                                                                  stop
                                                                                                  ;;
                                                                                              *)
                                                                                                   echo "Usage: $0 {start|stop|flush}"
                                                                                                   exit 1
                                                                                          esac
                                                                                          


                                                                                          запускалка для systemd
                                                                                          [Unit]
                                                                                          Description=Ramlog
                                                                                          After=local-fs.target
                                                                                          Before=cron.service syslog.service
                                                                                          
                                                                                          [Service]
                                                                                          Type=oneshot
                                                                                          RemainAfterExit=yes
                                                                                          ExecStart=/opt/bin/ramlog start
                                                                                          ExecStop=/opt/bin/ramlog stop
                                                                                          
                                                                                          [Install]
                                                                                          WantedBy=multi-user.target
                                                                                          


                                                                                          Ну и в кроне (ещё не сподобился научиться крону от systemd)
                                                                                          0 */6 * * /opt/bin/ramlog flush &> /dev/null
                                                                                          


                                                                                          #fstab
                                                                                          tmpfs /var/log tmpfs relatime,mode=1777

                                                                                          • 0
                                                                                            В принципе, до переполнения не должны забить память. Логично. Запишу в RAM.
                                                                                            • 0
                                                                                              Спасибо за комментарий, он навёл меня на мысль о том, куда лучше скидывать информацию, если не на флэшку:)

                                                                                              Скидывать лучше в облако, причём опытный ниндзя не будет использовать свой основной почтовый аккаунт. Конфиденциальные файлы (бэкапы настроек) перед отправкой в облако лучше зашифровать ассиметричным ключём, используя, например, команду openssl как-то так. Это позволит безопасно хранить публичную половину ключа key.pub на каждом устройстве, не боясь, что кто-то сможет им вскрыть информацию (для этого нужен закрытый ключ;-)
                                                                                              Ну а по поводу облака есть GDriveFS вообще и How to mount your google drive on Raspbian RPI with GDriveFS в частности.
                                                                                              Если информация достаточно безопасна, можно слать «периодику» по почте, но тогда желательно, чтобы её можно было читать сразу в почтовом клиенте, т.е. закладывать открытым текстом, без вложений. Искать гораздо удобнее, я пользуюсь для архивов S.M.A.R.T (у меня двенадцать 3.5" дисков в башне FreeNAS, и по каждому life time history в почте, это иногда очень выручает).
                                                                                          • 0
                                                                                            Какое гадство. openELEC не использует fstab!
                                                                                            • 0
                                                                                              А. Не, еще интереснее.
                                                                                              openelec uses a squashfs filesystem and is read-only at run time
                                                                                              • 0
                                                                                                Всё уже украдено до нас! © Root уже r/o — полдела сделано :)

                                                                                                А юзерские настройки он как-то хранит? Та же убунта замечательно хранит изменения поверх squashfs (casper-persistent кажется).

                                                                                                Не, уберджедаи могут «разобрать» squashfs, поправить и собрать обратно — как в кастомизации LiveCD.

                                                                                                Если есть откуда автоматом запустить скрипт, то остается «sudo mount --[r]bind /...»
                                                                                                • 0
                                                                                                  Надо покопаться. Но, по факту, он всего 10 мегабайт в сутки пишет. Флеш на 16 ГБ. Должно надолго хватить.
                                                                                        • 0
                                                                                          Если флешка не китайское гуано — несколько лет помучается поработает без проблем. Моя три года прожила именно на openELEC+XBMC/KODI в ежедневноактивном режиме, пока не сдохла.
                                                                                          • 0
                                                                                            OpenELEC — довольно популярный дистрибутив. Может, кто посмотрит, что он на карту пишет :)
                                                                                          • 0
                                                                                            Может покажусь дилетантом, но:
                                                                                            внешний cd-rom с live-cd дистрибутивом?
                                                                                            • 0
                                                                                              А с ARM-архитектурой это возможно?
                                                                                              • +2
                                                                                                оптический привод по габаритам существенно превосходит одноплатный компьютер, не любит вибрации, нелепо выглядит, медленный, механический; но это близко к направлению SquashFS, которое я прокомментировал прямо в публикации, не стоит забывать о накладных расходах на изготовление образа firmware и обновлениях безопасности. Нужен адекватный community-проект, который будет публиковать обновления firmware и позволять их обновлять по сети, как это делают, например, OpenWRT и коммерческие производители. Это дорого.
                                                                                              • +2
                                                                                                Огромное спасибо за статью! У нас Raspberry используются вместе с висящими на стенами телевизорами для показа статуса Build-сервера, мониторинга и т.п. Каждые 8-12 месяцев приходится менять запиленную файловой системой SD-карточку.

                                                                                                Думается я 100% попадаю в целевую аудиторию Raspberry — деньги мы зарабатываем на технологиях далёких от Linux, и к Малинке обращаемся пару раз в год с дилетантскими задачами вроде «а как бы при старте автоматически запустить полноэкранный Chromium и открыть вот этот Url». Linux, увы, так и не выучил, а для малинки на любой вопрос можно выгуглить точный рецепт, причём из-за маленького зоопарка моделей рецепты четырёхлетней давности для Raspberry 1 обычно подходят и для Raspberry 3 (с GPIO чуть сложнее, но по сути надо различать всего две модели).

                                                                                                Особое спасибо за структуру статьи: описание проблемы/как будем решать/пошаговая инструкция. Это как раз на уровень знаний типичного пользователя малинки.

                                                                                                Пишите дальше в том же стиле, очень вам благодарен!
                                                                                                • 0
                                                                                                  Спасибо за столь тёплый отзыв, дорогой читатель! Рад стараться:)
                                                                                                • 0
                                                                                                  Не знаю, что я делаю не так, у меня малинка работает как торрентокачалка на большой диск, в качестве сервера стоит Transmission, около двух лет работает. Я, правда, ее редко трогаю, но все же…
                                                                                                  P.S. спаибо за статью, порадовался, что ГТ все еще ГТ.
                                                                                                  • 0

                                                                                                    без графики и swap пара лет на нормальной флэшке — это вроде норма, как раз пора менять, может скоро сдохнуть:)


                                                                                                    и благодарю за комплимент;)

                                                                                                    • 0
                                                                                                      Так в том то и дело! там все включено и иксы запущены! Трансмишен постоянно что-то раздает/получает.
                                                                                                      • 0
                                                                                                        а как флэшку зовут? есть возможность посмотреть hdparm -I /dev/mmcblk0
                                                                                                        • 0
                                                                                                          Флешка smartbuy на 8 гигов а hdparm говорит invalid argument… Я не линуксоид, поэтому не знаю, что есть сие и как починить :)
                                                                                                          • 0
                                                                                                            прошу прощения, чинить ничего не надо
                                                                                                            похоже, достаточно udevadm info -a -n /dev/mmcblk0 с правами root
                                                                                                            там, правда, всё равно не понять ни рожна:)
                                                                                                            • 0
                                                                                                              Действительно, непонять ни рожна… Судя по дате, работает, все же не два года, а с 07/15
                                                                                                              как-то так
                                                                                                              looking at device '/devices/platform/soc/3f300000.mmc/mmc_host/mmc0/mmc0:59b4/block/mmcblk0':
                                                                                                              KERNEL==«mmcblk0»
                                                                                                              SUBSYSTEM==«block»
                                                                                                              DRIVER==""
                                                                                                              ATTR{ro}==«0»
                                                                                                              ATTR{size}==«15693824»
                                                                                                              ATTR{stat}==" 608935 111823 59031459 11015680 753422 705684 13380833 23508600 0 6669180 34541880"
                                                                                                              ATTR{range}==«32»
                                                                                                              ATTR{discard_alignment}==«0»
                                                                                                              ATTR{force_ro}==«0»
                                                                                                              ATTR{ext_range}==«32»
                                                                                                              ATTR{alignment_offset}==«0»
                                                                                                              ATTR{inflight}==" 0 0"
                                                                                                              ATTR{removable}==«0»
                                                                                                              ATTR{capability}==«10»

                                                                                                              looking at parent device '/devices/platform/soc/3f300000.mmc/mmc_host/mmc0/mmc0:59b4':
                                                                                                              KERNELS==«mmc0:59b4»
                                                                                                              SUBSYSTEMS==«mmc»
                                                                                                              DRIVERS==«mmcblk»
                                                                                                              ATTRS{cid}==«834e434e4361726402c2f10ca900f700»
                                                                                                              ATTRS{csd}==«400e00325b5900003bdd7f800a400000»
                                                                                                              ATTRS{scr}==«0235800300000000»
                                                                                                              ATTRS{date}==«07/2015»
                                                                                                              ATTRS{name}==«NCard»
                                                                                                              ATTRS{type}==«SD»
                                                                                                              ATTRS{preferred_erase_size}==«4194304»
                                                                                                              ATTRS{fwrev}==«0x2»
                                                                                                              ATTRS{hwrev}==«0x0»
                                                                                                              ATTRS{oemid}==«0x4e43»
                                                                                                              ATTRS{manfid}==«0x000083»
                                                                                                              ATTRS{serial}==«0xc2f10ca9»
                                                                                                              ATTRS{erase_size}==«512»

                                                                                                              looking at parent device '/devices/platform/soc/3f300000.mmc/mmc_host/mmc0':
                                                                                                              KERNELS==«mmc0»
                                                                                                              SUBSYSTEMS==«mmc_host»
                                                                                                              DRIVERS==""

                                                                                                              looking at parent device '/devices/platform/soc/3f300000.mmc':
                                                                                                              KERNELS==«3f300000.mmc»
                                                                                                              SUBSYSTEMS==«platform»
                                                                                                              DRIVERS==«mmc-bcm2835»
                                                                                                              ATTRS{driver_override}=="(null)"

                                                                                                              looking at parent device '/devices/platform/soc':
                                                                                                              KERNELS==«soc»
                                                                                                              SUBSYSTEMS==«platform»
                                                                                                              DRIVERS==""
                                                                                                              ATTRS{driver_override}=="(null)"

                                                                                                              looking at parent device '/devices/platform':
                                                                                                              KERNELS==«platform»
                                                                                                              SUBSYSTEMS==""
                                                                                                              DRIVERS==""