]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1196] Checkpoint: handled negative counters
authorFrancis Dupont <fdupont@isc.org>
Tue, 19 May 2020 17:36:11 +0000 (19:36 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 19 Jun 2020 15:04:50 +0000 (17:04 +0200)
src/lib/dhcpsrv/dhcpsrv_messages.cc
src/lib/dhcpsrv/dhcpsrv_messages.h
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.cc

index e273650aa6c401f91e9f04970111f50792edbe61..2422f89baf0a20760553bb3c3adf04234c56b3cc 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Thu Dec 05 2019 16:13
+// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Tue May 19 2020 19:04
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -188,6 +188,7 @@ extern const isc::log::MessageID DHCPSRV_MYSQL_GET_VERSION = "DHCPSRV_MYSQL_GET_
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB = "DHCPSRV_MYSQL_HOST_DB";
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_GET_VERSION = "DHCPSRV_MYSQL_HOST_DB_GET_VERSION";
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_READONLY = "DHCPSRV_MYSQL_HOST_DB_READONLY";
+extern const isc::log::MessageID DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT = "DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT";
 extern const isc::log::MessageID DHCPSRV_MYSQL_ROLLBACK = "DHCPSRV_MYSQL_ROLLBACK";
 extern const isc::log::MessageID DHCPSRV_MYSQL_START_TRANSACTION = "DHCPSRV_MYSQL_START_TRANSACTION";
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR4 = "DHCPSRV_MYSQL_UPDATE_ADDR4";
@@ -228,6 +229,7 @@ extern const isc::log::MessageID DHCPSRV_PGSQL_GET_VERSION = "DHCPSRV_PGSQL_GET_
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB = "DHCPSRV_PGSQL_HOST_DB";
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB_GET_VERSION = "DHCPSRV_PGSQL_HOST_DB_GET_VERSION";
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB_READONLY = "DHCPSRV_PGSQL_HOST_DB_READONLY";
+extern const isc::log::MessageID DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT = "DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT";
 extern const isc::log::MessageID DHCPSRV_PGSQL_ROLLBACK = "DHCPSRV_PGSQL_ROLLBACK";
 extern const isc::log::MessageID DHCPSRV_PGSQL_START_TRANSACTION = "DHCPSRV_PGSQL_START_TRANSACTION";
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR4 = "DHCPSRV_PGSQL_UPDATE_ADDR4";
@@ -432,6 +434,7 @@ const char* values[] = {
     "DHCPSRV_MYSQL_HOST_DB", "opening MySQL hosts database: %1",
     "DHCPSRV_MYSQL_HOST_DB_GET_VERSION", "obtaining schema version information for the MySQL hosts database",
     "DHCPSRV_MYSQL_HOST_DB_READONLY", "MySQL host database opened for read access only",
+    "DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT", "recount of leases returned a negative value",
     "DHCPSRV_MYSQL_ROLLBACK", "rolling back MySQL database",
     "DHCPSRV_MYSQL_START_TRANSACTION", "starting new MySQL transaction",
     "DHCPSRV_MYSQL_UPDATE_ADDR4", "updating IPv4 lease for address %1",
@@ -472,6 +475,7 @@ const char* values[] = {
     "DHCPSRV_PGSQL_HOST_DB", "opening PostgreSQL hosts database: %1",
     "DHCPSRV_PGSQL_HOST_DB_GET_VERSION", "obtaining schema version information for the PostgreSQL hosts database",
     "DHCPSRV_PGSQL_HOST_DB_READONLY", "PostgreSQL host database opened for read access only",
+    "DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT", "recount of leases returned a negative value",
     "DHCPSRV_PGSQL_ROLLBACK", "rolling back PostgreSQL database",
     "DHCPSRV_PGSQL_START_TRANSACTION", "starting a new PostgreSQL transaction",
     "DHCPSRV_PGSQL_UPDATE_ADDR4", "updating IPv4 lease for address %1",
index 8f40de10ad7001a898d33197607ede4fe698497a..1cea8adccc5a9654f815ec32737c991f7596225a 100644 (file)
@@ -1,4 +1,4 @@
-// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Thu Dec 05 2019 16:13
+// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Tue May 19 2020 19:04
 
 #ifndef DHCPSRV_MESSAGES_H
 #define DHCPSRV_MESSAGES_H
@@ -189,6 +189,7 @@ extern const isc::log::MessageID DHCPSRV_MYSQL_GET_VERSION;
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB;
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_GET_VERSION;
 extern const isc::log::MessageID DHCPSRV_MYSQL_HOST_DB_READONLY;
+extern const isc::log::MessageID DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT;
 extern const isc::log::MessageID DHCPSRV_MYSQL_ROLLBACK;
 extern const isc::log::MessageID DHCPSRV_MYSQL_START_TRANSACTION;
 extern const isc::log::MessageID DHCPSRV_MYSQL_UPDATE_ADDR4;
@@ -229,6 +230,7 @@ extern const isc::log::MessageID DHCPSRV_PGSQL_GET_VERSION;
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB;
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB_GET_VERSION;
 extern const isc::log::MessageID DHCPSRV_PGSQL_HOST_DB_READONLY;
+extern const isc::log::MessageID DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT;
 extern const isc::log::MessageID DHCPSRV_PGSQL_ROLLBACK;
 extern const isc::log::MessageID DHCPSRV_PGSQL_START_TRANSACTION;
 extern const isc::log::MessageID DHCPSRV_PGSQL_UPDATE_ADDR4;
index 91ce24cc4f08b08f6ff39f2b0eb9f663029d6ece..2ac5684c036f400db9fc64dea1e8f75b8506c353 100644 (file)
@@ -921,6 +921,12 @@ database in read-only mode. Kea will not be able to insert or modify
 host reservations but will be able to retrieve existing ones and
 assign them to the clients communicating with the server.
 
+% DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT recount of leases returned a negative value
+This warning message is issued when the recount of leases using counters
+in the MySQL database returned a negative value. This shows a problem
+which can be fixed only by an offline direct recount on the database.
+This message is issued only once.
+
 % DHCPSRV_MYSQL_ROLLBACK rolling back MySQL database
 The code has issued a rollback call.  All outstanding transaction will
 be rolled back and not committed to the database.
@@ -1115,6 +1121,12 @@ database in read-only mode. Kea will not be able to insert or modify
 host reservations but will be able to retrieve existing ones and
 assign them to the clients communicating with the server.
 
+% DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT recount of leases returned a negative value
+This warning message is issued when the recount of leases using counters
+in the PostgreSQL database returned a negative value. This shows a problem
+which can be fixed only by an offline direct recount on the database.
+This message is issued only once.
+
 % DHCPSRV_PGSQL_ROLLBACK rolling back PostgreSQL database
 The code has issued a rollback call.  All outstanding transaction will
 be rolled back and not committed to the database.
index 377793b3eca56ebd7a504a65f6de3f07e2ac26ff..d191639fbbe47f738cd98def210b825453b3578f 100644 (file)
@@ -1622,10 +1622,10 @@ public:
         bind_[col].is_unsigned = MLM_TRUE;
         ++col;
 
-        // state_count_: uint32_t
+        // state_count_: int64_t
         bind_[col].buffer_type = MYSQL_TYPE_LONGLONG;
         bind_[col].buffer = reinterpret_cast<char*>(&state_count_);
-        bind_[col].is_unsigned = MLM_TRUE;
+        //bind_[col].is_unsigned = MLM_FALSE;
 
         // Set up the MYSQL_BIND array for the data being returned
         // and bind it to the statement.
@@ -1649,6 +1649,10 @@ public:
     /// result set rows. Once the last row has been fetched, subsequent
     /// calls will return false.
     ///
+    /// Checks against negative values for the state count and logs once
+    /// a warning message. Unfortunately not getting the message is not
+    /// a proof that detailed counters are correct.
+    ///
     /// @param row Storage for the fetched row
     ///
     /// @return True if the fetch succeeded, false if there are no more
@@ -1660,7 +1664,15 @@ public:
             row.subnet_id_ = static_cast<SubnetID>(subnet_id_);
             row.lease_type_ = static_cast<Lease::Type>(lease_type_);
             row.lease_state_ = state_;
-            row.state_count_ = state_count_;
+            if (state_count_ >= 0) {
+                row.state_count_ = state_count_;
+            } else {
+                row.state_count_ = 0;
+                if (!negative_count_) {
+                    negative_count_ = true;
+                    LOG_WARN(dhcpsrv_logger, DHCPSRV_MYSQL_NEGATIVE_LEASES_STAT);
+                }
+            }
             have_row = true;
         } else if (status != MYSQL_NO_DATA) {
             conn_.checkError(status, statement_index_, "getNextRow failed");
@@ -1709,8 +1721,14 @@ private:
 
     /// @brief Receives the state count when fetching a row
     int64_t state_count_;
+
+    /// @brief Received negative state count showing a problem
+    static bool negative_count_;
 };
 
+// Initialize negative state count flag to false.
+bool MySqlLeaseStatsQuery::negative_count_ = false;
+
 // MySqlLeaseContext Constructor
 
 MySqlLeaseContext::MySqlLeaseContext(const DatabaseConnection::ParameterMap& parameters)
index b0af21717c0a27eafd8ad57acf3d43def261a909..546e1cf8df650f85eb7a9412e73f116eadc2850e 100644 (file)
@@ -1085,6 +1085,10 @@ public:
     /// result set rows. Once the last row has been fetched, subsequent
     /// calls will return false.
     ///
+    /// Checks against negative values for the state count and logs once
+    /// a warning message. Unfortunately not getting the message is not
+    /// a proof that detailed counters are correct.
+    ///
     /// @param row Storage for the fetched row
     ///
     /// @return True if the fetch succeeded, false if there are no more
@@ -1122,6 +1126,15 @@ public:
         PgSqlExchange::getColumnValue(*result_set_, next_row_, col,
                                       row.state_count_);
 
+        // Protect against negative state count.a
+        if (row.state_count_ < 0) {
+            row.state_count_ = 0;
+            if (!negative_count_) {
+                negative_count_ = true;
+                LOG_WARN(dhcpsrv_logger, DHCPSRV_PGSQL_NEGATIVE_LEASES_STAT);
+            }
+        }
+
         // Point to the next row.
         ++next_row_;
         return (true);
@@ -1143,8 +1156,14 @@ protected:
 
     /// @brief Indicates if query supplies lease type
     bool fetch_type_;
+
+    /// @brief Received negative state count showing a problem
+    static bool negative_count_;
 };
 
+// Initialize negative state count flag to false.
+bool PgSqlLeaseStatsQuery::negative_count_ = false;
+
 // PgSqlLeaseContext Constructor
 
 PgSqlLeaseContext::PgSqlLeaseContext(const DatabaseConnection::ParameterMap& parameters)