secgateway/Platform/user/ulog/log-sched/log_pty.c

247 lines
7.5 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <sys/epoll.h>
#include "log_pty.h"
#include "log_types.h"
#include "log_common.h"
#include "ret_errno.h"
#define MAX_EVENT_NUMBER 64
#define LOG_DEV_PTY_DIR LOG_DEV_DIR"pts/"
#define LOG_CONF_PTY_FILE_NAME "log-pty.conf"
int g_epoll_fd = -1;
int g_watch_fd = -1;
int g_inotify_fd = -1;
pthread_t g_monitor_thread;
static int write_pty_content(FILE *fp, const u8 level, const char *filter_mod, void *arg);
static void *pty_monitor_thread(void *arg)
{
struct epoll_event events[MAX_EVENT_NUMBER];
int ret;
char buf[MAX_LINE_SZ];
ssize_t len;
char *ptr;
struct inotify_event *inotify_ev;
ULOG_DEBUG(g_log, "Monitor pty is begining");
while (1) {
//ULOG_DEBUG(g_log, "Epoll is waiting");
ret = epoll_wait(g_epoll_fd, events, MAX_EVENT_NUMBER, 1000);
if (ret == -1) {
if (errno == EBADF) {
ULOG_DEBUG(g_log, "Epoll has been shut or invalid");
} else {
ULOG_ERR(g_log, "Waiting epoll is failure:%s, code:%d", strerror(errno), errno);
}
break;
}
if (ret == 0) { // 超时
continue;
}
for (int i = 0; i < MAX_EVENT_NUMBER; i++) {
ULOG_DEBUG(g_log, "Epoll event value is 0x%x", events[i].events);
if ((events[i].events & EPOLLIN) != EPOLLIN) {
continue;
}
len = read(g_inotify_fd, buf, sizeof(buf));
if ((len == -1) && (errno != EAGAIN)) {
ULOG_ERR(g_log, "Reading inotify is failure:%s", strerror(errno));
break;
}
if (len <= 0) {
continue;
}
for (ptr = buf; ptr < buf + len;
ptr += sizeof(struct inotify_event) + inotify_ev->len) {
inotify_ev = (struct inotify_event *) ptr;
if (((inotify_ev->mask & IN_CREATE) != IN_CREATE)
&& ((inotify_ev->mask & IN_DELETE) != IN_DELETE)) {
ULOG_DEBUG(g_log, "Current ev mask:%u, anything willn't be done", inotify_ev->mask);
continue;
}
// sleep一下防止权限修改不成功
sleep(1);
ULOG_DEBUG(g_log, "Current ev mask:%u, wo will write configure and restart rsyslog", inotify_ev->mask);
log_conf(LOG_INFO, LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME, NULL,
write_pty_content, NULL);
if (log_sev_restart() != 0) {
ULOG_ERR(g_log, "Pty monitor restart rsyslog 2 is failure");
}
}
}
}
ULOG_ERR(g_log, "Monitor pty is end");
}
static void close_monitor()
{
if (g_epoll_fd != -1) {
close(g_epoll_fd);
g_epoll_fd = -1;
}
if (g_watch_fd != -1) {
inotify_rm_watch(g_inotify_fd, g_watch_fd);
close(g_watch_fd);
g_watch_fd = -1;
}
if (g_inotify_fd != -1) {
close(g_inotify_fd);
g_inotify_fd = -1;
}
}
static ret_code start_dev_pty_monitor()
{
if (g_inotify_fd != -1) {
ULOG_ERR(g_log, "Monitoring pty has started up, value:%d", g_inotify_fd);
return RET_OK;
}
g_inotify_fd = inotify_init();
if (g_inotify_fd == -1) {
ULOG_ERR(g_log, "Initiating file notify is failure:%s", strerror(errno));
return RET_ERR;
}
g_watch_fd = inotify_add_watch(g_inotify_fd, LOG_DEV_PTY_DIR, IN_CREATE | IN_DELETE);
if(g_watch_fd == -1) {
ULOG_ERR(g_log, "Intify add watch is failure:%s", strerror(errno));
goto FAIL;
}
g_epoll_fd = epoll_create1(0);
if (g_epoll_fd == -1) {
ULOG_ERR(g_log, "Creating epoll is failure:%s", strerror(errno));
goto FAIL;
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = g_inotify_fd;
if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, g_inotify_fd, &ev) == -1) {
ULOG_ERR(g_log, "Setting epoll is failure:%s", strerror(errno));
goto FAIL;
}
int ret = pthread_create(&g_monitor_thread, NULL, pty_monitor_thread, NULL);
if (ret != 0) {
ULOG_ERR(g_log, "Creating monitor thread is failure:%d", ret);
goto FAIL;
}
return RET_OK;
FAIL:
close_monitor();
return RET_ERR;
}
static void stop_dev_pty_monitor()
{
ULOG_DEBUG(g_log, "Stopping dev pty monitor");
close_monitor();
pthread_join(g_monitor_thread, NULL);
}
static int write_pty_content(FILE *fp, const u8 level, const char *filter_mod, void *arg)
{
DIR *dir;
if ((dir = opendir(LOG_DEV_PTY_DIR)) == NULL) {
ULOG_ERR(g_log, "Open dir:[%s] is failure:%d", LOG_DEV_PTY_DIR, strerror(errno));
return -1;
}
struct dirent *ptr;
char path[MAX_PATH_SZ];
while ((ptr = readdir(dir)) != NULL) {
if ((strcmp(ptr->d_name, ".") == 0)
|| (strcmp(ptr->d_name, "..") == 0)
|| (ptr->d_type == DT_DIR)) { ///current dir OR parrent dir
ULOG_DEBUG(g_log,"The file:[%s] or directory jump over\n", ptr->d_name);
continue;
}
if (strstr(ptr->d_name, "ptmx") != NULL) {
ULOG_DEBUG(g_log,"The file:[%s] isn't redirected\n", ptr->d_name);
continue;
}
ULOG_DEBUG(g_log, "pty name:%s", ptr->d_name);
if (snprintf(path, sizeof(path), "%s%s", LOG_DEV_PTY_DIR, ptr->d_name) < 0) {
ULOG_ERR(g_log, "Setting pty of log[%s] is failure", ptr->d_name);
return -1;
}
if (write_conf_content_authorizing(fp, level, filter_mod, path) != 0) {
ULOG_ERR(g_log, "Writing pty[module:%s] of log is failure", filter_mod);
return -1;
}
}
if (start_dev_pty_monitor() != RET_OK) {
ULOG_ERR(g_log, "Starting pty monitor is failure");
return -1;
}
return 0;
}
static int config_log_pty(const log_pty_t *conf)
{
int ret = -1;
switch (conf->on)
{
case LOG_OFF:
stop_dev_pty_monitor();
ret = log_off_with_file(LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME);
break;
case LOG_ON:
if (log_conf(conf->level, LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME, conf->module,
write_pty_content, NULL) != 0) {
ULOG_ERR(g_log, "Log's pty configure which is written is failure");
ret = -1;
} else {
ret = 0;
}
break;
default:
ULOG_WARNING(g_log, "Unknown on value:%u", conf->on);
break;
}
return ret;
}
static int __rpc_conf_log_pty(pointer input, const void *arg, char *str_err, int str_len)
{
if (config_log_pty((const log_pty_t *)input) != 0) {
strncpy(str_err, "Configuring pty of log is faiure", str_len);
return -1;
}
return 0;
}
void rpc_conf_log_pty(rpc_conn *conn, pointer input, int input_len, pointer data)
{
rpc_conf_proc(conn, input, input_len, sizeof(log_pty_t), __rpc_conf_log_pty, NULL);
}