cfengine  3.15.4
About: CFEngine is a configuration management system for configuring and maintaining Unix-like computers (using an own high level policy language). Community version.
  Fossies Dox: cfengine-3.15.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cf-monitord.c
Go to the documentation of this file.
1 /*
2  Copyright 2019 Northern.tech AS
3 
4  This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the
8  Free Software Foundation; version 3.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 
19  To the extent this program is licensed as part of the Enterprise
20  versions of CFEngine, the applicable Commercial Open Source License
21  (COSL) may apply to this file if you as a licensee so wish it. See
22  included file COSL.txt.
23 */
24 
25 #include <generic_agent.h>
26 #include <mon.h>
27 
28 #include <eval_context.h>
29 #include <env_monitor.h>
30 #include <conversion.h>
31 #include <vars.h>
32 #include <signals.h>
33 #include <scope.h>
34 #include <known_dirs.h>
35 #include <man.h>
36 #include <bootstrap.h>
37 #include <timeout.h>
38 #include <time_classes.h>
39 #include <loading.h>
40 #include <cleanup.h>
41 #include <file_lib.h> /* FILE_SEPARATOR */
42 
43 typedef enum
44 {
51 
52 static void ThisAgentInit(EvalContext *ctx);
53 static GenericAgentConfig *CheckOpts(int argc, char **argv);
54 static void KeepPromises(EvalContext *ctx, const Policy *policy);
55 
56 /*****************************************************************************/
57 /* Globals */
58 /*****************************************************************************/
59 
60 extern int NO_FORK;
61 
62 extern const ConstraintSyntax CFM_CONTROLBODY[];
63 
64 /*******************************************************************/
65 /* Command line options */
66 /*******************************************************************/
67 
68 static const char *const CF_MONITORD_SHORT_DESCRIPTION =
69  "monitoring daemon for CFEngine";
70 
71 static const char *const CF_MONITORD_MANPAGE_LONG_DESCRIPTION =
72  "cf-monitord is the monitoring daemon for CFEngine. It samples probes defined in policy code and attempts to learn the "
73  "normal system state based on current and past observations. Current estimates are made available as "
74  "special variables (e.g. $(mon.av_cpu)) to cf-agent, which may use them to inform policy decisions.";
75 
76 static const struct option OPTIONS[] =
77 {
78  {"help", no_argument, 0, 'h'},
79  {"debug", no_argument, 0, 'd'},
80  {"verbose", no_argument, 0, 'v'},
81  {"dry-run", no_argument, 0, 'n'},
82  {"version", no_argument, 0, 'V'},
83  {"no-lock", no_argument, 0, 'K'},
84  {"file", required_argument, 0, 'f'},
85  {"log-level", required_argument, 0, 'g'},
86  {"inform", no_argument, 0, 'I'},
87  {"diagnostic", no_argument, 0, 'x'},
88  {"no-fork", no_argument, 0, 'F'},
89  {"histograms", no_argument, 0, 'H'},
90  {"tcpdump", no_argument, 0, 'T'},
91  {"color", optional_argument, 0, 'C'},
92  {"timestamp", no_argument, 0, 'l'},
93  {NULL, 0, 0, '\0'}
94 };
95 
96 static const char *const HINTS[] =
97 {
98  "Print the help message",
99  "Enable debugging output",
100  "Output verbose information about the behaviour of cf-monitord",
101  "All talk and no action mode - make no changes, only inform of promises not kept",
102  "Output the version of the software",
103  "Ignore system lock",
104  "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.",
105  "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'",
106  "Print basic information about changes made to the system, i.e. promises repaired",
107  "Activate internal diagnostics (developers only)",
108  "Run process in foreground, not as a daemon",
109  "Ignored for backward compatibility",
110  "Interface with tcpdump if available to collect data about network",
111  "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'",
112  "Log timestamps on each line of log output",
113  NULL
114 };
115 
116 /*****************************************************************************/
117 
118 int main(int argc, char *argv[])
119 {
120  GenericAgentConfig *config = CheckOpts(argc, argv);
121  EvalContext *ctx = EvalContextNew();
122  GenericAgentConfigApply(ctx, config);
123 
124  const char *program_invocation_name = argv[0];
125  const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR);
126  const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name);
127  GenericAgentDiscoverContext(ctx, config, program_name);
128 
129  Policy *policy = LoadPolicy(ctx, config);
130 
132  ThisAgentInit(ctx);
133 
134  KeepPromises(ctx, policy);
135 
136  MonitorStartServer(ctx, policy);
137 
138  PolicyDestroy(policy);
139  GenericAgentFinalize(ctx, config);
141  return 0;
142 }
143 
144 /*******************************************************************/
145 
146 static GenericAgentConfig *CheckOpts(int argc, char **argv)
147 {
148  extern char *optarg;
149  int c;
151 
152  while ((c = getopt_long(argc, argv, "dvnIf:g:VSxHTKMFhC::l",
153  OPTIONS, NULL)) != -1)
154  {
155  switch (c)
156  {
157  case 'f':
159  MINUSF = true;
160  break;
161 
162  case 'd':
164  NO_FORK = true;
165  break;
166 
167  case 'K':
168  config->ignore_locks = true;
169  break;
170 
171  case 'I':
173  break;
174 
175  case 'v':
177  NO_FORK = true;
178  break;
179 
180  case 'g':
182  break;
183 
184  case 'F':
185  NO_FORK = true;
186  break;
187 
188  case 'H': /* Keep accepting this option for compatibility -- no longer used */
189  break;
190 
191  case 'T':
193  break;
194 
195  case 'V':
196  {
197  Writer *w = FileWriter(stdout);
199  FileWriterDetach(w);
200  }
201  DoCleanupAndExit(EXIT_SUCCESS);
202 
203  case 'h':
204  {
205  Writer *w = FileWriter(stdout);
206  WriterWriteHelp(w, "cf-monitord", OPTIONS, HINTS, NULL, false, true);
207  FileWriterDetach(w);
208  }
209  DoCleanupAndExit(EXIT_SUCCESS);
210 
211  case 'M':
212  {
213  Writer *out = FileWriter(stdout);
214  ManPageWrite(out, "cf-monitord", time(NULL),
217  OPTIONS, HINTS,
218  NULL, false,
219  true);
220  FileWriterDetach(out);
221  DoCleanupAndExit(EXIT_SUCCESS);
222  }
223 
224  case 'x':
225  Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
226  DoCleanupAndExit(EXIT_SUCCESS);
227 
228  case 'C':
229  if (!GenericAgentConfigParseColor(config, optarg))
230  {
231  DoCleanupAndExit(EXIT_FAILURE);
232  }
233  break;
234 
235  case 'l':
237  break;
238 
239  default:
240  {
241  Writer *w = FileWriter(stdout);
242  WriterWriteHelp(w, "cf-monitord", OPTIONS, HINTS, NULL, false, true);
243  FileWriterDetach(w);
244  }
245  DoCleanupAndExit(EXIT_FAILURE);
246  }
247  }
248 
249  if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
250  {
251  Log(LOG_LEVEL_ERR, "Too many arguments");
252  DoCleanupAndExit(EXIT_FAILURE);
253  }
254 
255  return config;
256 }
257 
258 /*****************************************************************************/
259 
260 static void KeepPromises(EvalContext *ctx, const Policy *policy)
261 {
262  Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_MONITOR);
263  if (constraints)
264  {
265  for (size_t i = 0; i < SeqLength(constraints); i++)
266  {
267  Constraint *cp = SeqAt(constraints, i);
268 
269  if (!IsDefinedClass(ctx, cp->classes))
270  {
271  continue;
272  }
273 
274  VarRef *ref = VarRefParseFromScope(cp->lval, "control_monitor");
275  const void *value = EvalContextVariableGet(ctx, ref, NULL);
276  VarRefDestroy(ref);
277  if (!value)
278  {
279  Log(LOG_LEVEL_ERR, "Unknown lval '%s' in monitor control body", cp->lval);
280  continue;
281  }
282 
283  if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_HISTOGRAMS].lval) == 0)
284  {
285  /* Keep accepting this option for backward compatibility. */
286  }
287 
288  if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_TCP_DUMP].lval) == 0)
289  {
291  }
292 
293  if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_FORGET_RATE].lval) == 0)
294  {
295  sscanf(value, "%lf", &FORGETRATE);
296  Log(LOG_LEVEL_DEBUG, "forget rate %f", FORGETRATE);
297  }
298  }
299  }
300 }
301 
302 /*****************************************************************************/
303 /* Level 1 */
304 /*****************************************************************************/
305 
306 static void ThisAgentInit(EvalContext *ctx)
307 {
308  umask(077);
309  strcpy(VPREFIX, "cf-monitord");
310 
311  time_t t = SetReferenceTime();
312  UpdateTimeClasses(ctx, t);
313 
314  signal(SIGINT, HandleSignalsForDaemon);
315  signal(SIGTERM, HandleSignalsForDaemon);
316  signal(SIGBUS, HandleSignalsForDaemon);
317  signal(SIGHUP, SIG_IGN);
318  signal(SIGPIPE, SIG_IGN);
319  signal(SIGUSR1, HandleSignalsForDaemon);
320  signal(SIGUSR2, HandleSignalsForDaemon);
321 
322  FORGETRATE = 0.6;
323 
325 }
int main(int argc, char *argv[])
Definition: cf-monitord.c:118
const ConstraintSyntax CFM_CONTROLBODY[]
Definition: mod_common.c:351
static void KeepPromises(EvalContext *ctx, const Policy *policy)
Definition: cf-monitord.c:260
static GenericAgentConfig * CheckOpts(int argc, char **argv)
Definition: cf-monitord.c:146
static const char *const HINTS[]
Definition: cf-monitord.c:96
static void ThisAgentInit(EvalContext *ctx)
Definition: cf-monitord.c:306
MonitorControl
Definition: cf-monitord.c:44
@ MONITOR_CONTROL_HISTOGRAMS
Definition: cf-monitord.c:47
@ MONITOR_CONTROL_NONE
Definition: cf-monitord.c:49
@ MONITOR_CONTROL_TCP_DUMP
Definition: cf-monitord.c:48
@ MONITOR_CONTROL_FORGET_RATE
Definition: cf-monitord.c:45
@ MONITOR_CONTROL_MONITOR_FACILITY
Definition: cf-monitord.c:46
static const char *const CF_MONITORD_SHORT_DESCRIPTION
Definition: cf-monitord.c:68
static const char *const CF_MONITORD_MANPAGE_LONG_DESCRIPTION
Definition: cf-monitord.c:71
static const struct option OPTIONS[]
Definition: cf-monitord.c:76
int NO_FORK
Definition: env_monitor.c:94
@ AGENT_TYPE_MONITOR
Definition: cf3.defs.h:404
bool MINUSF
Definition: cf3globals.c:150
void CallCleanupFunctions(void)
Definition: cleanup.c:39
void DoCleanupAndExit(int ret)
Definition: cleanup.c:57
bool BooleanFromString(const char *s)
Definition: conversion.c:354
void MonitorInitialize(void)
Definition: env_monitor.c:121
void MonitorStartServer(EvalContext *ctx, const Policy *policy)
Definition: env_monitor.c:267
double FORGETRATE
Definition: env_monitor.c:65
EvalContext * EvalContextNew(void)
const void * EvalContextVariableGet(const EvalContext *ctx, const VarRef *ref, DataType *type_out)
static bool IsDefinedClass(const EvalContext *ctx, const char *context)
Definition: eval_context.h:213
#define FILE_SEPARATOR
Definition: file_lib.h:102
void GenericAgentConfigSetInputFile(GenericAgentConfig *config, const char *inputdir, const char *input_file)
GenericAgentConfig * GenericAgentConfigNewDefault(AgentType agent_type, bool tty_interactive)
bool GenericAgentPostLoadInit(const EvalContext *ctx)
Seq * ControlBodyConstraints(const Policy *policy, AgentType agent)
void GenericAgentFinalize(EvalContext *ctx, GenericAgentConfig *config)
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config, const char *program_name)
bool GenericAgentConfigParseArguments(GenericAgentConfig *config, int argc, char **argv)
bool GetTTYInteractive(void)
bool GenericAgentConfigParseColor(GenericAgentConfig *config, const char *mode)
void GenericAgentConfigApply(EvalContext *ctx, const GenericAgentConfig *config)
void GenericAgentWriteVersion(Writer *w)
#define NULL
Definition: getopt1.c:56
int optind
Definition: getopt.c:102
char * optarg
Definition: getopt.c:87
#define no_argument
Definition: getopt.h:98
#define required_argument
Definition: getopt.h:99
int getopt_long()
#define optional_argument
Definition: getopt.h:100
const char * GetInputDir(void)
Definition: known_dirs.c:182
Policy * LoadPolicy(EvalContext *ctx, GenericAgentConfig *config)
Definition: loading.c:495
void LogSetGlobalLevelArgOrExit(const char *const arg)
Definition: logging.c:567
void LoggingEnableTimestamps(bool enable)
Definition: logging.c:88
void LogSetGlobalLevel(LogLevel level)
Definition: logging.c:561
char VPREFIX[1024]
Definition: logging.c:33
void Log(LogLevel level, const char *fmt,...)
Definition: logging.c:409
@ LOG_LEVEL_ERR
Definition: logging.h:42
@ LOG_LEVEL_DEBUG
Definition: logging.h:47
@ LOG_LEVEL_VERBOSE
Definition: logging.h:46
@ LOG_LEVEL_INFO
Definition: logging.h:45
void ManPageWrite(Writer *out, const char *program, time_t last_modified, const char *short_description, const char *long_description, const struct option options[], const char *const option_hints[], const Description *commands, bool command_first, bool accepts_file_argument)
Definition: man.c:226
void MonNetworkSnifferEnable(bool enable)
void PolicyDestroy(Policy *policy)
Definition: policy.c:121
size_t SeqLength(const Seq *seq)
Length of the sequence.
Definition: sequence.c:354
static void * SeqAt(const Seq *seq, int i)
Definition: sequence.h:57
void HandleSignalsForDaemon(int signum)
Definition: signals.c:194
const char * lval
Definition: cf3.defs.h:656
char * classes
Definition: policy.h:135
char * lval
Definition: policy.h:132
Definition: policy.h:53
Sequence data-structure.
Definition: sequence.h:50
Definition: writer.c:45
Definition: getopt.h:83
void UpdateTimeClasses(EvalContext *ctx, time_t t)
Definition: time_classes.c:133
time_t SetReferenceTime(void)
Definition: timeout.c:55
VarRef * VarRefParseFromScope(const char *var_ref_string, const char *scope)
void VarRefDestroy(VarRef *ref)
void WriterWriteHelp(Writer *w, const char *component, const struct option options[], const char *const hints[], const Description *commands, bool command_first, bool accepts_file_argument)
Definition: writer.c:331
Writer * FileWriter(FILE *file)
Definition: writer.c:56
FILE * FileWriterDetach(Writer *writer)
Definition: writer.c:277