|
Packit |
c22fc9 |
/*
|
|
Packit |
c22fc9 |
* Soft: Keepalived is a failover program for the LVS project
|
|
Packit |
c22fc9 |
* <www.linuxvirtualserver.org>. It monitor & manipulate
|
|
Packit |
c22fc9 |
* a loadbalanced server pool using multi-layer checks.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* Part: BFD child process handling
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* Author: Ilya Voronin, <ivoronin@gmail.com>
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
c22fc9 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
c22fc9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
c22fc9 |
* See the GNU General Public License for more details.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
c22fc9 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
c22fc9 |
* as published by the Free Software Foundation; either version
|
|
Packit |
c22fc9 |
* 2 of the License, or (at your option) any later version.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* Copyright (C) 2015-2017 Alexandre Cassen, <acassen@gmail.com>
|
|
Packit |
c22fc9 |
*/
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#include "config.h"
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#include <unistd.h>
|
|
Packit |
c22fc9 |
#include <sys/types.h>
|
|
Packit |
c22fc9 |
#include <sys/stat.h>
|
|
Packit |
c22fc9 |
#include <sys/prctl.h>
|
|
Packit |
c22fc9 |
#include <fcntl.h>
|
|
Packit |
c22fc9 |
#include <sys/time.h>
|
|
Packit |
c22fc9 |
#include <sys/resource.h>
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#include "bfd.h"
|
|
Packit |
c22fc9 |
#include "bfd_daemon.h"
|
|
Packit |
c22fc9 |
#include "bfd_data.h"
|
|
Packit |
c22fc9 |
#include "bfd_parser.h"
|
|
Packit |
c22fc9 |
#include "bfd_scheduler.h"
|
|
Packit |
c22fc9 |
#include "bfd_event.h"
|
|
Packit |
c22fc9 |
#include "pidfile.h"
|
|
Packit |
c22fc9 |
#include "logger.h"
|
|
Packit |
c22fc9 |
#include "signals.h"
|
|
Packit |
c22fc9 |
#include "main.h"
|
|
Packit |
c22fc9 |
#include "parser.h"
|
|
Packit |
c22fc9 |
#include "time.h"
|
|
Packit |
c22fc9 |
#include "global_data.h"
|
|
Packit |
c22fc9 |
#include "bitops.h"
|
|
Packit |
c22fc9 |
#include "utils.h"
|
|
Packit |
c22fc9 |
#include "scheduler.h"
|
|
Packit |
c22fc9 |
#include "process.h"
|
|
Packit |
c22fc9 |
#include "utils.h"
|
|
Packit Service |
dfccb1 |
#ifdef _WITH_CN_PROC_
|
|
Packit Service |
dfccb1 |
#include "track_process.h"
|
|
Packit Service |
dfccb1 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Global variables */
|
|
Packit |
c22fc9 |
int bfd_vrrp_event_pipe[2] = { -1, -1};
|
|
Packit |
c22fc9 |
int bfd_checker_event_pipe[2] = { -1, -1};
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Local variables */
|
|
Packit Service |
dfccb1 |
static const char *bfd_syslog_ident;
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
#ifndef _ONE_PROCESS_DEBUG_
|
|
Packit Service |
dfccb1 |
static void reload_bfd_thread(thread_ref_t);
|
|
Packit Service |
dfccb1 |
static timeval_t bfd_start_time;
|
|
Packit Service |
dfccb1 |
static unsigned bfd_next_restart_delay;
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Daemon stop sequence */
|
|
Packit |
c22fc9 |
static void
|
|
Packit |
c22fc9 |
stop_bfd(int status)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
struct rusage usage;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if (__test_bit(CONFIG_TEST_BIT, &debug))
|
|
Packit |
c22fc9 |
return;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Stop daemon */
|
|
Packit |
c22fc9 |
pidfile_rm(bfd_pidfile);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Clean data */
|
|
Packit |
c22fc9 |
free_global_data(global_data);
|
|
Packit |
c22fc9 |
bfd_dispatcher_release(bfd_data);
|
|
Packit |
c22fc9 |
free_bfd_data(bfd_data);
|
|
Packit |
c22fc9 |
free_bfd_buffer();
|
|
Packit |
c22fc9 |
thread_destroy_master(master);
|
|
Packit |
c22fc9 |
free_parent_mallocs_exit();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/*
|
|
Packit |
c22fc9 |
* Reached when terminate signal catched.
|
|
Packit |
c22fc9 |
* finally return to parent process.
|
|
Packit |
c22fc9 |
*/
|
|
Packit |
c22fc9 |
if (__test_bit(LOG_DETAIL_BIT, &debug)) {
|
|
Packit |
c22fc9 |
getrusage(RUSAGE_SELF, &usage);
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "Stopped - used %ld.%6.6ld user time, %ld.%6.6ld system time", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec, usage.ru_stime.tv_sec, usage.ru_stime.tv_usec);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
else
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "Stopped");
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef ENABLE_LOG_TO_FILE
|
|
Packit |
c22fc9 |
if (log_file_name)
|
|
Packit |
c22fc9 |
close_log_file();
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
closelog();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifndef _MEM_CHECK_LOG_
|
|
Packit Service |
dfccb1 |
FREE_CONST_PTR(bfd_syslog_ident);
|
|
Packit |
c22fc9 |
#else
|
|
Packit |
c22fc9 |
if (bfd_syslog_ident)
|
|
Packit Service |
dfccb1 |
free(no_const_char_p(bfd_syslog_ident)); /* malloc'd by make_syslog_ident() */
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
close_std_fd();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
exit(status);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Daemon init sequence */
|
|
Packit Service |
dfccb1 |
bool
|
|
Packit |
c22fc9 |
open_bfd_pipes(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
#ifdef _WITH_VRRP_
|
|
Packit |
c22fc9 |
/* Open BFD VRRP control pipe */
|
|
Packit |
c22fc9 |
if (open_pipe(bfd_vrrp_event_pipe) == -1) {
|
|
Packit |
c22fc9 |
log_message(LOG_ERR, "Unable to create BFD vrrp event pipe: %m");
|
|
Packit Service |
dfccb1 |
return false;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef _WITH_LVS_
|
|
Packit |
c22fc9 |
/* Open BFD checker control pipe */
|
|
Packit |
c22fc9 |
if (open_pipe(bfd_checker_event_pipe) == -1) {
|
|
Packit |
c22fc9 |
log_message(LOG_ERR, "Unable to create BFD checker event pipe: %m");
|
|
Packit Service |
dfccb1 |
return false;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
#endif
|
|
Packit Service |
dfccb1 |
|
|
Packit Service |
dfccb1 |
return true;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Daemon init sequence */
|
|
Packit |
c22fc9 |
static void
|
|
Packit Service |
dfccb1 |
start_bfd(__attribute__((unused)) data_t *prev_global_data)
|
|
Packit |
c22fc9 |
{
|
|
Packit Service |
dfccb1 |
srandom(time(NULL));
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if (reload)
|
|
Packit |
c22fc9 |
global_data = alloc_global_data();
|
|
Packit |
c22fc9 |
if (!(bfd_data = alloc_bfd_data())) {
|
|
Packit |
c22fc9 |
stop_bfd(KEEPALIVED_EXIT_FATAL);
|
|
Packit |
c22fc9 |
return;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
alloc_bfd_buffer();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
init_data(conf_file, bfd_init_keywords);
|
|
Packit |
c22fc9 |
if (reload)
|
|
Packit Service |
dfccb1 |
init_global_data(global_data, prev_global_data, true);
|
|
Packit Service |
dfccb1 |
|
|
Packit Service |
dfccb1 |
/* Update process name if necessary */
|
|
Packit Service |
dfccb1 |
if ((!reload && global_data->bfd_process_name) ||
|
|
Packit Service |
dfccb1 |
(reload &&
|
|
Packit Service |
dfccb1 |
(!global_data->bfd_process_name != !prev_global_data->bfd_process_name ||
|
|
Packit Service |
dfccb1 |
(global_data->bfd_process_name && strcmp(global_data->bfd_process_name, prev_global_data->bfd_process_name)))))
|
|
Packit Service |
dfccb1 |
set_process_name(global_data->bfd_process_name);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* If we are just testing the configuration, then we terminate now */
|
|
Packit |
c22fc9 |
if (__test_bit(CONFIG_TEST_BIT, &debug))
|
|
Packit |
c22fc9 |
return;
|
|
Packit |
c22fc9 |
bfd_complete_init();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Post initializations */
|
|
Packit |
c22fc9 |
#ifdef _MEM_CHECK_
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "Configuration is using : %zu Bytes", mem_allocated);
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if (__test_bit(DUMP_CONF_BIT, &debug))
|
|
Packit |
c22fc9 |
dump_bfd_data(NULL, bfd_data);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
thread_add_event(master, bfd_dispatcher_init, bfd_data, 0);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Set the process priority and non swappable if configured */
|
|
Packit |
c22fc9 |
// TODO - measure max stack usage
|
|
Packit |
c22fc9 |
set_process_priorities(
|
|
Packit Service |
dfccb1 |
global_data->bfd_realtime_priority, global_data->max_auto_priority, global_data->min_auto_priority_delay,
|
|
Packit |
c22fc9 |
#if HAVE_DECL_RLIMIT_RTTIME == 1
|
|
Packit |
c22fc9 |
global_data->bfd_rlimit_rt,
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
global_data->bfd_process_priority, global_data->bfd_no_swap ? 4096 : 0);
|
|
Packit Service |
dfccb1 |
|
|
Packit Service |
dfccb1 |
/* Set the process cpu affinity if configured */
|
|
Packit Service |
dfccb1 |
set_process_cpu_affinity(&global_data->bfd_cpu_mask, "bfd");
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
void
|
|
Packit |
c22fc9 |
bfd_validate_config(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
start_bfd(NULL);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
#ifndef _ONE_PROCESS_DEBUG_
|
|
Packit Service |
dfccb1 |
static void
|
|
Packit Service |
dfccb1 |
print_bfd_thread(__attribute__((unused)) thread_ref_t thread)
|
|
Packit Service |
dfccb1 |
{
|
|
Packit Service |
dfccb1 |
bfd_print_data();
|
|
Packit Service |
dfccb1 |
}
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
/* Reload handler */
|
|
Packit |
c22fc9 |
static void
|
|
Packit |
c22fc9 |
sigreload_bfd(__attribute__ ((unused)) void *v,
|
|
Packit |
c22fc9 |
__attribute__ ((unused)) int sig)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
thread_add_event(master, reload_bfd_thread, NULL, 0);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
static void
|
|
Packit Service |
dfccb1 |
sigdump_bfd(__attribute__((unused)) void *v, __attribute__((unused)) int sig)
|
|
Packit Service |
dfccb1 |
{
|
|
Packit Service |
dfccb1 |
log_message(LOG_INFO, "Printing BFD data for process(%d) on signal",
|
|
Packit Service |
dfccb1 |
getpid());
|
|
Packit Service |
dfccb1 |
thread_add_event(master, print_bfd_thread, NULL, 0);
|
|
Packit Service |
dfccb1 |
}
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
/* Terminate handler */
|
|
Packit |
c22fc9 |
static void
|
|
Packit |
c22fc9 |
sigend_bfd(__attribute__ ((unused)) void *v,
|
|
Packit |
c22fc9 |
__attribute__ ((unused)) int sig)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
if (master)
|
|
Packit |
c22fc9 |
thread_add_terminate_event(master);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* BFD Child signal handling */
|
|
Packit |
c22fc9 |
static void
|
|
Packit |
c22fc9 |
bfd_signal_init(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
signal_set(SIGHUP, sigreload_bfd, NULL);
|
|
Packit |
c22fc9 |
signal_set(SIGINT, sigend_bfd, NULL);
|
|
Packit |
c22fc9 |
signal_set(SIGTERM, sigend_bfd, NULL);
|
|
Packit Service |
dfccb1 |
signal_set(SIGUSR1, sigdump_bfd, NULL);
|
|
Packit Service |
dfccb1 |
#ifdef THREAD_DUMP
|
|
Packit Service |
dfccb1 |
signal_set(SIGTDUMP, thread_dump_signal, NULL);
|
|
Packit Service |
dfccb1 |
#endif
|
|
Packit |
c22fc9 |
signal_ignore(SIGPIPE);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Reload thread */
|
|
Packit Service |
dfccb1 |
static void
|
|
Packit Service |
dfccb1 |
reload_bfd_thread(__attribute__((unused)) thread_ref_t thread)
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
timeval_t timer;
|
|
Packit |
c22fc9 |
timer = timer_now();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "Reloading");
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Use standard scheduling while reloading */
|
|
Packit |
c22fc9 |
reset_process_priorities();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* set the reloading flag */
|
|
Packit |
c22fc9 |
SET_RELOAD;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Destroy master thread */
|
|
Packit |
c22fc9 |
bfd_dispatcher_release(bfd_data);
|
|
Packit Service |
dfccb1 |
thread_cleanup_master(master);
|
|
Packit Service |
dfccb1 |
thread_add_base_threads(master, false);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
old_bfd_data = bfd_data;
|
|
Packit |
c22fc9 |
bfd_data = NULL;
|
|
Packit |
c22fc9 |
old_global_data = global_data;
|
|
Packit |
c22fc9 |
global_data = NULL;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Reload the conf */
|
|
Packit |
c22fc9 |
signal_set(SIGCHLD, thread_child_handler, master);
|
|
Packit |
c22fc9 |
start_bfd(old_global_data);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
free_bfd_data(old_bfd_data);
|
|
Packit |
c22fc9 |
free_global_data(old_global_data);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
UNSET_RELOAD;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
set_time_now();
|
|
Packit Service |
dfccb1 |
log_message(LOG_INFO, "Reload finished in %lu usec", -timer_long(timer_sub_now(timer)));
|
|
Packit Service |
dfccb1 |
}
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
/* This function runs in the parent process. */
|
|
Packit Service |
dfccb1 |
static void
|
|
Packit Service |
dfccb1 |
delayed_restart_bfd_child_thread(__attribute__((unused)) thread_ref_t thread)
|
|
Packit Service |
dfccb1 |
{
|
|
Packit Service |
dfccb1 |
start_bfd_child();
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
/* BFD Child respawning thread. This function runs in the parent process. */
|
|
Packit Service |
dfccb1 |
static void
|
|
Packit Service |
dfccb1 |
bfd_respawn_thread(thread_ref_t thread)
|
|
Packit |
c22fc9 |
{
|
|
Packit Service |
dfccb1 |
unsigned restart_delay;
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
/* We catch a SIGCHLD, handle it */
|
|
Packit |
c22fc9 |
bfd_child = 0;
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
if (report_child_status(thread->u.c.status, thread->u.c.pid, NULL))
|
|
Packit Service |
dfccb1 |
thread_add_terminate_event(thread->master);
|
|
Packit Service |
dfccb1 |
else if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
|
|
Packit |
c22fc9 |
log_message(LOG_ALERT, "BFD child process(%d) died: Respawning", thread->u.c.pid);
|
|
Packit Service |
dfccb1 |
restart_delay = calc_restart_delay(&bfd_start_time, &bfd_next_restart_delay, "BFD");
|
|
Packit Service |
dfccb1 |
if (!restart_delay)
|
|
Packit Service |
dfccb1 |
start_bfd_child();
|
|
Packit Service |
dfccb1 |
else
|
|
Packit Service |
dfccb1 |
thread_add_timer(thread->master, delayed_restart_bfd_child_thread, NULL, restart_delay * TIMER_HZ);
|
|
Packit |
c22fc9 |
} else {
|
|
Packit |
c22fc9 |
log_message(LOG_ALERT, "BFD child process(%d) died: Exiting", thread->u.c.pid);
|
|
Packit |
c22fc9 |
raise(SIGTERM);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef THREAD_DUMP
|
|
Packit |
c22fc9 |
static void
|
|
Packit |
c22fc9 |
register_bfd_thread_addresses(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit Service |
dfccb1 |
/* Remove anything we might have inherited from parent */
|
|
Packit Service |
dfccb1 |
deregister_thread_addresses();
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
register_scheduler_addresses();
|
|
Packit |
c22fc9 |
register_signal_thread_addresses();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
register_bfd_scheduler_addresses();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
register_thread_address("bfd_dispatcher_init", bfd_dispatcher_init);
|
|
Packit |
c22fc9 |
register_thread_address("reload_bfd_thread", reload_bfd_thread);
|
|
Packit Service |
dfccb1 |
register_thread_address("print_bfd_thread", print_bfd_thread);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
register_signal_handler_address("sigreload_bfd", sigreload_bfd);
|
|
Packit Service |
dfccb1 |
register_signal_handler_address("sigdump_bfd", sigdump_bfd);
|
|
Packit |
c22fc9 |
register_signal_handler_address("sigend_bfd", sigend_bfd);
|
|
Packit |
c22fc9 |
register_signal_handler_address("thread_child_handler", thread_child_handler);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
int
|
|
Packit |
c22fc9 |
start_bfd_child(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit Service |
dfccb1 |
#ifndef _ONE_PROCESS_DEBUG_
|
|
Packit |
c22fc9 |
pid_t pid;
|
|
Packit |
c22fc9 |
int ret;
|
|
Packit Service |
dfccb1 |
const char *syslog_ident;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Initialize child process */
|
|
Packit |
c22fc9 |
#ifdef ENABLE_LOG_TO_FILE
|
|
Packit |
c22fc9 |
if (log_file_name)
|
|
Packit |
c22fc9 |
flush_log_file();
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
pid = fork();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if (pid < 0) {
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "BFD child process: fork error(%m)");
|
|
Packit |
c22fc9 |
return -1;
|
|
Packit |
c22fc9 |
} else if (pid) {
|
|
Packit |
c22fc9 |
bfd_child = pid;
|
|
Packit Service |
dfccb1 |
bfd_start_time = time_now;
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "Starting BFD child process, pid=%d",
|
|
Packit |
c22fc9 |
pid);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Start respawning thread */
|
|
Packit |
c22fc9 |
thread_add_child(master, bfd_respawn_thread, NULL,
|
|
Packit |
c22fc9 |
pid, TIMER_NEVER);
|
|
Packit |
c22fc9 |
return 0;
|
|
Packit |
c22fc9 |
}
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
prog_type = PROG_TYPE_BFD;
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
/* Close the read end of the event notification pipes, and the track_process fd */
|
|
Packit |
c22fc9 |
#ifdef _WITH_VRRP_
|
|
Packit |
c22fc9 |
close(bfd_vrrp_event_pipe[0]);
|
|
Packit Service |
dfccb1 |
#ifdef _WITH_CN_PROC_
|
|
Packit Service |
dfccb1 |
close_track_processes();
|
|
Packit Service |
dfccb1 |
#endif
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
#ifdef _WITH_LVS_
|
|
Packit |
c22fc9 |
close(bfd_checker_event_pipe[0]);
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
initialise_debug_options();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if ((global_data->instance_name
|
|
Packit |
c22fc9 |
#if HAVE_DECL_CLONE_NEWNET
|
|
Packit |
c22fc9 |
|| global_data->network_namespace
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
) &&
|
|
Packit |
c22fc9 |
(bfd_syslog_ident = make_syslog_ident(PROG_BFD)))
|
|
Packit |
c22fc9 |
syslog_ident = bfd_syslog_ident;
|
|
Packit |
c22fc9 |
else
|
|
Packit |
c22fc9 |
syslog_ident = PROG_BFD;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Opening local BFD syslog channel */
|
|
Packit |
c22fc9 |
if (!__test_bit(NO_SYSLOG_BIT, &debug))
|
|
Packit |
c22fc9 |
openlog(syslog_ident, LOG_PID | ((__test_bit(LOG_CONSOLE_BIT, &debug)) ? LOG_CONS : 0)
|
|
Packit |
c22fc9 |
, (log_facility==LOG_DAEMON) ? LOG_LOCAL2 : log_facility);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef ENABLE_LOG_TO_FILE
|
|
Packit |
c22fc9 |
if (log_file_name)
|
|
Packit |
c22fc9 |
open_log_file(log_file_name,
|
|
Packit |
c22fc9 |
"bfd",
|
|
Packit |
c22fc9 |
#if HAVE_DECL_CLONE_NEWNET
|
|
Packit |
c22fc9 |
global_data->network_namespace,
|
|
Packit |
c22fc9 |
#else
|
|
Packit |
c22fc9 |
NULL,
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
global_data->instance_name);
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef _MEM_CHECK_
|
|
Packit |
c22fc9 |
mem_log_init(PROG_BFD, "BFD child process");
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
free_parent_mallocs_startup(true);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Clear any child finder functions set in parent */
|
|
Packit |
c22fc9 |
set_child_finder_name(NULL);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Child process part, write pidfile */
|
|
Packit |
c22fc9 |
if (!pidfile_write(bfd_pidfile, getpid())) {
|
|
Packit |
c22fc9 |
/* Fatal error */
|
|
Packit |
c22fc9 |
log_message(LOG_INFO,
|
|
Packit |
c22fc9 |
"BFD child process: cannot write pidfile");
|
|
Packit |
c22fc9 |
exit(0);
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Create the new master thread */
|
|
Packit |
c22fc9 |
thread_destroy_master(master);
|
|
Packit |
c22fc9 |
master = thread_make_master();
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* change to / dir */
|
|
Packit |
c22fc9 |
ret = chdir("/");
|
|
Packit |
c22fc9 |
if (ret < 0) {
|
|
Packit |
c22fc9 |
log_message(LOG_INFO, "BFD child process: error chdir");
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* If last process died during a reload, we can get there and we
|
|
Packit |
c22fc9 |
* don't want to loop again, because we're not reloading anymore.
|
|
Packit |
c22fc9 |
*/
|
|
Packit |
c22fc9 |
UNSET_RELOAD;
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
#ifndef _ONE_PROCESS_DEBUG_
|
|
Packit |
c22fc9 |
/* Signal handling initialization */
|
|
Packit |
c22fc9 |
bfd_signal_init();
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Start BFD daemon */
|
|
Packit |
c22fc9 |
start_bfd(NULL);
|
|
Packit |
c22fc9 |
|
|
Packit Service |
dfccb1 |
#ifdef _ONE_PROCESS_DEBUG_
|
|
Packit |
c22fc9 |
return 0;
|
|
Packit |
c22fc9 |
#else
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef THREAD_DUMP
|
|
Packit |
c22fc9 |
register_bfd_thread_addresses();
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Launch the scheduling I/O multiplexer */
|
|
Packit |
c22fc9 |
launch_thread_scheduler(master);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef THREAD_DUMP
|
|
Packit |
c22fc9 |
deregister_thread_addresses();
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* Finish BFD daemon process */
|
|
Packit |
c22fc9 |
stop_bfd(EXIT_SUCCESS);
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
/* unreachable */
|
|
Packit |
c22fc9 |
exit(EXIT_SUCCESS);
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#ifdef THREAD_DUMP
|
|
Packit |
c22fc9 |
void
|
|
Packit |
c22fc9 |
register_bfd_parent_addresses(void)
|
|
Packit |
c22fc9 |
{
|
|
Packit Service |
dfccb1 |
#ifndef _ONE_PROCESS_DEBUG_
|
|
Packit |
c22fc9 |
register_thread_address("bfd_respawn_thread", bfd_respawn_thread);
|
|
Packit Service |
dfccb1 |
register_thread_address("delayed_restart_bfd_child_thread", delayed_restart_bfd_child_thread);
|
|
Packit |
c22fc9 |
#endif
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
#endif
|