r4794 - trunk/varnish-cache/bin/varnishd
phk at varnish-cache.org
phk at varnish-cache.org
Mon May 17 09:36:04 CEST 2010
Author: phk
Date: 2010-05-17 09:36:03 +0200 (Mon, 17 May 2010)
New Revision: 4794
Added:
trunk/varnish-cache/bin/varnishd/cache_shmlog.c
trunk/varnish-cache/bin/varnishd/mgt_shmem.c
Removed:
trunk/varnish-cache/bin/varnishd/shmlog.c
Modified:
trunk/varnish-cache/bin/varnishd/Makefile.am
trunk/varnish-cache/bin/varnishd/common.h
Log:
Split shmlog.c into mgt_shmem.c and cache_shmlog.c
Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am 2010-05-15 21:50:12 UTC (rev 4793)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am 2010-05-17 07:36:03 UTC (rev 4794)
@@ -33,6 +33,7 @@
cache_pool.c \
cache_response.c \
cache_session.c \
+ cache_shmlog.c \
cache_vary.c \
cache_vcl.c \
cache_vrt.c \
@@ -46,9 +47,9 @@
mgt_cli.c \
mgt_param.c \
mgt_pool.c \
+ mgt_shmem.c \
mgt_vcc.c \
rfc2616.c \
- shmlog.c \
stevedore.c \
storage_file.c \
storage_malloc.c \
Copied: trunk/varnish-cache/bin/varnishd/cache_shmlog.c (from rev 4793, trunk/varnish-cache/bin/varnishd/shmlog.c)
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_shmlog.c (rev 0)
+++ trunk/varnish-cache/bin/varnishd/cache_shmlog.c 2010-05-17 07:36:03 UTC (rev 4794)
@@ -0,0 +1,300 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at 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.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "shmlog.h"
+#include "cache.h"
+
+static pthread_mutex_t vsl_mtx;
+
+#define LOCKSHM(foo) \
+ do { \
+ if (pthread_mutex_trylock(foo)) { \
+ AZ(pthread_mutex_lock(foo)); \
+ VSL_stats->shm_cont++; \
+ } \
+ } while (0);
+
+#define UNLOCKSHM(foo) AZ(pthread_mutex_unlock(foo))
+
+static void
+vsl_wrap(void)
+{
+
+ assert(loghead->magic == SHMLOGHEAD_MAGIC);
+ *logstart = SLT_ENDMARKER;
+ logstart[loghead->ptr] = SLT_WRAPMARKER;
+ loghead->ptr = 0;
+ VSL_stats->shm_cycles++;
+ assert(loghead->magic == SHMLOGHEAD_MAGIC);
+}
+
+static void
+vsl_hdr(enum shmlogtag tag, unsigned char *p, unsigned len, unsigned id)
+{
+
+ assert(loghead->magic == SHMLOGHEAD_MAGIC);
+ assert(len < 0x10000);
+ p[__SHMLOG_LEN_HIGH] = (len >> 8) & 0xff;
+ p[__SHMLOG_LEN_LOW] = len & 0xff;
+ p[__SHMLOG_ID_HIGH] = (id >> 24) & 0xff;
+ p[__SHMLOG_ID_MEDHIGH] = (id >> 16) & 0xff;
+ p[__SHMLOG_ID_MEDLOW] = (id >> 8) & 0xff;
+ p[__SHMLOG_ID_LOW] = id & 0xff;
+ p[SHMLOG_DATA + len] = '\0';
+ p[SHMLOG_NEXTTAG + len] = SLT_ENDMARKER;
+ /* XXX: Write barrier here */
+ p[SHMLOG_TAG] = tag;
+}
+
+/*--------------------------------------------------------------------
+ * This variant copies a byte-range directly to the log, without
+ * taking the detour over sprintf()
+ */
+
+static void
+VSLR(enum shmlogtag tag, int id, txt t)
+{
+ unsigned char *p;
+ unsigned l, mlen;
+
+ Tcheck(t);
+ mlen = params->shm_reclen;
+
+ /* Truncate */
+ l = Tlen(t);
+ if (l > mlen) {
+ l = mlen;
+ t.e = t.b + l;
+ }
+
+ /* Only hold the lock while we find our space */
+ LOCKSHM(&vsl_mtx);
+ VSL_stats->shm_writes++;
+ VSL_stats->shm_records++;
+ assert(loghead->ptr < loghead->size);
+
+ /* Wrap if necessary */
+ if (loghead->ptr + SHMLOG_NEXTTAG + l + 1 >= loghead->size)
+ vsl_wrap();
+ p = logstart + loghead->ptr;
+ loghead->ptr += SHMLOG_NEXTTAG + l;
+ assert(loghead->ptr < loghead->size);
+ UNLOCKSHM(&vsl_mtx);
+
+ memcpy(p + SHMLOG_DATA, t.b, l);
+ vsl_hdr(tag, p, l, id);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL(enum shmlogtag tag, int id, const char *fmt, ...)
+{
+ va_list ap;
+ unsigned char *p;
+ unsigned n, mlen;
+ txt t;
+
+ AN(fmt);
+ va_start(ap, fmt);
+ mlen = params->shm_reclen;
+
+ if (strchr(fmt, '%') == NULL) {
+ t.b = TRUST_ME(fmt);
+ t.e = strchr(t.b, '\0');
+ VSLR(tag, id, t);
+ } else {
+ LOCKSHM(&vsl_mtx);
+ VSL_stats->shm_writes++;
+ VSL_stats->shm_records++;
+ assert(loghead->ptr < loghead->size);
+
+ /* Wrap if we cannot fit a full size record */
+ if (loghead->ptr + SHMLOG_NEXTTAG + mlen + 1 >= loghead->size)
+ vsl_wrap();
+
+ p = logstart + loghead->ptr;
+ /* +1 for the NUL */
+ n = vsnprintf((char *)(p + SHMLOG_DATA), mlen + 1L, fmt, ap);
+ if (n > mlen)
+ n = mlen; /* we truncate long fields */
+ vsl_hdr(tag, p, n, id);
+ loghead->ptr += SHMLOG_NEXTTAG + n;
+ assert(loghead->ptr < loghead->size);
+ UNLOCKSHM(&vsl_mtx);
+ }
+ va_end(ap);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+WSL_Flush(struct worker *w, int overflow)
+{
+ unsigned char *p;
+ unsigned l;
+
+ l = pdiff(w->wlb, w->wlp);
+ if (l == 0)
+ return;
+ LOCKSHM(&vsl_mtx);
+ VSL_stats->shm_flushes += overflow;
+ VSL_stats->shm_writes++;
+ VSL_stats->shm_records += w->wlr;
+ if (loghead->ptr + l + 1 >= loghead->size)
+ vsl_wrap();
+ p = logstart + loghead->ptr;
+ p[l] = SLT_ENDMARKER;
+ loghead->ptr += l;
+ assert(loghead->ptr < loghead->size);
+ UNLOCKSHM(&vsl_mtx);
+ memcpy(p + 1, w->wlb + 1, l - 1);
+ /* XXX: memory barrier here */
+ p[0] = w->wlb[0];
+ w->wlp = w->wlb;
+ w->wlr = 0;
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+WSLR(struct worker *w, enum shmlogtag tag, int id, txt t)
+{
+ unsigned char *p;
+ unsigned l, mlen;
+
+ Tcheck(t);
+ mlen = params->shm_reclen;
+
+ /* Truncate */
+ l = Tlen(t);
+ if (l > mlen) {
+ l = mlen;
+ t.e = t.b + l;
+ }
+
+ assert(w->wlp < w->wle);
+
+ /* Wrap if necessary */
+ if (w->wlp + SHMLOG_NEXTTAG + l + 1 >= w->wle)
+ WSL_Flush(w, 1);
+ p = w->wlp;
+ w->wlp += SHMLOG_NEXTTAG + l;
+ assert(w->wlp < w->wle);
+ memcpy(p + SHMLOG_DATA, t.b, l);
+ vsl_hdr(tag, p, l, id);
+ w->wlr++;
+ if (params->diag_bitmap & 0x10000)
+ WSL_Flush(w, 0);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+WSL(struct worker *w, enum shmlogtag tag, int id, const char *fmt, ...)
+{
+ va_list ap;
+ unsigned char *p;
+ unsigned n, mlen;
+ txt t;
+
+ AN(fmt);
+ va_start(ap, fmt);
+ mlen = params->shm_reclen;
+
+ if (strchr(fmt, '%') == NULL) {
+ t.b = TRUST_ME(fmt);
+ t.e = strchr(t.b, '\0');
+ WSLR(w, tag, id, t);
+ } else {
+ assert(w->wlp < w->wle);
+
+ /* Wrap if we cannot fit a full size record */
+ if (w->wlp + SHMLOG_NEXTTAG + mlen + 1 >= w->wle)
+ WSL_Flush(w, 1);
+
+ p = w->wlp;
+ /* +1 for the NUL */
+ n = vsnprintf((char *)(p + SHMLOG_DATA), mlen + 1L, fmt, ap);
+ if (n > mlen)
+ n = mlen; /* we truncate long fields */
+ vsl_hdr(tag, p, n, id);
+ w->wlp += SHMLOG_NEXTTAG + n;
+ assert(w->wlp < w->wle);
+ w->wlr++;
+ }
+ va_end(ap);
+ if (params->diag_bitmap & 0x10000)
+ WSL_Flush(w, 0);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_Panic(int *len, char **ptr)
+{
+ static char a[1] = { '\0' };
+
+ AN(len);
+ AN(ptr);
+ if (loghead->magic == SHMLOGHEAD_MAGIC) {
+ assert(loghead->hdrsize == sizeof *loghead);
+ *len = sizeof(loghead->panicstr);
+ *ptr = loghead->panicstr;
+ } else {
+ *len = 0;
+ *ptr = a;
+ }
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSL_Init(void)
+{
+
+ assert(loghead->magic == SHMLOGHEAD_MAGIC);
+ assert(loghead->hdrsize == sizeof *loghead);
+ /* XXX more check sanity of loghead ? */
+ logstart = (unsigned char *)loghead + loghead->start;
+ AZ(pthread_mutex_init(&vsl_mtx, NULL));
+ loghead->starttime = TIM_real();
+ loghead->panicstr[0] = '\0';
+ memset(VSL_stats, 0, sizeof *VSL_stats);
+ loghead->child_pid = getpid();
+}
Modified: trunk/varnish-cache/bin/varnishd/common.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/common.h 2010-05-15 21:50:12 UTC (rev 4793)
+++ trunk/varnish-cache/bin/varnishd/common.h 2010-05-17 07:36:03 UTC (rev 4794)
@@ -41,10 +41,12 @@
/* shmlog.c */
void VSL_Panic(int *len, char **ptr);
-/* shmlog.c */
+/* mgt_shmem.c */
void VSL_MgtInit(const char *fn, unsigned size);
void VSL_MgtPid(void);
extern struct varnish_stats *VSL_stats;
+extern struct shmloghead *loghead;
+extern unsigned char *logstart;
/* varnishd.c */
struct vsb;
Copied: trunk/varnish-cache/bin/varnishd/mgt_shmem.c (from rev 4793, trunk/varnish-cache/bin/varnishd/shmlog.c)
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_shmem.c (rev 0)
+++ trunk/varnish-cache/bin/varnishd/mgt_shmem.c 2010-05-17 07:36:03 UTC (rev 4794)
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2010 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at 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.
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "shmlog.h"
+#include "mgt.h"
+#include "heritage.h"
+
+#ifndef MAP_HASSEMAPHORE
+#define MAP_HASSEMAPHORE 0 /* XXX Linux */
+#endif
+
+#ifndef MAP_NOSYNC
+#define MAP_NOSYNC 0 /* XXX Linux */
+#endif
+
+struct varnish_stats *VSL_stats;
+struct shmloghead *loghead;
+unsigned char *logstart;
+
+
+/*--------------------------------------------------------------------*/
+
+static int
+vsl_goodold(int fd)
+{
+ struct shmloghead slh;
+ int i;
+
+ memset(&slh, 0, sizeof slh); /* XXX: for flexelint */
+ i = read(fd, &slh, sizeof slh);
+ if (i != sizeof slh)
+ return (0);
+ if (slh.magic != SHMLOGHEAD_MAGIC)
+ return (0);
+ if (slh.hdrsize != sizeof slh)
+ return (0);
+ if (slh.start != sizeof slh + sizeof *params)
+ return (0);
+
+ if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) {
+ fprintf(stderr,
+ "SHMFILE owned by running varnishd master (pid=%jd)\n",
+ (intmax_t)slh.master_pid);
+ fprintf(stderr,
+ "(Use unique -n arguments if you want multiple "
+ "instances.)\n");
+ exit(2);
+ }
+
+ if (slh.child_pid != 0 && !kill(slh.child_pid, 0)) {
+ fprintf(stderr,
+ "SHMFILE used by orphan varnishd child process (pid=%jd)\n",
+ (intmax_t)slh.child_pid);
+ fprintf(stderr, "(We assume that process is busy dying.)\n");
+ return (0);
+ }
+
+ /* XXX more checks */
+ heritage.vsl_size = slh.size + slh.start;
+ return (1);
+}
+
+static void
+vsl_buildnew(const char *fn, unsigned size)
+{
+ struct shmloghead slh;
+ int i;
+
+ (void)unlink(fn);
+ heritage.vsl_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0644);
+ if (heritage.vsl_fd < 0) {
+ fprintf(stderr, "Could not open %s: %s\n",
+ fn, strerror(errno));
+ exit (1);
+ }
+
+ memset(&slh, 0, sizeof slh);
+ slh.magic = SHMLOGHEAD_MAGIC;
+ slh.hdrsize = sizeof slh;
+ slh.size = size;
+ slh.ptr = 0;
+ slh.start = sizeof slh + sizeof *params;
+ i = write(heritage.vsl_fd, &slh, sizeof slh);
+ xxxassert(i == sizeof slh);
+ heritage.vsl_size = slh.start + size;
+ AZ(ftruncate(heritage.vsl_fd, (off_t)heritage.vsl_size));
+}
+
+void
+VSL_MgtInit(const char *fn, unsigned size)
+{
+ int i;
+ struct params *pp;
+
+ i = open(fn, O_RDWR, 0644);
+ if (i >= 0 && vsl_goodold(i)) {
+ fprintf(stderr, "Using old SHMFILE\n");
+ heritage.vsl_fd = i;
+ } else {
+ fprintf(stderr, "Creating new SHMFILE\n");
+ (void)close(i);
+ vsl_buildnew(fn, size);
+ }
+
+ loghead = (void *)mmap(NULL, heritage.vsl_size,
+ PROT_READ|PROT_WRITE,
+ MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
+ heritage.vsl_fd, 0);
+ loghead->master_pid = getpid();
+ xxxassert(loghead != MAP_FAILED);
+ (void)mlock((void*)loghead, heritage.vsl_size);
+ VSL_stats = &loghead->stats;
+ pp = (void *)(loghead + 1);
+ *pp = *params;
+ params = pp;
+}
+
+void
+VSL_MgtPid(void)
+{
+
+ loghead->master_pid = getpid();
+}
Deleted: trunk/varnish-cache/bin/varnishd/shmlog.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/shmlog.c 2010-05-15 21:50:12 UTC (rev 4793)
+++ trunk/varnish-cache/bin/varnishd/shmlog.c 2010-05-17 07:36:03 UTC (rev 4794)
@@ -1,422 +0,0 @@
-/*-
- * Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006-2010 Redpill Linpro AS
- * All rights reserved.
- *
- * Author: Poul-Henning Kamp <phk at 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.
- */
-
-#include "config.h"
-
-#include "svnid.h"
-SVNID("$Id$")
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdarg.h>
-#include <sys/mman.h>
-
-#include "shmlog.h"
-#include "cache.h"
-
-#define LOCKSHM(foo) \
- do { \
- if (pthread_mutex_trylock(foo)) { \
- AZ(pthread_mutex_lock(foo)); \
- VSL_stats->shm_cont++; \
- } \
- } while (0);
-
-#define UNLOCKSHM(foo) AZ(pthread_mutex_unlock(foo))
-
-#ifndef MAP_HASSEMAPHORE
-#define MAP_HASSEMAPHORE 0 /* XXX Linux */
-#endif
-
-#ifndef MAP_NOSYNC
-#define MAP_NOSYNC 0 /* XXX Linux */
-#endif
-
-struct varnish_stats *VSL_stats;
-static struct shmloghead *loghead;
-static unsigned char *logstart;
-static pthread_mutex_t vsl_mtx;
-
-
-static void
-vsl_wrap(void)
-{
-
- assert(loghead->magic == SHMLOGHEAD_MAGIC);
- *logstart = SLT_ENDMARKER;
- logstart[loghead->ptr] = SLT_WRAPMARKER;
- loghead->ptr = 0;
- VSL_stats->shm_cycles++;
- assert(loghead->magic == SHMLOGHEAD_MAGIC);
-}
-
-static void
-vsl_hdr(enum shmlogtag tag, unsigned char *p, unsigned len, unsigned id)
-{
-
- assert(loghead->magic == SHMLOGHEAD_MAGIC);
- assert(len < 0x10000);
- p[__SHMLOG_LEN_HIGH] = (len >> 8) & 0xff;
- p[__SHMLOG_LEN_LOW] = len & 0xff;
- p[__SHMLOG_ID_HIGH] = (id >> 24) & 0xff;
- p[__SHMLOG_ID_MEDHIGH] = (id >> 16) & 0xff;
- p[__SHMLOG_ID_MEDLOW] = (id >> 8) & 0xff;
- p[__SHMLOG_ID_LOW] = id & 0xff;
- p[SHMLOG_DATA + len] = '\0';
- p[SHMLOG_NEXTTAG + len] = SLT_ENDMARKER;
- /* XXX: Write barrier here */
- p[SHMLOG_TAG] = tag;
-}
-
-/*--------------------------------------------------------------------
- * This variant copies a byte-range directly to the log, without
- * taking the detour over sprintf()
- */
-
-static void
-VSLR(enum shmlogtag tag, int id, txt t)
-{
- unsigned char *p;
- unsigned l, mlen;
-
- Tcheck(t);
- mlen = params->shm_reclen;
-
- /* Truncate */
- l = Tlen(t);
- if (l > mlen) {
- l = mlen;
- t.e = t.b + l;
- }
-
- /* Only hold the lock while we find our space */
- LOCKSHM(&vsl_mtx);
- VSL_stats->shm_writes++;
- VSL_stats->shm_records++;
- assert(loghead->ptr < loghead->size);
-
- /* Wrap if necessary */
- if (loghead->ptr + SHMLOG_NEXTTAG + l + 1 >= loghead->size)
- vsl_wrap();
- p = logstart + loghead->ptr;
- loghead->ptr += SHMLOG_NEXTTAG + l;
- assert(loghead->ptr < loghead->size);
- UNLOCKSHM(&vsl_mtx);
-
- memcpy(p + SHMLOG_DATA, t.b, l);
- vsl_hdr(tag, p, l, id);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL(enum shmlogtag tag, int id, const char *fmt, ...)
-{
- va_list ap;
- unsigned char *p;
- unsigned n, mlen;
- txt t;
-
- AN(fmt);
- va_start(ap, fmt);
- mlen = params->shm_reclen;
-
- if (strchr(fmt, '%') == NULL) {
- t.b = TRUST_ME(fmt);
- t.e = strchr(t.b, '\0');
- VSLR(tag, id, t);
- } else {
- LOCKSHM(&vsl_mtx);
- VSL_stats->shm_writes++;
- VSL_stats->shm_records++;
- assert(loghead->ptr < loghead->size);
-
- /* Wrap if we cannot fit a full size record */
- if (loghead->ptr + SHMLOG_NEXTTAG + mlen + 1 >= loghead->size)
- vsl_wrap();
-
- p = logstart + loghead->ptr;
- /* +1 for the NUL */
- n = vsnprintf((char *)(p + SHMLOG_DATA), mlen + 1L, fmt, ap);
- if (n > mlen)
- n = mlen; /* we truncate long fields */
- vsl_hdr(tag, p, n, id);
- loghead->ptr += SHMLOG_NEXTTAG + n;
- assert(loghead->ptr < loghead->size);
- UNLOCKSHM(&vsl_mtx);
- }
- va_end(ap);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-WSL_Flush(struct worker *w, int overflow)
-{
- unsigned char *p;
- unsigned l;
-
- l = pdiff(w->wlb, w->wlp);
- if (l == 0)
- return;
- LOCKSHM(&vsl_mtx);
- VSL_stats->shm_flushes += overflow;
- VSL_stats->shm_writes++;
- VSL_stats->shm_records += w->wlr;
- if (loghead->ptr + l + 1 >= loghead->size)
- vsl_wrap();
- p = logstart + loghead->ptr;
- p[l] = SLT_ENDMARKER;
- loghead->ptr += l;
- assert(loghead->ptr < loghead->size);
- UNLOCKSHM(&vsl_mtx);
- memcpy(p + 1, w->wlb + 1, l - 1);
- /* XXX: memory barrier here */
- p[0] = w->wlb[0];
- w->wlp = w->wlb;
- w->wlr = 0;
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-WSLR(struct worker *w, enum shmlogtag tag, int id, txt t)
-{
- unsigned char *p;
- unsigned l, mlen;
-
- Tcheck(t);
- mlen = params->shm_reclen;
-
- /* Truncate */
- l = Tlen(t);
- if (l > mlen) {
- l = mlen;
- t.e = t.b + l;
- }
-
- assert(w->wlp < w->wle);
-
- /* Wrap if necessary */
- if (w->wlp + SHMLOG_NEXTTAG + l + 1 >= w->wle)
- WSL_Flush(w, 1);
- p = w->wlp;
- w->wlp += SHMLOG_NEXTTAG + l;
- assert(w->wlp < w->wle);
- memcpy(p + SHMLOG_DATA, t.b, l);
- vsl_hdr(tag, p, l, id);
- w->wlr++;
- if (params->diag_bitmap & 0x10000)
- WSL_Flush(w, 0);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-WSL(struct worker *w, enum shmlogtag tag, int id, const char *fmt, ...)
-{
- va_list ap;
- unsigned char *p;
- unsigned n, mlen;
- txt t;
-
- AN(fmt);
- va_start(ap, fmt);
- mlen = params->shm_reclen;
-
- if (strchr(fmt, '%') == NULL) {
- t.b = TRUST_ME(fmt);
- t.e = strchr(t.b, '\0');
- WSLR(w, tag, id, t);
- } else {
- assert(w->wlp < w->wle);
-
- /* Wrap if we cannot fit a full size record */
- if (w->wlp + SHMLOG_NEXTTAG + mlen + 1 >= w->wle)
- WSL_Flush(w, 1);
-
- p = w->wlp;
- /* +1 for the NUL */
- n = vsnprintf((char *)(p + SHMLOG_DATA), mlen + 1L, fmt, ap);
- if (n > mlen)
- n = mlen; /* we truncate long fields */
- vsl_hdr(tag, p, n, id);
- w->wlp += SHMLOG_NEXTTAG + n;
- assert(w->wlp < w->wle);
- w->wlr++;
- }
- va_end(ap);
- if (params->diag_bitmap & 0x10000)
- WSL_Flush(w, 0);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL_Panic(int *len, char **ptr)
-{
- static char a[1] = { '\0' };
-
- AN(len);
- AN(ptr);
- if (loghead->magic == SHMLOGHEAD_MAGIC) {
- assert(loghead->hdrsize == sizeof *loghead);
- *len = sizeof(loghead->panicstr);
- *ptr = loghead->panicstr;
- } else {
- *len = 0;
- *ptr = a;
- }
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSL_Init(void)
-{
-
- assert(loghead->magic == SHMLOGHEAD_MAGIC);
- assert(loghead->hdrsize == sizeof *loghead);
- /* XXX more check sanity of loghead ? */
- logstart = (unsigned char *)loghead + loghead->start;
- AZ(pthread_mutex_init(&vsl_mtx, NULL));
- loghead->starttime = TIM_real();
- loghead->panicstr[0] = '\0';
- memset(VSL_stats, 0, sizeof *VSL_stats);
- loghead->child_pid = getpid();
-}
-
-/*--------------------------------------------------------------------*/
-
-static int
-vsl_goodold(int fd)
-{
- struct shmloghead slh;
- int i;
-
- memset(&slh, 0, sizeof slh); /* XXX: for flexelint */
- i = read(fd, &slh, sizeof slh);
- if (i != sizeof slh)
- return (0);
- if (slh.magic != SHMLOGHEAD_MAGIC)
- return (0);
- if (slh.hdrsize != sizeof slh)
- return (0);
- if (slh.start != sizeof slh + sizeof *params)
- return (0);
-
- if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) {
- fprintf(stderr,
- "SHMFILE owned by running varnishd master (pid=%jd)\n",
- (intmax_t)slh.master_pid);
- fprintf(stderr,
- "(Use unique -n arguments if you want multiple "
- "instances.)\n");
- exit(2);
- }
-
- if (slh.child_pid != 0 && !kill(slh.child_pid, 0)) {
- fprintf(stderr,
- "SHMFILE used by orphan varnishd child process (pid=%jd)\n",
- (intmax_t)slh.child_pid);
- fprintf(stderr, "(We assume that process is busy dying.)\n");
- return (0);
- }
-
- /* XXX more checks */
- heritage.vsl_size = slh.size + slh.start;
- return (1);
-}
-
-static void
-vsl_buildnew(const char *fn, unsigned size)
-{
- struct shmloghead slh;
- int i;
-
- (void)unlink(fn);
- heritage.vsl_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0644);
- if (heritage.vsl_fd < 0) {
- fprintf(stderr, "Could not open %s: %s\n",
- fn, strerror(errno));
- exit (1);
- }
-
- memset(&slh, 0, sizeof slh);
- slh.magic = SHMLOGHEAD_MAGIC;
- slh.hdrsize = sizeof slh;
- slh.size = size;
- slh.ptr = 0;
- slh.start = sizeof slh + sizeof *params;
- i = write(heritage.vsl_fd, &slh, sizeof slh);
- xxxassert(i == sizeof slh);
- heritage.vsl_size = slh.start + size;
- AZ(ftruncate(heritage.vsl_fd, (off_t)heritage.vsl_size));
-}
-
-void
-VSL_MgtInit(const char *fn, unsigned size)
-{
- int i;
- struct params *pp;
-
- i = open(fn, O_RDWR, 0644);
- if (i >= 0 && vsl_goodold(i)) {
- fprintf(stderr, "Using old SHMFILE\n");
- heritage.vsl_fd = i;
- } else {
- fprintf(stderr, "Creating new SHMFILE\n");
- (void)close(i);
- vsl_buildnew(fn, size);
- }
-
- loghead = (void *)mmap(NULL, heritage.vsl_size,
- PROT_READ|PROT_WRITE,
- MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
- heritage.vsl_fd, 0);
- loghead->master_pid = getpid();
- xxxassert(loghead != MAP_FAILED);
- (void)mlock((void*)loghead, heritage.vsl_size);
- VSL_stats = &loghead->stats;
- pp = (void *)(loghead + 1);
- *pp = *params;
- params = pp;
-}
-
-void
-VSL_MgtPid(void)
-{
-
- loghead->master_pid = getpid();
-}
More information about the varnish-commit
mailing list