From: Vsevolod Stakhov Date: Sun, 23 Oct 2022 17:37:34 +0000 (+0100) Subject: [Project] Synchronize hyperscan caches via the main process X-Git-Tag: 3.4~28 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=63c6d3080d531e7eb4bf32ac985408dbd0513c6b;p=rspamd.git [Project] Synchronize hyperscan caches via the main process --- diff --git a/src/libserver/hyperscan_tools.cxx b/src/libserver/hyperscan_tools.cxx index 4f3ac013a..3383915c3 100644 --- a/src/libserver/hyperscan_tools.cxx +++ b/src/libserver/hyperscan_tools.cxx @@ -31,6 +31,7 @@ #include /* for unlink */ #include #include "unix-std.h" +#include "rspamd_control.h" #define msg_info_hyperscan(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \ "hyperscan", "", \ @@ -66,7 +67,8 @@ private: virtual ~hs_known_files_cache() { // Cleanup cache dir - if (rspamd_current_worker != nullptr && rspamd_worker_is_primary_controller(rspamd_current_worker)) { + /* We clean dir merely if we are running from the main process */ + if (rspamd_current_worker == nullptr) { auto cleanup_dir = [&](std::string_view dir) -> void { for (const auto &ext : cache_extensions) { glob_t globbuf; @@ -423,6 +425,23 @@ void rspamd_hyperscan_notice_known(const char *fname) { rspamd::util::hs_known_files_cache::get().add_cached_file(fname); + + if (rspamd_current_worker != nullptr) { + /* Also notify main process */ + struct rspamd_srv_command notice_cmd; + + if (strlen(fname) >= sizeof(notice_cmd.cmd.hyperscan_cache_file.path)) { + msg_err("internal error: length of the filename %d ('%s') is larger than control buffer path: %d", + (int)strlen(fname), fname, (int)sizeof(notice_cmd.cmd.hyperscan_cache_file.path)); + } + else { + notice_cmd.type = RSPAMD_NOTICE_HYPERSCAN_CACHE; + rspamd_srv_send_command(rspamd_current_worker, + rspamd_current_worker->srv->event_loop, ¬ice_cmd, -1, + nullptr, + nullptr); + } + } } #endif // WITH_HYPERSCAN \ No newline at end of file diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c index 199efa948..63999ab6f 100644 --- a/src/libserver/rspamd_control.c +++ b/src/libserver/rspamd_control.c @@ -27,6 +27,10 @@ #include #endif +#ifdef WITH_HYPERSCAN +#include "hyperscan_tools.h" +#endif + static ev_tstamp io_timeout = 30.0; static ev_tstamp worker_io_timeout = 0.5; @@ -1014,6 +1018,12 @@ rspamd_srv_handler (EV_P_ ev_io *w, int revents) case RSPAMD_SRV_HEALTH: rspamd_fill_health_reply (srv, &rdata->rep); break; + case RSPAMD_NOTICE_HYPERSCAN_CACHE: +#ifdef WITH_HYPERSCAN + rspamd_hyperscan_notice_known(cmd.cmd.hyperscan_cache_file.path); +#endif + rdata->rep.reply.hyperscan_cache_file.unused = 0; + break; default: msg_err ("unknown command type: %d", cmd.type); break; diff --git a/src/libserver/rspamd_control.h b/src/libserver/rspamd_control.h index 1c0f593e3..dff48927d 100644 --- a/src/libserver/rspamd_control.h +++ b/src/libserver/rspamd_control.h @@ -47,12 +47,13 @@ enum rspamd_srv_type { RSPAMD_SRV_ON_FORK, RSPAMD_SRV_HEARTBEAT, RSPAMD_SRV_HEALTH, + RSPAMD_NOTICE_HYPERSCAN_CACHE, }; enum rspamd_log_pipe_type { RSPAMD_LOG_PIPE_SYMBOLS = 0, }; -#define CONTROL_PATHLEN MIN(PATH_MAX, PIPE_BUF - sizeof(int) * 2) +#define CONTROL_PATHLEN MIN(PATH_MAX, PIPE_BUF - sizeof(int) * 2 - sizeof(gint64)) struct rspamd_control_command { enum rspamd_control_type type; union { @@ -174,6 +175,10 @@ struct rspamd_srv_command { struct { guint status; } health; + /* Used when a worker loads a valid hyperscan file */ + struct { + char path[CONTROL_PATHLEN]; + } hyperscan_cache_file; } cmd; }; @@ -205,6 +210,9 @@ struct rspamd_srv_reply { guint scanners_count; guint workers_hb_lost; } health; + struct { + int unused; + } hyperscan_cache_file; } reply; };