summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2010-09-22 22:53:59 +0400
committerDmitry Kozlov <xeb@mail.ru>2010-09-22 22:53:59 +0400
commit3e61cb3f8d58f64c8023e95bf74341e6bc61560e (patch)
treed73a44bf63044e35e8c3b1088598fc29e95a30b9
parentb96fbc3f966b012720d2b74b1dfd2a0ab95086cf (diff)
downloadaccel-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.txt2
-rw-r--r--accel-pptpd/accel-pptpd.conf12
-rw-r--r--accel-pptpd/ctrl/pptp.c10
l---------accel-pptpd/include/mempool.h1
-rw-r--r--accel-pptpd/log.c80
-rw-r--r--accel-pptpd/log.h5
-rw-r--r--accel-pptpd/logs/CMakeLists.txt2
-rw-r--r--accel-pptpd/logs/log_file.c595
-rw-r--r--accel-pptpd/logs/log_pgsql.c9
-rw-r--r--accel-pptpd/main.c38
-rw-r--r--accel-pptpd/radius/dict/dictionary.rfc28652
-rw-r--r--accel-pptpd/radius/req.c5
-rw-r--r--accel-pptpd/sigchld.c12
-rw-r--r--accel-pptpd/triton/md.c26
-rw-r--r--accel-pptpd/triton/timer.c10
-rw-r--r--accel-pptpd/triton/triton.c128
-rw-r--r--accel-pptpd/triton/triton.h6
-rw-r--r--accel-pptpd/triton/triton_p.h1
18 files changed, 545 insertions, 399 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt
index ee00a28..3de0072 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 230ddba..965d9bc 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 b8bb366..9f76a34 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 0000000..2637ab6
--- /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 b0f6d52..60ac57e 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 ec0e5b7..9789459 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 4282761..17ae92d 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 f5bded9..b13f81a 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 f9cf7ed..393c3bd 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 147c248..afd6b58 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 3abe1b2..7e5bf58 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 ac41f19..6b812f1 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 3843e4f..fd07c0a 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 06b2b30..133abe8 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 53abd3b..cbf2b13 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 9593064..2de2e67 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 c3c9d2a..6f70275 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 ec2eb84..7c0615f 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;