Skip to content

Commit 48f850a

Browse files
committed
[#3652] Remove the config history completely
- Removed revert() which makes no sense anymore. - Since rollback() was significantly simplified, renamed it to clearStagingConfiguration(). - Removed kludgy ensureCurrentAllocated(). The only new required allocations are on constructor and on clear().
1 parent 62013e9 commit 48f850a

File tree

7 files changed

+41
-223
lines changed

7 files changed

+41
-223
lines changed

src/bin/dhcp4/ctrl_dhcp4_srv.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ ControlledDhcpv4Srv::loadConfigFile(const std::string& file_name) {
179179
} catch (const std::exception& ex) {
180180
// If configuration failed at any stage, we drop the staging
181181
// configuration and continue to use the previous one.
182-
CfgMgr::instance().rollback();
182+
CfgMgr::instance().clearStagingConfiguration();
183183

184184
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL)
185185
.arg(file_name).arg(ex.what());
@@ -372,7 +372,7 @@ ControlledDhcpv4Srv::commandConfigSetHandler(const string&,
372372
// We are starting the configuration process so we should remove any
373373
// staging configuration that has been created during previous
374374
// configuration attempts.
375-
CfgMgr::instance().rollback();
375+
CfgMgr::instance().clearStagingConfiguration();
376376

377377
// Parse the logger configuration explicitly into the staging config.
378378
// Note this does not alter the current loggers, they remain in
@@ -478,7 +478,7 @@ ControlledDhcpv4Srv::commandConfigTestHandler(const string&,
478478
// We are starting the configuration process so we should remove any
479479
// staging configuration that has been created during previous
480480
// configuration attempts.
481-
CfgMgr::instance().rollback();
481+
CfgMgr::instance().clearStagingConfiguration();
482482

483483
// Now we check the server proper.
484484
return (checkConfig(dhcp4));

src/bin/dhcp4/tests/config_parser_unittest.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,6 @@ class Dhcp4ParserTest : public LogContentTest {
751751
"\"dhcp-ddns\": { \"enable-updates\" : false }, "
752752
"\"option-def\": [ ], "
753753
"\"option-data\": [ ] }";
754-
CfgMgr::instance().rollback();
755754
static_cast<void>(executeConfiguration(config,
756755
"reset configuration database"));
757756
// The default setting is to listen on all interfaces. In order to

src/bin/dhcp6/ctrl_dhcp6_srv.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ ControlledDhcpv6Srv::loadConfigFile(const std::string& file_name) {
182182
} catch (const std::exception& ex) {
183183
// If configuration failed at any stage, we drop the staging
184184
// configuration and continue to use the previous one.
185-
CfgMgr::instance().rollback();
185+
CfgMgr::instance().clearStagingConfiguration();
186186

187187
LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL)
188188
.arg(file_name).arg(ex.what());
@@ -375,7 +375,7 @@ ControlledDhcpv6Srv::commandConfigSetHandler(const string&,
375375
// We are starting the configuration process so we should remove any
376376
// staging configuration that has been created during previous
377377
// configuration attempts.
378-
CfgMgr::instance().rollback();
378+
CfgMgr::instance().clearStagingConfiguration();
379379

380380
// Parse the logger configuration explicitly into the staging config.
381381
// Note this does not alter the current loggers, they remain in
@@ -481,7 +481,7 @@ ControlledDhcpv6Srv::commandConfigTestHandler(const string&,
481481
// We are starting the configuration process so we should remove any
482482
// staging configuration that has been created during previous
483483
// configuration attempts.
484-
CfgMgr::instance().rollback();
484+
CfgMgr::instance().clearStagingConfiguration();
485485

486486
// Now we check the server proper.
487487
return (checkConfig(dhcp6));

src/bin/dhcp6/tests/config_parser_unittest.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,6 @@ class Dhcp6ParserTest : public LogContentTest {
881881
"\"dhcp-ddns\": { \"enable-updates\" : false }, "
882882
"\"option-def\": [ ], "
883883
"\"option-data\": [ ] }";
884-
CfgMgr::instance().rollback();
885884
static_cast<void>(executeConfiguration(config,
886885
"reset configuration database"));
887886
// The default setting is to listen on all interfaces. In order to

src/lib/dhcpsrv/cfgmgr.cc

Lines changed: 19 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ using namespace isc::util;
1919
namespace isc {
2020
namespace dhcp {
2121

22-
// Value 0 effectively disables configuration history. Higher values can lead to proportionally
23-
// increased memory usage which can be extreme in case of sizable configurations.
24-
const size_t CfgMgr::CONFIG_LIST_SIZE = 0;
22+
CfgMgr::CfgMgr()
23+
: datadir_(DHCP_DATA_DIR, true), d2_client_mgr_(new D2ClientMgr()),
24+
configuration_(new SrvConfig()), family_(AF_INET) {
25+
}
2526

2627
CfgMgr&
2728
CfgMgr::instance() {
@@ -41,7 +42,6 @@ CfgMgr::setDataDir(const std::string& datadir, bool unspecified) {
4142

4243
void
4344
CfgMgr::setD2ClientConfig(D2ClientConfigPtr& new_config) {
44-
ensureCurrentAllocated();
4545
// Note that D2ClientMgr::setD2Config() actually attempts to apply the
4646
// configuration by stopping its sender and opening a new one and so
4747
// forth per the new configuration.
@@ -69,40 +69,36 @@ CfgMgr::getD2ClientMgr() {
6969
return (*d2_client_mgr_);
7070
}
7171

72-
void
73-
CfgMgr::ensureCurrentAllocated() {
74-
if (!configuration_) {
75-
configuration_.reset(new SrvConfig());
76-
configs_.push_back(configuration_);
77-
}
78-
}
79-
8072
void
8173
CfgMgr::clear() {
74+
if (staging_configuration_) {
75+
staging_configuration_.reset();
76+
}
8277
if (configuration_) {
8378
configuration_->removeStatistics();
84-
configuration_.reset();
79+
configuration_.reset(new SrvConfig());
8580
}
86-
configs_.clear();
8781
external_configs_.clear();
8882
D2ClientConfigPtr d2_default_conf(new D2ClientConfig());
8983
setD2ClientConfig(d2_default_conf);
9084
}
9185

9286
void
93-
CfgMgr::commit() {
94-
ensureCurrentAllocated();
87+
CfgMgr::clearStagingConfiguration() {
88+
staging_configuration_.reset();
89+
}
9590

91+
void
92+
CfgMgr::commit() {
9693
// First we need to remove statistics. The new configuration can have fewer
9794
// subnets. Also, it may change subnet-ids. So we need to remove them all
9895
// and add them back.
9996
configuration_->removeStatistics();
10097

101-
bool promoted(false);
102-
if (!configs_.empty() && !configs_.back()->sequenceEquals(*configuration_)) {
98+
if (staging_configuration_ && !configuration_->sequenceEquals(*staging_configuration_)) {
10399
// Promote the staging configuration to the current configuration.
104-
configuration_ = configs_.back();
105-
promoted = true;
100+
configuration_ = staging_configuration_;
101+
staging_configuration_.reset();
106102
}
107103

108104
// Set the last commit timestamp.
@@ -113,74 +109,20 @@ CfgMgr::commit() {
113109
configuration_->updateStatistics();
114110

115111
configuration_->configureLowerLevelLibraries();
116-
117-
if (promoted) {
118-
// Keep track of the maximum size of the configs history. Remove the oldest elements.
119-
if (configs_.size() > CONFIG_LIST_SIZE) {
120-
SrvConfigList::const_iterator it = configs_.begin();
121-
std::advance(it, configs_.size() - CONFIG_LIST_SIZE);
122-
configs_.erase(configs_.begin(), it);
123-
}
124-
}
125-
}
126-
127-
void
128-
CfgMgr::rollback() {
129-
ensureCurrentAllocated();
130-
if (!configs_.empty() && !configuration_->sequenceEquals(*configs_.back())) {
131-
configs_.pop_back();
132-
}
133-
}
134-
135-
void
136-
CfgMgr::revert(const size_t index) {
137-
ensureCurrentAllocated();
138-
if (index == 0) {
139-
isc_throw(isc::OutOfRange, "invalid commit index 0 when reverting"
140-
" to an old configuration");
141-
} else if (configs_.size() <= index) {
142-
isc_throw(isc::OutOfRange, "unable to revert to commit index '"
143-
<< index << "', only '" << (configs_.size() == 0 ? 0 : configs_.size() - 1)
144-
<< "' previous commits available");
145-
}
146-
147-
// Let's rollback an existing configuration to make sure that the last
148-
// configuration on the list is the current one. Note that all remaining
149-
// operations in this function should be exception free so there shouldn't
150-
// be a problem that the revert operation fails and the staging
151-
// configuration is destroyed by this rollback.
152-
rollback();
153-
154-
if (!configs_.empty()) {
155-
// Get the iterator to the current configuration and then advance to the
156-
// desired one.
157-
SrvConfigList::const_reverse_iterator it = configs_.rbegin();
158-
std::advance(it, index);
159-
160-
// Copy the desired configuration to the new staging configuration. The
161-
// staging configuration is re-created here because we rolled back earlier
162-
// in this function.
163-
(*it)->copy(*getStagingCfg());
164-
165-
// Make the staging configuration a current one.
166-
commit();
167-
}
168112
}
169113

170114
SrvConfigPtr
171115
CfgMgr::getCurrentCfg() {
172-
ensureCurrentAllocated();
173116
return (configuration_);
174117
}
175118

176119
SrvConfigPtr
177120
CfgMgr::getStagingCfg() {
178-
ensureCurrentAllocated();
179-
if (configs_.empty() || configuration_->sequenceEquals(*configs_.back())) {
121+
if (!staging_configuration_ || configuration_->sequenceEquals(*staging_configuration_)) {
180122
uint32_t sequence = configuration_->getSequence();
181-
configs_.push_back(SrvConfigPtr(new SrvConfig(++sequence)));
123+
staging_configuration_ = SrvConfigPtr(new SrvConfig(++sequence));
182124
}
183-
return (configs_.back());
125+
return (staging_configuration_);
184126
}
185127

186128
SrvConfigPtr
@@ -230,15 +172,5 @@ CfgMgr::mergeIntoCfg(const SrvConfigPtr& target_config, const uint32_t seq) {
230172
}
231173
}
232174

233-
CfgMgr::CfgMgr()
234-
: datadir_(DHCP_DATA_DIR, true), d2_client_mgr_(new D2ClientMgr()), family_(AF_INET) {
235-
// DHCP_DATA_DIR must be set set with -DDHCP_DATA_DIR="..." in Makefile.am
236-
// Note: the definition of DHCP_DATA_DIR needs to include quotation marks
237-
// See AM_CPPFLAGS definition in Makefile.am
238-
}
239-
240-
CfgMgr::~CfgMgr() {
241-
}
242-
243175
} // end of isc::dhcp namespace
244176
} // end of isc namespace

src/lib/dhcpsrv/cfgmgr.h

Lines changed: 12 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,6 @@ class DuplicateListeningIface : public Exception {
6969
/// @ref isc::dhcp::SimpleParser6::deriveParameters.
7070
class CfgMgr : public boost::noncopyable {
7171
public:
72-
73-
/// @brief A number of configurations held by @c CfgMgr.
74-
///
75-
/// @todo Make it configurable.
76-
static const size_t CONFIG_LIST_SIZE;
77-
7872
/// @brief returns a single instance of Configuration Manager
7973
///
8074
/// CfgMgr is a singleton and this method is the only way of
@@ -127,18 +121,13 @@ class CfgMgr : public boost::noncopyable {
127121
/// The following methods manage the process of preparing a configuration
128122
/// without affecting a currently used configuration and then committing
129123
/// the configuration to replace current configuration atomically.
130-
/// They also allow for keeping a history of previous configurations so
131-
/// as the @c CfgMgr can revert to the historical configuration when
132-
/// required.
133124
///
134125
/// @todo Migrate all configuration parameters to use the model supported
135126
/// by these functions.
136127
///
137-
/// @todo Make the size of the configurations history configurable.
138-
///
139128
//@{
140129

141-
/// @brief Removes current, staging and all previous configurations.
130+
/// @brief Remove current, staging, and external configurations.
142131
///
143132
/// This function removes all configurations, including current,
144133
/// staging and external configurations. It creates a new current
@@ -147,52 +136,18 @@ class CfgMgr : public boost::noncopyable {
147136
/// This function is exception safe.
148137
void clear();
149138

150-
/// @brief Commits the staging configuration.
151-
///
152-
/// The staging configuration becomes current configuration when this
153-
/// function is called. It removes the oldest configurations held in the
154-
/// history so as the size of the list of configuration does not exceed
155-
/// the @c CONFIG_LIST_SIZE.
139+
/// @brief Remove staging configuration.
156140
///
157141
/// This function is exception safe.
158-
void commit();
142+
void clearStagingConfiguration();
159143

160-
/// @brief Removes staging configuration.
144+
/// @brief Commits the staging configuration.
161145
///
162-
/// This function should be called when there is a staging configuration
163-
/// (likely created in the previous configuration attempt) but the entire
164-
/// new configuration should be created. It removes the existing staging
165-
/// configuration and the next call to @c CfgMgr::getStagingCfg will return a
166-
/// fresh (default) configuration.
146+
/// The staging configuration becomes current configuration when this
147+
/// function is called.
167148
///
168149
/// This function is exception safe.
169-
void rollback();
170-
171-
/// @brief Reverts to one of the previous configurations.
172-
///
173-
/// This function reverts to selected previous configuration. The previous
174-
/// configuration is entirely copied to a new @c SrvConfig instance. This
175-
/// new instance has a unique sequence id (sequence id is not copied). The
176-
/// previous configuration (being copied) is not modified by this operation.
177-
///
178-
/// The configuration to be copied is identified by the index value which
179-
/// is the distance between the current (most recent) and desired
180-
/// configuration. If the index is out of range an exception is thrown.
181-
///
182-
/// @warning Revert operation will rollback any changes to the staging
183-
/// configuration (if it exists).
184-
///
185-
/// @warning This function requires that the entire previous configuration
186-
/// is copied to the new configuration object. This is not working for
187-
/// some of the complex configuration objects, e.g. subnets. Hence, the
188-
/// "revert" operation is not really usable at this point.
189-
///
190-
/// @param index A distance from the current configuration to the
191-
/// past configuration to be reverted. The minimal value is 1 which points
192-
/// to the nearest configuration.
193-
///
194-
/// @throw isc::OutOfRange if the specified index is out of range.
195-
void revert(const size_t index);
150+
void commit();
196151

197152
/// @brief Returns a pointer to the current configuration.
198153
///
@@ -294,18 +249,9 @@ class CfgMgr : public boost::noncopyable {
294249
CfgMgr();
295250

296251
/// @brief virtual destructor
297-
virtual ~CfgMgr();
252+
virtual ~CfgMgr() = default;
298253

299254
private:
300-
301-
/// @brief Checks if current configuration is created and creates it if needed.
302-
///
303-
/// This private method is called to ensure that the current configuration
304-
/// is created. If current configuration is not set, it creates the
305-
/// default current configuration.
306-
void ensureCurrentAllocated();
307-
308-
309255
/// @brief Merges external configuration with the given sequence number
310256
/// into the specified configuration.
311257
///
@@ -320,21 +266,16 @@ class CfgMgr : public boost::noncopyable {
320266
/// @brief Manages the DHCP-DDNS client and its configuration.
321267
D2ClientMgrPtr d2_client_mgr_;
322268

323-
/// @brief Server configuration
269+
/// @brief Current server configuration
324270
///
325271
/// This is a structure that will hold all configuration.
326272
/// @todo: migrate all other parameters to that structure.
327273
SrvConfigPtr configuration_;
328274

329-
/// @name Configuration List.
275+
/// @brief Staging server configuration
330276
///
331-
//@{
332-
/// @brief Server configuration list type.
333-
typedef std::list<SrvConfigPtr> SrvConfigList;
334-
335-
/// @brief Container holding all previous and current configurations.
336-
SrvConfigList configs_;
337-
//@}
277+
/// This is a structure that holds configuration until it is applied.
278+
SrvConfigPtr staging_configuration_;
338279

339280
/// @name Map of external configurations.
340281
///

0 commit comments

Comments
 (0)