Browse Source

[3966] Implemented methods to retrieve expired leases in MySQL.

Marcin Siodelski 9 years ago
parent
commit
54a90126ec
2 changed files with 114 additions and 22 deletions
  1. 84 22
      src/lib/dhcpsrv/mysql_lease_mgr.cc
  2. 30 0
      src/lib/dhcpsrv/mysql_lease_mgr.h

+ 84 - 22
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -25,6 +25,7 @@
 
 
 #include <iostream>
 #include <iostream>
 #include <iomanip>
 #include <iomanip>
+#include <limits.h>
 #include <sstream>
 #include <sstream>
 #include <string>
 #include <string>
 #include <time.h>
 #include <time.h>
@@ -162,6 +163,15 @@ TaggedStatement tagged_statements[] = {
                         "state "
                         "state "
                             "FROM lease4 "
                             "FROM lease4 "
                             "WHERE hwaddr = ? AND subnet_id = ?"},
                             "WHERE hwaddr = ? AND subnet_id = ?"},
+    {MySqlLeaseMgr::GET_LEASE4_EXPIRE,
+                    "SELECT address, hwaddr, client_id, "
+                        "valid_lifetime, expire, subnet_id, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "state "
+                            "FROM lease4 "
+                            "WHERE state != ? AND expire < ? "
+                            "ORDER BY expire "
+                            "LIMIT ?"},
     {MySqlLeaseMgr::GET_LEASE6_ADDR,
     {MySqlLeaseMgr::GET_LEASE6_ADDR,
                     "SELECT address, duid, valid_lifetime, "
                     "SELECT address, duid, valid_lifetime, "
                         "expire, subnet_id, pref_lifetime, "
                         "expire, subnet_id, pref_lifetime, "
@@ -190,6 +200,17 @@ TaggedStatement tagged_statements[] = {
                             "FROM lease6 "
                             "FROM lease6 "
                             "WHERE duid = ? AND iaid = ? AND subnet_id = ? "
                             "WHERE duid = ? AND iaid = ? AND subnet_id = ? "
                             "AND lease_type = ?"},
                             "AND lease_type = ?"},
+    {MySqlLeaseMgr::GET_LEASE6_EXPIRE,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "hwaddr, hwtype, hwaddr_source, "
+                        "state "
+                            "FROM lease6 "
+                            "WHERE state != ? AND expire < ? "
+                            "ORDER BY expire "
+                            "LIMIT ?"},
     {MySqlLeaseMgr::GET_VERSION,
     {MySqlLeaseMgr::GET_VERSION,
                     "SELECT version, minor FROM schema_version"},
                     "SELECT version, minor FROM schema_version"},
     {MySqlLeaseMgr::INSERT_LEASE4,
     {MySqlLeaseMgr::INSERT_LEASE4,
@@ -936,7 +957,7 @@ public:
 
 
             // state:  uint32_t
             // state:  uint32_t
             bind_[15].buffer_type = MYSQL_TYPE_LONG;
             bind_[15].buffer_type = MYSQL_TYPE_LONG;
-            bind_[15].buffer = reinterpret_cast<char*>(&state_);
+            bind_[15].buffer = reinterpret_cast<char*>(&lease_->state_);
             bind_[15].is_unsigned = MLM_TRUE;
             bind_[15].is_unsigned = MLM_TRUE;
             // bind_[15].is_null = &MLM_FALSE; // commented out for performance
             // bind_[15].is_null = &MLM_FALSE; // commented out for performance
                                                // reasons, see memset() above
                                                // reasons, see memset() above
@@ -1337,6 +1358,25 @@ MySqlLeaseMgr::getDBVersion() {
 //    from a time read from the database into a local time.
 //    from a time read from the database into a local time.
 
 
 void
 void
+MySqlLeaseMgr::convertToDatabaseTime(const time_t input_time,
+                                     MYSQL_TIME& output_time) {
+
+    // Convert to broken-out time
+    struct tm time_tm;
+    (void) localtime_r(&input_time, &time_tm);
+
+    // Place in output expire structure.
+    output_time.year = time_tm.tm_year + 1900;
+    output_time.month = time_tm.tm_mon + 1;     // Note different base
+    output_time.day = time_tm.tm_mday;
+    output_time.hour = time_tm.tm_hour;
+    output_time.minute = time_tm.tm_min;
+    output_time.second = time_tm.tm_sec;
+    output_time.second_part = 0;                  // No fractional seconds
+    output_time.neg = my_bool(0);                 // Not negative
+}
+
+void
 MySqlLeaseMgr::convertToDatabaseTime(const time_t cltt,
 MySqlLeaseMgr::convertToDatabaseTime(const time_t cltt,
                                      const uint32_t valid_lifetime,
                                      const uint32_t valid_lifetime,
                                      MYSQL_TIME& expire) {
                                      MYSQL_TIME& expire) {
@@ -1352,21 +1392,7 @@ MySqlLeaseMgr::convertToDatabaseTime(const time_t cltt,
         isc_throw(BadValue, "Time value is too large: " << expire_time_64);
         isc_throw(BadValue, "Time value is too large: " << expire_time_64);
     }
     }
 
 
-    const time_t expire_time = static_cast<const time_t>(expire_time_64);
-
-    // Convert to broken-out time
-    struct tm expire_tm;
-    (void) localtime_r(&expire_time, &expire_tm);
-
-    // Place in output expire structure.
-    expire.year = expire_tm.tm_year + 1900;
-    expire.month = expire_tm.tm_mon + 1;     // Note different base
-    expire.day = expire_tm.tm_mday;
-    expire.hour = expire_tm.tm_hour;
-    expire.minute = expire_tm.tm_min;
-    expire.second = expire_tm.tm_sec;
-    expire.second_part = 0;                  // No fractional seconds
-    expire.neg = my_bool(0);                 // Not negative
+    convertToDatabaseTime(static_cast<time_t>(expire_time_64), expire);
 }
 }
 
 
 void
 void
@@ -1980,17 +2006,53 @@ MySqlLeaseMgr::getLeases6(Lease::Type lease_type,
 }
 }
 
 
 void
 void
-MySqlLeaseMgr::getExpiredLeases6(Lease6Collection&, const size_t) const {
-    isc_throw(NotImplemented, "MySqlLeaseMgr::getExpiredLeases6 is currently"
-              " not implemented");
+MySqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
+                                 const size_t max_leases) const {
+    getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
+}
+
+void
+MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
+                                 const size_t max_leases) const {
+    getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE);
 }
 }
 
 
