]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3315] fix ProcessSpawn IOService
authorRazvan Becheriu <razvan@isc.org>
Sat, 20 Apr 2024 08:07:22 +0000 (11:07 +0300)
committerRazvan Becheriu <razvan@isc.org>
Mon, 22 Apr 2024 19:59:07 +0000 (22:59 +0300)
17 files changed:
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/dhcp4_test_utils.h
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/hooks/dhcp/run_script/run_script.cc
src/hooks/dhcp/run_script/run_script.h
src/hooks/dhcp/run_script/run_script_callouts.cc
src/hooks/dhcp/run_script/tests/run_script_unittests.cc
src/lib/asiolink/process_spawn.cc
src/lib/asiolink/process_spawn.h
src/lib/asiolink/tests/process_spawn_unittest.cc
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
src/lib/mysql/mysql_connection.cc
src/lib/pgsql/pgsql_connection.cc

index 3145be6a0ad05465baf09d208ee8c04ea2037fcd..2e8af5434c3ab1c3fd7c4bf4646ca01e09900b69 100644 (file)
@@ -7,6 +7,7 @@
 #include <config.h>
 
 #include <asiolink/io_service_mgr.h>
+#include <asiolink/process_spawn.h>
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <config/command_mgr.h>
@@ -1166,6 +1167,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t server_port /*= DHCP4_SERVER_P
     }
     server_ = this; // remember this instance for later use in handlers
 
+    // ProcessSpawn uses IO service to handle signal set events.
+    ProcessSpawn::setIOService(getIOService());
+
     // TimerMgr uses IO service to run asynchronous timers.
     TimerMgr::instance()->setIOService(getIOService());
 
index 73cae9b8e7cd0b20894b9c0555f8c7d5dd4bba89..de9d16012e5f3b996aabc2a9b06e1a3ebd59007a 100644 (file)
@@ -2908,6 +2908,9 @@ Dhcpv4SrvTest::loadConfigFile(const string& path) {
 
     // Reset DatabaseConnection IO service.
     DatabaseConnection::setIOService(IOServicePtr());
+
+    // Reset ProcessSpawn IO service.
+    ProcessSpawn::setIOService(IOServicePtr());
 }
 
 /// @brief Class which handles initialization of database
index 2db8a1ac5a452fb5c0166170c7a28d1c8a3f87b0..249429709ee27b18f902e2f5022042961429e128 100644 (file)
@@ -12,6 +12,8 @@
 #define DHCP4_TEST_UTILS_H
 
 #include <gtest/gtest.h>
+
+#include <asiolink/process_spawn.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcp/option4_addrlst.h>
 #include <dhcp/pkt4.h>
@@ -123,9 +125,13 @@ public:
         // Create a default lease database backend.
         std::string dbconfig = "type=memfile universe=4 persist=false";
         isc::dhcp::LeaseMgrFactory::create(dbconfig);
+
         // Create fixed server id.
         server_id_.reset(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER,
                                             asiolink::IOAddress("192.0.3.1")));
+
+        isc::asiolink::ProcessSpawn::setIOService(getIOService());
+
         db::DatabaseConnection::setIOService(getIOService());
 
         dhcp::TimerMgr::instance()->setIOService(getIOService());
index 1e4af158d1481c76fb1a286ba4a37a159b0a6056..35dbe1e0435787f413b777aca71c7e767e26f9cc 100644 (file)
@@ -7,6 +7,7 @@
 #include <config.h>
 
 #include <asiolink/io_service_mgr.h>
+#include <asiolink/process_spawn.h>
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
 #include <config/command_mgr.h>
@@ -1186,6 +1187,9 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port /*= DHCP6_SERVER_P
     }
     server_ = this; // remember this instance for later use in handlers
 
+    // ProcessSpawn uses IO service to handle signal set events.
+    ProcessSpawn::setIOService(getIOService());
+
     // TimerMgr uses IO service to run asynchronous timers.
     TimerMgr::instance()->setIOService(getIOService());
 
index 1cc9abf2393b6a6ac8d918bd72d296570f602bbb..b52149342e84fef1b9a85ff1d778bd11501017b2 100644 (file)
@@ -277,6 +277,9 @@ Dhcpv6SrvTest::loadConfigFile(const string& path) {
 
     // Reset DatabaseConnection IO service.
     DatabaseConnection::setIOService(IOServicePtr());
+
+    // Reset ProcessSpawn IO service.
+    ProcessSpawn::setIOService(IOServicePtr());
 }
 
 /// @brief Class which handles initialization of database
index 9b13230ddf87384c4c167e1d9238d437aab431b4..e519a6e267ddf6c0d5e8bb1ad7d067234070bfe3 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <gtest/gtest.h>
 
+#include <asiolink/process_spawn.h>
 #include <dhcp6/dhcp6_srv.h>
 #include <dhcp6/parser_context.h>
 #include <dhcp/pkt6.h>
@@ -136,6 +137,9 @@ public:
         // Open the "memfile" database for leases
         std::string memfile = "type=memfile universe=6 persist=false";
         isc::dhcp::LeaseMgrFactory::create(memfile);
+
+        isc::asiolink::ProcessSpawn::setIOService(getIOService());
+
         db::DatabaseConnection::setIOService(getIOService());
 
         dhcp::TimerMgr::instance()->setIOService(getIOService());
index f496cfcbe44108be39f5f107a08d7cefe995075e..01ab56ad2a1901b7fd08ceece2206b449a1b6670 100644 (file)
@@ -18,8 +18,6 @@ using namespace std;
 namespace isc {
 namespace run_script {
 
-IOServicePtr RunScriptImpl::io_service_;
-
 RunScriptImpl::RunScriptImpl() : io_context_(new IOService()), name_(), sync_(false) {
 }
 
@@ -33,7 +31,7 @@ RunScriptImpl::configure(LibraryHandle& handle) {
         isc_throw(InvalidParameter, "The 'name' parameter must be a string");
     }
     try {
-        ProcessSpawn process(IOServicePtr(), name->stringValue());
+        ProcessSpawn process(false, name->stringValue());
     } catch (const isc::Exception& ex) {
         isc_throw(InvalidParameter, "Invalid 'name' parameter: " << ex.what());
     }
@@ -49,7 +47,7 @@ RunScriptImpl::configure(LibraryHandle& handle) {
 
 void
 RunScriptImpl::runScript(const ProcessArgs& args, const ProcessEnvVars& vars) {
-    ProcessSpawn process(getIOService(), name_, args, vars);
+    ProcessSpawn process(false, name_, args, vars);
     process.spawn(true);
 }
 
index b276de76dff4ff13a9712520a81cdc8af7446969..829fb2dc483d672d315b675f0a51c03af7ccc444 100644 (file)
@@ -242,34 +242,6 @@ public:
     /// @brief This function parses and applies configuration parameters.
     void configure(isc::hooks::LibraryHandle& handle);
 
-    /// @brief Get the hook I/O service.
-    ///
-    /// @return the hook I/O service.
-    isc::asiolink::IOServicePtr getIOContext() {
-        return (io_context_);
-    }
-
-    /// @brief Set the hook I/O service.
-    ///
-    /// @param io_service the hook I/O service.
-    void setIOContext(isc::asiolink::IOServicePtr io_service) {
-        io_context_ = io_service;
-    }
-
-    /// @brief Get the hook I/O service.
-    ///
-    /// @return the hook I/O service.
-    static isc::asiolink::IOServicePtr getIOService() {
-        return (io_service_);
-    }
-
-    /// @brief Set the hook I/O service.
-    ///
-    /// @param io_service the hook I/O service.
-    static void setIOService(isc::asiolink::IOServicePtr io_service) {
-        io_service_ = io_service;
-    }
-
 private:
 
     /// @brief The IOService object, used for all ASIO operations.
@@ -284,9 +256,6 @@ private:
     /// exits, otherwise the call will return immediately after the script is
     /// started.
     bool sync_;
-
-    /// @brief The hook I/O service.
-    static isc::asiolink::IOServicePtr io_service_;
 };
 
 /// @brief The type of shared pointers to Run Script implementations.
index 2f54de78a4eb3b2f32eccd1feca495a91f53d255..bcb83a513cb3dd14281a1fa3180f5a4a1255bcc0 100644 (file)
@@ -81,57 +81,11 @@ int load(LibraryHandle& handle) {
 ///
 /// @return always 0.
 int unload() {
-    if (impl) {
-        IOServiceMgr::instance().unregisterIOService(impl->getIOContext());
-    }
     impl.reset();
-    if (RunScriptImpl::getIOService()) {
-        RunScriptImpl::getIOService()->stop();
-        RunScriptImpl::getIOService()->restart();
-        try {
-            RunScriptImpl::getIOService()->poll();
-        } catch (...) {
-        }
-    }
-    RunScriptImpl::setIOService(IOServicePtr());
     LOG_INFO(run_script_logger, RUN_SCRIPT_UNLOAD);
     return (0);
 }
 
-/// @brief dhcp4_srv_configured callout implementation.
-///
-/// @param handle callout handle.
-int dhcp4_srv_configured(CalloutHandle& handle) {
-    try {
-        RunScriptImpl::setIOService(impl->getIOContext());
-        IOServiceMgr::instance().registerIOService(impl->getIOContext());
-
-    } catch (const exception& ex) {
-        LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
-            .arg(ex.what());
-        handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
-        return (1);
-    }
-    return (0);
-}
-
-/// @brief dhcp6_srv_configured callout implementation.
-///
-/// @param handle callout handle.
-int dhcp6_srv_configured(CalloutHandle& handle) {
-    try {
-        RunScriptImpl::setIOService(impl->getIOContext());
-        IOServiceMgr::instance().registerIOService(impl->getIOContext());
-
-    } catch (const exception& ex) {
-        LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR)
-            .arg(ex.what());
-        handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
-        return (1);
-    }
-    return (0);
-}
-
 /// @brief handle @ref lease4_renew hook and set environment parameters for the
 /// script.
 /// IN: query4 subnet4 clientid hwaddr lease4
index dc8a18361f5cc852ce82f7c5525d6ac08a9fc4af..9292cc66c8897c58ef9c0c14c57232af37d24488 100644 (file)
@@ -788,13 +788,13 @@ public:
     /// @brief Constructor.
     RunScriptTest() :
         co_manager_(new CalloutManager(1)), io_service_(new IOService()) {
-        RunScriptImpl::setIOService(io_service_);
+        ProcessSpawn::setIOService(io_service_);
         clearLogFile();
     }
 
     /// @brief Destructor.
     ~RunScriptTest() {
-        RunScriptImpl::setIOService(IOServicePtr());
+        ProcessSpawn::setIOService(IOServicePtr());
         clearLogFile();
     }
 
index 9f55b51d28f86c09bf89b8d54bada05e008c64fb..32e0ec7644e9f8b02e690eb70b1eb5436b561f00 100644 (file)
@@ -77,20 +77,18 @@ public:
 
     /// @brief Constructor.
     ///
-    /// @param io_service The IOService which handles signal handlers.
+    /// @param sync enables synchronous mode (spawning thread waits on
+    /// child to complete if true)
     /// @param executable A full path to the program to be executed.
     /// @param args Arguments for the program to be executed.
     /// @param vars Environment variables for the program to be executed.
     /// @param inherit_env whether the spawned process will inherit the
-    ///        environment before adding 'vars' on top.
-    /// @param sync enables synchronous mode (spawning thread waits on
-    /// child to complete if true)
-    ProcessSpawnImpl(IOServicePtr io_service,
+    /// environment before adding 'vars' on top.
+    ProcessSpawnImpl(const bool sync,
                      const std::string& executable,
                      const ProcessArgs& args,
                      const ProcessEnvVars& vars,
-                     const bool inherit_env,
-                     const bool sync);
+                     const bool inherit_env);
 
     /// @brief Destructor.
     ~ProcessSpawnImpl();
@@ -211,11 +209,16 @@ private:
     /// for any child process
     /// @param sync whether this function is called immediately after spawning
     /// (synchronous) or not (asynchronous, default).
-    static void waitForProcess(int signum, pid_t const wpid = -1, bool const sync = false);
+    static void waitForProcess(int signum, pid_t const wpid = -1,
+                               bool const sync = false);
 
     /// @brief A map holding the status codes of executed processes.
     static ProcessCollection process_collection_;
 
+    /// @brief Whether the process is waited immediately after spawning
+    /// (synchronous) or not (asynchronous, default).
+    bool sync_;
+
     /// @brief Path to an executable.
     std::string executable_;
 
@@ -236,13 +239,6 @@ private:
 
     /// @brief Mutex to protect internal state.
     static std::mutex mutex_;
-
-    /// @brief The IOService which handles IO operations.
-    IOServicePtr io_service_;
-
-    /// @brief Whether the process is waited immediately after spawning
-    /// (synchronous) or not (asynchronous, default).
-    bool sync_;
 };
 
 ProcessCollection ProcessSpawnImpl::process_collection_;
@@ -252,14 +248,13 @@ void ProcessSpawnImpl::IOSignalSetInitializer::initIOSignalSet(IOServicePtr io_s
     static IOSignalSetInitializer init(io_service);
 }
 
-ProcessSpawnImpl::ProcessSpawnImpl(IOServicePtr io_service,
+ProcessSpawnImpl::ProcessSpawnImpl(const bool sync,
                                    const std::string& executable,
                                    const ProcessArgs& args,
                                    const ProcessEnvVars& vars,
-                                   const bool inherit_env,
-                                   const bool sync)
-    : executable_(executable), args_(new char*[args.size() + 2]),
-      store_(false), io_service_(io_service), sync_(sync) {
+                                   const bool inherit_env)
+    : sync_(sync), executable_(executable), args_(new char*[args.size() + 2]),
+      store_(false) {
 
     // Size of vars except the trailing null
     size_t vars_size;
@@ -335,7 +330,7 @@ pid_t
 ProcessSpawnImpl::spawn(bool dismiss) {
     lock_guard<std::mutex> lk(mutex_);
     if (!sync_) {
-        ProcessSpawnImpl::IOSignalSetInitializer::initIOSignalSet(io_service_);
+        ProcessSpawnImpl::IOSignalSetInitializer::initIOSignalSet(ProcessSpawn::getIOService());
     }
     // Create the child
     pid_t pid = fork();
@@ -479,29 +474,14 @@ ProcessSpawnImpl::clearState(const pid_t pid) {
     }
 }
 
-ProcessSpawn::ProcessSpawn(IOServicePtr io_service,
-                           const std::string& executable,
-                           const ProcessArgs& args,
-                           const ProcessEnvVars& vars,
-                           const bool inherit_env /* = false */)
-    : impl_(new ProcessSpawnImpl(io_service,
-                                 executable,
-                                 args,
-                                 vars,
-                                 inherit_env,
-                                 /* sync = */ false)) {
-}
+IOServicePtr ProcessSpawn::io_service_;
 
