[master] a099300 Beginnings of new VSL api
Martin Blix Grydeland
martin at varnish-cache.org
Wed May 15 14:46:14 CEST 2013
commit a0993006bb06c3684847057bd3dc692f2d03c04f
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Wed Apr 10 13:47:39 2013 +0200
Beginnings of new VSL api
Remove automagic reopening logic from vsl
Make vsl use the new VSL_head structure
Remove most of the old functionality
diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h
index db8b953..6ee0e33 100644
--- a/include/vapi/vsl.h
+++ b/include/vapi/vsl.h
@@ -28,131 +28,129 @@
*
* This is the public API for the VSL access.
*
- * VSL is a "subclass" of VSM.
- *
- * VSL can either read from VSM or from a file.
- *
- * When reading from a file, the filename is passed in with:
- * VSL_Arg(vd, "r", "/some/file");
- * and once VSL_Dispatch()/VSL_NextSLT() will indicate EOF by returning -2.
- * Another file can then be opened with VSL_Arg() and processed.
- *
*/
#ifndef VAPI_VSL_H_INCLUDED
#define VAPI_VSL_H_INCLUDED
-#include "vapi/vsl_int.h"
+#include <stdio.h>
-struct VSM_data;
+#include "vapi/vsm.h"
+#include "vapi/vsl_int.h"
-/*---------------------------------------------------------------------
- * VSL level access functions
- */
+#define VSL_ARGS "i:x:"
-#define VSL_ARGS "bCcdI:i:k:n:r:s:X:x:m:"
-#define VSL_b_USAGE "[-b]"
-#define VSL_c_USAGE "[-c]"
-#define VSL_C_USAGE "[-C]"
-#define VSL_d_USAGE "[-d]"
#define VSL_i_USAGE "[-i tag]"
-#define VSL_I_USAGE "[-I regexp]"
-#define VSL_k_USAGE "[-k keep]"
-#define VSL_m_USAGE "[-m tag:regex]"
-#define VSL_n_USAGE VSM_n_USAGE
-#define VSL_r_USAGE "[-r file]"
-#define VSL_s_USAGE "[-s skip]"
#define VSL_x_USAGE "[-x tag]"
-#define VSL_X_USAGE "[-X regexp]"
-#define VSL_USAGE "[-bCcd] " \
+#define VSL_USAGE "[...] " \
VSL_i_USAGE " " \
- VSL_I_USAGE " " \
- VSL_k_USAGE " " \
- VSL_m_USAGE " " \
- VSL_n_USAGE " " \
- VSL_r_USAGE " " \
- VSL_s_USAGE " " \
- VSL_X_USAGE " " \
VSL_x_USAGE
-int VSL_Arg(struct VSM_data *vd, int arg, const char *opt);
+struct VSL_data;
+
+struct VSL_cursor {
+ const uint32_t *ptr; /* Record pointer */
+};
+
+extern const char *VSL_tags[256];
+ /*
+ * Tag to string array. Contains NULL for invalid tags.
+ */
+
+int VSL_Name2Tag(const char *name, int l);
+ /*
+ * Convert string to tag number (= enum VSL_tag_e)
+ *
+ * Return values:
+ * >=0: Tag number
+ * -1: No tag matches
+ * -2: Multiple tags match substring
+ */
+
+struct VSL_data *VSL_New(void);
+int VSL_Arg(struct VSL_data *vsl, int opt, const char *arg);
/*
* Handle standard log-presenter arguments
* Return:
- * -1 error, VSM_Error() returns diagnostic string
+ * -1 error, VSL_Error() returns diagnostic string
* 0 not handled
* 1 Handled.
*/
-typedef int VSL_handler_f(void *priv, enum VSL_tag_e tag, unsigned fd,
- unsigned len, unsigned spec, const char *ptr, uint64_t bitmap);
+void VSL_Delete(struct VSL_data *vsl);
/*
- * This is the call-back function you must provide.
- * priv is whatever you asked for it to be.
- * tag is the SLT_mumble tag
- * fd is the filedescriptor associated with this record
- * len is the length of the data at ptr
- * spec are the VSL_S_* flags
- * ptr points to the data, beware of non-printables.
- * bitmap is XXX ???
+ * Delete a VSL context, freeing up the resources
*/
-#define VSL_S_CLIENT (1 << 0)
-#define VSL_S_BACKEND (1 << 1)
-
-VSL_handler_f VSL_H_Print;
+const char *VSL_Error(const struct VSL_data *vsl);
/*
- * This call-back function will printf() the record to the FILE *
- * specified in priv.
+ * Return the latest error message.
*/
-void VSL_Select(struct VSM_data *vd, enum VSL_tag_e tag);
+void VSL_ResetError(struct VSL_data *vsl);
/*
- * This adds tags which shall always be selected, similar to using
- * the '-i' option.
- * VSL_Select()/-i takes precedence over all other filtering.
+ * Reset any error message.
*/
-int VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv);
+struct VSL_cursor *VSL_CursorVSM(struct VSL_data *vsl, struct VSM_data *vsm,
+ int tail);
+ /*
+ * Set the cursor pointed to by cursor up as a raw cursor in the
+ * log. If tail is non-zero, it will point to the tail of the
+ * log. Is tail is zero, it will point close to the head of the
+ * log, at least 2 segments away from the head.
+ *
+ * Return values:
+ * non-NULL: Pointer to cursor
+ * NULL: Error, see VSL_Error
+ */
+
+struct VSL_cursor *VSL_CursorFile(struct VSL_data *vsl, const char *name);
/*
- * Call func(priv, ...) for all filtered VSL records.
+ * Create a cursor pointing to the beginning of the binary VSL log
+ * in file name. If name is '-' reads from stdin.
*
* Return values:
- * !=0: Non-zero return value from func()
- * 0: no VSL records.
- * -1: VSL chunk was abandoned.
- * -2: End of file (-r) / -k arg exhausted / "done"
+ * non-NULL: Pointer to cursor
+ * NULL: Error, see VSL_Error
*/
-int VSL_NextSLT(struct VSM_data *lh, uint32_t **pp, uint64_t *bitmap);
+void VSL_DeleteCursor(struct VSL_cursor *c);
/*
- * Return raw pointer to next filtered VSL record.
- *
- * Return values:
- * 1: Valid VSL record at *pp
- * 0: no VSL records
- * -1: VSL chunk was abandoned
- * -2: End of file (-r) / -k arg exhausted / "done"
+ * Delete the cursor pointed to by c
*/
-int VSL_Matched(struct VSM_data *vd, uint64_t bitmap);
+int VSL_Next(struct VSL_cursor *c);
/*
+ * Return raw pointer to next VSL record.
+ *
+ * Return values:
+ * 1: Cursor points to next log record
+ * 0: End of log
+ * -1: End of file (-r) (XXX / -k arg exhausted / "done")
+ * -2: Remote abandoned or closed
+ * -3: Overrun
+ * -4: I/O read error - see errno
*/
-int VSL_Name2Tag(const char *name, int l);
+int VSL_Match(struct VSL_data *vsl, const struct VSL_cursor *c);
/*
- * Convert string to tag number (= enum VSL_tag_e)
+ * Returns true if the record pointed to by cursor matches the
+ * record current record selectors
*
- * Return values:
- * >=0: Tag number
- * -1: No tag matches
- * -2: Multiple tags match substring
+ * Return value:
+ * 1: Match
+ * 0: No match
*/
-extern const char *VSL_tags[256];
+int VSL_Print(struct VSL_data *vsl, const struct VSL_cursor *c, void *file);
/*
- * Tag to string array. Contains NULL for invalid tags.
+ * Print the log record pointed to by cursor to stream.
+ *
+ * Return values:
+ * 0: OK
+ * -5: I/O write error - see errno
*/
#endif /* VAPI_VSL_H_INCLUDED */
diff --git a/include/vapi/vsl_int.h b/include/vapi/vsl_int.h
index c34706b..c42198a 100644
--- a/include/vapi/vsl_int.h
+++ b/include/vapi/vsl_int.h
@@ -88,6 +88,7 @@ struct VSL_head {
#define VSL_CLIENT(ptr) (((ptr)[1]) & VSL_CLIENTMARKER)
#define VSL_BACKEND(ptr) (((ptr)[1]) & VSL_BACKENDMARKER)
#define VSL_DATA(ptr) ((char*)((ptr)+2))
+#define VSL_CDATA(ptr) ((const char*)((ptr)+2))
#define VSL_ENDMARKER (((uint32_t)SLT__Reserved << 24) | 0x454545) /* "EEE" */
#define VSL_WRAPMARKER (((uint32_t)SLT__Reserved << 24) | 0x575757) /* "WWW" */
diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h
index c405168..f6f7f9e 100644
--- a/include/vapi/vsm.h
+++ b/include/vapi/vsm.h
@@ -148,7 +148,8 @@ int VSM_StillValid(const struct VSM_data *vd, struct VSM_fantom *vf);
* Return:
* 0: fantom is not valid any more.
* 1: fantom is still the same.
- * 2: a fantom with same dimensions exist, check class/type/ident
+ * 2: a fantom with same dimensions exist in same position,
+ * check class/type/ident
*/
int VSM_Get(const struct VSM_data *vd, struct VSM_fantom *vf,
diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am
index 2e5de91..6069534 100644
--- a/lib/libvarnishapi/Makefile.am
+++ b/lib/libvarnishapi/Makefile.am
@@ -26,6 +26,7 @@ libvarnishapi_la_SOURCES = \
../libvarnish/vsha256.c \
vsm.c \
vsl_arg.c \
+ vsl_cursor.c \
vsl.c \
vsc.c \
libvarnishapi.map
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index 34a851d..a25aa94 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -95,5 +95,15 @@ LIBVARNISHAPI_1.3 {
VSC_MainValid;
VSC_IterValid;
VSC_LevelDesc;
+ VSL_New;
+ VSL_Delete;
+ VSL_Error;
+ VSL_ResetError;
+ VSL_CursorVSM;
+ VSL_CursorFile;
+ VSL_DeleteCursor;
+ VSL_Next;
+ VSL_Match;
+ VSL_Print;
# Variables:
} LIBVARNISHAPI_1.0;
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index cb9e6eb..963afce 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -1,9 +1,10 @@
/*-
* Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006-2011 Varnish Software AS
+ * Copyright (c) 2006-2013 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Martin Blix Grydeland <martin at varnish-software.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +34,7 @@
#include <sys/types.h>
#include <errno.h>
+#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -43,12 +45,14 @@
#include "vas.h"
#include "vdef.h"
-#include "vapi/vsl.h"
#include "vapi/vsm.h"
+#include "vapi/vsl.h"
#include "vapi/vsm_int.h"
+#include "vin.h"
#include "vbm.h"
#include "vmb.h"
#include "vre.h"
+#include "vsb.h"
#include "vsl_api.h"
#include "vsm_api.h"
@@ -60,334 +64,139 @@ const char *VSL_tags[256] = {
# undef SLTM
};
-/*--------------------------------------------------------------------*/
-
-struct vsl *
-vsl_Setup(struct VSM_data *vd)
+int
+vsl_diag(struct VSL_data *vsl, const char *fmt, ...)
{
- struct vsl *vsl;
+ va_list ap;
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- if (vd->vsl == NULL) {
- ALLOC_OBJ(vd->vsl, VSL_MAGIC);
- AN(vd->vsl);
- vsl = vd->vsl;
- vsl->regflags = 0;
- vsl->vbm_supress = vbit_init(256);
- vsl->vbm_select = vbit_init(256);
- vsl->r_fd = -1;
- vsl->num_matchers = 0;
- VTAILQ_INIT(&vsl->matchers);
- }
- CHECK_OBJ_NOTNULL(vd->vsl, VSL_MAGIC);
- return (vd->vsl);
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ AN(fmt);
+
+ if (vsl->diag == NULL)
+ vsl->diag = VSB_new_auto();
+ AN(vsl->diag);
+ VSB_clear(vsl->diag);
+ va_start(ap, fmt);
+ VSB_vprintf(vsl->diag, fmt, ap);
+ va_end(ap);
+ AZ(VSB_finish(vsl->diag));
+ return (-1);
}
-/*--------------------------------------------------------------------
- * Called from VSM_Delete()
- */
-
-void
-VSL_Delete(struct VSM_data *vd)
+struct VSL_data *
+VSL_New(void)
{
- struct vsl *vsl;
+ struct VSL_data *vsl;
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- vsl = vd->vsl;
- vd->vsl = NULL;
- CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ ALLOC_OBJ(vsl, VSL_MAGIC);
+ if (vsl == NULL)
+ return (NULL);
- if (vsl->r_fd > STDIN_FILENO)
- (void)close(vsl->r_fd);
- vbit_destroy(vsl->vbm_supress);
- vbit_destroy(vsl->vbm_select);
- free(vsl->rbuf);
- FREE_OBJ(vsl);
-}
+ vsl->vbm_select = vbit_init(256);
+ vsl->vbm_supress = vbit_init(256);
-/*--------------------------------------------------------------------*/
+ return (vsl);
+}
void
-VSL_Select(struct VSM_data *vd, enum VSL_tag_e tag)
+VSL_Delete(struct VSL_data *vsl)
{
- struct vsl *vsl = vsl_Setup(vd);
-
- vbit_set(vsl->vbm_select, (int)tag);
-}
-/*--------------------------------------------------------------------
- */
-
-static int
-vsl_open(struct VSM_data *vd)
-{
- struct vsl *vsl = vsl_Setup(vd);
- int i;
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
- assert(vsl->r_fd < 0);
- if (vd->head == NULL) {
- i = VSM_Open(vd);
- if (i)
- return (i);
- }
- if (!VSM_Get(vd, &vsl->vf, VSL_CLASS, NULL, NULL)) {
- VSM_Close(vd);
- return (vsm_diag(vd, "No VSL chunk found "
- " (child not started ?)\n"));
- }
- vsl->log_start = vsl->vf.b;
- vsl->log_end = vsl->vf.e;
- vsl->log_ptr = vsl->log_start + 1;
- if (!vsl->d_opt) {
- while (vsl->log_ptr < vsl->log_end &&
- *vsl->log_ptr != VSL_ENDMARKER)
- vsl->log_ptr = VSL_NEXT(vsl->log_ptr);
- }
- if (vsl->log_ptr >= vsl->log_end)
- vsl->log_ptr = vsl->log_start + 1;
- vsl->last_seq = vsl->log_start[0];
- return (0);
+ vbit_destroy(vsl->vbm_select);
+ vbit_destroy(vsl->vbm_supress);
+ VSL_ResetError(vsl);
+ FREE_OBJ(vsl);
}
-/*--------------------------------------------------------------------
- */
-
-static void
-vsl_close(struct VSM_data *vd)
+const char *
+VSL_Error(const struct VSL_data *vsl)
{
- struct vsl *vsl = vsl_Setup(vd);
- assert(vsl->r_fd < 0);
- VSM_Close(vd);
- memset(&vsl->vf, 0, sizeof vsl->vf);
- vsl->log_start = NULL;
- vsl->log_end = NULL;
- vsl->log_ptr = NULL;
-}
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-/*--------------------------------------------------------------------
- * Return the next log record, if there is one
- *
- * Return:
- * <0: error
- * 0: no record
- * >0: record available at pp
- */
+ if (vsl->diag == NULL)
+ return (NULL);
+ else
+ return (VSB_data(vsl->diag));
+}
-static int
-vsl_nextslt(struct VSM_data *vd, uint32_t **pp)
+void
+VSL_ResetError(struct VSL_data *vsl)
{
- struct vsl *vsl = vsl_Setup(vd);
- unsigned l;
- uint32_t t;
- int i;
-
- *pp = NULL;
- if (vsl->r_fd != -1) {
- assert(vsl->rbuflen >= 8);
- i = read(vsl->r_fd, vsl->rbuf, 8);
- if (i == 0)
- return (-2);
- if (i != 8)
- return (-1);
- l = 2 + VSL_WORDS(VSL_LEN(vsl->rbuf));
- if (vsl->rbuflen < l) {
- l += 256;
- vsl->rbuf = realloc(vsl->rbuf, l * 4L);
- assert(vsl->rbuf != NULL);
- vsl->rbuflen = l;
- }
- i = read(vsl->r_fd, vsl->rbuf + 2, l * 4L - 8L);
- if (i != (l * 4L - 8L))
- return (-1);
- *pp = vsl->rbuf;
- return (1);
- }
-
- if (vsl->log_ptr == NULL && vsl_open(vd))
- return (0);
-
- while (1) {
- assert(vsl->log_ptr >= vsl->log_start + 1);
- assert(vsl->log_ptr < vsl->log_end);
- t = *vsl->log_ptr;
-
- if (t == VSL_WRAPMARKER) {
- /* Wrap around not possible at front */
- if (vsl->log_ptr == vsl->log_start + 1)
- return (-1);
- vsl->log_ptr = vsl->log_start + 1;
- continue;
- }
- if (t == VSL_ENDMARKER) {
- if (vsl->log_ptr != vsl->log_start + 1 &&
- vsl->last_seq != vsl->log_start[0]) {
- /* ENDMARKER not at front and seq wrapped */
- vsl->log_ptr = vsl->log_start + 1;
- continue;
- }
- return (0);
- }
-
- if (t == 0) {
- /* Uninitialized VSL */
- return (0);
- }
-
- if (vsl->log_ptr == vsl->log_start + 1)
- vsl->last_seq = vsl->log_start[0];
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
- *pp = (void*)(uintptr_t)vsl->log_ptr; /* Loose volatile */
- vsl->log_ptr = VSL_NEXT(vsl->log_ptr);
- return (1);
- }
+ if (vsl->diag == NULL)
+ return;
+ VSB_delete(vsl->diag);
+ vsl->diag = NULL;
}
int
-VSL_NextSLT(struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
+VSL_Match(struct VSL_data *vsl, const struct VSL_cursor *c)
{
- struct vsl *vsl = vsl_Setup(vd);
- uint32_t *p;
- unsigned char t;
- int i;
- struct vsl_re_match *vrm;
- int j;
-
- if (bits != NULL)
- *bits = 0;
-
- while (1) {
- i = vsl_nextslt(vd, &p);
- if (i < 0)
- return (i);
- if (i == 0) {
- if (vsl->d_opt || vsl->r_fd >= 0)
- return (i);
- if (!VSM_StillValid(vd, &vsl->vf))
- vsl_close(vd);
- return (i);
- }
+ enum VSL_tag_e tag;
- t = VSL_TAG(p);
- if (t == SLT__Batch) {
- continue;
- } else if (vbit_test(vsl->vbm_select, t)) {
- /* nothing */
- } else if (vbit_test(vsl->vbm_supress, t)) {
- continue;
- } else if (vsl->b_opt && !VSL_BACKEND(p)) {
- continue;
- } else if (vsl->c_opt && !VSL_CLIENT(p)) {
- continue;
- } else if (vsl->regincl != NULL) {
- i = VRE_exec(vsl->regincl, VSL_DATA(p), VSL_LEN(p),
- 0, 0, NULL, 0, NULL);
- if (i == VRE_ERROR_NOMATCH)
- continue;
- } else if (vsl->regexcl != NULL) {
- i = VRE_exec(vsl->regexcl, VSL_DATA(p), VSL_LEN(p),
- 0, 0, NULL, 0, NULL);
- if (i != VRE_ERROR_NOMATCH)
- continue;
- }
-
- if (vsl->skip) {
- --vsl->skip;
- continue;
- } else if (vsl->keep) {
- if (--vsl->keep == 0)
- return (-2);
- }
-
- if (bits != NULL) {
- j = 0;
- VTAILQ_FOREACH(vrm, &vsl->matchers, next) {
- if (vrm->tag == t) {
- i = VRE_exec(vrm->re, VSL_DATA(p),
- VSL_LEN(p), 0, 0, NULL, 0, NULL);
- if (i >= 0) /* XXX ?? */
- *bits |= (uintmax_t)1 << j;
- }
- j++;
- }
- }
- *pp = p;
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ if (c == NULL || c->ptr == NULL)
+ return (0);
+ tag = VSL_TAG(c->ptr);
+ if (tag <= SLT__Bogus || tag >= SLT__Reserved)
+ return (0);
+ if (vbit_test(vsl->vbm_select, tag))
return (1);
- }
-}
-
-/*--------------------------------------------------------------------*/
-
-int
-VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv)
-{
- int i;
- unsigned u, l, s;
- uint32_t *p;
- uint64_t bitmap;
+ else if (vbit_test(vsl->vbm_supress, tag))
+ return (0);
- while (1) {
- i = VSL_NextSLT(vd, &p, &bitmap);
- if (i <= 0)
- return (i);
- u = VSL_ID(p);
- l = VSL_LEN(p);
- s = 0;
- if (VSL_CLIENT(p))
- s |= VSL_S_CLIENT;
- if (VSL_BACKEND(p))
- s |= VSL_S_BACKEND;
- i = func(priv, (enum VSL_tag_e)VSL_TAG(p),
- u, l, s, VSL_DATA(p), bitmap);
- if (i)
- return (i);
- }
+ /* Default show */
+ return (1);
}
-/*--------------------------------------------------------------------*/
-
int
-VSL_H_Print(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len,
- unsigned spec, const char *ptr, uint64_t bitmap)
+VSL_Print(struct VSL_data *vsl, const struct VSL_cursor *c, void *fo)
{
- FILE *fo = priv;
+ enum VSL_tag_e tag;
+ uint32_t vxid;
+ unsigned len;
+ const char *data;
int type;
+ int i;
- (void) bitmap;
- assert(fo != NULL);
-
- type = (spec & VSL_S_CLIENT) ? 'c' :
- (spec & VSL_S_BACKEND) ? 'b' : '-';
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ if (c == NULL || c->ptr == NULL)
+ return (0);
+ if (fo == NULL)
+ fo = stdout;
+ tag = VSL_TAG(c->ptr);
+ vxid = VSL_ID(c->ptr);
+ len = VSL_LEN(c->ptr);
+ type = VSL_CLIENT(c->ptr) ? 'c' : VSL_BACKEND(c->ptr) ? 'b' : '-';
+ data = VSL_CDATA(c->ptr);
if (tag == SLT_Debug) {
- fprintf(fo, "%5u %-12s %c \"", fd, VSL_tags[tag], type);
+ i = fprintf(fo, "%10u %-15s %c \"", vxid, VSL_tags[tag], type);
+ if (i < 0)
+ return (-5);
while (len-- > 0) {
- if (*ptr >= ' ' && *ptr <= '~')
- fprintf(fo, "%c", *ptr);
+ if (*data >= ' ' && *data <= '~')
+ i = fprintf(fo, "%c", *data);
else
- fprintf(fo, "%%%02x", (unsigned char)*ptr);
- ptr++;
+ i = fprintf(fo, "%%%02x", (unsigned char)*data);
+ if (i < 0)
+ return (-5);
+ data++;
}
- fprintf(fo, "\"\n");
+ i = fprintf(fo, "\"\n");
+ if (i < 0)
+ return (-5);
return (0);
}
- fprintf(fo, "%5u %-12s %c %.*s\n",
- fd, VSL_tags[tag], type, (int)len, ptr);
- return (0);
-}
-
-/*--------------------------------------------------------------------*/
-int
-VSL_Matched(struct VSM_data *vd, uint64_t bitmap)
-{
- struct vsl *vsl = vsl_Setup(vd);
-
- if (vsl->num_matchers > 0) {
- uint64_t t;
- t = vsl->num_matchers | (vsl->num_matchers - 1);
- return (bitmap == t);
- }
- return (1);
+ i = fprintf(fo, "%10u %-15s %c %.*s\n",
+ vxid, VSL_tags[tag], type, (int)len, data);
+ if (i < 0)
+ return (-5);
+ return (0);
}
diff --git a/lib/libvarnishapi/vsl_api.h b/lib/libvarnishapi/vsl_api.h
index b203ae8..8b70098 100644
--- a/lib/libvarnishapi/vsl_api.h
+++ b/lib/libvarnishapi/vsl_api.h
@@ -1,9 +1,10 @@
/*-
* Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006-2011 Varnish Software AS
+ * Copyright (c) 2006-2013 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Martin Blix Grydeland <martin at varnish-software.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,64 +29,38 @@
*
*/
+#include "vdef.h"
#include "vqueue.h"
+#include "vapi/vsm.h"
-#define SLEEP_USEC (50*1000)
-#define TIMEOUT_USEC (5*1000*1000)
+#define VSL_FILE_HEAD "VSL"
+int vsl_diag(struct VSL_data *vsl, const char *fmt, ...)
+ __printflike(2, 3);
-struct vsl_re_match {
- unsigned magic;
-#define VSL_RE_MATCH_MAGIC 0x4013151e
- int tag;
- vre_t *re;
- VTAILQ_ENTRY(vsl_re_match) next;
-};
-
-struct vsl {
- unsigned magic;
-#define VSL_MAGIC 0x7a31db38
-
- struct VSM_fantom vf;
-
- /* Stuff relating the log records below here */
-
- volatile uint32_t *log_start;
- volatile uint32_t *log_end;
- volatile uint32_t *log_ptr;
+typedef void vslc_delete_f(void *);
+typedef int vslc_next_f(void *);
- volatile uint32_t last_seq;
-
- /* for -r option */
- int r_fd;
- unsigned rbuflen;
- uint32_t *rbuf;
-
- int b_opt;
- int c_opt;
- int d_opt;
+struct vslc {
+ struct VSL_cursor c;
+ unsigned magic;
+#define VSLC_MAGIC 0x5007C0DE
- unsigned flags;
-#define F_SEEN_IX (1 << 0)
+ vslc_delete_f *delete;
+ vslc_next_f *next;
+};
- /*
- * Bit map of programatically selected tags, that cannot be suppressed.
- * This way programs can make sure they will see certain tags, even
- * if the user tries to supress them with -x/-X
- */
- struct vbitmap *vbm_select; /* index: tag */
+struct VSL_data {
+ unsigned magic;
+#undef VSL_MAGIC
+#define VSL_MAGIC 0x8E6C92AA
- /* Bit map of tags selected/supressed with -[iIxX] options */
- struct vbitmap *vbm_supress; /* index: tag */
+ struct vsb *diag;
- int regflags;
- vre_t *regincl;
- vre_t *regexcl;
- int num_matchers;
- VTAILQ_HEAD(, vsl_re_match) matchers;
+ unsigned flags;
+#define F_SEEN_ix (1 << 0)
- unsigned long skip;
- unsigned long keep;
+ /* Bitmaps of -ix selected tags */
+ struct vbitmap *vbm_select;
+ struct vbitmap *vbm_supress;
};
-
-struct vsl *vsl_Setup(struct VSM_data *vd);
diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c
index e10567c..72c1f22 100644
--- a/lib/libvarnishapi/vsl_arg.c
+++ b/lib/libvarnishapi/vsl_arg.c
@@ -83,71 +83,20 @@ VSL_Name2Tag(const char *name, int l)
return (n);
}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_r_arg(struct VSM_data *vd, const char *opt)
-{
- struct vsl *vsl = vsl_Setup(vd);
-
- if (vsl->r_fd > STDIN_FILENO)
- (void)close(vsl->r_fd);
- if (!strcmp(opt, "-"))
- vsl->r_fd = STDIN_FILENO;
- else
- vsl->r_fd = open(opt, O_RDONLY);
- if (vsl->r_fd < 0)
- return (vsm_diag(vd,
- "Could not open %s: %s", opt, strerror(errno)));
- if (vsl->rbuflen == 0) {
- vsl->rbuflen = BUFSIZ;
- vsl->rbuf = malloc(vsl->rbuflen);
- AN(vsl->rbuf);
- }
- return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
static int
-vsl_IX_arg(struct VSM_data *vd, const char *opt, int arg)
+vsl_ix_arg(struct VSL_data *vsl, int opt, const char *arg)
{
- struct vsl *vsl = vsl_Setup(vd);
- vre_t **rp;
- const char *error;
- int erroroffset;
-
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- if (arg == 'I')
- rp = &vsl->regincl;
- else
- rp = &vsl->regexcl;
- if (*rp != NULL)
- return (vsm_diag(vd, "Option %c can only be given once", arg));
- *rp = VRE_compile(opt, vsl->regflags, &error, &erroroffset);
- if (*rp == NULL)
- return (vsm_diag(vd, "Illegal regex: %s\n", error));
- return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_ix_arg(struct VSM_data *vd, const char *opt, int arg)
-{
- struct vsl *vsl = vsl_Setup(vd);
int i, l;
const char *b, *e;
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
/* If first option is 'i', set all bits for supression */
- if (arg == 'i' && !(vsl->flags & F_SEEN_IX))
+ if (opt == 'i' && !(vsl->flags & F_SEEN_ix))
for (i = 0; i < 256; i++)
vbit_set(vsl->vbm_supress, i);
- vsl->flags |= F_SEEN_IX;
+ vsl->flags |= F_SEEN_ix;
- for (b = opt; *b; b = e) {
+ for (b = arg; *b; b = e) {
while (isspace(*b))
b++;
e = strchr(b, ',');
@@ -160,123 +109,28 @@ vsl_ix_arg(struct VSM_data *vd, const char *opt, int arg)
l--;
i = VSL_Name2Tag(b, l);
if (i >= 0) {
- if (arg == 'x')
+ if (opt == 'x')
vbit_set(vsl->vbm_supress, i);
else
vbit_clr(vsl->vbm_supress, i);
} else if (i == -2) {
- return (vsm_diag(vd,
- "\"%*.*s\" matches multiple tags\n", l, l, b));
+ return (vsl_diag(vsl,
+ "-%c: \"%*.*s\" matches multiple tags\n",
+ (char)opt, l, l, b));
} else {
- return (vsm_diag(vd,
- "Could not match \"%*.*s\" to any tag\n", l, l, b));
+ return (vsl_diag(vsl,
+ "-%c: Could not match \"%*.*s\" to any tag\n",
+ (char)opt, l, l, b));
}
}
return (1);
}
-/*--------------------------------------------------------------------*/
-
-
-static int
-vsl_m_arg(struct VSM_data *vd, const char *opt)
-{
- struct vsl *vsl = vsl_Setup(vd);
- struct vsl_re_match *m;
- const char *error;
- char *o, *regex;
- int erroroffset;
-
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-
- if (!strchr(opt, ':'))
- return (vsm_diag(vd,
- "No : found in -m option %s\n", opt));
-
- o = strdup(opt);
- AN(o);
- regex = strchr(o, ':');
- *regex = '\0';
- regex++;
-
- ALLOC_OBJ(m, VSL_RE_MATCH_MAGIC);
- AN(m);
- m->tag = VSL_Name2Tag(o, -1);
- if (m->tag < 0) {
- (void)vsm_diag(vd, "Illegal tag %s specified\n", o);
- free(o);
- FREE_OBJ(m);
- return (-1);
- }
- /* Get tag, regex */
- m->re = VRE_compile(regex, vsl->regflags, &error, &erroroffset);
- if (m->re == NULL) {
- (void)vsm_diag(vd, "Illegal regex: %s\n", error);
- free(o);
- FREE_OBJ(m);
- return (-1);
- }
- vsl->num_matchers++;
- VTAILQ_INSERT_TAIL(&vsl->matchers, m, next);
- free(o);
- return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_s_arg(struct VSM_data *vd, const char *opt)
-{
- struct vsl *vsl = vsl_Setup(vd);
- char *end;
-
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- if (*opt == '\0')
- return (vsm_diag(vd, "number required for -s\n"));
- vsl->skip = strtoul(opt, &end, 10);
- if (*end != '\0')
- return (vsm_diag(vd, "invalid number for -k\n"));
- return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_k_arg(struct VSM_data *vd, const char *opt)
-{
- struct vsl *vsl = vsl_Setup(vd);
- char *end;
-
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- if (*opt == '\0')
- return (vsm_diag(vd, "number required for -k\n"));
- vsl->keep = strtoul(opt, &end, 10);
- if (*end != '\0')
- return (vsm_diag(vd, "invalid number for -k\n"));
- return (1);
-}
-
-/*--------------------------------------------------------------------*/
-
int
-VSL_Arg(struct VSM_data *vd, int arg, const char *opt)
+VSL_Arg(struct VSL_data *vsl, int opt, const char *arg)
{
- struct vsl *vsl = vsl_Setup(vd);
-
- switch (arg) {
- case 'b': vsl->b_opt = !vsl->b_opt; return (1);
- case 'c': vsl->c_opt = !vsl->c_opt; return (1);
- case 'd':
- vsl->d_opt = !vsl->d_opt;
- return (1);
- case 'i': case 'x': return (vsl_ix_arg(vd, opt, arg));
- case 'k': return (vsl_k_arg(vd, opt));
- case 'n': return (VSM_n_Arg(vd, opt));
- case 'r': return (vsl_r_arg(vd, opt));
- case 's': return (vsl_s_arg(vd, opt));
- case 'I': case 'X': return (vsl_IX_arg(vd, opt, arg));
- case 'm': return (vsl_m_arg(vd, opt));
- case 'C': vsl->regflags = VRE_CASELESS; return (1);
+ switch (opt) {
+ case 'i': case'x': return (vsl_ix_arg(vsl, opt, arg));
default:
return (0);
}
diff --git a/lib/libvarnishapi/vsl_cursor.c b/lib/libvarnishapi/vsl_cursor.c
new file mode 100644
index 0000000..65262d1
--- /dev/null
+++ b/lib/libvarnishapi/vsl_cursor.c
@@ -0,0 +1,359 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2013 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Martin Blix Grydeland <martin at varnish-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "vas.h"
+#include "vdef.h"
+#include "miniobj.h"
+#include "vapi/vsm.h"
+#include "vsm_api.h"
+#include "vapi/vsl.h"
+#include "vsl_api.h"
+
+struct vslc_vsm {
+ struct vslc c;
+ unsigned magic;
+#define VSLC_VSM_MAGIC 0x4D3903A6
+
+ struct VSM_data *vsm;
+ struct VSM_fantom vf;
+
+ volatile const struct VSL_head *head;
+ volatile const uint32_t *next;
+ const uint32_t *end;
+ ssize_t segsize;
+ unsigned seq;
+};
+
+static void
+vslc_vsm_delete(void *cursor)
+{
+ struct vslc_vsm *c;
+
+ CAST_OBJ_NOTNULL(c, (void *)cursor, VSLC_VSM_MAGIC);
+ FREE_OBJ(c);
+}
+
+static int
+vslc_vsm_next(void *cursor)
+{
+ struct vslc_vsm *c;
+ int diff;
+ unsigned segment;
+ uint32_t t;
+
+ CAST_OBJ_NOTNULL(c, cursor, VSLC_VSM_MAGIC);
+ CHECK_OBJ_NOTNULL(c->vsm, VSM_MAGIC);
+
+ /* Assert pointers */
+ AN(c->next);
+ assert(c->next >= c->head->log);
+ assert(c->next < c->end);
+
+ /* Check sequence number */
+ diff = c->head->seq - c->seq;
+ if (c->head->seq < c->seq)
+ /* Wrap around skips 0 */
+ diff -= 1;
+ if (diff > 1)
+ return (-3);
+
+ /* Check overrun */
+ segment = (c->next - c->head->log) / c->segsize;
+ if (segment >= VSL_SEGMENTS)
+ segment = VSL_SEGMENTS - 1;
+ diff = (segment - c->head->segment) % VSL_SEGMENTS;
+ if (0 < diff && diff <= 2)
+ return (-3);
+
+ /* Check VSL fantom and abandonment */
+ if (*c->next == VSL_ENDMARKER) {
+ if (!VSM_StillValid(c->vsm, &c->vf) ||
+ VSM_Abandoned(c->vsm))
+ return (-2);
+ }
+
+ while (1) {
+ assert(c->next >= c->head->log);
+ assert(c->next < c->end);
+ AN(c->head->seq);
+ t = *c->next;
+ AN(t);
+
+ if (t == VSL_WRAPMARKER) {
+ /* Wrap around not possible at front */
+ assert(c->next != c->head->log);
+ c->next = c->head->log;
+ continue;
+ }
+
+ if (t == VSL_ENDMARKER) {
+ if (c->next != c->head->log &&
+ c->seq != c->head->seq) {
+ /* ENDMARKER not at front and seq wrapped */
+ /* XXX: assert on this? */
+ c->next = c->head->log;
+ continue;
+ }
+ return (0);
+ }
+
+ if (c->next == c->head->log)
+ c->seq = c->head->seq;
+
+ c->c.c.ptr = (void*)(uintptr_t)c->next; /* Loose volatile */
+ c->next = VSL_NEXT(c->next);
+ return (1);
+ }
+}
+
+struct VSL_cursor *
+VSL_CursorVSM(struct VSL_data *vsl, struct VSM_data *vsm, int tail)
+{
+ struct vslc_vsm *c;
+ struct VSM_fantom vf;
+ struct VSL_head *head;
+ unsigned segment;
+
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ CHECK_OBJ_NOTNULL(vsm, VSM_MAGIC);
+
+ if (!VSM_Get(vsm, &vf, VSL_CLASS, "", "")) {
+ vsl_diag(vsl, "No VSL chunk found (child not started ?)\n");
+ return (NULL);
+ }
+
+ head = vf.b;
+ if (memcmp(head->marker, VSL_HEAD_MARKER, sizeof head->marker)) {
+ vsl_diag(vsl, "Not a VSL chunk\n");
+ return (NULL);
+ }
+ if (head->seq == 0) {
+ vsl_diag(vsl, "VSL chunk not initialized\n");
+ return (NULL);
+ }
+
+ ALLOC_OBJ(c, VSLC_VSM_MAGIC);
+ if (c == NULL) {
+ vsl_diag(vsl, "Out of memory\n");
+ return (NULL);
+ }
+ c->c.magic = VSLC_MAGIC;
+ c->c.delete = vslc_vsm_delete;
+ c->c.next = vslc_vsm_next;
+
+ c->vsm = vsm;
+ c->vf = vf;
+ c->head = head;
+ c->end = vf.e;
+ c->segsize = (c->end - c->head->log) / VSL_SEGMENTS;
+
+ if (tail) {
+ /* Locate tail of log */
+ c->next = c->head->log + c->head->segments[c->head->segment];
+ while (c->next < c->end && *c->next != VSL_ENDMARKER)
+ c->next = VSL_NEXT(c->next);
+ } else {
+ /*
+ * Starting (VSL_SEGMENTS - 3) behind varnishd. This way
+ * even if varnishd wraps immediately, we'll still have a
+ * full segment worth of log before the general constraint
+ * of at least 2 segments apart will be broken
+ */
+ segment = (c->head->segment + 3) % VSL_SEGMENTS;
+ if (c->head->segments[segment] < 0)
+ segment = 0;
+ assert(c->head->segments[segment] >= 0);
+ c->next = c->head->log + c->head->segments[segment];
+ }
+ c->seq = c->head->seq;
+
+ return (&c->c.c);
+}
+
+struct vslc_file {
+ struct vslc c;
+ unsigned magic;
+#define VSLC_FILE_MAGIC 0x1D65FFEF
+
+ int error;
+ int fd;
+ ssize_t buflen;
+ uint32_t *buf;
+};
+
+static void
+vslc_file_delete(void *cursor)
+{
+ struct vslc_file *c;
+
+ CAST_OBJ_NOTNULL(c, cursor, VSLC_FILE_MAGIC);
+ if (c->fd > STDIN_FILENO)
+ (void)close(c->fd);
+ if (c->buf != NULL)
+ free(c->buf);
+ FREE_OBJ(c);
+}
+
+static ssize_t
+vslc_file_readn(int fd, void *buf, size_t n)
+{
+ size_t t = 0;
+ ssize_t l;
+
+ while (t < n) {
+ l = read(fd, (char *)buf + t, n - t);
+ if (l <= 0)
+ return (l);
+ t += l;
+ }
+ return (t);
+}
+
+static int
+vslc_file_next(void *cursor)
+{
+ struct vslc_file *c;
+ ssize_t i, l;
+
+ CAST_OBJ_NOTNULL(c, cursor, VSLC_FILE_MAGIC);
+
+ if (c->error)
+ return (c->error);
+
+ do {
+ c->c.c.ptr = NULL;
+ assert(c->buflen >= 2 * 4);
+ i = vslc_file_readn(c->fd, c->buf, 2 * 4);
+ if (i < 0)
+ return (-4); /* I/O error */
+ if (i == 0)
+ return (-1); /* EOF */
+ assert(i == 2 * 4);
+ l = (2 + VSL_WORDS(VSL_LEN(c->buf))) * 4;
+ if (c->buflen < l) {
+ c->buf = realloc(c->buf, 2 * l);
+ AN(c->buf);
+ c->buflen = 2 * l;
+ }
+ i = vslc_file_readn(c->fd, c->buf + 2, l - 2 * 4);
+ if (i < 0)
+ return (-4); /* I/O error */
+ if (i == 0)
+ return (-1); /* EOF */
+ assert(i == l - 2 * 4);
+ c->c.c.ptr = c->buf;
+ } while (c->c.c.ptr != NULL && VSL_TAG(c->c.c.ptr) == SLT__Batch);
+ return (1);
+}
+
+struct VSL_cursor *
+VSL_CursorFile(struct VSL_data *vsl, const char *name)
+{
+ struct vslc_file *c;
+ int fd;
+ char buf[4];
+ ssize_t i;
+
+ if (!strcmp(name, "-")) {
+ fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ vsl_diag(vsl, "Could not open %s: %s\n", name,
+ strerror(errno));
+ return (NULL);
+ }
+ } else
+ fd = STDIN_FILENO;
+
+ i = vslc_file_readn(fd, buf, sizeof buf);
+ if (i <= 0) {
+ if (fd > STDIN_FILENO)
+ (void)close(fd);
+ vsl_diag(vsl, "VSL file read error: %s\n",
+ i < 0 ? strerror(errno) : "EOF");
+ return (NULL);
+ }
+ assert(i == sizeof buf);
+ if (memcmp(buf, VSL_FILE_HEAD, sizeof buf)) {
+ if (fd > STDIN_FILENO)
+ (void)close(fd);
+ vsl_diag(vsl, "Not a VSL file: %s\n", name);
+ return (NULL);
+ }
+
+ ALLOC_OBJ(c, VSLC_FILE_MAGIC);
+ if (c == NULL) {
+ if (fd > STDIN_FILENO)
+ (void)close(fd);
+ vsl_diag(vsl, "Out of memory\n");
+ return (NULL);
+ }
+ c->c.magic = VSLC_MAGIC;
+ c->c.delete = vslc_file_delete;
+ c->c.next = vslc_file_next;
+
+ c->fd = fd;
+ c->buflen = BUFSIZ;
+ c->buf = malloc(c->buflen);
+ AN(c->buf);
+
+ return (&c->c.c);
+}
+
+void
+VSL_DeleteCursor(struct VSL_cursor *cursor)
+{
+ struct vslc *c;
+
+ CAST_OBJ_NOTNULL(c, (void *)cursor, VSLC_MAGIC);
+ if (c->delete == NULL)
+ return;
+ (c->delete)(c);
+}
+
+int
+VSL_Next(struct VSL_cursor *cursor)
+{
+ struct vslc *c;
+
+ CAST_OBJ_NOTNULL(c, (void *)cursor, VSLC_MAGIC);
+ AN(c->next);
+ return ((c->next)(c));
+}
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index a957293..b40e3d4 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -163,8 +163,7 @@ VSM_Delete(struct VSM_data *vd)
free(vd->fname);
if (vd->vsc != NULL)
VSC_Delete(vd);
- if (vd->vsl != NULL)
- VSL_Delete(vd);
+ VSM_ResetError(vd);
FREE_OBJ(vd);
}
diff --git a/lib/libvarnishapi/vsm_api.h b/lib/libvarnishapi/vsm_api.h
index 2942494..04ebd7f 100644
--- a/lib/libvarnishapi/vsm_api.h
+++ b/lib/libvarnishapi/vsm_api.h
@@ -57,4 +57,3 @@ struct VSM_data {
int vsm_diag(struct VSM_data *vd, const char *fmt, ...)
__printflike(2, 3);
void VSC_Delete(struct VSM_data *vd);
-void VSL_Delete(struct VSM_data *vd);
More information about the varnish-commit
mailing list