[6.0] ed4e07b08 Add a syslog-server facility for the benefit of HAproxy testers.

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Aug 16 08:53:03 UTC 2018


commit ed4e07b08366eb59255440576d3654013e585de2
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue May 29 12:11:19 2018 +0000

    Add a syslog-server facility for the benefit of HAproxy testers.
    
    Submitted by: Frédéric Lécaille <flecaille at haproxy.com>
    
    Hacked to pieces by:    phk

diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am
index 392b02a13..0deef9cfb 100644
--- a/bin/varnishtest/Makefile.am
+++ b/bin/varnishtest/Makefile.am
@@ -57,6 +57,7 @@ varnishtest_SOURCES = \
 		vtc_proxy.c \
 		vtc_server.c \
 		vtc_subr.c \
+		vtc_syslog.c \
 		vtc_varnish.c
 
 varnishtest_LDADD = \
diff --git a/bin/varnishtest/Makefile.phk b/bin/varnishtest/Makefile.phk
index b50535d50..b406ccec4 100644
--- a/bin/varnishtest/Makefile.phk
+++ b/bin/varnishtest/Makefile.phk
@@ -6,6 +6,7 @@ PROG_SRC += vtc_logexp.c
 PROG_SRC += vtc_main.c
 PROG_SRC += vtc_barrier.c
 PROG_SRC += vtc_server.c
+PROG_SRC += vtc_syslog.c
 PROG_SRC += vtc_varnish.c
 PROG_SRC += vtc_process.c
 
diff --git a/bin/varnishtest/cmds.h b/bin/varnishtest/cmds.h
index 290237d7e..e856e6084 100644
--- a/bin/varnishtest/cmds.h
+++ b/bin/varnishtest/cmds.h
@@ -40,6 +40,7 @@ CMD(process)
 CMD(server)
 CMD(setenv)
 CMD(shell)
+CMD(syslog)
 CMD(varnish)
 CMD(varnishtest)
 #undef CMD
diff --git a/bin/varnishtest/tests/h00005.vtc b/bin/varnishtest/tests/h00005.vtc
new file mode 100644
index 000000000..44cf902e7
--- /dev/null
+++ b/bin/varnishtest/tests/h00005.vtc
@@ -0,0 +1,45 @@
+varnishtest "Exercise varnishtest syslog facility"
+
+feature ignore_unknown_macro
+feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'}
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+syslog sl1 -level notice -bind "127.0.0.1:0" {
+	recv
+	recv
+	recv info
+	expect ~ \"dip\":\"${h1_fe_1_addr}
+} -start
+
+haproxy h1 -conf {
+    global
+	log ${sl1_addr}:${sl1_port} local0
+
+    defaults
+	log global
+	timeout connect 3000
+	timeout client 5
+	timeout server  10000
+
+    frontend fe1
+	bind "fd@${fe_1}"
+	mode tcp
+	log-format {\"dip\":\"%fi\",\"dport\":\"%fp\"}
+	default_backend    be1
+
+    backend be1
+	server srv1 ${s1_addr}:${s1_port}
+} -start
+
+client c1 -connect ${h1_fe_1_sock} {
+	txreq -url "/"
+	delay 0.02
+	rxresp
+} -run
+
+syslog sl1 -wait
+
diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c
index c6c58979e..69b2d3db0 100644
--- a/bin/varnishtest/vtc.c
+++ b/bin/varnishtest/vtc.c
@@ -472,6 +472,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir,
 
 	init_macro();
 	init_server();
+	init_syslog();
 
 	vsb = VSB_new_auto();
 	AN(vsb);
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 8ad4a5a16..6ebff08a5 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -85,6 +85,7 @@ extern int feature_dns;
 extern int ign_unknown_macro;
 
 void init_server(void);
+void init_syslog(void);
 
 int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd,
 		 const char *addr);
