r41 - in trunk/varnish-cache: include include/varnish lib/libvarnishapi

des at projects.linpro.no des at projects.linpro.no
Thu Mar 2 11:31:17 CET 2006


Author: des
Date: 2006-03-02 11:31:17 +0100 (Thu, 02 Mar 2006)
New Revision: 41

Added:
   trunk/varnish-cache/include/varnish/
   trunk/varnish-cache/include/varnish/assert.h
   trunk/varnish-cache/lib/libvarnishapi/varnish_debug.c
   trunk/varnish-cache/lib/libvarnishapi/varnish_log.c
   trunk/varnish-cache/lib/libvarnishapi/varnish_util.c
Modified:
   trunk/varnish-cache/include/Makefile.am
   trunk/varnish-cache/include/varnishapi.h
   trunk/varnish-cache/lib/libvarnishapi/Makefile.am
Log:
Untested & undocumented login code.  I don't have time to continue working
on it right now, but I want it in the tree so phk doesn't start duplicating
my effort.

Modified: trunk/varnish-cache/include/Makefile.am
===================================================================
--- trunk/varnish-cache/include/Makefile.am	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/include/Makefile.am	2006-03-02 10:31:17 UTC (rev 41)
@@ -1,4 +1,6 @@
 # $Id$
 
-include_HEADERS = varnishapi.h
+include_HEADERS = \
+	varnish/assert.h \
+	varnishapi.h
 

