mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 05:27:55 +00:00
[master] Servers now create PID files
Merge branch 'trac3769'
This commit is contained in:
commit
cdce632add
@ -128,6 +128,35 @@ strings <userinput>path</userinput>/kea-dhcp-ddns | sed -n 's/;;;; //p'
|
||||
Upon start up the module will load its configuration and begin listening
|
||||
for NCRs based on that configuration.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
During startup the server will attempt to create a PID file of the
|
||||
form: [localstatedir]/[conf name].kea-dhcp-ddns.pid
|
||||
where:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><command>localstatedir</command>: The value as passed into the
|
||||
build configure script. It defaults defaults to "/usr/local/var". Note
|
||||
that this value may be overridden at run time by setting the environment
|
||||
variable KEA_PIDFILE_DIR. This is intended primarily for testing purposes.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>conf name</command>: The confguration file name
|
||||
used to start the server, minus all preceding path and file extension.
|
||||
For example, given a pathname of "/usr/local/etc/kea/myconf.txt", the
|
||||
portion used would be "myconf".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
If the file already exists and contains the PID of a live process,
|
||||
the server will issue a DHCP_DDNS_ALREADY_RUNNING log message and exit. It
|
||||
is possible, though unlikely, that the file is a remnant of a system crash
|
||||
and the process to which the PID belongs is unrelated to Kea. In such a
|
||||
case it would be necessary to manually delete the PID file.
|
||||
</para>
|
||||
|
||||
|
||||
</section> <!-- end start-stop -->
|
||||
<section id="d2-configuration">
|
||||
<title>Configuring the DHCP-DDNS Server</title>
|
||||
|
@ -106,6 +106,33 @@ strings <userinput>path</userinput>/kea-dhcp4 | sed -n 's/;;;; //p'
|
||||
access. Make sure you run this daemon as root.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
During startup the server will attempt to create a PID file of the
|
||||
form: [localstatedir]/[conf name].kea-dhcp4.pid
|
||||
where:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><command>localstatedir</command>: The value as passed into the
|
||||
build configure script. It defaults defaults to "/usr/local/var". Note
|
||||
that this value may be overridden at run time by setting the environment
|
||||
variable KEA_PIDFILE_DIR. This is intended primarily for testing purposes.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>conf name</command>: The confguration file name
|
||||
used to start the server, minus all preceding path and file extension.
|
||||
For example, given a pathname of "/usr/local/etc/kea/myconf.txt", the
|
||||
portion used would be "myconf".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
If the file already exists and contains the PID of a live process,
|
||||
the server will issue a DHCP4_ALREADY_RUNNING log message and exit. It
|
||||
is possible, though unlikely, that the file is a remnant of a system crash
|
||||
and the process to which the PID belongs is unrelated to Kea. In such a
|
||||
case it would be necessary to manually delete the PID file.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="dhcp4-configuration">
|
||||
|
@ -104,6 +104,32 @@ strings <userinput>path</userinput>/kea-dhcp6 | sed -n 's/;;;; //p'
|
||||
access. Make sure you run this daemon as root.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
During startup the server will attempt to create a PID file of the
|
||||
form: [localstatedir]/[conf name].kea-dhcp6.pid
|
||||
where:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><command>localstatedir</command>: The value as passed into the
|
||||
build configure script. It defaults defaults to "/usr/local/var". Note
|
||||
that this value may be overridden at run time by setting the environment
|
||||
variable KEA_PIDFILE_DIR. This is intended primarily for testing purposes.
|
||||
</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><command>conf name</command>: The confguration file name
|
||||
used to start the server, minus all preceding path and file extension.
|
||||
For example, given a pathname of "/usr/local/etc/kea/myconf.txt", the
|
||||
portion used would be "myconf".
|
||||
</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
If the file already exists and contains the PID of a live process,
|
||||
the server will issue a DHCP6_ALREADY_RUNNING log message and exit. It
|
||||
is possible, though unlikely, that the file is a remnant of a system crash
|
||||
and the process to which the PID belongs is unrelated to Kea. In such a
|
||||
case it would be necessary to manually delete the PID file.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="dhcp6-configuration">
|
||||
|
@ -100,6 +100,16 @@ documented in preceding log entries.
|
||||
This is an informational message issued after DHCP_DDNS has submitted DNS
|
||||
mapping additions which were received and accepted by an appropriate DNS server.
|
||||
|
||||
% DHCP_DDNS_ALREADY_RUNNING %1 already running? %2
|
||||
This is an error message that occurs when DHCP_DDNS encounters a pre-existing
|
||||
PID file which contains the PID of a running process. This most likely
|
||||
indicates an attempt to start a second instance of DHCP_DDNS using the
|
||||
same configuration file. It is possible, though unlikely, that the PID file
|
||||
is a remnant left behind by a server crash or power failure and the PID
|
||||
it contains refers to a process other than DHCP_DDNS. In such an event,
|
||||
it would be necessary to manually remove the PID file. The first argument is
|
||||
the DHCP_DDNS process name, the second contains the PID and PID file.
|
||||
|
||||
% DHCP_DDNS_AT_MAX_TRANSACTIONS application has %1 queued requests but has reached maximum number of %2 concurrent transactions
|
||||
This is a debug message that indicates that the application has DHCP_DDNS
|
||||
requests in the queue but is working as many concurrent requests as allowed.
|
||||
@ -277,6 +287,15 @@ no configured DDNS domains in the DHCP_DDNS configuration. Either the DHCP_DDNS
|
||||
configuration needs to be updated or the source of the FQDN itself should be
|
||||
investigated.
|
||||
|
||||
% DHCP_DDNS_PID_FILE_ERROR %1 could not create a PID file: %2
|
||||
This is an error message that occurs when DHCP_DDNS is unable to create
|
||||
its PID file. The log message should contain details sufficient to
|
||||
determine the underlying cause. The most likely culprits are that
|
||||
some portion of the pathname does not exist or a permissions issue. The
|
||||
default path is determined by --localstatedir configure paramter but
|
||||
may be overridden by setting environment variable, KEA_PIDFILE_DIR. The
|
||||
first argument is the DHCP_DDNS process name.
|
||||
|
||||
% DHCP_DDNS_PROCESS_INIT application init invoked
|
||||
This is a debug message issued when the DHCP-DDNS application enters
|
||||
its initialization method.
|
||||
|
@ -70,6 +70,8 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
|
||||
throw; // rethrow it
|
||||
}
|
||||
|
||||
setProcName(bin_name_);
|
||||
|
||||
// It is important that we set a default logger name because this name
|
||||
// will be used when the user doesn't provide the logging configuration
|
||||
// in the Kea configuration file.
|
||||
@ -87,6 +89,18 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) {
|
||||
Daemon::loggerInit(bin_name_.c_str(), verbose_);
|
||||
}
|
||||
|
||||
try {
|
||||
createPIDFile();
|
||||
} catch (const dhcp::DaemonPIDExists& ex) {
|
||||
LOG_FATAL(dctl_logger, DHCP_DDNS_ALREADY_RUNNING)
|
||||
.arg(bin_name_).arg(ex.what());
|
||||
isc_throw (LaunchError, "Launch Failed: " << ex.what());
|
||||
} catch (const std::exception& ex) {
|
||||
LOG_FATAL(dctl_logger, DHCP_DDNS_PID_FILE_ERROR)
|
||||
.arg(app_name_).arg(ex.what());
|
||||
isc_throw (LaunchError, "Launch failed: " << ex.what());
|
||||
}
|
||||
|
||||
// Log the starting of the service. Although this is the controller
|
||||
// module, use a "DHCP_DDNS_" prefix to the module (to conform to the
|
||||
// principle of least astonishment).
|
||||
@ -173,7 +187,7 @@ DControllerBase::parseArgs(int argc, char* argv[])
|
||||
isc_throw(InvalidUsage, "configuration file name missing");
|
||||
}
|
||||
|
||||
Daemon::init(optarg);
|
||||
setConfigFile(optarg);
|
||||
break;
|
||||
|
||||
case '?': {
|
||||
|
@ -50,6 +50,12 @@ public:
|
||||
isc::Exception(file, line, what) { };
|
||||
};
|
||||
|
||||
/// @brief Exception thrown when the controller launch fails.
|
||||
class LaunchError: public isc::Exception {
|
||||
public:
|
||||
LaunchError (const char* file, size_t line, const char* what) :
|
||||
isc::Exception(file, line, what) { };
|
||||
};
|
||||
|
||||
/// @brief Exception thrown when the application process fails.
|
||||
class ProcessInitError: public isc::Exception {
|
||||
|
@ -13,6 +13,7 @@ check-local:
|
||||
for shtest in $(SHTESTS) ; do \
|
||||
echo Running test: $$shtest ; \
|
||||
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
|
||||
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
|
||||
${SHELL} $(abs_builddir)/$$shtest || exit ; \
|
||||
done
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
# Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@ -235,6 +235,7 @@ shutdown_test() {
|
||||
test_finish 0
|
||||
}
|
||||
|
||||
server_pid_file_test "${CONFIG}" DHCP_DDNS_ALREADY_RUNNING
|
||||
dynamic_reconfiguration_test
|
||||
shutdown_test "dhcp-ddns.sigterm_test" 15
|
||||
shutdown_test "dhcp-ddns.sigint_test" 2
|
||||
|
@ -25,6 +25,9 @@ main(int argc, char* argv[]) {
|
||||
// src/lib/log/README for info on how to tweak logging
|
||||
isc::log::initLogger();
|
||||
|
||||
// Override --localstatedir value for PID files
|
||||
setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
|
||||
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
return (result);
|
||||
|
@ -229,7 +229,7 @@ TEST_F(DStubControllerTest, missingConfigFileArgument) {
|
||||
int argc = 2;
|
||||
|
||||
// Record start time, and invoke launch().
|
||||
EXPECT_THROW(launch(argc, argv), ProcessInitError);
|
||||
EXPECT_THROW(launch(argc, argv), LaunchError);
|
||||
}
|
||||
|
||||
/// @brief Tests launch with an operational error during application execution.
|
||||
|
@ -19,6 +19,17 @@ This message is printed when DHCPv4 server enabled an interface to be used
|
||||
to receive DHCPv4 traffic. IPv4 socket on this interface will be opened once
|
||||
Interface Manager starts up procedure of opening sockets.
|
||||
|
||||
% DHCP4_ALREADY_RUNNING %1 already running? %2
|
||||
This is an error message that occurs when the DHCPv4 server encounters
|
||||
a pre-existing PID file which contains the PID of a running process.
|
||||
This most likely indicates an attempt to start a second instance of
|
||||
the server using the same configuration file. It is possible, though
|
||||
unlikely that the PID file is a remnant left behind by a server crash or
|
||||
power failure and the PID it contains refers to a process other than
|
||||
the server. In such an event, it would be necessary to manually remove
|
||||
the PID file. The first argument is the DHCPv4 process name, the
|
||||
second contains the PID and PID file.
|
||||
|
||||
% DHCP4_BUFFER_RECEIVED received buffer from %1:%2 to %3:%4 over interface %5
|
||||
This debug message is logged when the server has received a packet
|
||||
over the socket. When the message is logged the contents of the received
|
||||
|
@ -168,9 +168,6 @@ namespace dhcp {
|
||||
|
||||
void
|
||||
ControlledDhcpv4Srv::init(const std::string& file_name) {
|
||||
// Call parent class's init to initialize file name.
|
||||
Daemon::init(file_name);
|
||||
|
||||
// Configure the server using JSON file.
|
||||
configure(file_name);
|
||||
|
||||
|
@ -118,6 +118,7 @@ main(int argc, char* argv[]) {
|
||||
usage();
|
||||
}
|
||||
|
||||
|
||||
// Configuration file is required.
|
||||
if (config_file.empty()) {
|
||||
cerr << "Configuration file not specified." << endl;
|
||||
@ -125,7 +126,6 @@ main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
try {
|
||||
// It is important that we set a default logger name because this name
|
||||
// will be used when the user doesn't provide the logging configuration
|
||||
@ -145,6 +145,11 @@ main(int argc, char* argv[]) {
|
||||
// Remember verbose-mode
|
||||
server.setVerbose(verbose_mode);
|
||||
|
||||
// Create our PID file.
|
||||
server.setProcName(DHCP4_NAME);
|
||||
server.setConfigFile(config_file);
|
||||
server.createPIDFile();
|
||||
|
||||
try {
|
||||
// Initialize the server.
|
||||
server.init(config_file);
|
||||
@ -173,8 +178,18 @@ main(int argc, char* argv[]) {
|
||||
|
||||
LOG_INFO(dhcp4_logger, DHCP4_SHUTDOWN);
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
} catch (const isc::dhcp::DaemonPIDExists& ex) {
|
||||
// First, we print the error on stderr (that should always work)
|
||||
cerr << DHCP4_NAME << " already running? " << ex.what()
|
||||
<< endl;
|
||||
|
||||
// Let's also try to log it using logging system, but we're not
|
||||
// sure if it's usable (the exception may have been thrown from
|
||||
// the logger subsystem)
|
||||
LOG_FATAL(dhcp4_logger, DHCP4_ALREADY_RUNNING)
|
||||
.arg(DHCP4_NAME).arg(ex.what());
|
||||
ret = EXIT_FAILURE;
|
||||
} catch (const std::exception& ex) {
|
||||
// First, we print the error on stderr (that should always work)
|
||||
cerr << DHCP4_NAME << ": Fatal error during start up: " << ex.what()
|
||||
<< endl;
|
||||
|
@ -12,6 +12,7 @@ check-local:
|
||||
for shtest in $(SHTESTS) ; do \
|
||||
echo Running test: $$shtest ; \
|
||||
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
|
||||
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
|
||||
${SHELL} $(abs_builddir)/$$shtest || exit ; \
|
||||
done
|
||||
|
||||
|
@ -272,6 +272,7 @@ shutdown_test() {
|
||||
test_finish 0
|
||||
}
|
||||
|
||||
server_pid_file_test "${CONFIG}" DHCP4_ALREADY_RUNNING
|
||||
dynamic_reconfiguration_test
|
||||
shutdown_test "dhcpv4.sigterm_test" 15
|
||||
shutdown_test "dhcpv4.sigint_test" 2
|
||||
|
@ -25,6 +25,7 @@ main(int argc, char* argv[]) {
|
||||
// src/lib/log/README for info on how to tweak logging
|
||||
isc::log::initLogger();
|
||||
|
||||
setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
return (result);
|
||||
|
@ -19,6 +19,17 @@ This message is printed when DHCPv6 server enabled an interface to be used
|
||||
to receive DHCPv6 traffic. IPv6 socket on this interface will be opened once
|
||||
Interface Manager starts up procedure of opening sockets.
|
||||
|
||||
% DHCP6_ALREADY_RUNNING %1 already running? %2
|
||||
This is an error message that occurs when the DHCPv6 server encounters
|
||||
a pre-existing PID file which contains the PID of a running process.
|
||||
This most likely indicates an attempt to start a second instance of
|
||||
the server using the same configuration file. It is possible, though
|
||||
unlikely that the PID file is a remnant left behind by a server crash or
|
||||
power failure and the PID it contains refers to a process other than
|
||||
the server. In such an event, it would be necessary to manually remove
|
||||
the PID file. The first argument is the DHCPv6 process name, the second
|
||||
contains the PID and PID file.
|
||||
|
||||
% DHCP6_ADD_GLOBAL_STATUS_CODE %1: adding Status Code to DHCPv6 packet: %2
|
||||
This message is logged when the server is adding the top-level
|
||||
Status Code option. The first argument includes the client and the
|
||||
|
@ -174,9 +174,6 @@ namespace dhcp {
|
||||
|
||||
void
|
||||
ControlledDhcpv6Srv::init(const std::string& file_name) {
|
||||
// Call parent class's init to initialize file name.
|
||||
Daemon::init(file_name);
|
||||
|
||||
// Configure the server using JSON file.
|
||||
configure(file_name);
|
||||
|
||||
|
@ -148,6 +148,11 @@ main(int argc, char* argv[]) {
|
||||
// Remember verbose-mode
|
||||
server.setVerbose(verbose_mode);
|
||||
|
||||
// Create our PID file
|
||||
server.setProcName(DHCP6_NAME);
|
||||
server.setConfigFile(config_file);
|
||||
server.createPIDFile();
|
||||
|
||||
try {
|
||||
// Initialize the server, e.g. establish control session
|
||||
// Read a configuration file
|
||||
@ -177,6 +182,17 @@ main(int argc, char* argv[]) {
|
||||
|
||||
LOG_INFO(dhcp6_logger, DHCP6_SHUTDOWN);
|
||||
|
||||
} catch (const isc::dhcp::DaemonPIDExists& ex) {
|
||||
// First, we print the error on stderr (that should always work)
|
||||
cerr << DHCP6_NAME << " already running? " << ex.what()
|
||||
<< endl;
|
||||
|
||||
// Let's also try to log it using logging system, but we're not
|
||||
// sure if it's usable (the exception may have been thrown from
|
||||
// the logger subsystem)
|
||||
LOG_FATAL(dhcp6_logger, DHCP6_ALREADY_RUNNING)
|
||||
.arg(DHCP6_NAME).arg(ex.what());
|
||||
ret = EXIT_FAILURE;
|
||||
} catch (const std::exception& ex) {
|
||||
|
||||
// First, we print the error on stderr (that should always work)
|
||||
|
@ -12,6 +12,7 @@ check-local:
|
||||
for shtest in $(SHTESTS) ; do \
|
||||
echo Running test: $$shtest ; \
|
||||
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
|
||||
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
|
||||
${SHELL} $(abs_builddir)/$$shtest || exit ; \
|
||||
done
|
||||
|
||||
|
@ -273,6 +273,7 @@ returned %d."
|
||||
test_finish 0
|
||||
}
|
||||
|
||||
server_pid_file_test "${CONFIG}" DHCP6_ALREADY_RUNNING
|
||||
dynamic_reconfiguration_test
|
||||
shutdown_test "dhcpv6.sigterm_test" 15
|
||||
shutdown_test "dhcpv6.sigint_test" 2
|
||||
|
@ -22,6 +22,7 @@ main(int argc, char* argv[]) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
isc::log::initLogger();
|
||||
|
||||
setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
return result;
|
||||
|
@ -16,6 +16,7 @@ check-local:
|
||||
chmod +x $(abs_builddir)/$$shtest ; \
|
||||
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
|
||||
export KEACTRL_BUILD_DIR=$(abs_top_builddir); \
|
||||
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
|
||||
export KEACTRL_CONF=$(abs_top_builddir)/src/bin/keactrl/tests/keactrl_test.conf; \
|
||||
${SHELL} $(abs_builddir)/$$shtest || exit ; \
|
||||
done
|
||||
|
@ -13,14 +13,18 @@
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include <config.h>
|
||||
#include <cc/data.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/daemon.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <cc/data.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include <logging.h>
|
||||
#include <log/logger_name.h>
|
||||
#include <log/logger_support.h>
|
||||
#include <logging.h>
|
||||
#include <util/filename.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <errno.h>
|
||||
|
||||
/// @brief provides default implementation for basic daemon operations
|
||||
@ -30,18 +34,22 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
// This is an initial config file location.
|
||||
std::string Daemon::config_file_ = "";
|
||||
|
||||
Daemon::Daemon()
|
||||
: signal_set_(), signal_handler_() {
|
||||
: signal_set_(), signal_handler_(), config_file_(""), proc_name_(""),
|
||||
pid_file_dir_(DHCP_DATA_DIR), pid_file_(), am_file_author_(false) {
|
||||
|
||||
// The pid_file_dir can be overridden via environment variable
|
||||
// This is primarily intended to simplify testing
|
||||
const char* const env = getenv("KEA_PIDFILE_DIR");
|
||||
if (env) {
|
||||
pid_file_dir_ = env;
|
||||
}
|
||||
}
|
||||
|
||||
Daemon::~Daemon() {
|
||||
}
|
||||
|
||||
void Daemon::init(const std::string& config_file) {
|
||||
config_file_ = config_file;
|
||||
if (pid_file_ && am_file_author_) {
|
||||
pid_file_->deleteFile();
|
||||
}
|
||||
}
|
||||
|
||||
void Daemon::cleanup() {
|
||||
@ -96,5 +104,114 @@ std::string Daemon::getVersion(bool /*extended*/) {
|
||||
isc_throw(isc::NotImplemented, "Daemon::getVersion() called");
|
||||
}
|
||||
|
||||
std::string
|
||||
Daemon::getConfigFile() const {
|
||||
return (config_file_);
|
||||
}
|
||||
|
||||
void
|
||||
Daemon::setConfigFile(const std::string& config_file) {
|
||||
config_file_ = config_file;
|
||||
}
|
||||
|
||||
std::string
|
||||
Daemon::getProcName() const {
|
||||
return (proc_name_);
|
||||
};
|
||||
|
||||
void
|
||||
Daemon::setProcName(const std::string& proc_name) {
|
||||
proc_name_ = proc_name;
|
||||
}
|
||||
|
||||
std::string
|
||||
Daemon::getPIDFileDir() const {
|
||||
return(pid_file_dir_);
|
||||
}
|
||||
|
||||
void
|
||||
Daemon::setPIDFileDir(const std::string& pid_file_dir) {
|
||||
pid_file_dir_ = pid_file_dir;
|
||||
}
|
||||
|
||||
std::string
|
||||
Daemon::getPIDFileName() const {
|
||||
if (pid_file_) {
|
||||
return (pid_file_->getFilename());
|
||||
}
|
||||
|
||||
return ("");
|
||||
};
|
||||
|
||||
void
|
||||
Daemon::setPIDFileName(const std::string& pid_file_name) {
|
||||
if (pid_file_) {
|
||||
isc_throw(isc::InvalidOperation, "Daemon::setConfigFile"
|
||||
" file name already set to:" << pid_file_->getFilename());
|
||||
}
|
||||
|
||||
if (pid_file_name.empty()) {
|
||||
isc_throw(isc::BadValue, "Daemon::setPIDFileName"
|
||||
" file name may not be empty");
|
||||
}
|
||||
|
||||
pid_file_.reset(new util::PIDFile(pid_file_name));
|
||||
};
|
||||
|
||||
std::string
|
||||
Daemon::makePIDFileName() const {
|
||||
if (config_file_.empty()) {
|
||||
isc_throw(isc::InvalidOperation,
|
||||
"Daemon::makePIDFileName config file name is not set");
|
||||
}
|
||||
|
||||
if (proc_name_.empty()) {
|
||||
isc_throw(isc::InvalidOperation,
|
||||
"Daemon::makePIDFileName process name is not set");
|
||||
}
|
||||
|
||||
// Create Filename instance from the config_file_ pathname, so we can
|
||||
// extract the fname component.
|
||||
isc::util::Filename file(config_file_);
|
||||
if (file.name().empty()) {
|
||||
isc_throw(isc::BadValue, "Daemon::makePIDFileName config file:"
|
||||
<< config_file_ << " is missing file name");
|
||||
}
|
||||
|
||||
// Make the pathname for the PID file from the runtime directory,
|
||||
// configuration name and process name.
|
||||
std::ostringstream stream;
|
||||
stream << pid_file_dir_ << "/" << file.name()
|
||||
<< "." << proc_name_ << ".pid";
|
||||
|
||||
return(stream.str());
|
||||
};
|
||||
|
||||
void
|
||||
Daemon::createPIDFile(int pid) {
|
||||
// If pid_file_ hasn't been instantiated explicitly, then do so
|
||||
// using the default name.
|
||||
if (!pid_file_) {
|
||||
setPIDFileName(makePIDFileName());
|
||||
}
|
||||
|
||||
// If we find a pre-existing file containing a live PID we bail.
|
||||
int chk_pid = pid_file_->check();
|
||||
if (chk_pid > 0) {
|
||||
isc_throw(DaemonPIDExists, "Daemon::createPIDFile: PID: " << chk_pid
|
||||
<< " exists, PID file: " << getPIDFileName());
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
// Write the PID of the current process
|
||||
pid_file_->write();
|
||||
} else {
|
||||
// Write the PID we were given
|
||||
pid_file_->write(pid);
|
||||
}
|
||||
|
||||
am_file_author_ = true;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <cc/data.h>
|
||||
#include <dhcpsrv/srv_config.h>
|
||||
#include <util/pid_file.h>
|
||||
#include <util/signal_set.h>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <string>
|
||||
@ -24,6 +25,13 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// @brief Exception thrown when a the PID file points to a live PID
|
||||
class DaemonPIDExists : public Exception {
|
||||
public:
|
||||
DaemonPIDExists(const char* file, size_t line, const char* what) :
|
||||
isc::Exception(file, line, what) { };
|
||||
};
|
||||
|
||||
/// @brief Base class for all services
|
||||
///
|
||||
/// This is the base class that all daemons (DHCPv4, DHCPv6, D2 and possibly
|
||||
@ -38,16 +46,6 @@ namespace dhcp {
|
||||
/// Dhcpv6Srv) in tests, without going through the hassles of implemeting stub
|
||||
/// methods.
|
||||
///
|
||||
/// This class comprises a static object holding a location of the configuration
|
||||
/// file. The object must be static because it is instantiated by the signal
|
||||
/// handler functions, which are static by their nature. The signal handlers
|
||||
/// are used to reconfigure a running server and they need access to the
|
||||
/// configuration file location. They get this access by calling
|
||||
/// @c Daemon::getConfigFile function.
|
||||
///
|
||||
/// By default, the configuration file location is empty and its actual value
|
||||
/// is assigned to the static object in @c Daemon::init function.
|
||||
///
|
||||
/// Classes derived from @c Daemon may install custom signal handlers using
|
||||
/// @c isc::util::SignalSet class. This base class provides a declaration
|
||||
/// of the @c SignalSet object that should be initialized in the derived
|
||||
@ -71,25 +69,6 @@ public:
|
||||
/// virtual destructor as well.
|
||||
virtual ~Daemon();
|
||||
|
||||
/// @brief Initializes the server.
|
||||
///
|
||||
/// Depending on the configuration backend, it establishes msgq session,
|
||||
/// or reads the configuration file.
|
||||
///
|
||||
/// Note: This function may throw to report enountered problems. It may
|
||||
/// also return false if the initialization was skipped. That may seem
|
||||
/// redundant, but the idea here is that in some cases the configuration
|
||||
/// was read, understood and the decision was made to not start. One
|
||||
/// case where such capability could be needed is when we have a single
|
||||
/// config file for Kea4 and D2, but the DNS Update is disabled. It is
|
||||
/// likely that the D2 will be started, it will analyze its config file,
|
||||
/// decide that it is not needed and will shut down.
|
||||
///
|
||||
/// @note this method may throw
|
||||
///
|
||||
/// @param config_file Config file name (may be empty if unused).
|
||||
virtual void init(const std::string& config_file);
|
||||
|
||||
/// @brief Performs final deconfiguration.
|
||||
///
|
||||
/// Performs configuration backend specific final clean-up. This is called
|
||||
@ -103,11 +82,6 @@ public:
|
||||
/// @brief Initiates shutdown procedure for the whole DHCPv6 server.
|
||||
virtual void shutdown();
|
||||
|
||||
/// @brief Returns config file name.
|
||||
static std::string getConfigFile() {
|
||||
return (config_file_);
|
||||
}
|
||||
|
||||
/// @brief Initializes logger
|
||||
///
|
||||
/// This method initializes logging system. It also sets the default
|
||||
@ -161,6 +135,60 @@ public:
|
||||
/// @return text string
|
||||
static std::string getVersion(bool extended);
|
||||
|
||||
/// @brief Returns config file name.
|
||||
/// @return text string
|
||||
std::string getConfigFile() const;
|
||||
|
||||
/// @brief Sets the configuration file name
|
||||
///
|
||||
/// @param config_file pathname of the configuration file
|
||||
void setConfigFile(const std::string& config_file);
|
||||
|
||||
/// @brief returns the process name
|
||||
/// This value is used as when forming the default PID file name
|
||||
/// @return text string
|
||||
std::string getProcName() const;
|
||||
|
||||
/// @brief Sets the process name
|
||||
/// @param proc_name name the process by which the process is recognized
|
||||
void setProcName(const std::string& proc_name);
|
||||
|
||||
/// @brief Returns the directory used when forming default PID file name
|
||||
/// @return text string
|
||||
std::string getPIDFileDir() const;
|
||||
|
||||
/// @brief Sets the PID file directory
|
||||
/// @param pid_file_dir path into which the PID file should be written
|
||||
/// Note the value should not include a trailing slash, '/'
|
||||
void setPIDFileDir(const std::string& pid_file_dir);
|
||||
|
||||
/// @brief Returns the current PID file name
|
||||
/// @return text string
|
||||
std::string getPIDFileName() const;
|
||||
|
||||
/// @brief Sets PID file name
|
||||
///
|
||||
/// If this method is called prior to calling createPIDFile,
|
||||
/// the value passed in will be treated as the full file name
|
||||
/// for the PID file. This provides a means to override the
|
||||
/// default file name with an explicit value.
|
||||
///
|
||||
/// @param pid_file_name file name to be used as the PID file
|
||||
void setPIDFileName(const std::string& pid_file_name);
|
||||
|
||||
/// @brief Creates the PID file
|
||||
///
|
||||
/// If the PID file name has not been previously set, the method
|
||||
/// uses manufacturePIDFileName() to set it. If the PID file
|
||||
/// name refers to an existing file whose contents are a PID whose
|
||||
/// process is still alive, the method will throw a DaemonPIDExists
|
||||
/// exception. Otherwise, the file created (or truncated) and
|
||||
/// the given pid (if not zero) is written to the file.
|
||||
///
|
||||
/// @param pid PID to write to the file if not zero, otherwise the
|
||||
/// PID of the current process is used.
|
||||
void createPIDFile(int pid = 0);
|
||||
|
||||
protected:
|
||||
|
||||
/// @brief Invokes handler for the next received signal.
|
||||
@ -189,11 +217,25 @@ protected:
|
||||
/// it not initialized, the signals will not be handled.
|
||||
isc::util::SignalHandler signal_handler_;
|
||||
|
||||
/// @brief Manufacture the pid file name
|
||||
std::string makePIDFileName() const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Config file name or empty if config file not used.
|
||||
static std::string config_file_;
|
||||
std::string config_file_;
|
||||
|
||||
/// @brief Name of this process, used when creating its pid file
|
||||
std::string proc_name_;
|
||||
|
||||
/// @brief Pointer to the directory where PID file(s) are written
|
||||
/// It defaults to --localstatedir
|
||||
std::string pid_file_dir_;
|
||||
|
||||
/// @brief Pointer to the PID file for this process
|
||||
isc::util::PIDFilePtr pid_file_;
|
||||
|
||||
/// @brief Flag indicating if this instance created the file
|
||||
bool am_file_author_;
|
||||
};
|
||||
|
||||
}; // end of isc::dhcp namespace
|
||||
|
@ -34,6 +34,8 @@ namespace dhcp {
|
||||
class DaemonImpl : public Daemon {
|
||||
public:
|
||||
static std::string getVersion(bool extended);
|
||||
|
||||
using Daemon::makePIDFileName;
|
||||
};
|
||||
|
||||
std::string DaemonImpl::getVersion(bool extended) {
|
||||
@ -75,6 +77,172 @@ TEST_F(DaemonTest, constructor) {
|
||||
// Check that the verbose mode is not set by default.
|
||||
Daemon instance2;
|
||||
EXPECT_FALSE(instance2.getVerbose());
|
||||
|
||||
EXPECT_TRUE(instance2.getConfigFile().empty());
|
||||
EXPECT_TRUE(instance2.getProcName().empty());
|
||||
EXPECT_EQ(CfgMgr::instance().getDataDir(),instance2.getPIDFileDir());
|
||||
EXPECT_TRUE(instance2.getPIDFileName().empty());
|
||||
}
|
||||
|
||||
// Verify config file accessors
|
||||
TEST_F(DaemonTest, getSetConfigFile) {
|
||||
Daemon instance;
|
||||
|
||||
EXPECT_NO_THROW(instance.setConfigFile("test.txt"));
|
||||
EXPECT_EQ("test.txt", instance.getConfigFile());
|
||||
}
|
||||
|
||||
// Verify process name accessors
|
||||
TEST_F(DaemonTest, getSetProcName) {
|
||||
Daemon instance;
|
||||
|
||||
EXPECT_NO_THROW(instance.setProcName("myproc"));
|
||||
EXPECT_EQ("myproc", instance.getProcName());
|
||||
}
|
||||
|
||||
// Verify PID file directory name accessors
|
||||
TEST_F(DaemonTest, getSetPIDFileDir) {
|
||||
Daemon instance;
|
||||
|
||||
EXPECT_NO_THROW(instance.setPIDFileDir("/tmp"));
|
||||
EXPECT_EQ("/tmp", instance.getPIDFileDir());
|
||||
}
|
||||
|
||||
// Verify PID file name accessors.
|
||||
TEST_F(DaemonTest, setPIDFileName) {
|
||||
Daemon instance;
|
||||
|
||||
// Verify that PID file name may not be set to empty
|
||||
EXPECT_THROW(instance.setPIDFileName(""), BadValue);
|
||||
|
||||
EXPECT_NO_THROW(instance.setPIDFileName("myproc"));
|
||||
EXPECT_EQ("myproc", instance.getPIDFileName());
|
||||
|
||||
// Verify that setPIDFileName cannot be called twice on the same instance.
|
||||
EXPECT_THROW(instance.setPIDFileName("again"), InvalidOperation);
|
||||
}
|
||||
|
||||
// Test the getVersion() redefinition
|
||||
TEST_F(DaemonTest, getVersion) {
|
||||
EXPECT_THROW(Daemon::getVersion(false), NotImplemented);
|
||||
|
||||
ASSERT_NO_THROW(DaemonImpl::getVersion(false));
|
||||
|
||||
EXPECT_EQ(DaemonImpl::getVersion(false), "BASIC");
|
||||
|
||||
ASSERT_NO_THROW(DaemonImpl::getVersion(true));
|
||||
|
||||
EXPECT_EQ(DaemonImpl::getVersion(true), "EXTENDED");
|
||||
}
|
||||
|
||||
// Verify makePIDFileName method
|
||||
TEST_F(DaemonTest, makePIDFileName) {
|
||||
DaemonImpl instance;
|
||||
|
||||
// Verify that config file cannot be blank
|
||||
instance.setProcName("notblank");
|
||||
EXPECT_THROW(instance.makePIDFileName(), InvalidOperation);
|
||||
|
||||
// Verify that proc name cannot be blank
|
||||
instance.setProcName("");
|
||||
instance.setConfigFile("notblank");
|
||||
EXPECT_THROW(instance.makePIDFileName(), InvalidOperation);
|
||||
|
||||
// Verify that config file must contain a file name
|
||||
instance.setProcName("myproc");
|
||||
instance.setConfigFile(".txt");
|
||||
EXPECT_THROW(instance.makePIDFileName(), BadValue);
|
||||
instance.setConfigFile("/tmp/");
|
||||
EXPECT_THROW(instance.makePIDFileName(), BadValue);
|
||||
|
||||
// Given a valid config file name and proc name we should good to go
|
||||
instance.setConfigFile("/tmp/test.conf");
|
||||
std::string name;
|
||||
EXPECT_NO_THROW(name = instance.makePIDFileName());
|
||||
|
||||
// Make sure the name is as we expect
|
||||
std::ostringstream stream;
|
||||
stream << CfgMgr::instance().getDataDir() << "/test.myproc.pid";
|
||||
EXPECT_EQ(stream.str(), name);
|
||||
|
||||
// Verify that the default directory can be overridden
|
||||
instance.setPIDFileDir("/tmp");
|
||||
EXPECT_NO_THROW(name = instance.makePIDFileName());
|
||||
EXPECT_EQ("/tmp/test.myproc.pid", name);
|
||||
}
|
||||
|
||||
// Verifies the creation a PID file and that a pre-existing PID file
|
||||
// which points to a live PID causes a throw.
|
||||
TEST_F(DaemonTest, createPIDFile) {
|
||||
DaemonImpl instance;
|
||||
|
||||
instance.setConfigFile("test.conf");
|
||||
instance.setProcName("daemon_test");
|
||||
instance.setPIDFileDir(TEST_DATA_BUILDDIR);
|
||||
|
||||
EXPECT_NO_THROW(instance.createPIDFile());
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << TEST_DATA_BUILDDIR << "/test.daemon_test.pid";
|
||||
EXPECT_EQ(stream.str(), instance.getPIDFileName());
|
||||
|
||||
// If we try again, we should see our own PID file and fail
|
||||
EXPECT_THROW(instance.createPIDFile(), DaemonPIDExists);
|
||||
}
|
||||
|
||||
// Verifies that a pre-existing PID file which points to a dead PID
|
||||
// is overwritten.
|
||||
TEST_F(DaemonTest, createPIDFileOverwrite) {
|
||||
DaemonImpl instance;
|
||||
|
||||
// We're going to use fork to generate a PID we KNOW is dead.
|
||||
int pid = fork();
|
||||
ASSERT_GE(pid, 0);
|
||||
|
||||
if (pid == 0) {
|
||||
// This is the child, die right away. Tragic, no?
|
||||
exit (0);
|
||||
}
|
||||
|
||||
// Back in the parent test, we need to wait for the child to die
|
||||
int stat;
|
||||
int ret = waitpid(pid, &stat, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
// Ok, so we should now have a PID that we know to be dead.
|
||||
// Let's use it to create a PID file.
|
||||
instance.setConfigFile("test.conf");
|
||||
instance.setProcName("daemon_test");
|
||||
instance.setPIDFileDir(TEST_DATA_BUILDDIR);
|
||||
EXPECT_NO_THROW(instance.createPIDFile(pid));
|
||||
|
||||
// If we try to create the PID file again, this should work.
|
||||
EXPECT_NO_THROW(instance.createPIDFile());
|
||||
}
|
||||
|
||||
// Verifies that Daemon destruction deletes the PID file
|
||||
TEST_F(DaemonTest, PIDFileCleanup) {
|
||||
boost::shared_ptr<DaemonImpl> instance;
|
||||
instance.reset(new DaemonImpl);
|
||||
|
||||
instance->setConfigFile("test.conf");
|
||||
instance->setProcName("daemon_test");
|
||||
instance->setPIDFileDir(TEST_DATA_BUILDDIR);
|
||||
EXPECT_NO_THROW(instance->createPIDFile());
|
||||
|
||||
// If we try again, we should see our own PID file
|
||||
EXPECT_THROW(instance->createPIDFile(), DaemonPIDExists);
|
||||
|
||||
// Save the pid file name
|
||||
std::string pid_file_name = instance->getPIDFileName();
|
||||
|
||||
// Now delete the Daemon instance. This should remove the
|
||||
// PID file.
|
||||
instance.reset();
|
||||
|
||||
struct stat stat_buf;
|
||||
ASSERT_EQ(-1, stat(pid_file_name.c_str(), &stat_buf));
|
||||
EXPECT_EQ(errno, ENOENT);
|
||||
}
|
||||
|
||||
// Checks that configureLogger method is behaving properly.
|
||||
@ -117,18 +285,6 @@ TEST_F(DaemonTest, parsingConsoleOutput) {
|
||||
EXPECT_EQ("stdout" , storage->getLoggingInfo()[0].destinations_[0].output_);
|
||||
}
|
||||
|
||||
// Test the getVersion() redefinition
|
||||
TEST_F(DaemonTest, getVersion) {
|
||||
EXPECT_THROW(Daemon::getVersion(false), NotImplemented);
|
||||
|
||||
ASSERT_NO_THROW(DaemonImpl::getVersion(false));
|
||||
|
||||
EXPECT_EQ(DaemonImpl::getVersion(false), "BASIC");
|
||||
|
||||
ASSERT_NO_THROW(DaemonImpl::getVersion(true));
|
||||
|
||||
EXPECT_EQ(DaemonImpl::getVersion(true), "EXTENDED");
|
||||
}
|
||||
|
||||
|
||||
// More tests will appear here as we develop Daemon class.
|
||||
|
@ -426,6 +426,60 @@ must be a number"
|
||||
kill -${sig} ${_GET_PIDS}
|
||||
}
|
||||
|
||||
# Verifies that a server is up running by its PID file
|
||||
# The PID file is constructed from the given config file name and
|
||||
# binary name. If it exists and the PID it contains refers to a
|
||||
# live process it sets _SERVER_PID_FILE and _SERVER_PID to the
|
||||
# corresponding values. Otherwise, it emits an error and exits.
|
||||
verify_server_pid() {
|
||||
local bin_name="${1}" # binary name of the server
|
||||
local cfg_file="${2}" # config file name
|
||||
|
||||
# We will construct the PID file name based on the server config
|
||||
# and binary name
|
||||
if [ -z ${bin_name} ]; then
|
||||
test_lib_error "verify_server_pid requires binary name"
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
if [ -z ${cfg_file} ]; then
|
||||
test_lib_error "verify_server_pid requires config file name"
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# Only the file name portion of the config file is used, try and
|
||||
# extract it. NOTE if this "algorithm" changes this code will need
|
||||
# to be updated.
|
||||
fname=`basename ${cfg_file}`
|
||||
fname=`echo $fname | cut -f1 -d'.'`
|
||||
|
||||
if [ -z ${fname} ]; then
|
||||
test_lib_error "verify_server_pid could not extract config name"
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# Now we can build the name:
|
||||
pid_file="$KEA_PIDFILE_DIR/$fname.$bin_name.pid"
|
||||
|
||||
if [ ! -e ${pid_file} ]; then
|
||||
printf "ERROR: PID file:[%s] does not exist\n" ${pid_file}
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# File exists, does its PID point to a live process?
|
||||
pid=`cat ${pid_file}`
|
||||
kill -0 ${pid}
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "ERROR: PID file:[%s] exists but PID:[%d] does not\n" \
|
||||
${pid_file} ${pid}
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# Make the values accessible to the caller
|
||||
_SERVER_PID="${pid}"
|
||||
_SERVER_PID_FILE="${pid_file}"
|
||||
}
|
||||
|
||||
# This test verifies that the binary is reporting its version properly.
|
||||
version_test() {
|
||||
test_name=${1} # Test name
|
||||
@ -536,3 +590,49 @@ logger_vars_test() {
|
||||
|
||||
test_finish 0
|
||||
}
|
||||
|
||||
# This test verifies server PID file management
|
||||
# 1. It verifies that upon startup, the server creates a PID file
|
||||
# 2. It verifies the an attempt to start a second instance fails
|
||||
# due to pre-existing PID File/PID detection
|
||||
server_pid_file_test() {
|
||||
local server_cfg="${1}"
|
||||
local log_id="${2}"
|
||||
|
||||
# Log the start of the test and print test name.
|
||||
test_start "${bin}.server_pid_file_test"
|
||||
# Remove dangling DHCP4 instances and remove log files.
|
||||
cleanup
|
||||
# Create new configuration file.
|
||||
create_config "${CONFIG}"
|
||||
# Instruct server to log to the specific file.
|
||||
set_logger
|
||||
# Start server
|
||||
start_kea ${bin_path}/${bin}
|
||||
# Wait up to 20s for server to start.
|
||||
wait_for_kea 20
|
||||
if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
|
||||
printf "ERROR: timeout waiting for %s to start.\n" ${bin}
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# Verify server is still running
|
||||
verify_server_pid ${bin} ${CFG_FILE}
|
||||
|
||||
printf "PID file is [%s], PID is [%d]" ${_SERVER_PID_FILE} ${_SERVER_PID}
|
||||
|
||||
# Now try to start a second one
|
||||
start_kea ${bin_path}/${bin}
|
||||
|
||||
wait_for_message 10 "${log_id}" 1
|
||||
if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
|
||||
printf "ERROR: Second %s instance started? PID conflict not reported.\n" ${bin}
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
# Verify server is still running
|
||||
verify_server_pid ${bin} ${CFG_FILE}
|
||||
|
||||
# All ok. Shut down the server and exit.
|
||||
test_finish 0
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ PIDFile::PIDFile(const std::string& filename)
|
||||
PIDFile::~PIDFile() {
|
||||
}
|
||||
|
||||
bool
|
||||
int
|
||||
PIDFile::check() const {
|
||||
std::ifstream fs(filename_.c_str());
|
||||
int pid;
|
||||
@ -51,13 +51,13 @@ PIDFile::check() const {
|
||||
<< filename_ << "'");
|
||||
}
|
||||
|
||||
// If the process is still running return true
|
||||
// If the process is still running return its pid.
|
||||
if (kill(pid, 0) == 0) {
|
||||
return (true);
|
||||
return (pid);
|
||||
}
|
||||
|
||||
// No process
|
||||
return (false);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define PID_FILE_H
|
||||
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@ -62,11 +63,11 @@ public:
|
||||
/// If the file exists but can't be read or it doesn't have
|
||||
/// the proper format treat it as the process existing.
|
||||
///
|
||||
/// @return true if the PID is in use, false otherwise
|
||||
/// @return returns the PID if it is in, 0 otherwise.
|
||||
///
|
||||
/// @throw throws PIDCantReadPID if it was able to open the file
|
||||
/// but was unable to read the PID from it.
|
||||
bool check() const;
|
||||
int check() const;
|
||||
|
||||
/// @brief Write the PID to the file.
|
||||
///
|
||||
@ -95,6 +96,9 @@ private:
|
||||
std::string filename_;
|
||||
};
|
||||
|
||||
/// @brief Defines a shared pointer to a PIDFile
|
||||
typedef boost::shared_ptr<PIDFile> PIDFilePtr;
|
||||
|
||||
} // namespace isc::util
|
||||
} // namespace isc
|
||||
|
||||
|
@ -127,7 +127,7 @@ TEST_F(PIDFileTest, pidInUse) {
|
||||
pid_file.write();
|
||||
|
||||
// Check if we think the process is running
|
||||
EXPECT_TRUE(pid_file.check());
|
||||
EXPECT_EQ(getpid(), pid_file.check());
|
||||
}
|
||||
|
||||
/// @brief Test checking a PID. Write a PID that isn't in use
|
||||
@ -148,7 +148,7 @@ TEST_F(PIDFileTest, pidNotInUse) {
|
||||
pid_file.write(pid);
|
||||
|
||||
// Check to see if we think the process is running
|
||||
if (!pid_file.check()) {
|
||||
if (pid_file.check() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ TEST_F(PIDFileTest, pidNotInUse) {
|
||||
pid_file.write(pid);
|
||||
|
||||
// Check to see if we think the process is running
|
||||
EXPECT_FALSE(pid_file.check());
|
||||
EXPECT_EQ(0, pid_file.check());
|
||||
}
|
||||
|
||||
/// @brief Test checking a PID. Write garbage to the PID file
|
||||
|
Loading…
x
Reference in New Issue
Block a user