diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2010-09-22 22:53:59 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2010-09-22 22:53:59 +0400 |
commit | 3e61cb3f8d58f64c8023e95bf74341e6bc61560e (patch) | |
tree | d73a44bf63044e35e8c3b1088598fc29e95a30b9 | |
parent | b96fbc3f966b012720d2b74b1dfd2a0ab95086cf (diff) | |
download | accel-ppp-3e61cb3f8d58f64c8023e95bf74341e6bc61560e.tar.gz accel-ppp-3e61cb3f8d58f64c8023e95bf74341e6bc61560e.zip |
log: log_file rewrited to use aio
log: simplified engine
various bug fixes
-rw-r--r-- | accel-pptpd/CMakeLists.txt | 2 | ||||
-rw-r--r-- | accel-pptpd/accel-pptpd.conf | 12 | ||||
-rw-r--r-- | accel-pptpd/ctrl/pptp.c | 10 | ||||
l--------- | accel-pptpd/include/mempool.h | 1 | ||||
-rw-r--r-- | accel-pptpd/log.c | 80 | ||||
-rw-r--r-- | accel-pptpd/log.h | 5 | ||||
-rw-r--r-- | accel-pptpd/logs/CMakeLists.txt | 2 | ||||
-rw-r--r-- | accel-pptpd/logs/log_file.c | 595 | ||||
-rw-r--r-- | accel-pptpd/logs/log_pgsql.c | 9 | ||||
-rw-r--r-- | accel-pptpd/main.c | 38 | ||||
-rw-r--r-- | accel-pptpd/radius/dict/dictionary.rfc2865 | 2 | ||||
-rw-r--r-- | accel-pptpd/radius/req.c | 5 | ||||
-rw-r--r-- | accel-pptpd/sigchld.c | 12 | ||||
-rw-r--r-- | accel-pptpd/triton/md.c | 26 | ||||
-rw-r--r-- | accel-pptpd/triton/timer.c | 10 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.c | 128 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.h | 6 | ||||
-rw-r--r-- | accel-pptpd/triton/triton_p.h | 1 |
18 files changed, 545 insertions, 399 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index ee00a283..3de0072d 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -1,7 +1,7 @@ PROJECT (pptpd) cmake_minimum_required(VERSION 2.6) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -D_GNU_SOURCE -DSPINLOCK_GCC -DMEMDEBUG") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -D_GNU_SOURCE -DGCC_SPINLOCK -DMEMDEBUG") INCLUDE_DIRECTORIES(include) diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index 230ddba6..965d9bcf 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -11,6 +11,7 @@ [core] log-error=/dev/stderr +thread-count=4 [ppp] verbose=1 @@ -33,8 +34,9 @@ dm_coa_secret=testing123 verbose=1 [client-ip-range] -192.168.11.20-20 -192.168.11.6/32 +192.168.10.20-20 +192.168.10.6/32 +192.168.10.1/32 [ip-pool] gw-ip-address=192.168.100.1 @@ -47,13 +49,13 @@ gw-ip-address=192.168.100.1 [log] log-file=general.log -log-emerg=emerg.log +log-emerg=/dev/stderr log-debug=debug.log copy=1 -color=1 +#color=1 per-user-dir=per_user per-session-dir=per_session -per-session=1 +#per-session=1 [log-pgsql] conninfo=user=log diff --git a/accel-pptpd/ctrl/pptp.c b/accel-pptpd/ctrl/pptp.c index b8bb3663..9f76a341 100644 --- a/accel-pptpd/ctrl/pptp.c +++ b/accel-pptpd/ctrl/pptp.c @@ -511,6 +511,8 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ppp.ctrl = &conn->ctrl; triton_context_register(&conn->ctx, &conn->ppp); + conn->ctx.fname=__FILE__; + conn->ctx.line=__LINE__; triton_md_register_handler(&conn->ctx, &conn->hnd); triton_md_enable_handler(&conn->hnd,MD_MODE_READ); triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); @@ -539,26 +541,26 @@ static void __init pptp_init(void) serv.hnd.fd = socket (PF_INET, SOCK_STREAM, 0); if (serv.hnd.fd < 0) { - log_error("pptp: failed to create server socket: %s\n", strerror(errno)); + log_emerg("pptp: failed to create server socket: %s\n", strerror(errno)); return; } addr.sin_family = AF_INET; addr.sin_port = htons (PPTP_PORT); addr.sin_addr.s_addr = htonl (INADDR_ANY); if (bind (serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { - log_error("pptp: failed to bind socket: %s\n", strerror(errno)); + log_emerg("pptp: failed to bind socket: %s\n", strerror(errno)); close(serv.hnd.fd); return; } if (listen (serv.hnd.fd, 100) < 0) { - log_error("pptp: failed to listen socket: %s\n", strerror(errno)); + log_emerg("pptp: failed to listen socket: %s\n", strerror(errno)); close(serv.hnd.fd); return; } if (fcntl(serv.hnd.fd, F_SETFL, O_NONBLOCK)) { - log_error("pptp: failed to set nonblocking mode: %s\n", strerror(errno)); + log_emerg("pptp: failed to set nonblocking mode: %s\n", strerror(errno)); close(serv.hnd.fd); return; } diff --git a/accel-pptpd/include/mempool.h b/accel-pptpd/include/mempool.h new file mode 120000 index 00000000..2637ab65 --- /dev/null +++ b/accel-pptpd/include/mempool.h @@ -0,0 +1 @@ +../triton/mempool.h
\ No newline at end of file diff --git a/accel-pptpd/log.c b/accel-pptpd/log.c index b0f6d520..60ac57e4 100644 --- a/accel-pptpd/log.c +++ b/accel-pptpd/log.c @@ -34,7 +34,6 @@ struct _log_msg_t }; static int log_level=10; -static int conf_copy = 0; static LIST_HEAD(targets); static mempool_t msg_pool; @@ -48,22 +47,16 @@ static __thread char stat_buf[LOG_MAX_SIZE+1]; static FILE *emerg_file; static FILE *debug_file; -static void *pd_key; - static void _log_free_msg(struct _log_msg_t *msg); static struct log_msg_t *clone_msg(struct _log_msg_t *msg); static int add_msg(struct _log_msg_t *msg, const char *buf); -static struct log_pd_t *find_pd(struct ppp_t *ppp); +//static struct log_pd_t *find_pd(struct ppp_t *ppp); static void write_msg(FILE *f, struct _log_msg_t *msg, struct ppp_t *ppp); static void do_log(int level, const char *fmt, va_list ap, struct ppp_t *ppp) { struct log_target_t *t; struct log_msg_t *m; - struct log_pd_t *lpd; - - if (list_empty(&targets)) - return; vsnprintf(stat_buf, LOG_MAX_SIZE, fmt, ap); @@ -86,33 +79,15 @@ static void do_log(int level, const char *fmt, va_list ap, struct ppp_t *ppp) if (debug_file) write_msg(debug_file, cur_msg, ppp); - if (ppp && !ppp->username) { - lpd = find_pd(ppp); - list_add_tail(&cur_msg->entry, &lpd->msgs); - } - list_for_each_entry(t, &targets, entry) { - if (ppp && ppp->username) { - if (t->session_log) { - m = clone_msg(cur_msg); - if (!m) - break; - t->session_log(ppp, m); - } - } - if (!ppp || conf_copy) { - if (t->log) { - m = clone_msg(cur_msg); - if (!m) - break; - t->log(m); - } - } + m = clone_msg(cur_msg); + if (!m) + break; + t->log(m, ppp); } out: - if (!ppp || ppp->username) - _log_free_msg(cur_msg); + _log_free_msg(cur_msg); cur_msg = NULL; } @@ -226,6 +201,8 @@ void __export log_free_msg(struct log_msg_t *m) { struct _log_msg_t *msg = (struct _log_msg_t *)m->lpd; + //printf("free msg %p\n", m); + mempool_free(m->hdr); _log_free_msg(msg); @@ -272,6 +249,7 @@ static struct log_msg_t *clone_msg(struct _log_msg_t *msg) __sync_add_and_fetch(&msg->refs, 1); + //printf("clone msg %p\n", m); return m; } @@ -298,21 +276,6 @@ static int add_msg(struct _log_msg_t *msg, const char *buf) return 0; } -static struct log_pd_t *find_pd(struct ppp_t *ppp) -{ - struct ppp_pd_t *pd; - struct log_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; - } - } - log_emerg("log:BUG: pd not found\n"); - abort(); -} - static void write_msg(FILE *f, struct _log_msg_t *msg, struct ppp_t *ppp) { struct log_chunk_t *chunk; @@ -329,6 +292,21 @@ static void write_msg(FILE *f, struct _log_msg_t *msg, struct ppp_t *ppp) fflush(f); } +/*static struct log_pd_t *find_pd(struct ppp_t *ppp) +{ + struct ppp_pd_t *pd; + struct log_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; + } + } + log_emerg("log:BUG: pd not found\n"); + abort(); +} + static void ev_ctrl_starting(struct ppp_t *ppp) { struct log_pd_t *lpd = _malloc(sizeof(*lpd)); @@ -414,7 +392,7 @@ static void ev_ppp_authorized(struct ppp_t *ppp) } lpd->authorized = 1; -} +}*/ void __export log_switch(struct triton_context_t *ctx, void *arg) { @@ -444,15 +422,7 @@ static void __init log_init(void) fprintf(stderr, "log:open: %s\n", strerror(errno)); } - opt = conf_get_opt("log", "copy"); - if (opt && atoi(opt) > 0) - conf_copy = 1; - msg_pool = mempool_create(sizeof(struct log_msg_t)); _msg_pool = mempool_create(sizeof(struct _log_msg_t)); chunk_pool = mempool_create(sizeof(struct log_chunk_t) + LOG_CHUNK_SIZE + 1); - - triton_event_register_handler(EV_CTRL_STARTING, (triton_event_func)ev_ctrl_starting); - triton_event_register_handler(EV_CTRL_FINISHED, (triton_event_func)ev_ctrl_finished); - triton_event_register_handler(EV_PPP_AUTHORIZED, (triton_event_func)ev_ppp_authorized); } diff --git a/accel-pptpd/log.h b/accel-pptpd/log.h index ec0e5b73..97894597 100644 --- a/accel-pptpd/log.h +++ b/accel-pptpd/log.h @@ -39,10 +39,7 @@ struct log_target_t { struct list_head entry; - void (*log)(struct log_msg_t *); - void (*session_log)(struct ppp_t *ppp, struct log_msg_t *); - void (*session_start)(struct ppp_t *ppp); - void (*session_stop)(struct ppp_t *ppp); + void (*log)(struct log_msg_t *, struct ppp_t *ppp); }; void log_free_msg(struct log_msg_t *msg); diff --git a/accel-pptpd/logs/CMakeLists.txt b/accel-pptpd/logs/CMakeLists.txt index 4282761b..17ae92d0 100644 --- a/accel-pptpd/logs/CMakeLists.txt +++ b/accel-pptpd/logs/CMakeLists.txt @@ -1,4 +1,4 @@ -ADD_LIBRARY(log_file SHARED log_file.c) +ADD_LIBRARY(log_file SHARED log_file2.c) ADD_LIBRARY(log_pgsql SHARED log_pgsql.c) TARGET_LINK_LIBRARIES(log_pgsql pq) diff --git a/accel-pptpd/logs/log_file.c b/accel-pptpd/logs/log_file.c index f5bded9d..b13f81a4 100644 --- a/accel-pptpd/logs/log_file.c +++ b/accel-pptpd/logs/log_file.c @@ -5,13 +5,19 @@ #include <fcntl.h> #include <unistd.h> #include <limits.h> +#include <aio.h> +#include <sys/signalfd.h> #include "log.h" +#include "events.h" #include "ppp.h" #include "spinlock.h" +#include "mempool.h" #include "memdebug.h" +#define LOG_BUF_SIZE 16*1024 + #define RED_COLOR "\033[1;31m" #define GREEN_COLOR "\033[1;32m" #define YELLOW_COLOR "\033[1;33m" @@ -20,28 +26,29 @@ struct log_file_t { - struct triton_context_t ctx; - struct triton_md_handler_t hnd; + struct list_head entry; struct list_head msgs; - struct log_msg_t *cur_msg; - struct log_chunk_t *cur_chunk; - int cur_pos; spinlock_t lock; - int sleeping:1; int need_free:1; + int queued:1; struct log_file_pd_t *lpd; + + int fd; + off_t offset; }; struct log_file_pd_t { struct ppp_pd_t pd; struct log_file_t lf; + uint64_t tmp; }; 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 const char* level_name[]={" msg", "error", " warn", " info", "debug"}; static const char* level_color[]={NORMAL_COLOR, RED_COLOR, YELLOW_COLOR, GREEN_COLOR, BLUE_COLOR}; @@ -50,175 +57,192 @@ static void *pd_key1; static void *pd_key2; static struct log_file_t *log_file; -static int log_write(struct triton_md_handler_t *h); +static mempool_t lpd_pool; +static char *log_buf; + +static struct aiocb aiocb = { + .aio_lio_opcode = LIO_WRITE, + .aio_sigevent.sigev_notify = SIGEV_SIGNAL, + .aio_sigevent.sigev_signo = SIGIO, +}; + +static LIST_HEAD(lf_queue); +static spinlock_t lf_queue_lock = SPINLOCK_INITIALIZER; +static int lf_queue_sleeping = 1; + +static uint64_t temp_seq; + +static void send_next_chunk(); -static int log_file_init(struct log_file_t *lf, const char *fname) +static void log_file_init(struct log_file_t *lf) { spinlock_init(&lf->lock); - lf->sleeping = 1; INIT_LIST_HEAD(&lf->msgs); - lf->hnd.write = log_write; + lf->fd = -1; +} - lf->hnd.fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - if (lf->hnd.fd < 0) { +static int log_file_open(struct log_file_t *lf, const char *fname) +{ + lf->fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (lf->fd < 0) { log_emerg("log_file: open '%s': %s\n", fname, strerror(errno)); return -1; } - lseek(lf->hnd.fd, 0, SEEK_END); + lf->offset = lseek(lf->fd, 0, SEEK_END); - if (fcntl(lf->hnd.fd, F_SETFL, O_NONBLOCK)) { - log_emerg("log_file: cann't to set nonblocking mode: %s\n", strerror(errno)); - goto out_err; - } - - if (triton_context_register(&lf->ctx, NULL)) - goto out_err; - triton_md_register_handler(&lf->ctx, &lf->hnd); return 0; - -out_err: - close(lf->hnd.fd); - return -1; } -static void set_hdr(struct log_msg_t *msg, struct ppp_t *ppp) +static void sigio(int num, siginfo_t *si, void *uc) { - struct tm tm; - char timestamp[32]; + struct log_file_t *lf; + int n; - localtime_r(&msg->timestamp.tv_sec, &tm); + lf = (struct log_file_t *)si->si_ptr; - strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &tm); - sprintf(msg->hdr->msg, "%s[%s]: %s: %s%s%s", conf_color ? level_color[msg->level] : "", - timestamp, level_name[msg->level], - ppp ? ppp->ifname : "", - ppp ? ": " : "", - conf_color ? NORMAL_COLOR : ""); - msg->hdr->len = strlen(msg->hdr->msg); + n = aio_return(&aiocb); + if (n < 0) + log_emerg("log_file: %s\n", strerror(aio_error(&aiocb))); + else if (n < aiocb.aio_nbytes) + log_emerg("log_file: short write %i %lu\n", n, aiocb.aio_nbytes); + + spin_lock(&lf->lock); + lf->offset += n; + if (list_empty(&lf->msgs) && lf->need_free) { + spin_unlock(&lf->lock); + close(lf->fd); + mempool_free(lf->lpd); + } else + spin_unlock(&lf->lock); + + send_next_chunk(); } -static int write_chunk(int fd, struct log_chunk_t *chunk, int pos) + +static int dequeue_log(struct log_file_t *lf) { - int n; + int n, pos = 0; + struct log_msg_t *msg; + struct log_chunk_t *chunk; while (1) { - n = write(fd, chunk->msg + pos, chunk->len - pos); - if (n < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - return pos; - log_emerg("log_file: write: %s\n", strerror(errno)); - break; + spin_lock(&lf->lock); + if (list_empty(&lf->msgs)) { + lf->queued = 0; + spin_unlock(&lf->lock); + return pos; } + msg = list_entry(lf->msgs.next, typeof(*msg), entry); + list_del(&msg->entry); + spin_unlock(&lf->lock); + + memcpy(log_buf + pos, msg->hdr->msg, msg->hdr->len); + n = msg->hdr->len; + if (pos + n > LOG_BUF_SIZE) + goto overrun; + + list_for_each_entry(chunk, msg->chunks, entry) { + memcpy(log_buf + pos + n, chunk->msg, chunk->len); + n += chunk->len; + if (pos + n > LOG_BUF_SIZE) + goto overrun; + } + + log_free_msg(msg); pos += n; - if (pos == chunk->len) - return 0; - } - return -1; -} -static int write_msg(struct log_file_t *lf) -{ - if (!lf->cur_chunk) - lf->cur_chunk = lf->cur_msg->hdr; - - if (lf->cur_chunk == lf->cur_msg->hdr) { - lf->cur_pos = write_chunk(lf->hnd.fd, lf->cur_chunk, lf->cur_pos); - if (lf->cur_pos < 0) - goto out; - if (lf->cur_pos) - return -1; - lf->cur_chunk = list_entry(lf->cur_msg->chunks->next, typeof(*lf->cur_chunk), entry); } - while(&lf->cur_chunk->entry != lf->cur_msg->chunks) { - lf->cur_pos = write_chunk(lf->hnd.fd, lf->cur_chunk, lf->cur_pos); - if (lf->cur_pos < 0) - break; - if (lf->cur_pos) - return -1; - lf->cur_chunk = list_entry(lf->cur_chunk->entry.next, typeof(*lf->cur_chunk), entry); - } +overrun: + spin_lock(&lf->lock); + list_add(&msg->entry, &lf->msgs); + spin_unlock(&lf->lock); -out: - log_free_msg(lf->cur_msg); - lf->cur_chunk = NULL; - lf->cur_msg = NULL; - lf->cur_pos = 0; - return 0; + spin_lock(&lf_queue_lock); + list_add_tail(&lf->entry, &lf_queue); + spin_unlock(&lf_queue_lock); + + return pos; } -static int log_write(struct triton_md_handler_t *h) +static void send_next_chunk(void) { - struct log_file_t *lf = container_of(h, typeof(*lf), hnd); + struct log_file_t *lf; - if (lf->cur_msg) - if (write_msg(lf)) - return 0; + spin_lock(&lf_queue_lock); + if (list_empty(&lf_queue)) { + lf_queue_sleeping = 1; + spin_unlock(&lf_queue_lock); + return; + } + lf = list_entry(lf_queue.next, typeof(*lf), entry); + list_del(&lf->entry); + spin_unlock(&lf_queue_lock); - while (1) { - spin_lock(&lf->lock); - if (!list_empty(&lf->msgs)) { - lf->cur_msg = list_entry(lf->msgs.next, typeof(*lf->cur_msg), entry); - list_del(&lf->cur_msg->entry); - spin_unlock(&lf->lock); + aiocb.aio_fildes = lf->fd; + aiocb.aio_offset = lf->offset; + aiocb.aio_sigevent.sigev_value.sival_ptr = lf; + aiocb.aio_nbytes = dequeue_log(lf); - if (write_msg(lf)) - return 0; - - continue; - } - if (lf->need_free) { - spin_unlock(&lf->lock); - triton_md_unregister_handler(&lf->hnd); - close(lf->hnd.fd); - triton_context_unregister(&lf->ctx); - _free(lf->lpd); - return 1; - } - lf->sleeping = 1; - spin_unlock(&lf->lock); - triton_md_disable_handler(&lf->hnd, MD_MODE_WRITE); - return 0; - } + if (aio_write(&aiocb)) + log_emerg("log_file: aio_write: %s\n", strerror(errno)); } -static void log_wakeup(struct log_file_t *lf) +static void queue_lf(struct log_file_t *lf) { - if (log_write(&lf->hnd)) - return ; + int r; + + spin_lock(&lf_queue_lock); + list_add_tail(&lf->entry, &lf_queue); + r = lf_queue_sleeping; + lf_queue_sleeping = 0; + spin_unlock(&lf_queue_lock); - if (!lf->sleeping) - triton_md_enable_handler(&lf->hnd, MD_MODE_WRITE); + if (r) + send_next_chunk(); } -static void log_queue(struct log_file_t *lf, struct log_msg_t *msg) +static void queue_log(struct log_file_t *lf, struct log_msg_t *msg) { int r; + spin_lock(&lf->lock); list_add_tail(&msg->entry, &lf->msgs); - r = lf->sleeping; - lf->sleeping = 0; + if (lf->fd != -1) { + r = lf->queued; + lf->queued = 1; + } else + r = 1; spin_unlock(&lf->lock); - if (r) - triton_context_call(&lf->ctx, (void (*)(void *))log_wakeup, lf); + if (!r) + queue_lf(lf); } -static void general_log(struct log_msg_t *msg) +static void set_hdr(struct log_msg_t *msg, struct ppp_t *ppp) { - if (!log_file) - return; - set_hdr(msg, NULL); - log_queue(log_file, msg); + struct tm tm; + char timestamp[32]; + + localtime_r(&msg->timestamp.tv_sec, &tm); + + strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &tm); + sprintf(msg->hdr->msg, "%s[%s]: %s: %s%s%s", conf_color ? level_color[msg->level] : "", + timestamp, level_name[msg->level], + ppp ? ppp->ifname : "", + ppp ? ": " : "", + conf_color ? NORMAL_COLOR : ""); + msg->hdr->len = strlen(msg->hdr->msg); } -static void general_session_log(struct ppp_t *ppp, struct log_msg_t *msg) +static void general_log(struct log_msg_t *msg, struct ppp_t *ppp) { - if (!log_file) + if (ppp && !conf_copy) { + log_free_msg(msg); return; + } + set_hdr(msg, ppp); - log_queue(log_file, msg); + queue_log(log_file, msg); } static struct log_file_pd_t *find_pd(struct ppp_t *ppp, void *pd_key) @@ -237,48 +261,200 @@ static struct log_file_pd_t *find_pd(struct ppp_t *ppp, void *pd_key) return NULL; } -static void session_log(struct ppp_t *ppp, struct log_msg_t *msg, void *pd_key) +static void per_user_log(struct log_msg_t *msg, struct ppp_t *ppp) +{ + struct log_file_pd_t *lpd; + + if (!ppp) { + log_free_msg(msg); + return; + } + + lpd = find_pd(ppp, &pd_key1); + + if (!lpd) { + log_free_msg(msg); + return; + } + + set_hdr(msg, ppp); + queue_log(&lpd->lf, msg); +} + +static void per_session_log(struct log_msg_t *msg, struct ppp_t *ppp) { - struct log_file_pd_t *lpd = find_pd(ppp, pd_key); + struct log_file_pd_t *lpd; + + if (!ppp) { + log_free_msg(msg); + return; + } - if (!lpd) + lpd = find_pd(ppp, &pd_key2); + + if (!lpd) { + log_free_msg(msg); return; + } set_hdr(msg, ppp); - log_queue(&lpd->lf, msg); + queue_log(&lpd->lf, msg); } -static void per_user_session_log(struct ppp_t *ppp, struct log_msg_t *msg) +static void free_lpd(struct log_file_pd_t *lpd) { - session_log(ppp, msg, &pd_key1); + struct log_msg_t *msg; + + spin_lock(&lpd->lf.lock); + lpd->lf.need_free = 1; + if (lpd->lf.queued) + spin_unlock(&lpd->lf.lock); + else { + while (!list_empty(&lpd->lf.msgs)) { + msg = list_entry(lpd->lf.msgs.next, typeof(*msg), entry); + list_del(&msg->entry); + log_free_msg(msg); + } + if (lpd->lf.fd != -1) + close(lpd->lf.fd); + spin_unlock(&lpd->lf.lock); + mempool_free(lpd); + } } -static void per_session_log(struct ppp_t *ppp, struct log_msg_t *msg) +static void ev_ctrl_started(struct ppp_t *ppp) { - session_log(ppp, msg, &pd_key2); + struct log_file_pd_t *lpd; + char *fname; + + if (conf_per_user_dir) { + lpd = mempool_alloc(lpd_pool); + if (!lpd) { + log_emerg("log_file: out of memory\n"); + return; + } + memset(lpd, 0, sizeof(*lpd)); + lpd->pd.key = &pd_key1; + log_file_init(&lpd->lf); + lpd->lf.lpd = lpd; + list_add_tail(&lpd->pd.entry, &ppp->pd_list); + } + + if (conf_per_session_dir) { + lpd = mempool_alloc(lpd_pool); + if (!lpd) { + log_emerg("log_file: out of memory\n"); + return; + } + memset(lpd, 0, sizeof(*lpd)); + lpd->pd.key = &pd_key2; + log_file_init(&lpd->lf); + lpd->lf.lpd = lpd; + + fname = _malloc(PATH_MAX); + if (!fname) { + mempool_free(lpd); + log_emerg("log_file: out of memory\n"); + return; + } + + lpd->tmp = __sync_fetch_and_add(&temp_seq, 1); + strcpy(fname, conf_per_session_dir); + strcat(fname, "/tmp"); + sprintf(fname + strlen(fname), "%lu", lpd->tmp); + + if (log_file_open(&lpd->lf, fname)) { + mempool_free(lpd); + _free(fname); + return; + } + + _free(fname); + + list_add_tail(&lpd->pd.entry, &ppp->pd_list); + } } -static void per_user_session_start(struct ppp_t *ppp) +static void ev_ctrl_finished(struct ppp_t *ppp) { struct log_file_pd_t *lpd; char *fname; + + lpd = find_pd(ppp, &pd_key1); + if (lpd) + free_lpd(lpd); + + + lpd = find_pd(ppp, &pd_key2); + if (lpd) { + if (lpd->tmp) { + fname = _malloc(PATH_MAX); + if (fname) { + strcpy(fname, conf_per_session_dir); + strcat(fname, "/tmp"); + sprintf(fname + strlen(fname), "%lu", lpd->tmp); + if (unlink(fname)) + log_emerg("log_file: unlink '%s': %s\n", fname, strerror(errno)); + _free(fname); + } else + log_emerg("log_file: out of memory\n"); + } + free_lpd(lpd); + } +} + +static void ev_ppp_starting(struct ppp_t *ppp) +{ + struct log_file_pd_t *lpd; + char *fname1, *fname2; + + lpd = find_pd(ppp, &pd_key2); + if (!lpd) + return; - fname = _malloc(PATH_MAX + 32); - if (!fname) { + fname1 = _malloc(PATH_MAX); + if (!fname1) { log_emerg("log_file: out of memory\n"); return; } - lpd = _malloc(sizeof(*lpd)); - if (!lpd) { + fname2 = _malloc(PATH_MAX); + if (!fname2) { log_emerg("log_file: out of memory\n"); - goto out_err; + _free(fname1); + return; + } + + strcpy(fname1, conf_per_session_dir); + strcat(fname1, "/tmp"); + sprintf(fname1 + strlen(fname1), "%lu", lpd->tmp); + + strcpy(fname2, conf_per_session_dir); + strcat(fname2, "/"); + strcat(fname2, ppp->sessionid); + strcat(fname2, ".log"); + + if (rename(fname1, fname2)) + log_emerg("log_file: rename '%s' to '%s': %s\n", fname1, fname2, strerror(errno)); + + _free(fname1); + _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; } - - memset(lpd, 0, sizeof(*lpd)); - lpd->pd.key = &pd_key1; - lpd->lf.hnd.fd = -1; - lpd->lf.lpd = lpd; strcpy(fname, conf_per_user_dir); strcat(fname, "/"); @@ -293,123 +469,71 @@ static void per_user_session_start(struct ppp_t *ppp) } strcat(fname, ".log"); - if (log_file_init(&lpd->lf, fname)) + if (log_file_open(&lpd->lf, fname)) goto out_err; - - list_add_tail(&lpd->pd.entry, &ppp->pd_list); _free(fname); - return; -out_err: - _free(fname); - if (lpd) - _free(lpd); -} -static void per_session_start(struct ppp_t *ppp) -{ - struct log_file_pd_t *lpd; - char *fname; - - fname = _malloc(PATH_MAX + 32); - if (!fname) { - log_emerg("log_file: out of memory\n"); - return; - } - - lpd = _malloc(sizeof(*lpd)); - if (!lpd) { - log_emerg("log_file: out of memory\n"); - goto out_err; + if (!list_empty(&lpd->lf.msgs)) { + lpd->lf.queued = 1; + queue_lf(&lpd->lf); } - - memset(lpd, 0, sizeof(*lpd)); - lpd->pd.key = &pd_key2; - lpd->lf.hnd.fd = -1; - lpd->lf.lpd = lpd; - - strcpy(fname, conf_per_session_dir); - strcat(fname, "/"); - strcat(fname, ppp->sessionid); - strcat(fname, ".log"); - - if (log_file_init(&lpd->lf, fname)) - goto out_err; - - list_add_tail(&lpd->pd.entry, &ppp->pd_list); - _free(fname); return; out_err: _free(fname); - if (lpd) - _free(lpd); -} - -static void session_stop(struct ppp_t *ppp, void *pd_key) -{ - struct log_file_pd_t *lpd = find_pd(ppp, pd_key); - int r; - - spin_lock(&lpd->lf.lock); - r = lpd->lf.sleeping; - lpd->lf.sleeping = 0; - lpd->lf.need_free = 1; - spin_unlock(&lpd->lf.lock); - - if (r) - triton_context_call(&lpd->lf.ctx, (void (*)(void *))log_wakeup, &lpd->lf); + list_del(&lpd->pd.entry); + free_lpd(lpd); } -static void per_user_session_stop(struct ppp_t *ppp) -{ - session_stop(ppp, &pd_key1); -} - -static void per_session_stop(struct ppp_t *ppp) -{ - session_stop(ppp, &pd_key2); -} - -static struct log_target_t target = +static struct log_target_t general_target = { .log = general_log, }; static struct log_target_t per_user_target = { - .session_log = per_user_session_log, - .session_start = per_user_session_start, - .session_stop = per_user_session_stop, + .log = per_user_log, }; static struct log_target_t per_session_target = { - .session_log = per_session_log, - .session_start = per_session_start, - .session_stop = per_session_stop, + .log = per_session_log, }; - static void __init init(void) { char *opt; - - opt = conf_get_opt("log","color"); - if (opt && atoi(opt) > 0) - conf_color = 1; - + struct sigaction sa = { + .sa_sigaction = sigio, + .sa_flags = SA_SIGINFO, + }; + + lpd_pool = mempool_create(sizeof(struct log_file_pd_t)); + log_buf = malloc(LOG_BUF_SIZE); + aiocb.aio_buf = log_buf; + + if (sigaction(SIGIO, &sa, NULL)) { + log_emerg("log_file: sigaction: %s\n", strerror(errno)); + return; + } + opt = conf_get_opt("log", "log-file"); if (opt) { - log_file = _malloc(sizeof(*log_file)); + log_file = malloc(sizeof(*log_file)); memset(log_file, 0, sizeof(*log_file)); - if (log_file_init(log_file, opt)) { - _free(log_file); - log_file = NULL; + log_file_init(log_file); + if (log_file_open(log_file, opt)) { + free(log_file); + _exit(EXIT_FAILURE); } } + opt = conf_get_opt("log","color"); + if (opt && atoi(opt) > 0) + conf_color = 1; + opt = conf_get_opt("log", "per-user-dir"); if (opt) conf_per_user_dir = opt; @@ -421,17 +545,22 @@ static void __init init(void) opt = conf_get_opt("log", "per-session"); if (opt && atoi(opt) > 0) conf_per_session = 1; + + opt = conf_get_opt("log", "copy"); + if (opt && atoi(opt) > 0) + conf_copy = 1; + log_register_target(&general_target); + if (conf_per_user_dir) log_register_target(&per_user_target); if (conf_per_session_dir) log_register_target(&per_session_target); - - if (log_file) { - if (!conf_per_user_dir && !conf_per_session_dir) - target.session_log = general_session_log; - log_register_target(&target); - } + + 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); } diff --git a/accel-pptpd/logs/log_pgsql.c b/accel-pptpd/logs/log_pgsql.c index f9cf7ed2..393c3bdc 100644 --- a/accel-pptpd/logs/log_pgsql.c +++ b/accel-pptpd/logs/log_pgsql.c @@ -161,13 +161,7 @@ static void queue_log(struct log_msg_t *msg) } -static void general_log(struct log_msg_t *msg) -{ - set_hdr(msg, NULL); - queue_log(msg); -} - -static void session_log(struct ppp_t *ppp, struct log_msg_t *msg) +static void general_log(struct log_msg_t *msg, struct ppp_t *ppp) { set_hdr(msg, ppp); queue_log(msg); @@ -238,7 +232,6 @@ static void start_connect_timer(struct triton_timer_t *t) static struct log_target_t target = { .log = general_log, - .session_log = session_log, }; static void __init init(void) diff --git a/accel-pptpd/main.c b/accel-pptpd/main.c index 147c248c..afd6b588 100644 --- a/accel-pptpd/main.c +++ b/accel-pptpd/main.c @@ -14,10 +14,6 @@ static int goto_daemon; static char *pid_file; static char *conf_file; -static void sigterm(int num) -{ -} - #define ARG_MAX 128 static int parse_cmdline(char ***argv) { @@ -87,6 +83,7 @@ usage: int main(int argc, char **argv) { sigset_t set; + int sig; if (triton_load_modules("modules")) return EXIT_FAILURE; @@ -119,21 +116,34 @@ int main(int argc, char **argv) } } - signal(SIGTERM, sigterm); - signal(SIGPIPE, sigterm); - signal(SIGUSR1, sigterm); - + //signal(SIGTERM, sigterm); + //signal(SIGPIPE, sigterm); + triton_run(); - + sigfillset(&set); - sigdelset(&set, SIGINT); - sigdelset(&set, SIGTERM); + sigdelset(&set, SIGKILL); + sigdelset(&set, SIGSTOP); sigdelset(&set, SIGSEGV); - sigdelset(&set, SIGILL); sigdelset(&set, SIGFPE); + sigdelset(&set, SIGILL); sigdelset(&set, SIGBUS); - - sigsuspend(&set); + sigdelset(&set, 35); + sigdelset(&set, 36); + sigdelset(&set, SIGIO); + sigdelset(&set, SIGINT); + pthread_sigmask(SIG_SETMASK, &set, NULL); + + sigemptyset(&set); + //sigaddset(&set, SIGINT); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGSEGV); + sigaddset(&set, SIGILL); + sigaddset(&set, SIGFPE); + sigaddset(&set, SIGBUS); + + sigwait(&set, &sig); + printf("terminate, sig = %i\n", sig); triton_terminate(); diff --git a/accel-pptpd/radius/dict/dictionary.rfc2865 b/accel-pptpd/radius/dict/dictionary.rfc2865 index 3abe1b2b..7e5bf583 100644 --- a/accel-pptpd/radius/dict/dictionary.rfc2865 +++ b/accel-pptpd/radius/dict/dictionary.rfc2865 @@ -6,7 +6,7 @@ # $Id: dictionary.rfc2865,v 1.3 2005/08/10 20:59:40 aland Exp $ # ATTRIBUTE User-Name 1 string -ATTRIBUTE User-Password 2 string encrypt=1 +ATTRIBUTE User-Password 2 octets ATTRIBUTE CHAP-Password 3 octets ATTRIBUTE NAS-IP-Address 4 ipaddr ATTRIBUTE NAS-Port 5 integer diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c index ac41f199..6b812f11 100644 --- a/accel-pptpd/radius/req.c +++ b/accel-pptpd/radius/req.c @@ -173,10 +173,11 @@ out_err: static void req_wakeup(struct rad_req_t *req) { - triton_context_wakeup(req->rpd->ppp->ctrl->ctx); + struct triton_context_t *ctx = req->rpd->ppp->ctrl->ctx; triton_timer_del(&req->timeout); triton_md_unregister_handler(&req->hnd); triton_context_unregister(&req->ctx); + triton_context_wakeup(ctx); } static int rad_req_read(struct triton_md_handler_t *h) { @@ -200,6 +201,8 @@ int rad_req_wait(struct rad_req_t *req, int timeout) req->timeout.expire = rad_req_timeout; triton_context_register(&req->ctx, req->rpd->ppp); + req->ctx.fname=__FILE__; + req->ctx.line=__LINE__; triton_md_register_handler(&req->ctx, &req->hnd); if (triton_md_enable_handler(&req->hnd, MD_MODE_READ)) return -1; diff --git a/accel-pptpd/sigchld.c b/accel-pptpd/sigchld.c index 3843e4f7..fd07c0a6 100644 --- a/accel-pptpd/sigchld.c +++ b/accel-pptpd/sigchld.c @@ -27,19 +27,11 @@ static void* sigchld_thread(void *arg) int status, sig; sigfillset(&set); + sigdelset(&set, SIGKILL); + sigdelset(&set, SIGSTOP); pthread_sigmask(SIG_BLOCK, &set, NULL); sigemptyset(&set); - sigaddset(&set, SIGUSR1); - sigaddset(&set, SIGQUIT); - sigaddset(&set, SIGSEGV); - sigaddset(&set, SIGFPE); - sigaddset(&set, SIGILL); - sigaddset(&set, SIGBUS); - sigaddset(&set, SIGCHLD); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); - - sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGQUIT); diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c index 06b2b30b..133abe80 100644 --- a/accel-pptpd/triton/md.c +++ b/accel-pptpd/triton/md.c @@ -59,24 +59,16 @@ static void *md_thread(void *arg) sigset_t set; sigfillset(&set); + sigdelset(&set, SIGKILL); + sigdelset(&set, SIGSTOP); pthread_sigmask(SIG_BLOCK, &set, NULL); - sigemptyset(&set); - sigaddset(&set, SIGQUIT); - sigaddset(&set, SIGSEGV); - sigaddset(&set, SIGFPE); - sigaddset(&set, SIGILL); - sigaddset(&set, SIGBUS); - sigdelset(&set, 35); - sigdelset(&set, 36); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); - while(1) { n = epoll_wait(epoll_fd, epoll_events, max_events, -1); if (n < 0) { if (errno == EINTR) continue; - triton_log_error("md:epoll_wait: %s", strerror(errno)); + triton_log_error("md:epoll_wait: %s\n", strerror(errno)); _exit(-1); } @@ -152,8 +144,10 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode) else r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->ud->fd, &h->epoll_event); - if (r) - triton_log_error("md:epoll_ctl: %s",strerror(errno)); + if (r) { + triton_log_error("md:epoll_ctl: %s\n",strerror(errno)); + abort(); + } return r; } @@ -177,8 +171,10 @@ int __export triton_md_disable_handler(struct triton_md_handler_t *ud,int mode) r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->ud->fd, NULL); } - if (r) - triton_log_error("md:epoll_ctl: %s",strerror(errno)); + if (r) { + triton_log_error("md:epoll_ctl: %s\n",strerror(errno)); + abort(); + } return r; } diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c index 53abd3b9..cbf2b13d 100644 --- a/accel-pptpd/triton/timer.c +++ b/accel-pptpd/triton/timer.c @@ -60,16 +60,10 @@ void *timer_thread(void *arg) sigset_t set; sigfillset(&set); + sigdelset(&set, SIGKILL); + sigdelset(&set, SIGSTOP); pthread_sigmask(SIG_BLOCK, &set, NULL); - sigemptyset(&set); - sigaddset(&set, SIGQUIT); - sigaddset(&set, SIGSEGV); - sigaddset(&set, SIGFPE); - sigaddset(&set, SIGILL); - sigaddset(&set, SIGBUS); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); - while(1) { n = epoll_wait(epoll_fd, epoll_events, max_events, -1); if (n < 0) { diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index 95930647..2de2e67b 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -8,7 +8,7 @@ #include "triton_p.h" #include "memdebug.h" -int thread_count = 1; +int thread_count = 2; int max_events = 64; static spinlock_t threads_lock = SPINLOCK_INITIALIZER; @@ -25,46 +25,75 @@ static int terminate; static mempool_t *ctx_pool; static mempool_t *call_pool; +static mempool_t *ctx_stack_pool; __export struct triton_stat_t triton_stat; void triton_thread_wakeup(struct _triton_thread_t *thread) { + //printf("wake up thread %p\n", thread); pthread_kill(thread->thread, SIGUSR1); } static void* triton_thread(struct _triton_thread_t *thread) { sigset_t set; + int sig; sigfillset(&set); - sigdelset(&set, SIGSEGV); - sigdelset(&set, SIGFPE); - sigdelset(&set, SIGILL); - sigdelset(&set, SIGBUS); - pthread_sigmask(SIG_SETMASK, &set, NULL); + sigdelset(&set, SIGKILL); + sigdelset(&set, SIGSTOP); + pthread_sigmask(SIG_BLOCK, &set, NULL); - sigdelset(&set, SIGUSR1); - sigdelset(&set, SIGQUIT); + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGQUIT); while (1) { __sync_fetch_and_sub(&triton_stat.thread_active, 1); - sigsuspend(&set); + //printf("thread %p: enter sigwait\n", thread); + sigwait(&set, &sig); + //printf("thread %p: exit sigwait\n", thread); __sync_fetch_and_add(&triton_stat.thread_active, 1); cont: + //printf("thread %p: ctx=%p %p\n", thread, thread->ctx, thread->ctx ? thread->ctx->thread : NULL); if (thread->ctx->ud->before_switch) thread->ctx->ud->before_switch(thread->ctx->ud, thread->ctx->bf_arg); - if (swapcontext(&thread->uctx, &thread->ctx->uctx)) - triton_log_error("swapcontext: %s\n", strerror(errno)); - - if (thread->ctx->need_free) - mempool_free(thread->ctx); + + //printf("thread %p: switch to %p\n", thread, thread->ctx); + while (1) { + if (swapcontext(&thread->uctx, &thread->ctx->uctx)) { + if (errno == EINTR) + continue; + triton_log_error("swapcontext: %s\n", strerror(errno)); + } else + break; + } + //printf("thread %p: switch from %p %p\n", thread, thread->ctx, thread->ctx->thread); + + if (thread->ctx->thread) { + spin_lock(&thread->ctx->lock); + if (thread->ctx->pending) { + spin_unlock(&thread->ctx->lock); + goto cont; + } + thread->ctx->thread = NULL; + spin_unlock(&thread->ctx->lock); + + if (thread->ctx->need_free) { + //printf("- context %p removed\n", thread->ctx); + mempool_free(thread->ctx->uctx.uc_stack.ss_sp); + mempool_free(thread->ctx); + } + } + thread->ctx = NULL; spin_lock(&threads_lock); if (!list_empty(&ctx_queue)) { thread->ctx = list_entry(ctx_queue.next, typeof(*thread->ctx), entry2); + //printf("thread: %p: dequeued ctx %p\n", thread, thread->ctx); list_del(&thread->ctx->entry2); spin_unlock(&threads_lock); spin_lock(&thread->ctx->lock); @@ -74,6 +103,7 @@ cont: __sync_fetch_and_sub(&triton_stat.context_pending, 1); goto cont; } else { + //printf("thread: %p: sleeping\n", thread); if (!terminate) list_add(&thread->entry2, &sleep_threads); spin_unlock(&threads_lock); @@ -89,10 +119,9 @@ static void ctx_thread(struct _triton_context_t *ctx) struct _triton_timer_t *t; struct _triton_ctx_call_t *call; uint64_t tt; - ucontext_t *uctx; while (1) { - uctx = &ctx->thread->uctx; + //printf("ctx %p %p: enter\n", ctx, ctx->thread); if (ctx->need_close) { if (ctx->ud->close) ctx->ud->close(ctx->ud); @@ -131,11 +160,19 @@ static void ctx_thread(struct _triton_context_t *ctx) call->func(call->arg); mempool_free(call); } - ctx->thread = NULL; + ctx->pending = 0; spin_unlock(&ctx->lock); - - if (swapcontext(&ctx->uctx, uctx)) + break; + } + + //printf("ctx %p %p: exit\n", ctx, ctx->thread); + while (1) { + if (swapcontext(&ctx->uctx, &ctx->thread->uctx)) { + if (errno == EINTR) + continue; triton_log_error("swapcontext: %s\n", strerror(errno)); + } else + break; } } } @@ -160,6 +197,7 @@ struct _triton_thread_t *create_thread() int triton_queue_ctx(struct _triton_context_t *ctx) { + ctx->pending = 1; if (ctx->thread || ctx->queued || ctx->sleeping) return 0; @@ -168,12 +206,14 @@ int triton_queue_ctx(struct _triton_context_t *ctx) list_add_tail(&ctx->entry2, &ctx_queue); spin_unlock(&threads_lock); ctx->queued = 1; + //printf("ctx %p: queued\n", ctx); __sync_fetch_and_add(&triton_stat.context_pending, 1); return 0; } ctx->thread = list_entry(sleep_threads.next, typeof(*ctx->thread), entry2); ctx->thread->ctx = ctx; + //printf("ctx %p: assigned to thread %p\n", ctx, ctx->thread); list_del(&ctx->thread->entry2); spin_unlock(&threads_lock); @@ -204,12 +244,13 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg) } ctx->uctx.uc_stack.ss_size = CTX_STACK_SIZE; - ctx->uctx.uc_stack.ss_sp = _malloc(CTX_STACK_SIZE); + ctx->uctx.uc_stack.ss_sp = mempool_alloc(ctx_stack_pool); if (!ctx->uctx.uc_stack.ss_sp) { triton_log_error("out of memory\n"); _free(ctx); return -1; } + sigfillset(&ctx->uctx.uc_sigmask); makecontext(&ctx->uctx, (void (*)())ctx_thread, 1, ctx); ud->tpd = ctx; @@ -223,6 +264,15 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg) return 0; } +int __export triton_context_print() +{ + struct _triton_context_t *ctx; + + list_for_each_entry(ctx, &ctx_list, entry) + if (ctx->ud) + printf("%s:%i\n", ctx->ud->fname, ctx->ud->line); +} + void __export triton_context_unregister(struct triton_context_t *ud) { struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; @@ -244,14 +294,6 @@ void __export triton_context_unregister(struct triton_context_t *ud) } if (!list_empty(&ctx->timers)) { triton_log_error("BUG:ctx:triton_unregister_ctx: timers is not empty"); - { - struct _triton_timer_t *t; - while(!list_empty(&ctx->timers)) { - t = list_entry(ctx->timers.next, typeof(*t), entry); - t->ud->expire(t->ud); - list_del(&t->entry); - } - } abort(); } if (!list_empty(&ctx->pending_timers)) { @@ -259,8 +301,6 @@ void __export triton_context_unregister(struct triton_context_t *ud) abort(); } - _free(ctx->uctx.uc_stack.ss_sp); - ctx->need_free = 1; spin_lock(&ctx_list_lock); list_del(&ctx->entry); @@ -278,18 +318,28 @@ void __export triton_context_schedule(struct triton_context_t *ud) ctx->thread = NULL; spin_unlock(&ctx->lock); - if (swapcontext(&ctx->uctx, uctx)) - triton_log_error("swaswpntext: %s\n", strerror(errno)); + while (1) { + if (swapcontext(&ctx->uctx, uctx)) { + if (errno == EINTR) + continue; + triton_log_error("swaswpntext: %s\n", strerror(errno)); + } else + break; + } __sync_fetch_and_add(&triton_stat.context_sleeping, 1); } -void __export triton_context_wakeup(struct triton_context_t *ud) +int __export triton_context_wakeup(struct triton_context_t *ud) { struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; int r; spin_lock(&ctx->lock); + if (!ctx->sleeping) { + spin_unlock(&ctx->lock); + return -1; + } ctx->sleeping = 0; r = triton_queue_ctx(ctx); spin_unlock(&ctx->lock); @@ -298,6 +348,8 @@ void __export triton_context_wakeup(struct triton_context_t *ud) triton_thread_wakeup(ctx->thread); __sync_fetch_and_sub(&triton_stat.context_sleeping, 1); + + return 0; } int __export triton_context_call(struct triton_context_t *ud, void (*func)(void *), void *arg) @@ -327,12 +379,9 @@ int __export triton_init(const char *conf_file) { ctx_pool = mempool_create(sizeof(struct _triton_context_t)); call_pool = mempool_create(sizeof(struct _triton_ctx_call_t)); + ctx_stack_pool = mempool_create(CTX_STACK_SIZE); default_ctx = _malloc(sizeof(*default_ctx)); - if (!default_ctx) { - fprintf(stderr,"cann't allocate memory\n"); - return -1; - } triton_context_register(default_ctx, NULL); if (conf_load(conf_file)) @@ -365,6 +414,11 @@ void __export triton_run() { struct _triton_thread_t *t; int i; + char *opt; + + opt = conf_get_opt("core", "thread-count"); + if (opt && atoi(opt) > 0) + thread_count = atoi(opt); for(i = 0; i < thread_count; i++) { t = create_thread(); diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h index c3c9d2a9..6f702759 100644 --- a/accel-pptpd/triton/triton.h +++ b/accel-pptpd/triton/triton.h @@ -8,7 +8,9 @@ struct triton_context_t { - const void *tpd; // triton private data, don't touch! + const void *tpd; // triton private data, don't touch + const char *fname; + int line; void (*close)(struct triton_context_t*); void (*free)(struct triton_context_t*); void (*before_switch)(struct triton_context_t *ctx, void *arg); @@ -69,7 +71,7 @@ extern struct triton_stat_t triton_stat; int triton_context_register(struct triton_context_t *, void *arg); void triton_context_unregister(struct triton_context_t *); void triton_context_schedule(struct triton_context_t *); -void triton_context_wakeup(struct triton_context_t *); +int triton_context_wakeup(struct triton_context_t *); int triton_context_call(struct triton_context_t *, void (*func)(void *), void *arg); #define MD_MODE_READ 1 diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h index ec2eb840..7c0615f7 100644 --- a/accel-pptpd/triton/triton_p.h +++ b/accel-pptpd/triton/triton_p.h @@ -42,6 +42,7 @@ struct _triton_context_t int sleeping:1; int need_close:1; int need_free:1; + int pending:1; struct triton_context_t *ud; void *bf_arg; |