From 343b2a55b1692401194662ab3fe9b9290f0a6b97 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 21 Apr 2021 14:20:52 +0200 Subject: [PATCH] dnsdist: Make the backend queryLoad and dropRate values atomic So that there is no race when these vaues are read by the SNMP or web threads and updated by the health check thread at the same time. Reported by Thread Sanitizer: WARNING: ThreadSanitizer: data race (pid=11167) Write of size 8 at 0x7b7400002558 by thread T18: #0 healthChecksThread() /opt/project/pdns/dnsdistdist/dnsdist.cc:1712:22 (dnsdist+0xf2a4a2) #1 void std::__invoke_impl(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:60:14 (dnsdist+0xf40ea2) #2 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:95:14 (dnsdist+0xf40e0d) #3 decltype(std::__invoke(_S_declval<0ul>())) std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:244:13 (dnsdist+0xf40dd5) #4 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:253:11 (dnsdist+0xf40d95) #5 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:196:13 (dnsdist+0xf40c29) #6 (libstdc++.so.6+0xbbb2e) Previous read of size 8 at 0x7b7400002558 by thread T2: #0 backendStatTable_handler(netsnmp_mib_handler_s*, netsnmp_handler_registration_s*, netsnmp_agent_request_info_s*, netsnmp_request_info_s*) /opt/project/pdns/dnsdistdist/dnsdist-snmp.cc:356:62 (dnsdist+0xeccf98) #1 netsnmp_call_next_handler (libnetsnmpagent.so.30+0x2a0cc) #2 SNMPAgent::handleSNMPQueryCB(int, boost::any&) /opt/project/pdns/dnsdistdist/snmp-agent.cc:96:13 (dnsdist+0xfb0847) #3 boost::detail::function::void_function_invoker2::invoke(boost::detail::function::function_buffer&, int, boost::any&) /usr/include/boost/function/function_template.hpp:118:11 (dnsdist+0x8937d8) #4 boost::function2::operator()(int, boost::any&) const /usr/include/boost/function/function_template.hpp:768:14 (dnsdist+0xf9d56c) #5 EpollFDMultiplexer::run(timeval*, int) /opt/project/pdns/dnsdistdist/epollmplexer.cc:176:7 (dnsdist+0xfd041b) #6 SNMPAgent::worker() /opt/project/pdns/dnsdistdist/snmp-agent.cc:141:24 (dnsdist+0xfb0b6f) #7 void std::__invoke_impl(std::__invoke_memfun_deref, void (SNMPAgent::*&&)(), SNMPAgent*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:73:14 (dnsdist+0xf344c9) #8 std::__invoke_result::type std::__invoke(void (SNMPAgent::*&&)(), SNMPAgent*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:95:14 (dnsdist+0xf343c1) #9 decltype(std::__invoke(_S_declval<0ul>(), _S_declval<1ul>())) std::thread::_Invoker >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:244:13 (dnsdist+0xf3436e) #10 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:253:11 (dnsdist+0xf34315) #11 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:196:13 (dnsdist+0xf34079) #12 (libstdc++.so.6+0xbbb2e) --- pdns/dnsdist.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index f89734d2b3..e2448fab46 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -944,8 +944,8 @@ struct DownstreamState size_t socketsOffset{0}; size_t d_maxInFlightQueriesPerConn{1}; size_t d_tcpConcurrentConnectionsLimit{0}; - double queryLoad{0.0}; - double dropRate{0.0}; + pdns::stat_t_trait queryLoad{0.0}; + pdns::stat_t_trait dropRate{0.0}; double latencyUsec{0.0}; int order{1}; int weight{1}; -- 2.47.2