From a4d37132bf36f4793bc90d167dfb34e25698c03c Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 12 Mar 2015 09:39:53 +0100 Subject: [PATCH] Implement a check for IDO database connections fixes #8688 --- doc/7-icinga-template-library.md | 13 ++- lib/db_ido/CMakeLists.txt | 10 ++- lib/db_ido/db_ido-check.conf | 26 ++++++ lib/db_ido/dbconnection.cpp | 18 ++++ lib/db_ido/dbconnection.hpp | 11 +++ lib/db_ido/dbconnection.ti | 6 ++ lib/db_ido/idochecktask.cpp | 115 ++++++++++++++++++++++++ lib/db_ido/idochecktask.hpp | 46 ++++++++++ lib/db_ido_mysql/idomysqlconnection.cpp | 45 ++++++---- lib/db_ido_mysql/idomysqlconnection.hpp | 1 - lib/db_ido_pgsql/idopgsqlconnection.cpp | 20 ++++- tools/mkembedconfig/CMakeLists.txt | 1 + 12 files changed, 284 insertions(+), 28 deletions(-) create mode 100644 lib/db_ido/db_ido-check.conf create mode 100644 lib/db_ido/idochecktask.cpp create mode 100644 lib/db_ido/idochecktask.hpp diff --git a/doc/7-icinga-template-library.md b/doc/7-icinga-template-library.md index 029842015..1fff9de11 100644 --- a/doc/7-icinga-template-library.md +++ b/doc/7-icinga-template-library.md @@ -52,12 +52,23 @@ The `cluster` check command does not support any vars. Check command for the built-in `cluster-zone` check. -Cluster Attributes: +Custom Attributes: Name | Description -------------|--------------- cluster_zone | **Optional.** The zone name. Defaults to "$host.name$". +### ido + +Check command for the built-in `ido` check. + +Custom Attributes: + +Name | Description +-------------|--------------- +ido_type | **Required.** The type of the IDO connection object. Can be either "IdoMysqlConnection" or "IdoPgsqlConnection". +ido_name | **Required.** The name of the IDO connection object. + # Plugin Check Commands The Plugin Check Commands provides example configuration for plugin check commands diff --git a/lib/db_ido/CMakeLists.txt b/lib/db_ido/CMakeLists.txt index 98c756a49..49d3e114d 100644 --- a/lib/db_ido/CMakeLists.txt +++ b/lib/db_ido/CMakeLists.txt @@ -18,13 +18,15 @@ mkclass_target(dbconnection.ti dbconnection.thpp) mkembedconfig_target(db_ido-type.conf db_ido-type.cpp) +mkembedconfig_target(db_ido-check.conf db_ido-check.cpp) set(db_ido_SOURCES commanddbobject.cpp dbconnection.cpp dbconnection.thpp dbconnection.thpp - db_ido-type.cpp dbevents.cpp dbobject.cpp dbquery.cpp dbreference.cpp dbtype.cpp - dbvalue.cpp endpointdbobject.cpp hostdbobject.cpp hostgroupdbobject.cpp - servicedbobject.cpp servicegroupdbobject.cpp timeperioddbobject.cpp - userdbobject.cpp usergroupdbobject.cpp + db_ido-type.cpp db_ido-check.cpp dbevents.cpp dbobject.cpp dbquery.cpp + dbreference.cpp dbtype.cpp dbvalue.cpp endpointdbobject.cpp hostdbobject.cpp + hostgroupdbobject.cpp idochecktask.cpp servicedbobject.cpp + servicegroupdbobject.cpp timeperioddbobject.cpp userdbobject.cpp + usergroupdbobject.cpp ) if(ICINGA2_UNITY_BUILD) diff --git a/lib/db_ido/db_ido-check.conf b/lib/db_ido/db_ido-check.conf new file mode 100644 index 000000000..5994733d9 --- /dev/null +++ b/lib/db_ido/db_ido-check.conf @@ -0,0 +1,26 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +template CheckCommand "ido-check-command" { + execute = IdoCheck +} + +object CheckCommand "ido" { + import "ido-check-command" +} diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp index 4cb73339c..2baa0175f 100644 --- a/lib/db_ido/dbconnection.cpp +++ b/lib/db_ido/dbconnection.cpp @@ -39,6 +39,10 @@ REGISTER_SCRIPTFUNCTION(ValidateFailoverTimeout, &DbConnection::ValidateFailover Timer::Ptr DbConnection::m_ProgramStatusTimer; boost::once_flag DbConnection::m_OnceFlag = BOOST_ONCE_INIT; +DbConnection::DbConnection(void) + : m_QueryStats(15 * 60) +{ } + void DbConnection::OnConfigLoaded(void) { DynamicObject::OnConfigLoaded(); @@ -443,3 +447,17 @@ void DbConnection::ValidateFailoverTimeout(const String& location, const DbConne location + ": Failover timeout minimum is 60s.", object->GetDebugInfo())); } } + +void DbConnection::IncreaseQueryCount(void) +{ + double now = Utility::GetTime(); + + boost::mutex::scoped_lock lock(m_StatsMutex); + m_QueryStats.InsertValue(now, 1); +} + +int DbConnection::GetQueryCount(RingBuffer::SizeType span) const +{ + boost::mutex::scoped_lock lock(m_StatsMutex); + return m_QueryStats.GetValues(span); +} diff --git a/lib/db_ido/dbconnection.hpp b/lib/db_ido/dbconnection.hpp index 4fefab1b7..529c45069 100644 --- a/lib/db_ido/dbconnection.hpp +++ b/lib/db_ido/dbconnection.hpp @@ -25,7 +25,9 @@ #include "db_ido/dbobject.hpp" #include "db_ido/dbquery.hpp" #include "base/timer.hpp" +#include "base/ringbuffer.hpp" #include +#include #define IDO_CURRENT_SCHEMA_VERSION "1.13.0" #define IDO_COMPAT_SCHEMA_VERSION "1.12.0" @@ -43,6 +45,8 @@ class I2_DB_IDO_API DbConnection : public ObjectImpl public: DECLARE_OBJECT(DbConnection); + DbConnection(void); + static void InitializeDbTimer(void); void SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref); @@ -67,6 +71,8 @@ public: void SetStatusUpdate(const DbObject::Ptr& dbobj, bool hasupdate); bool GetStatusUpdate(const DbObject::Ptr& dbobj) const; + int GetQueryCount(RingBuffer::SizeType span) const; + static void ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object); protected: @@ -87,6 +93,8 @@ protected: void PrepareDatabase(void); + void IncreaseQueryCount(void); + private: std::map m_ObjectIDs; std::map, DbReference> m_InsertIDs; @@ -105,6 +113,9 @@ private: static void InsertRuntimeVariable(const String& key, const Value& value); static void ProgramStatusHandler(void); + + mutable boost::mutex m_StatsMutex; + RingBuffer m_QueryStats; }; struct database_error : virtual std::exception, virtual boost::exception { }; diff --git a/lib/db_ido/dbconnection.ti b/lib/db_ido/dbconnection.ti index 5531f142b..498490e03 100644 --- a/lib/db_ido/dbconnection.ti +++ b/lib/db_ido/dbconnection.ti @@ -48,6 +48,12 @@ abstract class DbConnection : DynamicObject [config] double failover_timeout { default {{{ return 60; }}} }; + + String schema_version; + bool connected; + bool should_connect { + default {{{ return true; }}} + }; }; } diff --git a/lib/db_ido/idochecktask.cpp b/lib/db_ido/idochecktask.cpp new file mode 100644 index 000000000..5a077596c --- /dev/null +++ b/lib/db_ido/idochecktask.cpp @@ -0,0 +1,115 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "db_ido/idochecktask.hpp" +#include "icinga/host.hpp" +#include "icinga/checkcommand.hpp" +#include "icinga/macroprocessor.hpp" +#include "icinga/perfdatavalue.hpp" +#include "remote/apilistener.hpp" +#include "remote/endpoint.hpp" +#include "remote/zone.hpp" +#include "base/function.hpp" +#include "base/utility.hpp" +#include "base/dynamictype.hpp" +#include "base/convert.hpp" +#include + +using namespace icinga; + +REGISTER_SCRIPTFUNCTION(IdoCheck, &IdoCheckTask::ScriptFunc); + +void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, + const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) +{ + CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); + Value raw_command = commandObj->GetCommandLine(); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + MacroProcessor::ResolverList resolvers; + if (service) + resolvers.push_back(std::make_pair("service", service)); + resolvers.push_back(std::make_pair("host", host)); + resolvers.push_back(std::make_pair("command", commandObj)); + resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); + + String idoType = MacroProcessor::ResolveMacros("$ido_type$", resolvers, checkable->GetLastCheckResult(), + NULL, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros); + + if (resolvedMacros && !useResolvedMacros) + return; + + String idoName = MacroProcessor::ResolveMacros("$ido_name$", resolvers, checkable->GetLastCheckResult(), + NULL, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros); + + if (resolvedMacros && !useResolvedMacros) + return; + + if (idoName.IsEmpty()) { + cr->SetOutput("Macro 'ido_name' must be set."); + cr->SetState(ServiceUnknown); + checkable->ProcessCheckResult(cr); + return; + } + + Type::Ptr type = Type::GetByName(idoType); + + if (!type || !Type::GetByName("DbConnection")->IsAssignableFrom(type)) { + cr->SetOutput("IDO type '" + idoType + "' is invalid."); + cr->SetState(ServiceUnknown); + checkable->ProcessCheckResult(cr); + return; + } + + DynamicType::Ptr dtype = DynamicType::GetByName(idoType); + VERIFY(dtype); + + DbConnection::Ptr conn = static_pointer_cast(dtype->GetObject(idoName)); + + double qps = conn->GetQueryCount(60) / 60.0; + + if (!conn->GetConnected() && conn->GetShouldConnect()) { + cr->SetOutput("Could not connect to the database server."); + cr->SetState(ServiceCritical); + } else { + String schema_version = conn->GetSchemaVersion(); + + if (Utility::CompareVersion(IDO_CURRENT_SCHEMA_VERSION, schema_version) < 0) { + cr->SetOutput("Outdated schema version: " + schema_version + "; Latest version: " IDO_CURRENT_SCHEMA_VERSION); + cr->SetState(ServiceWarning); + } else { + std::ostringstream msgbuf; + msgbuf << "Connected to the database server; queries per second: " << std::fixed << std::setprecision(3) << qps; + cr->SetOutput(msgbuf.str()); + cr->SetState(ServiceOK); + } + } + + Array::Ptr perfdata = new Array(); + perfdata->Add(new PerfdataValue("queries", qps)); + perfdata->Add(new PerfdataValue("queries_1min", conn->GetQueryCount(60))); + perfdata->Add(new PerfdataValue("queries_5mins", conn->GetQueryCount(5 * 60))); + perfdata->Add(new PerfdataValue("queries_15mins", conn->GetQueryCount(15 * 60))); + cr->SetPerformanceData(perfdata); + + checkable->ProcessCheckResult(cr); +} diff --git a/lib/db_ido/idochecktask.hpp b/lib/db_ido/idochecktask.hpp new file mode 100644 index 000000000..d7f8979ba --- /dev/null +++ b/lib/db_ido/idochecktask.hpp @@ -0,0 +1,46 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef IDOCHECKTASK_H +#define IDOCHECKTASK_H + +#include "db_ido/dbconnection.hpp" +#include "icinga/checkable.hpp" + +namespace icinga +{ + +/** + * IDO check type. + * + * @ingroup db_ido + */ +class IdoCheckTask +{ +public: + static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, + const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); + +private: + IdoCheckTask(void); +}; + +} + +#endif /* IDOCHECKTASK_H */ diff --git a/lib/db_ido_mysql/idomysqlconnection.cpp b/lib/db_ido_mysql/idomysqlconnection.cpp index 2fe3797a8..e66479ba4 100644 --- a/lib/db_ido_mysql/idomysqlconnection.cpp +++ b/lib/db_ido_mysql/idomysqlconnection.cpp @@ -38,7 +38,7 @@ REGISTER_TYPE(IdoMysqlConnection); REGISTER_STATSFUNCTION(IdoMysqlConnectionStats, &IdoMysqlConnection::StatsFunc); IdoMysqlConnection::IdoMysqlConnection(void) - : m_QueryQueue(500000), m_Connected(false) + : m_QueryQueue(500000) { } void IdoMysqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) @@ -49,7 +49,7 @@ void IdoMysqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::P size_t items = idomysqlconnection->m_QueryQueue.GetLength(); Dictionary::Ptr stats = new Dictionary(); - stats->Set("version", IDO_CURRENT_SCHEMA_VERSION); + stats->Set("version", idomysqlconnection->GetSchemaVersion()); stats->Set("instance_name", idomysqlconnection->GetInstanceName()); stats->Set("query_queue_items", items); @@ -65,7 +65,7 @@ void IdoMysqlConnection::Resume(void) { DbConnection::Resume(); - m_Connected = false; + SetConnected(false); m_QueryQueue.SetExceptionCallback(boost::bind(&IdoMysqlConnection::ExceptionHandler, this, _1)); @@ -102,10 +102,10 @@ void IdoMysqlConnection::ExceptionHandler(boost::exception_ptr exp) boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (m_Connected) { + if (GetConnected()) { mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); } } @@ -120,13 +120,13 @@ void IdoMysqlConnection::Disconnect(void) boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (!m_Connected) + if (!GetConnected()) return; Query("COMMIT"); mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); } void IdoMysqlConnection::TxTimerHandler(void) @@ -143,7 +143,7 @@ void IdoMysqlConnection::InternalNewTransaction(void) { boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (!m_Connected) + if (!GetConnected()) return; Query("COMMIT"); @@ -161,6 +161,8 @@ void IdoMysqlConnection::Reconnect(void) CONTEXT("Reconnecting to MySQL IDO database '" + GetName() + "'"); + SetShouldConnect(true); + std::vector active_dbobjs; { @@ -168,13 +170,13 @@ void IdoMysqlConnection::Reconnect(void) bool reconnect = false; - if (m_Connected) { + if (GetConnected()) { /* Check if we're really still connected */ if (mysql_ping(&m_Connection) == 0) return; mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); reconnect = true; } @@ -213,7 +215,7 @@ void IdoMysqlConnection::Reconnect(void) BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection))); } - m_Connected = true; + SetConnected(true); String dbVersionName = "idoutils"; IdoMysqlResult result = Query("SELECT version FROM " + GetTablePrefix() + "dbversion WHERE name='" + Escape(dbVersionName) + "'"); @@ -222,7 +224,7 @@ void IdoMysqlConnection::Reconnect(void) if (!row) { mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); Log(LogCritical, "IdoMysqlConnection", "Schema does not provide any valid version! Verify your schema installation."); @@ -234,9 +236,11 @@ void IdoMysqlConnection::Reconnect(void) String version = row->Get("version"); + SetSchemaVersion(version); + if (Utility::CompareVersion(IDO_COMPAT_SCHEMA_VERSION, version) < 0) { mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); Log(LogCritical, "IdoMysqlConnection") << "Schema version '" << version << "' does not match the required version '" @@ -293,7 +297,8 @@ void IdoMysqlConnection::Reconnect(void) if (status_update_age < GetFailoverTimeout()) { mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); + SetShouldConnect(false); return; } @@ -304,7 +309,7 @@ void IdoMysqlConnection::Reconnect(void) << "Local endpoint '" << my_endpoint->GetName() << "' is not authoritative, bailing out."; mysql_close(&m_Connection); - m_Connected = false; + SetConnected(false); return; } @@ -374,6 +379,8 @@ IdoMysqlResult IdoMysqlConnection::Query(const String& query) Log(LogDebug, "IdoMysqlConnection") << "Query: " << query; + IncreaseQueryCount(); + if (mysql_query(&m_Connection, query.CStr()) != 0) { std::ostringstream msgbuf; String message = mysql_error(&m_Connection); @@ -484,7 +491,7 @@ void IdoMysqlConnection::ActivateObject(const DbObject::Ptr& dbobj) void IdoMysqlConnection::InternalActivateObject(const DbObject::Ptr& dbobj) { - if (!m_Connected) + if (!GetConnected()) return; DbReference dbref = GetObjectID(dbobj); @@ -513,7 +520,7 @@ void IdoMysqlConnection::DeactivateObject(const DbObject::Ptr& dbobj) { boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (!m_Connected) + if (!GetConnected()) return; DbReference dbref = GetObjectID(dbobj); @@ -606,7 +613,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType if ((query.Category & GetCategories()) == 0) return; - if (!m_Connected) + if (!GetConnected()) return; if (query.Object && query.Object->GetObject()->GetExtension("agent_check").ToBool()) @@ -746,7 +753,7 @@ void IdoMysqlConnection::InternalCleanUpExecuteQuery(const String& table, const { boost::mutex::scoped_lock lock(m_ConnectionMutex); - if (!m_Connected) + if (!GetConnected()) return; Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + diff --git a/lib/db_ido_mysql/idomysqlconnection.hpp b/lib/db_ido_mysql/idomysqlconnection.hpp index 474fbe464..5985f5813 100644 --- a/lib/db_ido_mysql/idomysqlconnection.hpp +++ b/lib/db_ido_mysql/idomysqlconnection.hpp @@ -63,7 +63,6 @@ private: WorkQueue m_QueryQueue; boost::mutex m_ConnectionMutex; - bool m_Connected; MYSQL m_Connection; int m_AffectedRows; diff --git a/lib/db_ido_pgsql/idopgsqlconnection.cpp b/lib/db_ido_pgsql/idopgsqlconnection.cpp index f392a32db..54622c6c9 100644 --- a/lib/db_ido_pgsql/idopgsqlconnection.cpp +++ b/lib/db_ido_pgsql/idopgsqlconnection.cpp @@ -51,7 +51,7 @@ void IdoPgsqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::P size_t items = idopgsqlconnection->m_QueryQueue.GetLength(); Dictionary::Ptr stats = new Dictionary(); - stats->Set("version", IDO_CURRENT_SCHEMA_VERSION); + stats->Set("version", idopgsqlconnection->GetSchemaVersion()); stats->Set("instance_name", idopgsqlconnection->GetInstanceName()); stats->Set("query_queue_items", items); @@ -67,6 +67,7 @@ void IdoPgsqlConnection::Resume(void) { DbConnection::Resume(); + SetConnected(false); m_Connection = NULL; m_QueryQueue.SetExceptionCallback(boost::bind(&IdoPgsqlConnection::ExceptionHandler, this, _1)); @@ -106,6 +107,7 @@ void IdoPgsqlConnection::ExceptionHandler(boost::exception_ptr exp) if (m_Connection) { PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; } } @@ -127,6 +129,7 @@ void IdoPgsqlConnection::Disconnect(void) Query("COMMIT"); PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; } @@ -175,6 +178,7 @@ void IdoPgsqlConnection::Reconnect(void) Query("SELECT 1"); return; } catch (const std::exception&) { + SetConnected(false); PQfinish(m_Connection); m_Connection = NULL; reconnect = true; @@ -203,9 +207,12 @@ void IdoPgsqlConnection::Reconnect(void) if (!m_Connection) return; + SetConnected(true); + if (PQstatus(m_Connection) != CONNECTION_OK) { String message = PQerrorMessage(m_Connection); PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; Log(LogCritical, "IdoPgsqlConnection") @@ -222,18 +229,21 @@ void IdoPgsqlConnection::Reconnect(void) if (!row) { PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; Log(LogCritical, "IdoPgsqlConnection", "Schema does not provide any valid version! Verify your schema installation."); - Application::RequestShutdown(EXIT_FAILURE); - return; + BOOST_THROW_EXCEPTION(std::runtime_error("Schema does not provide any valid version! Verify your schema installation.")); } String version = row->Get("version"); + SetSchemaVersion(version); + if (Utility::CompareVersion(IDO_COMPAT_SCHEMA_VERSION, version) < 0) { PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; Log(LogCritical, "IdoPgsqlConnection") @@ -288,6 +298,7 @@ void IdoPgsqlConnection::Reconnect(void) if (status_update_age < GetFailoverTimeout()) { PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; return; @@ -299,6 +310,7 @@ void IdoPgsqlConnection::Reconnect(void) << "Local endpoint '" << my_endpoint->GetName() << "' is not authoritative, bailing out."; PQfinish(m_Connection); + SetConnected(false); m_Connection = NULL; return; @@ -369,6 +381,8 @@ IdoPgsqlResult IdoPgsqlConnection::Query(const String& query) Log(LogDebug, "IdoPgsqlConnection") << "Query: " << query; + IncreaseQueryCount(); + PGresult *result = PQexec(m_Connection, query.CStr()); if (!result) { diff --git a/tools/mkembedconfig/CMakeLists.txt b/tools/mkembedconfig/CMakeLists.txt index 25605bbd1..5c6fed416 100644 --- a/tools/mkembedconfig/CMakeLists.txt +++ b/tools/mkembedconfig/CMakeLists.txt @@ -30,5 +30,6 @@ macro(MKEMBEDCONFIG_TARGET EmbedInput EmbedOutput) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS mkembedconfig ${EmbedInput} ) + set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/${EmbedOutput} PROPERTY EXCLUDE_UNITY_BUILD TRUE) endmacro()