Я хотел бы прошивать 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-карты?

1 ответ1

0

Редактировать: Кажется, лучший способ - направить вашу команду на "сейчас", чтобы udev не убил ее. Например, "echo mycommand.sh | at now".

Изначально казалось, что «& disown» будет работать, но на самом деле он сталкивается с той же проблемой, что и udev, убивший его, сразу после 300 (5m), а не ~ 2-3s.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .