[master] 9be1300 Move vsmw from libvarnish to varnishd/common

Poul-Henning Kamp phk at FreeBSD.org
Wed Jan 3 09:46:10 UTC 2018


commit 9be13007ffcb36a14f7780a37ba5f626c123802f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jan 3 09:44:47 2018 +0000

    Move vsmw from libvarnish to varnishd/common

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 68a7072..3cf7519 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -52,6 +52,7 @@ varnishd_SOURCES = \
 	cache/cache_wrk.c \
 	cache/cache_ws.c \
 	common/common_vsc.c \
+	common/common_vsmw.c \
 	hash/hash_classic.c \
 	hash/hash_critbit.c \
 	hash/hash_simple_list.c \
@@ -123,6 +124,7 @@ noinst_HEADERS = \
 	cache/cache_vgz.h \
 	common/common_param.h \
 	common/heritage.h \
+	common/vsmw.h \
 	hash/hash_slinger.h \
 	hpack/vhp.h \
 	http1/cache_http1.h \
diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index cbb72a8..c01e01e 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -35,13 +35,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "common/heritage.h"
-
 #include "vend.h"
 #include "vgz.h"
 #include "vsl_priv.h"
 #include "vmb.h"
-#include "vsmw.h"
+
+#include "common/heritage.h"
+#include "common/vsmw.h"
 
 /* These cannot be struct lock, which depends on vsm/vsl working */
 static pthread_mutex_t vsl_mtx;
diff --git a/bin/varnishd/common/common_vsc.c b/bin/varnishd/common/common_vsc.c
index 3a719ed..6b8c0c5 100644
--- a/bin/varnishd/common/common_vsc.c
+++ b/bin/varnishd/common/common_vsc.c
@@ -42,10 +42,10 @@
 #include "vas.h"
 #include "vmb.h"
 #include "vsc_priv.h"
-#include "vsmw.h"
 #include "vqueue.h"
 
-#include "common/heritage.h"
+#include "heritage.h"
+#include "vsmw.h"
 
 /*--------------------------------------------------------------------*/
 