-ProcessSpawn::ProcessSpawn(const std::string& executable,
+ProcessSpawn::ProcessSpawn(const bool sync,
+                           const std::string& executable,
                            const ProcessArgs& args,
                            const ProcessEnvVars& vars,
                            const bool inherit_env /* = false */)
-    : impl_(new ProcessSpawnImpl(IOServicePtr(new IOService()),
-                                 executable,
-                                 args,
-                                 vars,
-                                 inherit_env,
-                                 /* sync = */ true)) {
+    : impl_(new ProcessSpawnImpl(sync, executable, args, vars, inherit_env)) {
 }
 
 std::string
index 5cdb70721fddd396093006d67785d6ebdf94386f..f6bcb62ed9d8bbc079d84041854c017d17648dc4 100644 (file)
@@ -63,33 +63,19 @@ public:
 
     /// @brief Constructor.
     ///
-    /// @param io_service The IOService which handles signal handlers.
+    /// @param sync enables synchronous mode (spawning thread waits on
+    /// child to complete if true)
     /// @param executable A full path to the program to be executed.
     /// @param args Arguments for the program to be executed.
     /// @param vars Environment variables for the program to be executed.
     /// @param inherit_env whether the spawned process will inherit the
-    ///        environment before adding 'vars' on top.
-    ProcessSpawn(isc::asiolink::IOServicePtr io_service,
+    /// environment before adding 'vars' on top.
+    ProcessSpawn(bool sync,
                  const std::string& executable,
                  const ProcessArgs& args = ProcessArgs(),
                  const ProcessEnvVars& vars = ProcessEnvVars(),
                  const bool inherit_env = false);
 
-    /// @brief Constructor for synchronous spawn and wait.
-    ///
-    /// Abstracts away the IO service detail since the caller is not
-    /// required to interact with it in sync mode.
-    ///
-    /// @param executable A full path to the program to be executed.
-    /// @param args Arguments for the program to be executed.
-    /// @param vars Environment variables for the program to be executed.
-    /// @param inherit_env whether the spawned process will inherit the
-    ///        environment before adding 'vars' on top.
-    ProcessSpawn(const std::string& executable,
-                 const ProcessArgs& args = ProcessArgs(),
-                 const ProcessEnvVars& vars = ProcessEnvVars(),
-                 const bool inherit_env = false);
-
     /// @brief Destructor.
     ~ProcessSpawn() = default;
 
@@ -155,8 +141,25 @@ public:
     /// @param pid A process pid.
     void clearState(const pid_t pid);
 
+    /// @brief Get the I/O service.
+    ///
+    /// @return the I/O service.
+    static isc::asiolink::IOServicePtr getIOService() {
+        return (io_service_);
+    }
+
+    /// @brief Set the I/O service.
+    ///
+    /// @param io_service the I/O service.
+    static void setIOService(isc::asiolink::IOServicePtr io_service) {
+        io_service_ = io_service;
+    }
+
 private:
 
+    /// @brief The IOService object, used for all ASIO operations.
+    static isc::asiolink::IOServicePtr io_service_;
+
     /// @brief A smart pointer to the implementation of this class.
     ProcessSpawnImplPtr impl_;
 };
index 63355fb8de0569634d10f38b92674fe016a2da2f..e7b66888f4666a5b97c7e03976a50e1c41ba7be4 100644 (file)
@@ -56,6 +56,7 @@ public:
     ProcessSpawnTest() :
         io_service_(getIOService()), test_timer_(io_service_),
         test_time_ms_(0), io_signal_set_(), processed_signals_() {
+        ProcessSpawn::setIOService(getIOService());
 
         io_signal_set_.reset(new IOSignalSet(io_service_,
                                              std::bind(&ProcessSpawnTest::processSignal,
@@ -114,7 +115,7 @@ TEST_F(ProcessSpawnTest, spawnWithArgs) {
     args.push_back("-e");
     args.push_back("64");
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args);
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -148,7 +149,7 @@ TEST_F(ProcessSpawnTest, spawnWithArgsAndEnvVars) {
     args.push_back("TEST_VARIABLE_VALUE");
     vars.push_back("TEST_VARIABLE_NAME=TEST_VARIABLE_VALUE");
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args, vars);
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args, vars);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -180,7 +181,7 @@ TEST_F(ProcessSpawnTest, spawnTwoProcesses) {
     vector<string> args;
     args.push_back("-p");
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args);
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args);
     pid_t pid1 = 0;
     ASSERT_NO_THROW(pid1 = process.spawn());
 
@@ -236,7 +237,7 @@ TEST_F(ProcessSpawnTest, spawnTwoProcesses) {
 // This test verifies that the external application can be ran without
 // arguments and that the exit code is gathered.
 TEST_F(ProcessSpawnTest, spawnNoArgs) {
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH);
+    ProcessSpawn process(false, TEST_SCRIPT_SH);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -285,14 +286,14 @@ TEST_F(ProcessSpawnTest, spawnNoArgs) {
 // application can't be executed.
 TEST_F(ProcessSpawnTest, invalidExecutable) {
     std::string expected = "File not found: foo";
-    ASSERT_THROW_MSG(ProcessSpawn process(io_service_, "foo"),
+    ASSERT_THROW_MSG(ProcessSpawn process(false, "foo"),
                      ProcessSpawnError, expected);
 
     std::string name = INVALID_TEST_SCRIPT_SH;
 
     expected = "File not executable: ";
     expected += name;
-    ASSERT_THROW_MSG(ProcessSpawn process(io_service_, name),
+    ASSERT_THROW_MSG(ProcessSpawn process(false, name),
                      ProcessSpawnError, expected);
 }
 
@@ -306,7 +307,7 @@ TEST_F(ProcessSpawnTest, getCommandLine) {
         args.push_back("-y");
         args.push_back("foo");
         args.push_back("bar");
-        ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args);
+        ProcessSpawn process(false, TEST_SCRIPT_SH, args);
         std::string expected = TEST_SCRIPT_SH;
         expected += " -x -y foo bar";
         EXPECT_EQ(expected, process.getCommandLine());
@@ -314,7 +315,7 @@ TEST_F(ProcessSpawnTest, getCommandLine) {
 
     {
         // Case 2: no arguments.
-        ProcessSpawn process(io_service_, TEST_SCRIPT_SH);
+        ProcessSpawn process(false, TEST_SCRIPT_SH);
         EXPECT_EQ(TEST_SCRIPT_SH, process.getCommandLine());
     }
 }
@@ -328,7 +329,7 @@ TEST_F(ProcessSpawnTest, isRunning) {
     args.push_back("-s");
     args.push_back("10");
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args);
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -362,7 +363,7 @@ TEST_F(ProcessSpawnTest, inheritEnv) {
 
     ProcessEnvVars vars{"VAR=value"};
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args, vars,
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args, vars,
                          /* inherit_env = */ true);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
@@ -396,7 +397,7 @@ TEST_F(ProcessSpawnTest, inheritEnvWithParentVar) {
 
     ProcessEnvVars vars{"VAR=value"};
 
-    ProcessSpawn process(io_service_, TEST_SCRIPT_SH, args, vars,
+    ProcessSpawn process(false, TEST_SCRIPT_SH, args, vars,
                          /* inherit_env = */ true);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
@@ -428,7 +429,7 @@ TEST_F(ProcessSpawnTest, spawnWithArgsSync) {
     args.push_back("-e");
     args.push_back("64");
 
-    ProcessSpawn process(TEST_SCRIPT_SH, args);
+    ProcessSpawn process(true, TEST_SCRIPT_SH, args);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -446,7 +447,7 @@ TEST_F(ProcessSpawnTest, spawnWithArgsAndEnvVarsSync) {
     args.push_back("TEST_VARIABLE_VALUE");
     vars.push_back("TEST_VARIABLE_NAME=TEST_VARIABLE_VALUE");
 
-    ProcessSpawn process(TEST_SCRIPT_SH, args, vars);
+    ProcessSpawn process(true, TEST_SCRIPT_SH, args, vars);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -462,7 +463,7 @@ TEST_F(ProcessSpawnTest, spawnTwoProcessesSync) {
     vector<string> args;
     args.push_back("-p");
 
-    ProcessSpawn process(TEST_SCRIPT_SH, args);
+    ProcessSpawn process(true, TEST_SCRIPT_SH, args);
     pid_t pid1 = 0;
     ASSERT_NO_THROW(pid1 = process.spawn());
 
@@ -485,7 +486,7 @@ TEST_F(ProcessSpawnTest, spawnTwoProcessesSync) {
 // This test verifies that the external application can be ran synchronously
 // without arguments and that the exit code is gathered.
 TEST_F(ProcessSpawnTest, spawnNoArgsSync) {
-    ProcessSpawn process(TEST_SCRIPT_SH);
+    ProcessSpawn process(true, TEST_SCRIPT_SH);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -501,14 +502,14 @@ TEST_F(ProcessSpawnTest, spawnNoArgsSync) {
 // application can't be executed synchronously.
 TEST_F(ProcessSpawnTest, invalidExecutableSync) {
     std::string expected = "File not found: foo";
-    ASSERT_THROW_MSG(ProcessSpawn process("foo"),
+    ASSERT_THROW_MSG(ProcessSpawn process(true, "foo"),
                      ProcessSpawnError, expected);
 
     std::string name = INVALID_TEST_SCRIPT_SH;
 
     expected = "File not executable: ";
     expected += name;
-    ASSERT_THROW_MSG(ProcessSpawn process(name),
+    ASSERT_THROW_MSG(ProcessSpawn process(true, name),
                      ProcessSpawnError, expected);
 }
 
@@ -522,7 +523,7 @@ TEST_F(ProcessSpawnTest, getCommandLineSync) {
         args.push_back("-y");
         args.push_back("foo");
         args.push_back("bar");
-        ProcessSpawn process(TEST_SCRIPT_SH, args);
+        ProcessSpawn process(true, TEST_SCRIPT_SH, args);
         std::string expected = TEST_SCRIPT_SH;
         expected += " -x -y foo bar";
         EXPECT_EQ(expected, process.getCommandLine());
@@ -530,7 +531,7 @@ TEST_F(ProcessSpawnTest, getCommandLineSync) {
 
     {
         // Case 2: no arguments.
-        ProcessSpawn process(TEST_SCRIPT_SH);
+        ProcessSpawn process(true, TEST_SCRIPT_SH);
         EXPECT_EQ(TEST_SCRIPT_SH, process.getCommandLine());
     }
 }
@@ -538,7 +539,7 @@ TEST_F(ProcessSpawnTest, getCommandLineSync) {
 // This test verifies that the synchronous process reports as not running after
 // it was spawned.
 TEST_F(ProcessSpawnTest, isRunningSync) {
-    ProcessSpawn process(TEST_SCRIPT_SH);
+    ProcessSpawn process(true, TEST_SCRIPT_SH);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
 
@@ -553,7 +554,7 @@ TEST_F(ProcessSpawnTest, inheritEnvSync) {
 
     ProcessEnvVars vars{"VAR=value"};
 
-    ProcessSpawn process(TEST_SCRIPT_SH, args, vars,
+    ProcessSpawn process(true, TEST_SCRIPT_SH, args, vars,
                          /* inherit_env = */ true);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
@@ -571,7 +572,7 @@ TEST_F(ProcessSpawnTest, inheritEnvWithParentVarSync) {
 
     ProcessEnvVars vars{"VAR=value"};
 
-    ProcessSpawn process(TEST_SCRIPT_SH, args, vars,
+    ProcessSpawn process(true, TEST_SCRIPT_SH, args, vars,
                          /* inherit_env = */ true);
     pid_t pid = 0;
     ASSERT_NO_THROW(pid = process.spawn());
index c89b02ee288f0511ad6d42e05a7d43c15eab8381..aa534665b2a3db3859101f5aaf5e3076a64538e1 100644 (file)
@@ -7,7 +7,6 @@
 #include <config.h>
 
 #include <asiolink/addr_utilities.h>
-#include <database/database_connection.h>
 #include <dhcpsrv/cfg_consistency.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dhcpsrv_exceptions.h>
@@ -210,7 +209,7 @@ LFCSetup::setup(const uint32_t lfc_interval,
     args.push_back("ignored-path");
 
     // Create the process (do not start it yet).
-    process_.reset(new ProcessSpawn(DatabaseConnection::getIOService(), executable, args));
+    process_.reset(new ProcessSpawn(false, executable, args));
 
     // If we've been told to run it once now, invoke the callback directly.
     if (run_once_now) {
index 7e2c656017e302985ac641975248d39a1d79d5c1..ecec43ddaa1cb337f622cab732ae4694bc81f339 100644 (file)
@@ -118,6 +118,7 @@ public:
 
         timer_mgr_->setIOService(io_service_);
         DatabaseConnection::setIOService(io_service_);
+        ProcessSpawn::setIOService(io_service_);
 
         std::ostringstream s;
         s << KEA_LFC_BUILD_DIR << "/kea-lfc";
index f25029cdc1422530960ce308f8eee17037d8776f..052e8539a2dba9d2ee12050b39f7d80b527b3447 100644 (file)
@@ -434,7 +434,7 @@ MySqlConnection::initializeSchema(const ParameterMap& parameters) {
     kea_admin_parameters.insert(kea_admin_parameters.begin(), "db-init");
 
     // Run.
-    ProcessSpawn kea_admin(KEA_ADMIN_, kea_admin_parameters, vars,
+    ProcessSpawn kea_admin(true, KEA_ADMIN_, kea_admin_parameters, vars,
                            /* inherit_env = */ true);
     DB_LOG_INFO(MYSQL_INITIALIZE_SCHEMA).arg(kea_admin.getCommandLine());
     pid_t const pid(kea_admin.spawn());
index 68b7a4cba429a205d3c6ee81a72be6fe4b7b4844..b7a45628c75ee506c8f28fe584291ceba9d94741 100644 (file)
@@ -237,7 +237,7 @@ PgSqlConnection::initializeSchema(const ParameterMap& parameters) {
     kea_admin_parameters.insert(kea_admin_parameters.begin(), "db-init");
 
     // Run.
-    ProcessSpawn kea_admin(KEA_ADMIN_, kea_admin_parameters, vars,
+    ProcessSpawn kea_admin(true, KEA_ADMIN_, kea_admin_parameters, vars,
                            /* inherit_env = */ true);
     DB_LOG_INFO(PGSQL_INITIALIZE_SCHEMA).arg(kea_admin.getCommandLine());
     pid_t const pid(kea_admin.spawn());