aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/binlog.c159
-rw-r--r--src/binlogsel.c235
-rw-r--r--src/vmod-binlog.h18
4 files changed, 394 insertions, 19 deletions
diff --git a/configure.ac b/configure.ac
index 2bb8f38..56e0411 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,24 +19,25 @@ AC_CONFIG_AUX_DIR([build-aux])
19AC_CONFIG_MACRO_DIR([m4]) 19AC_CONFIG_MACRO_DIR([m4])
20AC_CONFIG_SRCDIR(src/binlog.c) 20AC_CONFIG_SRCDIR(src/binlog.c)
21AM_CONFIG_HEADER(config.h) 21AM_CONFIG_HEADER(config.h)
22 22
23AC_CANONICAL_SYSTEM 23AC_CANONICAL_SYSTEM
24AC_LANG(C) 24AC_LANG(C)
25 25
26AM_INIT_AUTOMAKE([gnu tar-ustar]) 26AM_INIT_AUTOMAKE([gnu tar-ustar])
27 27
28AC_GNU_SOURCE 28AC_GNU_SOURCE
29AC_PROG_CC 29AC_PROG_CC
30AC_PROG_CC_STDC 30AC_PROG_CC_STDC
31AM_PROG_CC_C_O
31if test "x$ac_cv_prog_cc_c99" = xno; then 32if test "x$ac_cv_prog_cc_c99" = xno; then
32 AC_MSG_ERROR([could not find a C99 compatible compiler]) 33 AC_MSG_ERROR([could not find a C99 compatible compiler])
33fi 34fi
34AC_PROG_CPP 35AC_PROG_CPP
35AC_PROG_YACC 36AC_PROG_YACC
36AC_PROG_INSTALL 37AC_PROG_INSTALL
37AC_PROG_LIBTOOL 38AC_PROG_LIBTOOL
38AC_PROG_MAKE_SET 39AC_PROG_MAKE_SET
39 40
40# Check for pkg-config 41# Check for pkg-config
41PKG_PROG_PKG_CONFIG 42PKG_PROG_PKG_CONFIG
42 43
diff --git a/src/binlog.c b/src/binlog.c
index 765b945..e7ac7e5 100644
--- a/src/binlog.c
+++ b/src/binlog.c
@@ -29,24 +29,25 @@
29#include <time.h> 29#include <time.h>
30#include "vrt.h" 30#include "vrt.h"
31#include "vcc_if.h" 31#include "vcc_if.h"
32#include "bin/varnishd/cache.h" 32#include "bin/varnishd/cache.h"
33#include "vmod-binlog.h" 33#include "vmod-binlog.h"
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
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};
47 48
48struct binlog_config { 49struct binlog_config {
49 size_t size; /* maximum file size */ 50 size_t size; /* maximum file size */
50 unsigned interval; /* file rotation interval */ 51 unsigned interval; /* file rotation interval */
51 char *pattern; /* file name pattern */ 52 char *pattern; /* file name pattern */
52 int umask; /* umask for new files and directories */ 53 int umask; /* umask for new files and directories */
@@ -174,32 +175,56 @@ getinterval(char *p, char **endp)
174 seconds = n; 175 seconds = n;
175 break; 176 break;
176 default: 177 default:
177 *endp = p; 178 *endp = p;
178 if (!hours && !minutes && !seconds) 179 if (!hours && !minutes && !seconds)
179 return n; 180 return n;
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 }
200 225
201 if (stat(dir, &st)) { 226 if (stat(dir, &st)) {
202 if (errno == ENOENT) 227 if (errno == ENOENT)
203 binlog_error("logging directory does not exist"); 228 binlog_error("logging directory does not exist");
204 else 229 else
205 binlog_error("cannot stat logging directory %s: %s", 230 binlog_error("cannot stat logging directory %s: %s",
@@ -229,26 +254,50 @@ vmod_init(struct sess *sp, struct vmod_priv *priv,
229 } 254 }
230 conf->recsize = packsize(conf->inst_head); 255 conf->recsize = packsize(conf->inst_head);
231 conf->env = packenv_create(conf->recsize); 256 conf->env = packenv_create(conf->recsize);
232 AN(conf->env); 257 AN(conf->env);
233 conf->recsize += offsetof(struct binlog_record,data); 258 conf->recsize += offsetof(struct binlog_record,data);
234 conf->dataspec = strdup(dataspec); 259 conf->dataspec = strdup(dataspec);
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;
249 u = strtoul(p, &q, 10); 298 u = strtoul(p, &q, 10);
250 if (errno) { 299 if (errno) {
251 binlog_error("invalid size value"); 300 binlog_error("invalid size value");
252 abort(); 301 abort();
253 } 302 }
254 free(p); 303 free(p);
@@ -297,24 +346,33 @@ vmod_init(struct sess *sp, struct vmod_priv *priv,
297 } else 346 } else
298 conf->umask = BINLOG_UMASK; 347 conf->umask = BINLOG_UMASK;
299 348
300 p = findparam(param, "roundts"); 349 p = findparam(param, "roundts");
301 if (p) { 350 if (p) {
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 }
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 }