summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-03-09 17:09:25 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-03-09 17:09:25 +0300
commit3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3 (patch)
treef9eceb3c7cabed463f4ed009484d77e05baaf2c8
parent8cc93b54959dc754b70698a2b397b3406dd7928e (diff)
downloadrspamd-3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3.tar.gz
rspamd-3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3.zip
* Add monitoring for cdb
-rw-r--r--src/cdb/cdb.h124
-rw-r--r--src/cdb/cdb_init.c52
-rw-r--r--src/lua/lua_cdb.c13
3 files changed, 126 insertions, 63 deletions
diff --git a/src/cdb/cdb.h b/src/cdb/cdb.h
index 5802da4d5..f61d51334 100644
--- a/src/cdb/cdb.h
+++ b/src/cdb/cdb.h
@@ -21,15 +21,19 @@ unsigned cdb_hash(const void *buf, unsigned len);
unsigned cdb_unpack(const unsigned char buf[4]);
void cdb_pack(unsigned num, unsigned char buf[4]);
-struct cdb {
- int cdb_fd; /* file descriptor */
- char *filename; /* file name */
- /* private members */
- unsigned cdb_fsize; /* datafile size */
- unsigned cdb_dend; /* end of data ptr */
- const unsigned char *cdb_mem; /* mmap'ed file memory */
- unsigned cdb_vpos, cdb_vlen; /* found data */
- unsigned cdb_kpos, cdb_klen; /* found key */
+struct cdb
+{
+ int cdb_fd; /* file descriptor */
+ char *filename; /* file name */
+ time_t mtime; /* mtime of cdb file */
+ struct event *check_timer_ev; /* event structure for checking cdb for modifications */
+ struct timeval *check_timer_tv;
+ /* private members */
+ unsigned cdb_fsize; /* datafile size */
+ unsigned cdb_dend; /* end of data ptr */
+ const unsigned char *cdb_mem; /* mmap'ed file memory */
+ unsigned cdb_vpos, cdb_vlen; /* found data */
+ unsigned cdb_kpos, cdb_klen; /* found key */
};
#define CDB_STATIC_INIT {0,0,0,0,0,0,0,0}
@@ -41,10 +45,10 @@ struct cdb {
#define cdb_fileno(c) ((c)->cdb_fd)
int cdb_init(struct cdb *cdbp, int fd);
+void cdb_add_timer(struct cdb *cdbp, unsigned seconds);
void cdb_free(struct cdb *cdbp);
-int cdb_read(const struct cdb *cdbp,
- void *buf, unsigned len, unsigned pos);
+int cdb_read(const struct cdb *cdbp, void *buf, unsigned len, unsigned pos);
#define cdb_readdata(cdbp, buf) \
cdb_read((cdbp), (buf), cdb_datalen(cdbp), cdb_datapos(cdbp))
#define cdb_readkey(cdbp, buf) \
@@ -58,17 +62,18 @@ const void *cdb_get(const struct cdb *cdbp, unsigned len, unsigned pos);
int cdb_find(struct cdb *cdbp, const void *key, unsigned klen);
-struct cdb_find {
- struct cdb *cdb_cdbp;
- unsigned cdb_hval;
- const unsigned char *cdb_htp, *cdb_htab, *cdb_htend;
- unsigned cdb_httodo;
- const void *cdb_key;
- unsigned cdb_klen;
+struct cdb_find
+{
+ struct cdb *cdb_cdbp;
+ unsigned cdb_hval;
+ const unsigned char *cdb_htp, *cdb_htab, *cdb_htend;
+ unsigned cdb_httodo;
+ const void *cdb_key;
+ unsigned cdb_klen;
};
-int cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
- const void *key, unsigned klen);
+int cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp, const void *key,
+ unsigned klen);
int cdb_findnext(struct cdb_find *cdbfp);
#define cdb_seqinit(cptr, cdbp) ((*(cptr))=2048)
@@ -81,66 +86,63 @@ int cdb_bread(int fd, void *buf, int len);
/* cdb_make */
-struct cdb_make {
- int cdb_fd; /* file descriptor */
- /* private */
- unsigned cdb_dpos; /* data position so far */
- unsigned cdb_rcnt; /* record count so far */
- unsigned char cdb_buf[4096]; /* write buffer */
- unsigned char *cdb_bpos; /* current buf position */
- struct cdb_rl *cdb_rec[256]; /* list of arrays of record infos */
+struct cdb_make
+{
+ int cdb_fd; /* file descriptor */
+
+ /* private */
+ unsigned cdb_dpos; /* data position so far */
+ unsigned cdb_rcnt; /* record count so far */
+ unsigned char cdb_buf[4096]; /* write buffer */
+ unsigned char *cdb_bpos; /* current buf position */
+ struct cdb_rl *cdb_rec[256]; /* list of arrays of record infos */
};
-enum cdb_put_mode {
- CDB_PUT_ADD = 0, /* add unconditionnaly, like cdb_make_add() */
+enum cdb_put_mode
+{
+ CDB_PUT_ADD = 0, /* add unconditionnaly, like cdb_make_add() */
#define CDB_PUT_ADD CDB_PUT_ADD
- CDB_FIND = CDB_PUT_ADD,
- CDB_PUT_REPLACE, /* replace: do not place to index OLD record */
+ CDB_FIND = CDB_PUT_ADD, CDB_PUT_REPLACE, /* replace: do not place to index OLD record */
#define CDB_PUT_REPLACE CDB_PUT_REPLACE
- CDB_FIND_REMOVE = CDB_PUT_REPLACE,
- CDB_PUT_INSERT, /* add only if not already exists */
+ CDB_FIND_REMOVE = CDB_PUT_REPLACE, CDB_PUT_INSERT, /* add only if not already exists */
#define CDB_PUT_INSERT CDB_PUT_INSERT
- CDB_PUT_WARN, /* add unconditionally but ret. 1 if exists */
+ CDB_PUT_WARN, /* add unconditionally but ret. 1 if exists */
#define CDB_PUT_WARN CDB_PUT_WARN
- CDB_PUT_REPLACE0, /* if a record exists, fill old one with zeros */
+ CDB_PUT_REPLACE0, /* if a record exists, fill old one with zeros */
#define CDB_PUT_REPLACE0 CDB_PUT_REPLACE0
- CDB_FIND_FILL0 = CDB_PUT_REPLACE0
+ CDB_FIND_FILL0 = CDB_PUT_REPLACE0
};
int cdb_make_start(struct cdb_make *cdbmp, int fd);
-int cdb_make_add(struct cdb_make *cdbmp,
- const void *key, unsigned klen,
- const void *val, unsigned vlen);
-int cdb_make_exists(struct cdb_make *cdbmp,
- const void *key, unsigned klen);
-int cdb_make_find(struct cdb_make *cdbmp,
- const void *key, unsigned klen,
- enum cdb_put_mode mode);
-int cdb_make_put(struct cdb_make *cdbmp,
- const void *key, unsigned klen,
- const void *val, unsigned vlen,
- enum cdb_put_mode mode);
+int cdb_make_add(struct cdb_make *cdbmp, const void *key, unsigned klen,
+ const void *val, unsigned vlen);
+int cdb_make_exists(struct cdb_make *cdbmp, const void *key, unsigned klen);
+int cdb_make_find(struct cdb_make *cdbmp, const void *key, unsigned klen,
+ enum cdb_put_mode mode);
+int cdb_make_put(struct cdb_make *cdbmp, const void *key, unsigned klen,
+ const void *val, unsigned vlen, enum cdb_put_mode mode);
int cdb_make_finish(struct cdb_make *cdbmp);
/** Private API **/
-struct cdb_rec {
- unsigned hval;
- unsigned rpos;
+struct cdb_rec
+{
+ unsigned hval;
+ unsigned rpos;
};
-struct cdb_rl {
- struct cdb_rl *next;
- unsigned cnt;
- struct cdb_rec rec[254];
+struct cdb_rl
+{
+ struct cdb_rl *next;
+ unsigned cnt;
+ struct cdb_rec rec[254];
};
-int _cdb_make_write(struct cdb_make *cdbmp,
- const unsigned char *ptr, unsigned len);
+int _cdb_make_write(struct cdb_make *cdbmp, const unsigned char *ptr,
+ unsigned len);
int _cdb_make_fullwrite(int fd, const unsigned char *buf, unsigned len);
int _cdb_make_flush(struct cdb_make *cdbmp);
-int _cdb_make_add(struct cdb_make *cdbmp, unsigned hval,
- const void *key, unsigned klen,
- const void *val, unsigned vlen);
+int _cdb_make_add(struct cdb_make *cdbmp, unsigned hval, const void *key,
+ unsigned klen, const void *val, unsigned vlen);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/cdb/cdb_init.c b/src/cdb/cdb_init.c
index d3ae8c01b..af7b25256 100644
--- a/src/cdb/cdb_init.c
+++ b/src/cdb/cdb_init.c
@@ -56,7 +56,9 @@ cdb_init(struct cdb *cdbp, int fd)
cdbp->cdb_fd = fd;
cdbp->cdb_fsize = fsize;
cdbp->cdb_mem = mem;
-
+ cdbp->mtime = st.st_mtime;
+ cdbp->check_timer_ev = NULL;
+ cdbp->check_timer_tv = NULL;
cdbp->cdb_vpos = cdbp->cdb_vlen = 0;
cdbp->cdb_kpos = cdbp->cdb_klen = 0;
@@ -82,6 +84,12 @@ cdb_free(struct cdb *cdbp)
cdbp->cdb_mem = NULL;
}
cdbp->cdb_fsize = 0;
+
+ if (cdbp->check_timer_ev) {
+ evtimer_del (cdbp->check_timer_ev);
+ g_free (cdbp->check_timer_ev);
+ g_free (cdbp->check_timer_tv);
+ }
}
const void *
@@ -103,3 +111,45 @@ cdb_read(const struct cdb *cdbp, void *buf, unsigned len, unsigned pos)
memcpy (buf, data, len);
return 0;
}
+
+static void
+cdb_timer_callback (int fd, short what, gpointer ud)
+{
+ struct cdb *cdbp = ud;
+ gint nfd;
+ struct stat st;
+
+ /* Check cdb file for modifications */
+ if (stat (cdbp->filename, &st) != -1) {
+ if (st.st_mtime > cdbp->mtime) {
+ if ((nfd = open (cdbp->filename, O_RDONLY)) != -1) {
+ if (cdbp->cdb_mem) {
+#ifdef _WIN32
+ UnmapViewOfFile((void*) cdbp->cdb_mem);
+#else
+ munmap ((void*) cdbp->cdb_mem, cdbp->cdb_fsize);
+#endif /* _WIN32 */
+ cdbp->cdb_mem = NULL;
+ }
+ (void)close (cdbp->cdb_fd);
+ cdbp->cdb_fsize = 0;
+ (void)cdb_init (cdbp, fd);
+ }
+ }
+ }
+
+ evtimer_add (cdbp->check_timer_ev, cdbp->check_timer_tv);
+}
+
+void
+cdb_add_timer(struct cdb *cdbp, unsigned seconds)
+{
+ cdbp->check_timer_ev = g_malloc (sizeof (struct event));
+ cdbp->check_timer_tv = g_malloc (sizeof (struct timeval));
+
+ cdbp->check_timer_tv->tv_sec = seconds;
+ cdbp->check_timer_tv->tv_usec = 0;
+
+ evtimer_set (cdbp->check_timer_ev, cdb_timer_callback, cdbp);
+ evtimer_add (cdbp->check_timer_ev, cdbp->check_timer_tv);
+}
diff --git a/src/lua/lua_cdb.c b/src/lua/lua_cdb.c
index ef6041d7c..61bcf1df4 100644
--- a/src/lua/lua_cdb.c
+++ b/src/lua/lua_cdb.c
@@ -24,6 +24,8 @@
#include "lua_common.h"
#include "../cdb/cdb.h"
+#define CDB_REFRESH_TIME 60
+
LUA_FUNCTION_DEF (cdb, create);
LUA_FUNCTION_DEF (cdb, lookup);
LUA_FUNCTION_DEF (cdb, get_name);
@@ -102,6 +104,14 @@ lua_cdb_lookup (lua_State *L)
gsize vlen;
goffset vpos;
+ /*
+ * XXX: this code is placed here because event_loop is called inside workers, so start
+ * monitoring on first check, not on creation
+ */
+ if (cdb->check_timer_ev == NULL) {
+ cdb_add_timer (cdb, CDB_REFRESH_TIME);
+ }
+
what = luaL_checkstring (L, 2);
if (cdb_find (cdb, what, strlen (what)) > 0) {
/* Extract and push value to lua as string */
@@ -126,6 +136,7 @@ lua_cdb_destroy (lua_State *L)
if (cdb) {
cdb_free (cdb);
+ (void)close (cdb->cdb_fd);
g_free (cdb->filename);
g_free (cdb);
}
@@ -146,7 +157,7 @@ luaopen_cdb (lua_State * L)
lua_rawset (L, -3);
luaL_openlib (L, NULL, cdblib_m, 0);
- luaL_openlib(L, "cdb", cdblib_f, 0);
+ luaL_openlib (L, "cdb", cdblib_f, 0);
return 1;
}