diff options
author | Tomek Mrugalski <tomasz@isc.org> | 2018-08-29 20:28:51 +0200 |
---|---|---|
committer | Tomek Mrugalski <tomasz@isc.org> | 2018-09-07 16:40:06 +0200 |
commit | b0976de24882129cbd6b777dfb72ade6f5ebd5ae (patch) | |
tree | 4f0b836ed9389da9ed55e815b8c83e31326f5baa /src/lib/process/daemon.h | |
parent | [master] Added ChangeLog entry 1449. (diff) | |
download | kea-b0976de24882129cbd6b777dfb72ade6f5ebd5ae.tar.xz kea-b0976de24882129cbd6b777dfb72ade6f5ebd5ae.zip |
[#25,!14] Moved daemon.cc|h, unittests to process
Diffstat (limited to 'src/lib/process/daemon.h')
-rw-r--r-- | src/lib/process/daemon.h | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/lib/process/daemon.h b/src/lib/process/daemon.h new file mode 100644 index 0000000000..df895ddd42 --- /dev/null +++ b/src/lib/process/daemon.h @@ -0,0 +1,255 @@ +// Copyright (C) 2014-2015,2017 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/. + +#ifndef DAEMON_H +#define DAEMON_H + +#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> + +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 +/// others) are derived from. It provides a standard interface for starting up, +/// reconfiguring, shutting down and several other operations. It also covers +/// some common operations. +/// +/// This class is not expected to be instantiated directly, but rather daemon +/// implementations should derive from it. +/// +/// Methods are not pure virtual, as we need to instantiate basic daemons (e.g. +/// Dhcpv6Srv) in tests, without going through the hassles of implementing stub +/// methods. +/// +/// 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 +/// classes to install the custom exception handlers. +/// +/// @note Only one instance of this class is instantiated as it encompasses +/// the whole operation of the server. Nothing, however, enforces the +/// singleton status of the object. +class Daemon : public boost::noncopyable { + +public: + /// @brief Default constructor + /// + /// Initializes the object installing custom signal handlers for the + /// process to NULL. + Daemon(); + + /// @brief Destructor + /// + /// Having virtual destructor ensures that all derived classes will have + /// virtual destructor as well. + virtual ~Daemon(); + + /// @brief Performs final deconfiguration. + /// + /// Performs configuration backend specific final clean-up. This is called + /// shortly before the daemon terminates. Depending on backend, it may + /// terminat existing msgq session, close LDAP connection or similar. + /// + /// The daemon is not expected to receive any further commands or + /// configuration updates as it is in final stages of shutdown. + virtual void cleanup(); + + /// @brief Initiates shutdown procedure for the whole DHCPv6 server. + virtual void shutdown(); + + /// @brief Initializes logger + /// + /// This method initializes logging system. It also sets the default + /// output to stdout. This is used in early stages of the startup + /// phase before config file and parsed and proper logging details + /// are known. + /// + /// @param log_name name used in logger initialization + /// @param verbose verbose mode (true usually enables DEBUG messages) + static void loggerInit(const char* log_name, bool verbose); + + /// @brief Configures logger + /// + /// Applies configuration stored in "Logging" structure in the + /// configuration file. This structure has a "loggers" array that + /// contains 0 or more entries, each configuring one logging source + /// (name, severity, debuglevel), each with zero or more outputs (file, + /// maxsize, maximum number of files). + /// + /// @param log_config JSON structures that describe logging + /// @param storage configuration will be stored here + static void configureLogger(const isc::data::ConstElementPtr& log_config, + const isc::dhcp::SrvConfigPtr& storage); + + /// @brief Sets or clears verbose mode + /// + /// Verbose mode (-v in command-line) triggers loggers to log everything + /// (sets severity to DEBUG and debuglevel to 99). Values specified in the + /// config file are ignored. + /// + /// @param verbose specifies if verbose should be set or not + void setVerbose(const bool verbose); + + /// @brief Returns if running in verbose mode + /// + /// @return verbose mode + bool getVerbose() const; + + /// @brief returns Kea version on stdout and exits. + /// + /// With extended == false, this method returns a simple string + /// containing version number. With extended == true, it returns + /// also additional information about sources. It is expected to + /// return extra information about dependencies and used DB backends. + /// + /// As there is no static virtual methods in C++ this class method + /// has to be redefined in derived classes and called with the + /// derived class name or a child name. + /// + /// @param extended print additional information? + /// @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 Writes current configuration to specified file + /// + /// This method writes the current configuration to specified file. + /// @todo: this logically more belongs to CPL process file. Once + /// Daemon is merged with CPL architecture, it will be a better + /// fit. + /// + /// If cfg is not specified, the current config (as returned by + /// CfgMgr::instance().getCurrentCfg() will be returned. + /// + /// @param config_file name of the file to write the configuration to + /// @param cfg configuration to write (optional) + /// @return number of files written + /// @throw Unexpected if CfgMgr can't retrieve configuration or file cannot + /// be written + virtual size_t + writeConfigFile(const std::string& config_file, + isc::data::ConstElementPtr cfg = isc::data::ConstElementPtr()) const; + + /// @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. + /// + /// This function provides a default implementation for the function + /// handling next signal received by the process. It checks if a pointer + /// to @c isc::util::SignalSet object and the signal handler function + /// have been set. If they have been set, the signal handler is invoked for + /// the the next signal registered in the @c SignalSet object. + /// + /// This function should be received in the main loop of the process. + virtual void handleSignal(); + + /// @brief A pointer to the object installing custom signal handlers. + /// + /// This pointer needs to be initialized to point to the @c SignalSet + /// object in the derived classes which need to handle signals received + /// by the process. + isc::util::SignalSetPtr signal_set_; + + /// @brief Pointer to the common signal handler invoked by the handleSignal + /// function. + /// + /// This pointer needs to be initialized to point to the signal handler + /// function for signals being handled by the process. If signal handler + /// 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. + 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 +}; // end of isc namespace + +#endif |