Commit 0031a2fb authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move the log records to an allocated chunk of shmem.

Warning: may contain nut^H^H^Hnuts.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4805 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 16b7701e
......@@ -55,19 +55,21 @@ static void
vsl_wrap(void)
{
assert(loghead->magic == SHMLOGHEAD_MAGIC);
*logstart = SLT_ENDMARKER;
logstart[loghead->ptr] = SLT_WRAPMARKER;
loghead->ptr = 0;
assert(vsl_log_nxt < vsl_log_end);
vsl_log_start[1] = SLT_ENDMARKER;
MEMORY_BARRIER();
*vsl_log_nxt = SLT_WRAPMARKER;
MEMORY_BARRIER();
vsl_log_start[0]++;
vsl_log_nxt = vsl_log_start + 1;
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(vsl_log_nxt + SHMLOG_NEXTTAG + len < vsl_log_end);
assert(len < 0x10000);
p[__SHMLOG_LEN_HIGH] = (len >> 8) & 0xff;
p[__SHMLOG_LEN_LOW] = len & 0xff;
......@@ -76,11 +78,28 @@ vsl_hdr(enum shmlogtag tag, unsigned char *p, unsigned len, unsigned id)
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 */
MEMORY_BARRIER();
p[SHMLOG_TAG] = tag;
}
static uint8_t *
vsl_get(unsigned len)
{
uint8_t *p;
assert(vsl_log_nxt < vsl_log_end);
/* Wrap if necessary */
if (vsl_log_nxt + SHMLOG_NEXTTAG + len + 1 >= vsl_log_end) /* XXX: + 1 ?? */
vsl_wrap();
p = vsl_log_nxt;
vsl_log_nxt += SHMLOG_NEXTTAG + len;
assert(vsl_log_nxt < vsl_log_end);
*vsl_log_nxt = SLT_ENDMARKER;
return (p);
}
/*--------------------------------------------------------------------
* This variant copies a byte-range directly to the log, without
* taking the detour over sprintf()
......@@ -106,14 +125,7 @@ VSLR(enum shmlogtag tag, int id, txt t)
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);
p = vsl_get(l);
UNLOCKSHM(&vsl_mtx);
memcpy(p + SHMLOG_DATA, t.b, l);
......@@ -142,21 +154,25 @@ VSL(enum shmlogtag tag, int id, const char *fmt, ...)
LOCKSHM(&vsl_mtx);
VSL_stats->shm_writes++;
VSL_stats->shm_records++;
assert(loghead->ptr < loghead->size);
assert(vsl_log_nxt < vsl_log_end);
/* Wrap if we cannot fit a full size record */
if (loghead->ptr + SHMLOG_NEXTTAG + mlen + 1 >= loghead->size)
if (vsl_log_nxt + SHMLOG_NEXTTAG + mlen + 1 >= vsl_log_end)
vsl_wrap();
p = logstart + loghead->ptr;
p = vsl_log_nxt;
/* +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);
vsl_log_nxt += SHMLOG_NEXTTAG + n;
assert(vsl_log_nxt < vsl_log_end);
*vsl_log_nxt = SLT_ENDMARKER;
UNLOCKSHM(&vsl_mtx);
vsl_hdr(tag, p, n, id);
}
va_end(ap);
}
......@@ -166,7 +182,7 @@ VSL(enum shmlogtag tag, int id, const char *fmt, ...)
void
WSL_Flush(struct worker *w, int overflow)
{
unsigned char *p;
uint8_t *p;
unsigned l;
l = pdiff(w->wlb, w->wlp);
......@@ -176,15 +192,11 @@ WSL_Flush(struct worker *w, int overflow)
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);
p = vsl_get(l);
UNLOCKSHM(&vsl_mtx);
memcpy(p + 1, w->wlb + 1, l - 1);
/* XXX: memory barrier here */
MEMORY_BARRIER();
p[0] = w->wlb[0];
w->wlp = w->wlb;
w->wlr = 0;
......@@ -269,10 +281,6 @@ 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';
......
......@@ -41,7 +41,9 @@ void VCA_tweak_waiter(struct cli *cli, const char *arg);
/* mgt_shmem.c */
extern struct varnish_stats *VSL_stats;
extern struct shmloghead *loghead;
extern unsigned char *logstart;
extern uint8_t *vsl_log_start;
extern uint8_t *vsl_log_end;
extern uint8_t *vsl_log_nxt;
/* varnishd.c */
struct vsb;
......
......@@ -56,6 +56,9 @@ SVNID("$Id$")
struct varnish_stats *VSL_stats;
struct shmloghead *loghead;
unsigned char *logstart;
uint8_t *vsl_log_start;
uint8_t *vsl_log_end;
uint8_t *vsl_log_nxt;
static int vsl_fd = -1;
......@@ -102,7 +105,7 @@ mgt_SHM_Alloc(unsigned size, const char *type, const char *ident)
loghead->alloc_seq = seq++;
MEMORY_BARRIER();
return ((void*)(sha + 1));
return (SHA_PTR(sha));
}
return (NULL);
......@@ -114,7 +117,7 @@ mgt_SHM_Alloc(unsigned size, const char *type, const char *ident)
*/
static int
vsl_goodold(int fd, unsigned size, unsigned s2)
vsl_goodold(int fd, unsigned size)
{
struct shmloghead slh;
int i;
......@@ -153,7 +156,7 @@ vsl_goodold(int fd, unsigned size, unsigned s2)
/* Sanity checks */
if (slh.start != s2)
if (slh.shm_size != size)
return (0);
if (st.st_size != size)
......@@ -163,7 +166,7 @@ vsl_goodold(int fd, unsigned size, unsigned s2)
}
static void
vsl_buildnew(const char *fn, unsigned size, int fill, unsigned s2)
vsl_buildnew(const char *fn, unsigned size, int fill)
{
struct shmloghead slh;
int i;
......@@ -181,9 +184,7 @@ vsl_buildnew(const char *fn, unsigned size, int fill, unsigned s2)
memset(&slh, 0, sizeof slh);
slh.magic = SHMLOGHEAD_MAGIC;
slh.hdrsize = sizeof slh;
slh.size = size;
slh.ptr = 0;
slh.start = s2;
slh.shm_size = size;
i = write(vsl_fd, &slh, sizeof slh);
xxxassert(i == sizeof slh);
......@@ -272,13 +273,13 @@ mgt_SHM_Init(const char *fn, const char *l_arg)
size &= ~(ps - 1);
i = open(fn, O_RDWR, 0644);
if (i >= 0 && vsl_goodold(i, size, s2)) {
if (i >= 0 && vsl_goodold(i, size)) {
fprintf(stderr, "Using old SHMFILE\n");
vsl_fd = i;
} else {
fprintf(stderr, "Creating new SHMFILE\n");
(void)close(i);
vsl_buildnew(fn, size, fill, s2);
vsl_buildnew(fn, size, fill);
}
loghead = (void *)mmap(NULL, size,
......@@ -295,11 +296,11 @@ mgt_SHM_Init(const char *fn, const char *l_arg)
memset(&loghead->head, 0, sizeof loghead->head);
loghead->head.magic = SHMALLOC_MAGIC;
loghead->head.len = s2 - sizeof *loghead;
loghead->head.len = size - sizeof *loghead;
bprintf(loghead->head.type, "%s", "Free");
MEMORY_BARRIER();
VSL_stats = mgt_SHM_Alloc(sizeof *VSL_stats, VSL_STAT_TYPE, "");
VSL_stats = mgt_SHM_Alloc(sizeof *VSL_stats, VSL_TYPE_STAT, "");
AN(VSL_stats);
pp = mgt_SHM_Alloc(sizeof *pp, "Params", "");
......@@ -307,6 +308,15 @@ mgt_SHM_Init(const char *fn, const char *l_arg)
*pp = *params;
params = pp;
vsl_log_start = mgt_SHM_Alloc(s1, VSL_TYPE_LOG, "");
AN(vsl_log_start);
vsl_log_end = vsl_log_start + s1;
vsl_log_nxt = vsl_log_start + 1;
*vsl_log_nxt = SLT_ENDMARKER;
MEMORY_BARRIER();
*vsl_log_start = random();
MEMORY_BARRIER();
loghead->alloc_seq = random();
MEMORY_BARRIER();
}
......
......@@ -68,17 +68,7 @@ struct shmloghead {
pid_t master_pid;
pid_t child_pid;
/*
* Byte offset into the file where the fifolog starts
* This allows the header to expand later.
*/
unsigned start;
/* Length of the fifolog area in bytes */
unsigned size;
/* Current write position relative to the beginning of start */
unsigned ptr;
unsigned shm_size;
/* Panic message buffer */
char panicstr[64 * 1024];
......@@ -88,6 +78,8 @@ struct shmloghead {
struct shmalloc head;
};
#define VSL_TYPE_LOG "Log"
/*
* Record format is as follows:
*
......
......@@ -31,7 +31,7 @@
#include <stdint.h>
#define VSL_STAT_TYPE "Stats"
#define VSL_TYPE_STAT "Stats"
struct varnish_stats {
#define MAC_STAT(n, t, l, f, e) t n;
......
......@@ -89,6 +89,9 @@ static inline void
vbit_set(struct vbitmap *vb, unsigned bit)
{
if (0) /* XXX: HACK: ref it, to silence compiler */
vbit_destroy(vb);
if (bit >= vb->nbits)
vbit_expand(vb, bit);
vb->bits[VBITMAP_IDX(bit)] |= VBITMAP_BIT(bit);
......
......@@ -137,7 +137,7 @@ VSL_Open(struct VSL_data *vd)
return (1);
}
vd->vsl_lh = (void *)mmap(NULL, slh.size + sizeof slh,
vd->vsl_lh = (void *)mmap(NULL, slh.shm_size,
PROT_READ, MAP_SHARED|MAP_HASSEMAPHORE, vd->vsl_fd, 0);
if (vd->vsl_lh == MAP_FAILED) {
fprintf(stderr, "Cannot mmap %s: %s\n",
......@@ -154,8 +154,7 @@ VSL_Close(struct VSL_data *vd)
{
if (vd->vsl_lh == NULL)
return;
assert(0 == munmap((void*)vd->vsl_lh,
vd->vsl_lh->size + sizeof *vd->vsl_lh));
assert(0 == munmap((void*)vd->vsl_lh, vd->vsl_lh->shm_size));
vd->vsl_lh = NULL;
assert(vd->vsl_fd >= 0);
assert(0 == close(vd->vsl_fd));
......@@ -188,9 +187,10 @@ VSL_OpenStats(struct VSL_data *vd)
{
struct shmalloc *sha;
CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
if (VSL_Open(vd))
return (NULL);
sha = vsl_find_alloc(vd, VSL_STAT_TYPE, "");
sha = vsl_find_alloc(vd, VSL_TYPE_STAT, "");
assert(sha != NULL);
return (SHA_PTR(sha));
}
......@@ -201,23 +201,22 @@ int
VSL_OpenLog(struct VSL_data *vd)
{
unsigned char *p;
struct shmalloc *sha;
CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
if (vd->r_fd != -1)
return (0);
if (VSL_Open(vd))
return (-1);
sha = vsl_find_alloc(vd, VSL_TYPE_LOG, "");
assert(sha != NULL);
vd->head = vd->vsl_lh;
vd->logstart = (unsigned char *)vd->vsl_lh + vd->vsl_lh->start;
vd->logend = vd->logstart + vd->vsl_lh->size;
vd->ptr = vd->logstart;
vd->log_start = SHA_PTR(sha);
vd->log_end = vd->log_start + sha->len - sizeof *sha;
vd->log_ptr = vd->log_start + 1;
if (!vd->d_opt && vd->r_fd == -1) {
for (p = vd->ptr; *p != SLT_ENDMARKER; )
for (p = vd->log_ptr; *p != SLT_ENDMARKER; )
p += SHMLOG_LEN(p) + SHMLOG_NEXTTAG;
vd->ptr = p;
vd->log_ptr = p;
}
return (0);
}
......
......@@ -37,10 +37,13 @@ struct VSL_data {
unsigned magic;
#define VSL_MAGIC 0x6e3bd69b
struct shmloghead *head;
unsigned char *logstart;
unsigned char *logend;
unsigned char *ptr;
int vsl_fd;
struct shmloghead *vsl_lh;
unsigned char *log_start;
unsigned char *log_end;
unsigned char *log_ptr;
/* for -r option */
int r_fd;
......@@ -80,7 +83,4 @@ struct VSL_data {
unsigned long skip;
unsigned long keep;
int vsl_fd;
struct shmloghead *vsl_lh;
};
......@@ -119,10 +119,10 @@ vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
return (1);
}
p = vd->ptr;
p = vd->log_ptr;
for (w = 0; w < TIMEOUT_USEC;) {
if (*p == SLT_WRAPMARKER) {
p = vd->logstart;
p = vd->log_start + 1;
continue;
}
if (*p == SLT_ENDMARKER) {
......@@ -133,11 +133,11 @@ vsl_nextlog(struct VSL_data *vd, unsigned char **pp)
continue;
}
l = SHMLOG_LEN(p);
vd->ptr = p + l + SHMLOG_NEXTTAG;
vd->log_ptr = p + l + SHMLOG_NEXTTAG;
*pp = p;
return (1);
}
vd->ptr = p;
vd->log_ptr = p;
return (0);
}
......
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