From c6e6ea88a2e03609b0be013d2df0de1c6062712f Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 18 Dec 2009 17:48:06 +0300 Subject: [PATCH] * Add limits support to each worker (max open files and max core size) * Fix dependency on lex and yacc sources --- CMakeLists.txt | 7 +++++-- src/cfg_file.h | 5 ++++- src/cfg_file.l | 3 +++ src/cfg_file.y | 18 +++++++++++++++++- src/cfg_utils.c | 5 +++++ src/main.c | 27 +++++++++++++++++++++++++++ src/plugins/spf.c | 46 ++++++++++++++++++++++++---------------------- 7 files changed, 85 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d6678d67..cc652ee3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -443,15 +443,18 @@ STRING(REPLACE "_file.l" "_lex.c" LEX_OUTPUT ${LEX_SRC}) ############################ TARGETS SECTION ############################### ADD_CUSTOM_COMMAND(OUTPUT ${LEX_OUTPUT} - COMMAND ${LEX_EXECUTABLE} -o${LEX_OUTPUT} ${LEX_SRC}) + COMMAND ${LEX_EXECUTABLE} -o${LEX_OUTPUT} ${LEX_SRC} + DEPENDS ${LEX_SRC}) ADD_CUSTOM_COMMAND(OUTPUT ${YACC_OUTPUT} - COMMAND ${YACC_EXECUTABLE} -d -o ${YACC_OUTPUT} ${YACC_SRC}) + COMMAND ${YACC_EXECUTABLE} -d -o ${YACC_OUTPUT} ${YACC_SRC} + DEPENDS ${YACC_SRC}) ADD_CUSTOM_COMMAND(OUTPUT src/modules.c COMMAND ../utils/gen-modules.sh ${PLUGINSSRC} WORKING_DIRECTORY src) IF(PERL_EXECUTABLE) ADD_CUSTOM_COMMAND(OUTPUT perl/Makefile + PRE_BUILD COMMAND ${PERL_EXECUTABLE} ./Makefile.PL WORKING_DIRECTORY perl) CONFIGURE_FILE(perl/Makefile.PL.in perl/Makefile.PL) diff --git a/src/cfg_file.h b/src/cfg_file.h index bb07a40c5..16b59c45f 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -197,8 +197,10 @@ struct worker_conf { uint16_t bind_port; /**< bind port in case of TCP socket */ uint16_t bind_family; /**< bind type (AF_UNIX or AF_INET) */ int count; /**< number of workers */ - GHashTable *params; /**< params for worker */ int listen_sock; /**< listening socket desctiptor */ + uint32_t rlimit_nofile; /**< max files limit */ + uint32_t rlimit_maxcore; /**< maximum core file size */ + GHashTable *params; /**< params for worker */ GQueue *active_workers; /**< linked list of spawned workers */ gboolean has_socket; /**< whether we should make listening socket in main process */ }; @@ -267,6 +269,7 @@ struct config_file { GList *views; /**< views */ GHashTable* domain_settings; /**< settings per-domains */ GHashTable* user_settings; /**< settings per-user */ + }; /** diff --git a/src/cfg_file.l b/src/cfg_file.l index fdb151b45..5eea28ba3 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -63,6 +63,9 @@ settings return SETTINGS; user_settings return USER_SETTINGS; domain_settings return DOMAIN_SETTINGS; +maxfiles return MAXFILES; +maxcore return MAXCORE; + filters return FILTERS; factors return FACTORS; grow_factor return GROW_FACTOR; diff --git a/src/cfg_file.y b/src/cfg_file.y index 15a9a91da..a4f7034d0 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -58,7 +58,7 @@ struct rspamd_view *cur_view = NULL; %token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER BINLOG BINLOG_MASTER BINLOG_ROTATE %token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE PROFILE_FILE COUNT %token VIEW IP FROM SYMBOLS CLIENT_IP -%token AUTOLEARN MIN_MARK MAX_MARK +%token AUTOLEARN MIN_MARK MAX_MARK MAXFILES MAXCORE %token SETTINGS USER_SETTINGS DOMAIN_SETTINGS SYMBOL PATH SKIP_CHECK GROW_FACTOR %type STRING @@ -229,6 +229,8 @@ workercmd: | bindsock | workertype | workercount + | workerlimitfiles + | workerlimitcore | workerparam ; @@ -302,6 +304,20 @@ workercount: } ; +workerlimitfiles: + MAXFILES EQSIGN NUMBER { + cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker->rlimit_nofile = $3; + } + ; + +workerlimitcore: + MAXCORE EQSIGN NUMBER { + cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker->rlimit_maxcore = $3; + } + ; + workerparam: STRING EQSIGN QUOTEDSTRING { cur_worker = check_worker_conf (cfg, cur_worker); diff --git a/src/cfg_utils.c b/src/cfg_utils.c index f8518e164..865c81f7f 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -34,6 +34,9 @@ #define DEFAULT_SCORE 10.0 +#define DEFAULT_RLIMIT_NOFILE 2048 +#define DEFAULT_RLIMIT_MAXCORE 0 + extern int yylineno; extern char *yytext; @@ -644,6 +647,8 @@ check_worker_conf (struct config_file *cfg, struct worker_conf *c) #else c->count = DEFAULT_WORKERS_NUM; #endif + c->rlimit_nofile = DEFAULT_RLIMIT_NOFILE; + c->rlimit_maxcore = DEFAULT_RLIMIT_MAXCORE; } return c; diff --git a/src/main.c b/src/main.c index 49ef09b59..dd17b98d1 100644 --- a/src/main.c +++ b/src/main.c @@ -329,6 +329,31 @@ reread_config (struct rspamd_main *rspamd) } } +static void +set_worker_limits (struct worker_conf *cf) +{ + struct rlimit rlmt; + + if (cf->rlimit_nofile != 0) { + rlmt.rlim_cur = (rlim_t) cf->rlimit_nofile; + rlmt.rlim_max = (rlim_t) cf->rlimit_nofile; + + if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + msg_warn ("set_worker_limits: cannot set files rlimit: %d, %s", cf->rlimit_nofile, strerror (errno)); + } + } + + if (cf->rlimit_maxcore != 0) { + rlmt.rlim_cur = (rlim_t) cf->rlimit_maxcore; + rlmt.rlim_max = (rlim_t) cf->rlimit_maxcore; + + if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { + msg_warn ("set_worker_limits: cannot set max core rlimit: %d, %s", cf->rlimit_maxcore, strerror (errno)); + } + } + +} + static struct rspamd_worker * fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) { @@ -347,6 +372,8 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) case 0: /* Drop privilleges */ drop_priv (cfg); + /* Set limits */ + set_worker_limits (cf); switch (cf->type) { case TYPE_CONTROLLER: setproctitle ("controller process"); diff --git a/src/plugins/spf.c b/src/plugins/spf.c index b597da1e5..581f08b84 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -144,28 +144,30 @@ spf_plugin_callback (struct spf_record *record, struct worker_task *task) s = ntohl (task->from_addr.s_addr); while (cur) { addr = cur->data; - if (addr->mask == 0) { - m = 0; - } - else { - m = G_MAXUINT32 << (32 - addr->mask); - } - if ((s & m) == (addr->addr & m)) { - switch (addr->mech) { - case SPF_FAIL: - insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_fail, 1, g_list_prepend (NULL, addr->spf_string)); - break; - case SPF_SOFT_FAIL: - case SPF_NEUTRAL: - insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_softfail, 1, g_list_prepend (NULL, addr->spf_string)); - break; - default: - insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_allow, 1, g_list_prepend (NULL, addr->spf_string)); - break; - } - /* Stop parsing */ - break; - } + if (addr != NULL) { + if (addr->mask == 0) { + m = 0; + } + else { + m = G_MAXUINT32 << (32 - addr->mask); + } + if ((s & m) == (addr->addr & m)) { + switch (addr->mech) { + case SPF_FAIL: + insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_fail, 1, g_list_prepend (NULL, addr->spf_string)); + break; + case SPF_SOFT_FAIL: + case SPF_NEUTRAL: + insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_softfail, 1, g_list_prepend (NULL, addr->spf_string)); + break; + default: + insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_allow, 1, g_list_prepend (NULL, addr->spf_string)); + break; + } + /* Stop parsing */ + break; + } + } cur = g_list_next (cur); } } -- 2.39.5