Added: trunk/varnish-cache/include/varnish/assert.h
===================================================================
--- trunk/varnish-cache/include/varnish/assert.h	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/include/varnish/assert.h	2006-03-02 10:31:17 UTC (rev 41)
@@ -0,0 +1,20 @@
+/*
+ * $Id$
+ */
+
+#ifndef VARNISH_ASSERT_H_INCLUDED
+#define VARNISH_ASSERT_H_INCLUDED
+
+#ifdef NDEBUG
+#define V_ASSERT(test) \
+	do { /* nothing */ } while (0)
+#else
+#define V_ASSERT(test) \
+	do { \
+		if (!(test)) \
+			vdb_panic("assertion failed in %s line %d: %s", \
+			    #test, __FILE__, __LINE__); \
+	} while (0)
+#endif
+
+#endif

Modified: trunk/varnish-cache/include/varnishapi.h
===================================================================
--- trunk/varnish-cache/include/varnishapi.h	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/include/varnishapi.h	2006-03-02 10:31:17 UTC (rev 41)
@@ -5,6 +5,23 @@
 #ifndef VARNISHAPI_H_INCLUDED
 #define VARNISHAPI_H_INCLUDED
 
-/* ... */
+#define V_DEAD __attribute__ ((noreturn))
 
+/* varnish_debug.c */
+void		 vdb_panic(const char *, ...) V_DEAD;
+
+/* varnish_log.c */
+typedef struct vlo_buffer vlo_buffer_t;
+vlo_buffer_t	*vlo_open(const char *, size_t, int);
+ssize_t		 vlo_write(vlo_buffer_t *, const void *, size_t);
+vlo_buffer_t	*vlo_attach(const char *);
+ssize_t		 vlo_read(vlo_buffer_t *, const void *, size_t);
+#if 0
+uuid_t		 vlo_get_uuid(vlo_buffer_t *);
 #endif
+int		 vlo_close(vlo_buffer_t *);
+
+/* varnish_util.c */
+int		 vut_open_lock(const char *, int, int, int);
+
+#endif

Modified: trunk/varnish-cache/lib/libvarnishapi/Makefile.am
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2006-03-02 10:31:17 UTC (rev 41)
@@ -4,4 +4,7 @@
 
 lib_LTLIBRARIES = libvarnishapi.la
 
-libvarnishapi_la_SOURCES =
+libvarnishapi_la_SOURCES = \
+	varnish_debug.c \
+	varnish_log.c \
+	varnish_util.c

Added: trunk/varnish-cache/lib/libvarnishapi/varnish_debug.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/varnish_debug.c	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/lib/libvarnishapi/varnish_debug.c	2006-03-02 10:31:17 UTC (rev 41)
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <varnishapi.h>
+
+void
+varnish_panic(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	fprintf(stderr, fmt, ap);
+	va_end(ap);
+	signal(SIGABRT, SIG_DFL);
+	raise(SIGABRT);
+}

Added: trunk/varnish-cache/lib/libvarnishapi/varnish_log.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/varnish_log.c	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/lib/libvarnishapi/varnish_log.c	2006-03-02 10:31:17 UTC (rev 41)
@@ -0,0 +1,293 @@
+/*
+ * $Id$
+ */
+
+#include "config.h"
+
+#include <sys/file.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <varnish/assert.h>
+
+#include <varnishapi.h>
+
+#define VLO_MAGIC 0x564c4f00
+
+typedef struct vlo_control vlo_control_t;
+
+/* should this be part of the exported API? */
+struct vlo_control {
+	uint32_t	 magic;
+#if 0
+	uuid_t		 uuid;
+#endif
+	uint32_t	 size;
+	uint32_t	 head;
+	uint32_t	 tail;
+};
+
+struct vlo_buffer {
+	int		 mode;
+	int		 cfd;
+	vlo_control_t	*ctl;
+	int		 bfd;
+	unsigned char	*buf;
+	uint32_t	 rpos;
+};
+
+/*
+ * Open a log file for writing; create it if necessary.  If the control
+ * file already exists, try to preserve its state, in case someone is
+ * already listening.
+ */
+vlo_buffer_t *
+vlo_open(const char *name, size_t size, int perm)
+{
+	char ctlname[PATH_MAX];
+	vlo_buffer_t *vb;
+	int page_size;
+	int i, serr;
+
+	page_size = getpagesize();
+
+	V_ASSERT(size > 0);
+	V_ASSERT(size % page_size == 0);
+
+	if (snprintf(ctlname, sizeof ctlname, "%s.ctl", name) >= sizeof ctlname) {
+		errno = ENAMETOOLONG;
+		return (NULL);
+	}
+	if ((vb = malloc(sizeof *vb)) == NULL)
+		goto out;
+	vb->mode = O_RDWR;
+	vb->cfd = -1;
+	vb->ctl = NULL;
+	vb->bfd = -1;
+	vb->buf = NULL;
+	vb->rpos = 0;
+
+	/* open, lock and mmap the control file */
+	if ((vb->cfd = vut_open_lock(ctlname, O_RDWR|O_CREAT,
+		 LOCK_EX|LOCK_NB, perm)) == -1 ||
+	    ftruncate(vb->cfd, page_size) == -1 ||
+	    (vb->ctl = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
+		MAP_SHARED, vb->cfd, 0)) == NULL ||
+	    mlock(vb->ctl, page_size) == -1)
+		goto out;
+
+	/* open, lock and mmap the buffer file */
+	if ((vb->bfd = open(name, O_RDWR|O_CREAT, perm)) == -1 ||
+	    flock(vb->bfd, LOCK_EX) == -1 ||
+	    ftruncate(vb->bfd, size) == -1 ||
+	    (vb->buf = mmap(NULL, size, PROT_READ|PROT_WRITE,
+		MAP_SHARED, vb->bfd, 0)) == NULL ||
+	    mlock(vb->ctl, size) == -1)
+		goto out;
+
+	/* initialize control structures */
+	if (vb->ctl->magic != VLO_MAGIC ||
+	    vb->ctl->size != size ||
+	    vb->ctl->head >= size ||
+	    vb->ctl->tail >= size) {
+		vb->ctl->magic = VLO_MAGIC;
+#if 0
+		vb->ctl->uuid = /* XXX */;
+#endif
+		vb->ctl->size = size;
+		vb->ctl->head = size - page_size; /* early wraparound */
+		vb->ctl->tail = vb->ctl->head;
+		vb->rpos = vb->ctl->tail;
+	}
+
+	/* pre-fault buffer */
+	for (i = 0; i < size; i += page_size)
+		vb->buf[i] = '\0';
+
+	return (vb);
+ out:
+	serr = errno;
+	if (vb != NULL) {
+		if (vb->buf != NULL) {
+			munlock(vb->buf, size);
+			munmap(vb->buf, size);
+		}
+		if (vb->bfd != -1)
+			close(vb->bfd);
+		if (vb->ctl != NULL) {
+			munlock(vb->ctl, page_size);
+			munmap(vb->ctl, page_size);
+		}
+		if (vb->cfd != -1)
+			close(vb->cfd);
+		free(vb);
+	}
+	errno = serr;
+	return (NULL);
+}
+
+/*
+ * Write to a log file.
+ */
+ssize_t
+vlo_write(vlo_buffer_t *vb, const void *data, size_t len)
+{
+	ssize_t result;
+	size_t copylen;
+
+	V_ASSERT(vb != NULL);
+	V_ASSERT(vb->mode == O_WRONLY || vb->mode == O_RDWR);
+	V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
+	V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
+	V_ASSERT(vb->ctl->magic == VLO_MAGIC);
+
+	for (result = 0; len > 0; len -= copylen, result += copylen) {
+		if (vb->ctl->head + len > vb->ctl->size)
+			copylen = vb->ctl->size - vb->ctl->head;
+		else
+			copylen = len;
+		if (vb->ctl->tail > vb->ctl->head &&
+		    vb->ctl->tail <= vb->ctl->head + copylen)
+			vb->ctl->tail =
+			    (vb->ctl->head + copylen + 1) % vb->ctl->size;
+		memcpy(vb->buf + vb->ctl->head, data, copylen);
+		vb->ctl->head = (vb->ctl->head + copylen) % vb->ctl->size;
+	}
+	return (result);
+}
+
+/*
+ * Attach to an existing log buffer.
+ */
+vlo_buffer_t *
+vlo_attach(const char *name)
+{
+	char ctlname[PATH_MAX];
+	vlo_buffer_t *vb;
+	int page_size;
+	int serr;
+
+	page_size = getpagesize();
+
+	if (snprintf(ctlname, sizeof ctlname, "%s.ctl", name) >= sizeof ctlname) {
+		errno = ENAMETOOLONG;
+		return (NULL);
+	}
+	if ((vb = malloc(sizeof *vb)) == NULL)
+		goto out;
+	vb->mode = O_RDONLY;
+	vb->cfd = -1;
+	vb->ctl = NULL;
+	vb->bfd = -1;
+	vb->buf = NULL;
+	vb->rpos = 0;
+
+	/* open, lock and mmap the control file */
+	if ((vb->cfd = open(ctlname, O_RDONLY)) == -1 ||
+	    (vb->ctl = mmap(NULL, page_size, PROT_READ,
+		MAP_SHARED, vb->cfd, 0)) == NULL ||
+	    mlock(vb->ctl, page_size) == -1)
+		goto out;
+
+	/* verify control structure */
+	if (vb->ctl->magic != VLO_MAGIC ||
+	    !(vb->ctl->size > 0 && (vb->ctl->size % page_size) == 0)) {
+		errno = EINVAL; /* XXX document */
+		goto out;
+	}
+
+	/* open, lock and mmap the buffer file */
+	if ((vb->bfd = open(name, O_RDONLY)) == -1 ||
+	    (vb->buf = mmap(NULL, vb->ctl->size, PROT_READ,
+		MAP_SHARED, vb->bfd, 0)) == NULL ||
+	    mlock(vb->ctl, vb->ctl->size) == -1)
+		goto out;
+
+	vb->rpos = vb->ctl->tail;
+
+	return (vb);
+ out:
+	serr = errno;
+	if (vb != NULL) {
+		if (vb->buf != NULL) {
+			munlock(vb->buf, vb->ctl->size);
+			munmap(vb->buf, vb->ctl->size);
+		}
+		if (vb->bfd != -1)
+			close(vb->bfd);
+		if (vb->ctl != NULL) {
+			munlock(vb->ctl, page_size);
+			munmap(vb->ctl, page_size);
+		}
+		if (vb->cfd != -1)
+			close(vb->cfd);
+		free(vb);
+	}
+	errno = serr;
+	return (NULL);
+}
+
+/*
+ * Read from a log file.
+ */
+ssize_t
+vlo_read(vlo_buffer_t *vb, const void *data, size_t len)
+{
+	V_ASSERT(vb != NULL);
+	V_ASSERT(vb->mode == O_RDONLY || vb->mode == O_RDWR);
+	V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
+	V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
+	V_ASSERT(vb->ctl->magic == VLO_MAGIC);
+
+	/* not implemented */
+	return (-1);
+}
+
+#if 0
+/*
+ * Return the UUID of the process writing to the log file.
+ */
+uuid_t
+vlo_get_uuid(vlo_buffer *vb)
+{
+	V_ASSERT(vb != NULL);
+	V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
+	V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
+	V_ASSERT(vb->ctl->magic == VLO_MAGIC);
+
+	return (vb->ctl->uuid);
+}
+#endif
+
+/*
+ * Close a log file.
+ */
+int
+vlo_close(vlo_buffer_t *vb)
+{
+	int page_size;
+
+	page_size = getpagesize();
+
+	V_ASSERT(vb != NULL);
+	V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
+	V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
+	V_ASSERT(vb->ctl->magic == VLO_MAGIC);
+
+	munlock(vb->buf, vb->ctl->size);
+	munmap(vb->buf, vb->ctl->size);
+	close(vb->bfd);
+	munlock(vb->ctl, page_size);
+	munmap(vb->ctl, page_size);
+	close(vb->cfd);
+	free(vb);
+	return (0);
+}

