wazuh通过wazuh-modulesd进程启动各个模块的提供的线程函数来运行各个模块的功能

int main(int argc, char **argv)
{
    int c;
    int wm_debug = 0;
    int test_config = 0;

    /* Set the name */
    OS_SetName(ARGV0);

    // Define current working directory
    char * home_path = w_homedir(argv[0]);
    if (chdir(home_path) == -1) {
        merror_exit(CHDIR_ERROR, home_path, errno, strerror(errno));
    }

    wmodule *cur_module;
    wm_debug_level = getDefine_Int("wazuh_modules", "debug", 0, 2);

    // Get command line options

    while ((c = getopt(argc, argv, "dfht")) != -1) {
        switch (c) {
        case 'd':
            nowDebug();
            wm_debug = 1;
            break;
        case 'f':
            flag_foreground = 1;
            break;
        case 'h':
            wm_help();
            break;
        case 't':
            test_config = 1;
            flag_foreground = 1;
            break;
        default:
            print_out(" ");
            wm_help();
        }
    }

    // Get default debug level

    if (wm_debug == 0) {
        wm_debug = wm_debug_level;

        while (wm_debug != 0) {
            nowDebug();
            wm_debug--;
        }
    }

    mdebug1(WAZUH_HOMEDIR, home_path);
    os_free(home_path);

    // Setup daemon

    wm_setup();

    if (test_config)
        exit(EXIT_SUCCESS);

    minfo(STARTUP_MSG, (int)getpid());

    // Run modules

    for (cur_module = wmodules; cur_module; cur_module = cur_module->next) {
        if (CreateThreadJoinable(&cur_module->thread, cur_module->context->start, cur_module->data) < 0) {
            merror_exit("CreateThreadJoinable() for '%s': %s", cur_module->tag, strerror(errno));
        }
        mdebug2("Created new thread for the '%s' module.", cur_module->tag);
    }

    // Start com request thread
    w_create_thread(wmcom_main, NULL);

    // Wait for threads

    for (cur_module = wmodules; cur_module; cur_module = cur_module->next) {
        pthread_join(cur_module->thread, NULL);
    }

    return EXIT_SUCCESS;
}

wazuh-modulesd 必须要在home目录下才能启动, w_homedir(argv[0]);  argv[0]是当前命令所在的命令行绝对路径,比如在/var/ossec/目录下执行 wazuh-modulesd, 那么argv[0]就是/var/ossec,

// Define current working directory
    char * home_path = w_homedir(argv[0]);
    if (chdir(home_path) == -1) {
        merror_exit(CHDIR_ERROR, home_path, errno, strerror(errno));
    }

w_homedir()函数,分析/proc , argv[0], 环境变量WAZUH_HOME。home目录下必须包含"/bin"

/**
 * @brief Get the Wazuh installation directory
 *
 * It is obtained from the /proc directory, argv[0], or the env variable WAZUH_HOME
 *
 * @param arg ARGV0 - Program name
 * @return Pointer to the Wazuh installation path on success
 */
char *w_homedir(char *arg) {
    minfo("heath arg : '%s'", arg);
    char *buff = NULL;
    struct stat buff_stat;
    char * delim = "/bin";
    os_calloc(PATH_MAX, sizeof(char), buff);
#ifdef __MACH__
    pid_t pid = getpid();
    if (proc_pidpath(pid, buff, PATH_MAX) > 0) {
        buff = w_strtok_r_str_delim(delim, &buff);
    }
#else
    if (realpath("/proc/self/exe", buff) != NULL) {
        dirname(buff);
        buff = w_strtok_r_str_delim(delim, &buff);
    }
    else if (realpath("/proc/curproc/file", buff) != NULL) {
        dirname(buff);
        buff = w_strtok_r_str_delim(delim, &buff);
    }
    else if (realpath("/proc/self/path/a.out", buff) != NULL) {
        dirname(buff);
        buff = w_strtok_r_str_delim(delim, &buff);
    }
#endif
    else if (realpath(arg, buff) != NULL) {
        dirname(buff);
        buff = w_strtok_r_str_delim(delim, &buff);
    } else {
        // The path was not found so read WAZUH_HOME env var
        char * home_env = NULL;
        if (home_env = getenv(WAZUH_HOME_ENV), home_env) {
            snprintf(buff, PATH_MAX, "%s", home_env);
        }
    }

    if ((stat(buff, &buff_stat) < 0) || !S_ISDIR(buff_stat.st_mode)) {
        os_free(buff);
        merror_exit(HOME_ERROR);
    }

    return buff;
}

 创建各模块线程, 这里主要关注sca模块的线程函数

// Run modules

    for (cur_module = wmodules; cur_module; cur_module = cur_module->next) {
        if (CreateThreadJoinable(&cur_module->thread, cur_module->context->start, cur_module->data) < 0) {
            merror_exit("CreateThreadJoinable() for '%s': %s", cur_module->tag, strerror(errno));
        }
        mdebug2("Created new thread for the '%s' module.", cur_module->tag);
    }