Kea  2.3.6-git
daemon.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2022 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 <cc/data.h>
10 #include <process/daemon.h>
11 #include <process/log_parser.h>
12 #include <exceptions/exceptions.h>
13 #include <log/logger_name.h>
14 #include <log/logger_support.h>
15 #include <process/config_base.h>
16 #include <process/redact_config.h>
17 #include <util/filename.h>
18 
19 #include <functional>
20 #include <sstream>
21 #include <fstream>
22 
23 #include <errno.h>
24 
25 using namespace isc::data;
26 namespace ph = std::placeholders;
27 
32 namespace isc {
33 namespace process {
34 
35 bool Daemon::verbose_ = false;
36 
37 std::string Daemon::proc_name_("");
38 
39 std::string Daemon::default_logger_name_("kea");
40 
41 Daemon::Daemon()
42  : signal_set_(), config_file_(""),
43  pid_file_dir_(DATA_DIR), pid_file_(), am_file_author_(false),
44  exit_value_(EXIT_SUCCESS) {
45 
46  // The pid_file_dir can be overridden via environment variable
47  // This is primarily intended to simplify testing
48  const char* const env = getenv("KEA_PIDFILE_DIR");
49  if (env) {
50  pid_file_dir_ = env;
51  }
52 }
53 
55  if (pid_file_ && am_file_author_) {
56  pid_file_->deleteFile();
57  }
58 }
59 
61 }
62 
64 }
65 
67  const ConfigPtr& storage) {
68 
69  if (log_config) {
70  ConstElementPtr loggers = log_config->get("loggers");
71  if (loggers) {
72  LogConfigParser parser(storage);
73  parser.parseConfiguration(loggers, verbose_);
74  }
75  }
76 }
77 
78 void
79 Daemon::setVerbose(bool verbose) {
80  verbose_ = verbose;
81 }
82 
83 bool
85  return (verbose_);
86 }
87 
88 void Daemon::loggerInit(const char* name, bool verbose) {
89 
90  setenv("KEA_LOGGER_DESTINATION", "stdout", 0);
91 
92  // Initialize logger system
94 
95  // Apply default configuration (log INFO or DEBUG to stdout)
97 }
98 
99 std::string Daemon::getVersion(bool /*extended*/) {
100  isc_throw(isc::NotImplemented, "Daemon::getVersion() called");
101 }
102 
103 std::string
105  return (config_file_);
106 }
107 
108 void
109 Daemon::setConfigFile(const std::string& config_file) {
110  config_file_ = config_file;
111 }
112 
113 void
115  if (config_file_.empty()) {
116  isc_throw(isc::BadValue, "config file name is not set");
117  }
118 
119  // Create Filename instance from the config_file_ pathname, and
120  // check the file name component.
121  isc::util::Filename file(config_file_);
122  if (file.name().empty()) {
123  isc_throw(isc::BadValue, "config file:" << config_file_
124  << " is missing file name");
125  }
126 }
127 
128 std::string
130  return (proc_name_);
131 };
132 
133 void
134 Daemon::setProcName(const std::string& proc_name) {
135  proc_name_ = proc_name;
136 }
137 
138 std::string
140  return(pid_file_dir_);
141 }
142 
143 void
144 Daemon::setPIDFileDir(const std::string& pid_file_dir) {
145  pid_file_dir_ = pid_file_dir;
146 }
147 
148 std::string
150  if (pid_file_) {
151  return (pid_file_->getFilename());
152  }
153 
154  return ("");
155 };
156 
157 void
158 Daemon::setPIDFileName(const std::string& pid_file_name) {
159  if (pid_file_) {
160  isc_throw(isc::InvalidOperation, "Daemon::setConfigFile"
161  " file name already set to:" << pid_file_->getFilename());
162  }
163 
164  if (pid_file_name.empty()) {
165  isc_throw(isc::BadValue, "Daemon::setPIDFileName"
166  " file name may not be empty");
167  }
168 
169  pid_file_.reset(new util::PIDFile(pid_file_name));
170 };
171 
172 std::string
174  if (config_file_.empty()) {
176  "Daemon::makePIDFileName config file name is not set");
177  }
178 
179  // Create Filename instance from the config_file_ pathname, so we can
180  // extract the fname component.
181  isc::util::Filename file(config_file_);
182  if (file.name().empty()) {
183  isc_throw(isc::BadValue, "Daemon::makePIDFileName config file:"
184  << config_file_ << " is missing file name");
185  }
186 
187  if (proc_name_.empty()) {
189  "Daemon::makePIDFileName process name is not set");
190  }
191 
192  // Make the pathname for the PID file from the runtime directory,
193  // configuration name and process name.
194  std::ostringstream stream;
195  stream << pid_file_dir_ << "/" << file.name()
196  << "." << proc_name_ << ".pid";
197 
198  return(stream.str());
199 };
200 
201 void
203  // If pid_file_ hasn't been instantiated explicitly, then do so
204  // using the default name.
205  if (!pid_file_) {
207  }
208 
209  // If we find a pre-existing file containing a live PID we bail.
210  int chk_pid = pid_file_->check();
211  if (chk_pid > 0) {
212  isc_throw(DaemonPIDExists, "Daemon::createPIDFile: PID: " << chk_pid
213  << " exists, PID file: " << getPIDFileName());
214  }
215 
216  if (pid == 0) {
217  // Write the PID of the current process
218  pid_file_->write();
219  } else {
220  // Write the PID we were given
221  pid_file_->write(pid);
222  }
223 
224  am_file_author_ = true;
225 }
226 
227 size_t
228 Daemon::writeConfigFile(const std::string& config_file,
229  ConstElementPtr cfg) const {
230  if (!cfg) {
231  isc_throw(Unexpected, "Can't write configuration: conversion to JSON failed");
232  }
233 
234  std::ofstream out(config_file, std::ios::trunc);
235  if (!out.good()) {
236  isc_throw(Unexpected, "Unable to open file " + config_file + " for writing");
237  }
238 
239  // Write the actual content using pretty printing.
240  prettyPrint(cfg, out);
241 
242  size_t bytes = static_cast<size_t>(out.tellp());
243 
244  out.close();
245 
246  return (bytes);
247 }
248 
249 std::list<std::list<std::string>>
251  static std::list<std::list<std::string>> const list;
252  return list;
253 }
254 
257  isc::data::ConstElementPtr result(config);
258  for (std::list<std::string>& json_path : jsonPathsToRedact()) {
259  result = isc::process::redactConfig(result, json_path);
260  }
261  return result;
262 }
263 
264 } // namespace process
265 } // namespace isc
A generic exception that is thrown when a function is not implemented.
void setDefaultLoggingOutput(bool verbose)
Reset root logger characteristics.
void setPIDFileName(const std::string &pid_file_name)
Sets PID file name.
Definition: daemon.cc:158
std::string name() const
Definition: filename.h:88
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition: data.cc:1487
void checkConfigFile() const
Checks the configuration file name.
Definition: daemon.cc:114
virtual void shutdown()
Initiates shutdown procedure for the whole server.
Definition: daemon.cc:63
virtual void cleanup()
Performs final deconfiguration.
Definition: daemon.cc:60
virtual ~Daemon()
Destructor.
Definition: daemon.cc:54
Class to help with processing PID files.
Definition: pid_file.h:40
std::string getConfigFile() const
Returns config file name.
Definition: daemon.cc:104
void parseConfiguration(const isc::data::ConstElementPtr &log_config, bool verbose=false)
Parses specified configuration.
Definition: log_parser.cc:31
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static void setProcName(const std::string &proc_name)
Sets the process name.
Definition: daemon.cc:134
A generic exception that is thrown when an unexpected error condition occurs.
void setConfigFile(const std::string &config_file)
Sets the configuration file name.
Definition: daemon.cc:109
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
virtual std::list< std::list< std::string > > jsonPathsToRedact() const
Return a list of all paths that contain passwords or secrets.
Definition: daemon.cc:250
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
Definition: daemon.cc:256
static std::string getVersion(bool extended)
returns Kea version on stdout and exits.
Definition: daemon.cc:99
static void setVerbose(const bool verbose)
Sets or clears verbose mode.
Definition: daemon.cc:79
ConstElementPtr redactConfig(ConstElementPtr const &element, list< string > const &json_path)
Redact a configuration.
Defines the logger used by the top-level component of kea-lfc.
std::string getPIDFileName() const
Returns the current PID file name.
Definition: daemon.cc:149
static void loggerInit(const char *log_name, bool verbose)
Initializes logger.
Definition: daemon.cc:88
Logging initialization functions.
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:228
Configures log4cplus by translating Kea configuration structures.
Definition: log_parser.h:43
A generic exception that is thrown if a function is called in a prohibited way.
static bool getVerbose()
Returns if running in verbose mode.
Definition: daemon.cc:84
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name ...
Definition: daemon.cc:129
void setPIDFileDir(const std::string &pid_file_dir)
Sets the PID file directory.
Definition: daemon.cc:144
Exception thrown when the PID file points to a live PID.
Definition: daemon.h:25
void initLogger(const string &root, isc::log::Severity severity, int dbglevel, const char *file, bool buffer)
Run-time initialization.
std::string getPIDFileDir() const
Returns the directory used when forming default PID file name.
Definition: daemon.cc:139
void createPIDFile(int pid=0)
Creates the PID file.
Definition: daemon.cc:202
Class to Manipulate Filenames.
Definition: filename.h:50
const int MAX_DEBUG_LEVEL
Definition: logger_level.h:36
std::string makePIDFileName() const
Manufacture the pid file name.
Definition: daemon.cc:173
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
Definition: config_base.h:176
static void configureLogger(const isc::data::ConstElementPtr &log_config, const isc::process::ConfigPtr &storage)
Configures logger.
Definition: daemon.cc:66