]> err.no Git - varnish/commitdiff
Untested & undocumented login code. I don't have time to continue working
authordes <des@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 2 Mar 2006 10:31:17 +0000 (10:31 +0000)
committerdes <des@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 2 Mar 2006 10:31:17 +0000 (10:31 +0000)
on it right now, but I want it in the tree so phk doesn't start duplicating
my effort.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@41 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/include/Makefile.am
varnish-cache/include/varnish/assert.h [new file with mode: 0644]
varnish-cache/include/varnishapi.h
varnish-cache/lib/libvarnishapi/Makefile.am
varnish-cache/lib/libvarnishapi/varnish_debug.c [new file with mode: 0644]
varnish-cache/lib/libvarnishapi/varnish_log.c [new file with mode: 0644]
varnish-cache/lib/libvarnishapi/varnish_util.c [new file with mode: 0644]

index 3e43d4e636654e6ecbc4344c553f34e1ad931274..8f2d6473aaf744a01a20d5cbe38d21e704fb36e2 100644 (file)
@@ -1,4 +1,6 @@
 # $Id$
 
-include_HEADERS = varnishapi.h
+include_HEADERS = \
+       varnish/assert.h \
+       varnishapi.h
 
diff --git a/varnish-cache/include/varnish/assert.h b/varnish-cache/include/varnish/assert.h
new file mode 100644 (file)
index 0000000..9755b2c
--- /dev/null
@@ -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
index 48cee3120c93141886852ade070492f2439c9f49..fe384fd48f9134498077747b0ffd6f5a215b71df 100644 (file)
@@ -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
index 3bee1cbaa48fe647b35a3e9855ab31a8e97434f9..6baa51cd7db072d7430a3f8dde019d4d7b0d579f 100644 (file)
@@ -4,4 +4,7 @@ INCLUDES = -I$(top_srcdir)/include
 
 lib_LTLIBRARIES = libvarnishapi.la
 
-libvarnishapi_la_SOURCES =
+libvarnishapi_la_SOURCES = \
+       varnish_debug.c \
+       varnish_log.c \
+       varnish_util.c
diff --git a/varnish-cache/lib/libvarnishapi/varnish_debug.c b/varnish-cache/lib/libvarnishapi/varnish_debug.c
new file mode 100644 (file)
index 0000000..7d38cbd
--- /dev/null
@@ -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);
+}
diff --git a/varnish-cache/lib/libvarnishapi/varnish_log.c b/varnish-cache/lib/libvarnishapi/varnish_log.c
new file mode 100644 (file)
index 0000000..0f91e61
--- /dev/null
@@ -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);
+}
diff --git a/varnish-cache/lib/libvarnishapi/varnish_util.c b/varnish-cache/lib/libvarnishapi/varnish_util.c
new file mode 100644 (file)
index 0000000..39870e1
--- /dev/null
@@ -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 */
+}