深入学习keepalived之一 keepalived的启动

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 & 2 || !daemon_mode)

        start_check_child();

#endif

#ifdef _WITH_VRRP_

    /* start vrrp child */

    if (daemon_mode & 1 || !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 < 0) {

        log_message(LOG_INFO, "Healthcheck child process: fork error(%s)"

                   , strerror(errno));

        return -1;

    } 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 0;

    }



    /* Opening local CHECK syslog channel */

    openlog(PROG_CHECK, LOG_PID | ((debug & 1) ? LOG_CONS : 0),

        (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(0);

    }



    /* Create the new master thread */

    signal_handler_destroy();

    thread_destroy_master(master);

    master = thread_make_master();



    /* change to / dir */

    ret = chdir("/");

    if (ret < 0) {

        log_message(LOG_INFO, "Healthcheck child process: error chdir");

    }



    /* Set mask */

    umask(0);

#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(0);

}

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[0], F_SETFL, O_NONBLOCK | fcntl(signal_pipe[0], F_GETFL));

    fcntl(signal_pipe[1], F_SETFL, O_NONBLOCK | fcntl(signal_pipe[1], 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 & 4) {

        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 & 520) == 520) {

            debug &= ~520;

            thread_add_terminate_event(master);

        }

#endif

        thread_call(&thread);

    }

}

 

 

 

 

 

你可能感兴趣的:(keepalived)