123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // Copyright (C) 2014-2015 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
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #include <config.h>
- #include <cc/data.h>
- #include <dhcpsrv/cfgmgr.h>
- #include <dhcpsrv/daemon.h>
- #include <exceptions/exceptions.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
- ///
- /// This file provides stub implementations that are expected to be redefined
- /// in derived classes (e.g. ControlledDhcpv6Srv)
- namespace isc {
- namespace dhcp {
- Daemon::Daemon()
- : 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() {
- if (pid_file_ && am_file_author_) {
- pid_file_->deleteFile();
- }
- }
- void Daemon::cleanup() {
- }
- void Daemon::shutdown() {
- }
- void Daemon::handleSignal() {
- if (signal_set_ && signal_handler_) {
- signal_set_->handleNext(boost::bind(signal_handler_, _1));
- }
- }
- void Daemon::configureLogger(const isc::data::ConstElementPtr& log_config,
- const SrvConfigPtr& storage) {
- if (log_config) {
- isc::data::ConstElementPtr loggers = log_config->get("loggers");
- if (loggers) {
- LogConfigParser parser(storage);
- parser.parseConfiguration(loggers, CfgMgr::instance().isVerbose());
- }
- }
- }
- void
- Daemon::setVerbose(bool verbose) {
- CfgMgr::instance().setVerbose(verbose);
- }
- bool
- Daemon::getVerbose() const {
- return (CfgMgr::instance().isVerbose());
- }
- void Daemon::loggerInit(const char* name, bool verbose) {
- setenv("KEA_LOGGER_DESTINATION", "stdout", 0);
- // Initialize logger system
- isc::log::initLogger(name, isc::log::DEBUG, isc::log::MAX_DEBUG_LEVEL,
- NULL);
- // Apply default configuration (log INFO or DEBUG to stdout)
- isc::log::setDefaultLoggingOutput(verbose);
- }
- 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;
- }
- };
- };
|