+template<typename LeaseCollection>
 void
 void
-MySqlLeaseMgr::getExpiredLeases4(Lease4Collection&, const size_t) const {
-    isc_throw(NotImplemented, "MySqlLeaseMgr::getExpiredLeases4 is currently"
-              " not implemented");
+MySqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
+                                      const size_t max_leases,
+                                      StatementIndex statement_index) const {
+    // Set up the WHERE clause value
+    MYSQL_BIND inbind[3];
+    memset(inbind, 0, sizeof(inbind));
+
+    // Exclude reclaimed leases.
+    uint32_t state = static_cast<uint32_t>(Lease::STATE_EXPIRED_RECLAIMED);
+    inbind[0].buffer_type = MYSQL_TYPE_LONG;
+    inbind[0].buffer = reinterpret_cast<char*>(&state);
+    inbind[0].is_unsigned = MLM_TRUE;
+
+    // Expiration timestamp.
+    MYSQL_TIME expire_time;
+    convertToDatabaseTime(time(NULL), expire_time);
+    inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
+    inbind[1].buffer = reinterpret_cast<char*>(&expire_time);
+    inbind[1].buffer_length = sizeof(expire_time);
+
+    // If the number of leases is 0, we will return all leases. This is
+    // achieved by setting the limit to a very high value.
+    uint32_t limit = max_leases > 0 ? static_cast<uint32_t>(max_leases) :
+        std::numeric_limits<uint32_t>::max();
+    inbind[2].buffer_type = MYSQL_TYPE_LONG;
+    inbind[2].buffer = reinterpret_cast<char*>(&limit);
+    inbind[2].is_unsigned = MLM_TRUE;
+
+    // Get the data
+    getLeaseCollection(statement_index, inbind, expired_leases);
 }
 }
 
 
+
+
 // Update lease methods.  These comprise common code that handles the actual
 // Update lease methods.  These comprise common code that handles the actual
 // update, and type-specific methods that set up the parameters for the prepared
 // update, and type-specific methods that set up the parameters for the prepared
 // statement depending on the type of lease.
 // statement depending on the type of lease.

+ 30 - 0
src/lib/dhcpsrv/mysql_lease_mgr.h

@@ -455,6 +455,14 @@ public:
     /// the lease file - which may be read by the user - it is the expiry time
     /// the lease file - which may be read by the user - it is the expiry time
     /// of the lease.
     /// of the lease.
 
 
+    /// @brief Convert time_t value to database time.
+    ///
+    /// @param input_time A time_t value representing time.
+    /// @param output_time Reference to MYSQL_TIME object where converted time
+    ///        will be put.
+    static
+    void convertToDatabaseTime(const time_t input_time, MYSQL_TIME& output_time);
+
     /// @brief Convert Lease Time to Database Times
     /// @brief Convert Lease Time to Database Times
     ///
     ///
     /// Within the DHCP servers, times are stored as client last transmit time
     /// Within the DHCP servers, times are stored as client last transmit time
@@ -511,9 +519,11 @@ public:
         GET_LEASE4_CLIENTID_SUBID,  // Get lease4 by client ID & subnet ID
         GET_LEASE4_CLIENTID_SUBID,  // Get lease4 by client ID & subnet ID
         GET_LEASE4_HWADDR,          // Get lease4 by HW address
         GET_LEASE4_HWADDR,          // Get lease4 by HW address
         GET_LEASE4_HWADDR_SUBID,    // Get lease4 by HW address & subnet ID
         GET_LEASE4_HWADDR_SUBID,    // Get lease4 by HW address & subnet ID
+        GET_LEASE4_EXPIRE,          // Get lease4 by expiration.
         GET_LEASE6_ADDR,            // Get lease6 by address
         GET_LEASE6_ADDR,            // Get lease6 by address
         GET_LEASE6_DUID_IAID,       // Get lease6 by DUID and IAID
         GET_LEASE6_DUID_IAID,       // Get lease6 by DUID and IAID
         GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and subnet ID
         GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and subnet ID
+        GET_LEASE6_EXPIRE,          // Get lease6 by expiration.
         GET_VERSION,                // Obtain version number
         GET_VERSION,                // Obtain version number
         INSERT_LEASE4,              // Add entry to lease4 table
         INSERT_LEASE4,              // Add entry to lease4 table
         INSERT_LEASE6,              // Add entry to lease6 table
         INSERT_LEASE6,              // Add entry to lease6 table
@@ -665,6 +675,26 @@ private:
     void getLease(StatementIndex stindex, MYSQL_BIND* bind,
     void getLease(StatementIndex stindex, MYSQL_BIND* bind,
                    Lease6Ptr& result) const;
                    Lease6Ptr& result) const;
 
 
+
+    /// @brief Get expired leases common code.
+    ///
+    /// This method retrieves expired and not reclaimed leases from the
+    /// lease database. The returned leases are ordered by the expiration
+    /// time. The maximum number of leases to be returned is specified
+    /// as an argument.
+    ///
+    /// @param [out] expired_leases Reference to the container where the
+    ///        retrieved leases are put.
+    /// @param max_leases Maximum number of leases to be returned.
+    /// @param statement_index One of the @c GET_LEASE4_EXPIRE or
+    ///        @c GET_LEASE6_EXPIRE.
+    ///
+    /// @tparam One of the @c Lease4Collection or @c Lease6Collection.
+    template<typename LeaseCollection>
+    void getExpiredLeasesCommon(LeaseCollection& expired_leases,
+                                const size_t max_leases,
+                                StatementIndex statement_index) const;
+
     /// @brief Update lease common code
     /// @brief Update lease common code
     ///
     ///
     /// Holds the common code for updating a lease.  It binds the parameters
     /// Holds the common code for updating a lease.  It binds the parameters