aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-15 18:38:49 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-10-15 18:56:22 +0300
commitef3f928cc712f6774e19f8cb8f880cbeac15e8ff (patch)
tree88f59a4c8d1867bfadb924ee547b4b74a97c5ce0 /src
parentf035194d7d1b6cc0846ad7a5d86e0d6fa9463c67 (diff)
downloadvmod-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.c159
-rw-r--r--src/binlogsel.c235
-rw-r--r--src/vmod-binlog.h18
3 files changed, 393 insertions, 19 deletions
diff --git a/src/binlog.c b/src/binlog.c
index 765b945..e7ac7e5 100644
--- a/src/binlog.c
+++ b/src/binlog.c
@@ -35,12 +35,13 @@
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
42enum binlog_state { 43enum binlog_state {
43 state_init, 44 state_init,
44 state_start, 45 state_start,
45 state_pack 46 state_pack
46}; 47};
@@ -180,20 +181,44 @@ 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
187static 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
200static char *
201getindexpat(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
186void 210void
187vmod_init(struct sess *sp, struct vmod_priv *priv, 211vmod_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;
218 int user_pattern = 0;
194 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 }
@@ -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);
266 } else
267 user_pattern = 1;
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();
241 } 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);
242 conf->pattern = p; 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;
@@ -303,12 +352,21 @@ vmod_init(struct sess *sp, struct vmod_priv *priv,
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 }
308 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 }
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}
314 372
@@ -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,25 +475,109 @@ 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
422static int 480static int
481checkheader(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",
532 conf->dir, conf->fname, c));
533 return 1;