Я хотел бы прошивать SD-карты с помощью специального сценария (записывает таблицу разделов, затем копирует поверх rootfs и т.д.) Всякий раз, когда вставляется SD-карта.
На первый взгляд это казалось простым - я бы просто использовал правило udev для определения SD-карты, а затем вызвал скрипт. Первая проблема заключается в том, что, поскольку читатель уже существует, он не вызывает "добавление", а просто "изменение", и не только это, он вызывает несколько событий и запускает сценарий несколько раз. После еще нескольких фильтров я смог заставить простой скрипт запускаться только один раз (/etc/udev/rules.d/99-sd-detect.rules):
ACTION=="change", KERNEL=="sd[b-z]", SUBSYSTEM=="block", ENV{DISK_MEDIA_CHANGE}=="1", ENV{DEVTYPE}=="disk", ATTRS{idVendor}=="8564", ATTRS{idProduct}=="4000", ENV{ID_DRIVE_FLASH_CF}=="1", RUN+="/bin/sh -c '/root/udev_flash_sd.sh %E{DEVNAME}'"
Однако, когда у меня есть скрипт, записывающий данные на SD-карту, он уничтожается через несколько секунд. Очевидно, в 2012 году udev внес изменения, которые убивают процессы, которые не возвращаются через несколько секунд. Я пробовал разные варианты разветвления / отсоединения / ноу-хау и т.д., Пытаясь поддерживать его работу, но безрезультатно.
Кажется, правильное решение состоит в том, чтобы он вызывал службу systemd для запуска чего-либо, что занимает больше времени, например что-то вроде:
ACTION=="change", KERNEL=="sd[b-z]", SUBSYSTEM=="block", ENV{DISK_MEDIA_CHANGE}=="1", ENV{DEVTYPE}=="disk", ATTRS{idVendor}=="8564", ATTRS{idProduct}=="4000", ENV{ID_DRIVE_FLASH_CF}=="1", TAG+="systemd", PROGRAM="/bin/systemd-escape -p --template=flash_sd@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c"
Где /etc/systemd/system/flash_sd@.service имеет:
[Unit]
BindTo=%i.device
After=%i.device
[Service]
Type=oneshot
TimeoutStartSec=360
ExecStart=/root/udev_flash_sd.sh /%I
Это работает, если вы вызываете «systemctl start flash_sd@dev-sde.service», что также является частью PROGRAM правила udev (по крайней мере для /dev /sde). После долгих поисков похоже, что udev не будет вызывать сервис при событии change, а только при добавлении. ("udevadm monitor -p" показывает SYSTEMD_WANTS и тег правильно, не говоря уже о тестировании простого правила добавления, которое вызывает службу systemd, работает нормально.)
Итак, как мне автоматически вызвать специальный скрипт перепрошивки при вставке SD-карты?