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

363 lines
11 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"
#include "sev_sched.h"
#define MAX_EVENT_NUMBER 64
#define LOG_DEV_PTY_DIR LOG_DEV_DIR"pts/"
#define LOG_CONF_PTY_FILE_NAME "log-pty.conf"
#define LOG_CONF_KEY_PTY_LEVEL_STR "pty.level"
#define LOG_CONF_KEY_PTY_MODULE_STR "pty.module"
pthread_mutex_t g_mutex_pty;
volatile 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 ret_code write_pty_conf()
{
char value_str[128]="";
uint level = LOG_INFO;
char *module = NULL;
ret_code ret = RET_OK;
memset(value_str, 0, sizeof(value_str));
sprintf(value_str, "%s%s", LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME);
if (access(value_str, 0) == 0)
{
/* 获取配置 */
memset(value_str, 0, sizeof(value_str));
if (get_log_file_conf(LOG_CONF_KEY_PTY_LEVEL_STR, value_str, sizeof(value_str)) == 0)
{
level = atoi(value_str);
}
memset(value_str, 0, sizeof(value_str));
if (get_log_file_conf(LOG_CONF_KEY_PTY_MODULE_STR, value_str, sizeof(value_str)) == 0)
{
module = value_str;
}
pthread_mutex_lock(&g_mutex_pty);
int ret_conf = log_conf((u8)level, LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME, module,
write_pty_content, NULL);
pthread_mutex_unlock(&g_mutex_pty);
if (ret_conf != 0)
{
ULOG_ERR(g_log, "Log's pty configure which is written is failure");
ret = RET_ERR;
}
else
{
ULOG_DEBUG(g_log, "Pty config level(%u) and module(%s) successed.", level, module!=NULL?module:"NULL");
}
}
return ret;
}
static void *pty_monitor_thread(void *arg)
{
struct epoll_event events[MAX_EVENT_NUMBER];
ret_code ret_c;
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");
int 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);
ret_c = write_pty_conf();
if (ret_c != RET_OK) {
ULOG_ERR(g_log, "Pty monitor write pty configure is failure(code:%d)", ret_c);
continue;
}
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);
closedir(dir);
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);
closedir(dir);
return -1;
}
}
closedir(dir);
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;
char value_str[128]="";
switch (conf->on)
{
case LOG_OFF:
stop_dev_pty_monitor();
ret = log_off_with_file(LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME);
/* off时将log-sched配置文件中pty日志级别调成默认值info即level=6 */
if (0 == ret) {
memset(value_str, 0, sizeof(value_str));
snprintf(value_str, sizeof(value_str), "%u", LOG_INFO);
if (write_log_file_conf(LOG_CONF_KEY_PTY_LEVEL_STR, value_str) != 0) {
ULOG_ERR(g_log, "Pty-level which is written is failure");
return -1;
}
}
break;
case LOG_ON:
pthread_mutex_lock(&g_mutex_pty);
ret = log_conf(conf->level, LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME, conf->module,
write_pty_content, NULL);
pthread_mutex_unlock(&g_mutex_pty);
if (ret != 0) {
ULOG_ERR(g_log, "Log's pty configure which is written is failure");
} else {
ret = 0;
}
/* 写pty日志级别与模块名称到log-sched配置文件 */
if (0 == ret) {
memset(value_str, 0, sizeof(value_str));
sprintf(value_str, "%u", conf->level);
if (write_log_file_conf(LOG_CONF_KEY_PTY_LEVEL_STR, value_str) != 0) {
ULOG_ERR(g_log, "Pty-level which is written is failure");
return -1;
}
memset(value_str, 0, sizeof(value_str));
sprintf(value_str, "%s", conf->module);
if (write_log_file_conf(LOG_CONF_KEY_PTY_MODULE_STR, value_str) != 0) {
ULOG_ERR(g_log, "Pty-module which is written is failure");
return -1;
}
}
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);
}
ret_code pty_initial()
{
int thread_ret = pthread_mutex_init(&g_mutex_pty, NULL);
if (thread_ret != 0) {
ULOG_DEBUG(g_log, "Initiating pthread lock is failure(cdoe:%d)", thread_ret);
}
ret_code ret = write_pty_conf();
if (ret != RET_OK) {
ULOG_DEBUG(g_log, "Initiating pty is failure(cdoe:%d)", ret);
} else {
ULOG_INFO(g_log, "Initiating pty is success");
}
return ret;
}
ret_code pty_exit()
{
ret_code ret = RET_OK;
int thread_ret = pthread_mutex_destroy(&g_mutex_pty);
if (0 != thread_ret) {
ret = RET_ERR;
ULOG_DEBUG(g_log, "Destroying pthread lock is failure(cdoe:%d)", thread_ret);
}
stop_dev_pty_monitor();
return ret;
}