From: Marcin Siodelski Date: Tue, 20 Jan 2015 13:48:34 +0000 (+0100) Subject: [master] Merge branch 'trac3668' X-Git-Tag: trac3712_base~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2ce54eeb607d2caa0901125b5d86a373e9e3f165;p=thirdparty%2Fkea.git [master] Merge branch 'trac3668' Conflicts: src/lib/dhcpsrv/memfile_lease_mgr.cc src/lib/dhcpsrv/memfile_lease_mgr.h --- 2ce54eeb607d2caa0901125b5d86a373e9e3f165 diff --cc src/lib/dhcpsrv/dhcpsrv_messages.mes index 8c01fed969,35746a00b3..8eac7c5941 --- a/src/lib/dhcpsrv/dhcpsrv_messages.mes +++ b/src/lib/dhcpsrv/dhcpsrv_messages.mes @@@ -289,9 -289,28 +289,18 @@@ An info message issued when the server from the lease file. All leases currently held in the memory will be replaced by those read from the file. -% DHCPSRV_MEMFILE_LEASES_RELOAD6 reloading leases from %1 -An info message issued when the server is about to start reading DHCPv6 leases -from the lease file. All leases currently held in the memory will be -replaced by those read from the file. - -% DHCPSRV_MEMFILE_LEASE_LOAD4 loading lease %1 -A debug message issued when DHCPv4 lease is being loaded from the file to -memory. - -% DHCPSRV_MEMFILE_LEASE_LOAD6 loading lease %1 -A debug message issued when DHCPv6 lease is being loaded from the file to -memory. +% DHCPSRV_MEMFILE_LEASE_LOAD loading lease %1 +A debug message issued when DHCP lease is being loaded from the file to memory. + % DHCPSRV_MEMFILE_LFC_SETUP setting up the Lease File Cleanup interval to %1 sec + An informational message logged when the Memfile lease database backend + configures the LFC to be executed periodically. The argument holds the + interval in seconds in which the LFC will be executed. + + % DHCPSRV_MEMFILE_LFC_START starting Lease File Cleanup + An informational message issued when the Memfile lease database backend + starts the periodic Lease File Cleanup. + % DHCPSRV_MEMFILE_NO_STORAGE running in non-persistent mode, leases will be lost after restart A warning message issued when writes of leases to disk have been disabled in the configuration. This mode is useful for some kinds of performance diff --cc src/lib/dhcpsrv/memfile_lease_mgr.cc index ca2ebf04ba,1086f177a3..24abc463b0 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@@ -474,32 -476,157 +482,64 @@@ Memfile_LeaseMgr::initLeaseFilePath(Uni return (lease_file); } + void + Memfile_LeaseMgr::initTimers() { + std::string lfc_interval_str = "0"; + try { + lfc_interval_str = getParameter("lfc-interval"); + } catch (const std::exception& ex) { + // Ignore and default to 0. + } + + uint32_t lfc_interval = 0; + try { + lfc_interval = boost::lexical_cast(lfc_interval_str); + } catch (boost::bad_lexical_cast& ex) { + isc_throw(isc::BadValue, "invalid value of the lfc-interval " + << lfc_interval_str << " specified"); + } + + if (lfc_interval > 0) { + asiolink::IntervalTimer::Callback cb = + boost::bind(&Memfile_LeaseMgr::lfcCallback, this); + LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_SETUP).arg(lfc_interval); + lfc_timer_.setup(cb, lfc_interval * 1000); + } + } + + void + Memfile_LeaseMgr::lfcCallback() { + /// @todo Extend this method to spawn the new process which will + /// perform the Lease File Cleanup in background. + LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_START); + } + -void -Memfile_LeaseMgr::load4() { - // If lease file hasn't been opened, we are working in non-persistent mode. - // That's fine, just leave. - if (!persistLeases(V4)) { - return; - } +template +void Memfile_LeaseMgr:: +loadLeasesFromFiles(const std::string& filename, + boost::shared_ptr& lease_file, + StorageType& storage) { + storage.clear(); - LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASES_RELOAD4) - .arg(lease_file4_->getFilename()); - - // Remove existing leases (if any). We will recreate them based on the - // data on disk. - storage4_.clear(); - - Lease4Ptr lease; - do { - /// @todo Currently we stop parsing on first failure. It is possible - /// that only one (or a few) leases are bad, so in theory we could - /// continue parsing but that would require some error counters to - /// prevent endless loops. That is enhancement for later time. - if (!lease_file4_->next(lease)) { - isc_throw(DbOperationError, "Failed to parse the DHCPv6 lease in" - " the lease file: " << lease_file4_->getReadMsg()); - } - // If we got the lease, we update the internal container holding - // leases. Otherwise, we reached the end of file and we leave. - if (lease) { - LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA, - DHCPSRV_MEMFILE_LEASE_LOAD4) - .arg(lease->toText()); - loadLease4(lease); - } - } while (lease); -} + // Load the leasefile.completed, if exists. + lease_file.reset(new LeaseFileType(std::string(filename + ".completed"))); + if (lease_file->exists()) { + LeaseFileLoader::load(*lease_file, storage, + MAX_LEASE_ERRORS); -void -Memfile_LeaseMgr::loadLease4(Lease4Ptr& lease) { - // Check if the lease already exists. - Lease4Storage::iterator lease_it = storage4_.find(lease->addr_); - // Lease doesn't exist. - if (lease_it == storage4_.end()) { - // Add the lease only if valid lifetime is greater than 0. - // We use valid lifetime of 0 to indicate that lease should - // be removed. - if (lease->valid_lft_ > 0) { - storage4_.insert(lease); - } } else { - // We use valid lifetime of 0 to indicate that the lease is - // to be removed. In such case, erase the lease. - if (lease->valid_lft_ == 0) { - storage4_.erase(lease_it); - - } else { - // Update existing lease. - **lease_it = *lease; + // If the leasefile.completed doesn't exist, let's load the leases + // from leasefile.2 and leasefile.1, if they exist. + lease_file.reset(new LeaseFileType(std::string(filename + ".2"))); + if (lease_file->exists()) { + LeaseFileLoader::load(*lease_file, storage, + MAX_LEASE_ERRORS); } - } -} - -void -Memfile_LeaseMgr::load6() { - // If lease file hasn't been opened, we are working in non-persistent mode. - // That's fine, just leave. - if (!persistLeases(V6)) { - return; - } - LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASES_RELOAD6) - .arg(lease_file6_->getFilename()); - - // Remove existing leases (if any). We will recreate them based on the - // data on disk. - storage6_.clear(); - - Lease6Ptr lease; - do { - /// @todo Currently we stop parsing on first failure. It is possible - /// that only one (or a few) leases are bad, so in theory we could - /// continue parsing but that would require some error counters to - /// prevent endless loops. That is enhancement for later time. - if (!lease_file6_->next(lease)) { - isc_throw(DbOperationError, "Failed to parse the DHCPv6 lease in" - " the lease file: " << lease_file6_->getReadMsg()); - } - // If we got the lease, we update the internal container holding - // leases. Otherwise, we reached the end of file and we leave. - if (lease) { - LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA, - DHCPSRV_MEMFILE_LEASE_LOAD6) - .arg(lease->toText()); - - loadLease6(lease); - } - } while (lease); -} - -void -Memfile_LeaseMgr::loadLease6(Lease6Ptr& lease) { - // Check if the lease already exists. - Lease6Storage::iterator lease_it = storage6_.find(lease->addr_); - // Lease doesn't exist. - if (lease_it == storage6_.end()) { - // Add the lease only if valid lifetime is greater than 0. - // We use valid lifetime of 0 to indicate that lease should - // be removed. - if (lease->valid_lft_ > 0) { - storage6_.insert(lease); - } - } else { - // We use valid lifetime of 0 to indicate that the lease is - // to be removed. In such case, erase the lease. - if (lease->valid_lft_ == 0) { - storage6_.erase(lease_it); - - } else { - // Update existing lease. - **lease_it = *lease; + lease_file.reset(new LeaseFileType(std::string(filename + ".1"))); + if (lease_file->exists()) { + LeaseFileLoader::load(*lease_file, storage, + MAX_LEASE_ERRORS); } } diff --cc src/lib/dhcpsrv/memfile_lease_mgr.h index 8995b31103,b1b70477a6..dd1eebf098 --- a/src/lib/dhcpsrv/memfile_lease_mgr.h +++ b/src/lib/dhcpsrv/memfile_lease_mgr.h @@@ -330,8 -362,66 +359,27 @@@ public /// server shut down. bool persistLeases(Universe u) const; -protected: +private: + /// @brief A callback function triggering Lease File Cleanup. + /// + /// This method is virtual so as it can be overriden and customized in + /// the unit tests. In particular, the unit test which checks that the + /// callback function has been executed would override this function + /// to increase the execution counter each time it is executed. + /// + /// @todo Once the callback is implemented, there is a need to + /// extend the documentation of this method. Currently, it simply + /// logs that it has been called. + virtual void lfcCallback(); + + private: + - /// @brief Load all DHCPv4 leases from the file. - /// - /// This method loads all DHCPv4 leases from a file to memory. It removes - /// existing leases before reading a file. - /// - /// @throw isc::DbOperationError If failed to read a lease from the lease - /// file. - void load4(); - - /// @brief Loads a single DHCPv4 lease from the file. - /// - /// This method reads a single lease record from the lease file. If the - /// corresponding record doesn't exist in the in-memory container, the - /// lease is added to the container (except for a lease which valid lifetime - /// is 0). If the corresponding lease exists, the lease being read updates - /// the existing lease. If the lease being read from the lease file has - /// valid lifetime of 0 and the corresponding lease exists in the in-memory - /// database, the existing lease is removed. - /// - /// @param lease Pointer to the lease read from the lease file. - void loadLease4(Lease4Ptr& lease); - - /// @brief Load all DHCPv6 leases from the file. - /// - /// This method loads all DHCPv6 leases from a file to memory. It removes - /// existing leases before reading a file. - /// - /// @throw isc::DbOperationError If failed to read a lease from the lease - /// file. - void load6(); - - /// @brief Loads a single DHCPv6 lease from the file. - /// - /// This method reads a single lease record from the lease file. If the - /// corresponding record doesn't exist in the in-memory container, the - /// lease is added to the container (except for a lease which valid lifetime - /// is 0). If the corresponding lease exists, the lease being read updates - /// the existing lease. If the lease being read from the lease file has - /// valid lifetime of 0 and the corresponding lease exists in the in-memory - /// database, the existing lease is removed. ++ /// @brief Initialize the timers used to perform repeating tasks. + /// - /// @param lease Pointer to the lease read from the lease file. - void loadLease6(Lease6Ptr& lease); - ++ /// Currently only one timer is supported. This timer executes the ++ /// Lease File Cleanup periodically. ++ void initTimers(); /// @brief Initialize the location of the lease file. /// /// This method uses the parameters passed as a map to the constructor to