Added: trunk/varnish-cache/lib/libvarnishapi/varnish_util.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/varnish_util.c	2006-03-02 10:29:52 UTC (rev 40)
+++ trunk/varnish-cache/lib/libvarnishapi/varnish_util.c	2006-03-02 10:31:17 UTC (rev 41)
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <varnishapi.h>
+
+/**
+ * Open and lock a file.
+ */
+int
+vut_open_lock(const char *name, int mode, int lockop, int perm)
+{
+	struct stat sb, fsb;
+	int fd, serr;
+
+	for (;;) {
+		if ((fd = open(name, mode, perm)) == -1)
+			/* not much we can do about that */
+			return (-1);
+		while (flock(fd, lockop) == -1) {
+			if (errno != EINTR) {
+				serr = errno;
+				close(fd);
+				errno = serr;
+				return (-1);
+			}
+		}
+		if (stat(name, &sb) == -1) {
+			serr = errno;
+			close(fd);
+			errno = serr;
+
+			if (errno == ENOENT && (mode & O_CREAT))
+				/* file was deleted from under our nose */
+				continue;
+			return (-1);
+		}
+		if (fstat(fd, &fsb) == -1) {
+			/* serious voodoo is going on*/
+			serr = errno;
+			close(fd);
+			errno = serr;
+			return (-1);
+		}
+		if (sb.st_dev == fsb.st_dev && sb.st_ino == fsb.st_ino)
+			/* we have the correct file */
+			return (fd);
+		close(fd);
+	}
+	/* not reached */
+}




More information about the varnish-commit mailing list