From 381371a7a250e06d0d46bf5fb6f8ba8f2ce27687 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Wed, 6 Mar 2019 18:34:22 +0100 Subject: [PATCH] [430-configure-location-of-datadir] Moved datadir to server config and use it for v6 --- doc/examples/kea6/all-keys.json | 1 + doc/guide/dhcp6-srv.xml | 16 +++ src/bin/dhcp4/tests/dhcp4_test_utils.cc | 11 +- src/bin/dhcp6/ctrl_dhcp6_srv.cc | 5 +- src/bin/dhcp6/json_config_parser.cc | 27 ++++ src/bin/dhcp6/tests/config_parser_unittest.cc | 65 +++++++++ src/bin/dhcp6/tests/dhcp6_test_utils.cc | 14 +- src/bin/dhcp6/tests/get_config_unittest.cc | 124 ++++++++++++++---- src/lib/dhcpsrv/cfgmgr.cc | 15 +-- src/lib/dhcpsrv/cfgmgr.h | 15 --- src/lib/dhcpsrv/memfile_lease_mgr.cc | 7 +- src/lib/dhcpsrv/srv_config.cc | 27 +++- src/lib/dhcpsrv/srv_config.h | 22 ++++ 13 files changed, 271 insertions(+), 78 deletions(-) diff --git a/doc/examples/kea6/all-keys.json b/doc/examples/kea6/all-keys.json index 5c250a124e..0d5c312f70 100644 --- a/doc/examples/kea6/all-keys.json +++ b/doc/examples/kea6/all-keys.json @@ -645,6 +645,7 @@ // Queue type was mandatory. "queue-type": "kea-ring6" } + // missing data-directory }, // Logging configuration begins here. diff --git a/doc/guide/dhcp6-srv.xml b/doc/guide/dhcp6-srv.xml index 531414ac89..293304fa22 100644 --- a/doc/guide/dhcp6-srv.xml +++ b/doc/guide/dhcp6-srv.xml @@ -4444,6 +4444,22 @@ autogenerated IDs are not stable across configuration changes. identifier is explicitly specified in the configuration. +
+ DHCPv6 data directory + The Kea DHCPv6 server puts the server identifier file and the + default memory lease file into its data directory. By default + this directory is prefix/var/kea + but this location can be changed using the + data-directory global parameter as in: + +"Dhcp6": { + "data-directory": /var/tmp/kea-server6, + ... +} + + +
+
Stateless DHCPv6 (Information-Request Message) Typically DHCPv6 is used to assign both addresses and options. These diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.cc b/src/bin/dhcp4/tests/dhcp4_test_utils.cc index 2083ad9270..0f23420a64 100644 --- a/src/bin/dhcp4/tests/dhcp4_test_utils.cc +++ b/src/bin/dhcp4/tests/dhcp4_test_utils.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -36,18 +36,19 @@ namespace dhcp { namespace test { BaseServerTest::BaseServerTest() - : original_datadir_(CfgMgr::instance().getDataDir()) { - CfgMgr::instance().setDataDir(TEST_DATA_BUILDDIR); + : original_datadir_(CfgMgr::instance().getCurrentCfg()->getDataDir()) { + CfgMgr::instance().getStagingCfg()->setDataDir(TEST_DATA_BUILDDIR); } BaseServerTest::~BaseServerTest() { // Remove default lease file. std::ostringstream s2; - s2 << CfgMgr::instance().getDataDir() << "/" << "kea-leases4.csv"; + s2 << CfgMgr::instance().getStagingCfg()->getDataDir() + << "/" << "kea-leases4.csv"; static_cast(::remove(s2.str().c_str())); // Revert to original data directory. - CfgMgr::instance().setDataDir(original_datadir_); + CfgMgr::instance().getStagingCfg()->setDataDir(original_datadir_); // Revert to unit test logging, in case the test reconfigured it. isc::log::initLogger(); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 84ba14ddc6..f3014957ff 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -617,7 +617,8 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) { // Regenerate server identifier if needed. try { - const std::string duid_file = CfgMgr::instance().getDataDir() + "/" + + const std::string duid_file = + CfgMgr::instance().getStagingCfg()->getDataDir() + "/" + std::string(SERVER_DUID_FILE); DuidPtr duid = CfgMgr::instance().getStagingCfg()->getCfgDUID()->create(duid_file); server_->serverid_.reset(new Option(Option::V6, D6O_SERVERID, duid->getDuid())); diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index fff19d006c..bb62c2f305 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -65,6 +65,21 @@ using namespace isc::hooks; namespace { +/// @brief Checks if specified directory exists. +/// +/// @param dir_path Path to a directory. +/// @throw BadValue If the directory does not exist or is not a directory. +void dirExists(const string& dir_path) { + struct stat statbuf; + if (stat(dir_path.c_str(), &statbuf) < 0) { + isc_throw(BadValue, "Bad directory '" << dir_path + << "': " << strerror(errno)); + } + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { + isc_throw(BadValue, "'" << dir_path << "' is not a directory"); + } +} + /// @brief Parser for list of RSOO options /// /// This parser handles a Dhcp6/relay-supplied-options entry. It contains a @@ -148,6 +163,7 @@ public: /// /// Currently this method sets the following global parameters: /// + /// - data-directory /// - decline-probation-period /// - dhcp4o6-port /// - user-context @@ -156,6 +172,11 @@ public: /// or having incorrect values. void parse(const SrvConfigPtr& srv_config, const ConstElementPtr& global) { + // Set the data directory for server id file. + if (global->contains("data-directory")) { + srv_config->setDataDir(getString(global, "data-directory")); + } + // Set the probation period for decline handling. uint32_t probation_period = getUint32(global, "decline-probation-period"); @@ -458,6 +479,12 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, // with the parser code debugability, so I decided to keep it as a // series of independent ifs. + if (config_pair.first == "data-directory") { + // Specific check for this global parameter. + dirExists(config_pair.second->stringValue()); + continue; + } + if (config_pair.first == "option-def") { // This is converted to SimpleParser and is handled already above. continue; diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index ebb285e8c2..063a91e344 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -5451,6 +5451,71 @@ TEST_F(Dhcp6ParserTest, rsooBogusName) { EXPECT_TRUE(errorContainsPosition(status, "")); } +/// Check that not existent data directory returns an error. +TEST_F(Dhcp6ParserTest, notExistDataDir) { + + string config_txt = "{\n" + "\"data-directory\": \"/does-not-exist--\"\n" + "}"; + ConstElementPtr config; + ASSERT_NO_THROW(config = parseDHCP6(config_txt)); + + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config)); + + // returned value should be 1 (error) + int rcode; + ConstElementPtr comment = parseAnswer(rcode, status); + EXPECT_EQ(1, rcode); + string text; + ASSERT_NO_THROW(text = comment->stringValue()); + EXPECT_EQ("Bad directory '/does-not-exist--': No such file or directory", + text); +} + +/// Check that not a directory data directory returns an error. +TEST_F(Dhcp6ParserTest, notDirDataDir) { + + string config_txt = "{\n" + "\"data-directory\": \"/dev/null\"\n" + "}"; + ConstElementPtr config; + ASSERT_NO_THROW(config = parseDHCP6(config_txt)); + + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config)); + + // returned value should be 1 (error) + int rcode; + ConstElementPtr comment = parseAnswer(rcode, status); + EXPECT_EQ(1, rcode); + string text; + ASSERT_NO_THROW(text = comment->stringValue()); + EXPECT_EQ("'/dev/null' is not a directory", text); +} + +/// Check that a valid data directory is accepted. +TEST_F(Dhcp6ParserTest, testDataDir) { + + string datadir(TEST_DATA_BUILDDIR); + string config_txt = "{\n" + "\"data-directory\": \"" + datadir + "\"\n" + "}"; + ConstElementPtr config; + ASSERT_NO_THROW(config = parseDHCP6(config_txt)); + extractConfig(config_txt); + + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config)); + + // returned value should be 0 (success); + checkResult(status, 0); + + // The value of data-directory was updated. + EXPECT_EQ(datadir, CfgMgr::instance().getStagingCfg()->getDataDir()); + EXPECT_NE(datadir, CfgMgr::instance().getCurrentCfg()->getDataDir()); +} + /// Check that the decline-probation-period value has a default value if not /// specified explicitly. TEST_F(Dhcp6ParserTest, declineTimerDefault) { diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index f25e164586..da0ed3bbd2 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -30,23 +30,25 @@ namespace test { const char* BaseServerTest::DUID_FILE = "kea-dhcp6-serverid"; BaseServerTest::BaseServerTest() - : original_datadir_(CfgMgr::instance().getDataDir()) { - CfgMgr::instance().setDataDir(TEST_DATA_BUILDDIR); + : original_datadir_(CfgMgr::instance().getCurrentCfg()->getDataDir()) { + CfgMgr::instance().getStagingCfg()->setDataDir(TEST_DATA_BUILDDIR); } BaseServerTest::~BaseServerTest() { // Remove test DUID file. std::ostringstream s; - s << CfgMgr::instance().getDataDir() << "/" << DUID_FILE; + s << CfgMgr::instance().getStagingCfg()->getDataDir() + << "/" << DUID_FILE; static_cast(::remove(s.str().c_str())); // Remove default lease file. std::ostringstream s2; - s2 << CfgMgr::instance().getDataDir() << "/" << "kea-leases6.csv"; + s2 << CfgMgr::instance().getStagingCfg()->getDataDir() + << "/" << "kea-leases6.csv"; static_cast(::remove(s2.str().c_str())); // Revert to original data directory. - CfgMgr::instance().setDataDir(original_datadir_); + CfgMgr::instance().getStagingCfg()->setDataDir(original_datadir_); // Revert to unit test logging in case the test reconfigured logging. isc::log::initLogger(); diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc index abb8f461b4..0c6f91c7cc 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc +++ b/src/bin/dhcp6/tests/get_config_unittest.cc @@ -1399,13 +1399,17 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 43 "{\n" +" \"data-directory\": \"/tmp/k430/src/bin/dhcp6/tests\"\n" +" }\n", + // CONFIGURATION 44 +"{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" " },\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 44 + // CONFIGURATION 45 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1413,7 +1417,7 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 45 + // CONFIGURATION 46 "{\n" " \"decline-probation-period\": 12345,\n" " \"interfaces-config\": {\n" @@ -1422,7 +1426,7 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 46 + // CONFIGURATION 47 "{\n" " \"expired-leases-processing\": {\n" " \"flush-reclaimed-timer-wait-time\": 35,\n" @@ -1438,7 +1442,7 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 48 "{\n" " \"client-classes\": [\n" " {\n" @@ -1470,7 +1474,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 49 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1491,7 +1495,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 50 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1513,7 +1517,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 51 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1540,7 +1544,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 52 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1567,7 +1571,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 52 + // CONFIGURATION 53 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1590,7 +1594,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 53 + // CONFIGURATION 54 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1614,7 +1618,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 54 + // CONFIGURATION 55 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1643,7 +1647,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 55 + // CONFIGURATION 56 "{\n" " \"hosts-databases\": [\n" " {\n" @@ -1668,7 +1672,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 56 + // CONFIGURATION 57 "{\n" " \"comment\": \"A DHCPv6 server\",\n" " \"client-classes\": [\n" @@ -1765,7 +1769,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 57 + // CONFIGURATION 58 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1830,7 +1834,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 58 + // CONFIGURATION 59 "{\n" " \"config-control\": {\n" " \"config-databases\": [\n" @@ -6299,6 +6303,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n", // CONFIGURATION 43 "{\n" +" \"data-directory\": \"/tmp/k430/src/bin/dhcp6/tests\",\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": false,\n" @@ -6334,7 +6339,7 @@ const char* UNPARSED_CONFIGS[] = { " \"hooks-libraries\": [ ],\n" " \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n" " \"interfaces-config\": {\n" -" \"interfaces\": [ \"*\" ],\n" +" \"interfaces\": [ ],\n" " \"re-detect\": false\n" " },\n" " \"lease-database\": {\n" @@ -6421,7 +6426,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n", // CONFIGURATION 45 "{\n" -" \"decline-probation-period\": 12345,\n" +" \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": false,\n" " \"generated-prefix\": \"myhost\",\n" @@ -6482,6 +6487,67 @@ const char* UNPARSED_CONFIGS[] = { " }\n", // CONFIGURATION 46 "{\n" +" \"decline-probation-period\": 12345,\n" +" \"dhcp-ddns\": {\n" +" \"enable-updates\": false,\n" +" \"generated-prefix\": \"myhost\",\n" +" \"hostname-char-replacement\": \"\",\n" +" \"hostname-char-set\": \"\",\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"override-client-update\": false,\n" +" \"override-no-update\": false,\n" +" \"qualifying-suffix\": \"\",\n" +" \"replace-client-name\": \"never\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp-queue-control\": {\n" +" \"capacity\": 500,\n" +" \"enable-queue\": false,\n" +" \"queue-type\": \"kea-ring6\"\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"expired-leases-processing\": {\n" +" \"flush-reclaimed-timer-wait-time\": 25,\n" +" \"hold-reclaimed-time\": 3600,\n" +" \"max-reclaim-leases\": 100,\n" +" \"max-reclaim-time\": 250,\n" +" \"reclaim-timer-wait-time\": 10,\n" +" \"unwarned-reclaim-cycles\": 5\n" +" },\n" +" \"hooks-libraries\": [ ],\n" +" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"mac-sources\": [ \"any\" ],\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"relay-supplied-options\": [ \"65\" ],\n" +" \"sanity-checks\": {\n" +" \"lease-checks\": \"warn\"\n" +" },\n" +" \"server-id\": {\n" +" \"enterprise-id\": 0,\n" +" \"htype\": 0,\n" +" \"identifier\": \"\",\n" +" \"persist\": true,\n" +" \"time\": 0,\n" +" \"type\": \"LLT\"\n" +" },\n" +" \"shared-networks\": [ ],\n" +" \"subnet6\": [ ]\n" +" }\n", + // CONFIGURATION 47 +"{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": false,\n" @@ -6541,7 +6607,7 @@ const char* UNPARSED_CONFIGS[] = { " \"shared-networks\": [ ],\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 48 "{\n" " \"client-classes\": [\n" " {\n" @@ -6643,7 +6709,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 49 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6731,7 +6797,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 50 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6820,7 +6886,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 51 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6914,7 +6980,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 52 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7008,7 +7074,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 52 + // CONFIGURATION 53 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7098,7 +7164,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 53 + // CONFIGURATION 54 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7189,7 +7255,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 54 + // CONFIGURATION 55 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7285,7 +7351,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 55 + // CONFIGURATION 56 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7364,7 +7430,7 @@ const char* UNPARSED_CONFIGS[] = { " \"subnet6\": [ ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 56 + // CONFIGURATION 57 "{\n" " \"comment\": \"A DHCPv6 server\",\n" " \"client-classes\": [\n" @@ -7544,7 +7610,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"subnet6\": [ ]\n" " }\n", - // CONFIGURATION 57 + // CONFIGURATION 58 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -7718,7 +7784,7 @@ const char* UNPARSED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 58 + // CONFIGURATION 59 "{\n" " \"config-control\": {\n" " \"config-databases\": [\n" diff --git a/src/lib/dhcpsrv/cfgmgr.cc b/src/lib/dhcpsrv/cfgmgr.cc index db59f1b1b9..eb93c5985e 100644 --- a/src/lib/dhcpsrv/cfgmgr.cc +++ b/src/lib/dhcpsrv/cfgmgr.cc @@ -27,15 +27,6 @@ CfgMgr::instance() { return (cfg_mgr); } -std::string CfgMgr::getDataDir() const { - return (datadir_); -} - -void -CfgMgr::setDataDir(const std::string& datadir) { - datadir_ = datadir; -} - void CfgMgr::setD2ClientConfig(D2ClientConfigPtr& new_config) { ensureCurrentAllocated(); @@ -203,11 +194,7 @@ CfgMgr::mergeIntoCfg(const SrvConfigPtr& target_config, const uint32_t seq) { } } -CfgMgr::CfgMgr() - : datadir_(DHCP_DATA_DIR), d2_client_mgr_(), family_(AF_INET) { - // DHCP_DATA_DIR must be set set with -DDHCP_DATA_DIR="..." in Makefile.am - // Note: the definition of DHCP_DATA_DIR needs to include quotation marks - // See AM_CPPFLAGS definition in Makefile.am +CfgMgr::CfgMgr() : d2_client_mgr_(), family_(AF_INET) { } CfgMgr::~CfgMgr() { diff --git a/src/lib/dhcpsrv/cfgmgr.h b/src/lib/dhcpsrv/cfgmgr.h index 5df381bcc3..8960bbd6c2 100644 --- a/src/lib/dhcpsrv/cfgmgr.h +++ b/src/lib/dhcpsrv/cfgmgr.h @@ -80,18 +80,6 @@ public: /// accessing it. static CfgMgr& instance(); - /// @brief returns path do the data directory - /// - /// This method returns a path to writable directory that DHCP servers - /// can store data in. - /// @return data directory - std::string getDataDir() const; - - /// @brief Sets new data directory. - /// - /// @param datadir New data directory. - void setDataDir(const std::string& datadir); - /// @brief Updates the DHCP-DDNS client configuration to the given value. /// /// Passes the new configuration to the D2ClientMgr instance, @@ -312,9 +300,6 @@ private: /// @param seq Source configuration sequence number. void mergeIntoCfg(const SrvConfigPtr& taget_config, const uint32_t seq); - /// @brief directory where data files (e.g. server-id) are stored - std::string datadir_; - /// @brief Manages the DHCP-DDNS client and its configuration. D2ClientMgr d2_client_mgr_; diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index d060e22057..0eafe27254 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -1347,7 +1347,10 @@ Memfile_LeaseMgr::appendSuffix(const std::string& file_name, std::string Memfile_LeaseMgr::getDefaultLeaseFilePath(Universe u) const { std::ostringstream s; - s << CfgMgr::instance().getDataDir() << "/kea-leases"; + // Use the staging configuration because either it is called + // during (re)configuration or with a fresh configuration. + // In both cases the right value is at least at this place. + s << CfgMgr::instance().getStagingCfg()->getDataDir() << "/kea-leases"; s << (u == V4 ? "4" : "6"); s << ".csv"; return (s.str()); diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index f335fc5360..d011cc1690 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -25,8 +25,14 @@ using namespace isc::process; namespace isc { namespace dhcp { +// DHCP_DATA_DIR must be set set with -DDHCP_DATA_DIR="..." in Makefile.am +// Note: the definition of DHCP_DATA_DIR needs to include quotation marks +// See AM_CPPFLAGS definition in Makefile.am +const std::string +SrvConfig::DEFAULT_DATA_DIR = DHCP_DATA_DIR; + SrvConfig::SrvConfig() - : sequence_(0), cfg_iface_(new CfgIface()), + : sequence_(0), datadir_(DEFAULT_DATA_DIR), cfg_iface_(new CfgIface()), cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()), cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()), cfg_shared_networks4_(new CfgSharedNetworks4()), @@ -45,7 +51,8 @@ SrvConfig::SrvConfig() } SrvConfig::SrvConfig(const uint32_t sequence) - : sequence_(sequence), cfg_iface_(new CfgIface()), + : sequence_(sequence), + datadir_(DEFAULT_DATA_DIR),cfg_iface_(new CfgIface()), cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()), cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()), cfg_shared_networks4_(new CfgSharedNetworks4()), @@ -113,6 +120,8 @@ void SrvConfig::copy(SrvConfig& new_config) const { ConfigBase::copy(new_config); + // Replace data directory. + new_config.datadir_ = datadir_; // Replace interface configuration. new_config.cfg_iface_.reset(new CfgIface(*cfg_iface_)); // Replace option definitions. @@ -141,7 +150,8 @@ SrvConfig::equals(const SrvConfig& other) const { } // Common information is equal between objects, so check other values. - if ((*cfg_iface_ != *other.cfg_iface_) || + if ((datadir_ != other.datadir_) || + (*cfg_iface_ != *other.cfg_iface_) || (*cfg_option_def_ != *other.cfg_option_def_) || (*cfg_option_ != *other.cfg_option_) || (*class_dictionary_ != *other.class_dictionary_) || @@ -204,13 +214,15 @@ SrvConfig::mergeGlobals4(SrvConfig& other) { addConfiguredGlobal(other_global.first, other_global.second); } - // A handful of values are stored as members in SrvConfig. So we'll + // A handful of values are stored as members in SrvConfig. So we'll // iterate over the merged globals, setting approprate members. for (auto merged_global : getConfiguredGlobals()->mapValue()) { std::string name = merged_global.first; ConstElementPtr element = merged_global.second; try { - if (name == "decline-probation-period") { + if (name == "data-directory") { + setDataDir(element->stringValue()); + } if (name == "decline-probation-period") { setDeclinePeriod(element->intValue()); } else if (name == "echo-client-id") { @@ -284,6 +296,11 @@ SrvConfig::toElement() const { // Set user-context contextToElement(dhcp); + // Set data directory if DHCPv6 and not default. + if ((family == AF_INET6) && (getDataDir() != DEFAULT_DATA_DIR)) { + dhcp->set("data-directory", Element::create(getDataDir())); + } + // Set decline-probation-period dhcp->set("decline-probation-period", Element::create(static_cast(decline_timer_))); diff --git a/src/lib/dhcpsrv/srv_config.h b/src/lib/dhcpsrv/srv_config.h index 7dcb361c78..18c21d17e4 100644 --- a/src/lib/dhcpsrv/srv_config.h +++ b/src/lib/dhcpsrv/srv_config.h @@ -119,6 +119,25 @@ public: /// @return true if sequence numbers are equal. bool sequenceEquals(const SrvConfig& other); + /// @brief Default data directory. + static const std::string DEFAULT_DATA_DIR; + + /// @brief returns path do the data directory. + /// + /// This method returns a path to writable directory that DHCP servers + /// can store data in. + /// @return data directory. + std::string getDataDir() const { + return (datadir_); + } + + /// @brief Sets new data directory. + /// + /// @param datadir New data directory. + void setDataDir(const std::string& datadir) { + datadir_ = datadir; + } + /// @brief Returns non-const pointer to interface configuration. /// /// This function returns a non-const pointer to the interface @@ -692,6 +711,9 @@ private: /// @brief Sequence number identifying the configuration. uint32_t sequence_; + /// @brief directory where data files (e.g. server-id) are stored. + std::string datadir_; + /// @brief Interface configuration. /// /// Used to select interfaces on which the DHCP server will listen to -- 2.47.2