diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-15 18:38:49 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-15 18:56:22 +0300 |
commit | ef3f928cc712f6774e19f8cb8f880cbeac15e8ff (patch) | |
tree | 88f59a4c8d1867bfadb924ee547b4b74a97c5ce0 /src | |
parent | f035194d7d1b6cc0846ad7a5d86e0d6fa9463c67 (diff) | |
download | vmod-binlog-ef3f928cc712f6774e19f8cb8f880cbeac15e8ff.tar.gz vmod-binlog-ef3f928cc712f6774e19f8cb8f880cbeac15e8ff.tar.bz2 |
Change default log naming.
* configure.ac: Call AM_PROG_CC_C_O
* src/binlog.c (BLF_TRUNCATE): New flag.
(vmod_init): Change pattern initialization.
New parameter "reuselog".
(createfile): Remove O_TRUNC.
(checkheader): New function.
(newfile): Reuse existing file, if it is the first file
to be opened after varnish startup and its header matches
exactly our data.
* src/binlogsel.c: Use indexed directory structure to speed up
searches.
* src/vmod-binlog.h (BINLOG_PATTERN): Change pattern.
(BINLOG_GLOB_PATTERN,BINLOG_INDEX): New defines.
Diffstat (limited to 'src')
-rw-r--r-- | src/binlog.c | 181 | ||||
-rw-r--r-- | src/binlogsel.c | 245 | ||||
-rw-r--r-- | src/vmod-binlog.h | 18 |
3 files changed, 409 insertions, 35 deletions
diff --git a/src/binlog.c b/src/binlog.c index 765b945..e7ac7e5 100644 --- a/src/binlog.c +++ b/src/binlog.c | |||
@@ -34,13 +34,14 @@ | |||
34 | #include "pack.h" | 34 | #include "pack.h" |
35 | 35 | ||
36 | #ifndef O_SEARCH | 36 | #ifndef O_SEARCH |
37 | # define O_SEARCH 0 | 37 | # define O_SEARCH 0 |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #define BLF_ROUNDTS 0x01 | 40 | #define BLF_ROUNDTS 0x01 |
41 | #define BLF_TRUNCATE 0x02 | ||
41 | 42 | ||
42 | enum binlog_state { | 43 | enum binlog_state { |
43 | state_init, | 44 | state_init, |
44 | state_start, | 45 | state_start, |
45 | state_pack | 46 | state_pack |
46 | }; | 47 | }; |
@@ -180,21 +181,45 @@ getinterval(char *p, char **endp) | |||
180 | return (hours*60 + minutes)*60 + seconds; | 181 | return (hours*60 + minutes)*60 + seconds; |
181 | } | 182 | } |
182 | p++; | 183 | p++; |
183 | } | 184 | } |
184 | } | 185 | } |
185 | 186 | ||
187 | static struct indexdef { | ||
188 | char *name; | ||
189 | char *pat; | ||
190 | } indextab[] = { | ||
191 | { "year", "%Y" }, | ||
192 | { "0", "%Y" }, | ||
193 | { "month", "%Y/%m" }, | ||
194 | { "1", "%Y/%m" }, | ||
195 | { "day", "%Y/%m/%d" }, | ||
196 | { "2", "%Y/%m/%d" }, | ||
197 | { NULL } | ||
198 | }; | ||
199 | |||
200 | static char * | ||
201 | getindexpat(const char *name) | ||
202 | { | ||
203 | struct indexdef *p; | ||
204 | for (p = indextab; p->name; p++) | ||
205 | if (strcmp(p->name, name) == 0) | ||
206 | return p->pat; | ||
207 | return NULL; | ||
208 | } | ||
209 | |||
186 | void | 210 | void |
187 | vmod_init(struct sess *sp, struct vmod_priv *priv, | 211 | vmod_init(struct sess *sp, struct vmod_priv *priv, |
188 | const char *dir, const char *dataspec, const char *param) | 212 | const char *dir, const char *dataspec, const char *param) |
189 | { | 213 | { |
190 | struct binlog_config *conf = priv->priv; | 214 | struct binlog_config *conf = priv->priv; |
191 | struct stat st; | 215 | struct stat st; |
192 | char *p, *q; | 216 | char *p, *q; |
193 | unsigned long n; | 217 | unsigned long n; |
194 | 218 | int user_pattern = 0; | |
219 | |||
195 | p = findparam(param, "debug"); | 220 | p = findparam(param, "debug"); |
196 | if (p) { | 221 | if (p) { |
197 | conf->debug = atoi(p); | 222 | conf->debug = atoi(p); |
198 | free(p); | 223 | free(p); |
199 | } | 224 | } |
200 | 225 | ||
@@ -235,14 +260,38 @@ vmod_init(struct sess *sp, struct vmod_priv *priv, | |||
235 | AN(conf->dataspec); | 260 | AN(conf->dataspec); |
236 | 261 | ||
237 | p = findparam(param, "pattern"); | 262 | p = findparam(param, "pattern"); |
238 | if (!p) { | 263 | if (!p) { |
239 | p = strdup(BINLOG_PATTERN); | 264 | p = strdup(BINLOG_PATTERN); |
240 | AN(p); | 265 | AN(p); |
241 | } | 266 | } else |
267 | user_pattern = 1; | ||
242 | conf->pattern = p; | 268 | conf->pattern = p; |
269 | |||
270 | p = findparam(param, "index"); | ||
271 | if (p) { | ||
272 | q = getindexpat(p); | ||
273 | if (!q) { | ||
274 | binlog_error("invalid index type"); | ||
275 | abort(); | ||
276 | } | ||
277 | } else if (!user_pattern) { | ||
278 | q = getindexpat(BINLOG_INDEX); | ||
279 | AN(q); | ||
280 | } else | ||
281 | q = NULL; | ||
282 | |||
283 | if (q) { | ||
284 | p = malloc(strlen(q) + strlen(conf->pattern) + 2); | ||
285 | AN(p); | ||
286 | strcpy(p, q); | ||
287 | strcat(p, "/"); | ||
288 | strcat(p, conf->pattern); | ||
289 | free(conf->pattern); | ||
290 | conf->pattern = p; | ||
291 | } | ||
243 | 292 | ||
244 | p = findparam(param, "size"); | 293 | p = findparam(param, "size"); |
245 | if (p) { | 294 | if (p) { |
246 | uintmax_t u; | 295 | uintmax_t u; |
247 | 296 | ||
248 | errno = 0; | 297 | errno = 0; |
@@ -302,12 +351,21 @@ vmod_init(struct sess *sp, struct vmod_priv *priv, | |||
302 | if (atoi(p)) | 351 | if (atoi(p)) |
303 | conf->flags |= BLF_ROUNDTS; | 352 | conf->flags |= BLF_ROUNDTS; |
304 | else | 353 | else |
305 | conf->flags &= ~BLF_ROUNDTS; | 354 | conf->flags &= ~BLF_ROUNDTS; |
306 | free(p); | 355 | free(p); |
307 | } | 356 | } |
357 | |||
358 | p = findparam(param, "reuselog"); | ||
359 | if (p) { | ||
360 | if (atoi(p)) | ||
361 | conf->flags &= ~BLF_TRUNCATE; | ||
362 | else | ||
363 | conf->flags |= BLF_TRUNCATE; | ||
364 | free(p); | ||
365 | } | ||
308 | 366 | ||
309 | conf->fd = -1; | 367 | conf->fd = -1; |
310 | conf->base = NULL; | 368 | conf->base = NULL; |
311 | conf->stoptime = time(NULL); | 369 | conf->stoptime = time(NULL); |
312 | pthread_mutex_init(&conf->mutex, NULL); | 370 | pthread_mutex_init(&conf->mutex, NULL); |
313 | } | 371 | } |
@@ -381,13 +439,13 @@ createfile(struct sess *sp, struct binlog_config *conf) | |||
381 | return -1; | 439 | return -1; |
382 | if (mkdir_p(conf, fname)) { | 440 | if (mkdir_p(conf, fname)) { |
383 | free(fname); | 441 | free(fname); |
384 | return -1; | 442 | return -1; |
385 | } | 443 | } |
386 | 444 | ||
387 | fd = openat(conf->dd, fname, O_CREAT|O_RDWR|O_TRUNC, | 445 | fd = openat(conf->dd, fname, O_CREAT|O_RDWR, |
388 | 0666 & ~conf->umask); | 446 | 0666 & ~conf->umask); |
389 | if (fd == -1) { | 447 | if (fd == -1) { |
390 | binlog_error("cannot create log file %s/%s: %s", | 448 | binlog_error("cannot create log file %s/%s: %s", |
391 | conf->dir, fname, strerror(errno)); | 449 | conf->dir, fname, strerror(errno)); |
392 | free(fname); | 450 | free(fname); |
393 | } | 451 | } |
@@ -417,60 +475,149 @@ setstoptime(struct binlog_config *conf) | |||
417 | } | 475 | } |
418 | 476 | ||
419 | #define binlog_recnum(conf) \ | 477 | #define binlog_recnum(conf) \ |
420 | (((conf)->size - (conf)->base->hdrsize) / (conf)->base->recsize) | 478 | (((conf)->size - (conf)->base->hdrsize) / (conf)->base->recsize) |
421 | 479 | ||
422 | static int | 480 | static int |
481 | checkheader(struct binlog_config *conf, size_t hdrsize) | ||
482 | { | ||
483 | struct binlog_file_header header; | ||
484 | int c; | ||
485 | ssize_t rc; | ||
486 | char *p; | ||
487 | |||
488 | rc = read(conf->fd, &header, sizeof(header)); | ||
489 | if (rc == -1) { | ||
490 | binlog_error("error reading header of %s/%s: %s", | ||
491 | conf->dir, conf->fname, strerror(errno)); | ||
492 | return -1; | ||
493 | } else if (rc != sizeof(header)) { | ||
494 | binlog_error("error reading header of %s/%s: %s", | ||
495 | conf->dir, conf->fname, "hit eof"); | ||
496 | return -1; | ||
497 | } | ||
498 | |||
499 | if (memcmp(header.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { | ||
500 | binlog_error("%s/%s is not a binlog file", | ||
501 | conf->dir, conf->fname); | ||
502 | return -1; | ||
503 | } | ||
504 | |||
505 | if (header.version != BINLOG_VERSION) { | ||
506 | binlog_error("%s/%s: unknown version", conf->dir, conf->fname); | ||
507 | return -1; | ||
508 | } | ||
509 | |||
510 | if (header.hdrsize != hdrsize) { | ||
511 | debug(conf,1,("%s/%s: header size mismatch", | ||
512 | conf->dir, conf->fname)); | ||
513 | return 1; | ||
514 | } | ||
515 | if (header.recsize != conf->recsize) { | ||
516 | debug(conf,1,("%s/%s: record size mismatch", | ||
517 | conf->dir, conf->fname)); | ||
518 | return 1; | ||
519 | } | ||
520 | |||
521 | p = conf->dataspec; | ||
522 | while (*p) { | ||
523 | if (read(conf->fd, &c, 1) != 1 || c != *p) { | ||
524 | debug(conf,1,("%s/%s: dataspec mismatch near %s: %c", | ||
525 | conf->dir, conf->fname, p, c)); | ||
526 | return 1; | ||
527 | } | ||
528 | ++p; | ||
529 | } | ||
530 | if (read(conf->fd, &c, 1) != 1 || c != 0) { | ||
531 | debug(conf,1,("%s/%s: dataspec mismatch at the end: %c", | ||