[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