Есть:
A: программа, которая содержит открытый сокет
B: сценарий сторожевого пса, работающий как услуга:
while true
do
if [ -z "`pidofproc $1`" ]; then
$1;
chrt -f -p 40 `pidofproc $1`
sleep 8
fi;
sleep 2
done
когда сервис начался — начался сторожевой пес
когда служба остановлена - сторожевая собака и программа убиты (killall).
Теперь программа хочет обновить себя, поэтому она вызывает system( "upgrade.sh" );
upgrade.sh:
/sbin/service watchdog stop
.... install upgrade .....
exec /sbin/service watchdog start &
обновление выполнено успешно, но при запуске программы — не удается открыть сокет (уже используется) — при этой ошибке — программа завершает работу (для перезапуска сторожем).
lsof -i показывает три программы для порта:
watchdog
program
sleep
PID программы и сна всегда меняются (то есть выход / перезапуск)
сторожевой пид упорный.
я пытался заменить system(...)
, с
if(!fork()) exec(...)
, но та же проблема остается.
В зависимости от того, как быстро происходит перезапуск после выключения, розетка будет задерживаться. Linux по умолчанию сохраняет сокеты помеченными как используемые в течение некоторого времени после их выпуска (либо close()
или когда процесс умирает), чтобы убедиться, что попытки входящего соединения или данные, которые запаздывают из-за задержек в сети, не окажутся в неправильном приложении.
Это должно быть исправлено внутри приложения. Требуется установить SO_REUSEADDR
sockopt. Согласно руководству сокета (7):
Указывает, что правила, используемые при проверке адресов, указаны
в вызове bind (2) следует разрешить повторное использование локальных адресов. За
Сокеты AF_INET это означает, что сокет может связываться, кроме случаев, когда
есть активный сокет прослушивания, связанный с адресом. когда
прослушивающий сокет связан с INADDR_ANY с определенным портом
тогда невозможно привязать к этому порту ни один локальный
адрес. Аргумент — это целочисленный логический флаг.
Это должно быть установлено с помощью setsockopt
после того, как сокет был создан.
Других решений пока нет …