diff --git a/bin/varnishtest/vtc_syslog.c b/bin/varnishtest/vtc_syslog.c
new file mode 100644
index 000000000..2ef8a8559
--- /dev/null
+++ b/bin/varnishtest/vtc_syslog.c
@@ -0,0 +1,649 @@
+/*-
+ * Copyright (c) 2008-2010 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Frédéric Lécaille <flecaille at haproxy.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 "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "vsa.h"
+#include "vss.h"
+#include "vtcp.h"
+#include "vre.h"
+
+#include "vtc.h"
+
+struct syslog_srv {
+	unsigned			magic;
+#define SYSLOG_SRV_MAGIC		0xbf28a692
+	char				*name;
+	struct vtclog			*vl;
+	VTAILQ_ENTRY(syslog_srv)	list;
+	char				run;
+
+	unsigned			repeat;
+	char				*spec;
+
+	int				sock;
+	char				bind[256];
+	int				lvl;
+
+	pthread_t			tp;
+	ssize_t				rxbuf_left;
+	size_t				rxbuf_sz;
+	char				*rxbuf;
+	double				timeout;
+};
+
+static pthread_mutex_t			syslog_mtx;
+
+static VTAILQ_HEAD(, syslog_srv)	syslogs =
+    VTAILQ_HEAD_INITIALIZER(syslogs);
+
+static const char * const syslog_levels[] = {
+	"emerg",
+	"alert",
+	"crit",
+	"err",
+	"warning",
+	"notice",
+	"info",
+	"debug",
+	NULL,
+};
+
+static int
+get_syslog_level(struct vtclog *vl, const char *lvl)
+{
+	int i;
+
+	for (i = 0; syslog_levels[i]; i++)
+		if (!strcmp(lvl, syslog_levels[i]))
+			return (i);
+	vtc_fatal(vl, "wrong syslog level '%s'\n", lvl);
+}
+
+/*--------------------------------------------------------------------
+ * Check if a UDP syscall return value is fatal
+ * XXX: Largely copied from VTCP, not sure if really applicable
+ */
+
+static int
+VUDP_Check(int a)
+{
+	if (a == 0)
+		return (1);
+	if (errno == ECONNRESET)
+		return (1);
+#if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__)
+	/*
+	 * Solaris returns EINVAL if the other end unexpectedly reset the
+	 * connection.
+	 * This is a bug in Solaris and documented behaviour on NetBSD.
+	 */
+	if (errno == EINVAL || errno == ETIMEDOUT || errno == EPIPE)
+		return (1);
+#elif defined (__APPLE__)
+	/*
+	 * MacOS returns EINVAL if the other end unexpectedly reset
+	 * the connection.
+	 */
+	if (errno == EINVAL)
+		return (1);
+#endif
+	return (0);
+}
+
+/*--------------------------------------------------------------------
+ * When closing a UDP connection, a couple of errno's are legit, we
+ * can't be held responsible for the other end wanting to talk to us.
+ */
+
+static void
+VUDP_close(int *s)
+{
+	int i;
+
+	i = close(*s);
+
+	assert(VUDP_Check(i));
+	*s = -1;
+}
+
+/*--------------------------------------------------------------------
+ * Given a struct suckaddr, open a socket of the appropriate type, and bind
+ * it to the requested address.
+ *
+ * If the address is an IPv6 address, the IPV6_V6ONLY option is set to
+ * avoid conflicts between INADDR_ANY and IN6ADDR_ANY.
+ */
+
+static int
+VUDP_bind(const struct suckaddr *sa, const char **errp)
+{
+	int sd, val, e;
+	socklen_t sl;
+	const struct sockaddr *so;
+	int proto;
+
+	if (errp != NULL)
+		*errp = NULL;
+
+	proto = VSA_Get_Proto(sa);
+	sd = socket(proto, SOCK_DGRAM, 0);
+	if (sd < 0) {
+		if (errp != NULL)
+			*errp = "socket(2)";
+		return (-1);
+	}
+	val = 1;
+	if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) != 0) {
+		if (errp != NULL)
+			*errp = "setsockopt(SO_REUSEADDR, 1)";
+		e = errno;
+		closefd(&sd);
+		errno = e;
+		return (-1);
+	}
+
+#ifdef IPV6_V6ONLY
+	/* forcibly use separate sockets for IPv4 and IPv6 */
+	val = 1;
+	if (proto == AF_INET6 &&
+	    setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) {
+		if (errp != NULL)
+			*errp = "setsockopt(IPV6_V6ONLY, 1)";
+		e = errno;
+		closefd(&sd);
+		errno = e;
+		return (-1);
+	}
+#endif
+	so = VSA_Get_Sockaddr(sa, &sl);
+	if (bind(sd, so, sl) != 0) {
+		if (errp != NULL)
+			*errp = "bind(2)";
+		e = errno;
+		closefd(&sd);
+		errno = e;
+		return (-1);
+	}
+	return (sd);
+}
+
+/*--------------------------------------------------------------------*/
+
+struct udp_helper {
+	const char	**errp;
+};
+
+static int v_matchproto_(vss_resolved_f)
+vudp_lo_cb(void *priv, const struct suckaddr *sa)
+{
+	int sock;
+	struct udp_helper *hp = priv;
+
+	sock = VUDP_bind(sa, hp->errp);
+	if (sock > 0) {
+		*hp->errp = NULL;
+		return (sock);
+	}
+	AN(*hp->errp);
+	return (0);
+}
+
+static int
+VUDP_bind_on(const char *addr, const char *def_port, const char **errp)
+{
+	struct udp_helper h;
+	int sock;
+
+	h.errp = errp;
+
+	sock = VSS_resolver_socktype(
+	    addr, def_port, vudp_lo_cb, &h, errp, SOCK_DGRAM);
+	if (*errp != NULL)
+		return (-1);
+	return (sock);
+}
+
+/**********************************************************************
+ * Allocate and initialize a syslog
+ */
+
+static struct syslog_srv *
+syslog_new(const char *name, struct vtclog *vl)
+{
+	struct syslog_srv *s;
+
+	VTC_CHECK_NAME(vl, name, "Syslog", 's');
+	ALLOC_OBJ(s, SYSLOG_SRV_MAGIC);
+	AN(s);
+	REPLACE(s->name, name);
+	s->vl = vtc_logopen(s->name);
+	AN(s->vl);
+
+	bprintf(s->bind, "%s", "127.0.0.1 0");
+	s->repeat = 1;
+	s->sock = -1;
+	s->lvl = -1;
+	s->timeout = vtc_maxdur * .5;		// XXX
+
+	vl = vtc_logopen(s->name);
+	AN(vl);
+
+	s->rxbuf_sz = s->rxbuf_left = 2048*1024;
+	s->rxbuf = malloc(s->rxbuf_sz);		/* XXX */
+	AN(s->rxbuf);
+
+	AZ(pthread_mutex_lock(&syslog_mtx));
+	VTAILQ_INSERT_TAIL(&syslogs, s, list);
+	AZ(pthread_mutex_unlock(&syslog_mtx));
+	return (s);
+}
+
+/**********************************************************************
+ * Clean up a syslog
+ */
+
+static void
+syslog_delete(struct syslog_srv *s)
+{
+
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+	macro_undef(s->vl, s->name, "addr");
+	macro_undef(s->vl, s->name, "port");
+	macro_undef(s->vl, s->name, "sock");
+	vtc_logclose(s->vl);
+	free(s->name);
+	free(s->rxbuf);
+	/* XXX: MEMLEAK (?) (VSS ??) */
+	FREE_OBJ(s);
+}
+
+static void
+syslog_rx(const struct syslog_srv *s, int lvl)
+{
+	ssize_t ret;
+
+	while (!vtc_error) {
+		/* Pointers to syslog priority value (see <PRIVAL>, rfc5424). */
+		char *prib, *prie, *end;
+		unsigned int prival;
+
+		VTCP_set_read_timeout(s->sock, s->timeout);
+
+		ret = recv(s->sock, s->rxbuf, s->rxbuf_sz - 1, 0);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+
+			vtc_fatal(s->vl,
+			    "%s: recv failed (fd: %d read: %s", __func__,
+			    s->sock, strerror(errno));
+		}
+		if (ret == 0)
+			vtc_fatal(s->vl,
+			    "syslog rx timeout (fd: %d %.3fs ret: %zd)",
+			    s->sock, s->timeout, ret);
+
+		s->rxbuf[ret] = '\0';
+		vtc_dump(s->vl, 4, "syslog", s->rxbuf, ret);
+
+		prib = s->rxbuf;
+		if (*prib++ != '<')
+			vtc_fatal(s->vl, "syslog PRI, no '<'");
+		prie = strchr(prib, '>');
+		if (prie == NULL)
+			vtc_fatal(s->vl, "syslog PRI, no '>'");
+
+		prival = strtoul(prib, &end, 10);
+		if (end != prie)
+			vtc_fatal(s->vl, "syslog PRI, bad number");
+
+		if (lvl >= 0 && lvl == (prival & 0x7))
+			return;
+	}
+}
+
+/**********************************************************************
+ * Syslog server bind
+ */
+
+static void
+syslog_bind(struct syslog_srv *s)
+{
+	const char *err;
+	char aaddr[VTCP_ADDRBUFSIZE];
+	char aport[VTCP_PORTBUFSIZE];
+
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+
+	if (s->sock >= 0)
+		VUDP_close(&s->sock);
+	s->sock = VUDP_bind_on(s->bind, "0", &err);
+	if (err != NULL)
+		vtc_fatal(s->vl,
+		    "Syslog server bind address (%s) cannot be resolved: %s",
+		    s->bind, err);
+	assert(s->sock > 0);
+	VTCP_myname(s->sock, aaddr, sizeof aaddr, aport, sizeof aport);
+	macro_def(s->vl, s->name, "addr", "%s", aaddr);
+	macro_def(s->vl, s->name, "port", "%s", aport);
+	macro_def(s->vl, s->name, "sock", "%s %s", aaddr, aport);
+	/* Record the actual port, and reuse it on subsequent starts */
+	bprintf(s->bind, "%s %s", aaddr, aport);
+}
+
+static void v_matchproto_(cmd_f)
+cmd_syslog_expect(CMD_ARGS)
+{
+	struct syslog_srv *s;
+	vre_t *vre;
+	const char *error;
+	int erroroffset, i, ret;
+	char *cmp, *spec;
+
+	(void)vl;
+	(void)cmd;
+	CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC);
+	AZ(strcmp(av[0], "expect"));
+	av++;
+
+	cmp = av[0];
+	spec = av[1];
+	AN(cmp);
+	AN(spec);
+	AZ(av[2]);
+
+	assert(!strcmp(cmp, "~") || !strcmp(cmp, "!~"));
+
+	vre = VRE_compile(spec, 0, &error, &erroroffset);
+	if (!vre)
+		vtc_fatal(s->vl, "REGEXP error: '%s' (@%d) (%s)",
+		    error, erroroffset, spec);
+
+	i = VRE_exec(vre, s->rxbuf, strlen(s->rxbuf), 0, 0, NULL, 0, 0);
+
+	VRE_free(&vre);
+
+	ret = (i >= 0 && *cmp == '~') || (i < 0 && *cmp == '!');
+	if (!ret)
+		vtc_fatal(s->vl, "EXPECT FAILED %s \"%s\"", cmp, spec);
+	else
+		vtc_log(s->vl, 4, "EXPECT MATCH %s \"%s\"", cmp, spec);
+}
+
+static void v_matchproto_(cmd_f)
+cmd_syslog_recv(CMD_ARGS)
+{
+	int lvl;
+	struct syslog_srv *s;
+
+	CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC);
+	(void)cmd;
+	(void)vl;
+	AZ(strcmp(av[0], "recv"));
+	av++;
+	if (av[0] == NULL)
+		lvl = s->lvl;
+	else
+		lvl = get_syslog_level(vl, av[0]);
+
+	syslog_rx(s, lvl);
+}
+
+static const struct cmds syslog_cmds[] = {
+#define CMD_SYSLOG(n) { #n, cmd_syslog_##n },
+	/* session */
+	CMD_SYSLOG(expect)
+	CMD_SYSLOG(recv)
+#undef CMD_SYSLOG
+};
+
+/**********************************************************************
+ * Syslog server thread
+ */
+
+static void *
+syslog_thread(void *priv)
+{
+	struct syslog_srv *s;
+	int i;
+
+	CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC);
+	assert(s->sock >= 0);
+
+	vtc_log(s->vl, 2, "Started on %s (level: %d)", s->bind, s->lvl);
+	for (i = 0; i < s->repeat; i++) {
+		if (s->repeat > 1)
+			vtc_log(s->vl, 3, "Iteration %d", i);
+		parse_string(s->spec, syslog_cmds, s, s->vl);
+		vtc_log(s->vl, 3, "shutting fd %d", s->sock);
+	}
+	VUDP_close(&s->sock);
+	vtc_log(s->vl, 2, "Ending");
+	return (NULL);
+}
+
+/**********************************************************************
+ * Start the syslog thread
+ */
+
+static void
+syslog_start(struct syslog_srv *s)
+{
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+	vtc_log(s->vl, 2, "Starting syslog server");
+	if (s->sock == -1)
+		syslog_bind(s);
+	vtc_log(s->vl, 1, "Bound on %s", s->bind);
+	s->run = 1;
+	AZ(pthread_create(&s->tp, NULL, syslog_thread, s));
+}
+
+/**********************************************************************
+ * Force stop the syslog thread
+ */
+
+static void
+syslog_stop(struct syslog_srv *s)
+{
+	void *res;
+
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+	vtc_log(s->vl, 2, "Stopping for syslog server");
+	(void)pthread_cancel(s->tp);
+	AZ(pthread_join(s->tp, &res));
+	s->tp = 0;
+	s->run = 0;
+}
+
+/**********************************************************************
+ * Wait for syslog thread to stop
+ */
+
+static void
+syslog_wait(struct syslog_srv *s)
+{
+	void *res;
+
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+	vtc_log(s->vl, 2, "Waiting for syslog server (%d)", s->sock);
+	AZ(pthread_join(s->tp, &res));
+	if (res != NULL && !vtc_stop)
+		vtc_fatal(s->vl, "Syslog server returned \"%p\"",
+		    (char *)res);
+	s->tp = 0;
+	s->run = 0;
+}
+
+/* SECTION: syslog syslog
+ *
+ * Define and interact with syslog instances.
+ *
+ * To define a syslog server, you'll use this syntax::
+ *
+ * syslog sNAME
+ *
+ * Arguments:
+ *
+ * sNAME
+ *     Identify the syslog server with a string which must start with 's'.
+ *
+ * \-level STRING
+ *         Set the default syslog priority level used by any subsequent "recv"
+ *         command.
+ *         Any syslog dgram with a different level will be skipped by
+ *         "recv" command. This default level value may be superseded
+ *         by "recv" command if supplied as first argument: "recv <level>".
+ *
+ * \-start
+ *         Start the syslog server thread in the background.
+ *
+ * \-repeat
+ *         Instead of processing the specification only once, do it
+ *	   NUMBER times.
+ *
+ * \-bind
+ *         Bind the syslog socket to a local address.
+ *
+ * \-wait
+ *         Wait for that thread to terminate.
+ *
+ * \-stop
+ *         Stop the syslog server thread.
+ */
+
+void v_matchproto_(cmd_f)
+cmd_syslog(CMD_ARGS)
+{
+	struct syslog_srv *s;
+
+	(void)priv;
+	(void)cmd;
+
+	if (av == NULL) {
+		/* Reset and free */
+		do {
+			AZ(pthread_mutex_lock(&syslog_mtx));
+			s = VTAILQ_FIRST(&syslogs);
+			CHECK_OBJ_ORNULL(s, SYSLOG_SRV_MAGIC);
+			if (s != NULL)
+				VTAILQ_REMOVE(&syslogs, s, list);
+			AZ(pthread_mutex_unlock(&syslog_mtx));
+			if (s != NULL) {
+				if (s->run) {
+					(void)pthread_cancel(s->tp);
+					syslog_wait(s);
+				}
+				if (s->sock >= 0)
+					VUDP_close(&s->sock);
+				syslog_delete(s);
+			}
+		} while (s != NULL);
+		return;
+	}
+
+	AZ(strcmp(av[0], "syslog"));
+	av++;
+
+	AZ(pthread_mutex_lock(&syslog_mtx));
+	VTAILQ_FOREACH(s, &syslogs, list)
+		if (!strcmp(s->name, av[0]))
+			break;
+	AZ(pthread_mutex_unlock(&syslog_mtx));
+	if (s == NULL)
+		s = syslog_new(av[0], vl);
+	CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
+	av++;
+
+	for (; *av != NULL; av++) {
+		if (vtc_error)
+			break;
+		if (!strcmp(*av, "-wait")) {
+			if (!s->run)
+				vtc_fatal(s->vl, "Syslog server not -started");
+			syslog_wait(s);
+			continue;
+		}
+
+		if (!strcmp(*av, "-stop")) {
+			syslog_stop(s);
+			continue;
+		}
+
+		/*
+		 * We do an implict -wait if people muck about with a
+		 * running syslog.
+		 * This only works if the previous ->spec has completed
+		 */
+		if (s->run)
+			syslog_wait(s);
+
+		AZ(s->run);
+		if (!strcmp(*av, "-repeat")) {
+			AN(av[1]);
+			s->repeat = atoi(av[1]);
+			av++;
+			continue;
+		}
+		if (!strcmp(*av, "-bind")) {
+			AN(av[1]);
+			bprintf(s->bind, "%s", av[1]);
+			av++;
+			syslog_bind(s);
+			continue;
+		}
+		if (!strcmp(*av, "-level")) {
+			AN(av[1]);
+			s->lvl = get_syslog_level(vl, av[1]);
+			av++;
+			continue;
+		}
+		if (!strcmp(*av, "-start")) {
+			syslog_start(s);
+			continue;
+		}
+		if (**av == '-')
+			vtc_fatal(s->vl, "Unknown syslog argument: %s", *av);
+		s->spec = *av;
+	}
+}
+
+void
+init_syslog(void)
+{
+	AZ(pthread_mutex_init(&syslog_mtx, NULL));
+}


More information about the varnish-commit mailing list