2015-11-11 1 views
0

Мне нужно разработать механизм для обновления работающего демона в рабочей среде до новой версии без потери соединений клиента (TCP). Что-то похожее на то, что делает nginx, когда вы обновляете его до новой версии. Мне нужно это для удаления ошибки или для выпуска незначительных изменений версии, которые могут быть один раз в день. Демон разработан на платформе C для Linux.исполняемый файл сервера обновления без потери соединений пользователя

Процесс обновления будет выглядеть так:

  1. new_daemon будет выбежала из командной строки с указанием идентификатор процесса old_daemon
  2. new_daemon соединится через гнездо для старого демона отправлять/получать данные и сообщения.
  3. New_daemon отправил old_daemon сообщение, чтобы прекратить прослушивание на PORT, который используется для получения соединений клиента. После подтверждения задержания службы прослушивания новый_дамон начнет прослушивать PORT
  4. Новый_даем отправит сообщение old_daemon для отправки в настоящее время открытых файловых описаний соединений пользователя. Используя системный вызов sendmsg(), old_daemon передаст new_daemon все ресурсы, которые он выделил ядру, а не только соединения, но также и все открытые файлы.
  5. New_daemon отправил сообщение old_daemon для передачи всех глобальных переменных памяти, а old_daemon отправил бы его через соединение сокета между обоими процессами.

Этот процесс очень сложный, поэтому я хотел бы спросить, может ли кто-нибудь предложить лучший процесс или, может быть, есть какая-то методика, чтобы сделать это легко? Цель состоит в том, чтобы иметь наименьшее время простоя в процессе обновления.

ТИА

ответ

0

Одна альтернатива, чтобы написать большую часть вашего демона как разделяемую библиотеку и использовать dlopen связать новые функции в процессе бега. Это означает, что некоторые части не могут быть изменены, и вы можете столкнуться с проблемами параллелизма, но это устраняет необходимость в IPC.

+0

Я согласен, это самый дешевый (в плане разработки) вариант. Может быть, я поеду за ним. Но это работает, только если структура данных (переменные) не изменяется. Итак, ваше предложение ОЧЕНЬ хорошо, о чем я не думал, но это все еще 50% решения. – Nulik

1

Другая альтернатива заключается в том, чтобы направить old_daemon на fork()/exec()new_daemon и немедленно прекратить прием. new_daemon наследует прослушивающий сокет, существующие соединения и открытые файлы (если они не являются fcntl 'd до FD_CLOEXEC) автоматически.

Сказанное, я не думаю, что есть чистый способ передать неполные рабочие места (как я понимаю, шаги 4 и 5 пытаются выполнить). Если возможно, позвольте old_daemon заполнить их.

+0

Спасибо, это отличный способ скопировать дескрипторы файлов. +1 для этого. – Nulik

Смежные вопросы