[experimental-ims] 356d46a First part of VSM overhaul, this compiles and varnishd runs, but varnishapi and users do not work yet.

Geoff Simmons geoff at varnish-cache.org
Mon Jan 9 21:52:40 CET 2012


commit 356d46a8fdb03f7179c757aa4d2160c238321f9d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Nov 18 22:18:06 2011 +0000

    First part of VSM overhaul, this compiles and varnishd runs,
    but varnishapi and users do not work yet.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index bae2572..432e22b 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -853,7 +853,7 @@ int SES_Schedule(struct sess *sp);
 void VSL_Init(void);
 void *VSM_Alloc(unsigned size, const char *class, const char *type,
     const char *ident);
-void VSM_Free(const void *ptr);
+void VSM_Free(void *ptr);
 #ifdef VSL_ENDMARKER
 void VSL(enum VSL_tag_e tag, int id, const char *fmt, ...);
 void WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t);
diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index e004896..63157c7 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -30,8 +30,10 @@
 #include "config.h"
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "cache.h"
+#include "common/heritage.h"
 
 #include "cache_backend.h"	// For w->vbc
 
@@ -300,25 +302,32 @@ WSLB(struct worker *w, enum VSL_tag_e tag, const char *fmt, ...)
 void
 VSL_Init(void)
 {
-	struct VSM_chunk *vsc;
+	uint32_t *vsl_log_start;
 
 	AZ(pthread_mutex_init(&vsl_mtx, NULL));
 	AZ(pthread_mutex_init(&vsm_mtx, NULL));
 
-	VSM__Clean();
+	vsl_log_start = VSM_Alloc(cache_param->vsl_space, VSL_CLASS, "", "");
+	AN(vsl_log_start);
+	vsl_log_start[1] = VSL_ENDMARKER;
+	VWMB();
+	do
+		*vsl_log_start = random() & 0xffff;
+	while (*vsl_log_start == 0);
+	VWMB();
 
-	VSM_ITER(vsc)
-		if (!strcmp(vsc->class, VSL_CLASS))
-			break;
-	AN(vsc);
-	vsl_start = VSM_PTR(vsc);
-	vsl_end = VSM_NEXT(vsc);
+	vsl_start = vsl_log_start;
+	vsl_end = vsl_start + cache_param->vsl_space;
 	vsl_ptr = vsl_start + 1;
 
+	VSC_C_main = VSM_Alloc(sizeof *VSC_C_main,
+	    VSC_CLASS, VSC_TYPE_MAIN, "");
+	AN(VSC_C_main);
+
 	vsl_wrap();
-	VSM_head->starttime = (intmax_t)VTIM_real();
+	// VSM_head->starttime = (intmax_t)VTIM_real();
 	memset(VSC_C_main, 0, sizeof *VSC_C_main);
-	VSM_head->child_pid = getpid();
+	// VSM_head->child_pid = getpid();
 }
 
 /*--------------------------------------------------------------------*/
@@ -327,19 +336,19 @@ void *
 VSM_Alloc(unsigned size, const char *class, const char *type,
     const char *ident)
 {
-	void *p;
+	volatile void *p;
 
 	AZ(pthread_mutex_lock(&vsm_mtx));
-	p = VSM__Alloc(size, class, type, ident);
+	p = VSM_common_alloc(heritage.vsm, size, class, type, ident);
 	AZ(pthread_mutex_unlock(&vsm_mtx));
-	return (p);
+	return (TRUST_ME(p));
 }
 
 void
-VSM_Free(const void *ptr)
+VSM_Free(void *ptr)
 {
 
 	AZ(pthread_mutex_lock(&vsm_mtx));
-	VSM__Free(ptr);
+	VSM_common_free(heritage.vsm, ptr);
 	AZ(pthread_mutex_unlock(&vsm_mtx));
 }
