The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Патч для ограничения колличества sendmail процессов (patch sendmail)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: patch, sendmail,  (найти похожие документы)
Date: Thu, 7 Feb 2002 20:22:40 +0000 (UTC) From: Valentin Nechayev <netch@segfault.kiev.ua> Newsgroups: fido7.ru.unix.bsd Subject: Патч для ограничения колличества sendmail процессов > > Я искал как ограничить количество тех процессов, что отфоркиваются при > > 1) генерации отлупов, 2) фоновом запуске доставки при DeliveryMode=background. > Тогда решение - в студию (и FAQ) :-)))) Вот такой он - сразу ему решение подавай... Ладно, см. конец письма. Это для sendall() - через него управление проходит, если не поднят флаг doublequeue. Если поднят - тогда идет через dowork(), там аналогично, но в cvs еще не вносил. FAQ не может быть потому что вопросы еще никто не задавал;)) > > Тормозов не заметил, абсолютно. Причем не три access() а три open()+flock() > Что ещё хуже. Чем хуже-то? Номера инодов фактически в name cache, каталог очереди - в dir cache. > > Типа да. Ассманн, Шапиро... > В таких развесистых долгих проектах код расползается, как тараканы. Это без качественного дизайна. sendmail в этом плане вообще ужас. В качестве примера, рекомендую почитать dropenvelope(): с одной стороны, там генерируются отлупы; с другой стороны, это деструктор объекта "письмо"; с третьей стороны, это часть конструктора объекта "письмо", которая действует после начального bzero()! Я вообще не понимаю как можно в таком бардаке достигать какого-то существенного прогресса... > Удивительно, что всего в двух (?) местах пришлось править - у M$ > каждый программист с собой копию stdlib тянет со своими isalpha()/isdigit()/etc :-)) Sendmail 8.12 тянет вообще свой stdio. Правда, под BSD его не включает - возможности BSD'шного удовлетворяют. Под glibc не смотрел, что делает. Два места - это уже специфика того, как sendmail обходится с ситуацией изменения списка получателей. В srvrsmtp.c есть такой кусок: SmtpPhase = "delivery"; e->e_xfp = freopen(queuename(e, 'x'), "w", e->e_xfp); id = e->e_id; if (doublequeue) { /* make sure it is in the queue */ queueup(e, FALSE); } else { /* send to all recipients */ sendall(e, SM_DEFAULT); } e->e_to = NULL; /* issue success message */ message("250 %s Message accepted for delivery", id); /* if we just queued, poke it */ if (doublequeue && e->e_sendmode != SM_QUEUE && e->e_sendmode != SM_DEFER) { CurrentLA = getla(); if (!shouldqueue(e->e_msgpriority, e->e_ctime)) { unlockqueue(e); (void) dowork(id, TRUE, TRUE, e); } } вот в нем и заключена злополучная развилка. Вызовы sendall() и dowork() здесь - два варианта, когда доставка уходит в фоновый процесс; doublequeue - флаг, который подымается, если получатели раскрывались (по крайней мере, я так понял - логика там темная, замечал уже по результатам). Когда-то это, наверно, имело заметный смысл. Но сейчас от этого больше путаницы, чем пользы. > > оседают в своп - чтобы в памяти не лежать - и оттуда обычно не возвращаются. > > Часто лежит еще что-то. > О нашёл - на DDT после 64 дней в свопе аж 116 кил! :-))) > Сильно бездельничающей я бы её не назвал - одних nnrpd 180 штук, > и CGP на ней нет :((( Видимо, всё же нужно памяти в ваши релеи > довоткнуть - говорят, она всё ещё дешёвая. BSD будет высвоплять ненужное независимо от объема памяти, так уж VM устроена. А подымать этим память только ради того чтобы оно делало thrashing на один раз в сутки меньше... не думаю, что это того стоит.;)) Хотя память добавлять, естественно, будем. По плану.;)) /netch Index: deliver.c
RCS file: /usr/homes/netch/Cvsroot/luckynet/sendmail/8.9/src/deliver.c,v retrieving revision 1.7 retrieving revision 1.11 diff -u -r1.7 -r1.11 --- deliver.c 2000/12/04 13:41:21 1.7 +++ deliver.c 2001/12/19 12:59:02 1.11 @@ -8,10 +8,11 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * + * @(#)deliver.c 8.367 (Berkeley) 1/18/1999 */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 8.367 (Berkeley) 1/18/1999"; +static char sccsid[] = "@(#)$Id: deliver.c,v 1.11 2001/12/19 12:59:02 netch Exp $"; #endif /* not lint */ #include "sendmail.h" @@ -65,6 +66,12 @@ bool somedeliveries = FALSE, expensive = FALSE; pid_t pid; void sendenvelope __P((ENVELOPE *, int)); +#define _NXLA +#if defined(_NXLA) + int fd_worklock = -1; + char P[1024]; + int ii, rval, nmax; +#endif /* ** If this message is to be discarded, don't bother sending @@ -544,6 +551,47 @@ pid = fork(); if (pid > 0) exit(EX_OK); + /*sm_syslog( LOG_INFO, e->e_id, "_: sendall(): double fork" );*/ +#if defined(_NXLA) + nmax = MaxChildren; + if( nmax <= 0 ) + nmax = RefuseLA; + if( nmax <= 0 ) + nmax = 10; + fd_worklock = -1; + srand(time(NULL)+getpid()); + for( ii = 1; ii <= 3; ii++ ) { + int se; + rval = rand() % nmax; + snprintf( P, sizeof P, + "%s/dowork_lock.%d", + QueueDir, rval ); + fd_worklock = safeopen( P, + O_RDWR|O_CREAT, + 0644, + SFF_NOLINK|SFF_ROOTOK|\ + SFF_SAFEDIRPATH|SFF_CREAT|\ + SFF_REGONLY|SFF_NOWLINK|\ + SFF_OPENASROOT|SFF_NOLOCK + ); + se = errno; + if( fd_worklock < 0 ) + continue; + if( flock( fd_worklock, LOCK_EX|LOCK_NB ) ) { + close( fd_worklock ); + fd_worklock = -1; + continue; + } + break; + } + if( fd_worklock < 0 ) { + if( LogLevel > 8 ) { + sm_syslog( LOG_INFO, e->e_id, + "worklock: denynow" ); + } + finis( TRUE, EX_TEMPFAIL ); + } +#endif /* _NXLA */ /* be sure we are immune from the terminal */ disconnect(2, e); @@ -616,8 +664,12 @@ CurEnv = e; Verbose = oldverbose; - if (mode == SM_FORK) + if (mode == SM_FORK) { +#if defined(_NXLA) + close( fd_worklock ); +#endif finis(TRUE, ExitStat); + } } void

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру