]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[430-configure-location-of-datadir] Moved datadir to server config and use it for v6
authorFrancis Dupont <fdupont@isc.org>
Wed, 6 Mar 2019 17:34:22 +0000 (18:34 +0100)
committerFrancis Dupont <fdupont@isc.org>
Fri, 15 Mar 2019 23:23:05 +0000 (00:23 +0100)
13 files changed:
doc/examples/kea6/all-keys.json
doc/guide/dhcp6-srv.xml
src/bin/dhcp4/tests/dhcp4_test_utils.cc
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/get_config_unittest.cc
src/lib/dhcpsrv/cfgmgr.cc
src/lib/dhcpsrv/cfgmgr.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/srv_config.cc
src/lib/dhcpsrv/srv_config.h

index 5c250a124e68edcc460d46904d2d9a0ac7fc5261..0d5c312f7025e652a432a0f63b34c9722511eb8a 100644 (file)
             // Queue type was mandatory.
             "queue-type": "kea-ring6"
         }
+       // missing data-directory
     },
 
     // Logging configuration begins here.
index 531414ac899edbc225228967cda8c30d3fc57888..293304fa2259b68870d03408fb1688956b1bbb15 100644 (file)
@@ -4444,6 +4444,22 @@ autogenerated IDs are not stable across configuration changes.
       identifier is explicitly specified in the configuration.</para>
     </section>
 
+    <section xml:id="data-directory">
+      <title>DHCPv6 data directory</title>
+      <para>The Kea DHCPv6 server puts the server identifier file and the
+      default memory lease file into its data directory. By default
+      this directory is <filename><userinput>prefix</userinput>/var/kea</filename>
+      but this location can be changed using the
+      <command>data-directory</command> global parameter as in:
+<screen>
+"Dhcp6": {
+    "data-directory": <userinput>/var/tmp/kea-server6</userinput>,
+    ...
+}
+</screen>
+      </para>
+    </section>
+
     <section xml:id="stateless-dhcp6">
       <title>Stateless DHCPv6 (Information-Request Message)</title>
       <para>Typically DHCPv6 is used to assign both addresses and options. These
index 2083ad9270fb48e8d47670ab5f119ad9208152af..0f23420a64d4c6c3f7d9cf84aa7c21d02bafee61 100644 (file)
@@ -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<void>(::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();
index 84ba14ddc61b321f85efa2021f7a1e259223e096..f3014957ff8cd3556177c65f3e594b83cbd95c2e 100644 (file)
@@ -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()));
index fff19d006c638e1e8ea95b54b054ffd1807bcc7a..bb62c2f3050013c6b3ec2158b3ab512acb3dfda3 100644 (file)
@@ -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;
index ebb285e8c2d7100573087025ebc13df06e46ed16..063a91e34484b30e337a98a465920b804c6fafd6 100644 (file)
@@ -5451,6 +5451,71 @@ TEST_F(Dhcp6ParserTest, rsooBogusName) {
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 
+/// 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) {
index f25e164586057124be688ccb18ab50ba28307075..da0ed3bbd253925072f4d0c0b7be8f80b36adbd4 100644 (file)
@@ -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<void>(::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<void>(::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();
index abb8f461b4a99cd9e175a13cb50741bc988d2b67..0c6f91c7cc360c61430fac895527831bf708adcf 100644 (file)
@@ -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"
index db59f1b1b9770712671bab6b5535d91ea2e5642d..eb93c5985ece87478da3029f0673247b18bca8ce 100644 (file)
@@ -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() {
index 5df381bcc30c4abd10f39c1ebb98e718f8641427..8960bbd6c250f6beb76c384ef10391b9fbd59811 100644 (file)
@@ -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_;
 
index d060e220574083994f3563c49d962eaf9c020468..0eafe27254491ebf4b154bbf5525c899b603ae14 100644 (file)
@@ -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());
index f335fc5360a8e607e038ecdc8ceaf12f05d41f39..d011cc16900ab63916b67d7fc201ac17f038cdef 100644 (file)
@@ -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<long long>(decline_timer_)));
index 7dcb361c78bb8434ab122989661ee300ecf06c18..18c21d17e45181cc86969ca253a683996cafdf7f 100644 (file)
@@ -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