[devel] q: installer: Killing all remaining processes (forever)
Evgeny Sinelnikov
=?iso-8859-1?q?sin_=CE=C1_altlinux=2Eru?=
Ср Апр 16 06:01:27 MSD 2008
2008/4/16 Dmitry V. Levin <ldv at altlinux.org>:
> On Wed, Apr 16, 2008 at 04:03:19AM +0400, Evgeny Sinelnikov wrote:
> > > $ strace -qe waitpid ./waitpid
> > > waitpid(-1, 0xbf88880c, WNOHANG) = -1 ECHILD (No child processes)
> > > waitpid(-1, 0xbf88880c, WNOHANG) = -1 ECHILD (No child processes)
> >
> > Странный пример, у него же нет потомков, и нет обработчика SIGCHILD.
> > Но он демонстрирует, что ECHILD приходит.
>
> Он демонстрирует, что повторный waitpid снова приводит к ECHILD.
>
>
> > > > Это же подтверждено не практике. В моём случае стоит
> > > > ожидание только по этому сигналу, иначе цикл в killall() у меня вообще
> > > > не завершится... Но он завершается, а следовательно ECHILD, как и
> > > > ожидается, приходит...
> > >
> > > ECHILD у init произойдёт только в случае если в системе не останется
> > > процессов, у которых ppid==1; такое может произойти, но может и не
> > > произойти. У нас на стенде init не получал ECHILD ни разу.
> >
> > Такое обязательно произойдёт, если этого дождаться... Иначе нет
> > никакой гарантии, что процессы, занявшие ресурсы /mnt/destination
> > завершены. В коде же инсталятора это ожидание раньше полагалось на
> > секунду после первого общего сигнала. А то, что оно не происходило
> > означает, что никогда не было момента, чтобы последний сигнал был
> > получен и успел быть обработан. Хотя конечно это странно...
> >
> > ECHILD может быть не получен, только, если последний процесс не
> > пришлёт SIGCHILD... Если такое вдруг произойдёт, то таймаут, конечно,
> > выход...
>
> ECHILD может не случиться, если в системе остался хотя бы один процесс
> с ppid==1, который не собирается завершаться. На нашем стенде это
> происходит всегда.
>
Даже когда ему SIGKILL отправили не отрывается... ? Хм... Ну, всякое
бывает, но это какие-то проблемы ядра. Сизифный вариант на 2.6.24
такого не давал ни разу.... Теперь понятно почему ранее не выявлялся
баг с killall()...
>
> > Текущий вариант (когда превратиться в alt14) должен быть вполне
> > работоспособен... Вот только 5 секунд - это маловато...
>
> А вот мне кажется, что и 5 секунд многовато. Не договоримся. :)
>
Ну, скажем так, пока это вероятно приемлимо...
>
> > Ведь sleep()
> > прерывается во время прихода сигнала и, при интенсивном приходе
> > SIGCHILD на этапе ожидания завершения процессов, может пять раз подряд
> > прерваться может. И никакой гарантии, что 6 и 7 процессы ещё не
> > завершились нет. Статистически же поймать это будет теперь ещё
> > сложнее...
>
> Можно использовать альтернативную реализацию sleep(3), например:
>
> static void mysleep(time_t sec)
> {
> struct timespec req = { sec, 0 }, rem;
>
> for (; req.tv_sec || req.tv_nsec; req = rem)
> if (!nanosleep(&req, &rem))
> break;
> }
>
Как-то оно не очень... Вся прелесть была как раз в том, что sleep()
отрывался после очередной обработки сигнала и, если это был последний
процесс, то переменная got_ECHILD была уже установлена... Холостое
ожидание было сведено к минимуму... Если конечно таких багов не было
бы, когда процессы зависают... А для того, чтобы этот процесс был
виден точки рисуютс как раз... У меня ни разу не было видно как они
рисуются... Моментально пробегают и тут же ECHILD ловится....
--
Sin (Sinelnikov Evgeny)
Подробная информация о списке рассылки Devel