深入学习keepalived之一 keepalived的启动
2024-10-21 12:51:49
1.keepalived的启动过程:
启动健康检查子进程和vrrp子进程。其中_WITH_LVS_,_WITH_VRRP_在configure和configure.in文件中定义。
源码如下:
/* Daemon init sequence */
static void
start_keepalived(void)
{
#ifdef _WITH_LVS_
/* start healthchecker child */
if (daemon_mode & || !daemon_mode)
start_check_child();
#endif
#ifdef _WITH_VRRP_
/* start vrrp child */
if (daemon_mode & || !daemon_mode)
start_vrrp_child();
#endif
}
2. 启动健康检查子进程。
/* Register CHECK thread */
int
start_check_child(void)
{
#ifndef _DEBUG_
pid_t pid;
int ret; /* Initialize child process */
pid = fork(); if (pid < ) {
log_message(LOG_INFO, "Healthcheck child process: fork error(%s)"
, strerror(errno));
return -;
} else if (pid) {
checkers_child = pid;
log_message(LOG_INFO, "Starting Healthcheck child process, pid=%d"
, pid); /* Start respawning thread */
thread_add_child(master, check_respawn_thread, NULL,
pid, RESPAWN_TIMER);
return ;
} /* Opening local CHECK syslog channel */
openlog(PROG_CHECK, LOG_PID | ((debug & ) ? LOG_CONS : ),
(log_facility==LOG_DAEMON) ? LOG_LOCAL2 : log_facility); /* Child process part, write pidfile */
if (!pidfile_write(checkers_pidfile, getpid())) {
log_message(LOG_INFO, "Healthcheck child process: cannot write pidfile");
exit();
} /* Create the new master thread */
signal_handler_destroy();
thread_destroy_master(master);
master = thread_make_master(); /* change to / dir */
ret = chdir("/");
if (ret < ) {
log_message(LOG_INFO, "Healthcheck child process: error chdir");
} /* Set mask */
umask();
#endif /* If last process died during a reload, we can get there and we
* don't want to loop again, because we're not reloading anymore.
*/
UNSET_RELOAD; /* Signal handling initialization */
check_signal_init(); /* Start Healthcheck daemon */
start_check(); /* Launch the scheduling I/O multiplexer */
launch_scheduler(); /* Finish healthchecker daemon process */
stop_check();
exit();
}
debug模式暂且不考虑。
2.1 健康检查信号初始化
/* CHECK Child signal handling */
void
check_signal_init(void)
{
signal_handler_init();
signal_set(SIGHUP, sighup_check, NULL);
signal_set(SIGINT, sigend_check, NULL);
signal_set(SIGTERM, sigend_check, NULL);
signal_ignore(SIGPIPE);
} /* Handlers intialization */
void
signal_handler_init(void)
{
int n = pipe(signal_pipe);
assert(!n); fcntl(signal_pipe[], F_SETFL, O_NONBLOCK | fcntl(signal_pipe[], F_GETFL));
fcntl(signal_pipe[], F_SETFL, O_NONBLOCK | fcntl(signal_pipe[], F_GETFL)); signal_SIGHUP_handler = NULL;
signal_SIGINT_handler = NULL;
signal_SIGTERM_handler = NULL;
signal_SIGCHLD_handler = NULL;
}
2.2 启动健康检查后台程序
/* Daemon init sequence */
static void
start_check(void)
{
/* Initialize sub-system */
ipvs_start();
init_checkers_queue();
#ifdef _WITH_VRRP_
init_interface_queue();
kernel_netlink_init();
#endif
#ifdef _WITH_SNMP_
if (!reload && snmp)
check_snmp_agent_init();
#endif /* Parse configuration file */
global_data = alloc_global_data();
check_data = alloc_check_data();
init_data(conf_file, check_init_keywords);
if (!check_data) {
stop_check();
return;
} /* Post initializations */
log_message(LOG_INFO, "Configuration is using : %lu Bytes", mem_allocated); /* SSL load static data & initialize common ctx context */
if (!init_ssl_ctx()) {
stop_check();
return;
} /* Processing differential configuration parsing */
if (reload) {
clear_diff_services();
copy_srv_states();
} /* Initialize IPVS topology */
if (!init_services()) {
stop_check();
return;
} /* Dump configuration */
if (debug & ) {
dump_global_data(global_data);
dump_check_data(check_data);
} #ifdef _WITH_VRRP_
/* Initialize linkbeat */
init_interface_linkbeat();
#endif /* Register checkers thread */
register_checkers_thread();
}
2.3 启动I/O复用分发调度器
/* Our infinite scheduling loop */
void
launch_scheduler(void)
{
thread_t thread; signal_set(SIGCHLD, thread_child_handler, master); /*
* Processing the master thread queues,
* return and execute one ready thread.
*/
while (thread_fetch(master, &thread)) {
/* Run until error, used for debuging only */
#ifdef _DEBUG_
if ((debug & ) == ) {
debug &= ~;
thread_add_terminate_event(master);
}
#endif
thread_call(&thread);
}
}
最新文章
- seajs和requirejs
- 基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化
- ffmpeg-20160815-bin.7z
- Syslog-ng
- ThinkPHP之数据库操作
- HighCharts入门
- Codeforces Round #282 (Div. 1) A. Treasure 水题
- jquery单页网站导航插件One Page Nav
- Chrome控制台 JS调试
- shell 远程备份日志
- websocket 70K连接测试
- redis 实现
- unity打包exe中的资源管理
- [swarthmore cs75] Compiler 4 – Diamondback
- Java入门(四):运算符优先级、关键字与保留字
- git 提交解决冲突(转载)
- python词云
- Java 导入数据到Excel并提供文件下载接口
- graphite custom functions
- POJ 2771
热门文章
- 如何在ubuntu下使用samba创建共享
- openstack组件服务的入口寻找方法
- ubuntu14.04,安装Git(源代码管理工具)
- Xcode打包提交至itunes connect后,提交审核成功,随后出现二进制文件无效
- React基础篇(2) -- state&;props&;refs
- cookie,session 的概念以及在django中的用法,以及cbv装饰器用法
- 【bzoj4103】[Thu Summer Camp 2015]异或运算 可持久化trie树
- 【guava】对象处理
- JVM高级特性与实践(一):Java内存区域 与 内存溢出异常
- 老男孩Day17作业:后台管理平台编辑表格