aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-08-01 19:20:54 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-08-02 10:48:54 +0300
commit73f605f76d82aec40a7f1bbd309e2097d9abfd42 (patch)
tree5820713d17efcb482a8801f4f805b0ae121903f7
parentd78a58be5fa2385987a3141ccbe942107332e677 (diff)
downloadvmod-tbf-73f605f76d82aec40a7f1bbd309e2097d9abfd42.tar.gz
vmod-tbf-73f605f76d82aec40a7f1bbd309e2097d9abfd42.tar.bz2
Switch to CDB environment.
* configure.ac: Version 0.99.91 * src/tbf.c (dbdir): New static. (tbf_set_db_name): Remove. (tbf_set_db_dir): New function. (tbf_open): Rename the parameter and related variables. Create a CDB environment and the database in it. (vmod_open): Change semantics of the first argument. * src/vmod-tbf.3: Update. * tests/Makefile.am (distclean-local): New rule, instead of DISTCLEANFILES. * tests/test00.vtc: Update call to tbf.open. * tests/test01.vtc: Likewise. * tests/test02.vtc: Likewise. * tests/test03.vtc: Likewise.
-rw-r--r--configure.ac2
-rw-r--r--src/tbf.c208
-rw-r--r--src/vmod-tbf.332
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/test00.vtc2
-rw-r--r--tests/test01.vtc2
-rw-r--r--tests/test02.vtc2
-rw-r--r--tests/test03.vtc2
8 files changed, 173 insertions, 81 deletions
diff --git a/configure.ac b/configure.ac
index 9c228f6..4ca4e6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@
14# You should have received a copy of the GNU General Public License 14# You should have received a copy of the GNU General Public License
15# along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>. 15# along with vmod-tbf. If not, see <http://www.gnu.org/licenses/>.
16AC_PREREQ(2.69) 16AC_PREREQ(2.69)
17AC_INIT([vmod-tbf], 0.99.90, [gray@gnu.org]) 17AC_INIT([vmod-tbf], 0.99.91, [gray@gnu.org])
18AC_CONFIG_AUX_DIR([build-aux]) 18AC_CONFIG_AUX_DIR([build-aux])
19AC_CONFIG_MACRO_DIR([m4]) 19AC_CONFIG_MACRO_DIR([m4])
20AC_CONFIG_SRCDIR(src/vmod_tbf.vcc) 20AC_CONFIG_SRCDIR(src/vmod_tbf.vcc)
diff --git a/src/tbf.c b/src/tbf.c
index 1dfb6c6..7050fc7 100644
--- a/src/tbf.c
+++ b/src/tbf.c
@@ -20,6 +20,7 @@
20#include <stdbool.h> 20#include <stdbool.h>
21#include <syslog.h> 21#include <syslog.h>
22#include <inttypes.h> 22#include <inttypes.h>
23#include <sys/stat.h>
23#include <db.h> 24#include <db.h>
24#include "vrt.h" 25#include "vrt.h"
25#include "vcc_if.h" 26#include "vcc_if.h"
@@ -41,14 +42,19 @@ debugprt(const char *fmt, ...)
41# define USEC_PER_SEC 1000000L 42# define USEC_PER_SEC 1000000L
42#endif 43#endif
43 44
45#define DEFDBNAME "tbf.bdb"
46#define DEFOPENPARAMS "truncate"
47#define DBFILEMODE 0640
48
49static char *dbdir;
44static char *dbname; 50static char *dbname;
51static DB_ENV *dbenv;
45static DB *db; 52static DB *db;
46static uint64_t autosync_max; 53static uint64_t autosync_max;
47static uint64_t autosync_count; 54static uint64_t autosync_count;
48static int tbf_disabled; 55static int tbf_disabled;
49 56
50static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 57static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
51#define DBFILEMODE 0640
52 58
53 59
54/* The keylock structure serializes accesses to each db record, ensuring 60/* The keylock structure serializes accesses to each db record, ensuring
@@ -122,147 +128,217 @@ keylock_remove_safe(struct keylock *kp)
122} 128}
123 129
124static void 130static void
125tbf_set_db_name(const char *file_name) 131tbf_set_db_dir(const char *dir)
126{ 132{
127 if (dbname) 133 if (dbdir)
128 free(dbname); 134 free(dbdir);
129 dbname = strdup(file_name); 135 dbdir = strdup(dir);
130 if (!dbname) 136 AN(dbdir);
131 abort();
132} 137}
133 138
134struct mode_kw { 139struct param_kw {
135 char *mkw_str; 140 char *pkw_str;
136 int mkw_len; 141 int pkw_len;
137 int mkw_tok; 142 int pkw_tok;
138}; 143};
139 144
140enum { 145enum {
141 MKW_TRUNCATE, 146 PKW_TRUNCATE,
142 MKW_MODE, 147 PKW_MODE,
143 MKW_SYNC, 148 PKW_SYNC,
144 MKW_DEBUG, 149 PKW_DEBUG,
150 PKW_DBNAME
145}; 151};
146 152
147static struct mode_kw mode_kw_tab[] = { 153static struct param_kw param_kw_tab[] = {
148#define S(s) #s, sizeof(#s)-1 154#define S(s) #s, sizeof(#s)-1
149 { S(truncate), MKW_TRUNCATE }, 155 { S(truncate), PKW_TRUNCATE },
150 { S(trunc), MKW_TRUNCATE }, 156 { S(trunc), PKW_TRUNCATE },
151 { S(mode=), MKW_MODE }, 157 { S(mode=), PKW_MODE },
152 { S(sync=), MKW_SYNC }, 158 { S(sync=), PKW_SYNC },
153 { S(debug=), MKW_DEBUG }, 159 { S(debug=), PKW_DEBUG },
160 { S(dbname=), PKW_DBNAME },
154 { NULL } 161 { NULL }
155#undef S 162#undef S
156}; 163};
157 164
158static void 165static void
159tbf_open(const char *mode) 166tbf_open(const char *params)
160{ 167{
161 int rc; 168 int rc;
162 int flags = DB_CREATE|DB_THREAD;
163 int filemode = DBFILEMODE; 169 int filemode = DBFILEMODE;
164 uint64_t n; 170 uint64_t n;
165 char *p; 171 char *p;
172 struct stat st;
173 int truncate = 0;
166 174
167 if (!dbname) 175 if (!dbdir) {
168 tbf_set_db_name(LOCALSTATEDIR "/tbf.db"); 176 dbdir = strdup(LOCALSTATEDIR "/vmod-tbf");
169 177 AN(dbdir);
170 rc = db_create(&db, NULL, 0); 178 }
171 if (rc) { 179 if (!dbname) {
172 syslog(LOG_DAEMON|LOG_ERR, "cannot create db struct"); 180 dbname = strdup(DEFDBNAME);
173 return; 181 AN(dbname);
174 } 182 }
175 183
176 while (*mode) { 184 while (*params) {
177 struct mode_kw *mkw; 185 struct param_kw *pkw;
178 186
179 for (mkw = mode_kw_tab; mkw->mkw_str; mkw++) { 187 for (pkw = param_kw_tab; pkw->pkw_str; pkw++) {
180 if (strncmp(mode, mkw->mkw_str, mkw->mkw_len) == 0) 188 if (strncmp(params, pkw->pkw_str, pkw->pkw_len) == 0)
181 break; 189 break;
182 } 190 }
183 191
184 if (!mkw->mkw_str) { 192 if (!pkw->pkw_str) {
185 syslog(LOG_DAEMON|LOG_ERR, "invalid keyword %s", mode); 193 syslog(LOG_DAEMON|LOG_ERR, "invalid keyword %s", params);
186 break; 194 break;
187 } 195 }
188 196
189 mode += mkw->mkw_len; 197 params += pkw->pkw_len;
190 198
191 switch (mkw->mkw_tok) { 199 switch (pkw->pkw_tok) {
192 case MKW_TRUNCATE: 200 case PKW_TRUNCATE:
193 flags |= DB_TRUNCATE; 201 truncate = 1;
194 break; 202 break;
195 203
196 case MKW_MODE: 204 case PKW_MODE:
197 errno = 0; 205 errno = 0;
198 n = strtoul(mode, &p, 8); 206 n = strtoul(params, &p, 8);
199 if (errno || (n & ~0777) || !(*p == 0 || *p == ';')) { 207 if (errno || (n & ~0777) || !(*p == 0 || *p == ';')) {
200 syslog(LOG_DAEMON|LOG_ERR, 208 syslog(LOG_DAEMON|LOG_ERR,
201 "invalid file mode near %s", p); 209 "invalid file mode near %s", p);
202 mode += strlen(mode); 210 params += strlen(params);
203 } else { 211 } else {
204 filemode = n; 212 filemode = n;
205 mode = p; 213 params = p;
206 } 214 }
207 break; 215 break;
208 216
209 case MKW_SYNC: 217 case PKW_SYNC:
210 errno = 0; 218 errno = 0;
211 n = strtoul(mode, &p, 10); 219 n = strtoul(params, &p, 10);
212 if (errno || !(*p == 0 || *p == ';')) { 220 if (errno || !(*p == 0 || *p == ';')) {
213 syslog(LOG_DAEMON|LOG_ERR, 221 syslog(LOG_DAEMON|LOG_ERR,
214 "invalid count near %s", p); 222 "invalid count near %s", p);
215 mode += strlen(mode); 223 params += strlen(params);
216 } else { 224 } else {
217 autosync_max = n; 225 autosync_max = n;
218 autosync_count = 0; 226 autosync_count = 0;
219 mode = p; 227 params = p;
220 } 228 }
221 break; 229 break;
222 230
223 case MKW_DEBUG: 231 case PKW_DEBUG:
224 errno = 0; 232 errno = 0;
225 n = strtoul(mode, &p, 10); 233 n = strtoul(param