From: Thomas Markwalder Date: Mon, 15 Aug 2016 17:57:13 +0000 (-0400) Subject: [4294] Added abstract support for IPv6 lease stats recount to LeaseMgr X-Git-Tag: trac4631_base~6^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61bc7b004aefc683e239917a6afa717c14744456;p=thirdparty%2Fkea.git [4294] Added abstract support for IPv6 lease stats recount to LeaseMgr src/lib/dhcpsrv/lease_mgr.h src/lib/dhcpsrv/lease_mgr.cc AddressStatsRow6 - new struct that contains a single row of IPv6 lease statistical data AddressStatsQuery6 - new base class for fulfilling the IPv6 statistical lease data query LeaseMgr::recountAddressStats6() - new method that recalculates per-subnet and global stats for IPv6 leases LeaseMgr::startAddressStatsQuery6() - new virtual method which creates then executes the IPv6 lease stats query --- diff --git a/src/lib/dhcpsrv/lease_mgr.cc b/src/lib/dhcpsrv/lease_mgr.cc index 491c5a0010..341b285c78 100644 --- a/src/lib/dhcpsrv/lease_mgr.cc +++ b/src/lib/dhcpsrv/lease_mgr.cc @@ -47,7 +47,7 @@ LeaseMgr::getLease6(Lease::Type type, const DUID& duid, return (*col.begin()); } -void +void LeaseMgr::recountAddressStats4() { using namespace stats; @@ -68,8 +68,8 @@ LeaseMgr::recountAddressStats4() { stats_mgr.setValue("declined-reclaimed-addresses", zero); // Clear subnet level stats. This ensures we don't end up with corner - // cases that leave stale values in place. - const Subnet4Collection* subnets = + // cases that leave stale values in place. + const Subnet4Collection* subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll(); for (Subnet4Collection::const_iterator subnet = subnets->begin(); @@ -86,15 +86,15 @@ LeaseMgr::recountAddressStats4() { "declined-reclaimed-addresses"), zero); } - + // Get counts per state per subnet. Iterate over the result set - // updating the subnet and global values. + // updating the subnet and global values. AddressStatsRow4 row; while (query->getNextRow(row)) { switch(row.lease_state_) { case Lease::STATE_DEFAULT: // Set subnet level value. - stats_mgr.setValue(StatsMgr::generateName("subnet", + stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_, "assigned-addresses"), row.state_count_); @@ -123,6 +123,114 @@ LeaseMgr::startAddressStatsQuery4() { return(AddressStatsQuery4Ptr()); } +void +LeaseMgr::recountAddressStats6() { + using namespace stats; + + StatsMgr& stats_mgr = StatsMgr::instance(); + + AddressStatsQuery6Ptr query = startAddressStatsQuery6(); + if (!query) { + /// NULL means not backend does not support recounting. + return; + } + + // Zero out the global stats. (Ok, so currently there's only one + // that should be cleared. "reclaimed-declined-addresses" never + // gets zeroed. @todo discuss with Tomek the rational of not + // clearing it when we clear the rest. + int64_t zero = 0; + stats_mgr.setValue("declined-addresses", zero); + stats_mgr.setValue("declined-reclaimed-addresses", zero); + + // Clear subnet level stats. This ensures we don't end up with corner + // cases that leave stale values in place. + const Subnet6Collection* subnets = + CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll(); + + for (Subnet6Collection::const_iterator subnet = subnets->begin(); + subnet != subnets->end(); ++subnet) { + SubnetID subnet_id = (*subnet)->getID(); + stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, + "assigned-nas"), + zero); + + stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, + "declined-nas"), + zero); + + stats_mgr.setValue(StatsMgr:: + generateName("subnet", subnet_id, + "declined-reclaimed-addresses"), + zero); + + stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, + "assigned-pds"), + zero); + } + + // Get counts per state per subnet. Iterate over the result set + // updating the subnet and global values. + AddressStatsRow6 row; + while (query->getNextRow(row)) { + switch(row.lease_type_) { + case Lease::TYPE_NA: + switch(row.lease_state_) { + case Lease::STATE_DEFAULT: + // Set subnet level value. + stats_mgr.setValue(StatsMgr:: + generateName("subnet", + row.subnet_id_, + "assigned-nas"), + row.state_count_); + break; + case Lease::STATE_DECLINED: + // Set subnet level value. + stats_mgr.setValue(StatsMgr:: + generateName("subnet", + row.subnet_id_, + "declined-nas"), + row.state_count_); + + // Add to the global value. + stats_mgr.addValue("declined-addresses", + row.state_count_); + break; + default: + // Not one we're tracking. + break; + } + break; + + case Lease::TYPE_PD: + switch(row.lease_state_) { + case Lease::STATE_DEFAULT: + // Set subnet level value. + stats_mgr.setValue(StatsMgr:: + generateName("subnet", + row.subnet_id_, + "assigned-pds"), + row.state_count_); + break; + default: + // Not one we're tracking. + break; + } + break; + + default: + // We dont' support TYPE_TAs yet + break; + } + } +} + +AddressStatsQuery6Ptr +LeaseMgr::startAddressStatsQuery6() { + return(AddressStatsQuery6Ptr()); +} + + std::string LeaseMgr::getDBVersion() { isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called"); diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h index e8123e840f..140a7d1c72 100644 --- a/src/lib/dhcpsrv/lease_mgr.h +++ b/src/lib/dhcpsrv/lease_mgr.h @@ -153,7 +153,7 @@ public: /// and the number of leases in that state for that subnet ID. struct AddressStatsRow4 { /// @brief Default constructor - AddressStatsRow4() : + AddressStatsRow4() : subnet_id_(0), lease_state_(Lease::STATE_DEFAULT), state_count_(0) { } @@ -164,15 +164,15 @@ struct AddressStatsRow4 { /// @param state_count The count of leases in the lease state AddressStatsRow4(const SubnetID& subnet_id, const Lease::LeaseState& lease_state, - const int64_t state_count) - : subnet_id_(subnet_id), lease_state_(lease_state), + const int64_t state_count) + : subnet_id_(subnet_id), lease_state_(lease_state), state_count_(state_count) { } /// @brief The subnet ID to which this data applies SubnetID subnet_id_; /// @brief The lease_state to which the count applies - uint32_t lease_state_; + Lease::LeaseState lease_state_; /// @brief state_count The count of leases in the lease state int64_t state_count_; }; @@ -188,12 +188,12 @@ public: /// @brief Default constructor AddressStatsQuery4() {}; - /// @brief virtual destructor + /// @brief virtual destructor virtual ~AddressStatsQuery4() {}; /// @brief Executes the query /// - /// This method should conduct whatever steps are required to + /// This method should conduct whatever steps are required to /// calculate the IPv4 lease statistical data by examining the /// IPv4 lease data and making that results available row by row. virtual void start() {}; @@ -210,6 +210,72 @@ public: /// @brief Defines a pointer to an AddressStatsQuery4. typedef boost::shared_ptr AddressStatsQuery4Ptr; +/// @brief Contains a single row of IPv6 lease statistical data +/// +/// The contents of the row consist of a subnet ID, a lease state, +/// and the number of leases in that state for that subnet ID. +struct AddressStatsRow6 { + /// @brief Default constructor + AddressStatsRow6() : + subnet_id_(0), lease_type_(Lease::TYPE_NA), + lease_state_(Lease::STATE_DEFAULT), state_count_(0) { + } + + /// @brief Constructor + /// + /// @param subnet_id The subnet id to which this data applies + /// @param lease_state The lease state counted + /// @param state_count The count of leases in the lease state + AddressStatsRow6(const SubnetID& subnet_id, const Lease::Type& lease_type, + const Lease::LeaseState& lease_state, + const int64_t state_count) + : subnet_id_(subnet_id), lease_state_(lease_state), + state_count_(state_count) { + } + + /// @brief The subnet ID to which this data applies + SubnetID subnet_id_; + /// @brief The lease_state to which the count applies + Lease::Type lease_type_; + /// @brief The lease_state to which the count applies + uint32_t lease_state_; + /// @brief state_count The count of leases in the lease state + int64_t state_count_; +}; + +/// @brief Base class for fulfilling IPv6 statistical lease data query +/// +/// LeaseMgr derivations implement this class such that it provides +/// upto date IPv6 statistical lease data organized as rows of +/// AddressStatsRow6 instances. The rows must be accessible in +/// ascending order by subnet id. +class AddressStatsQuery6 { +public: + /// @brief Default constructor + AddressStatsQuery6() {}; + + /// @brief virtual destructor + virtual ~AddressStatsQuery6() {}; + + /// @brief Executes the query + /// + /// This method should conduct whatever steps are required to + /// calculate the IPv6 lease statistical data by examining the + /// IPv6 lease data and making that results available row by row. + virtual void start() {}; + + /// @brief Fetches the next row of data + /// + /// @param[out] row Storage into which the row is fetched + /// + /// @return True if a row was fetched, false if there are no + /// more rows. + virtual bool getNextRow(AddressStatsRow6& row) { return (false); }; +}; + +/// @brief Defines a pointer to an AddressStatsQuery6. +typedef boost::shared_ptr AddressStatsQuery6Ptr; + /// @brief Abstract Lease Manager /// /// This is an abstract API for lease database backends. It provides unified @@ -463,7 +529,7 @@ public: /// @brief Recalculates per-subnet and global stats for IPv4 leases /// - /// This method recalculates the following statistics: + /// This method recalculates the following statistics: /// per-subnet: /// - assigned-addresses /// - declined-addresses @@ -476,21 +542,52 @@ public: /// returns an instance of an AddressStats4Qry. The query /// query contains a "result set" where each row is an AddressStatRow4 /// that contains a subnet id, a lease state, the number of leases in that - /// state and is ordered by subnet id. The method iterates over the + /// state and is ordered by subnet id. The method iterates over the /// result set rows, setting the appropriate statistic per subnet and - /// adding to the approporate global statistic. + /// adding to the approporate global statistic. void recountAddressStats4(); - /// @brief Virtual method which creates and runs the IPv4 lease stats query + /// @brief Virtual method which creates and runs the IPv4 lease stats query /// /// LeaseMgr derivations implement this method such that it creates and - /// returns an instance of an AddressStatsQuery whose result set has been - /// populated with upto date IPv4 lease statistical data. Each row of the - /// result set is an AddressStatRow4 which ordered ascending by subnet ID. + /// returns an instance of an AddressStatsQuery whose result set has been + /// populated with upto date IPv4 lease statistical data. Each row of the + /// result set is an AddressStatRow4 which ordered ascending by subnet ID. /// /// @return A populated AddressStatsQuery4 virtual AddressStatsQuery4Ptr startAddressStatsQuery4(); + /// @brief Recalculates per-subnet and global stats for IPv6 leases + /// + /// This method recalculates the following statistics: + /// per-subnet: + /// - assigned-addresses + /// - declined-addresses + /// - declined-reclaimed-addresses (reset to zero) + /// - assigned-pds + /// global: + /// - declined-addresses + /// - declined-reclaimed-addresses (reset to zero) + /// + /// It invokes the virtual method, startAddressStatsQuery6(), which + /// returns an instance of an AddressStats6Qry. The query + /// query contains a "result set" where each row is an AddressStatRow6 + /// that contains a subnet id, a lease state, the number of leases in that + /// state and is ordered by subnet id. The method iterates over the + /// result set rows, setting the appropriate statistic per subnet and + /// adding to the approporate global statistic. + void recountAddressStats6(); + + /// @brief Virtual method which creates and runs the IPv6 lease stats query + /// + /// LeaseMgr derivations implement this method such that it creates and + /// returns an instance of an AddressStatsQuery whose result set has been + /// populated with upto date IPv6 lease statistical data. Each row of the + /// result set is an AddressStatRow6 which ordered ascending by subnet ID. + /// + /// @return A populated AddressStatsQuery6 + virtual AddressStatsQuery6Ptr startAddressStatsQuery6(); + /// @brief Return backend type /// /// Returns the type of the backend (e.g. "mysql", "memfile" etc.) diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc index d8ced0e5f2..aa3ff1a11b 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc @@ -2406,13 +2406,6 @@ GenericLeaseMgrTest::checkAddressStats4(const StatValMapList& expectedStats) { int64_t declined_addresses = 0; int64_t declined_reclaimed_addresses = 0; -#if 0 - isc::data::ConstElementPtr allstats = stats::StatsMgr::instance().getAll(); - std::cout << "ALL: "; - allstats->toJSON(std::cout); - std::cout << std::endl; -#endif - // Iterate over all stats for each subnet for (int subnet_idx = 0; subnet_idx < expectedStats.size(); ++subnet_idx) { BOOST_FOREACH(StatValPair expectedStat, expectedStats[subnet_idx]) {