diff options
Diffstat (limited to 'accel-pppd/logs/log_file.c')
-rw-r--r-- | accel-pppd/logs/log_file.c | 277 |
1 files changed, 216 insertions, 61 deletions
diff --git a/accel-pppd/logs/log_file.c b/accel-pppd/logs/log_file.c index e435757..f1a5018 100644 --- a/accel-pppd/logs/log_file.c +++ b/accel-pppd/logs/log_file.c @@ -47,20 +47,32 @@ struct log_file_pd_t unsigned long tmp; }; +struct fail_log_pd_t +{ + struct ppp_pd_t pd; + struct list_head msgs; +}; + + static int conf_color; static int conf_per_session; static char *conf_per_user_dir; static char *conf_per_session_dir; static int conf_copy; +static int conf_fail_log; static const char* level_name[]={" msg", "error", " warn", " info", " info", "debug"}; static const char* level_color[]={NORMAL_COLOR, RED_COLOR, YELLOW_COLOR, GREEN_COLOR, GREEN_COLOR, BLUE_COLOR}; static void *pd_key1; static void *pd_key2; +static void *pd_key3; + static struct log_file_t *log_file; +static struct log_file_t *fail_log_file; static mempool_t lpd_pool; +static mempool_t fpd_pool; static char *log_buf; static struct aiocb aiocb = { @@ -248,6 +260,29 @@ static void queue_log(struct log_file_t *lf, struct log_msg_t *msg) queue_lf(lf); } +static void queue_log_list(struct log_file_t *lf, struct list_head *l) +{ + int r; + struct log_msg_t *msg; + + spin_lock(&lf->lock); + while (!list_empty(l)) { + msg = list_entry(l->next, typeof(*msg), entry); + list_del(&msg->entry); + list_add_tail(&msg->entry, &lf->msgs); + } + if (lf->fd != -1) { + r = lf->queued; + lf->queued = 1; + } else + r = 1; + spin_unlock(&lf->lock); + + if (!r) + queue_lf(lf); +} + + static void set_hdr(struct log_msg_t *msg, struct ppp_t *ppp) { struct tm tm; @@ -275,20 +310,40 @@ static void general_log(struct log_target_t *t, struct log_msg_t *msg, struct pp queue_log(log_file, msg); } -static struct log_file_pd_t *find_pd(struct ppp_t *ppp, void *pd_key) +static struct ppp_pd_t *find_pd(struct ppp_t *ppp, void *pd_key) { struct ppp_pd_t *pd; - struct log_file_pd_t *lpd; list_for_each_entry(pd, &ppp->pd_list, entry) { if (pd->key == pd_key) { - lpd = container_of(pd, typeof(*lpd), pd); - return lpd; + return pd; } } + return NULL; } +static struct log_file_pd_t *find_lpd(struct ppp_t *ppp, void *pd_key) +{ + struct ppp_pd_t *pd = find_pd(ppp, pd_key); + + if (!pd) + return NULL; + + return container_of(pd, struct log_file_pd_t, pd); +} + +static struct fail_log_pd_t *find_fpd(struct ppp_t *ppp, void *pd_key) +{ + struct ppp_pd_t *pd = find_pd(ppp, pd_key); + + if (!pd) + return NULL; + + return container_of(pd, struct fail_log_pd_t, pd); +} + + static void per_user_log(struct log_target_t *t, struct log_msg_t *msg, struct ppp_t *ppp) { struct log_file_pd_t *lpd; @@ -298,7 +353,7 @@ static void per_user_log(struct log_target_t *t, struct log_msg_t *msg, struct p return; } - lpd = find_pd(ppp, &pd_key1); + lpd = find_lpd(ppp, &pd_key1); if (!lpd) { log_free_msg(msg); @@ -318,7 +373,7 @@ static void per_session_log(struct log_target_t *t, struct log_msg_t *msg, struc return; } - lpd = find_pd(ppp, &pd_key2); + lpd = find_lpd(ppp, &pd_key2); if (!lpd) { log_free_msg(msg); @@ -329,6 +384,38 @@ static void per_session_log(struct log_target_t *t, struct log_msg_t *msg, struc queue_log(&lpd->lf, msg); } +static void fail_log(struct log_target_t *t, struct log_msg_t *msg, struct ppp_t *ppp) +{ + struct fail_log_pd_t *fpd; + + if (!ppp || !conf_fail_log) { + log_free_msg(msg); + return; + } + + fpd = find_fpd(ppp, &pd_key3); + + if (!fpd) { + log_free_msg(msg); + return; + } + + set_hdr(msg, ppp); + list_add_tail(&msg->entry, &fpd->msgs); +} + +static void fail_reopen(void) +{ + char *fname = conf_get_opt("log", "log-fail-file"); + int fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + log_emerg("log_file: open '%s': %s\n", fname, strerror(errno)); + return; + } + fail_log_file->new_fd = fd; +} + + static void general_reopen(void) { char *fname = conf_get_opt("log", "log-file"); @@ -362,9 +449,75 @@ static void free_lpd(struct log_file_pd_t *lpd) } } +static void ev_ppp_authorized2(struct ppp_t *ppp) +{ + struct fail_log_pd_t *fpd; + struct log_msg_t *msg; + + fpd = find_fpd(ppp, &pd_key3); + if (!fpd) + return; + + while (!list_empty(&fpd->msgs)) { + msg = list_entry(fpd->msgs.next, typeof(*msg), entry); + list_del(&msg->entry); + log_free_msg(msg); + } + + list_del(&fpd->pd.entry); + mempool_free(fpd); +} + +static void ev_ppp_authorized1(struct ppp_t *ppp) +{ + struct log_file_pd_t *lpd; + char *fname; + + lpd = find_lpd(ppp, &pd_key1); + if (!lpd) + return; + + fname = _malloc(PATH_MAX); + if (!fname) { + log_emerg("log_file: out of memory\n"); + return; + } + + strcpy(fname, conf_per_user_dir); + strcat(fname, "/"); + strcat(fname, ppp->username); + if (conf_per_session) { + if (mkdir(fname, S_IRWXU) && errno != EEXIST) { + log_emerg("log_file: mkdir '%s': %s'\n", fname, strerror(errno)); + goto out_err; + } + strcat(fname, "/"); + strcat(fname, ppp->sessionid); + } + strcat(fname, ".log"); + + if (log_file_open(&lpd->lf, fname)) + goto out_err; + + _free(fname); + + if (!list_empty(&lpd->lf.msgs)) { + lpd->lf.queued = 1; + queue_lf(&lpd->lf); + } + + return; + +out_err: + _free(fname); + list_del(&lpd->pd.entry); + free_lpd(lpd); +} + static void ev_ctrl_started(struct ppp_t *ppp) { struct log_file_pd_t *lpd; + struct fail_log_pd_t *fpd; char *fname; if (conf_per_user_dir) { @@ -413,19 +566,38 @@ static void ev_ctrl_started(struct ppp_t *ppp) list_add_tail(&lpd->pd.entry, &ppp->pd_list); } + + if (conf_fail_log) { + fpd = mempool_alloc(fpd_pool); + if (!fpd) { + log_emerg("log_file: out of memory\n"); + return; + } + memset(fpd, 0, sizeof(*fpd)); + fpd->pd.key = &pd_key3; + list_add_tail(&fpd->pd.entry, &ppp->pd_list); + INIT_LIST_HEAD(&fpd->msgs); + } } static void ev_ctrl_finished(struct ppp_t *ppp) { struct log_file_pd_t *lpd; + struct fail_log_pd_t *fpd; char *fname; - lpd = find_pd(ppp, &pd_key1); + fpd = find_fpd(ppp, &pd_key3); + if (fpd) { + queue_log_list(fail_log_file, &fpd->msgs); + list_del(&fpd->pd.entry); + mempool_free(fpd); + } + + lpd = find_lpd(ppp, &pd_key1); if (lpd) free_lpd(lpd); - - lpd = find_pd(ppp, &pd_key2); + lpd = find_lpd(ppp, &pd_key2); if (lpd) { if (lpd->tmp) { fname = _malloc(PATH_MAX); @@ -448,7 +620,7 @@ static void ev_ppp_starting(struct ppp_t *ppp) struct log_file_pd_t *lpd; char *fname1, *fname2; - lpd = find_pd(ppp, &pd_key2); + lpd = find_lpd(ppp, &pd_key2); if (!lpd) return; @@ -483,52 +655,6 @@ static void ev_ppp_starting(struct ppp_t *ppp) _free(fname2); } -static void ev_ppp_authorized(struct ppp_t *ppp) -{ - struct log_file_pd_t *lpd; - char *fname; - - lpd = find_pd(ppp, &pd_key1); - if (!lpd) - return; - - fname = _malloc(PATH_MAX); - if (!fname) { - log_emerg("log_file: out of memory\n"); - return; - } - - strcpy(fname, conf_per_user_dir); - strcat(fname, "/"); - strcat(fname, ppp->username); - if (conf_per_session) { - if (mkdir(fname, S_IRWXU) && errno != EEXIST) { - log_emerg("log_file: mkdir '%s': %s'\n", fname, strerror(errno)); - goto out_err; - } - strcat(fname, "/"); - strcat(fname, ppp->sessionid); - } - strcat(fname, ".log"); - - if (log_file_open(&lpd->lf, fname)) - goto out_err; - - _free(fname); - - if (!list_empty(&lpd->lf.msgs)) { - lpd->lf.queued = 1; - queue_lf(&lpd->lf); - } - - return; - -out_err: - _free(fname); - list_del(&lpd->pd.entry); - free_lpd(lpd); -} - static struct log_target_t general_target = { .log = general_log, @@ -545,7 +671,14 @@ static struct log_target_t per_session_target = .log = per_session_log, }; -static void __init init(void) +static struct log_target_t fail_log_target = +{ + .log = fail_log, + .reopen = fail_reopen, +}; + + +static void init(void) { char *opt; @@ -560,6 +693,7 @@ static void __init init(void) }; lpd_pool = mempool_create(sizeof(struct log_file_pd_t)); + fpd_pool = mempool_create(sizeof(struct fail_log_pd_t)); log_buf = malloc(LOG_BUF_SIZE); aiocb.aio_buf = log_buf; @@ -579,6 +713,18 @@ static void __init init(void) } } + opt = conf_get_opt("log", "log-fail-file"); + if (opt) { + fail_log_file = malloc(sizeof(*fail_log_file)); + memset(fail_log_file, 0, sizeof(*fail_log_file)); + log_file_init(fail_log_file); + if (log_file_open(fail_log_file, opt)) { + free(fail_log_file); + _exit(EXIT_FAILURE); + } + conf_fail_log = 1; + } + opt = conf_get_opt("log","color"); if (opt && atoi(opt) > 0) conf_color = 1; @@ -601,14 +747,23 @@ static void __init init(void) log_register_target(&general_target); - if (conf_per_user_dir) + if (conf_per_user_dir) { log_register_target(&per_user_target); + triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized1); + } - if (conf_per_session_dir) + if (conf_per_session_dir) { log_register_target(&per_session_target); + triton_event_register_handler(EV_PPP_STARTING, (triton_event_func)ev_ppp_starting); + } + + if (conf_fail_log) { + log_register_target(&fail_log_target); + triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized2); + } triton_event_register_handler(EV_CTRL_STARTED, (triton_event_func)ev_ctrl_started); triton_event_register_handler(EV_CTRL_FINISHED, (triton_event_func)ev_ctrl_finished); - triton_event_register_handler(EV_PPP_STARTING, (triton_event_func)ev_ppp_starting); - triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized); } + +DEFINE_INIT(1, init); |