2019-07-26 10:22:43 +00:00
|
|
|
|
#include <string.h>
|
2019-08-29 07:41:08 +00:00
|
|
|
|
#include <unistd.h>
|
2019-07-26 10:22:43 +00:00
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#include <errno.h>
|
2019-08-29 07:41:08 +00:00
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/inotify.h>
|
|
|
|
|
#include <sys/epoll.h>
|
2019-07-26 10:22:43 +00:00
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
#include "log_pty.h"
|
2019-08-02 09:58:02 +00:00
|
|
|
|
#include "log_types.h"
|
2019-07-26 10:22:43 +00:00
|
|
|
|
#include "log_common.h"
|
2019-08-29 07:41:08 +00:00
|
|
|
|
#include "ret_errno.h"
|
2019-08-30 06:13:48 +00:00
|
|
|
|
#include "sev_sched.h"
|
|
|
|
|
|
2019-07-26 10:22:43 +00:00
|
|
|
|
|
2019-08-29 07:41:08 +00:00
|
|
|
|
#define MAX_EVENT_NUMBER 64
|
2019-07-31 09:32:43 +00:00
|
|
|
|
#define LOG_DEV_PTY_DIR LOG_DEV_DIR"pts/"
|
|
|
|
|
#define LOG_CONF_PTY_FILE_NAME "log-pty.conf"
|
2019-08-30 02:36:56 +00:00
|
|
|
|
#define LOG_CONF_KEY_PTY_LEVEL_STR "pty.level"
|
|
|
|
|
#define LOG_CONF_KEY_PTY_MODULE_STR "pty.module"
|
|
|
|
|
|
2019-08-30 09:34:00 +00:00
|
|
|
|
pthread_mutex_t g_mutex_pty;
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
2019-08-30 09:34:00 +00:00
|
|
|
|
volatile int g_epoll_fd = -1;
|
2019-08-29 07:41:08 +00:00
|
|
|
|
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);
|
|
|
|
|
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-29 07:41:08 +00:00
|
|
|
|
static void *pty_monitor_thread(void *arg)
|
|
|
|
|
{
|
|
|
|
|
struct epoll_event events[MAX_EVENT_NUMBER];
|
|
|
|
|
int ret;
|
2019-08-30 09:34:00 +00:00
|
|
|
|
ret_code ret_c;
|
2019-08-29 07:41:08 +00:00
|
|
|
|
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);
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2019-08-29 07:41:08 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-26 10:22:43 +00:00
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
static int write_pty_content(FILE *fp, const u8 level, const char *filter_mod, void *arg)
|
2019-07-26 10:22:43 +00:00
|
|
|
|
{
|
|
|
|
|
DIR *dir;
|
2019-07-29 03:50:57 +00:00
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
if ((dir = opendir(LOG_DEV_PTY_DIR)) == NULL) {
|
2019-08-29 07:41:08 +00:00
|
|
|
|
ULOG_ERR(g_log, "Open dir:[%s] is failure:%d", LOG_DEV_PTY_DIR, strerror(errno));
|
2019-08-01 08:44:18 +00:00
|
|
|
|
return -1;
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct dirent *ptr;
|
2019-07-29 03:50:57 +00:00
|
|
|
|
char path[MAX_PATH_SZ];
|
2019-07-26 10:22:43 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
if (strstr(ptr->d_name, "ptmx") != NULL) {
|
2019-07-26 10:22:43 +00:00
|
|
|
|
ULOG_DEBUG(g_log,"The file:[%s] isn't redirected\n", ptr->d_name);
|
2019-07-29 03:50:57 +00:00
|
|
|
|
continue;
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
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);
|
2019-08-01 08:44:18 +00:00
|
|
|
|
return -1;
|
2019-07-29 10:20:17 +00:00
|
|
|
|
}
|
2019-07-29 03:50:57 +00:00
|
|
|
|
if (write_conf_content_authorizing(fp, level, filter_mod, path) != 0) {
|
2019-07-31 09:32:43 +00:00
|
|
|
|
ULOG_ERR(g_log, "Writing pty[module:%s] of log is failure", filter_mod);
|
2019-08-01 08:44:18 +00:00
|
|
|
|
return -1;
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
2019-07-29 03:50:57 +00:00
|
|
|
|
|
2019-08-29 07:41:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (start_dev_pty_monitor() != RET_OK) {
|
|
|
|
|
ULOG_ERR(g_log, "Starting pty monitor is failure");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2019-07-29 03:50:57 +00:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 09:32:43 +00:00
|
|
|
|
static int config_log_pty(const log_pty_t *conf)
|
2019-07-29 03:50:57 +00:00
|
|
|
|
{
|
2019-08-13 08:25:43 +00:00
|
|
|
|
int ret = -1;
|
2019-08-30 02:36:56 +00:00
|
|
|
|
char value_str[128]="";
|
2019-08-13 08:25:43 +00:00
|
|
|
|
|
|
|
|
|
switch (conf->on)
|
|
|
|
|
{
|
2019-08-29 07:41:08 +00:00
|
|
|
|
case LOG_OFF:
|
|
|
|
|
stop_dev_pty_monitor();
|
2019-08-14 09:17:18 +00:00
|
|
|
|
ret = log_off_with_file(LOG_CONF_PATH, LOG_CONF_PTY_FILE_NAME);
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
|
|
|
|
/* off时,将log-sched配置文件中pty日志级别调成默认值info,即level=6 */
|
|
|
|
|
if (0 == ret) {
|
|
|
|
|
memset(value_str, 0, sizeof(value_str));
|
|
|
|
|
sprintf(value_str, "%u", 6);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-13 08:25:43 +00:00
|
|
|
|
break;
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
2019-08-13 08:25:43 +00:00
|
|
|
|
case LOG_ON:
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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) {
|
2019-08-13 08:25:43 +00:00
|
|
|
|
ULOG_ERR(g_log, "Log's pty configure which is written is failure");
|
|
|
|
|
} else {
|
|
|
|
|
ret = 0;
|
|
|
|
|
}
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
|
|
|
|
/* 写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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 08:25:43 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ULOG_WARNING(g_log, "Unknown on value:%u", conf->on);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-16 07:49:28 +00:00
|
|
|
|
static int __rpc_conf_log_pty(pointer input, const void *arg, char *str_err, int str_len)
|
2019-07-26 10:22:43 +00:00
|
|
|
|
{
|
2019-08-16 07:49:28 +00:00
|
|
|
|
if (config_log_pty((const log_pty_t *)input) != 0) {
|
|
|
|
|
strncpy(str_err, "Configuring pty of log is faiure", str_len);
|
|
|
|
|
return -1;
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
2019-08-16 07:49:28 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-07-26 10:22:43 +00:00
|
|
|
|
|
2019-08-16 07:49:28 +00:00
|
|
|
|
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);
|
2019-07-26 10:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-30 02:36:56 +00:00
|
|
|
|
ret_code pty_initial()
|
|
|
|
|
{
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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");
|
|
|
|
|
}
|
2019-08-30 02:36:56 +00:00
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret_code pty_exit()
|
|
|
|
|
{
|
2019-08-30 09:34:00 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
2019-08-30 02:36:56 +00:00
|
|
|
|
stop_dev_pty_monitor();
|
2019-08-30 09:34:00 +00:00
|
|
|
|
return ret;
|
2019-08-30 02:36:56 +00:00
|
|
|
|
}
|
|
|
|
|
|