From 9bacf0d835d66aaddcdb9e664a34364f25ed2554 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 16 Jan 2012 20:59:37 +0400 Subject: [PATCH] * Introduce new system of worker's and modules initialization: - Removed legacy limitation of worker's types; - Using GQuarks to identify workers and modules; - Remove modules.sh script; - Add a common system of workers and modules; - Write management and configuration for new architecture. --- CMakeLists.txt | 62 ++++++++++++++++++-- config.h.in | 16 +++++- src/cfg_file.h | 4 +- src/cfg_utils.c | 10 ++-- src/cfg_xml.c | 64 ++++++--------------- src/controller.c | 23 ++++++-- src/fuzzy_storage.c | 33 ++++++++--- src/fuzzy_storage.h | 3 - src/kvstorage_server.c | 24 ++++++-- src/kvstorage_server.h | 3 - src/lmtp.c | 24 ++++++-- src/lmtp.h | 2 - src/logger.c | 8 +-- src/logger.h | 4 +- src/main.c | 116 +++++++++++--------------------------- src/main.h | 21 +++---- src/plugins/chartable.c | 12 ++++ src/plugins/fuzzy_check.c | 12 ++++ src/plugins/regexp.c | 12 ++++ src/plugins/spf.c | 12 ++++ src/plugins/surbl.c | 12 ++++ src/smtp.c | 42 +++++++++----- src/smtp.h | 10 ---- src/util.c | 74 ++++++++---------------- src/util.h | 37 +++--------- src/worker.c | 29 +++++++--- 26 files changed, 364 insertions(+), 305 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c02fbab9e..758081459 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,11 +3,14 @@ # # Cmake configuration file # + +############################# INITIAL SECTION ############################################# + PROJECT(rspamd C) SET(RSPAMD_VERSION_MAJOR 0) SET(RSPAMD_VERSION_MINOR 4) -SET(RSPAMD_VERSION_PATCH 6) +SET(RSPAMD_VERSION_PATCH 7) SET(RSPAMD_VERSION "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}.${RSPAMD_VERSION_PATCH}") @@ -17,6 +20,8 @@ SET(RSPAMD_GROUP "nobody") CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) +############################# OPTIONS SECTION ############################################# + OPTION(DEBUG_MODE "Enable debug output [default: ON]" ON) OPTION(ENABLE_OPTIMIZATION "Enable optimization [default: OFF]" OFF) OPTION(SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF) @@ -30,7 +35,7 @@ OPTION(FORCE_GMIME24 "Link with gmime2.4 [default: OFF]" # Build optimized code for following CPU (default i386) #SET(CPU_TUNE "i686") -############################# CONFIG SECTION ############################################# +############################# INCLUDE SECTION ############################################# INCLUDE(CheckIncludeFiles) INCLUDE(CheckFunctionExists) @@ -41,6 +46,51 @@ INCLUDE(FindPkgConfig) INCLUDE(CheckCCompilerFlag) INCLUDE(FindPerl) +############################# MODULES SECTION ############################################# + +MACRO(_AddModulesForced MLIST WLIST) +# Generate unique string for this build + STRING(RANDOM LENGTH 8 _MODULES_ID) + SET(MODULES_ID ${_MODULES_ID} CACHE INTERNAL "Modules ID" FORCE) + FILE(WRITE "src/modules.c" "/* ${MODULES_ID} */\n#include \"config.h\"\n") + FOREACH(MOD IN LISTS ${MLIST}) + FILE(APPEND "src/modules.c" "extern module_t ${MOD}_module;\n") + ENDFOREACH(MOD IN LISTS ${MLIST}) + + FILE(APPEND "src/modules.c" "\n\nmodule_t *modules[] = {\n") + + FOREACH(MOD IN LISTS ${MLIST}) + FILE(APPEND "src/modules.c" "&${MOD}_module,\n") + ENDFOREACH(MOD IN LISTS ${MLIST}) + FILE(APPEND "src/modules.c" "NULL\n};\n") + + FOREACH(WRK IN LISTS ${WLIST}) + FILE(APPEND "src/modules.c" "extern worker_t ${WRK}_worker;\n") + ENDFOREACH(WRK IN LISTS ${WLIST}) + + FILE(APPEND "src/modules.c" "\n\nworker_t *workers[] = {\n") + + FOREACH(WRK IN LISTS ${WLIST}) + FILE(APPEND "src/modules.c" "&${WRK}_worker,\n") + ENDFOREACH(WRK IN LISTS ${WLIST}) + FILE(APPEND "src/modules.c" "NULL\n};\n") +ENDMACRO(_AddModulesForced MLIST WLIST) + +MACRO(AddModules MLIST WLIST) + _AddModulesForced(${MLIST} ${WLIST}) + #IF(NOT EXISTS "src/modules.c") + # _AddModulesForced(${MLIST} ${WLIST}) + #ELSE(NOT EXISTS "src/modules.c") + # FILE(STRINGS "src/modules.c" FILE_ID_RAW REGEX "^/.*[a-zA-Z0-9]+.*/$") + # STRING(REGEX MATCH "[a-zA-Z0-9]+" FILE_ID "${FILE_ID_RAW}") + # IF(NOT FILE_ID STREQUAL MODULES_ID) + # MESSAGE("Regenerate modules info") + # _AddModulesForced(${MLIST} ${WLIST}) + # ENDIF(NOT FILE_ID STREQUAL MODULES_ID) + #ENDIF(NOT EXISTS "src/modules.c") +ENDMACRO(AddModules MLIST WLIST) + +############################# CONFIG SECTION ############################################# # Initial set IF(CMAKE_INSTALL_PREFIX) @@ -812,14 +862,14 @@ SET(PLUGINSSRC src/plugins/surbl.c src/plugins/chartable.c src/plugins/fuzzy_check.c src/plugins/spf.c) + +SET(MODULES_LIST surbl regexp chartable fuzzy_check spf) +SET(WORKERS_LIST normal controller smtp lmtp fuzzy keystorage) +AddModules(MODULES_LIST WORKERS_LIST) ################################ SUBDIRS SECTION ########################### -ADD_CUSTOM_COMMAND(OUTPUT src/modules.c - COMMAND ${CMAKE_SOURCE_DIR}/utils/gen-modules.sh ${PLUGINSSRC} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src) - ADD_SUBDIRECTORY(contrib/lgpl) IF(GLIB_COMPAT) INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/contrib/lgpl") diff --git a/config.h.in b/config.h.in index 8eedae5c0..8ad00557d 100644 --- a/config.h.in +++ b/config.h.in @@ -433,14 +433,26 @@ /* Forwarded declaration */ struct module_ctx; struct config_file; +struct rspamd_worker; typedef struct module_s { - const char *name; + const gchar *name; int (*module_init_func)(struct config_file *cfg, struct module_ctx **ctx); int (*module_config_func)(struct config_file *cfg); int (*module_reconfig_func)(struct config_file *cfg); } module_t; -extern module_t modules[]; +typedef struct worker_s { + const gchar *name; + gpointer (*worker_init_func)(); + void (*worker_start_func)(struct rspamd_worker *worker); + gboolean has_socket; + gboolean unique; + gboolean threaded; + gboolean killable; +} worker_t; + +extern module_t *modules[]; +extern worker_t *workers[]; #endif diff --git a/src/cfg_file.h b/src/cfg_file.h index 797f32837..b90171426 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -224,7 +224,8 @@ struct config_scalar { * Config params for rspamd worker */ struct worker_conf { - gint type; /**< worker type */ + worker_t *worker; /**< pointer to worker type */ + GQuark type; /**< type of worker */ gchar *bind_host; /**< bind line */ struct in_addr bind_addr; /**< bind address in case of TCP socket */ guint16 bind_port; /**< bind port in case of TCP socket */ @@ -299,7 +300,6 @@ struct config_file { GList *filters; /**< linked list of all filters */ GList *workers; /**< linked list of all workers params */ gchar *filters_str; /**< string of filters */ - guint modules_num; GHashTable* modules_opts; /**< hash for module options indexed by module name */ GHashTable* variables; /**< hash of $variables defined in config, indexed by variable name */ GHashTable* metrics; /**< hash of metrics indexed by metric name */ diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 2117025ba..f7d1b7ecf 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -523,7 +523,7 @@ parse_filters_str (struct config_file *cfg, const gchar *str) { gchar **strvec, **p; struct filter *cur; - guint i; + module_t **pmodule; if (str == NULL) { return; @@ -538,18 +538,20 @@ parse_filters_str (struct config_file *cfg, const gchar *str) while (*p) { cur = NULL; /* Search modules from known C modules */ - for (i = 0; i < cfg->modules_num; i++) { + pmodule = &modules[0]; + while (*pmodule) { g_strstrip (*p); - if (modules[i].name != NULL && g_ascii_strcasecmp (modules[i].name, *p) == 0) { + if ((*pmodule)->name != NULL && g_ascii_strcasecmp ((*pmodule)->name, *p) == 0) { cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter)); cur->type = C_FILTER; msg_debug ("found C filter %s", *p); cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); - cur->module = &modules[i]; + cur->module = (*pmodule); cfg->filters = g_list_prepend (cfg->filters, cur); break; } + pmodule ++; } if (cur != NULL) { /* Go to next iteration */ diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 87929f510..8ecd7a986 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -850,13 +850,9 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud) struct xml_config_param *cparam; GHashTable *worker_config; - if (cd->wrk->ctx == NULL) { - cd->wrk->ctx = init_workers_ctx (cd->wrk->type); - } - if (!worker_options || (worker_config = g_hash_table_lookup (worker_options, &cd->wrk->type)) == NULL || (cparam = g_hash_table_lookup (worker_config, k)) == NULL) { - msg_warn ("unregistered worker attribute '%s' for worker %s", k, process_to_str (cd->wrk->type)); + msg_warn ("unregistered worker attribute '%s' for worker %s", k, g_quark_to_string (cd->wrk->type)); } else { @@ -864,7 +860,7 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud) cparam->handler (cd->cfg, cd->ctx, NULL, v, NULL, cd->wrk->ctx, cparam->offset); } else { - msg_err ("Bad error detected: module %s has not initialized its context", process_to_str (cd->wrk->type)); + msg_err ("Bad error detected: module %s has not initialized its context", g_quark_to_string (cd->wrk->type)); } } } @@ -894,31 +890,20 @@ gboolean worker_handle_type (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset) { struct worker_conf *wrk = ctx->section_pointer; - + GQuark type; - if (g_ascii_strcasecmp (data, "normal") == 0) { - wrk->type = TYPE_WORKER; - wrk->has_socket = TRUE; - } - else if (g_ascii_strcasecmp (data, "controller") == 0) { - wrk->type = TYPE_CONTROLLER; - wrk->has_socket = TRUE; - } - else if (g_ascii_strcasecmp (data, "lmtp") == 0) { - wrk->type = TYPE_LMTP; - wrk->has_socket = TRUE; - } - else if (g_ascii_strcasecmp (data, "smtp") == 0) { - wrk->type = TYPE_SMTP; - wrk->has_socket = TRUE; - } - else if (g_ascii_strcasecmp (data, "fuzzy") == 0) { - wrk->type = TYPE_FUZZY; - wrk->has_socket = FALSE; - } - else if (g_ascii_strcasecmp (data, "keystorage") == 0) { - wrk->type = TYPE_KVSTORAGE; - wrk->has_socket = TRUE; + type = g_quark_try_string (data); + + if (type != 0) { + wrk->worker = get_worker_by_type (type); + if (wrk->worker == NULL) { + msg_err ("unknown worker type: %s", data); + return FALSE; + } + wrk->type = type; + if (wrk->worker->worker_init_func) { + wrk->ctx = wrk->worker->worker_init_func (); + } } else { msg_err ("unknown worker type: %s", data); @@ -2441,23 +2426,8 @@ xml_dump_workers (struct config_file *cfg, FILE *f) wrk = cur->data; rspamd_fprintf (f, "" EOL); - switch (wrk->type) { - case TYPE_WORKER: - rspamd_fprintf (f, " normal" EOL); - break; - case TYPE_CONTROLLER: - rspamd_fprintf (f, " controller" EOL); - break; - case TYPE_FUZZY: - rspamd_fprintf (f, " fuzzy" EOL); - break; - case TYPE_LMTP: - rspamd_fprintf (f, " lmtp" EOL); - break; - case TYPE_SMTP: - rspamd_fprintf (f, " smtp" EOL); - break; - } + + rspamd_fprintf (f, " %s" EOL, g_quark_to_string (wrk->type)); escaped_str = g_markup_escape_text (wrk->bind_host, -1); rspamd_fprintf (f, " %s" EOL, escaped_str); g_free (escaped_str); diff --git a/src/controller.c b/src/controller.c index 1b78b82f5..b9ec3677c 100644 --- a/src/controller.c +++ b/src/controller.c @@ -30,7 +30,6 @@ #include "upstream.h" #include "cfg_file.h" #include "cfg_xml.h" -#include "modules.h" #include "map.h" #include "dns.h" #include "tokenizers/tokenizers.h" @@ -44,6 +43,20 @@ /* 120 seconds for controller's IO */ #define CONTROLLER_IO_TIMEOUT 120 +/* Init functions */ +gpointer init_controller (); +void start_controller (struct rspamd_worker *worker); + +worker_t controller_worker = { + "controller", /* Name */ + init_controller, /* Init function */ + start_controller, /* Start function */ + TRUE, /* Has socket */ + FALSE, /* Non unique */ + FALSE, /* Non threaded */ + TRUE /* Killable */ +}; + enum command_type { COMMAND_PASSWORD, COMMAND_QUIT, @@ -1229,16 +1242,18 @@ accept_socket (gint fd, short what, void *arg) } gpointer -init_controller (void) +init_controller () { struct rspamd_controller_ctx *ctx; + GQuark type; + type = g_quark_try_string ("controller"); ctx = g_malloc0 (sizeof (struct rspamd_controller_ctx)); ctx->timeout = CONTROLLER_IO_TIMEOUT * 1000; - register_worker_opt (TYPE_CONTROLLER, "password", xml_handle_string, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, password)); - register_worker_opt (TYPE_CONTROLLER, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, timeout)); + register_worker_opt (type, "password", xml_handle_string, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, password)); + register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_controller_ctx, timeout)); return ctx; } diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 408d39960..d8344b96c 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -34,7 +34,6 @@ #include "cfg_file.h" #include "cfg_xml.h" #include "url.h" -#include "modules.h" #include "message.h" #include "fuzzy.h" #include "bloom.h" @@ -63,6 +62,20 @@ /* Current version of fuzzy hash file format */ #define CURRENT_FUZZY_VERSION 1 +/* Init functions */ +gpointer init_fuzzy (); +void start_fuzzy (struct rspamd_worker *worker); + +worker_t fuzzy_worker = { + "fuzzy", /* Name */ + init_fuzzy, /* Init function */ + start_fuzzy, /* Start function */ + TRUE, /* Has socket */ + TRUE, /* Non unique */ + FALSE, /* Non threaded */ + FALSE /* Non killable */ +}; + static GQueue *hashes[BUCKETS]; static GQueue *frequent; #ifdef WITH_JUDY @@ -756,9 +769,12 @@ sync_callback (gint fd, short what, void *arg) } gpointer -init_fuzzy_storage (void) +init_fuzzy (void) { struct rspamd_fuzzy_storage_ctx *ctx; + GQuark type; + + type = g_quark_try_string ("fuzzy"); ctx = g_malloc0 (sizeof (struct rspamd_fuzzy_storage_ctx)); @@ -766,15 +782,15 @@ init_fuzzy_storage (void) ctx->frequent_score = DEFAULT_FREQUENT_SCORE; ctx->expire = DEFAULT_EXPIRE; - register_worker_opt (TYPE_FUZZY, "hashfile", xml_handle_string, ctx, + register_worker_opt (type, "hashfile", xml_handle_string, ctx, G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, hashfile)); - register_worker_opt (TYPE_FUZZY, "max_mods", xml_handle_uint32, ctx, + register_worker_opt (type, "max_mods", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, max_mods)); - register_worker_opt (TYPE_FUZZY, "frequent_score", xml_handle_uint32, ctx, + register_worker_opt (type, "frequent_score", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, frequent_score)); - register_worker_opt (TYPE_FUZZY, "expire", xml_handle_seconds, ctx, + register_worker_opt (type, "expire", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, expire)); - register_worker_opt (TYPE_FUZZY, "use_judy", xml_handle_boolean, ctx, + register_worker_opt (type, "use_judy", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_fuzzy_storage_ctx, use_judy)); return ctx; @@ -784,14 +800,13 @@ init_fuzzy_storage (void) * Start worker process */ void -start_fuzzy_storage (struct rspamd_worker *worker) +start_fuzzy (struct rspamd_worker *worker) { struct sigaction signals; struct event sev; gint retries = 0; worker->srv->pid = getpid (); - worker->srv->type = TYPE_FUZZY; event_init (); diff --git a/src/fuzzy_storage.h b/src/fuzzy_storage.h index f5196b1d6..2e60670df 100644 --- a/src/fuzzy_storage.h +++ b/src/fuzzy_storage.h @@ -27,7 +27,4 @@ struct fuzzy_session { struct sockaddr_storage sa; }; -gpointer init_fuzzy_storage (void); -void start_fuzzy_storage (struct rspamd_worker *worker); - #endif diff --git a/src/kvstorage_server.c b/src/kvstorage_server.c index c55c7c37e..059a0e6e8 100644 --- a/src/kvstorage_server.c +++ b/src/kvstorage_server.c @@ -63,6 +63,20 @@ static sig_atomic_t soft_wanna_die = 0; g_static_mutex_unlock (thr->log_mtx); \ } while (0) +/* Init functions */ +gpointer init_keystorage (); +void start_keystorage (struct rspamd_worker *worker); + +worker_t keystorage_worker = { + "keystorage", /* Name */ + init_keystorage, /* Init function */ + start_keystorage, /* Start function */ + TRUE, /* Has socket */ + FALSE, /* Non unique */ + TRUE, /* Non threaded */ + FALSE /* Non killable */ +}; + #ifndef HAVE_SA_SIGINFO static void sig_handler (gint signo) @@ -86,19 +100,21 @@ sig_handler (gint signo, siginfo_t *info, void *unused) } gpointer -init_kvstorage_worker (void) +init_keystorage (void) { struct kvstorage_worker_ctx *ctx; + GQuark type; + type = g_quark_try_string ("keystorage"); ctx = g_malloc0 (sizeof (struct kvstorage_worker_ctx)); ctx->pool = memory_pool_new (memory_pool_get_size ()); /* Set default values */ ctx->timeout_raw = 300000; - register_worker_opt (TYPE_KVSTORAGE, "timeout", xml_handle_seconds, ctx, + register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct kvstorage_worker_ctx, timeout_raw)); - register_worker_opt (TYPE_KVSTORAGE, "redis", xml_handle_boolean, ctx, + register_worker_opt (type, "redis", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct kvstorage_worker_ctx, is_redis)); return ctx; } @@ -1066,7 +1082,7 @@ create_kvstorage_thread (struct rspamd_worker *worker, struct kvstorage_worker_c * Start worker process */ void -start_kvstorage_worker (struct rspamd_worker *worker) +start_keystorage (struct rspamd_worker *worker) { struct sigaction signals; struct kvstorage_worker_ctx *ctx = worker->ctx; diff --git a/src/kvstorage_server.h b/src/kvstorage_server.h index e2d670bad..aeb11e249 100644 --- a/src/kvstorage_server.h +++ b/src/kvstorage_server.h @@ -93,7 +93,4 @@ struct kvstorage_session { time_t now; }; -gpointer init_kvstorage_worker (void); -void start_kvstorage_worker (struct rspamd_worker *worker); - #endif /* KVSTORAGE_SERVER_H_ */ diff --git a/src/lmtp.c b/src/lmtp.c index 81b546d4f..da38dc6ae 100644 --- a/src/lmtp.c +++ b/src/lmtp.c @@ -30,7 +30,6 @@ #include "cfg_file.h" #include "util.h" #include "url.h" -#include "modules.h" #include "message.h" static gchar greetingbuf[1024]; @@ -38,6 +37,18 @@ static struct timeval io_tv; static gboolean lmtp_write_socket (void *arg); +void start_lmtp (struct rspamd_worker *worker); + +worker_t lmtp_worker = { + "controller", /* Name */ + NULL, /* Init function */ + start_lmtp, /* Start function */ + TRUE, /* Has socket */ + FALSE, /* Non unique */ + FALSE, /* Non threaded */ + TRUE /* Killable */ +}; + #ifndef HAVE_SA_SIGINFO static void sig_handler (gint signo) @@ -279,15 +290,14 @@ accept_socket (gint fd, short what, void *arg) * Start lmtp worker process */ void -start_lmtp_worker (struct rspamd_worker *worker) +start_lmtp (struct rspamd_worker *worker) { struct sigaction signals; - gint i; gchar *hostbuf; gsize hostmax; + module_t **mod; worker->srv->pid = getpid (); - worker->srv->type = TYPE_LMTP; worker->ctx = event_init (); g_mime_init (0); @@ -310,8 +320,10 @@ start_lmtp_worker (struct rspamd_worker *worker) event_add (&worker->bind_ev, NULL); /* Perform modules configuring */ - for (i = 0; i < MODULES_NUM; i++) { - modules[i].module_config_func (worker->srv->cfg); + mod = &modules[0]; + while (*mod) { + (*mod)->module_config_func (worker->srv->cfg); + mod ++; } /* Fill hostname buf */ diff --git a/src/lmtp.h b/src/lmtp.h index d7c13c497..863c6eacd 100644 --- a/src/lmtp.h +++ b/src/lmtp.h @@ -15,6 +15,4 @@ #define LMTP_NO_RCPT 554 #define LMTP_TEMP_FAIL 421 -void start_lmtp_worker (struct rspamd_worker *worker); - #endif diff --git a/src/logger.c b/src/logger.c index 219f04cac..2abdf0dfc 100644 --- a/src/logger.c +++ b/src/logger.c @@ -54,7 +54,7 @@ struct rspamd_logger_s { sig_atomic_t do_reopen_log; enum rspamd_log_type type; pid_t pid; - enum process_type process_type; + GQuark process_type; radix_tree_t *debug_ip; guint32 last_line_cksum; guint32 repeats; @@ -252,7 +252,7 @@ reopen_log (rspamd_logger_t *logger) * Setup logger */ void -rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *rspamd) +rspamd_set_logger (enum rspamd_log_type type, GQuark ptype, struct rspamd_main *rspamd) { gchar **strvec, *p, *err; gint num, i, k; @@ -340,7 +340,7 @@ rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rs * Used after fork() for updating structure params */ void -update_log_pid (enum process_type ptype, rspamd_logger_t *rspamd_log) +update_log_pid (GQuark ptype, rspamd_logger_t *rspamd_log) { rspamd_log->pid = getpid (); rspamd_log->process_type = ptype; @@ -568,7 +568,7 @@ file_log_function (const gchar * log_domain, const gchar *function, GLogLevelFla tms = localtime (&now); strftime (timebuf, sizeof (timebuf), "%F %H:%M:%S", tms); - cptype = process_to_str (rspamd_log->process_type); + cptype = g_quark_to_string (rspamd_log->process_type); if (rspamd_log->cfg->log_color) { if (log_level >= G_LOG_LEVEL_INFO) { diff --git a/src/logger.h b/src/logger.h index e25d6bfff..6d0cac4b8 100644 --- a/src/logger.h +++ b/src/logger.h @@ -15,7 +15,7 @@ typedef struct rspamd_logger_s rspamd_logger_t; /** * Init logger */ -void rspamd_set_logger (enum rspamd_log_type type, enum process_type ptype, struct rspamd_main *main); +void rspamd_set_logger (enum rspamd_log_type type, GQuark ptype, struct rspamd_main *main); /** * Open log file or initialize other structures */ @@ -45,7 +45,7 @@ gint reopen_log_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid); /** * Set log pid */ -void update_log_pid (enum process_type ptype, rspamd_logger_t *logger); +void update_log_pid (GQuark ptype, rspamd_logger_t *logger); /** * Flush log buffer for some types of logging diff --git a/src/main.c b/src/main.c index e16d9d5e0..bb6209974 100644 --- a/src/main.c +++ b/src/main.c @@ -262,9 +262,9 @@ drop_priv (struct rspamd_main *rspamd) } static void -config_logger (struct rspamd_main *rspamd, gboolean is_fatal) +config_logger (struct rspamd_main *rspamd, GQuark type, gboolean is_fatal) { - rspamd_set_logger (rspamd->cfg->log_type, TYPE_MAIN, rspamd); + rspamd_set_logger (rspamd->cfg->log_type, type, rspamd); if (open_log_priv (rspamd->logger, rspamd->workers_uid, rspamd->workers_gid) == -1) { if (is_fatal) { fprintf (stderr, "Fatal error, cannot open logfile, exiting\n"); @@ -283,12 +283,12 @@ reread_config (struct rspamd_main *rspamd) gchar *cfg_file; GList *l; struct filter *filt; + GQuark type; tmp_cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); if (tmp_cfg) { bzero (tmp_cfg, sizeof (struct config_file)); tmp_cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); - tmp_cfg->modules_num = MODULES_NUM; init_defaults (tmp_cfg); cfg_file = memory_pool_strdup (tmp_cfg->cfg_pool, rspamd->cfg->cfg_name); /* Save some variables */ @@ -309,7 +309,8 @@ reread_config (struct rspamd_main *rspamd) if (is_debug) { rspamd->cfg->log_level = G_LOG_LEVEL_DEBUG; } - config_logger (rspamd, FALSE); + type = g_quark_try_string ("main"); + config_logger (rspamd, type, FALSE); /* Pre-init of cache */ rspamd->cfg->cache = g_new0 (struct symbols_cache, 1); rspamd->cfg->cache->static_pool = memory_pool_new (memory_pool_get_size ()); @@ -368,15 +369,9 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) cur->type = cf->type; cur->pid = fork (); cur->cf = g_malloc (sizeof (struct worker_conf)); - /* Copy or init context */ - if (cf->ctx) { - cur->ctx = cf->ctx; - } - else { - cur->ctx = init_workers_ctx (cf->type); - } memcpy (cur->cf, cf, sizeof (struct worker_conf)); cur->pending = FALSE; + cur->ctx = cf->ctx; switch (cur->pid) { case 0: /* Update pid for logging */ @@ -385,45 +380,10 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) drop_priv (rspamd); /* Set limits */ set_worker_limits (cf); - switch (cf->type) { - case TYPE_CONTROLLER: - setproctitle ("controller process"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting controller process %P", getpid ()); - start_controller (cur); - break; - case TYPE_LMTP: - setproctitle ("lmtp process"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting lmtp process %P", getpid ()); - start_lmtp_worker (cur); - break; - case TYPE_SMTP: - setproctitle ("smtp process"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting smtp process %P", getpid ()); - start_smtp_worker (cur); - break; - case TYPE_FUZZY: - setproctitle ("fuzzy storage"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting fuzzy storage process %P", getpid ()); - start_fuzzy_storage (cur); - break; - case TYPE_KVSTORAGE: - setproctitle ("kv storage"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting key-value storage process %P", getpid ()); - start_kvstorage_worker (cur); - break; - case TYPE_WORKER: - default: - setproctitle ("worker process"); - rspamd_pidfile_close (rspamd->pfh); - msg_info ("starting worker process %P", getpid ()); - start_worker (cur); - break; - } + setproctitle ("%s process", cf->worker->name); + rspamd_pidfile_close (rspamd->pfh); + msg_info ("starting %s process %P", cf->worker->name, getpid ()); + cf->worker->worker_start_func (cur); break; case -1: msg_err ("cannot fork main process. %s", strerror (errno)); @@ -584,7 +544,7 @@ spawn_workers (struct rspamd_main *rspamd) while (cur) { cf = cur->data; - if (cf->has_socket) { + if (cf->worker->has_socket) { if ((p = g_hash_table_lookup (listen_sockets, GINT_TO_POINTER ( make_listen_key (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host)))) == NULL) { /* Create listen socket */ @@ -603,13 +563,13 @@ spawn_workers (struct rspamd_main *rspamd) cf->listen_sock = listen_sock; } - if (cf->type == TYPE_FUZZY) { + if (cf->worker->unique) { if (cf->count > 1) { - msg_err ("cannot spawn more than 1 fuzzy storage worker, so spawn one"); + msg_err ("cannot spawn more than 1 %s worker, so spawn one", cf->worker->name); } fork_worker (rspamd, cf); } - else if (cf->type == TYPE_KVSTORAGE) { + else if (cf->worker->threaded) { fork_worker (rspamd, cf); } else { @@ -646,19 +606,19 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused) if (waitpid (w->pid, &res, 0) == -1) { if (errno == EINTR) { got_alarm = 1; - if (w->type != TYPE_KVSTORAGE) { + if (w->cf->worker->killable) { msg_info ("terminate worker %P with SIGKILL", w->pid); kill (w->pid, SIGKILL); } else { - msg_info ("waiting for storages to sync"); + msg_info ("waiting for workers to sync"); wait_for_workers (key, value, unused); return TRUE; } } } - msg_info ("%s process %P terminated %s", process_to_str (w->type), w->pid, + msg_info ("%s process %P terminated %s", g_quark_to_string (w->type), w->pid, got_alarm ? "hardly" : "softly"); g_free (w->cf); g_free (w); @@ -841,24 +801,6 @@ print_symbols_cache (struct config_file *cfg) } } -gpointer -init_workers_ctx (enum process_type type) -{ - switch (type) { - case TYPE_WORKER: - return init_worker (); - case TYPE_CONTROLLER: - return init_controller (); - case TYPE_FUZZY: - return init_fuzzy_storage (); - case TYPE_SMTP: - return init_smtp_worker (); - case TYPE_KVSTORAGE: - return init_kvstorage_worker (); - default: - return NULL; - } -} gint main (gint argc, gchar **argv, gchar **env) @@ -870,6 +812,8 @@ main (gint argc, gchar **argv, gchar **env) struct filter *filt; pid_t wrk; GList *l; + worker_t **pworker; + GQuark type; #ifdef HAVE_SA_SIGINFO signals_info = g_queue_new (); @@ -893,7 +837,6 @@ main (gint argc, gchar **argv, gchar **env) memset (rspamd_main->cfg, 0, sizeof (struct config_file)); rspamd_main->cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); - rspamd_main->cfg->modules_num = MODULES_NUM; init_defaults (rspamd_main->cfg); memset (&signals, 0, sizeof (struct sigaction)); @@ -910,6 +853,8 @@ main (gint argc, gchar **argv, gchar **env) rspamd_main->cfg->log_level = G_LOG_LEVEL_CRITICAL; } + type = g_quark_from_static_string ("main"); + #ifdef HAVE_SETLOCALE /* Set locale setting to C locale to avoid problems in future */ setlocale (LC_ALL, "C"); @@ -919,13 +864,20 @@ main (gint argc, gchar **argv, gchar **env) #endif /* First set logger to console logger */ - rspamd_set_logger (RSPAMD_LOG_CONSOLE, TYPE_MAIN, rspamd_main); + rspamd_set_logger (RSPAMD_LOG_CONSOLE, type, rspamd_main); (void)open_log (rspamd_main->logger); g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); detect_priv (rspamd_main); init_lua (rspamd_main->cfg); + pworker = &workers[0]; + while (*pworker) { + /* Init string quarks */ + (void)g_quark_from_static_string ((*pworker)->name); + pworker ++; + } + /* Init counters */ counters = rspamd_hash_new_shared (rspamd_main->server_pool, g_str_hash, g_str_equal, 64); /* Init listen sockets hash */ @@ -998,7 +950,7 @@ main (gint argc, gchar **argv, gchar **env) rlim.rlim_cur = 100 * 1024 * 1024; setrlimit (RLIMIT_STACK, &rlim); - config_logger (rspamd_main, TRUE); + config_logger (rspamd_main, type, TRUE); msg_info ("rspamd " RVERSION " is starting, build id: " RID); rspamd_main->cfg->cfg_name = memory_pool_strdup (rspamd_main->cfg->cfg_pool, rspamd_main->cfg->cfg_name); @@ -1011,7 +963,7 @@ main (gint argc, gchar **argv, gchar **env) /* Write info */ rspamd_main->pid = getpid (); - rspamd_main->type = TYPE_MAIN; + rspamd_main->type = type; init_signals (&signals, sig_handler); @@ -1098,14 +1050,14 @@ main (gint argc, gchar **argv, gchar **env) if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { /* Normal worker termination, do not fork one more */ - msg_info ("%s process %P terminated normally", process_to_str (cur->type), cur->pid); + msg_info ("%s process %P terminated normally", g_quark_to_string (cur->type), cur->pid); } else { if (WIFSIGNALED (res)) { - msg_warn ("%s process %P terminated abnormally by signal: %d", process_to_str (cur->type), cur->pid, WTERMSIG (res)); + msg_warn ("%s process %P terminated abnormally by signal: %d", g_quark_to_string (cur->type), cur->pid, WTERMSIG (res)); } else { - msg_warn ("%s process %P terminated abnormally", process_to_str (cur->type), cur->pid); + msg_warn ("%s process %P terminated abnormally", g_quark_to_string (cur->type), cur->pid); } /* Fork another worker in replace of dead one */ delay_fork (cur->cf); diff --git a/src/main.h b/src/main.h index ada9d97e4..63a94b462 100644 --- a/src/main.h +++ b/src/main.h @@ -49,7 +49,7 @@ struct rspamd_worker { gboolean is_dying; /**< if worker is going to shutdown */ gboolean pending; /**< if worker is pending to run */ struct rspamd_main *srv; /**< pointer to server structure */ - enum process_type type; /**< process type */ + GQuark type; /**< process type */ struct event sig_ev_usr1; /**< signals event */ struct event sig_ev_usr2; /**< signals event */ struct event bind_ev; /**< socket events */ @@ -57,6 +57,10 @@ struct rspamd_worker { gpointer ctx; /**< worker's specific data */ }; +/** + * Module + */ + struct pidfh; struct config_file; struct tokenizer; @@ -88,8 +92,8 @@ struct rspamd_main { struct config_file *cfg; /**< pointer to config structure */ pid_t pid; /**< main pid */ /* Pid file structure */ - rspamd_pidfh_t *pfh; /**< struct pidfh for pidfile */ - enum process_type type; /**< process type */ + rspamd_pidfh_t *pfh; /**< struct pidfh for pidfile */ + GQuark type; /**< process type */ guint ev_initialized; /**< is event system is initialized */ struct rspamd_stat *stat; /**< pointer to statistics */ @@ -262,22 +266,11 @@ struct c_module { struct module_ctx *ctx; /**< pointer to context */ }; -/* Workers' initialization and start functions */ -gpointer init_worker (void); -void start_worker (struct rspamd_worker *worker); -gpointer init_controller (void); -void start_controller (struct rspamd_worker *worker); - /** * Register custom controller function */ void register_custom_controller_command (const gchar *name, controller_func_t handler, gboolean privilleged, gboolean require_message); -/** - * Initialize context for worker of specified type - */ -gpointer init_workers_ctx (enum process_type type); - /** * If set, reopen log file on next write */ diff --git a/src/plugins/chartable.c b/src/plugins/chartable.c index 6458b3e2d..87b419076 100644 --- a/src/plugins/chartable.c +++ b/src/plugins/chartable.c @@ -42,6 +42,18 @@ #define DEFAULT_SYMBOL "R_CHARSET_MIXED" #define DEFAULT_THRESHOLD 0.1 +/* Initialization */ +gint chartable_module_init (struct config_file *cfg, struct module_ctx **ctx); +gint chartable_module_config (struct config_file *cfg); +gint chartable_module_reconfig (struct config_file *cfg); + +module_t chartable_module = { + "chartable", + chartable_module_init, + chartable_module_config, + chartable_module_reconfig +}; + struct chartable_ctx { gint (*filter) (struct worker_task * task); gchar *symbol; diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index f7191117b..ef88cab6b 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -126,6 +126,18 @@ static void fuzzy_symbol_callback (struct worker_task *task, static void fuzzy_add_handler (gchar **args, struct controller_session *session); static void fuzzy_delete_handler (gchar **args, struct controller_session *session); +/* Initialization */ +gint fuzzy_check_module_init (struct config_file *cfg, struct module_ctx **ctx); +gint fuzzy_check_module_config (struct config_file *cfg); +gint fuzzy_check_module_reconfig (struct config_file *cfg); + +module_t fuzzy_check_module = { + "fuzzy_check", + fuzzy_check_module_init, + fuzzy_check_module_config, + fuzzy_check_module_reconfig +}; + /* Flags string is in format ::weight[, ::weight...] */ static void parse_flags_string (struct config_file *cfg, gchar *str) diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 77c67015c..ea1841969 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -91,6 +91,18 @@ static gboolean rspamd_check_smtp_data (struct worker_task *task static gboolean rspamd_regexp_occurs_number (struct worker_task *task, GList * args, void *unused); static void process_regexp_item (struct worker_task *task, void *user_data); +/* Initialization */ +gint regexp_module_init (struct config_file *cfg, struct module_ctx **ctx); +gint regexp_module_config (struct config_file *cfg); +gint regexp_module_reconfig (struct config_file *cfg); + +module_t regexp_module = { + "regexp", + regexp_module_init, + regexp_module_config, + regexp_module_reconfig +}; + static gint luaopen_regexp (lua_State * L) { diff --git a/src/plugins/spf.c b/src/plugins/spf.c index 12ec80e67..093c57703 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -67,6 +67,18 @@ static void spf_symbol_callback (struct worker_task *task, voi static GList * spf_record_copy (GList *addrs); static void spf_record_destroy (gpointer list); +/* Initialization */ +gint spf_module_init (struct config_file *cfg, struct module_ctx **ctx); +gint spf_module_config (struct config_file *cfg); +gint spf_module_reconfig (struct config_file *cfg); + +module_t spf_module = { + "spf", + spf_module_init, + spf_module_config, + spf_module_reconfig +}; + gint spf_module_init (struct config_file *cfg, struct module_ctx **ctx) { diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index fe0c1d6de..2482dc589 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -75,6 +75,18 @@ surbl_error_quark (void) return g_quark_from_static_string ("surbl-error-quark"); } +/* Initialization */ +gint surbl_module_init (struct config_file *cfg, struct module_ctx **ctx); +gint surbl_module_config (struct config_file *cfg); +gint surbl_module_reconfig (struct config_file *cfg); + +module_t surbl_module = { + "surbl", + surbl_module_init, + surbl_module_config, + surbl_module_reconfig +}; + static void exception_insert (gpointer st, gconstpointer key, gpointer value) { diff --git a/src/smtp.c b/src/smtp.c index cc0e93391..2b5236cc6 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -52,6 +52,19 @@ static gboolean smtp_write_socket (void *arg); static sig_atomic_t wanna_die = 0; +/* Init functions */ +gpointer init_smtp (); +void start_smtp (struct rspamd_worker *worker); + +worker_t smtp_worker = { + "smtp", /* Name */ + init_smtp, /* Init function */ + start_smtp, /* Start function */ + TRUE, /* Has socket */ + FALSE, /* Non unique */ + FALSE, /* Non threaded */ + TRUE /* Killable */ +}; #ifndef HAVE_SA_SIGINFO static void @@ -907,9 +920,12 @@ make_capabilities (struct smtp_worker_ctx *ctx, const gchar *line) } gpointer -init_smtp_worker (void) +init_smtp (void) { - struct smtp_worker_ctx *ctx; + struct smtp_worker_ctx *ctx; + GQuark type; + + type = g_quark_try_string ("smtp"); ctx = g_malloc0 (sizeof (struct smtp_worker_ctx)); ctx->pool = memory_pool_new (memory_pool_get_size ()); @@ -922,25 +938,25 @@ init_smtp_worker (void) ctx->max_errors = DEFAULT_MAX_ERRORS; ctx->reject_message = DEFAULT_REJECT_MESSAGE; - register_worker_opt (TYPE_SMTP, "upstreams", xml_handle_string, ctx, + register_worker_opt (type, "upstreams", xml_handle_string, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, upstreams_str)); - register_worker_opt (TYPE_SMTP, "banner", xml_handle_string, ctx, + register_worker_opt (type, "banner", xml_handle_string, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_banner_str)); - register_worker_opt (TYPE_SMTP, "timeout", xml_handle_seconds, ctx, + register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_timeout_raw)); - register_worker_opt (TYPE_SMTP, "delay", xml_handle_seconds, ctx, + register_worker_opt (type, "delay", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_delay)); - register_worker_opt (TYPE_SMTP, "jitter", xml_handle_seconds, ctx, + register_worker_opt (type, "jitter", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, delay_jitter)); - register_worker_opt (TYPE_SMTP, "capabilities", xml_handle_string, ctx, + register_worker_opt (type, "capabilities", xml_handle_string, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, smtp_capabilities_str)); - register_worker_opt (TYPE_SMTP, "xclient", xml_handle_boolean, ctx, + register_worker_opt (type, "xclient", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, use_xclient)); - register_worker_opt (TYPE_SMTP, "reject_message", xml_handle_string, ctx, + register_worker_opt (type, "reject_message", xml_handle_string, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, reject_message)); - register_worker_opt (TYPE_SMTP, "max_errors", xml_handle_uint32, ctx, + register_worker_opt (type, "max_errors", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, max_errors)); - register_worker_opt (TYPE_SMTP, "max_size", xml_handle_size, ctx, + register_worker_opt (type, "max_size", xml_handle_size, ctx, G_STRUCT_OFFSET (struct smtp_worker_ctx, max_size)); return ctx; @@ -984,7 +1000,7 @@ config_smtp_worker (struct rspamd_worker *worker) * Start worker process */ void -start_smtp_worker (struct rspamd_worker *worker) +start_smtp (struct rspamd_worker *worker) { struct sigaction signals; struct smtp_worker_ctx *ctx = worker->ctx; diff --git a/src/smtp.h b/src/smtp.h index 00d8c3abf..d2c14f924 100644 --- a/src/smtp.h +++ b/src/smtp.h @@ -121,16 +121,6 @@ struct smtp_filter { gpointer filter_data; }; -/* - * Perform initialization of SMTP worker - */ -gpointer init_smtp_worker (void); - -/* - * Start SMTP worker - */ -void start_smtp_worker (struct rspamd_worker *worker); - /* * Register new SMTP filter * XXX: work is still in progress diff --git a/src/util.c b/src/util.c index 23203255b..5fcf0858b 100644 --- a/src/util.c +++ b/src/util.c @@ -1161,57 +1161,6 @@ rspamd_strlcpy (gchar *dst, const gchar *src, gsize siz) return (s - src - 1); /* count does not include NUL */ } -/* Convert process type to its name */ -const gchar * -process_to_str (enum process_type type) -{ - switch (type) { - case TYPE_MAIN: - return "main"; - case TYPE_WORKER: - return "worker"; - case TYPE_FUZZY: - return "fuzzy"; - case TYPE_CONTROLLER: - return "controller"; - case TYPE_LMTP: - return "lmtp"; - case TYPE_SMTP: - return "smtp"; - case TYPE_KVSTORAGE: - return "keystorage"; - default: - return "unknown"; - } - - return NULL; -} -/* Convert string to process type */ -enum process_type -str_to_process (const gchar *str) -{ - if (g_ascii_strcasecmp (str, "main") == 0) { - return TYPE_MAIN; - } - else if (g_ascii_strcasecmp (str, "worker") == 0) { - return TYPE_WORKER; - } - else if (g_ascii_strcasecmp (str, "fuzzy") == 0) { - return TYPE_FUZZY; - } - else if (g_ascii_strcasecmp (str, "controller") == 0) { - return TYPE_CONTROLLER; - } - else if (g_ascii_strcasecmp (str, "smtp") == 0) { - return TYPE_SMTP; - } - else if (g_ascii_strcasecmp (str, "lmtp") == 0) { - return TYPE_LMTP; - } - - return TYPE_UNKNOWN; -} - /* Compare two emails for building emails tree */ gint compare_email_func (gconstpointer a, gconstpointer b) @@ -1396,6 +1345,29 @@ rspamd_fallocate (gint fd, off_t offset, off_t len) #endif } + +/** + * Return worker's control structure by its type + * @param type + * @return worker's control structure or NULL + */ +worker_t* +get_worker_by_type (GQuark type) +{ + worker_t **cur; + + cur = &workers[0]; + while (*cur) { + if (g_quark_from_string ((*cur)->name) == type) { + return *cur; + } + cur ++; + } + + return NULL; +} + + /* * vi:ts=4 */ diff --git a/src/util.h b/src/util.h index c4fcc80f4..e520c9d2d 100644 --- a/src/util.h +++ b/src/util.h @@ -14,21 +14,6 @@ struct workq; struct statfile; struct classifier_config; -/** - * Process type: main or worker - */ -enum process_type { - TYPE_UNKNOWN=-1, - TYPE_MAIN, - TYPE_WORKER, - TYPE_CONTROLLER, - TYPE_LMTP, - TYPE_SMTP, - TYPE_FUZZY, - TYPE_KVSTORAGE, - TYPE_MAX=255 -}; - /* * Create socket and bind or connect it to specified address and port */ @@ -194,21 +179,6 @@ void g_queue_clear (GQueue *queue); */ gsize rspamd_strlcpy (gchar *dst, const gchar *src, gsize siz); -/* - * Convert process type to its name - * - * @param type numeric type - * @return string representation of type - */ -const gchar * process_to_str (enum process_type type); -/* - * Convert string to process type - * - * @param type numeric type - * @return string representation of type - */ -enum process_type str_to_process (const gchar *str); - /* * Strip <> from email address */ @@ -250,4 +220,11 @@ gboolean rspamd_strtoul (const gchar *s, gsize len, gulong *value); */ gint rspamd_fallocate (gint fd, off_t offset, off_t len); +/** + * Return worker's control structure by its type + * @param type + * @return worker's control structure or NULL + */ +worker_t* get_worker_by_type (GQuark type); + #endif diff --git a/src/worker.c b/src/worker.c index 151045c19..48f4d1936 100644 --- a/src/worker.c +++ b/src/worker.c @@ -34,7 +34,6 @@ #include "cfg_file.h" #include "cfg_xml.h" #include "url.h" -#include "modules.h" #include "message.h" #include "map.h" #include "dns.h" @@ -48,6 +47,19 @@ /* 60 seconds for worker's IO */ #define DEFAULT_WORKER_IO_TIMEOUT 60000 +gpointer init_worker (void); +void start_worker (struct rspamd_worker *worker); + +worker_t normal_worker = { + "normal", /* Name */ + init_worker, /* Init function */ + start_worker, /* Start function */ + TRUE, /* Has socket */ + FALSE, /* Non unique */ + FALSE, /* Non threaded */ + TRUE /* Killable */ +}; + #ifndef BUILD_STATIC #define MODULE_INIT_FUNC "module_init" @@ -822,18 +834,21 @@ gpointer init_worker (void) { struct rspamd_worker_ctx *ctx; + GQuark type; + + type = g_quark_try_string ("normal"); ctx = g_malloc0 (sizeof (struct rspamd_worker_ctx)); ctx->is_mime = TRUE; ctx->timeout = DEFAULT_WORKER_IO_TIMEOUT; - register_worker_opt (TYPE_WORKER, "mime", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_mime)); - register_worker_opt (TYPE_WORKER, "http", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_http)); - register_worker_opt (TYPE_WORKER, "json", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_json)); - register_worker_opt (TYPE_WORKER, "allow_learn", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, allow_learn)); - register_worker_opt (TYPE_WORKER, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, timeout)); - register_worker_opt (TYPE_WORKER, "max_tasks", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, max_tasks)); + register_worker_opt (type, "mime", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_mime)); + register_worker_opt (type, "http", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_http)); + register_worker_opt (type, "json", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, is_json)); + register_worker_opt (type, "allow_learn", xml_handle_boolean, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, allow_learn)); + register_worker_opt (type, "timeout", xml_handle_seconds, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, timeout)); + register_worker_opt (type, "max_tasks", xml_handle_uint32, ctx, G_STRUCT_OFFSET (struct rspamd_worker_ctx, max_tasks)); return ctx; } -- 2.39.5