1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "common.h"
21 #include "sysinfo.h"
22
23 #include "cfg.h"
24 #include "log.h"
25 #include "zbxconf.h"
26 #include "zbxgetopt.h"
27 #include "comms.h"
28
29 char *CONFIG_HOSTS_ALLOWED = NULL;
30 char *CONFIG_HOSTNAME = NULL;
31 char *CONFIG_HOSTNAME_ITEM = NULL;
32 char *CONFIG_HOST_METADATA = NULL;
33 char *CONFIG_HOST_METADATA_ITEM = NULL;
34
35 int CONFIG_ENABLE_REMOTE_COMMANDS = 0;
36 int CONFIG_LOG_REMOTE_COMMANDS = 0;
37 int CONFIG_UNSAFE_USER_PARAMETERS = 0;
38 int CONFIG_LISTEN_PORT = ZBX_DEFAULT_AGENT_PORT;
39 int CONFIG_REFRESH_ACTIVE_CHECKS = 120;
40 char *CONFIG_LISTEN_IP = NULL;
41 char *CONFIG_SOURCE_IP = NULL;
42 int CONFIG_LOG_LEVEL = LOG_LEVEL_WARNING;
43
44 int CONFIG_BUFFER_SIZE = 100;
45 int CONFIG_BUFFER_SEND = 5;
46
47 int CONFIG_MAX_LINES_PER_SECOND = 20;
48
49 char *CONFIG_LOAD_MODULE_PATH = NULL;
50
51 char **CONFIG_ALIASES = NULL;
52 char **CONFIG_LOAD_MODULE = NULL;
53 char **CONFIG_USER_PARAMETERS = NULL;
54 #if defined(_WINDOWS)
55 char **CONFIG_PERF_COUNTERS = NULL;
56 char **CONFIG_PERF_COUNTERS_EN = NULL;
57 #endif
58
59 char *CONFIG_USER = NULL;
60
61 /* SSL parameters */
62 char *CONFIG_SSL_CA_LOCATION;
63 char *CONFIG_SSL_CERT_LOCATION;
64 char *CONFIG_SSL_KEY_LOCATION;
65
66 /* TLS parameters */
67 unsigned int configured_tls_connect_mode = ZBX_TCP_SEC_UNENCRYPTED;
68 unsigned int configured_tls_accept_modes = ZBX_TCP_SEC_UNENCRYPTED;
69
70 char *CONFIG_TLS_CONNECT = NULL;
71 char *CONFIG_TLS_ACCEPT = NULL;
72 char *CONFIG_TLS_CA_FILE = NULL;
73 char *CONFIG_TLS_CRL_FILE = NULL;
74 char *CONFIG_TLS_SERVER_CERT_ISSUER = NULL;
75 char *CONFIG_TLS_SERVER_CERT_SUBJECT = NULL;
76 char *CONFIG_TLS_CERT_FILE = NULL;
77 char *CONFIG_TLS_KEY_FILE = NULL;
78 char *CONFIG_TLS_PSK_IDENTITY = NULL;
79 char *CONFIG_TLS_PSK_FILE = NULL;
80 char *CONFIG_TLS_CIPHER_CERT13 = NULL;
81 char *CONFIG_TLS_CIPHER_CERT = NULL;
82 char *CONFIG_TLS_CIPHER_PSK13 = NULL;
83 char *CONFIG_TLS_CIPHER_PSK = NULL;
84 char *CONFIG_TLS_CIPHER_ALL13 = NULL;
85 char *CONFIG_TLS_CIPHER_ALL = NULL;
86 char *CONFIG_TLS_CIPHER_CMD13 = NULL; /* not used in agent, defined for linking with tls.c */
87 char *CONFIG_TLS_CIPHER_CMD = NULL; /* not used in agent, defined for linking with tls.c */
88
89 #ifndef _WINDOWS
90 # include "../libs/zbxnix/control.h"
91 # include "zbxmodules.h"
92 #endif
93
94 #include "comms.h"
95 #include "alias.h"
96
97 #include "stats.h"
98 #ifdef _WINDOWS
99 # include "perfstat.h"
100 #else
101 # include "zbxnix.h"
102 # include "sighandler.h"
103 #endif
104 #include "active.h"
105 #include "listener.h"
106
107 #include "symbols.h"
108
109 #if defined(ZABBIX_SERVICE)
110 # include "service.h"
111 #elif defined(ZABBIX_DAEMON)
112 # include "daemon.h"
113 #endif
114
115 #include "setproctitle.h"
116 #include "../libs/zbxcrypto/tls.h"
117
118 const char *progname = NULL;
119
120 /* application TITLE */
121 const char title_message[] = "zabbix_agentd"
122 #if defined(_WIN64)
123 " Win64"
124 #elif defined(_WIN32)
125 " Win32"
126 #endif
127 #if defined(ZABBIX_SERVICE)
128 " (service)"
129 #elif defined(ZABBIX_DAEMON)
130 " (daemon)"
131 #endif
132 ;
133 /* end of application TITLE */
134
135 const char syslog_app_name[] = "zabbix_agentd";
136
137 /* application USAGE message */
138 const char *usage_message[] = {
139 "[-c config-file]", NULL,
140 "[-c config-file]", "-p", NULL,
141 "[-c config-file]", "-t item-key", NULL,
142 #ifdef _WINDOWS
143 "[-c config-file]", "-i", "[-m]", NULL,
144 "[-c config-file]", "-d", "[-m]", NULL,
145 "[-c config-file]", "-s", "[-m]", NULL,
146 "[-c config-file]", "-x", "[-m]", NULL,
147 #else
148 "[-c config-file]", "-R runtime-option", NULL,
149 #endif
150 "-h", NULL,
151 "-V", NULL,
152 NULL /* end of text */
153 };
154 /* end of application USAGE message */
155
156 /* application HELP message */
157 const char *help_message[] = {
158 "A Zabbix daemon for monitoring of various server parameters.",
159 "",
160 "Options:",
161 " -c --config config-file Path to the configuration file",
162 " (default: \"" DEFAULT_CONFIG_FILE "\")",
163 " -f --foreground Run Zabbix agent in foreground",
164 " -p --print Print known items and exit",
165 " -t --test item-key Test specified item and exit",
166 #ifdef _WINDOWS
167 " -m --multiple-agents For -i -d -s -x functions service name will",
168 " include Hostname parameter specified in",
169 " configuration file",
170 "Functions:",
171 "",
172 " -i --install Install Zabbix agent as service",
173 " -d --uninstall Uninstall Zabbix agent from service",
174
175 " -s --start Start Zabbix agent service",
176 " -x --stop Stop Zabbix agent service",
177 #else
178 " -R --runtime-control runtime-option Perform administrative functions",
179 "",
180 " Runtime control options:",
181 " " ZBX_LOG_LEVEL_INCREASE "=target Increase log level, affects all processes if",
182 " target is not specified",
183 " " ZBX_LOG_LEVEL_DECREASE "=target Decrease log level, affects all processes if",
184 " target is not specified",
185 "",
186 " Log level control targets:",
187 " process-type All processes of specified type (active checks,",
188 " collector, listener)",
189 " process-type,N Process type and number (e.g., listener,3)",
190 " pid Process identifier, up to 65535. For larger",
191 " values specify target as \"process-type,N\"",
192 #endif
193 "",
194 " -h --help Display this help message",
195 " -V --version Display version number",
196 "",
197 #ifndef _WINDOWS
198 "Default loadable module location:",
199 " LoadModulePath \"" DEFAULT_LOAD_MODULE_PATH "\"",
200 "",
201 #endif
202 #ifdef _WINDOWS
203 "Example: zabbix_agentd -c C:\\zabbix\\zabbix_agentd.conf",
204 #else
205 "Example: zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf",
206 #endif
207 NULL /* end of text */
208 };
209 /* end of application HELP message */
210
211 /* COMMAND LINE OPTIONS */
212 static struct zbx_option longopts[] =
213 {
214 {"config", 1, NULL, 'c'},
215 {"foreground", 0, NULL, 'f'},
216 {"help", 0, NULL, 'h'},
217 {"version", 0, NULL, 'V'},
218 {"print", 0, NULL, 'p'},
219 {"test", 1, NULL, 't'},
220 #ifndef _WINDOWS
221 {"runtime-control", 1, NULL, 'R'},
222 #else
223 {"install", 0, NULL, 'i'},
224 {"uninstall", 0, NULL, 'd'},
225
226 {"start", 0, NULL, 's'},
227 {"stop", 0, NULL, 'x'},
228
229 {"multiple-agents", 0, NULL, 'm'},
230 #endif
231 {NULL}
232 };
233
234 static char shortopts[] =
235 "c:hVpt:f"
236 #ifndef _WINDOWS
237 "R:"
238 #else
239 "idsxm"
240 #endif
241 ;
242 /* end of COMMAND LINE OPTIONS */
243
244 static char *TEST_METRIC = NULL;
245 int threads_num = 0;
246 ZBX_THREAD_HANDLE *threads = NULL;
247 static int *threads_flags;
248
249 unsigned char program_type = ZBX_PROGRAM_TYPE_AGENTD;
250
251 ZBX_THREAD_LOCAL unsigned char process_type = 255; /* ZBX_PROCESS_TYPE_UNKNOWN */
252 ZBX_THREAD_LOCAL int process_num;
253 ZBX_THREAD_LOCAL int server_num = 0;
254
255 static ZBX_THREAD_ACTIVECHK_ARGS *CONFIG_ACTIVE_ARGS = NULL;
256
257 int CONFIG_ALERTER_FORKS = 0;
258 int CONFIG_DISCOVERER_FORKS = 0;
259 int CONFIG_HOUSEKEEPER_FORKS = 0;
260 int CONFIG_PINGER_FORKS = 0;
261 int CONFIG_POLLER_FORKS = 0;
262 int CONFIG_UNREACHABLE_POLLER_FORKS = 0;
263 int CONFIG_HTTPPOLLER_FORKS = 0;
264 int CONFIG_IPMIPOLLER_FORKS = 0;
265 int CONFIG_TIMER_FORKS = 0;
266 int CONFIG_TRAPPER_FORKS = 0;
267 int CONFIG_SNMPTRAPPER_FORKS = 0;
268 int CONFIG_JAVAPOLLER_FORKS = 0;
269 int CONFIG_ESCALATOR_FORKS = 0;
270 int CONFIG_SELFMON_FORKS = 0;
271 int CONFIG_DATASENDER_FORKS = 0;
272 int CONFIG_HEARTBEAT_FORKS = 0;
273 int CONFIG_PROXYPOLLER_FORKS = 0;
274 int CONFIG_HISTSYNCER_FORKS = 0;
275 int CONFIG_CONFSYNCER_FORKS = 0;
276 int CONFIG_VMWARE_FORKS = 0;
277 int CONFIG_COLLECTOR_FORKS = 1;
278 int CONFIG_PASSIVE_FORKS = 3; /* number of listeners for processing passive checks */
279 int CONFIG_ACTIVE_FORKS = 0;
280 int CONFIG_TASKMANAGER_FORKS = 0;
281 int CONFIG_IPMIMANAGER_FORKS = 0;
282 int CONFIG_ALERTMANAGER_FORKS = 0;
283 int CONFIG_PREPROCMAN_FORKS = 0;
284 int CONFIG_PREPROCESSOR_FORKS = 0;
285
286 char *opt = NULL;
287
288 #ifdef _WINDOWS
289 void zbx_co_uninitialize();
290 #endif
291
292 int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num);
293 void zbx_free_service_resources(int ret);
294
get_process_info_by_thread(int local_server_num,unsigned char * local_process_type,int * local_process_num)295 int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num)
296 {
297 int server_count = 0;
298
299 if (0 == local_server_num)
300 {
301 /* fail if the main process is queried */
302 return FAIL;
303 }
304 else if (local_server_num <= (server_count += CONFIG_COLLECTOR_FORKS))
305 {
306 *local_process_type = ZBX_PROCESS_TYPE_COLLECTOR;
307 *local_process_num = local_server_num - server_count + CONFIG_COLLECTOR_FORKS;
308 }
309 else if (local_server_num <= (server_count += CONFIG_PASSIVE_FORKS))
310 {
311 *local_process_type = ZBX_PROCESS_TYPE_LISTENER;
312 *local_process_num = local_server_num - server_count + CONFIG_PASSIVE_FORKS;
313
314 }
315 else if (local_server_num <= (server_count += CONFIG_ACTIVE_FORKS))
316 {
317 *local_process_type = ZBX_PROCESS_TYPE_ACTIVE_CHECKS;
318 *local_process_num = local_server_num - server_count + CONFIG_ACTIVE_FORKS;
319 }
320 else
321 return FAIL;
322
323 return SUCCEED;
324 }
325
parse_commandline(int argc,char ** argv,ZBX_TASK_EX * t)326 static int parse_commandline(int argc, char **argv, ZBX_TASK_EX *t)
327 {
328 int i, ret = SUCCEED;
329 char ch;
330 #ifdef _WINDOWS
331 unsigned int opt_mask = 0;
332 #endif
333 unsigned short opt_count[256] = {0};
334
335 t->task = ZBX_TASK_START;
336
337 /* parse the command-line */
338 while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, shortopts, longopts, NULL)))
339 {
340 opt_count[(unsigned char)ch]++;
341
342 switch (ch)
343 {
344 case 'c':
345 if (NULL == CONFIG_FILE)
346 CONFIG_FILE = strdup(zbx_optarg);
347 break;
348 #ifndef _WINDOWS
349 case 'R':
350 if (SUCCEED != parse_rtc_options(zbx_optarg, program_type, &t->data))
351 exit(EXIT_FAILURE);
352
353 t->task = ZBX_TASK_RUNTIME_CONTROL;
354 break;
355 #endif
356 case 'h':
357 t->task = ZBX_TASK_SHOW_HELP;
358 goto out;
359 case 'V':
360 t->task = ZBX_TASK_SHOW_VERSION;
361 goto out;
362 case 'p':
363 if (ZBX_TASK_START == t->task)
364 t->task = ZBX_TASK_PRINT_SUPPORTED;
365 break;
366 case 't':
367 if (ZBX_TASK_START == t->task)
368 {
369 t->task = ZBX_TASK_TEST_METRIC;
370 TEST_METRIC = strdup(zbx_optarg);
371 }
372 break;
373 case 'f':
374 t->flags |= ZBX_TASK_FLAG_FOREGROUND;
375 break;
376 #ifdef _WINDOWS
377 case 'i':
378 t->task = ZBX_TASK_INSTALL_SERVICE;
379 break;
380 case 'd':
381 t->task = ZBX_TASK_UNINSTALL_SERVICE;
382 break;
383 case 's':
384 t->task = ZBX_TASK_START_SERVICE;
385 break;
386 case 'x':
387 t->task = ZBX_TASK_STOP_SERVICE;
388 break;
389 case 'm':
390 t->flags |= ZBX_TASK_FLAG_MULTIPLE_AGENTS;
391 break;
392 #endif
393 default:
394 t->task = ZBX_TASK_SHOW_USAGE;
395 goto out;
396 }
397 }
398
399 #ifdef _WINDOWS
400 switch (t->task)
401 {
402 case ZBX_TASK_START:
403 break;
404 case ZBX_TASK_INSTALL_SERVICE:
405 case ZBX_TASK_UNINSTALL_SERVICE:
406 case ZBX_TASK_START_SERVICE:
407 case ZBX_TASK_STOP_SERVICE:
408 if (0 != (t->flags & ZBX_TASK_FLAG_FOREGROUND))
409 {
410 zbx_error("foreground option cannot be used with Zabbix agent services");
411 ret = FAIL;
412 goto out;
413 }
414 break;
415 default:
416 if (0 != (t->flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS))
417 {
418 zbx_error("multiple agents option can be used only with Zabbix agent services");
419 ret = FAIL;
420 goto out;
421 }
422 }
423 #endif
424
425 /* every option may be specified only once */
426
427 for (i = 0; NULL != longopts[i].name; i++)
428 {
429 ch = (char)longopts[i].val;
430
431 if ('h' == ch || 'V' == ch)
432 continue;
433
434 if (1 < opt_count[(unsigned char)ch])
435 {
436 if (NULL == strchr(shortopts, ch))
437 zbx_error("option \"--%s\" specified multiple times", longopts[i].name);
438 else
439 zbx_error("option \"-%c\" or \"--%s\" specified multiple times", ch, longopts[i].name);
440
441 ret = FAIL;
442 }
443 }
444
445 if (FAIL == ret)
446 goto out;
447
448 #ifdef _WINDOWS
449 /* check for mutually exclusive options */
450 /* Allowed option combinations. */
451 /* Option 'c' is always optional. */
452 /* p t i d s x m opt_mask */
453 /* --------------------- -------- */
454 /* - - - - - - - 0x00 */
455 /* p - - - - - - 0x40 */
456 /* - t - - - - - 0x20 */
457 /* - - i - - - - 0x10 */
458 /* - - - d - - - 0x08 */
459 /* - - - - s - - 0x04 */
460 /* - - - - - x - 0x02 */
461 /* - - i - - - m 0x11 */
462 /* - - - d - - m 0x09 */
463 /* - - - - s - m 0x05 */
464 /* - - - - - x m 0x03 */
465 /* - - - - - - m 0x01 special case required for starting as a service with '-m' option */
466
467 if (0 < opt_count['p'])
468 opt_mask |= 0x40;
469 if (0 < opt_count['t'])
470 opt_mask |= 0x20;
471 if (0 < opt_count['i'])
472 opt_mask |= 0x10;
473 if (0 < opt_count['d'])
474 opt_mask |= 0x08;
475 if (0 < opt_count['s'])
476 opt_mask |= 0x04;
477 if (0 < opt_count['x'])
478 opt_mask |= 0x02;
479 if (0 < opt_count['m'])
480 opt_mask |= 0x01;
481
482 switch (opt_mask)
483 {
484 case 0x00:
485 case 0x01:
486 case 0x02:
487 case 0x03:
488 case 0x04:
489 case 0x05:
490 case 0x08:
491 case 0x09:
492 case 0x10:
493 case 0x11:
494 case 0x20:
495 case 0x40:
496 break;
497 default:
498 zbx_error("mutually exclusive options used");
499 usage();
500 ret = FAIL;
501 goto out;
502 }
503 #else
504 /* check for mutually exclusive options */
505 if (1 < opt_count['p'] + opt_count['t'] + opt_count['R'])
506 {
507 zbx_error("only one of options \"-p\" or \"--print\", \"-t\" or \"--test\","
508 " \"-R\" or \"--runtime-control\" can be used");
509 ret = FAIL;
510 goto out;
511 }
512 #endif
513 /* Parameters which are not option values are invalid. The check relies on zbx_getopt_internal() which */
514 /* always permutes command line arguments regardless of POSIXLY_CORRECT environment variable. */
515 if (argc > zbx_optind)
516 {
517 for (i = zbx_optind; i < argc; i++)
518 zbx_error("invalid parameter \"%s\"", argv[i]);
519
520 ret = FAIL;
521 goto out;
522 }
523
524 if (NULL == CONFIG_FILE)
525 CONFIG_FILE = zbx_strdup(NULL, DEFAULT_CONFIG_FILE);
526 out:
527 if (FAIL == ret)
528 {
529 zbx_free(TEST_METRIC);
530 zbx_free(CONFIG_FILE);
531 }
532
533 return ret;
534 }
535
536 /******************************************************************************
537 * *
538 * Function: set_defaults *
539 * *
540 * Purpose: set configuration defaults *
541 * *
542 * Author: Vladimir Levijev, Rudolfs Kreicbergs *
543 * *
544 ******************************************************************************/
set_defaults(void)545 static void set_defaults(void)
546 {
547 AGENT_RESULT result;
548 char **value = NULL;
549
550 if (NULL == CONFIG_HOSTNAME)
551 {
552 if (NULL == CONFIG_HOSTNAME_ITEM)
553 CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");
554
555 init_result(&result);
556
557 if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, PROCESS_LOCAL_COMMAND | PROCESS_WITH_ALIAS, &result) &&
558 NULL != (value = GET_STR_RESULT(&result)))
559 {
560 assert(*value);
561
562 if (MAX_ZBX_HOSTNAME_LEN < strlen(*value))
563 {
564 (*value)[MAX_ZBX_HOSTNAME_LEN] = '\0';
565 zabbix_log(LOG_LEVEL_WARNING, "hostname truncated to [%s])", *value);
566 }
567
568 CONFIG_HOSTNAME = zbx_strdup(CONFIG_HOSTNAME, *value);
569 }
570 else
571 zabbix_log(LOG_LEVEL_WARNING, "failed to get system hostname from [%s])", CONFIG_HOSTNAME_ITEM);
572
573 free_result(&result);
574 }
575 else if (NULL != CONFIG_HOSTNAME_ITEM)
576 zabbix_log(LOG_LEVEL_WARNING, "both Hostname and HostnameItem defined, using [%s]", CONFIG_HOSTNAME);
577
578 if (NULL != CONFIG_HOST_METADATA && NULL != CONFIG_HOST_METADATA_ITEM)
579 {
580 zabbix_log(LOG_LEVEL_WARNING, "both HostMetadata and HostMetadataItem defined, using [%s]",
581 CONFIG_HOST_METADATA);
582 }
583
584 #ifndef _WINDOWS
585 if (NULL == CONFIG_LOAD_MODULE_PATH)
586 CONFIG_LOAD_MODULE_PATH = zbx_strdup(CONFIG_LOAD_MODULE_PATH, DEFAULT_LOAD_MODULE_PATH);
587
588 if (NULL == CONFIG_PID_FILE)
589 CONFIG_PID_FILE = (char *)"/tmp/zabbix_agentd.pid";
590 #endif
591 if (NULL == CONFIG_LOG_TYPE_STR)
592 CONFIG_LOG_TYPE_STR = zbx_strdup(CONFIG_LOG_TYPE_STR, ZBX_OPTION_LOGTYPE_FILE);
593 }
594
595 /******************************************************************************
596 * *
597 * Function: zbx_validate_config *
598 * *
599 * Purpose: validate configuration parameters *
600 * *
601 * Author: Vladimir Levijev *
602 * *
603 ******************************************************************************/
zbx_validate_config(ZBX_TASK_EX * task)604 static void zbx_validate_config(ZBX_TASK_EX *task)
605 {
606 char *ch_error;
607 int err = 0;
608
609 if (0 != CONFIG_PASSIVE_FORKS)
610 {
611 if (NULL == CONFIG_HOSTS_ALLOWED)
612 {
613 zabbix_log(LOG_LEVEL_CRIT, "StartAgents is not 0, parameter \"Server\" must be defined");
614 err = 1;
615 }
616 else if (SUCCEED != zbx_validate_peer_list(CONFIG_HOSTS_ALLOWED, &ch_error))
617 {
618 zabbix_log(LOG_LEVEL_CRIT, "invalid entry in \"Server\" configuration parameter: %s", ch_error);
619 zbx_free(ch_error);
620 err = 1;
621 }
622 }
623 if (NULL == CONFIG_HOSTNAME)
624 {
625 zabbix_log(LOG_LEVEL_CRIT, "\"Hostname\" configuration parameter is not defined");
626 err = 1;
627 }
628 else if (FAIL == zbx_check_hostname(CONFIG_HOSTNAME, &ch_error))
629 {
630 zabbix_log(LOG_LEVEL_CRIT, "invalid \"Hostname\" configuration parameter: '%s': %s", CONFIG_HOSTNAME,
631 ch_error);
632 zbx_free(ch_error);
633 err = 1;
634 }
635
636 if (NULL != CONFIG_HOST_METADATA && HOST_METADATA_LEN < zbx_strlen_utf8(CONFIG_HOST_METADATA))
637 {
638 zabbix_log(LOG_LEVEL_CRIT, "the value of \"HostMetadata\" configuration parameter cannot be longer than"
639 " %d characters", HOST_METADATA_LEN);
640 err = 1;
641 }
642
643 /* make sure active or passive check is enabled */
644 if (0 == CONFIG_ACTIVE_FORKS && 0 == CONFIG_PASSIVE_FORKS)
645 {
646 zabbix_log(LOG_LEVEL_CRIT, "either active or passive checks must be enabled");
647 err = 1;
648 }
649
650 if (NULL != CONFIG_SOURCE_IP && SUCCEED != is_supported_ip(CONFIG_SOURCE_IP))
651 {
652 zabbix_log(LOG_LEVEL_CRIT, "invalid \"SourceIP\" configuration parameter: '%s'", CONFIG_SOURCE_IP);
653 err = 1;
654 }
655
656 if (SUCCEED != zbx_validate_log_parameters(task))
657 err = 1;
658
659 #if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
660 err |= (FAIL == check_cfg_feature_str("TLSConnect", CONFIG_TLS_CONNECT, "TLS support"));
661 err |= (FAIL == check_cfg_feature_str("TLSAccept", CONFIG_TLS_ACCEPT, "TLS support"));
662 err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
663 err |= (FAIL == check_cfg_feature_str("TLSCRLFile", CONFIG_TLS_CRL_FILE, "TLS support"));
664 err |= (FAIL == check_cfg_feature_str("TLSServerCertIssuer", CONFIG_TLS_SERVER_CERT_ISSUER, "TLS support"));
665 err |= (FAIL == check_cfg_feature_str("TLSServerCertSubject", CONFIG_TLS_SERVER_CERT_SUBJECT, "TLS support"));
666 err |= (FAIL == check_cfg_feature_str("TLSCertFile", CONFIG_TLS_CERT_FILE, "TLS support"));
667 err |= (FAIL == check_cfg_feature_str("TLSKeyFile", CONFIG_TLS_KEY_FILE, "TLS support"));
668 err |= (FAIL == check_cfg_feature_str("TLSPSKIdentity", CONFIG_TLS_PSK_IDENTITY, "TLS support"));
669 err |= (FAIL == check_cfg_feature_str("TLSPSKFile", CONFIG_TLS_PSK_FILE, "TLS support"));
670 #endif
671 #if !(defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
672 err |= (FAIL == check_cfg_feature_str("TLSCipherCert", CONFIG_TLS_CIPHER_CERT, "GnuTLS or OpenSSL"));
673 err |= (FAIL == check_cfg_feature_str("TLSCipherPSK", CONFIG_TLS_CIPHER_PSK, "GnuTLS or OpenSSL"));
674 err |= (FAIL == check_cfg_feature_str("TLSCipherAll", CONFIG_TLS_CIPHER_ALL, "GnuTLS or OpenSSL"));
675 #endif
676 #if !defined(HAVE_OPENSSL)
677 err |= (FAIL == check_cfg_feature_str("TLSCipherCert13", CONFIG_TLS_CIPHER_CERT13, "OpenSSL 1.1.1 or newer"));
678 err |= (FAIL == check_cfg_feature_str("TLSCipherPSK13", CONFIG_TLS_CIPHER_PSK13, "OpenSSL 1.1.1 or newer"));
679 err |= (FAIL == check_cfg_feature_str("TLSCipherAll13", CONFIG_TLS_CIPHER_ALL13, "OpenSSL 1.1.1 or newer"));
680 #endif
681
682 if (0 != err)
683 exit(EXIT_FAILURE);
684 }
685
add_activechk_host(const char * host,unsigned short port)686 static int add_activechk_host(const char *host, unsigned short port)
687 {
688 int i;
689
690 for (i = 0; i < CONFIG_ACTIVE_FORKS; i++)
691 {
692 if (0 == strcmp(CONFIG_ACTIVE_ARGS[i].host, host) && CONFIG_ACTIVE_ARGS[i].port == port)
693 return FAIL;
694 }
695
696 CONFIG_ACTIVE_FORKS++;
697 CONFIG_ACTIVE_ARGS = (ZBX_THREAD_ACTIVECHK_ARGS *)zbx_realloc(CONFIG_ACTIVE_ARGS, sizeof(ZBX_THREAD_ACTIVECHK_ARGS) * CONFIG_ACTIVE_FORKS);
698 CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].host = zbx_strdup(NULL, host);
699 CONFIG_ACTIVE_ARGS[CONFIG_ACTIVE_FORKS - 1].port = port;
700
701 return SUCCEED;
702 }
703
704 /******************************************************************************
705 * *
706 * Function: get_serveractive_hosts *
707 * *
708 * Purpose: parse string like IP<:port>,[IPv6]<:port> *
709 * *
710 ******************************************************************************/
get_serveractive_hosts(char * active_hosts)711 static void get_serveractive_hosts(char *active_hosts)
712 {
713 char *l = active_hosts, *r;
714 int rc = SUCCEED;
715
716 do
717 {
718 char *host = NULL;
719 unsigned short port;
720
721 if (NULL != (r = strchr(l, ',')))
722 *r = '\0';
723
724 if (SUCCEED != parse_serveractive_element(l, &host, &port, (unsigned short)ZBX_DEFAULT_SERVER_PORT))
725 goto fail;
726
727 rc = add_activechk_host(host, port);
728
729 zbx_free(host);
730
731 if (SUCCEED != rc)
732 goto fail;
733
734 if (NULL != r)
735 {
736 *r = ',';
737 l = r + 1;
738 }
739 }
740 while (NULL != r);
741
742 return;
743 fail:
744 if (SUCCEED != rc)
745 zbx_error("error parsing a \"ServerActive\" option: address \"%s\" specified more than once", l);
746 else
747 zbx_error("error parsing a \"ServerActive\" option: address \"%s\" is invalid", l);
748
749 if (NULL != r)
750 *r = ',';
751
752 exit(EXIT_FAILURE);
753 }
754
755 /******************************************************************************
756 * *
757 * Function: zbx_load_config *
758 * *
759 * Purpose: load configuration from config file *
760 * *
761 * Parameters: requirement - produce error if config file missing or not *
762 * *
763 ******************************************************************************/
zbx_load_config(int requirement,ZBX_TASK_EX * task)764 static void zbx_load_config(int requirement, ZBX_TASK_EX *task)
765 {
766 static char *active_hosts;
767
768 struct cfg_line cfg[] =
769 {
770 /* PARAMETER, VAR, TYPE,
771 MANDATORY, MIN, MAX */
772 {"Server", &CONFIG_HOSTS_ALLOWED, TYPE_STRING_LIST,
773 PARM_OPT, 0, 0},
774 {"ServerActive", &active_hosts, TYPE_STRING_LIST,
775 PARM_OPT, 0, 0},
776 {"Hostname", &CONFIG_HOSTNAME, TYPE_STRING,
777 PARM_OPT, 0, 0},
778 {"HostnameItem", &CONFIG_HOSTNAME_ITEM, TYPE_STRING,
779 PARM_OPT, 0, 0},
780 {"HostMetadata", &CONFIG_HOST_METADATA, TYPE_STRING,
781 PARM_OPT, 0, 0},
782 {"HostMetadataItem", &CONFIG_HOST_METADATA_ITEM, TYPE_STRING,
783 PARM_OPT, 0, 0},
784 {"BufferSize", &CONFIG_BUFFER_SIZE, TYPE_INT,
785 PARM_OPT, 2, 65535},
786 {"BufferSend", &CONFIG_BUFFER_SEND, TYPE_INT,
787 PARM_OPT, 1, SEC_PER_HOUR},
788 #ifndef _WINDOWS
789 {"PidFile", &CONFIG_PID_FILE, TYPE_STRING,
790 PARM_OPT, 0, 0},
791 #endif
792 {"LogType", &CONFIG_LOG_TYPE_STR, TYPE_STRING,
793 PARM_OPT, 0, 0},
794 {"LogFile", &CONFIG_LOG_FILE, TYPE_STRING,
795 PARM_OPT, 0, 0},
796 {"LogFileSize", &CONFIG_LOG_FILE_SIZE, TYPE_INT,
797 PARM_OPT, 0, 1024},
798 {"Timeout", &CONFIG_TIMEOUT, TYPE_INT,
799 PARM_OPT, 1, 30},
800 {"ListenPort", &CONFIG_LISTEN_PORT, TYPE_INT,
801 PARM_OPT, 1024, 32767},
802 {"ListenIP", &CONFIG_LISTEN_IP, TYPE_STRING_LIST,
803 PARM_OPT, 0, 0},
804 {"SourceIP", &CONFIG_SOURCE_IP, TYPE_STRING,
805 PARM_OPT, 0, 0},
806 {"DebugLevel", &CONFIG_LOG_LEVEL, TYPE_INT,
807 PARM_OPT, 0, 5},
808 {"StartAgents", &CONFIG_PASSIVE_FORKS, TYPE_INT,
809 PARM_OPT, 0, 100},
810 {"RefreshActiveChecks", &CONFIG_REFRESH_ACTIVE_CHECKS, TYPE_INT,
811 PARM_OPT, SEC_PER_MIN, SEC_PER_HOUR},
812 {"MaxLinesPerSecond", &CONFIG_MAX_LINES_PER_SECOND, TYPE_INT,
813 PARM_OPT, 1, 1000},
814 {"EnableRemoteCommands", &CONFIG_ENABLE_REMOTE_COMMANDS, TYPE_INT,
815 PARM_OPT, 0, 1},
816 {"LogRemoteCommands", &CONFIG_LOG_REMOTE_COMMANDS, TYPE_INT,
817 PARM_OPT, 0, 1},
818 {"UnsafeUserParameters", &CONFIG_UNSAFE_USER_PARAMETERS, TYPE_INT,
819 PARM_OPT, 0, 1},
820 {"Alias", &CONFIG_ALIASES, TYPE_MULTISTRING,
821 PARM_OPT, 0, 0},
822 {"UserParameter", &CONFIG_USER_PARAMETERS, TYPE_MULTISTRING,
823 PARM_OPT, 0, 0},
824 #ifndef _WINDOWS
825 {"LoadModulePath", &CONFIG_LOAD_MODULE_PATH, TYPE_STRING,
826 PARM_OPT, 0, 0},
827 {"LoadModule", &CONFIG_LOAD_MODULE, TYPE_MULTISTRING,
828 PARM_OPT, 0, 0},
829 {"AllowRoot", &CONFIG_ALLOW_ROOT, TYPE_INT,
830 PARM_OPT, 0, 1},
831 {"User", &CONFIG_USER, TYPE_STRING,
832 PARM_OPT, 0, 0},
833 #endif
834 #ifdef _WINDOWS
835 {"PerfCounter", &CONFIG_PERF_COUNTERS, TYPE_MULTISTRING,
836 PARM_OPT, 0, 0},
837 {"PerfCounterEn", &CONFIG_PERF_COUNTERS_EN, TYPE_MULTISTRING,
838 PARM_OPT, 0, 0},
839 #endif
840 {"TLSConnect", &CONFIG_TLS_CONNECT, TYPE_STRING,
841 PARM_OPT, 0, 0},
842 {"TLSAccept", &CONFIG_TLS_ACCEPT, TYPE_STRING_LIST,
843 PARM_OPT, 0, 0},
844 {"TLSCAFile", &CONFIG_TLS_CA_FILE, TYPE_STRING,
845 PARM_OPT, 0, 0},
846 {"TLSCRLFile", &CONFIG_TLS_CRL_FILE, TYPE_STRING,
847 PARM_OPT, 0, 0},
848 {"TLSServerCertIssuer", &CONFIG_TLS_SERVER_CERT_ISSUER, TYPE_STRING,
849 PARM_OPT, 0, 0},
850 {"TLSServerCertSubject", &CONFIG_TLS_SERVER_CERT_SUBJECT, TYPE_STRING,
851 PARM_OPT, 0, 0},
852 {"TLSCertFile", &CONFIG_TLS_CERT_FILE, TYPE_STRING,
853 PARM_OPT, 0, 0},
854 {"TLSKeyFile", &CONFIG_TLS_KEY_FILE, TYPE_STRING,
855 PARM_OPT, 0, 0},
856 {"TLSPSKIdentity", &CONFIG_TLS_PSK_IDENTITY, TYPE_STRING,
857 PARM_OPT, 0, 0},
858 {"TLSPSKFile", &CONFIG_TLS_PSK_FILE, TYPE_STRING,
859 PARM_OPT, 0, 0},
860 {"TLSCipherCert13", &CONFIG_TLS_CIPHER_CERT13, TYPE_STRING,
861 PARM_OPT, 0, 0},
862 {"TLSCipherCert", &CONFIG_TLS_CIPHER_CERT, TYPE_STRING,
863 PARM_OPT, 0, 0},
864 {"TLSCipherPSK13", &CONFIG_TLS_CIPHER_PSK13, TYPE_STRING,
865 PARM_OPT, 0, 0},
866 {"TLSCipherPSK", &CONFIG_TLS_CIPHER_PSK, TYPE_STRING,
867 PARM_OPT, 0, 0},
868 {"TLSCipherAll13", &CONFIG_TLS_CIPHER_ALL13, TYPE_STRING,
869 PARM_OPT, 0, 0},
870 {"TLSCipherAll", &CONFIG_TLS_CIPHER_ALL, TYPE_STRING,
871 PARM_OPT, 0, 0},
872 {NULL}
873 };
874
875 /* initialize multistrings */
876 zbx_strarr_init(&CONFIG_ALIASES);
877 zbx_strarr_init(&CONFIG_USER_PARAMETERS);
878 #ifndef _WINDOWS
879 zbx_strarr_init(&CONFIG_LOAD_MODULE);
880 #endif
881 #ifdef _WINDOWS
882 zbx_strarr_init(&CONFIG_PERF_COUNTERS);
883 zbx_strarr_init(&CONFIG_PERF_COUNTERS_EN);
884 #endif
885 parse_cfg_file(CONFIG_FILE, cfg, requirement, ZBX_CFG_STRICT);
886
887 set_defaults();
888
889 CONFIG_LOG_TYPE = zbx_get_log_type(CONFIG_LOG_TYPE_STR);
890
891 if (NULL != active_hosts && '\0' != *active_hosts)
892 get_serveractive_hosts(active_hosts);
893
894 zbx_free(active_hosts);
895
896 if (ZBX_CFG_FILE_REQUIRED == requirement)
897 {
898 zbx_validate_config(task);
899 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
900 zbx_tls_validate_config();
901 #endif
902 }
903 }
904
905 /******************************************************************************
906 * *
907 * Function: zbx_free_config *
908 * *
909 * Purpose: free configuration memory *
910 * *
911 * Author: Vladimir Levijev *
912 * *
913 ******************************************************************************/
zbx_free_config(void)914 static void zbx_free_config(void)
915 {
916 zbx_strarr_free(CONFIG_ALIASES);
917 zbx_strarr_free(CONFIG_USER_PARAMETERS);
918 #ifndef _WINDOWS
919 zbx_strarr_free(CONFIG_LOAD_MODULE);
920 #endif
921 #ifdef _WINDOWS
922 zbx_strarr_free(CONFIG_PERF_COUNTERS);
923 zbx_strarr_free(CONFIG_PERF_COUNTERS_EN);
924 #endif
925 }
926
927 #ifdef _WINDOWS
zbx_exec_service_task(const char * name,const ZBX_TASK_EX * t)928 static int zbx_exec_service_task(const char *name, const ZBX_TASK_EX *t)
929 {
930 int ret;
931
932 switch (t->task)
933 {
934 case ZBX_TASK_INSTALL_SERVICE:
935 ret = ZabbixCreateService(name, t->flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS);
936 break;
937 case ZBX_TASK_UNINSTALL_SERVICE:
938 ret = ZabbixRemoveService();
939 break;
940 case ZBX_TASK_START_SERVICE:
941 ret = ZabbixStartService();
942 break;
943 case ZBX_TASK_STOP_SERVICE:
944 ret = ZabbixStopService();
945 break;
946 default:
947 /* there can not be other choice */
948 assert(0);
949 }
950
951 return ret;
952 }
953 #endif /* _WINDOWS */
954
MAIN_ZABBIX_ENTRY(int flags)955 int MAIN_ZABBIX_ENTRY(int flags)
956 {
957 zbx_socket_t listen_sock;
958 char *error = NULL;
959 int i, j = 0;
960 #ifdef _WINDOWS
961 DWORD res;
962 #endif
963
964 if (0 != (flags & ZBX_TASK_FLAG_FOREGROUND))
965 {
966 printf("Starting Zabbix Agent [%s]. Zabbix %s (revision %s).\nPress Ctrl+C to exit.\n\n",
967 CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
968 }
969 #ifndef _WINDOWS
970 if (SUCCEED != zbx_locks_create(&error))
971 {
972 zbx_error("cannot create locks: %s", error);
973 zbx_free(error);
974 exit(EXIT_FAILURE);
975 }
976 #endif
977 if (SUCCEED != zabbix_open_log(CONFIG_LOG_TYPE, CONFIG_LOG_LEVEL, CONFIG_LOG_FILE, &error))
978 {
979 zbx_error("cannot open log: %s", error);
980 zbx_free(error);
981 exit(EXIT_FAILURE);
982 }
983
984 #ifdef HAVE_IPV6
985 # define IPV6_FEATURE_STATUS "YES"
986 #else
987 # define IPV6_FEATURE_STATUS " NO"
988 #endif
989 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
990 # define TLS_FEATURE_STATUS "YES"
991 #else
992 # define TLS_FEATURE_STATUS " NO"
993 #endif
994
995 zabbix_log(LOG_LEVEL_INFORMATION, "Starting Zabbix Agent [%s]. Zabbix %s (revision %s).",
996 CONFIG_HOSTNAME, ZABBIX_VERSION, ZABBIX_REVISION);
997
998 zabbix_log(LOG_LEVEL_INFORMATION, "**** Enabled features ****");
999 zabbix_log(LOG_LEVEL_INFORMATION, "IPv6 support: " IPV6_FEATURE_STATUS);
1000 zabbix_log(LOG_LEVEL_INFORMATION, "TLS support: " TLS_FEATURE_STATUS);
1001 zabbix_log(LOG_LEVEL_INFORMATION, "**************************");
1002
1003 zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
1004
1005 #if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
1006 if (SUCCEED != zbx_coredump_disable())
1007 {
1008 zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
1009 zbx_free_service_resources(FAIL);
1010 exit(EXIT_FAILURE);
1011 }
1012 #endif
1013 #ifndef _WINDOWS
1014 if (FAIL == zbx_load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 1))
1015 {
1016 zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
1017 zbx_free_service_resources(FAIL);
1018 exit(EXIT_FAILURE);
1019 }
1020 #endif
1021 if (0 != CONFIG_PASSIVE_FORKS)
1022 {
1023 if (FAIL == zbx_tcp_listen(&listen_sock, CONFIG_LISTEN_IP, (unsigned short)CONFIG_LISTEN_PORT))
1024 {
1025 zabbix_log(LOG_LEVEL_CRIT, "listener failed: %s", zbx_socket_strerror());
1026 zbx_free_service_resources(FAIL);
1027 exit(EXIT_FAILURE);
1028 }
1029 }
1030
1031 if (SUCCEED != init_collector_data(&error))
1032 {
1033 zabbix_log(LOG_LEVEL_CRIT, "cannot initialize collector: %s", error);
1034 zbx_free(error);
1035 zbx_free_service_resources(FAIL);
1036 exit(EXIT_FAILURE);
1037 }
1038
1039 #ifdef _WINDOWS
1040 if (SUCCEED != init_perf_collector(ZBX_MULTI_THREADED, &error))
1041 {
1042 zabbix_log(LOG_LEVEL_CRIT, "cannot initialize performance counter collector: %s", error);
1043 zbx_free(error);
1044 zbx_free_service_resources(FAIL);
1045 exit(EXIT_FAILURE);
1046 }
1047
1048 load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN);
1049 #endif
1050 zbx_free_config();
1051
1052 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
1053 zbx_tls_init_parent();
1054 #endif
1055 /* --- START THREADS ---*/
1056
1057 /* allocate memory for a collector, all listeners and active checks */
1058 threads_num = CONFIG_COLLECTOR_FORKS + CONFIG_PASSIVE_FORKS + CONFIG_ACTIVE_FORKS;
1059
1060 #ifdef _WINDOWS
1061 if (MAXIMUM_WAIT_OBJECTS < threads_num)
1062 {
1063 zabbix_log(LOG_LEVEL_CRIT, "Too many agent threads. Please reduce the StartAgents configuration"
1064 " parameter or the number of active servers in ServerActive configuration parameter.");
1065 zbx_free_service_resources(FAIL);
1066 exit(EXIT_FAILURE);
1067 }
1068 #endif
1069 threads = (ZBX_THREAD_HANDLE *)zbx_calloc(threads, threads_num, sizeof(ZBX_THREAD_HANDLE));
1070 threads_flags = (int *)zbx_calloc(threads_flags, threads_num, sizeof(int));
1071
1072 zabbix_log(LOG_LEVEL_INFORMATION, "agent #0 started [main process]");
1073
1074 for (i = 0; i < threads_num; i++)
1075 {
1076 zbx_thread_args_t *thread_args;
1077
1078 thread_args = (zbx_thread_args_t *)zbx_malloc(NULL, sizeof(zbx_thread_args_t));
1079
1080 if (FAIL == get_process_info_by_thread(i + 1, &thread_args->process_type, &thread_args->process_num))
1081 {
1082 THIS_SHOULD_NEVER_HAPPEN;
1083 exit(EXIT_FAILURE);
1084 }
1085
1086 thread_args->server_num = i + 1;
1087 thread_args->args = NULL;
1088
1089 switch (thread_args->process_type)
1090 {
1091 case ZBX_PROCESS_TYPE_COLLECTOR:
1092 zbx_thread_start(collector_thread, thread_args, &threads[i]);
1093 break;
1094 case ZBX_PROCESS_TYPE_LISTENER:
1095 thread_args->args = &listen_sock;
1096 zbx_thread_start(listener_thread, thread_args, &threads[i]);
1097 break;
1098 case ZBX_PROCESS_TYPE_ACTIVE_CHECKS:
1099 thread_args->args = &CONFIG_ACTIVE_ARGS[j++];
1100 zbx_thread_start(active_checks_thread, thread_args, &threads[i]);
1101 break;
1102 }
1103 #ifndef _WINDOWS
1104 zbx_free(thread_args);
1105 #endif
1106 }
1107
1108 #ifdef _WINDOWS
1109 set_parent_signal_handler(); /* must be called after all threads are created */
1110
1111 /* wait for an exiting thread */
1112 res = WaitForMultipleObjectsEx(threads_num, threads, FALSE, INFINITE, FALSE);
1113
1114 if (ZBX_IS_RUNNING())
1115 {
1116 /* Zabbix agent service should either be stopped by the user in ServiceCtrlHandler() or */
1117 /* crash. If some thread has terminated normally, it means something is terribly wrong. */
1118
1119 zabbix_log(LOG_LEVEL_CRIT, "One thread has terminated unexpectedly (code:%lu). Exiting ...", res);
1120 THIS_SHOULD_NEVER_HAPPEN;
1121
1122 /* notify other threads and allow them to terminate */
1123 ZBX_DO_EXIT();
1124 zbx_sleep(1);
1125 }
1126 else
1127 {
1128 zbx_tcp_close(&listen_sock);
1129
1130 /* Wait for the service worker thread to terminate us. Listener threads may not exit up to */
1131 /* CONFIG_TIMEOUT seconds if they're waiting for external processes to finish / timeout */
1132 zbx_sleep(CONFIG_TIMEOUT);
1133
1134 THIS_SHOULD_NEVER_HAPPEN;
1135 }
1136 #else
1137 while (-1 == wait(&i)) /* wait for any child to exit */
1138 {
1139 if (EINTR != errno)
1140 {
1141 zabbix_log(LOG_LEVEL_ERR, "failed to wait on child processes: %s", zbx_strerror(errno));
1142 break;
1143 }
1144 }
1145
1146 /* all exiting child processes should be caught by signal handlers */
1147 THIS_SHOULD_NEVER_HAPPEN;
1148 #endif
1149 zbx_on_exit(SUCCEED);
1150
1151 return SUCCEED;
1152 }
1153
1154 /******************************************************************************
1155 * *
1156 * Function: zbx_free_service_resources *
1157 * *
1158 * Purpose: free service resources allocated by main thread *
1159 * *
1160 ******************************************************************************/
zbx_free_service_resources(int ret)1161 void zbx_free_service_resources(int ret)
1162 {
1163 if (NULL != threads)
1164 {
1165 zbx_threads_wait(threads, threads_flags, threads_num, ret); /* wait for all child processes to exit */
1166 zbx_free(threads);
1167 zbx_free(threads_flags);
1168 }
1169 #ifdef HAVE_PTHREAD_PROCESS_SHARED
1170 zbx_locks_disable();
1171 #endif
1172 free_metrics();
1173 alias_list_free();
1174 free_collector_data();
1175 #ifdef _WINDOWS
1176 free_perf_collector();
1177 zbx_co_uninitialize();
1178 #endif
1179 #ifndef _WINDOWS
1180 zbx_unload_modules();
1181 #endif
1182 zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent stopped. Zabbix %s (revision %s).",
1183 ZABBIX_VERSION, ZABBIX_REVISION);
1184
1185 zabbix_close_log();
1186 }
1187
zbx_on_exit(int ret)1188 void zbx_on_exit(int ret)
1189 {
1190 zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called");
1191
1192 zbx_free_service_resources(ret);
1193
1194 #if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
1195 zbx_tls_free();
1196 zbx_tls_library_deinit(); /* deinitialize crypto library from parent thread */
1197 #endif
1198 #if defined(PS_OVERWRITE_ARGV)
1199 setproctitle_free_env();
1200 #endif
1201 #ifdef _WINDOWS
1202 while (0 == WSACleanup())
1203 ;
1204 #endif
1205
1206 exit(EXIT_SUCCESS);
1207 }
1208
main(int argc,char ** argv)1209 int main(int argc, char **argv)
1210 {
1211 ZBX_TASK_EX t = {ZBX_TASK_START};
1212 #ifdef _WINDOWS
1213 int ret;
1214 char *error;
1215
1216 /* Provide, so our process handles errors instead of the system itself. */
1217 /* Attention!!! */
1218 /* The system does not display the critical-error-handler message box. */
1219 /* Instead, the system sends the error to the calling process.*/
1220 SetErrorMode(SEM_FAILCRITICALERRORS);
1221 #endif
1222 #if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV)
1223 argv = setproctitle_save_env(argc, argv);
1224 #endif
1225 progname = get_program_name(argv[0]);
1226
1227 if (SUCCEED != parse_commandline(argc, argv, &t))
1228 exit(EXIT_FAILURE);
1229
1230 import_symbols();
1231
1232 #ifdef _WINDOWS
1233 if (ZBX_TASK_SHOW_USAGE != t.task && ZBX_TASK_SHOW_VERSION != t.task && ZBX_TASK_SHOW_HELP != t.task &&
1234 SUCCEED != zbx_socket_start(&error))
1235 {
1236 zbx_error(error);
1237 zbx_free(error);
1238 exit(EXIT_FAILURE);
1239 }
1240 #endif
1241
1242 /* this is needed to set default hostname in zbx_load_config() */
1243 init_metrics();
1244
1245 switch (t.task)
1246 {
1247 case ZBX_TASK_SHOW_USAGE:
1248 usage();
1249 exit(EXIT_FAILURE);
1250 break;
1251 #ifndef _WINDOWS
1252 case ZBX_TASK_RUNTIME_CONTROL:
1253 zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1254 exit(SUCCEED == zbx_sigusr_send(t.data) ? EXIT_SUCCESS : EXIT_FAILURE);
1255 break;
1256 #else
1257 case ZBX_TASK_INSTALL_SERVICE:
1258 case ZBX_TASK_UNINSTALL_SERVICE:
1259 case ZBX_TASK_START_SERVICE:
1260 case ZBX_TASK_STOP_SERVICE:
1261 if (t.flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS)
1262 {
1263 zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1264
1265 zbx_snprintf(ZABBIX_SERVICE_NAME, sizeof(ZABBIX_SERVICE_NAME), "%s [%s]",
1266 APPLICATION_NAME, CONFIG_HOSTNAME);
1267 zbx_snprintf(ZABBIX_EVENT_SOURCE, sizeof(ZABBIX_EVENT_SOURCE), "%s [%s]",
1268 APPLICATION_NAME, CONFIG_HOSTNAME);
1269 }
1270 else
1271 zbx_load_config(ZBX_CFG_FILE_OPTIONAL, &t);
1272
1273 zbx_free_config();
1274
1275 ret = zbx_exec_service_task(argv[0], &t);
1276
1277 while (0 == WSACleanup())
1278 ;
1279
1280 free_metrics();
1281 exit(SUCCEED == ret ? EXIT_SUCCESS : EXIT_FAILURE);
1282 break;
1283 #endif
1284 case ZBX_TASK_TEST_METRIC:
1285 case ZBX_TASK_PRINT_SUPPORTED:
1286 zbx_load_config(ZBX_CFG_FILE_OPTIONAL, &t);
1287 #ifdef _WINDOWS
1288 if (SUCCEED != init_perf_collector(ZBX_SINGLE_THREADED, &error))
1289 {
1290 zbx_error("cannot initialize performance counter collector: %s", error);
1291 zbx_free(error);
1292 exit(EXIT_FAILURE);
1293 }
1294
1295 load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN);
1296 #else
1297 zbx_set_common_signal_handlers();
1298 #endif
1299 #ifndef _WINDOWS
1300 if (FAIL == zbx_load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 0))
1301 {
1302 zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
1303 exit(EXIT_FAILURE);
1304 }
1305 #endif
1306 load_user_parameters(CONFIG_USER_PARAMETERS);
1307 load_aliases(CONFIG_ALIASES);
1308 zbx_free_config();
1309 if (ZBX_TASK_TEST_METRIC == t.task)
1310 test_parameter(TEST_METRIC);
1311 else
1312 test_parameters();
1313 #ifdef _WINDOWS
1314 free_perf_collector(); /* cpu_collector must be freed before perf_collector is freed */
1315
1316 while (0 == WSACleanup())
1317 ;
1318 #endif
1319 #ifndef _WINDOWS
1320 zbx_unload_modules();
1321 #endif
1322 free_metrics();
1323 alias_list_free();
1324 exit(EXIT_SUCCESS);
1325 break;
1326 case ZBX_TASK_SHOW_VERSION:
1327 version();
1328 #ifdef _AIX
1329 printf("\n");
1330 tl_version();
1331 #endif
1332 exit(EXIT_SUCCESS);
1333 break;
1334 case ZBX_TASK_SHOW_HELP:
1335 help();
1336 exit(EXIT_SUCCESS);
1337 break;
1338 default:
1339 zbx_load_config(ZBX_CFG_FILE_REQUIRED, &t);
1340 load_user_parameters(CONFIG_USER_PARAMETERS);
1341 load_aliases(CONFIG_ALIASES);
1342 break;
1343 }
1344
1345 START_MAIN_ZABBIX_ENTRY(CONFIG_ALLOW_ROOT, CONFIG_USER, t.flags);
1346
1347 exit(EXIT_SUCCESS);
1348 }
1349