Kea 3.3.3
daemon.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <cstdlib>
10
11#include <cc/data.h>
12#include <process/daemon.h>
13#include <process/log_parser.h>
15#include <log/logger_name.h>
16#include <log/logger_support.h>
17#include <process/config_base.h>
19#include <util/filesystem.h>
20
21#include <functional>
22#include <sstream>
23#include <fstream>
24
25#include <errno.h>
26
27using namespace isc::data;
28using namespace isc::util;
29using namespace isc::util::file;
30
35namespace isc {
36namespace process {
37
38bool Daemon::verbose_ = false;
39bool Daemon::shutdown_on_failure_ = false;
40bool Daemon::cb_repair_mode_ = false;
41
42std::string Daemon::proc_name_("");
43
44std::string Daemon::default_logger_name_("kea");
45
47 : signal_set_(), config_file_(""),
48 pid_file_dir_(PIDFILE_DIR), pid_file_(), am_file_author_(false),
49 exit_value_(EXIT_SUCCESS) {
50
51 // The pid_file_dir can be overridden via environment variable
52 // This is primarily intended to simplify testing
53 const char* const env = getenv("KEA_PIDFILE_DIR");
54 if (env) {
55 pid_file_dir_ = env;
56 }
57}
58
60 if (pid_file_ && am_file_author_) {
61 pid_file_->deleteFile();
62 }
63}
64
66}
67
69}
70
72 const ConfigPtr& storage) {
73
74 if (log_config) {
75 ConstElementPtr loggers = log_config->get("loggers");
76 if (loggers) {
77 LogConfigParser parser(storage);
78 parser.parseConfiguration(loggers, verbose_);
79 }
80 }
81}
82
83void
84Daemon::setVerbose(bool verbose) {
85 verbose_ = verbose;
86}
87
88bool
90 return (verbose_);
91}
92
93void Daemon::loggerInit(const char* name, bool verbose) {
94
95 setenv("KEA_LOGGER_DESTINATION", "stdout", 0);
96
97 // Initialize logger system
99
100 // Apply default configuration (log INFO or DEBUG to stdout)
102}
103
104std::string Daemon::getVersion(bool /*extended*/) {
105 isc_throw(isc::NotImplemented, "Daemon::getVersion() called");
106}
107
108std::string
110 return (config_file_);
111}
112
113void
114Daemon::setConfigFile(const std::string& config_file) {
115 config_file_ = config_file;
116}
117
118void
120 if (config_file_.empty()) {
121 isc_throw(isc::BadValue, "config file name is not set");
122 }
123
124 // Create Path instance from the config_file_ pathname, and
125 // check the file name component.
126 Path file(config_file_);
127 if (file.stem().empty()) {
128 isc_throw(isc::BadValue, "config file:" << config_file_
129 << " is missing file name");
130 }
131}
132
133void
135 Path path(file);
136 // from checkConfigFile().
137 if (path.stem().empty()) {
138 isc_throw(isc::BadValue, "config file:" << file
139 << " is missing file name");
140 }
141 Path current(config_file_);
142 if (current.parentDirectory() == path.parentDirectory()) {
143 // Same parent directories!
144 return;
145 }
146 if (path.parentDirectory().empty()) {
147 // Note the current parent directory can't be empty here.
148 file = current.parentDirectory() + file;
149 return;
150 }
151 isc_throw(isc::BadValue, "file " << file << " must be in the same "
152 << "directory as the config file (" << config_file_ << ")");
153}
154
155std::string
157 return (proc_name_);
158}
159
160void
161Daemon::setProcName(const std::string& proc_name) {
162 proc_name_ = proc_name;
163}
164
165std::string
167 return(pid_file_dir_);
168}
169
170void
171Daemon::setPIDFileDir(const std::string& pid_file_dir) {
172 pid_file_dir_ = pid_file_dir;
173}
174
175std::string
177 if (pid_file_) {
178 return (pid_file_->getFilename());
179 }
180
181 return ("");
182}
183
184std::string
186 if (pid_file_) {
187 return (pid_file_->getLockname());
188 }
189
190 return ("");
191}
192
193void
194Daemon::setPIDFileName(const std::string& pid_file_name) {
195 if (pid_file_) {
196 isc_throw(isc::InvalidOperation, "Daemon::setConfigFile"
197 " file name already set to:" << pid_file_->getFilename());
198 }
199
200 if (pid_file_name.empty()) {
201 isc_throw(isc::BadValue, "Daemon::setPIDFileName"
202 " file name may not be empty");
203 }
204
205 pid_file_.reset(new PIDFile(pid_file_name));
206}
207
208std::string
210 if (config_file_.empty()) {
212 "Daemon::makePIDFileName config file name is not set");
213 }
214
215 // Create Path instance from the config_file_ pathname, so we can
216 // extract the fname component.
217 Path file(config_file_);
218 if (file.stem().empty()) {
219 isc_throw(isc::BadValue, "Daemon::makePIDFileName config file:"
220 << config_file_ << " is missing file name");
221 }
222
223 if (proc_name_.empty()) {
225 "Daemon::makePIDFileName process name is not set");
226 }
227
228 // Make the pathname for the PID file from the runtime directory,
229 // configuration name and process name.
230 std::ostringstream stream;
231 stream << pid_file_dir_ << "/" << file.stem()
232 << "." << proc_name_ << ".pid";
233
234 return(stream.str());
235};
236
237void
239 // If pid_file_ hasn't been instantiated explicitly, then do so
240 // using the default name.
241 if (!pid_file_) {
243 }
244
245 // Acquire a lock for check and write operations.
246 PIDLock pid_lock(getPIDLockName());
247 if (!pid_lock.isLocked()) {
248 isc_throw(DaemonPIDExists, "Daemon::createPIDFile: can't lock, "
249 "PID lock file: " << getPIDLockName());
250 }
251
252 // If we find a pre-existing file containing a live PID we bail.
253 int chk_pid = pid_file_->check();
254 if (chk_pid > 0) {
255 isc_throw(DaemonPIDExists, "Daemon::createPIDFile: PID: " << chk_pid
256 << " exists, PID file: " << getPIDFileName());
257 }
258
259 if (pid == 0) {
260 // Write the PID of the current process
261 pid_file_->write();
262 } else {
263 // Write the PID we were given
264 pid_file_->write(pid);
265 }
266
267 am_file_author_ = true;
268}
269
270size_t
271Daemon::writeConfigFile(const std::string& config_file,
272 ConstElementPtr cfg) const {
273 if (!cfg) {
274 isc_throw(Unexpected, "Can't write configuration: conversion to JSON failed");
275 }
276
277 std::ofstream out(config_file, std::ios::trunc);
278 if (!out.good()) {
279 isc_throw(Unexpected, "Unable to open file " + config_file + " for writing");
280 }
281
282 // Write the actual content using pretty printing.
283 prettyPrint(cfg, out);
284
285 size_t bytes = static_cast<size_t>(out.tellp());
286
287 out.close();
288
289 return (bytes);
290}
291
292std::list<std::list<std::string>>
294 static std::list<std::list<std::string>> const list;
295 return list;
296}
297
301 for (std::list<std::string>& json_path : jsonPathsToRedact()) {
302 result = isc::process::redactConfig(result, json_path);
303 }
304 return result;
305}
306
307} // namespace process
308} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown when an unexpected error condition occurs.
Exception thrown when the PID file points to a live PID.
Definition daemon.h:25
std::string getConfigFile() const
Returns config file name.
Definition daemon.cc:109
virtual size_t writeConfigFile(const std::string &config_file, isc::data::ConstElementPtr cfg=isc::data::ConstElementPtr()) const
Writes current configuration to specified file.
Definition daemon.cc:271
static std::string getVersion(bool extended)
returns Kea version on stdout and exits.
Definition daemon.cc:104
static void setVerbose(const bool verbose)
Sets or clears verbose mode.
Definition daemon.cc:84
std::string getPIDFileName() const
Returns the current PID file name.
Definition daemon.cc:176
virtual std::list< std::list< std::string > > jsonPathsToRedact() const
Return a list of all paths that contain passwords or secrets.
Definition daemon.cc:293
Daemon()
Default constructor.
Definition daemon.cc:46
virtual void shutdown()
Initiates shutdown procedure for the whole server.
Definition daemon.cc:68
std::string getPIDFileDir() const
Returns the directory used when forming default PID file name.
Definition daemon.cc:166
virtual ~Daemon()
Destructor.
Definition daemon.cc:59
isc::asiolink::IOSignalSetPtr signal_set_
A pointer to the object installing custom signal handlers.
Definition daemon.h:300
static void configureLogger(const isc::data::ConstElementPtr &log_config, const isc::process::ConfigPtr &storage)
Configures logger.
Definition daemon.cc:71
static bool getVerbose()
Returns if running in verbose mode.
Definition daemon.cc:89
static void loggerInit(const char *log_name, bool verbose)
Initializes logger.
Definition daemon.cc:93
void checkWriteConfigFile(std::string &file)
Checks the to-be-written configuration file name.
Definition daemon.cc:134
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:156
virtual void cleanup()
Performs final deconfiguration.
Definition daemon.cc:65
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
Definition daemon.cc:299
void checkConfigFile() const
Checks the configuration file name.
Definition daemon.cc:119
void setPIDFileName(const std::string &pid_file_name)
Sets PID file name.
Definition daemon.cc:194
static void setProcName(const std::string &proc_name)
Sets the process name.
Definition daemon.cc:161
void createPIDFile(int pid=0)
Creates the PID file.
Definition daemon.cc:238
void setPIDFileDir(const std::string &pid_file_dir)
Sets the PID file directory.
Definition daemon.cc:171
std::string getPIDLockName() const
Returns the current PID lock file name.
Definition daemon.cc:185
std::string makePIDFileName() const
Manufacture the pid file name.
Definition daemon.cc:209
void setConfigFile(const std::string &config_file)
Sets the configuration file name.
Definition daemon.cc:114
Configures log4cplus by translating Kea configuration structures.
Definition log_parser.h:43
void parseConfiguration(const isc::data::ConstElementPtr &log_config, bool verbose=false)
Parses specified configuration.
Definition log_parser.cc:38
Class to help with processing PID files.
Definition pid_file.h:40
RAII device to handle a lock file to avoid race conditions.
Definition pid_file.h:115
bool isLocked()
Return the lock status.
Definition pid_file.h:131
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Logging initialization functions.
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition data.cc:1770
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
void initLogger(const string &root, isc::log::Severity severity, int dbglevel, const char *file, bool buffer)
Run-time initialization.
const int MAX_DEBUG_LEVEL
void setDefaultLoggingOutput(bool verbose)
Reset root logger characteristics.
ConstElementPtr redactConfig(ConstElementPtr const &element, list< string > const &json_path, string obscure, unsigned max_nesting_depth)
Redact a configuration.
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
Defines the logger used by the top-level component of kea-lfc.
Paths on a filesystem.
Definition filesystem.h:126
std::string parentDirectory() const
Get the parent directory.
std::string stem() const
Get the base name of the file without the extension.