diff --git a/bin/varnishd/common/common.h b/bin/varnishd/common/common.h
index 8e32ec9..a35e649 100644
--- a/bin/varnishd/common/common.h
+++ b/bin/varnishd/common/common.h
@@ -74,6 +74,13 @@ void mgt_child_inherit(int fd, const char *what);
 
 
 /* vsm.c */
+struct vsm_sc;
+struct vsm_sc *VSM_common_new(void *ptr, unsigned len);
+void *VSM_common_alloc(struct vsm_sc *sc, unsigned size,
+    const char *class, const char *type, const char *ident);
+void VSM_common_free(struct vsm_sc *sc, void *ptr);
+void VSM_common_delete(struct vsm_sc *sc);
+
 // extern struct VSM_head		*VSM_head;
 // extern const struct VSM_chunk	*vsm_end;
 
diff --git a/bin/varnishd/common/common_vsm.c b/bin/varnishd/common/common_vsm.c
index 5298381..682f542 100644
--- a/bin/varnishd/common/common_vsm.c
+++ b/bin/varnishd/common/common_vsm.c
@@ -27,28 +27,35 @@
  *
  * VSM stuff common to manager and child.
  *
- * We have three potential conflicts we need to lock against here:
+ * We have three potential conflicts we need to deal with:
  *
  * VSM-studying programs (varnishstat...) vs. everybody else
  *	The VSM studying programs only have read-only access to the VSM
  *	so everybody else must use memory barriers, stable storage and
  *	similar tricks to keep the VSM image in sync (long enough) for
  *	the studying programs.
+ *	It can not be prevented, and may indeed in some cases be
+ *	desirable for such programs to write to VSM, for instance to
+ *	zero counters.
+ *	Varnishd should never trust the integrity of VSM content.
  *
  * Manager process vs child process.
- *	Will only muck about in VSM when child process is not running
- *	Responsible for cleaning up any mess left behind by dying child.
+ *	The manager will create a fresh VSM for each child process launch
+ *	and not muck about with VSM while the child runs.  If the child
+ *	crashes, the panicstring will be evacuated and the VSM possibly
+ *	saved for debugging, and a new VSM created before the child is
+ *	started again.
  *
  * Child process threads
  *	Pthread locking necessary.
  *
- * XXX: not all of this is in place yet.
  */
 
 #include "config.h"
 
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -58,181 +65,267 @@
 #include "vmb.h"
 #include "vtim.h"
 
-/* These two come from beyond (mgt_shmem.c actually) */
-struct VSM_head		*VSM_head;
-const struct VSM_chunk	*vsm_end;
-
-static unsigned
-vsm_mark(void)
-{
-	unsigned seq;
-
-	seq = VSM_head->alloc_seq;
-	VSM_head->alloc_seq = 0;
-	VWMB();
-	return (seq);
-}
-
-static void
-vsm_release(unsigned seq)
-{
+/*--------------------------------------------------------------------*/
 
-	if (seq == 0)
-		return;
-	VWMB();
-	do
-		VSM_head->alloc_seq = ++seq;
-	while (VSM_head->alloc_seq == 0);
-}
+struct vsm_range {
+	unsigned 			magic;
+#define VSM_RANGE_MAGIC			0x8d30f14
+	VTAILQ_ENTRY(vsm_range)		list;
+	unsigned			off; 
+	unsigned			len;
+	double				cool;
+	struct VSM_chunk		*chunk;
+	void				*ptr;
+};
+
+struct vsm_sc {
+	unsigned 			magic;
+#define VSM_SC_MAGIC			0x8b83270d
+	char				*b;
+	unsigned			len;
+	struct VSM_head			*head;
+	VTAILQ_HEAD(,vsm_range)		r_used;
+	VTAILQ_HEAD(,vsm_range)		r_cooling;
+	VTAILQ_HEAD(,vsm_range)		r_free;
+	VTAILQ_HEAD(,vsm_range)		r_bogus;
+};
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * The free list is sorted by size, which means that collapsing ranges
+ * on free becomes a multi-pass operation.
+ */
 
 static void
-vsm_cleanup(void)
+vsm_common_insert_free(struct vsm_sc *sc, struct vsm_range *vr)
 {
-	unsigned now = (unsigned)VTIM_mono();
-	struct VSM_chunk *sha, *sha2;
-	unsigned seq;
-
-	CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC);
-	VSM_ITER(sha) {
-		if (strcmp(sha->class, VSM_CLASS_COOL))
-			continue;
-		if (sha->state + VSM_COOL_TIME < now)
-			break;
-	}
-	if (sha == NULL)
-		return;
-	seq = vsm_mark();
-	/* First pass, free, and collapse with next if applicable */
-	VSM_ITER(sha) {
-		if (strcmp(sha->class, VSM_CLASS_COOL))
-			continue;
-		if (sha->state + VSM_COOL_TIME >= now)
-			continue;
-
-		bprintf(sha->class, "%s", VSM_CLASS_FREE);
-		bprintf(sha->type, "%s", "");
-		bprintf(sha->ident, "%s", "");
-		sha2 = VSM_NEXT(sha);
-		assert(sha2 <= vsm_end);
-		if (sha2 == vsm_end)
-			break;
-		CHECK_OBJ_NOTNULL(sha2, VSM_CHUNK_MAGIC);
-		if (!strcmp(sha2->class, VSM_CLASS_FREE)) {
-			sha->len += sha2->len;
-			memset(sha2, 0, sizeof *sha2);
+	struct vsm_range *vr2;
+
+	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+	CHECK_OBJ_NOTNULL(vr, VSM_RANGE_MAGIC);
+
+	/* First try to see if we can collapse anything */
+	VTAILQ_FOREACH(vr2, &sc->r_free, list) {
+		if (vr2->off == vr->off + vr->len) {
+			vr2->off = vr->off;
+			vr2->len += vr->len;
+			FREE_OBJ(vr);
+			VTAILQ_REMOVE(&sc->r_free, vr2, list);
+			vsm_common_insert_free(sc, vr2);
+			return;
+		}
+		if (vr->off == vr2->off + vr2->len) {
+			vr2->len += vr->len;
+			FREE_OBJ(vr);
+			VTAILQ_REMOVE(&sc->r_free, vr2, list);
+			vsm_common_insert_free(sc, vr2);
+			return;
 		}
-		sha->state = 0;
 	}
-	/* Second pass, collaps with prev if applicable */
-	VSM_ITER(sha) {
-		if (strcmp(sha->class, VSM_CLASS_FREE))
-			continue;
-		sha2 = VSM_NEXT(sha);
-		assert(sha2 <= vsm_end);
-		if (sha2 == vsm_end)
-			break;
-		CHECK_OBJ_NOTNULL(sha2, VSM_CHUNK_MAGIC);
-		if (!strcmp(sha2->class, VSM_CLASS_FREE)) {
-			sha->len += sha2->len;
-			memset(sha2, 0, sizeof *sha2);
+	/* Insert in size order */
+	VTAILQ_FOREACH(vr2, &sc->r_free, list) {
+		if (vr2->len > vr->len) {
+			VTAILQ_INSERT_BEFORE(vr2, vr, list);
+			return;
 		}
 	}
-	vsm_release(seq);
+	/* At tail, if everything in the list is smaller */
+	VTAILQ_INSERT_TAIL(&sc->r_free, vr, list);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Initialize a new VSM segment
+ */
 
-void *
-VSM__Alloc(unsigned size, const char *class, const char *type, const char *ident)
+struct vsm_sc *
+VSM_common_new(void *p, unsigned l)
 {
-	struct VSM_chunk *sha, *sha2;
-	unsigned seq;
-
-	CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC);
-
-	vsm_cleanup();
+	struct vsm_sc *sc;
+	struct vsm_range *vr;
+
+	assert(PAOK(sizeof(struct VSM_chunk)));
+	assert(PAOK(p));
+	ALLOC_OBJ(sc, VSM_SC_MAGIC);
+	AN(sc);
+	VTAILQ_INIT(&sc->r_used);
+	VTAILQ_INIT(&sc->r_cooling);
+	VTAILQ_INIT(&sc->r_free);
+	VTAILQ_INIT(&sc->r_bogus);
+	sc->b = p;
+	sc->len = l;
+
+	sc->head = (void *)sc->b;
+	memset(TRUST_ME(sc->head), 0, sizeof *sc->head);
+	sc->head->magic = VSM_HEAD_MAGIC;
+	sc->head->hdrsize = sizeof *sc->head;
+	sc->head->shm_size = l;
+
+	ALLOC_OBJ(vr, VSM_RANGE_MAGIC);
+	AN(vr);
+	vr->off = PRNDUP(sizeof(*sc->head));
+	vr->len = l - vr->off;
+	VTAILQ_INSERT_TAIL(&sc->r_free, vr, list);
+	return (sc);
+}
 
-	/* Round up to pointersize */
-	size = RUP2(size, sizeof(void*));
+/*--------------------------------------------------------------------
+ * Allocate a chunk from VSM
+ */
 
-	size += sizeof *sha;		/* Make space for the header */
+void *
+VSM_common_alloc(struct vsm_sc *sc, unsigned size,
+    const char *class, const char *type, const char *ident)
+{
+	struct vsm_range *vr, *vr2, *vr3;
+	double now = VTIM_real();
+	unsigned l1, l2;
+
+	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+	AN(size);
+
+	/* XXX: silent truncation instead of assert ? */
+	AN(class);
+	assert(strlen(class) < sizeof(vr->chunk->class));
+	AN(type);
+	assert(strlen(type) < sizeof(vr->chunk->type));
+	AN(ident);
+	assert(strlen(ident) < sizeof(vr->chunk->ident));
+
+	/* Move cooled off stuff to free list */
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_cooling, list, vr2) {
+		if (vr->cool > now)
+			break;
+		VTAILQ_REMOVE(&sc->r_cooling, vr, list);
+		vsm_common_insert_free(sc, vr);
+	}
 
-	VSM_ITER(sha) {
-		CHECK_OBJ_NOTNULL(sha, VSM_CHUNK_MAGIC);
+	size = PRNDUP(size);
+	l1 = size + sizeof(struct VSM_chunk);
+	l2 = size + 2 * sizeof(struct VSM_chunk);
 
-		if (strcmp(sha->class, VSM_CLASS_FREE))
+	/* Find space in free-list */
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_free, list, vr2) {
+		if (vr->len < l1)
 			continue;
+		if (vr->len <= l2) {
+			VTAILQ_REMOVE(&sc->r_free, vr, list);
+		} else {
+			ALLOC_OBJ(vr3, VSM_RANGE_MAGIC);
+			AN(vr3);
+			vr3->off = vr->off;
+			vr3->len = l1;
+			vr->off += l1;
+			vr->len -= l1;
+			VTAILQ_REMOVE(&sc->r_free, vr, list);
+			vsm_common_insert_free(sc, vr);
+			vr = vr3;
+		}
+		break;
+	}
 
-		if (size > sha->len)
-			continue;
+	if (vr == NULL) {
+		/*
+		 * No space in VSM, return malloc'd space
+		 */
+		ALLOC_OBJ(vr, VSM_RANGE_MAGIC);
+		AN(vr);
+		vr->ptr = malloc(size);
+		AN(vr->ptr);
+		VTAILQ_INSERT_TAIL(&sc->r_bogus, vr, list);
+		/* XXX: log + stats */
+		return (vr->ptr);
+	}
 
-		/* Mark as inconsistent while we write string fields */
-		seq = vsm_mark();
+	/* XXX: stats ? */
 
-		if (size + sizeof (*sha) < sha->len) {
-			sha2 = (void*)((uintptr_t)sha + size);
+	/* Zero the entire allocation, to avoid garbage confusing readers */
+	memset(TRUST_ME(sc->b + vr->off), 0, vr->len);
 
-			memset(sha2, 0, sizeof *sha2);
-			sha2->magic = VSM_CHUNK_MAGIC;
-			sha2->len = sha->len - size;
-			bprintf(sha2->class, "%s", VSM_CLASS_FREE);
-			sha->len = size;
-		}
+	vr->chunk = (void *)(sc->b + vr->off);
+	vr->ptr = (vr->chunk + 1);
+
+	vr->chunk->magic = VSM_CHUNK_MAGIC;
+	strcpy(TRUST_ME(vr->chunk->class), class);
+	strcpy(TRUST_ME(vr->chunk->type), type);
+	strcpy(TRUST_ME(vr->chunk->ident), ident);
+	VWMB();
 
-		bprintf(sha->class, "%s", class);
-		bprintf(sha->type, "%s", type);
-		bprintf(sha->ident, "%s", ident);
+	vr3 = VTAILQ_FIRST(&sc->r_used);
+	VTAILQ_INSERT_HEAD(&sc->r_used, vr, list);
 
-		vsm_release(seq);
-		return (VSM_PTR(sha));
+	if (vr3 != NULL) {	
+		AZ(vr3->chunk->next);
+		vr3->chunk->next = vr->off;
+	} else {
+		sc->head->first = vr->off;
 	}
-	return (NULL);
+	VWMB();
+	return (vr->ptr);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Free a chunk
+ */
 
 void
-VSM__Free(const void *ptr)
+VSM_common_free(struct vsm_sc *sc, void *ptr)
 {
-	struct VSM_chunk *sha;
-	unsigned seq;
+	struct vsm_range *vr, *vr2;
 
-	CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC);
-	VSM_ITER(sha)
-		if (VSM_PTR(sha) == ptr)
-			break;
-	AN(sha);
-	seq = vsm_mark();
-	bprintf(sha->class, "%s", VSM_CLASS_COOL);
-	sha->state = (unsigned)VTIM_mono();
-	vsm_release(seq);
+	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+	AN(ptr);
+
+	/* Look in used list, move to cooling list */
+	VTAILQ_FOREACH(vr, &sc->r_used, list) {
+		if (vr->ptr != ptr)
+			continue;
+		/* XXX: stats ? */
+		vr2 = VTAILQ_NEXT(vr, list);
+		VTAILQ_REMOVE(&sc->r_used, vr, list);
+		VTAILQ_INSERT_TAIL(&sc->r_cooling, vr, list);
+		vr->cool = VTIM_real() + 60;	/* XXX: param ? */
+		if (vr2 != NULL)
+			vr2->chunk->next = vr->chunk->next;
+		else
+			sc->head->first = vr->chunk->next;
+		VWMB();
+		vr->chunk->len = 0;
+		VWMB();
+		return;
+	}
+	/* Look in bogus list, free */
+	VTAILQ_FOREACH(vr, &sc->r_bogus, list) {
+		if (vr->ptr == ptr) {
+			VTAILQ_REMOVE(&sc->r_bogus, vr, list);
+			FREE_OBJ(vr);
+			/* XXX: stats ? */
+			free(TRUST_ME(ptr));
+			return;
+		}
+	}
+	/* Panic */
+	assert(ptr == "Bogus pointer freed");
 }
 
 /*--------------------------------------------------------------------
- * Free all allocations after the mark (ie: allocated by child).
+ * Delete a VSM segment
  */
 
 void
-VSM__Clean(void)
+VSM_common_delete(struct vsm_sc *sc)
 {
-	struct VSM_chunk *sha;
-	unsigned f, seq;
-
-	CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC);
-	f = 0;
-	seq = vsm_mark();
-	VSM_ITER(sha) {
-		if (f == 0 && !strcmp(sha->class, VSM_CLASS_MARK)) {
-			f = 1;
-			continue;
-		}
-		if (f == 0)
-			continue;
-		if (strcmp(sha->class, VSM_CLASS_FREE) &&
-		    strcmp(sha->class, VSM_CLASS_COOL))
-			VSM__Free(VSM_PTR(sha));
+	struct vsm_range *vr, *vr2;
+
+	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_free, list, vr2)
+		FREE_OBJ(vr);
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_used, list, vr2)
+		FREE_OBJ(vr);
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_cooling, list, vr2)
+		FREE_OBJ(vr);
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_bogus, list, vr2) {
+		free(TRUST_ME(vr->ptr));
+		FREE_OBJ(vr);
 	}
