From: Otto Moerbeek Date: Thu, 24 Oct 2024 08:30:48 +0000 (+0200) Subject: Reorganize a few things, add a Lua hook that's called on startup and (nice) shutdown X-Git-Tag: rec-5.2.0-alpha1~12^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a94852964d1b45ae3e380c813957df8a9fa88fb;p=thirdparty%2Fpdns.git Reorganize a few things, add a Lua hook that's called on startup and (nice) shutdown --- diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index 31323801ab..a95f8e05af 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -271,7 +271,8 @@ void BaseLua4::prepareContext() { }); d_lw->registerFunction("changeContent", [](DNSRecord& dr, const std::string& newContent) { dr.setContent(shared_ptr(DNSRecordContent::make(dr.d_type, 1, newContent))); }); - // pdnsload + // pdnslog +#ifdef RECURSOR d_lw->writeFunction("pdnslog", [](const std::string& msg, boost::optional loglevel, boost::optional> values) { auto log = g_slog->withName("lua"); if (values) { @@ -280,6 +281,10 @@ void BaseLua4::prepareContext() { } } log->info(static_cast(loglevel.get_value_or(Logr::Warning)), msg); +#else + d_lw->writeFunction("pdnslog", [](const std::string& msg, boost::optional loglevel) { + g_log << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<writeFunction("pdnsrandom", [](boost::optional maximum) { diff --git a/pdns/recursordist/docs/lua-scripting/functions.rst b/pdns/recursordist/docs/lua-scripting/functions.rst index 58f9a49379..af1ad09e44 100644 --- a/pdns/recursordist/docs/lua-scripting/functions.rst +++ b/pdns/recursordist/docs/lua-scripting/functions.rst @@ -30,6 +30,9 @@ These are some functions that don't really have a place in one of the other cate :param str script: The pathname of the Lua script to run. +.. note:: + The :func:`putIntoRecordCache` and :func:`getRecordCacheRecords` functions are experimental, their functionality might change in upcoming releases. + .. function:: putIntoRecordCache(dump) -> int .. versionadded:: 5.2.0 @@ -42,18 +45,19 @@ These are some functions that don't really have a place in one of the other cate Some records might be skipped, for example when they are already present in the record cache or contain specific information not supported yet by this function. If the :program:`Recursor` determines the version of the data is not compatible, it will skip loading and log an error. -.. function:: getRecordCacheRecords(perShard, maxSize) ->str +.. function:: getRecordCacheRecords(perShard, maxSize) -> str, int .. versionadded:: 5.2.0 Get a record cache dump in proprietary format. - :param int perShard: The maximum number of records to produce per shard. + :param int perShard: The maximum number of records to retrieve per shard. :param int maxSize: The maximum size of the dump. - :return: A string representing the records. + :return: A string representing the records and an integer specifying how many records were retrieved This function will scan the most recently used records of each shard, picking at most ``perShard`` records per shard and adding them to the result. If adding a record's data to the result would make the result size exceed ``maxSize``, the remainder of the current shard and further remaining shards are skipped. The format of the string produced is proprietary. The string contains meta information, so the :program:`Recursor` calling :func:`putIntoRecordCache` can check if the data format is compatible. + diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index b89d9ae3b6..2b4b5887cd 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -496,8 +496,8 @@ void RecursorLua4::postPrepareContext() // NOLINT(readability-function-cognitive d_lw->writeFunction("getRecordCacheRecords", [](size_t perShard, size_t maxSize) { std::string ret; - g_recCache->getRecords(perShard, maxSize, ret); - return ret; + auto number = g_recCache->getRecords(perShard, maxSize, ret); + return std::tuple{ret, number}; }); d_lw->writeFunction("putIntoRecordCache", [](const string& data) { @@ -505,8 +505,8 @@ void RecursorLua4::postPrepareContext() // NOLINT(readability-function-cognitive }); d_lw->writeFunction("spawnThread", [](const string& scriptName) { - auto log = g_slog->withName("lua")->withValues("name", Logging::Loggable(scriptName)); - log->info(Logr::Info, "Starting Lua thread"); + auto log = g_slog->withName("lua")->withValues("script", Logging::Loggable(scriptName)); + log->info(Logr::Info, "Starting Lua script in separate thread"); std::thread thread([=]() { auto lua = std::make_shared(); lua->loadFile(scriptName); @@ -550,6 +550,22 @@ void RecursorLua4::getFeatures(Features& features) features.emplace_back("PR8001_devicename", true); } +void RecursorLua4::runStartStopFunction(const string& script, bool start, Logr::log_t log) +{ + const string func = start ? "on_recursor_start" : "on_recursor_stop"; + auto mylog = log->withValues("script", Logging::Loggable(script), "function", Logging::Loggable(func)); + loadFile(script); + auto call = d_lw->readVariable>>(func).get_value_or(nullptr); + if (call) { + mylog->info(Logr::Info, "Starting Lua function"); + call(); + mylog->info(Logr::Info, "Lua function done"); + } + else { + mylog->info(Logr::Info, "No Lua function found"); + } +} + static void warnDrop(const RecursorLua4::DNSQuestion& dnsQuestion) { if (dnsQuestion.rcode == -2) { diff --git a/pdns/recursordist/lua-recursor4.hh b/pdns/recursordist/lua-recursor4.hh index 1a758abb5d..375a3b9fe0 100644 --- a/pdns/recursordist/lua-recursor4.hh +++ b/pdns/recursordist/lua-recursor4.hh @@ -224,6 +224,8 @@ public: bool policyHitEventFilter(const ComboAddress& remote, const DNSName& qname, const QType& qtype, bool tcp, DNSFilterEngine::Policy& policy, std::unordered_set& tags, std::unordered_map& discardedPolicies) const; + void runStartStopFunction(const std::string& script, bool start, Logr::log_t log); + [[nodiscard]] bool needDQ() const { return (d_prerpz || d_preresolve || d_nxdomain || d_nodata || d_postresolve); diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index a638ef8ea0..935c2e89aa 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -147,7 +147,7 @@ thread_local unsigned int RecThreadInfo::t_id; pdns::RateLimitedLog g_rateLimitedLogger; -static void runCustomLua(Logr::log_t log); +static void runStartStopLua(bool start, Logr::log_t log); static std::map> parseCPUMap(Logr::log_t log) { @@ -356,6 +356,7 @@ int RecThreadInfo::runThreads(Logr::log_t log) ret = tInfo.exitCode; } } + runStartStopLua(false, log); } return ret; } @@ -2378,8 +2379,8 @@ static int serviceMain(Logr::log_t log) setupNODThread(log); #endif /* NOD_ENABLED */ - runCustomLua(log); - + runStartStopLua(true, log); + return RecThreadInfo::runThreads(log); } @@ -3041,20 +3042,15 @@ static pair doConfig(Logr::log_t startupLog, const string& configname LockGuarded g_yamlStruct; -static void runCustomLua(Logr::log_t log) +static void runStartStopLua(bool start, Logr::log_t log) { auto settings = g_yamlStruct.lock(); - const auto& script = settings->recursor.lua_startup_script; + const auto& script = settings->recursor.lua_start_stop_script; if (script.empty()) { return; } - log->info(Logr::Info, "Starting Custom Lua", "script", Logging::Loggable(script)); - //std::thread thread([=]() { - auto lua = std::make_shared(); - lua->loadFile(std::string(script)); - log->info(Logr::Info, "Custom Lua done"); - //}); - //thread.detach(); + auto lua = std::make_shared(); + lua->runStartStopFunction(std::string(script), start, log); } static void handleRuntimeDefaults(Logr::log_t log) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index d3c05c2213..fb9dc700ad 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -1047,7 +1047,7 @@ void MemRecursorCache::getRecord(T& message, U recordSet) message.add_bool(PBCacheEntry::required_bool_tooBig, recordSet->d_tooBig); } -void MemRecursorCache::getRecords(size_t perShard, size_t maxSize, std::string& ret) +size_t MemRecursorCache::getRecords(size_t perShard, size_t maxSize, std::string& ret) { auto log = g_slog->withName("recordcache")->withValues("perShard", Logging::Loggable(perShard), "maxSize", Logging::Loggable(maxSize)); log->info(Logr::Info, "Producing cache dump"); @@ -1072,7 +1072,7 @@ void MemRecursorCache::getRecords(size_t perShard, size_t maxSize, std::string& if (ret.size() > maxSize) { message.rollback(); log->info(Logr::Info, "Produced cache dump (max size reached)", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); - return; + return count; } ++count; ++thisShardCount; @@ -1082,8 +1082,7 @@ void MemRecursorCache::getRecords(size_t perShard, size_t maxSize, std::string& } } log->info(Logr::Info, "Produced cache dump", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count)); - std::ofstream out("/tmp/pb"); - out.write(ret.data(), ret.size()); + return count; } template diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index d9f3a94ddf..50c637afdf 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -63,7 +63,7 @@ public: [[nodiscard]] pair stats(); [[nodiscard]] size_t ecsIndexSize(); - void getRecords(size_t howmany, size_t maxsize, std::string& ret); + size_t getRecords(size_t howmany, size_t maxsize, std::string& ret); size_t putRecords(const std::string& pbuf); using OptTag = boost::optional; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index cebd18355f..999d5b7967 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -3511,13 +3511,13 @@ Sequence of ProxyMapping 'versionadded': '5.1.0', }, { - 'name' : 'lua_startup_script', + 'name' : 'lua_start_stop_script', 'section' : 'recursor', 'type' : LType.String, 'default' : '', - 'help' : 'Custom Lua script to run on startup', + 'help' : 'Lua script containing functions to run on startup and shutdown', 'doc' : ''' -Run this Lua script on startup in a separate thread. +Load this Lua script on startup and shutdown and run the Lua function ``on_recursor_start`` on startup and the Lua function ``on_recursor_stop`` on a ``nice`` shutdown (using ``rec_control quit-nicely`` of the :program:`Recursor` process. ''', 'skip-old' : 'No equivalent old-style setting', 'versionadded': '5.2.0',