diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-03-09 17:09:25 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-03-09 17:09:25 +0300 |
commit | 3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3 (patch) | |
tree | f9eceb3c7cabed463f4ed009484d77e05baaf2c8 | |
parent | 8cc93b54959dc754b70698a2b397b3406dd7928e (diff) | |
download | rspamd-3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3.tar.gz rspamd-3e71b98b176fbaf54ff440e3831b5b1bd6d6e4f3.zip |
* Add monitoring for cdb
-rw-r--r-- | src/cdb/cdb.h | 124 | ||||
-rw-r--r-- | src/cdb/cdb_init.c | 52 | ||||
-rw-r--r-- | src/lua/lua_cdb.c | 13 |
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; } |