logcollector进程主函数
int main(int argc, char **argv)
{
int c;
int debug_level = 0;
int test_config = 0, run_foreground = 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));
}
const char *cfg = OSSECCONF;
gid_t gid;
const char *group = GROUPGLOBAL;
lc_debug_level = getDefine_Int("logcollector", "debug", 0, 2);
/* Setup random */
srandom_init();
...
/* Check if the group given is valid */
gid = Privsep_GetGroup(group);
if (gid == (gid_t) - 1) {
merror_exit(USER_ERROR, "", group, strerror(errno), errno);
}
/* Privilege separation */
if (Privsep_SetGroup(gid) < 0) {
merror_exit(SETGID_ERROR, group, errno, strerror(errno));
}
/* Check current debug_level
* Command line setting takes precedence
*/
if (debug_level == 0) {
/* Get debug level */
debug_level = lc_debug_level;
while (debug_level != 0) {
nowDebug();
debug_level--;
}
}
mdebug1(WAZUH_HOMEDIR, home_path);
os_free(home_path);
/* Init message queue */
w_msg_hash_queues_init();
/* Read config file */
if (LogCollectorConfig(cfg) < 0) {
merror_exit(CONFIG_ERROR, cfg);
}
/* Exit if test config */
if (test_config) {
exit(0);
}
/* No file available to monitor -- continue */
if (logff == NULL) {
os_calloc(2, sizeof(logreader), logff);
logff[0].file = NULL;
logff[0].ffile = NULL;
logff[0].logformat = NULL;
logff[0].fp = NULL;
logff[1].file = NULL;
logff[1].logformat = NULL;
minfo(NO_FILE);
}
/* No sockets defined */
if (logsk == NULL) {
os_calloc(2, sizeof(logsocket), logsk);
logsk[0].name = NULL;
logsk[0].location = NULL;
logsk[0].mode = 0;
logsk[0].prefix = NULL;
logsk[1].name = NULL;
logsk[1].location = NULL;
logsk[1].mode = 0;
logsk[1].prefix = NULL;
}
/* Start signal handler */
StartSIG(ARGV0);
// Set max open files limit
struct rlimit rlimit = { nofile, nofile };
if (setrlimit(RLIMIT_NOFILE, &rlimit) < 0) {
merror("Could not set resource limit for file descriptors to %d: %s (%d)", (int)nofile, strerror(errno), errno);
}
if (!run_foreground) {
/* Going on daemon mode */
nowDaemon();
goDaemon();
}
/* Create PID file */
if (CreatePID(ARGV0, getpid()) < 0) {
merror_exit(PID_ERROR);
}
/* Start the queue */
if ((logr_queue = StartMQ(DEFAULTQUEUE, WRITE, INFINITE_OPENQ_ATTEMPTS)) < 0) {
merror_exit(QUEUE_FATAL, DEFAULTQUEUE);
}
/* Main loop */
LogCollectorStart();
return (0);
}
消息队列声明与定义
/**
* Starts a Message Queue.
* @param key path where the message queue will be created
* @param type WRITE||READ
* @param n_attempts Number of attempts to connect to the queue (0 to attempt until a successful conection).
* @return
* UNIX -> OS_INVALID if queue failed to start
* UNIX -> int(rc) file descriptor of initialized queue
* WIN32 -> 0
*/
int StartMQ(const char *key, short int type, short int n_attempts) __attribute__((nonnull));
在函数声明末尾__attribute__((nonnull)); 使用nonnull能够将可能为空的值暴露出来,这样能够找出任何潜伏在调用代码中的空指针bug。如果key为空编译时将报错误,不至于到运行时才报错误。
/* Start the Message Queue. type: WRITE||READ */
int StartMQ(const char *path, short int type, short int n_attempts)
{
if (type == READ) {
return (OS_BindUnixDomain(path, SOCK_DGRAM, OS_MAXSTR + 512));
}
/* We give up to 21 seconds for the other end to start */
else {
int rc = 0, sleep_time = 5;
short int attempt = 0;
// If n_attempts is 0, trying to reconnect infinitely
while ((rc = OS_ConnectUnixDomain(path, SOCK_DGRAM, OS_MAXSTR + 256)), rc < 0){
attempt++;
mdebug1("Can't connect to '%s': %s (%d). Attempt: %d", path, strerror(errno), errno, attempt);
if (n_attempts != INFINITE_OPENQ_ATTEMPTS && attempt == n_attempts) {
break;
}
sleep(sleep_time += 5);
}
if (rc < 0) {
return OS_INVALID;
}
mdebug1("Connected succesfully to '%s' after %d attempts", path, attempt);
mdebug1(MSG_SOCKET_SIZE, OS_getsocketsize(rc));
return (rc);
}
}
用unix domain socket作为消息队列。读消息队列的时候用OS_BindUnixDomain()数据报socket读,写的时候用OS_ConnectUnixDomain()
版权声明:本文为CSDN博主「x-ghost」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/MEIYOUDAO_J…