Upstart, fork и daemon
Хороший способ обеспечить проблемы
У Upstart есть одна известная ошибка: неверное использование expect fork/expect daemon может подвесить initctl, после чего всякие start/stop/restart/reload <service> просто перестанут работать. Для полноты картины отмечу, что такой подвисший сервис не получится остановить и через /usr/sbin/service или /etc/init.d. Весёлая ошибка, но это еще не всё.
Есть еще одна тонкость: если программа использует fork(), то в конфигурационном файле upstart должна присутствовать строка expect fork. По аналогии можно подумать, что если программа использует daemon(), то в конфигурационном файле upstart должна присутствовать строка expect daemon. А вот и нет!
Я всегда полагал, что вызов daemon() — это, грубо говоря, последовательность fork() + setsid() + fork(). Даже неоднократно видел такую реализация daemon() в скриптах autotools.
Но, как оказалось (по крайней мере в eglibc), daemon() выполняет только один вызов fork():
daemon(nochdir, noclose)
int nochdir, noclose;
{
int fd;
switch (__fork()) {
case -1:
return (-1);
case 0:
break;
default:
_exit(0);
}
if (__setsid() == -1)
return (-1);
if (!nochdir)
(void)__chdir("/");
if (!noclose) {
struct stat64 st;
if ((fd = open_not_cancel(_PATH_DEVNULL, O_RDWR, 0)) != -1
&& (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0)
== 0)) {
if (__builtin_expect (S_ISCHR (st.st_mode), 1) != 0
#if defined DEV_NULL_MAJOR && defined DEV_NULL_MINOR
&& (st.st_rdev
== makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR))
#endif
) {
(void)__dup2(fd, STDIN_FILENO);
(void)__dup2(fd, STDOUT_FILENO);
(void)__dup2(fd, STDERR_FILENO);
if (fd > 2)
(void)__close (fd);
} else {
/* We must set an errno value since no
function call actually failed. */
close_not_cancel_no_status (fd);
__set_errno (ENODEV);
return -1;
}
} else {
close_not_cancel_no_status (fd);
return -1;
}
}
return (0);
}
Таким образом, если программа использует daemon() для демонизации, безопаснее начинать с expect fork. Или смотреть в реализацию daemon(). Другой вариант — не использовать upstart, пока его не допилят до вменяемого состояния.
Мне нравится сама идея upstart, но текущая реализация во многом оставляет желать лучшего. В результате имеем зоопарк: традиционные initrc-скрипты (которые далеко не всегда просто перевести в upstart) и скрипты upstart. Грустно.
Апр
2010
Комментарии к статье «Upstart, fork и daemon» (1) »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Upstart, fork и daemon»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.


[...] This post was mentioned on Twitter by Интернет заработок. Интернет заработок said: V.Kolesnikov: Upstart, fork и daemon [...]