Skip to content

Commit 96be593

Browse files
committedJun 16, 2018
Add -t config-test option
Issue #389 has received increasing support to add a configuration validation option. This commit adds the -t/--commit-test option to report any detected configururation errors and exit. Errors are logged to the system log by default, but use of the -g and -G options can make the errors be logged to files. Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
·
v2.3.4v2.0.4
1 parent cb7a97f commit 96be593

File tree

9 files changed

+101
-21
lines changed

9 files changed

+101
-21
lines changed
 

‎TODO

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ development:
3434
* Allow dynamic definitions, e.g. $_VI_NAME
3535
Also $*_INSTANCE net_namspace $_INSTANCE
3636
so $* means only do if $_INSTANCE not blank. */
37+
* ng-scheduler - would libev help, or use select with epoll to get
38+
micro-second timer
39+
Code has comments. Press enter to view.
3740

3841

3942
Other issues awaiting resolution:

‎doc/keepalived.conf.SYNOPSIS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ virtual_server group <STRING> { # VS group declaration
11431143
path <STRING> # Path
11441144
digest <STRING> # Digest computed with genhash
11451145
status_code <INTEGER> # status code returned into the HTTP
1146-
# header. I not specified, then any
1146+
# header. If not specified, then any
11471147
# 2xx code is accepted.
11481148
virtualhost <STRING> # VirtualHost string to use. If not set
11491149
# uses virtualhost from checker or real

‎keepalived/bfd/bfd_daemon.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ stop_bfd(int status)
7474
thread_destroy_master(master);
7575
free_parent_mallocs_exit();
7676

77-
7877
/*
7978
* Reached when terminate signal catched.
8079
* finally return to parent process.
@@ -142,6 +141,12 @@ start_bfd(void)
142141
init_global_data();
143142
*/
144143

144+
/* If we are just testing the configuration, then we terminate now */
145+
if (__test_bit(CONFIG_TEST_BIT, &debug)) {
146+
stop_bfd(KEEPALIVED_EXIT_CONFIG_TEST);
147+
return;
148+
}
149+
145150
/* Set the process priority and non swappable if configured */
146151
// TODO - measure max stack usage
147152
set_process_priorities(
@@ -247,7 +252,9 @@ bfd_respawn_thread(thread_t * thread)
247252
}
248253

249254
/* We catch a SIGCHLD, handle it */
250-
if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
255+
if (__test_bit(CONFIG_TEST_BIT, &debug))
256+
raise(SIGTERM);
257+
else if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
251258
log_message(LOG_ALERT, "BFD child process(%d) died: Respawning",
252259
pid);
253260
start_bfd_child();
@@ -291,7 +298,7 @@ start_bfd_child(void)
291298

292299
/* Clear any child finder functions set in parent */
293300
set_child_finder_name(NULL);
294-
set_child_finder(NULL, NULL, NULL, NULL, NULL, 0); /* Currently these won't be set */
301+
destroy_child_finder();
295302

296303
prog_type = PROG_TYPE_BFD;
297304

‎keepalived/check/check_daemon.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ checker_terminate_phase1(bool schedule_next_thread)
153153
script_killall(master, SIGTERM, true);
154154

155155
/* Send shutdown messages */
156-
if (!__test_bit(DONT_RELEASE_IPVS_BIT, &debug))
156+
if (!__test_bit(DONT_RELEASE_IPVS_BIT, &debug) &&
157+
!__test_bit(CONFIG_TEST_BIT, &debug))
157158
clear_services();
158159

159160
if (schedule_next_thread) {
@@ -227,6 +228,12 @@ start_check(list old_checkers_queue)
227228
log_message(LOG_INFO, "Configuration is using : %zu Bytes", mem_allocated);
228229
#endif
229230

231+
/* If we are just testing the configuration, then we terminate now */
232+
if (__test_bit(CONFIG_TEST_BIT, &debug)) {
233+
stop_check(KEEPALIVED_EXIT_CONFIG_TEST);
234+
return;
235+
}
236+
230237
/* Initialize sub-system if any virtual servers are configured */
231238
if ((!LIST_ISEMPTY(check_data->vs) || (reload && !LIST_ISEMPTY(old_check_data->vs))) &&
232239
ipvs_start() != IPVS_SUCCESS) {
@@ -384,7 +391,9 @@ check_respawn_thread(thread_t * thread)
384391
}
385392

386393
/* We catch a SIGCHLD, handle it */
387-
if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
394+
if (!__test_bit(CONFIG_TEST_BIT, &debug))
395+
raise(SIGTERM);
396+
else if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
388397
log_message(LOG_ALERT, "Healthcheck child process(%d) died: Respawning", pid);
389398
start_check_child();
390399
} else {
@@ -429,7 +438,7 @@ start_check_child(void)
429438

430439
/* Clear any child finder functions set in parent */
431440
set_child_finder_name(NULL);
432-
set_child_finder(NULL, NULL, NULL, NULL, NULL, 0); /* Currently these won't be set */
441+
destroy_child_finder();
433442

434443
prog_type = PROG_TYPE_CHECKER;
435444

‎keepalived/core/main.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,41 @@ make_pidfile_name(const char* start, const char* instance, const char* extn)
305305
return name;
306306
}
307307

308+
#ifndef _DEBUG_
309+
static void
310+
parent_child_remover(thread_t *thread)
311+
{
312+
313+
if (prog_type == PROG_TYPE_PARENT) {
314+
#ifdef _WITH_VRRP_
315+
if (thread->u.c.pid == vrrp_child)
316+
vrrp_child = 0;
317+
#endif
318+
#ifdef _WITH_LVS_
319+
if (thread->u.c.pid == checkers_child)
320+
checkers_child = 0;
321+
#endif
322+
#ifdef _WITH_BFD_
323+
if (thread->u.c.pid == bfd_child)
324+
bfd_child = 0;
325+
#endif
326+
327+
if (__test_bit(CONFIG_TEST_BIT, &debug)) {
328+
#ifdef _WITH_VRRP_
329+
if (vrrp_child == 0)
330+
#endif
331+
#ifdef _WITH_LVS_
332+
if (checkers_child == 0)
333+
#endif
334+
#ifdef _WITH_BFD_
335+
if (bfd_child == 0)
336+
#endif
337+
raise(SIGTERM);
338+
}
339+
}
340+
}
341+
#endif
342+
308343
#ifdef _WITH_VRRP_
309344
bool
310345
running_vrrp(void)
@@ -559,7 +594,7 @@ sigend(__attribute__((unused)) void *v, __attribute__((unused)) int sig)
559594

560595
#ifdef _WITH_VRRP_
561596
if (vrrp_child > 0) {
562-
if (kill(vrrp_child, SIGTERM)) {
597+
if (!__test_bit(CONFIG_TEST_BIT, &debug) && kill(vrrp_child, SIGTERM)) {
563598
/* ESRCH means no such process */
564599
if (errno == ESRCH)
565600
vrrp_child = 0;
@@ -570,7 +605,7 @@ sigend(__attribute__((unused)) void *v, __attribute__((unused)) int sig)
570605
#endif
571606
#ifdef _WITH_LVS_
572607
if (checkers_child > 0) {
573-
if (kill(checkers_child, SIGTERM)) {
608+
if (!__test_bit(CONFIG_TEST_BIT, &debug) && kill(checkers_child, SIGTERM)) {
574609
if (errno == ESRCH)
575610
checkers_child = 0;
576611
}
@@ -580,7 +615,7 @@ sigend(__attribute__((unused)) void *v, __attribute__((unused)) int sig)
580615
#endif
581616
#ifdef _WITH_BFD_
582617
if (bfd_child > 0) {
583-
if (kill(bfd_child, SIGTERM)) {
618+
if (!__test_bit(CONFIG_TEST_BIT, &debug) && kill(bfd_child, SIGTERM)) {
584619
if (errno == ESRCH)
585620
bfd_child = 0;
586621
}
@@ -868,6 +903,7 @@ usage(const char *prog)
868903
", JSON"
869904
#endif
870905
"\n");
906+
fprintf(stderr, " -t, --config-test Check the configuration for obvious errors\n");
871907
fprintf(stderr, " -v, --version Display the version number\n");
872908
fprintf(stderr, " -h, --help Display this help message\n");
873909
}
@@ -935,6 +971,7 @@ parse_cmdline(int argc, char **argv)
935971
#endif
936972
{"config-id", required_argument, NULL, 'i'},
937973
{"signum", required_argument, NULL, 4 },
974+
{"config-test", no_argument, NULL, 't'},
938975
{"version", no_argument, NULL, 'v'},
939976
{"help", no_argument, NULL, 'h'},
940977

@@ -945,7 +982,7 @@ parse_cmdline(int argc, char **argv)
945982
* of longindex, so we need to ensure that before calling getopt_long(), longindex
946983
* is set to a know invalid value */
947984
curind = optind;
948-
while (longindex = -1, (c = getopt_long(argc, argv, ":vhlndDRS:f:p:i:mM::g::G"
985+
while (longindex = -1, (c = getopt_long(argc, argv, ":vhlndDRS:f:p:i:mM::g::Gt"
949986
#if defined _WITH_VRRP_ && defined _WITH_LVS_
950987
"PC"
951988
#endif
@@ -1047,6 +1084,9 @@ parse_cmdline(int argc, char **argv)
10471084
__set_bit(NO_SYSLOG_BIT, &debug);
10481085
reopen_log = true;
10491086
break;
1087+
case 't':
1088+
__set_bit(CONFIG_TEST_BIT, &debug);
1089+
break;
10501090
case 'f':
10511091
conf_file = optarg;
10521092
break;
@@ -1194,6 +1234,9 @@ keepalived_main(int argc, char **argv)
11941234
/* Initialise pointer to child finding function */
11951235
set_child_finder_name(find_keepalived_child_name);
11961236

1237+
/* If one of our children terminates, we want to clear it out */
1238+
set_child_remover(parent_child_remover);
1239+
11971240
/* Initialise daemon_mode */
11981241
#ifdef _WITH_VRRP_
11991242
__set_bit(DAEMON_VRRP, &daemon_mode);

‎keepalived/vrrp/vrrp_daemon.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ start_vrrp(void)
322322
if (reload)
323323
init_global_data(global_data);
324324

325+
/* If we are just testing the configuration, then we terminate now */
326+
if (__test_bit(CONFIG_TEST_BIT, &debug)) {
327+
stop_vrrp(KEEPALIVED_EXIT_CONFIG_TEST);
328+
return;
329+
}
330+
325331
/* Set the process priority and non swappable if configured */
326332
set_process_priorities(
327333
#ifdef _HAVE_SCHED_RT_
@@ -681,7 +687,9 @@ vrrp_respawn_thread(thread_t * thread)
681687
}
682688

683689
/* We catch a SIGCHLD, handle it */
684-
if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
690+
if (__test_bit(CONFIG_TEST_BIT, &debug))
691+
raise(SIGTERM);
692+
else if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
685693
log_message(LOG_ALERT, "VRRP child process(%d) died: Respawning", pid);
686694
start_vrrp_child();
687695
} else {
@@ -771,7 +779,7 @@ start_vrrp_child(void)
771779

772780
/* Clear any child finder functions set in parent */
773781
set_child_finder_name(NULL);
774-
set_child_finder(NULL, NULL, NULL, NULL, NULL, 0); /* Currently these won't be set */
782+
destroy_child_finder();
775783

776784
/* Child process part, write pidfile */
777785
if (!pidfile_write(vrrp_pidfile, getpid())) {

‎lib/bitops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ enum global_bits {
7474
#ifdef _WITH_LVS_
7575
LOG_ADDRESS_CHANGES,
7676
#endif
77+
CONFIG_TEST_BIT,
7778
};
7879

7980
#endif

‎lib/scheduler.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@
4848
#include "utils.h"
4949
#include "signals.h"
5050
#include "logger.h"
51-
#ifdef _DEBUG_
5251
#include "bitops.h"
53-
#endif
5452
#include "git-commit.h"
5553
#include <sys/utsname.h>
5654
#include <linux/version.h>
@@ -195,7 +193,13 @@ set_child_finder(void (*adder_func)(thread_t *),
195193
}
196194
}
197195

198-
static void
196+
void
197+
set_child_remover(void (*remover_func)(thread_t *))
198+
{
199+
child_remover = remover_func;
200+
}
201+
202+
void
199203
destroy_child_finder(void)
200204
{
201205
set_child_finder(NULL, NULL, NULL, NULL, NULL, 0);
@@ -1201,13 +1205,15 @@ process_child_termination(pid_t pid, int status)
12011205
if (child_remover)
12021206
child_remover(thread);
12031207

1204-
if (permanent_vrrp_checker_error)
1208+
if (permanent_vrrp_checker_error || __test_bit(CONFIG_TEST_BIT, &debug))
12051209
{
1206-
/* The child had a permanant error, so no point in respawning */
1210+
/* The child had a permanant error, or we were just testing the config,
1211+
* so no point in respawning */
12071212
thread->type = THREAD_UNUSED;
12081213
thread_list_add(&m->unuse, thread);
12091214

1210-
raise(SIGTERM);
1215+
if (!__test_bit(CONFIG_TEST_BIT, &debug))
1216+
raise(SIGTERM);
12111217
}
12121218
else
12131219
{

‎lib/scheduler.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ typedef enum {
121121
#define THREAD_CHILD_STATUS(X) ((X)->u.c.status)
122122

123123
/* Exit codes */
124-
#define KEEPALIVED_EXIT_FATAL (EXIT_FAILURE+1)
125-
#define KEEPALIVED_EXIT_CONFIG (EXIT_FAILURE+2)
124+
#define KEEPALIVED_EXIT_FATAL (EXIT_FAILURE+1)
125+
#define KEEPALIVED_EXIT_CONFIG (EXIT_FAILURE+2)
126+
#define KEEPALIVED_EXIT_CONFIG_TEST (EXIT_FAILURE+3)
126127

127128
#define DEFAULT_CHILD_FINDER ((void *)1)
128129

@@ -138,6 +139,8 @@ extern bool snmp_running;
138139
/* Prototypes. */
139140
extern void set_child_finder_name(char const * (*)(pid_t));
140141
extern void set_child_finder(void (*)(thread_t *), thread_t *(*)(pid_t), void (*)(thread_t *), bool (*)(size_t), void(*)(void), size_t);
142+
extern void destroy_child_finder(void);
143+
extern void set_child_remover(void (*)(thread_t *));
141144
#ifndef _DEBUG_
142145
extern bool report_child_status(int, pid_t, const char *);
143146
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.