diff --git a/bin/varnishd/common/common_vsmw.c b/bin/varnishd/common/common_vsmw.c
new file mode 100644
index 0000000..a5cee24
--- /dev/null
+++ b/bin/varnishd/common/common_vsmw.c
@@ -0,0 +1,317 @@
+/*-
+ * Copyright (c) 2010-2011 Varnish Software 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.
+ *
+ * VSM stuff common to manager and child.
+ *
+ * Please see comments in <vsm_priv.h> for details of protocols and
+ * data consistency.
+ *
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "vdef.h"
+#include "vas.h"
+#include "vsb.h"
+#include "miniobj.h"
+#include "vqueue.h"
+
+#include "vfil.h"
+#include "vrnd.h"
+
+#include "vsmw.h"
+
+#ifndef MAP_HASSEMAPHORE
+#  define MAP_HASSEMAPHORE 0 /* XXX Linux */
+#endif
+
+#ifndef MAP_NOSYNC
+#  define MAP_NOSYNC 0 /* XXX Linux */
+#endif
+
+/*--------------------------------------------------------------------*/
+
+struct vsmwseg {
+	unsigned			magic;
+#define VSMWSEG_MAGIC			0x7e4ccaea
+	VTAILQ_ENTRY(vsmwseg)		list;
+	char				*fn;
+
+	char				*class;
+	size_t				len;
+	char				*id;
+	void				*ptr;
+};
+
+struct vsmw {
+	unsigned			magic;
+#define VSMW_MAGIC			0xc2ca2cd9
+	int				vdirfd;
+	int				mode;
+	char				*idx;
+	VTAILQ_HEAD(, vsmwseg)		segs;
+	struct vsb			*vsb;
+	pid_t				pid;
+	time_t				birth;
+};
+
+/*--------------------------------------------------------------------*/
+
+static void
+vsmw_idx_head(const struct vsmw *vsmw, int fd)
+{
+	char buf[64];
+
+	bprintf(buf, "# %jd %jd\n", (intmax_t)vsmw->pid, (intmax_t)vsmw->birth);
+	assert(write(fd, buf, strlen(buf)) == strlen(buf));
+}
+
+static void
+vsmw_write_index(const struct vsmw *vsmw, int fd, const struct vsmwseg *seg)
+{
+	ssize_t s;
+
+	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
+	CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
+	VSB_clear(vsmw->vsb);
+	VSB_printf(vsmw->vsb, "%s 0 %zu %s %s\n",
+	    seg->fn,
+	    seg->len,
+	    seg->class,
+	    seg->id);
+	AZ(VSB_finish(vsmw->vsb));
+	s = write(fd, VSB_data(vsmw->vsb), VSB_len(vsmw->vsb));
+	assert(s == VSB_len(vsmw->vsb));
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+vsmw_mkent(const struct vsmw *vsmw, const char *pfx)
+{
+	int fd;
+
+	while (1) {
+		VSB_clear(vsmw->vsb);
+		VSB_printf(vsmw->vsb, "_.%s", pfx);
+		VSB_printf(vsmw->vsb, ".%08lx", VRND_RandomTestable());
+		VSB_printf(vsmw->vsb, "%08lx", VRND_RandomTestable());
+		AZ(VSB_finish(vsmw->vsb));
+		fd = openat(vsmw->vdirfd, VSB_data(vsmw->vsb), O_RDONLY);
+		if (fd < 0 && errno == ENOENT)
+			return;
+		if (fd >= 0)
+			AZ(close(fd));
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+void *
+VSMW_Allocv(struct vsmw *vsmw, const char *class, size_t len,
+    const char *fmt, va_list va)
+{
+	struct vsmwseg *seg;
+	int fd;
+	size_t ps;
+
+	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
+
+	ALLOC_OBJ(seg, VSMWSEG_MAGIC);
+	AN(seg);
+	REPLACE(seg->class, class);
+	seg->len = len;
+
+	VSB_clear(vsmw->vsb);
+	VSB_vprintf(vsmw->vsb, fmt, va);
+	AZ(VSB_finish(vsmw->vsb));
+	REPLACE(seg->id, VSB_data(vsmw->vsb));
+
+	vsmw_mkent(vsmw, class);
+	REPLACE(seg->fn, VSB_data(vsmw->vsb));
+
+	ps = getpagesize();
+	len = RUP2(len, ps);
+
+	fd = openat(vsmw->vdirfd, seg->fn,
+	    O_RDWR | O_CREAT | O_EXCL, vsmw->mode);
+	assert(fd >= 0);
+
+	AZ(VFIL_allocate(fd, (off_t)len, 1));
+
+	seg->ptr = (void *)mmap(NULL, len,
+	    PROT_READ|PROT_WRITE,
+	    MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
+	    fd, 0);
+
+	AZ(close(fd));
+	assert(seg->ptr != MAP_FAILED);
+	(void)mlock(seg->ptr, len);
+
+	VTAILQ_INSERT_TAIL(&vsmw->segs, seg, list);
+	fd = openat(vsmw->vdirfd, vsmw->idx, O_APPEND | O_WRONLY);
+	assert(fd >= 0);
+	vsmw_write_index(vsmw, fd, seg);
+	AZ(close(fd));
+
+	return (seg->ptr);
+}
+
+void *
+VSMW_Allocf(struct vsmw *vsmw, const char *class, size_t len,
+    const char *fmt, ...)
+{
+	va_list ap;
+	void *p;
+
+	va_start(ap, fmt);
+	p = VSMW_Allocv(vsmw, class, len, fmt, ap);
+	va_end(ap);
+	return (p);
+}
+
+/*--------------------------------------------------------------------*/
+static void
+vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx)
+{
+	char *t = NULL;
+	int fd;
+	size_t len;
+
+	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
+	CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
+
+	len = getpagesize();
+	len = RUP2(seg->len, len);
+	AZ(munmap(seg->ptr, len));
+
+	VTAILQ_REMOVE(&vsmw->segs, seg, list);
+	if (unlinkat(vsmw->vdirfd, seg->fn, 0))
+		assert (errno == ENOENT);
+	REPLACE(seg->fn, NULL);
+	REPLACE(seg->class, NULL);
+	REPLACE(seg->id, NULL);
+	FREE_OBJ(seg);
+
+	if (fixidx) {
+		vsmw_mkent(vsmw, vsmw->idx);
+		REPLACE(t, VSB_data(vsmw->vsb));
+		AN(t);
+		fd = openat(vsmw->vdirfd, t, O_WRONLY|O_CREAT|O_EXCL, vsmw->mode);
+		assert(fd >= 0);
+		vsmw_idx_head(vsmw, fd);
+		VTAILQ_FOREACH(seg, &vsmw->segs, list)
+			vsmw_write_index(vsmw, fd, seg);
+		AZ(close(fd));
+		AZ(renameat(vsmw->vdirfd, t, vsmw->vdirfd, vsmw->idx));
+		REPLACE(t, NULL);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VSMW_Free(struct vsmw *vsmw, void **pp)
+{
+	struct vsmwseg *seg;
+	void *p;
+
+	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
+	AN(pp);
+	p = *pp;
+	AN(p);
+	*pp = NULL;
+	VTAILQ_FOREACH(seg, &vsmw->segs, list)
+		if (seg->ptr == p)
+			break;
+	AN(seg);
+	vsmw_delseg(vsmw, seg, 1);
+}
+
+/*--------------------------------------------------------------------*/
+
+struct vsmw *
+VSMW_New(int vdirfd, int mode, const char *idxname)
+{
+	struct vsmw *vsmw;
+	int fd;
+
+	assert(vdirfd > 0);
+	assert(mode > 0);
+	AN(idxname);
+
+	ALLOC_OBJ(vsmw, VSMW_MAGIC);
+	AN(vsmw);
+
+	VTAILQ_INIT(&vsmw->segs);
+	vsmw->vsb = VSB_new_auto();
+	AN(vsmw->vsb);
+	REPLACE(vsmw->idx, idxname);
+	vsmw->mode = mode;
+	vsmw->vdirfd = vdirfd;
+	vsmw->pid = getpid();
+	vsmw->birth = time(NULL);
+
+	if (unlinkat(vdirfd, vsmw->idx, 0))
+		assert (errno == ENOENT);
+	fd = openat(vdirfd,
+	    vsmw->idx, O_APPEND | O_WRONLY | O_CREAT, vsmw->mode);
+	assert(fd >= 0);
+	vsmw_idx_head(vsmw, fd);
+	AZ(close(fd));
+
+	return (vsmw);
+}
+
+void
+VSMW_Destroy(struct vsmw **pp)
+{
+	struct vsmw *vsmw;
+	struct vsmwseg *seg, *s2;
+
+	TAKE_OBJ_NOTNULL(vsmw, pp, VSMW_MAGIC);
+	if (unlinkat(vsmw->vdirfd, vsmw->idx, 0))
+		assert (errno == ENOENT);
+	REPLACE(vsmw->idx, NULL);
+	VTAILQ_FOREACH_SAFE(seg, &vsmw->segs, list, s2)
+		vsmw_delseg(vsmw, seg, 0);
+	VSB_destroy(&vsmw->vsb);
+	AZ(close(vsmw->vdirfd));
+	FREE_OBJ(vsmw);
+}
diff --git a/bin/varnishd/common/vsmw.h b/bin/varnishd/common/vsmw.h
new file mode 100644
index 0000000..1ba2975
--- /dev/null
+++ b/bin/varnishd/common/vsmw.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2017 Varnish Software 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.
+ */
+
+#ifdef VSMW_H_INCLUDED
+#error "Multiple includes of vsmw.h"
+#endif
+#define VSMW_H_INCLUDED
+
+struct vsmw;
+
+void *VSMW_Allocv(struct vsmw *, const char *, size_t, const char *, va_list);
+void *VSMW_Allocf(struct vsmw *, const char *, size_t, const char *, ...);
+void VSMW_Free(struct vsmw *, void **);
+
+struct vsmw *VSMW_New(int, int, const char *);
+void VSMW_Destroy(struct vsmw **);
diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index c0ce43d..062800e 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -44,8 +44,7 @@
 #include <syslog.h>
 #include <unistd.h>
 
-#include "mgt/mgt.h"
-#include "common/heritage.h"
+#include "mgt.h"
 
 #include "vbm.h"
 #include "vcli_serve.h"
@@ -53,7 +52,9 @@
 #include "vfil.h"
 #include "vlu.h"
 #include "vtim.h"
-#include "vsmw.h"
+
+#include "common/heritage.h"
+#include "common/vsmw.h"
 
 static pid_t		child_pid = -1;
 
diff --git a/bin/varnishd/mgt/mgt_shmem.c b/bin/varnishd/mgt/mgt_shmem.c
index 954c6e2..c165ceb 100644
--- a/bin/varnishd/mgt/mgt_shmem.c
+++ b/bin/varnishd/mgt/mgt_shmem.c
@@ -41,10 +41,11 @@
 #include <unistd.h>
 
 #include "mgt/mgt.h"
-#include "common/heritage.h"
 
 #include "vsm_priv.h"
-#include "vsmw.h"
+
+#include "common/heritage.h"
+#include "common/vsmw.h"
 
 static struct vsmw *mgt_vsmw;
 
diff --git a/include/Makefile.am b/include/Makefile.am
index 822dcdd..d59b310 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -92,7 +92,6 @@ nobase_noinst_HEADERS = \
 	vpf.h \
 	vsc_priv.h \
 	vsl_priv.h \
-	vsmw.h \
 	vsm_priv.h \
 	vsub.h \
 	vss.h \
diff --git a/include/vsmw.h b/include/vsmw.h
deleted file mode 100644
index 1ba2975..0000000
--- a/include/vsmw.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2017 Varnish Software 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.
- */
-
-#ifdef VSMW_H_INCLUDED
-#error "Multiple includes of vsmw.h"
-#endif
-#define VSMW_H_INCLUDED
-
-struct vsmw;
-
-void *VSMW_Allocv(struct vsmw *, const char *, size_t, const char *, va_list);
-void *VSMW_Allocf(struct vsmw *, const char *, size_t, const char *, ...);
-void VSMW_Free(struct vsmw *, void **);
-
-struct vsmw *VSMW_New(int, int, const char *);
-void VSMW_Destroy(struct vsmw **);
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index c772bf5..1616f0e 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -34,7 +34,6 @@ libvarnish_a_SOURCES = \
 	vsa.c \
 	vsb.c \
 	vsha256.c \
-	vsmw.c \
 	vss.c \
 	vsub.c \
 	vtcp.c \
diff --git a/lib/libvarnish/vsmw.c b/lib/libvarnish/vsmw.c
deleted file mode 100644
index c36e2d8..0000000
--- a/lib/libvarnish/vsmw.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*-
- * Copyright (c) 2010-2011 Varnish Software 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.
- *
- * VSM stuff common to manager and child.
- *
- * Please see comments in <vsm_priv.h> for details of protocols and
- * data consistency.
- *
- */
-
-#include "config.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include "vdef.h"
-#include "vas.h"
-#include "vsb.h"
-#include "miniobj.h"
-#include "vsmw.h"
-#include "vqueue.h"
-
-#include "vfil.h"
-#include "vrnd.h"
-
-#ifndef MAP_HASSEMAPHORE
-#  define MAP_HASSEMAPHORE 0 /* XXX Linux */
-#endif
-
-#ifndef MAP_NOSYNC
-#  define MAP_NOSYNC 0 /* XXX Linux */
-#endif
-
-/*--------------------------------------------------------------------*/
-
-struct vsmwseg {
-	unsigned			magic;
-#define VSMWSEG_MAGIC			0x7e4ccaea
-	VTAILQ_ENTRY(vsmwseg)		list;
-	char				*fn;
-
-	char				*class;
-	size_t				len;
-	char				*id;
-	void				*ptr;
-};
-
-struct vsmw {
-	unsigned			magic;
-#define VSMW_MAGIC			0xc2ca2cd9
-	int				vdirfd;
-	int				mode;
-	char				*idx;
-	VTAILQ_HEAD(, vsmwseg)		segs;
-	struct vsb			*vsb;
-	pid_t				pid;
-	time_t				birth;
-};
-
-/*--------------------------------------------------------------------*/
-
-static void
-vsmw_idx_head(const struct vsmw *vsmw, int fd)
-{
-	char buf[64];
-
-	bprintf(buf, "# %jd %jd\n", (intmax_t)vsmw->pid, (intmax_t)vsmw->birth);
-	assert(write(fd, buf, strlen(buf)) == strlen(buf));
-}
-
-static void
-vsmw_write_index(const struct vsmw *vsmw, int fd, const struct vsmwseg *seg)
-{
-	ssize_t s;
-
-	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
-	CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
-	VSB_clear(vsmw->vsb);
-	VSB_printf(vsmw->vsb, "%s 0 %zu %s %s\n",
-	    seg->fn,
-	    seg->len,
-	    seg->class,
-	    seg->id);
-	AZ(VSB_finish(vsmw->vsb));
-	s = write(fd, VSB_data(vsmw->vsb), VSB_len(vsmw->vsb));
-	assert(s == VSB_len(vsmw->vsb));
-}
-
-/*--------------------------------------------------------------------*/
-
-static void
-vsmw_mkent(const struct vsmw *vsmw, const char *pfx)
-{
-	int fd;
-
-	while (1) {
-		VSB_clear(vsmw->vsb);
-		VSB_printf(vsmw->vsb, "_.%s", pfx);
-		VSB_printf(vsmw->vsb, ".%08lx", VRND_RandomTestable());
-		VSB_printf(vsmw->vsb, "%08lx", VRND_RandomTestable());
-		AZ(VSB_finish(vsmw->vsb));
-		fd = openat(vsmw->vdirfd, VSB_data(vsmw->vsb), O_RDONLY);
-		if (fd < 0 && errno == ENOENT)
-			return;
-		if (fd >= 0)
-			AZ(close(fd));
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
-void *
-VSMW_Allocv(struct vsmw *vsmw, const char *class, size_t len,
-    const char *fmt, va_list va)
-{
-	struct vsmwseg *seg;
-	int fd;
-	size_t ps;
-
-	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
-
-	ALLOC_OBJ(seg, VSMWSEG_MAGIC);
-	AN(seg);
-	REPLACE(seg->class, class);
-	seg->len = len;
-
-	VSB_clear(vsmw->vsb);
-	VSB_vprintf(vsmw->vsb, fmt, va);
-	AZ(VSB_finish(vsmw->vsb));
-	REPLACE(seg->id, VSB_data(vsmw->vsb));
-
-	vsmw_mkent(vsmw, class);
-	REPLACE(seg->fn, VSB_data(vsmw->vsb));
-
-	ps = getpagesize();
-	len = RUP2(len, ps);
-
-	fd = openat(vsmw->vdirfd, seg->fn,
-	    O_RDWR | O_CREAT | O_EXCL, vsmw->mode);
-	assert(fd >= 0);
-
-	AZ(VFIL_allocate(fd, (off_t)len, 1));
-
-	seg->ptr = (void *)mmap(NULL, len,
-	    PROT_READ|PROT_WRITE,
-	    MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
-	    fd, 0);
-
-	AZ(close(fd));
-	assert(seg->ptr != MAP_FAILED);
-	(void)mlock(seg->ptr, len);
-
-	VTAILQ_INSERT_TAIL(&vsmw->segs, seg, list);
-	fd = openat(vsmw->vdirfd, vsmw->idx, O_APPEND | O_WRONLY);
-	assert(fd >= 0);
-	vsmw_write_index(vsmw, fd, seg);
-	AZ(close(fd));
-
-	return (seg->ptr);
-}
-
-void *
-VSMW_Allocf(struct vsmw *vsmw, const char *class, size_t len,
-    const char *fmt, ...)
-{
-	va_list ap;
-	void *p;
-
-	va_start(ap, fmt);
-	p = VSMW_Allocv(vsmw, class, len, fmt, ap);
-	va_end(ap);
-	return (p);
-}
-
-/*--------------------------------------------------------------------*/
-static void
-vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx)
-{
-	char *t = NULL;
-	int fd;
-	size_t len;
-
-	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
-	CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
-
-	len = getpagesize();
-	len = RUP2(seg->len, len);
-	AZ(munmap(seg->ptr, len));
-
-	VTAILQ_REMOVE(&vsmw->segs, seg, list);
-	if (unlinkat(vsmw->vdirfd, seg->fn, 0))
-		assert (errno == ENOENT);
-	REPLACE(seg->fn, NULL);
-	REPLACE(seg->class, NULL);
-	REPLACE(seg->id, NULL);
-	FREE_OBJ(seg);
-
-	if (fixidx) {
-		vsmw_mkent(vsmw, vsmw->idx);
-		REPLACE(t, VSB_data(vsmw->vsb));
-		AN(t);
-		fd = openat(vsmw->vdirfd, t, O_WRONLY|O_CREAT|O_EXCL, vsmw->mode);
-		assert(fd >= 0);
-		vsmw_idx_head(vsmw, fd);
-		VTAILQ_FOREACH(seg, &vsmw->segs, list)
-			vsmw_write_index(vsmw, fd, seg);
-		AZ(close(fd));
-		AZ(renameat(vsmw->vdirfd, t, vsmw->vdirfd, vsmw->idx));
-		REPLACE(t, NULL);
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-VSMW_Free(struct vsmw *vsmw, void **pp)
-{
-	struct vsmwseg *seg;
-	void *p;
-
-	CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
-	AN(pp);
-	p = *pp;
-	AN(p);
-	*pp = NULL;
-	VTAILQ_FOREACH(seg, &vsmw->segs, list)
-		if (seg->ptr == p)
-			break;
-	AN(seg);
-	vsmw_delseg(vsmw, seg, 1);
-}
-
-/*--------------------------------------------------------------------*/
-
-struct vsmw *
-VSMW_New(int vdirfd, int mode, const char *idxname)
-{
-	struct vsmw *vsmw;
-	int fd;
-
-	assert(vdirfd > 0);
-	assert(mode > 0);
-	AN(idxname);
-
-	ALLOC_OBJ(vsmw, VSMW_MAGIC);
-	AN(vsmw);
-
-	VTAILQ_INIT(&vsmw->segs);
-	vsmw->vsb = VSB_new_auto();
-	AN(vsmw->vsb);
-	REPLACE(vsmw->idx, idxname);
-	vsmw->mode = mode;
-	vsmw->vdirfd = vdirfd;
-	vsmw->pid = getpid();
-	vsmw->birth = time(NULL);
-
-	if (unlinkat(vdirfd, vsmw->idx, 0))
-		assert (errno == ENOENT);
-	fd = openat(vdirfd,
-	    vsmw->idx, O_APPEND | O_WRONLY | O_CREAT, vsmw->mode);
-	assert(fd >= 0);
-	vsmw_idx_head(vsmw, fd);
-	AZ(close(fd));
-
-	return (vsmw);
-}
-
-void
-VSMW_Destroy(struct vsmw **pp)
-{
-	struct vsmw *vsmw;
-	struct vsmwseg *seg, *s2;
-
-	TAKE_OBJ_NOTNULL(vsmw, pp, VSMW_MAGIC);
-	if (unlinkat(vsmw->vdirfd, vsmw->idx, 0))
-		assert (errno == ENOENT);
-	REPLACE(vsmw->idx, NULL);
-	VTAILQ_FOREACH_SAFE(seg, &vsmw->segs, list, s2)
-		vsmw_delseg(vsmw, seg, 0);
-	VSB_destroy(&vsmw->vsb);
-	AZ(close(vsmw->vdirfd));
-	FREE_OBJ(vsmw);
-}


More information about the varnish-commit mailing list