Commit 2075ead3 authored by Geoff Simmons's avatar Geoff Simmons

inital commit of a Varnish 4 version -- sources complile, but nothing works

parent c69d5078
#
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
EXTRA_DIST = LICENSE autogen.sh
DISTCHECK_CONFIGURE_FLAGS = \
--enable-developer-warnings \
--enable-debugging-symbols \
--enable-dependency-tracking \
--enable-diagnostics \
--enable-extra-developer-warnings \
--enable-tests \
--enable-werror
#!/bin/sh
#
warn() {
echo "WARNING: $@" 1>&2
}
case `uname -s` in
Darwin)
LIBTOOLIZE=glibtoolize
;;
FreeBSD)
LIBTOOLIZE=libtoolize
;;
OpenBSD)
LIBTOOLIZE=libtoolize
;;
Linux)
LIBTOOLIZE=libtoolize
;;
SunOS)
LIBTOOLIZE=libtoolize
;;
*)
warn "unrecognized platform:" `uname -s`
LIBTOOLIZE=libtoolize
esac
automake_version=`automake --version | tr ' ' '\n' | egrep '^[0-9]\.[0-9a-z.-]+'`
if [ -z "$automake_version" ] ; then
warn "unable to determine automake version"
else
case $automake_version in
0.*|1.[0-8]|1.[0-8][.-]*)
warn "automake ($automake_version) detected; 1.9 or newer recommended"
;;
*)
;;
esac
fi
set -ex
$LIBTOOLIZE --copy --force
aclocal -I m4
autoheader
automake --add-missing --copy --foreign
autoconf
This diff is collapsed.
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_lib_readline.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_LIB_READLINE
#
# DESCRIPTION
#
# Searches for a readline compatible library. If found, defines
# `HAVE_LIBREADLINE'. If the found library has the `add_history' function,
# sets also `HAVE_READLINE_HISTORY'. Also checks for the locations of the
# necessary include files and sets `HAVE_READLINE_H' or
# `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or
# 'HAVE_HISTORY_H' if the corresponding include files exists.
#
# The libraries that may be readline compatible are `libedit',
# `libeditline' and `libreadline'. Sometimes we need to link a termcap
# library for readline to work, this macro tests these cases too by trying
# to link with `libtermcap', `libcurses' or `libncurses' before giving up.
#
# Here is an example of how to use the information provided by this macro
# to perform the necessary includes or declarations in a C file:
#
# #ifdef HAVE_LIBREADLINE
# # if defined(HAVE_READLINE_READLINE_H)
# # include <readline/readline.h>
# # elif defined(HAVE_READLINE_H)
# # include <readline.h>
# # else /* !defined(HAVE_READLINE_H) */
# extern char *readline ();
# # endif /* !defined(HAVE_READLINE_H) */
# char *cmdline = NULL;
# #else /* !defined(HAVE_READLINE_READLINE_H) */
# /* no readline */
# #endif /* HAVE_LIBREADLINE */
#
# #ifdef HAVE_READLINE_HISTORY
# # if defined(HAVE_READLINE_HISTORY_H)
# # include <readline/history.h>
# # elif defined(HAVE_HISTORY_H)
# # include <history.h>
# # else /* !defined(HAVE_HISTORY_H) */
# extern void add_history ();
# extern int write_history ();
# extern int read_history ();
# # endif /* defined(HAVE_READLINE_HISTORY_H) */
# /* no history */
# #endif /* HAVE_READLINE_HISTORY */
#
# LICENSE
#
# Copyright (c) 2008 Ville Laurikari <vl@iki.fi>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 6
AU_ALIAS([VL_LIB_READLINE], [AX_LIB_READLINE])
AC_DEFUN([AX_LIB_READLINE], [
AC_CACHE_CHECK([for a readline compatible library],
ax_cv_lib_readline, [
ORIG_LIBS="$LIBS"
for readline_lib in readline edit editline; do
for termcap_lib in "" termcap curses ncurses; do
if test -z "$termcap_lib"; then
TRY_LIB="-l$readline_lib"
else
TRY_LIB="-l$readline_lib -l$termcap_lib"
fi
LIBS="$ORIG_LIBS $TRY_LIB"
AC_TRY_LINK_FUNC(readline, ax_cv_lib_readline="$TRY_LIB")
if test -n "$ax_cv_lib_readline"; then
break
fi
done
if test -n "$ax_cv_lib_readline"; then
break
fi
done
if test -z "$ax_cv_lib_readline"; then
ax_cv_lib_readline="no"
fi
LIBS="$ORIG_LIBS"
])
if test "$ax_cv_lib_readline" != "no"; then
LIBS="$LIBS $ax_cv_lib_readline"
AC_DEFINE(HAVE_LIBREADLINE, 1,
[Define if you have a readline compatible library])
AC_CHECK_HEADERS(readline.h readline/readline.h)
AC_CACHE_CHECK([whether readline supports history],
ax_cv_lib_readline_history, [
ax_cv_lib_readline_history="no"
AC_TRY_LINK_FUNC(add_history, ax_cv_lib_readline_history="yes")
])
if test "$ax_cv_lib_readline_history" = "yes"; then
AC_DEFINE(HAVE_READLINE_HISTORY, 1,
[Define if your readline library has \`add_history'])
AC_CHECK_HEADERS(history.h readline/history.h)
fi
fi
])dnl
This diff is collapsed.
# ld-version-script.m4 serial 1
dnl Copyright (C) 2008, 2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson
# FIXME: The test below returns a false positive for mingw
# cross-compiles, 'local:' statements does not reduce number of
# exported symbols in a DLL. Use --disable-ld-version-script to work
# around the problem.
# gl_LD_VERSION_SCRIPT
# --------------------
# Check if LD supports linker scripts, and define automake conditional
# HAVE_LD_VERSION_SCRIPT if so.
AC_DEFUN([gl_LD_VERSION_SCRIPT],
[
AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--enable-ld-version-script],
[enable linker version script (default is enabled when possible)]),
[have_ld_version_script=$enableval], [])
if test -z "$have_ld_version_script"; then
AC_MSG_CHECKING([if LD -Wl,--version-script works])
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
cat > conftest.map <<EOF
VERS_1 {
global: sym;
};
VERS_2 {
global: sym;
} VERS_1;
EOF
AC_LINK_IFELSE(AC_LANG_PROGRAM([], []),
[have_ld_version_script=yes], [have_ld_version_script=no])
rm -f conftest.map
LDFLAGS="$save_LDFLAGS"
AC_MSG_RESULT($have_ld_version_script)
fi
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
])
#
INCLUDES = -I${VARNISH_SHARE_INCLUDE} -I${VARNISH_PKG_INCLUDE}
SUBDIRS = test
bin_PROGRAMS = varnishevent
dist_man_MANS = varnishevent.1
varnishevent_SOURCES = \
varnishevent.c \
varnishevent.h \
signals.h \
base64.c \
base64.h \
data.c \
spscq.c \
writer.c \
config.c \
log.c \
monitor.c
# format.c \
# handler.c \
# strfTIM.h \
# strfTIM.c
varnishevent_LDADD = \
${PTHREAD_LIBS} ${RT_LIBS} ${LIBM} @VARNISH_LIBS@ \
-L${VARNISH_PKG_LIB}/varnish -lvarnish
varnishevent.1: $(top_srcdir)/doc/varnishevent.rst
if HAVE_RST2MAN
${RST2MAN} $? $@
else
@echo "========================================"
@echo "You need rst2man installed to make dist"
@echo "========================================"
@false
endif
/*
* Written by Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* This file is in the public domain.
*/
#include "config.h"
#include <sys/types.h>
#include "varnishapi.h"
#include "base64.h"
static const char b64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char i64[256];
void
VB64_init(void)
{
int i;
const char *p;
for (i = 0; i < 256; i++)
i64[i] = -1;
for (p = b64, i = 0; *p; p++, i++)
i64[(int)*p] = (char)i;
i64['='] = 0;
}
int
VB64_decode(char *d, unsigned dlen, const char *s)
{
unsigned u, v, l;
int i;
u = 0;
l = 0;
while (*s) {
for (v = 0; v < 4; v++) {
if (!*s)
break;
i = i64[(int)*s++];
if (i < 0)
return (-1);
u <<= 6;
u |= i;
}
for (v = 0; v < 3; v++) {
if (l >= dlen - 1)
return (-1);
*d = (u >> 16) & 0xff;
u <<= 8;
l++;
d++;
}
}
*d = '\0';
return (0);
}
#ifdef TEST_DRIVER
#include <stdio.h>
const char *test1 =
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
int
main(int argc, char **argv)
{
int i;
char buf[BUFSIZ];
unsigned l;
(void)argc;
(void)argv;
VB64_init();
l = sizeof buf;
VB64_decode(buf, &l, test1);
printf("%s\n", buf);
return (0);
}
#endif
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2011 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* 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.
*
*/
void VB64_init(void);
int VB64_decode(char *d, unsigned dlen, const char *s);
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <unistd.h>
#include <pwd.h>
#include "varnishevent.h"
#include "vas.h"
#define DEFAULT_USER "nobody"
static const int facilitynum[8] =
{ LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5,
LOG_LOCAL6, LOG_LOCAL7 };
static int
conf_getFacility(const char *facility) {
int localnum;
if (strcasecmp(facility, "USER") == 0)
return LOG_USER;
if (strlen(facility) != 6
|| strncasecmp(facility, "LOCAL", 5) != 0
|| !isdigit(facility[5]))
return(-1);
localnum = atoi(&facility[5]);
if (localnum > 7)
return(-1);
return(facilitynum[localnum]);
}
static int
conf_getUnsignedInt(const char *rval, unsigned *i)
{
long n;
char *p;
errno = 0;
n = strtoul(rval, &p, 10);
if (errno)
return(errno);
if (strlen(p) != 0)
return(EINVAL);
if (n < 0 || n > UINT_MAX)
return(ERANGE);
*i = (unsigned int) n;
return(0);
}
#define confString(name,fld) \
if (strcmp(lval, (name)) == 0) { \
strcpy((config.fld), rval); \
return(0); \
}
#define confUnsigned(name,fld) \
if (strcmp(lval, name) == 0) { \
unsigned int i; \
int err = conf_getUnsignedInt(rval, &i); \
if (err != 0) \
return err; \
config.fld = i; \
return(0); \
}
int
CONF_Add(const char *lval, const char *rval)
{
int ret;
confString("pid.file", pid_file);
confString("varnish.name", varnish_name);
confString("log.file", log_file);
confString("varnish.bindump", varnish_bindump);
confString("cformat", cformat);
confString("bformat", bformat);
confString("zformat", zformat);
confString("output.file", output_file);
confString("syslog.ident", syslog_ident);
confUnsigned("max.reclen", max_reclen);
confUnsigned("max.headers", max_headers);
confUnsigned("max.vcl_log", max_vcl_log);
confUnsigned("max.vcl_call", max_vcl_call);
confUnsigned("max.fd", max_fd);
confUnsigned("max.data", max_data);
confUnsigned("monitor.interval", monitor_interval);
confUnsigned("output.bufsiz", output_bufsiz);
confUnsigned("housekeep.interval", housekeep_interval);
confUnsigned("ttl", ttl);
confUnsigned("append", append);
if (strcmp(lval, "syslog.facility") == 0) {
if ((ret = conf_getFacility(rval)) < 0)
return EINVAL;
config.syslog_facility = ret;
strcpy(config.syslog_facility_name, rval);
char *p = &config.syslog_facility_name[0];
do { *p = toupper(*p); } while (*++p);
return(0);
}
if (strcmp(lval, "user") == 0) {
struct passwd *pw;
pw = getpwnam(rval);
if (pw == NULL)
return(EINVAL);
strcpy(config.user_name, pw->pw_name);
config.uid = pw->pw_uid;
config.gid = pw->pw_gid;
return(0);
}
if (strcmp(lval, "output.timeout") == 0) {
char *p;
errno = 0;
double to = strtod(rval, &p);
if (errno == ERANGE)
return errno;
if (p[0] != '\0' || to < 0 || isnan(to) || !finite(to))
return EINVAL;
config.output_timeout.tv_sec = trunc(to);
config.output_timeout.tv_usec = (int)(1e6 * (to - trunc(to)));
return(0);
}
return EINVAL;
}
static int
conf_ParseLine(char *ptr, char **lval, char **rval)
{
char *endlval;
*lval = ptr;
while(*++ptr && !isspace(*ptr) && *ptr != '=')
;
if (*ptr == '\0')
return(1);
endlval = ptr;
while(isspace(*ptr) && *++ptr)
;
if (ptr == '\0' || *ptr != '=')
return(1);
while(*++ptr && isspace(*ptr))
;
if (ptr == '\0')
return(1);
*endlval = '\0';
*rval = ptr;
return(0);
}
void
CONF_Init(void)
{
struct passwd *pw;
strcpy(config.pid_file, DEFAULT_PID_FILE);
strcpy(config.cformat, DEFAULT_CFORMAT);
strcpy(config.syslog_ident, "varnishevent");
config.bformat[0] = '\0';
config.zformat[0] = '\0';
config.varnish_name[0] = '\0';
config.log_file[0] = '\0';
config.varnish_bindump[0] = '\0';
config.syslog_facility = LOG_LOCAL0;
strcpy(config.syslog_facility_name, "LOCAL0");
config.monitor_interval = 30;
config.output_bufsiz = BUFSIZ;
config.max_reclen = DEFAULT_MAX_RECLEN;
config.max_headers = DEFAULT_MAX_HEADERS;
config.max_vcl_log = DEFAULT_MAX_HEADERS;
config.max_vcl_call = DEFAULT_MAX_HEADERS;
config.max_fd = DEFAULT_MAX_FD;
config.max_data = DEFAULT_MAX_DATA;
config.housekeep_interval = DEFAULT_HOUSEKEEP_INTERVAL;
config.ttl = DEFAULT_TTL;
/* Default is stdout */
config.output_file[0] = '\0';
config.append = 0;
config.output_timeout.tv_sec = 0;
config.output_timeout.tv_usec = 0;
pw = getpwnam(DEFAULT_USER);
if (pw == NULL)
pw = getpwuid(getuid());
AN(pw);
strcpy(config.user_name, pw->pw_name);
config.uid = pw->pw_uid;
config.gid = pw->pw_gid;
}
int
CONF_ReadFile(const char *file) {
FILE *in;
char line[BUFSIZ];
int linenum = 0;
in = fopen(file, "r");
if (in == NULL) {
perror(file);
return(-1);
}
while (fgets(line, BUFSIZ, in) != NULL) {
char orig[BUFSIZ];
linenum++;
char *comment = strchr(line, '#');
if (comment != NULL)
*comment = '\0';
if (strlen(line) == 0)
continue;
char *ptr = line + strlen(line) - 1;
while (ptr != line && isspace(*ptr))
--ptr;
ptr[isspace(*ptr) ? 0 : 1] = '\0';
if (strlen(line) == 0)
continue;
ptr = line;
while (isspace(*ptr) && *++ptr)
;
strcpy(orig, ptr);
char *lval, *rval;
if (conf_ParseLine(ptr, &lval, &rval) != 0) {
fprintf(stderr, "Cannot parse %s line %d: '%s'\n", file, linenum,
orig);
return(-1);
}
int ret;
if ((ret = CONF_Add((const char *) lval, (const char *) rval)) != 0) {
fprintf(stderr, "Error in %s line %d (%s): '%s'\n", file, linenum,
strerror(ret), orig);
return(-1);
}
}
fclose(in);
return(0);
}
#define confdump(str,val) \
LOG_Log(LOG_INFO, "config: " str, (val))
void
CONF_Dump(void)
{
confdump("pid.file = %s", config.pid_file);
confdump("varnish.name = %s", config.varnish_name);
confdump("log.file = %s",
strcmp(config.log_file,"-") == 0 ? "stdout" : config.log_file);
confdump("varnish.bindump = %s", config.varnish_bindump);
confdump("output.file = %s",
EMPTY(config.output_file) ? "stdout" : config.output_file);
confdump("append = %u", config.append);
confdump("output.timeout = %f",
config.output_timeout.tv_sec
+ (double) config.output_timeout.tv_usec / 1e-6);
confdump("cformat = %s", config.cformat);
confdump("bformat = %s", config.bformat);
confdump("zformat = %s", config.zformat);
confdump("syslog.facility = %s", config.syslog_facility_name);
confdump("syslog.ident = %s", config.syslog_ident);
confdump("monitor.interval = %u", config.monitor_interval);
confdump("max.reclen = %u", config.max_reclen);
confdump("max.headers = %u", config.max_headers);
confdump("max.vcl_log = %u", config.max_vcl_log);
confdump("max.vcl_call = %u", config.max_vcl_call);
confdump("max.fd = %u", config.max_fd);
confdump("max.data = %u", config.max_data);
confdump("housekeep.interval = %u", config.housekeep_interval);
confdump("ttl = %u", config.ttl);
confdump("output.bufsiz = %u", config.output_bufsiz);
confdump("user = %s", config.user_name);
}
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Authors: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <pthread.h>
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include "varnishevent.h"
#include "vas.h"
#include "miniobj.h"
#include "vqueue.h"
#include "vsb.h"
#define FAKE_DEFAULT_LINES_PER_TX 10
#if 0
static const char *statename[3] = { "EMPTY", "OPEN", "DONE" };
#endif
static pthread_mutex_t freelist_lock = PTHREAD_MUTEX_INITIALIZER;
static char *bufptr;
static int lines_per_tx = FAKE_DEFAULT_LINES_PER_TX;
#if 0
static void
free_hdrs(hdr_t *hdrs)
{
if (hdrs != NULL) {
free(hdrs->record);
free(hdrs);
}
}
#endif
static void
data_Cleanup(void)
{
for (int i = 0; i < config.max_data; i++) {
/* XXX: etc. ... */
}
free(txn);
free(bufptr);
AZ(pthread_mutex_destroy(&freelist_lock));
}
void
DATA_Clear_Logline(tx_t *tx)
{
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
tx->state = TX_EMPTY;
/* XXX: etc. ... */
}
#define INIT_HDR_RECORDS(tag, hdr, max) do { \
if (FMT_Read_Hdr(tag)) { \
hdr = (hdr_t *) malloc(sizeof(hdr_t)); \
if (hdr == NULL) \
return errno; \
hdr->record \
= (record_t *) calloc(max, sizeof(record_t)); \
if (hdr->record == NULL) \
return errno; \
for (int j = 0; j < max; j++) { \
hdr->record[j].magic = RECORD_MAGIC; \
hdr->record[j].data = &bufptr[bufidx++ * config.max_reclen]; \
} \
} \
else { \
hdr = NULL; \
} \
} while(0)
int
DATA_Init(void)
{
int bufidx = 0;
int nrecords;
#if 0
lines_per_tx = FMT_Get_nTags();
#endif
nrecords = config.max_data * lines_per_tx;
/* XXX: set up tables of txen, lines & chunks, set/estimate sizes */
LOG_Log(LOG_DEBUG, "Allocating space for %d records (%d bytes)", nrecords,
nrecords * config.max_reclen);
bufptr = (char *) calloc(nrecords, config.max_reclen);
if (bufptr == NULL)
return errno;
txn = (tx_t *) calloc(config.max_data, sizeof(tx_t));
if (txn == NULL)
return errno;
VSTAILQ_INIT(&freetxhead);
for (int i = 0; i < config.max_data; i++) {
/* XXX: init */
txn[i].magic = TX_MAGIC;
DATA_Clear_Logline(&txn[i]);
VSTAILQ_INSERT_TAIL(&freetxhead, &txn[i], freelist);
}
assert(bufidx == nrecords);
data_open = data_done = data_occ_hi = 0;
global_nfree = config.max_data;
atexit(data_Cleanup);
return(0);
}
/*
* take all free entries from the datatable for lockless allocation
*/
unsigned
DATA_Take_Freelist(struct txhead_s *dst)
{
unsigned nfree;
AZ(pthread_mutex_lock(&freelist_lock));
VSTAILQ_CONCAT(dst, &freetxhead);
nfree = global_nfree;
global_nfree = 0;
AZ(pthread_mutex_unlock(&freelist_lock));
return nfree;
}
/*
* return to global freelist
* returned must be locked by caller, if required
*/
void
DATA_Return_Freelist(struct txhead_s *returned, unsigned nreturned)
{
AZ(pthread_mutex_lock(&freelist_lock));
VSTAILQ_CONCAT(&freetxhead, returned);
global_nfree += nreturned;
AZ(pthread_mutex_unlock(&freelist_lock));
}
#define DUMP_HDRS(vsb, ll, hdr) do { \
if (ll->hdr) \
for (j = 0; j < ll->hdr->nrec; j++) \
if (ll->hdr->record[j].len) { \
VSB_putc(vsb, '['); \
VSB_bcat(vsb, ll->hdr->record[j].data, \
ll->hdr->record[j].len); \
VSB_cat(vsb, "] "); \
} \
} while (0)
void
DATA_Dump(void)
{
#if 0
struct vsb *data;
logline_t *ll;
data = VSB_new_auto();
for (int i = 0; i < config.max_data; i++) {
int j;
if (logline == NULL || logline[i].magic != LOGLINE_MAGIC)
continue;
if (logline[i].state == DATA_EMPTY)
continue;
ll = &logline[i];
VSB_clear(data);
VSB_printf(data, "Data entry %d: state=%s dir=%c tags={",
i, statename[ll->state],
C(ll->spec) ? 'c' : B(ll->spec) ? 'b' : '-');
for (j = 0; j < ntags; j++)
if (ll->tag[j].len) {
VSB_cat(data, VSL_tags[idx2tag[j]]);
VSB_cat(data, "=[");
VSB_bcat(data, ll->tag[j].data, ll->tag[j].len);
VSB_cat(data, "] ");
}
VSB_cat(data, "} rx_headers={");
DUMP_HDRS(data, ll, rx_headers);
VSB_cat(data, "} tx_headers={");
DUMP_HDRS(data, ll, tx_headers);
VSB_cat(data, "} vcl_log={");
DUMP_HDRS(data, ll, vcl_log);
VSB_putc(data, '}');
VSB_finish(data);
LOG_Log(LOG_INFO, "%s", VSB_data(data));
}
#endif
}
This diff is collapsed.
/*-
* Copyright (c) 2012 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2012 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Authors: Geoffrey Simmons <geoffrey.simmons@uplex.de>
* Nils Goroll <nils.goroll@uplex.de>
*
* Portions adopted from varnishlog.c from the Varnish project
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2011 Varnish Software AS
*
* 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 "config.h"
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef HAVE_EXECINFO_H
#include "compat/execinfo.h"
#else
#include <execinfo.h>
#endif
#include "vas.h"
#include "vsb.h"
#include "varnishevent.h"
/* XXX: configurable? */
#define MAX_STACK_DEPTH 100
/*--------------------------------------------------------------------*/
/*
* This hack is almost verbatim from varnishd.c -- attempt to run nm(1) on
* ourselves at startup to get a mapping from lib pointers to symbolic
* function names for stack traces.
*
* +1 to phk's rant in varnishd.c about the lack of a standard for this.
*/
struct symbols {
uintptr_t a;
char *n;
VTAILQ_ENTRY(symbols) list;
};
static VTAILQ_HEAD(,symbols) symbols = VTAILQ_HEAD_INITIALIZER(symbols);
static int
symbol_lookup(struct vsb *vsb, void *ptr)
{
struct symbols *s, *s0;
uintptr_t pp;
pp = (uintptr_t)ptr;
s0 = NULL;
VTAILQ_FOREACH(s, &symbols, list) {
if (s->a > pp)
continue;
if (s0 == NULL || s->a > s0->a)
s0 = s;
}
if (s0 == NULL)
return (-1);
VSB_printf(vsb, "%p: %s+%jx", ptr, s0->n, (uintmax_t)pp - s0->a);
return (0);
}
static void
symbol_hack(const char *a0)
{
char buf[BUFSIZ], *p, *e;
FILE *fi;
uintptr_t a;
struct symbols *s;
sprintf(buf, "nm -an %s 2>/dev/null", a0);
fi = popen(buf, "r");
if (fi == NULL)
return;
while (fgets(buf, sizeof buf, fi)) {
if (buf[0] == ' ')
continue;
p = NULL;
a = strtoul(buf, &p, 16);
if (p == NULL)
continue;
if (a == 0)
continue;
if (*p++ != ' ')
continue;
p++;
if (*p++ != ' ')
continue;
if (*p <= ' ')
continue;
e = strchr(p, '\0');
AN(e);
while (e > p && isspace(e[-1]))
e--;
*e = '\0';
s = malloc(sizeof *s + strlen(p) + 1);
AN(s);
s->a = a;
s->n = (void*)(s + 1);
strcpy(s->n, p);
VTAILQ_INSERT_TAIL(&symbols, s, list);
}
(void)pclose(fi);
}
static void
stacktrace(void)
{
void *buf[MAX_STACK_DEPTH];
int depth, i;
struct vsb *sb = VSB_new_auto();
depth = backtrace (buf, MAX_STACK_DEPTH);
if (depth == 0) {
LOG_Log0(LOG_ERR, "Stacktrace empty");
return;
}
for (i = 0; i < depth; i++) {
VSB_clear(sb);
if (symbol_lookup(sb, buf[i]) < 0) {
char **strings;
strings = backtrace_symbols(&buf[i], 1);
if (strings != NULL && strings[0] != NULL)
VSB_printf(sb, "%p: %s", buf[i], strings[0]);
else
VSB_printf(sb, "%p: (?)", buf[i]);
}
VSB_finish(sb);
LOG_Log(LOG_ERR, "%s", VSB_data(sb));
}
}
void
HNDL_Init(const char *a0)
{
symbol_hack(a0);
}
void
HNDL_Abort(int sig)
{
AZ(sigaction(SIGABRT, &default_action, NULL));
LOG_Log(LOG_ALERT, "Received signal %d (%s), stacktrace follows", sig,
strsignal(sig));
stacktrace();
CONF_Dump();
DATA_Dump();
MON_Output();
LOG_Log0(LOG_ALERT, "Aborting");
abort();
}
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <syslog.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include "varnishevent.h"
static const char *level2name[LOG_DEBUG+1];
static void
syslog_setlevel(int level)
{
setlogmask(LOG_UPTO(level));
}
static void
stdio_initnames(void)
{
level2name[LOG_EMERG] = "EMERG";
level2name[LOG_ALERT] = "ALERT";
level2name[LOG_CRIT] = "CRIT";
level2name[LOG_ERR] = "ERR";
level2name[LOG_WARNING] = "WARNING";
level2name[LOG_NOTICE] = "NOTICE";
level2name[LOG_INFO] = "INFO";
level2name[LOG_DEBUG] = "DEBUG";
}
static void
stdio_log(int level, const char *msg, ...)
{
va_list ap;
if (level > logconf.level)
return;
fprintf(logconf.out, "%s: ", level2name[level]);
va_start(ap, msg);
(void) vfprintf(logconf.out, msg, ap);
va_end(ap);
fprintf(logconf.out, "\n");
fflush(logconf.out);
}
static void
stdio_setlevel(int level)
{
logconf.level = level;
}
static void
stdio_close(void)
{
fclose(logconf.out);
}
int LOG_Open(const char *progname)
{
if (EMPTY(config.log_file)) {
/* syslog */
logconf.log = syslog;
logconf.setlevel = syslog_setlevel;
logconf.close = closelog;
openlog(progname, LOG_PID | LOG_CONS | LOG_NDELAY | LOG_NOWAIT,
config.syslog_facility);
setlogmask(LOG_UPTO(LOG_INFO));
atexit(closelog);
return(0);
}
if (strcmp(config.log_file, "-") == 0)
logconf.out = stdout;
else {
logconf.out = fopen(config.log_file, "a");
if (logconf.out == NULL) {
perror(config.log_file);
return(-1);
}
}
logconf.level = LOG_INFO;
logconf.log = stdio_log;
logconf.setlevel = stdio_setlevel;
logconf.close = stdio_close;
stdio_initnames();
return(0);
}
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <syslog.h>
#include <pthread.h>
#include <errno.h>
#include "varnishevent.h"
#include "vas.h"
static int run = 0;
static pthread_t monitor;
static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
static void
log_output(void)
{
LOG_Log(LOG_INFO, "Data table: len=%u open=%u done=%u load=%.2f occ_hi=%u "
"global_free=%u", config.max_data, data_open, data_done,
100.0 * (data_open + data_done) / config.max_data,
data_occ_hi, global_nfree);
RDR_Stats();
WRT_Stats();
SPSCQ_Stats();
}
static void
monitor_cleanup(void *arg)
{
(void) arg;
log_output();
LOG_Log0(LOG_INFO, "Monitoring thread exiting");
}
static void *
monitor_main(void *arg)
{
LOG_Log(LOG_INFO, "Monitor thread running every %u secs",
config.monitor_interval);
run = 1;
pthread_cleanup_push(monitor_cleanup, arg);
while (run) {
#if 0
TIM_sleep(config.monitor_interval);
#endif
log_output();
}
pthread_cleanup_pop(0);
LOG_Log0(LOG_INFO, "Monitoring thread exiting");
pthread_exit((void *) NULL);
}
void
MON_Output(void)
{
log_output();
}
void
MON_Shutdown(void)
{
if (run) {
run = 0;
AZ(pthread_cancel(monitor));
AZ(pthread_join(monitor, NULL));
}
AZ(pthread_mutex_destroy(&stats_lock));
}
void
MON_Start(void)
{
AZ(pthread_create(&monitor, NULL, monitor_main, NULL));
}
void
MON_StatsUpdate(stats_update_t update)
{
AZ(pthread_mutex_lock(&stats_lock));
switch(update) {
case STATS_WRITTEN:
data_done--;
break;
case STATS_DONE:
data_done++;
break;
default:
/* Unreachable */
AN(NULL);
}
AZ(pthread_mutex_unlock(&stats_lock));
}
/*-
* Copyright (c) 2012 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2012 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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.
*
*/
SIGDISP(SIGTERM, terminate_action);
SIGDISP(SIGINT, terminate_action);
SIGDISP(SIGUSR1, dump_action);
SIGDISP(SIGUSR2, ignore_action);
SIGDISP(SIGABRT, stacktrace_action);
SIGDISP(SIGSEGV, stacktrace_action);
SIGDISP(SIGBUS, stacktrace_action);
SIGDISP(SIGPIPE, reopen_action);
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <syslog.h>
#include <pthread.h>
#include <errno.h>
#include "varnishevent.h"
#include "vqueue.h"
#include "vas.h"
static volatile unsigned long enqs = 0, deqs = 0, occ_hi = 0;
VSTAILQ_HEAD(spscq_s, tx_t);
struct spscq_s spscq_head = VSTAILQ_HEAD_INITIALIZER(spscq_head);
struct spscq_s deq_head = VSTAILQ_HEAD_INITIALIZER(deq_head);
static pthread_mutex_t spscq_lock = PTHREAD_MUTEX_INITIALIZER;
void
SPSCQ_Enq(tx_t *ptr)
{
AZ(pthread_mutex_lock(&spscq_lock));
assert(enqs - deqs < config.max_data);
enqs++;
if (enqs - deqs > occ_hi)
occ_hi = enqs - deqs;
VSTAILQ_INSERT_TAIL(&spscq_head, ptr, spscq);
AZ(pthread_mutex_unlock(&spscq_lock));
}
tx_t
*SPSCQ_Deq(void)
{
void *ptr;
if (VSTAILQ_EMPTY(&deq_head)) {
AZ(pthread_mutex_lock(&spscq_lock));
VSTAILQ_CONCAT(&deq_head, &spscq_head);
AZ(pthread_mutex_unlock(&spscq_lock));
}
if (VSTAILQ_EMPTY(&deq_head))
return NULL;
ptr = VSTAILQ_FIRST(&deq_head);
VSTAILQ_REMOVE_HEAD(&deq_head, spscq);
deqs++;
return ptr;
}
void
SPSCQ_Stats(void)
{
unsigned len = enqs - deqs;
LOG_Log(LOG_INFO, "Queue: max=%u len=%u load=%.2f occ_hi=%u",
config.max_data, len, 100.0 * len / config.max_data, occ_hi);
}
void
SPSCQ_Shutdown(void)
{
AZ(pthread_mutex_destroy(&spscq_lock));
}
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <time.h>
#include "strfTIM.h"
#include "vsb.h"
#include "libvarnish.h"
size_t
strfTIM(char *s, size_t max, const char *fmt, struct tm *tm, long nsec)
{
struct vsb *vsb = VSB_new(NULL, NULL, max, VSB_FIXEDLEN);
const char *p;
size_t n;
for (p = fmt; *p; p++) {
if (*p != '%') {
VSB_putc(vsb, *p);
continue;
}
p++;
if (*p == '%') {
VSB_cat(vsb, "%%");
continue;
}
if (*p != 'N') {
VSB_putc(vsb, '%');
VSB_putc(vsb, *p);
continue;
}
VSB_printf(vsb, "%09ld", nsec);
}
VSB_finish(vsb);
if (VSB_error(vsb)) {
VSB_delete(vsb);
return 0;
}
n = strftime(s, max, VSB_data(vsb), tm);
VSB_delete(vsb);
return n;
}
#define strfTIM_tz(tz) \
size_t \
strfTIM##tz(char *s, size_t max, const char *fmt, double t) \
{ \
struct timespec tim = TIM_timespec(t); \
struct tm tm; \
\
AN(tz##time_r((time_t *) &tim.tv_sec, &tm)); \
return(strfTIM(s, max, fmt, &tm, tim.tv_nsec)); \
}
strfTIM_tz(local)
strfTIM_tz(gm)
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <time.h>
#include <stddef.h>
size_t strfTIM(char *s, size_t max, const char *fmt, struct tm *tm, long nsec);
size_t strfTIMlocal(char *s, size_t max, const char *fmt, double t);
size_t strfTIMgm(char *s, size_t max, const char *fmt, double t);
This diff is collapsed.
/*-
* Copyright (c) 2013 UPLEX Nils Goroll Systemoptimierung
* Copyright (c) 2013 Otto Gmbh & Co KG
* All rights reserved.
* Use only with permission
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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 <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <limits.h>
#include <signal.h>
#include <sys/time.h>
#include "vapi/vsl.h"
#include "vqueue.h"
#include "vsb.h"
#define C(spec) ((spec) & VSL_S_CLIENT)
#define B(spec) ((spec) & VSL_S_BACKEND)
#define Z(spec) ((spec) == 0)
/* Defaults from Varnish 3.0.3 */
#define DEFAULT_MAX_RECLEN 255 /* shm_reclen */
#define DEFAULT_MAX_HEADERS 64 /* http_max_hdr */
#define DEFAULT_MAX_FD 1024
#define DEFAULT_MAX_DATA 4096
#define DEFAULT_PID_FILE "/var/run/varnishevent.pid"
#define DEFAULT_HOUSEKEEP_INTERVAL 10
#define DEFAULT_TTL 120
#define MAX_VSL_TAG 256
#define DEFAULT_CFORMAT \
"%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""
#define ALT_CFORMAT \
"%{X-Forwarded-For}i %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""
struct sigaction default_action;
typedef enum {
DATA_EMPTY = 0,
DATA_DONE,
} data_state_e;
typedef enum {
TX_EMPTY = 0,
TX_DONE,
} tx_state_e;
typedef struct {
unsigned magic;
#define RECORD_MAGIC 0xdf4399b1
char *data;
unsigned len;
} record_t;
typedef struct {
record_t *record;
unsigned nrec;
} hdr_t;
typedef struct chunk_t {
unsigned magic;
#define CHUNK_MAGIC 0x676e0d19
char *data;
VSTAILQ_ENTRY(chunk_t) freelist;
VSTAILQ_ENTRY(chunk_t) chunklist;
} chunk_t;
VSTAILQ_HEAD(chunkhead_s, chunk_t);
chunk_t *chunks;
typedef struct logline_t {
unsigned magic;
#define LOGLINE_MAGIC 0xf427a374
enum VSL_tag_e tag;
data_state_e state;
struct chunkhead_s *chunks;
unsigned len;
VSTAILQ_ENTRY(logline_t) freelist;
VSTAILQ_ENTRY(logline_t) linelist;
} logline_t;
typedef VSTAILQ_HEAD(linehead_s, logline_t) linehead_t;
typedef struct tx_t {
unsigned magic;
#define TX_MAGIC 0xff463e42
tx_state_e state;
char spec; /* 'b'/'c'/'-' */
linehead_t *lines;
VSTAILQ_ENTRY(tx_t) freelist;
VSTAILQ_ENTRY(tx_t) spscq;
} tx_t;
tx_t *txn;
VSTAILQ_HEAD(txhead_s, tx_t);
unsigned data_open;
unsigned data_done;
unsigned data_occ_hi;
int tag2idx[MAX_VSL_TAG];
enum VSL_tag_e idx2tag[MAX_VSL_TAG];
VSTAILQ_HEAD(freehead_s, logline_t);
struct txhead_s freetxhead;
unsigned global_nfree;
/* Reader waits for this condition when the freelist is exhausted.
Writer signals the condition after returning space to the freelist. */
pthread_cond_t data_ready_cond;
pthread_mutex_t data_ready_lock;
/* Writer (consumer) waits for this condition when the SPSC queue is empty.
Reader (producer) signals the condition after enqueue. */
pthread_cond_t spscq_ready_cond;
pthread_mutex_t spscq_ready_lock;
struct config {
char pid_file[BUFSIZ];
/* VSL 'n' argument */
char varnish_name[BUFSIZ];
char log_file[BUFSIZ];
char output_file[PATH_MAX];
unsigned append;
struct timeval output_timeout;
/* VSL 'r' argument */
char varnish_bindump[BUFSIZ];
/* zformat is for fd 0 (neither 'c' nor 'b') */
/* XXX: better if these weren't limited to fixed buffer sizes, but the
* length of a configurable string is limited by the length of lines
* read by CONF_ReadFile(), currently BUFSIZ
*/
char cformat[BUFSIZ];
char bformat[BUFSIZ];
char zformat[BUFSIZ];
int syslog_facility;
char syslog_facility_name[BUFSIZ];
char syslog_ident[BUFSIZ];
unsigned monitor_interval;
/* varnishd param shm_reclen */
unsigned max_reclen;
/* varnishd param http_max_hdr */
unsigned max_headers;
unsigned max_vcl_log;
unsigned max_vcl_call;
unsigned max_fd;
unsigned chunk_size;
unsigned max_data;
unsigned housekeep_interval;
unsigned ttl;
size_t output_bufsiz;
char user_name[BUFSIZ];
uid_t uid;
gid_t gid;
} config;
/* varnishevent.c */
int RDR_Waiting(void);
void RDR_Stats(void);
/* config.c */
void CONF_Init(void);
int CONF_Add(const char *lval, const char *rval);
int CONF_ReadFile(const char *file);
void CONF_Dump(void);
/* log.c */
#define EMPTY(s) (s[0] == '\0')
typedef void log_log_t(int level, const char *msg, ...);
typedef void log_setlevel_t(int level);
typedef void log_close_t(void);
struct logconf {
log_log_t *log;
log_setlevel_t *setlevel;
log_close_t *close;
FILE *out;
int level;
} logconf;
int LOG_Open(const char *progname);
/* XXX: __VA_ARGS__ can't be empty ... */
#define LOG_Log0(level, msg) logconf.log(level, msg)
#define LOG_Log(level, msg, ...) logconf.log(level, msg, __VA_ARGS__)
#define LOG_SetLevel(level) logconf.setlevel(level)
#define LOG_Close() logconf.close()
/* data.c */
int DATA_Init(void);
void DATA_Clear_Logline(tx_t *tx);
unsigned DATA_Take_Freelist(struct txhead_s *dst);
void DATA_Return_Freelist(struct txhead_s *returned, unsigned nreturned);
void DATA_Dump(void);
/* writer.c */
int WRT_Init(void);
void WRT_Start(void);
void WRT_Stats(void);
int WRT_Running(void);
int WRT_Waiting(void);
void WRT_Reopen(void);
void WRT_Halt(void);
void WRT_Shutdown(void);
/* spscq.c */
void SPSCQ_Enq(tx_t *ptr);
tx_t *SPSCQ_Deq(void);
unsigned SPSCQ_Len(void);
void SPSCQ_Stats(void);
void SPSCQ_Shutdown(void);
/* monitor.c */
typedef enum {
/* "Ending" VSL tag seen */
STATS_DONE,
/* Log line written */
STATS_WRITTEN,
} stats_update_t;
void MON_Start(void);
void MON_Shutdown(void);
void MON_StatsUpdate(stats_update_t update);
void MON_Output(void);
#if 0
/* format.c */
int FMT_Init(char *err);
char *FMT_Get_i_Arg(void);
int FMT_Get_nTags(void);
int FMT_Read_Hdr(enum VSL_tag_e tag);
void FMT_Format(logline_t *ll, struct vsb *os);
void FMT_Shutdown(void);
/* handler.c */
void HNDL_Init(const char *a0);
void HNDL_Abort(int sig);
#endif
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment