Не секрет, что алгоритм инициализации заводской прошивки взят из TomatoUSB. Можно с некоторыми ограничениями использовать имеющуюся логику себе во благо.
1. Скрипты, вызываемые после монтирования USB-раздела и непосредственно перед его размонтированием можно записать прямо в NVRAM, что позволит им «пережить» перезагрузку. Вот простейший вариант:
Code:
$ cat ./nvram.sh
#!/bin/sh
cat << EOF > /tmp/script_usbumount.tmp
if [ \$1 = "/tmp/mnt/ENTWARE" ]
then
/opt/etc/init.d/rc.unslung stop
fi
EOF
nvram set script_usbumount="`cat /tmp/script_usbumount.tmp`"
cat << EOF > /tmp/script_usbmount.tmp
logger -t \$(basename \$0) "started [\$@]"
if [ \$1 = "/tmp/mnt/ENTWARE" ]
then
ln -sf \$1 /tmp/opt
/opt/etc/init.d/rc.unslung start
fi
EOF
nvram set script_usbmount="`cat /tmp/script_usbmount.tmp`"
nvram commit
Выполнив единожды скрипт из примера можно организовать запуск и остановку внешних сервисов Entware\Optware, расположенных на разделе диска с меткой ENTWARE. Ещё плюс в том, что можно не беспокоиться о нарушении порядка монтирования носителей (sda vs sdb), т.к. логика опирается на метку диска, которую, в свою очередь надо задать при форматировании раздела (e.g. $ mkfs.ext3 -j -L ENTWARE /dev/sda1). В примере с размонтированием я умышленно не пишу строчку в syslog, т.к. скрипт выполняется уже после остановки прошивочных сервисов, в т.ч. syslogd.
Логика заводской прошивки такова:
- После монтирования очередного раздела проверяется наличие переменной NVRAM script_usbmount и если она существует, то прошивка записывает во временный shell-скрипт заголовок "#!/bin/sh" и содержимое переменной, затем исполняет этот скрипт, передавая в качестве параметра точку монтирования раздела.
- Перед размонтированием очередного раздела проверяется наличие переменной NVRAM script_usbumount и если она существует, то прошивка записывает во временный shell-скрипт заголовок "#!/bin/sh" и содержимое переменной, затем исполняет этот скрипт, передавая в качестве параметра точку монтирования раздела.
2. Скрипт, вызываемый после изменений правил firewall'а тоже возможен, хоть и ограничен единственным диапазоном открываемых на роутере портов. Логика заводской прошивки такова:
- Если переменная NVRAM apps_dl_share установлена в «1», то прошивка считывает NVRAM переменные apps_dl_share_port_from и apps_dl_share_port_to и выполняет при накатывании правил firewall'а:
Code:
-I INPUT -p udp --dport 6881 -j ACCEPT
-I INPUT -p udp --dport apps_dl_share_port_from:apps_dl_share_port_to -j ACCEPT
-I INPUT -p tcp --dport apps_dl_share_port_from:apps_dl_share_port_to -j ACCEPT
т.е. безусловно открывает UDP порт 6881 и тот диапазон портов TCP/UDP, что вы укажете интервалом apps_dl_share_port_from…apps_dl_share_port_to
Прошу учесть, что время выполнения старт\стоп скриптов ограничено тремя секундами, по истечении которых прошивка оборвёт их выполнение и двинется дальше по своей логике. Если нужно больше, то необходимо использовать fork/dtach/screen.
Кроме того, в прошивке предусмотрена NVRAM переменная script_usbhotplug, которая может служить обработчиком при подключении неведомых прошивке USB-устройств. Она поможет, к примеру, тем, кто подключает к роутеру принтер. Код hotplug должен быть рабочий, но в деле я его не проверял.