Как мне получить процесс для перезагрузки себя в Linux? - PullRequest
2 голосов
/ 09 марта 2009

У меня есть служба, скажем, foo, написанная на C ++, которая работает как root. Есть обычный скрипт, /etc/init.d/foo start | stop | restart.

В определенное время foo должен перезагрузить себя. Обычно после завершения обновления. Но делать такие вещи, как:

system("/etc/init.d/foo restart")

не работает, так как как только перезапуск убивает foo, системный вызов (), очевидно, также уничтожается, и скрипт перезапуска никогда не выполняется до конца.

Есть ли другой вызов, который я могу использовать вместо system (), который выполняется асинхронно в качестве родственного элемента для вызывающего процесса вместо создания синхронного дочернего элемента?

Спасибо!

Ответы [ 9 ]

9 голосов
/ 09 марта 2009

Вы можете поместить его в inittab и позволить init беспокоиться о перезапуске процесса при его выходе по любой причине. Это также позаботится об автоматическом перезапуске, если ваш процесс произойдет сбой или assert () или неожиданно завершится другим способом.

Затем, чтобы обработать ваш вариант использования, процесс просто завершится сам.

9 голосов
/ 09 марта 2009

Вы уже рассматривали семью exec[*]? Вот один - execve.

5 голосов
/ 09 марта 2009

как насчет fork (), за которым следует exec ()?

2 голосов
/ 09 марта 2009

Рассмотрите возможность реализации

/etc/init.d/foo reload

для вашего демона (довольно стандартно, если судить по grep моего окна Debian).

Обычно это делается отправкой процессу сигнала SIGHUP; демон должен иметь обработчик сигнала, который ловит это и перезагружает любую конфигурацию.

Если процесс знает, что ему нужно перезагрузить компьютер, он может просто сигнализировать о себе.

Если вам действительно нужно перезапустить, чтобы забрать новые библиотеки, тогда наберите exec*()

1 голос
/ 10 марта 2009

Третья возможность, предложенная Ори и Полом, заключается в использовании daemontools. Это более портативно, но менее вероятно, будет доступно. Вы создаете скрипт с именем / service / foo / run, и daemontools перезапускает ваш сервис при каждом выходе.

http://cr.yp.to/daemontools.html

1 голос
/ 09 марта 2009

exec*() само по себе в исходной командной строке должно сработать. Вы, вероятно, можете опустить ответвление, потому что тогда у вас есть две запущенные копии, которые вам не нужны, и оригинальная копия должна выйти.

Но также посмотрите на inittab и event.d в зависимости от вашего дистрибутива, чтобы увидеть, будет ли он лучше выполнять то, что вам нужно.

1 голос
/ 09 марта 2009

В дополнение к тому, что уже сказал Ori, некоторые дистрибутивы Linux по-прежнему используют initab, но Ubuntu и, возможно, другие перешли на /etc/event.d. Вы помещаете туда файл (копируете и редактируете один из существующих), затем запускаете демон с помощью команды "sudo start ssh_tunnel" или как там у вас файл.

Затем, когда вам понадобится перезапустить его, вы можете просто убить его с помощью сигнала, и система перезапустит его. Или он может сам решить, что пора перезапускать, вызвав "exit (0);" или что угодно.

1 голос
/ 09 марта 2009

Объединяя два ответа, используйте fork-exec .

0 голосов
/ 09 марта 2009

Посмотрите справочную страницу для inittab.

Описывает, как система автоматически перезапустит ваши процессы, если она умрет (респаун).

При правильной настройке все, что вам нужно сделать - это выйти, и система автоматически позаботится о повторном запуске (респауне).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...