-	vsm_release(seq);
+	sc->head->magic = 0;
+	FREE_OBJ(sc);
 }
diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h
index 36433bb..db8b1f0 100644
--- a/bin/varnishd/common/heritage.h
+++ b/bin/varnishd/common/heritage.h
@@ -29,6 +29,8 @@
  * This file contains the heritage passed when mgt forks cache
  */
 
+struct vsm_sc;
+
 struct listen_sock {
 	unsigned			magic;
 #define LISTEN_SOCK_MAGIC		0x999e4b57
@@ -56,6 +58,8 @@ struct heritage {
 	/* Hash method */
 	const struct hash_slinger	*hash;
 
+	struct vsm_sc			*vsm;
+
 	char				*name;
 	char                            identity[1024];
 };
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 0650413..571aa23 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -110,9 +110,8 @@ extern unsigned mgt_vcc_err_unref;
 		syslog(pri, fmt, __VA_ARGS__);		\
 	} while (0)
 
-#define VSM_Alloc(a, b, c, d)	VSM__Alloc(a,b,c,d)
-#define VSM_Free(a)		VSM__Free(a)
-#define VSM_Clean()		VSM__Clean()
+#define VSM_Alloc(a, b, c, d)	VSM_common_alloc(heritage.vsm, a,b,c,d)
+#define VSM_Free(a)		VSM_common_free(heritage.vsm, a)
 
 #if defined(PTHREAD_CANCELED) || defined(PTHREAD_MUTEX_DEFAULT)
 #error "Keep pthreads out of in manager process"
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index 1d46d82..aa4fffe 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -493,15 +493,15 @@ mgt_cli_secret(const char *S_arg)
 {
 	int i, fd;
 	char buf[BUFSIZ];
-	char *p;
+	volatile char *p;
 
 	/* Save in shmem */
 	i = strlen(S_arg);
 	p = VSM_Alloc(i + 1, "Arg", "-S", "");
 	AN(p);
-	strcpy(p, S_arg);
+	memcpy(TRUST_ME(p), S_arg, i + 1);
 
-	srandomdev();
+	srandomdev();			/* XXX: why here ??? */
 	fd = open(S_arg, O_RDONLY);
 	if (fd < 0) {
 		fprintf(stderr, "Can not open secret-file \"%s\"\n", S_arg);
@@ -527,7 +527,7 @@ mgt_cli_telnet(const char *T_arg)
 	struct vss_addr **ta;
 	int i, n, sock, good;
 	struct telnet *tn;
-	char *p;
+	volatile char *p;
 	struct vsb *vsb;
 	char abuf[VTCP_ADDRBUFSIZE];
 	char pbuf[VTCP_PORTBUFSIZE];
@@ -566,7 +566,7 @@ mgt_cli_telnet(const char *T_arg)
 	/* Save in shmem */
 	p = VSM_Alloc(VSB_len(vsb) + 1, "Arg", "-T", "");
 	AN(p);
-	strcpy(p, VSB_data(vsb));
+	memcpy(TRUST_ME(p), VSB_data(vsb), VSB_len(vsb) + 1);
 	VSB_delete(vsb);
 }
 
diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c
index ff8992e..4e63c16 100644
--- a/bin/varnishd/mgt/mgt_main.c
+++ b/bin/varnishd/mgt/mgt_main.c
@@ -654,8 +654,6 @@ main(int argc, char * const *argv)
 	if (T_arg != NULL)
 		mgt_cli_telnet(T_arg);
 
-	AN(VSM_Alloc(0, VSM_CLASS_MARK, "", ""));
-
 	MGT_Run();
 
 	if (pfh != NULL)
diff --git a/bin/varnishd/mgt/mgt_shmem.c b/bin/varnishd/mgt/mgt_shmem.c
index d1bf18e..6095d9f 100644
--- a/bin/varnishd/mgt/mgt_shmem.c
+++ b/bin/varnishd/mgt/mgt_shmem.c
@@ -169,9 +169,8 @@ vsl_n_check(int fd)
  */
 
 static void
-vsl_buildnew(const char *fn, unsigned size, int fill)
+vsl_buildnew(const char *fn, ssize_t size)
 {
-	struct VSM_head slh;
 	int i;
 	unsigned u;
 	char buf[64*1024];
@@ -189,26 +188,16 @@ vsl_buildnew(const char *fn, unsigned size, int fill)
 	flags &= ~O_NONBLOCK;
 	AZ(fcntl(vsl_fd, F_SETFL, flags));
 
-	memset(&slh, 0, sizeof slh);
-	slh.magic = VSM_HEAD_MAGIC;
-	slh.hdrsize = sizeof slh;
-	slh.shm_size = size;
-	i = write(vsl_fd, &slh, sizeof slh);
-	xxxassert(i == sizeof slh);
-
-	if (fill) {
-		memset(buf, 0, sizeof buf);
-		for (u = sizeof slh; u < size; ) {
-			i = write(vsl_fd, buf, sizeof buf);
-			if (i <= 0) {
-				fprintf(stderr, "Write error %s: %s\n",
-				    fn, strerror(errno));
-				exit (1);
-			}
-			u += i;
+	memset(buf, 0, sizeof buf);
+	for (u = 0; u < size; ) {
+		i = write(vsl_fd, buf, sizeof buf);
+		if (i <= 0) {
+			fprintf(stderr, "Write error %s: %s\n",
+			    fn, strerror(errno));
+			exit (1);
 		}
+		u += i;
 	}
-
 	AZ(ftruncate(vsl_fd, (off_t)size));
 }
 
@@ -220,8 +209,10 @@ static
 void
 mgt_shm_atexit(void)
 {
+#if 0
 	if (getpid() == VSM_head->master_pid)
 		VSM_head->master_pid = 0;
+#endif
 }
 
 void
@@ -229,7 +220,10 @@ mgt_SHM_Init(void)
 {
 	int i, fill;
 	uintmax_t size, ps;
+	void *p;
+#if 0
 	uint32_t *vsl_log_start;
+#endif
 
 	fill = 1;
 
@@ -243,55 +237,49 @@ mgt_SHM_Init(void)
 		vsl_n_check(i);
 		(void)close(i);
 	}
-	vsl_buildnew(VSM_FILENAME, size, fill);
+	vsl_buildnew(VSM_FILENAME, size);
 
-	VSM_head = (void *)mmap(NULL, size,
+	p = (void *)mmap(NULL, size,
 	    PROT_READ|PROT_WRITE,
 	    MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
 	    vsl_fd, 0);
-	VSM_head->master_pid = getpid();
-	AZ(atexit(mgt_shm_atexit));
-	xxxassert(VSM_head != MAP_FAILED);
-	(void)mlock((void*)VSM_head, size);
-
-	memset(&VSM_head->head, 0, sizeof VSM_head->head);
-	VSM_head->head.magic = VSM_CHUNK_MAGIC;
-	VSM_head->head.len =
-	    (uint8_t*)(VSM_head) + size - (uint8_t*)&VSM_head->head;
-	bprintf(VSM_head->head.class, "%s", VSM_CLASS_FREE);
-	VWMB();
+	xxxassert(p != MAP_FAILED);
 
-	vsm_end = (void*)((uint8_t*)VSM_head + size);
+	heritage.vsm = VSM_common_new(p, size);
 
-	VSC_C_main = VSM_Alloc(sizeof *VSC_C_main,
-	    VSC_CLASS, VSC_TYPE_MAIN, "");
-	AN(VSC_C_main);
+	(void)mlock(p, size);
+	AZ(atexit(mgt_shm_atexit));
 
 	/* XXX: We need to zero params if we dealloc/clean/wash */
 	cache_param = VSM_Alloc(sizeof *cache_param, VSM_CLASS_PARAM, "", "");
 	AN(cache_param);
 	*cache_param = mgt_param;
 
-	vsl_log_start = VSM_Alloc(mgt_param.vsl_space, VSL_CLASS, "", "");
-	AN(vsl_log_start);
-	vsl_log_start[1] = VSL_ENDMARKER;
-	VWMB();
-
 	PAN_panicstr_len = 64 * 1024;
 	PAN_panicstr = VSM_Alloc(PAN_panicstr_len, PAN_CLASS, "", "");
 	AN(PAN_panicstr);
-	/* XXX: shouldn't VSM_Alloc zero ? */
-	memset(PAN_panicstr, '\0', PAN_panicstr_len);
 
-	do
-		*vsl_log_start = random() & 0xffff;
-	while (*vsl_log_start == 0);
+#if 0
+
+	VSM_head->master_pid = getpid();
 
+	memset(&VSM_head->head, 0, sizeof VSM_head->head);
+	VSM_head->head.magic = VSM_CHUNK_MAGIC;
+	VSM_head->head.len =
+	    (uint8_t*)(VSM_head) + size - (uint8_t*)&VSM_head->head;
+	bprintf(VSM_head->head.class, "%s", VSM_CLASS_FREE);
 	VWMB();
 
+	vsm_end = (void*)((uint8_t*)VSM_head + size);
+
+	VSC_C_main = VSM_Alloc(sizeof *VSC_C_main,
+	    VSC_CLASS, VSC_TYPE_MAIN, "");
+	AN(VSC_C_main);
+
 	do
 		VSM_head->alloc_seq = random();
 	while (VSM_head->alloc_seq == 0);
+#endif
 
 }
 
@@ -299,5 +287,7 @@ void
 mgt_SHM_Pid(void)
 {
 
+#if 0
 	VSM_head->master_pid = getpid();
+#endif
 }
diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h
index 521f89d..cad1e36 100644
--- a/include/vapi/vsm_int.h
+++ b/include/vapi/vsm_int.h
@@ -41,10 +41,11 @@
  */
 
 struct VSM_chunk {
-#define VSM_CHUNK_MAGIC		0x43907b6e	/* From /dev/random */
+#define VSM_CHUNK_MAGIC		0xa15712e5	/* From /dev/random */
 	unsigned		magic;
-	unsigned		len;
-	unsigned		state;
+	unsigned		len;		/* Incl VSM_chunk */
+	unsigned		next;		/* Offset in shmem */
+	unsigned		state;		/* XXX remove */
 	char			class[8];
 	char			type[8];
 	char			ident[64];
@@ -54,10 +55,11 @@ struct VSM_chunk {
 #define VSM_PTR(sha)		((void*)((uintptr_t)((sha) + 1)))
 
 struct VSM_head {
-#define VSM_HEAD_MAGIC		4185512502U	/* From /dev/random */
+#define VSM_HEAD_MAGIC		0xe75f7e91	/* From /dev/random */
 	unsigned		magic;
 
 	unsigned		hdrsize;
+	unsigned		first;		/* Offset, first chunk */
 
 	uint64_t		starttime;
 	int64_t			master_pid;



More information about the varnish-commit mailing list