]> err.no Git - varnish/commitdiff
Integrate Solaris patches, with a bit of polishing.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 19 Aug 2008 21:34:16 +0000 (21:34 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 19 Aug 2008 21:34:16 +0000 (21:34 +0000)
Don't look for umem on FreeBSD, which have dummy stub version for
dtrace or ZFS compatibility.

Generally restrict probes for Solaris specific stuff to when we
run on solaris, no need to make configure slower than it is.

Don't pretend we can get anywhere without poll(2) we use it for
lots of things:  Remove #if conditionals around poll-acceptor.

Sort a couple of lists, before they get too unsorted.

Submitted by: Theo Schlossnagle

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

varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_acceptor.h
varnish-cache/bin/varnishd/cache_acceptor_poll.c
varnish-cache/bin/varnishd/cache_acceptor_ports.c [new file with mode: 0644]
varnish-cache/bin/varnishd/cache_pool.c
varnish-cache/bin/varnishd/storage_umem.c [new file with mode: 0644]
varnish-cache/bin/varnishd/tcp.c
varnish-cache/bin/varnishd/varnishd.c
varnish-cache/configure.ac

index 82c1eef3bbfd88f5dce26032206167cd232098b7..e487812de52026cb15ae11744f64afea9e54b42d 100644 (file)
@@ -9,8 +9,9 @@ dist_man_MANS = varnishd.1
 varnishd_SOURCES = \
        cache_acceptor.c \
        cache_acceptor_epoll.c \
-       cache_acceptor_poll.c \
        cache_acceptor_kqueue.c \
+       cache_acceptor_poll.c \
+       cache_acceptor_ports.c \
        cache_backend.c \
        cache_backend_cfg.c \
        cache_backend_poll.c \
@@ -27,19 +28,19 @@ varnishd_SOURCES = \
        cache_httpconn.c \
        cache_main.c \
        cache_panic.c \
-       cache_pool.c \
        cache_pipe.c \
+       cache_pool.c \
        cache_response.c \
        cache_session.c \
        cache_vary.c \
        cache_vcl.c \
        cache_vrt.c \
        cache_vrt_acl.c \
-       cache_vrt_re.c \
        cache_vrt_esi.c \
+       cache_vrt_re.c \
        cache_ws.c \
-       hash_simple_list.c \
        hash_classic.c \
+       hash_simple_list.c \
        instance.c \
        mgt_child.c \
        mgt_cli.c \
@@ -51,15 +52,16 @@ varnishd_SOURCES = \
        storage_file.c \
        storage_malloc.c \
        storage_synth.c \
+       storage_umem.c \
        tcp.c \
        varnishd.c
 
 noinst_HEADERS = \
        acct_fields.h \
        cache.h \
+       cache_acceptor.h \
        cache_backend.h \
        cache_backend_poll.h \
-       cache_acceptor.h \
        common.h \
        default_vcl.h \
        hash_slinger.h \
index 7eee94f60f4d8d6596965091372b17c00279ef79..e4fa352c8e292b0b97b1c34027d9fbe1264be11d 100644 (file)
@@ -46,7 +46,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
-#include "config.h"
 #include "cli.h"
 #include "cli_priv.h"
 #include "shmlog.h"
@@ -60,9 +59,10 @@ static struct acceptor *vca_acceptors[] = {
 #if defined(HAVE_EPOLL_CTL)
        &acceptor_epoll,
 #endif
-#if defined(HAVE_POLL)
-       &acceptor_poll,
+#if defined(HAVE_PORT_CREATE)
+       &acceptor_ports,
 #endif
+       &acceptor_poll,
        NULL,
 };
 
index dcda822ee31971fb8f679cbd30072533225cc0f2..f885c1c37c47b1821e7f17d5f111a0e64171f1d7 100644 (file)
@@ -48,8 +48,10 @@ extern struct acceptor acceptor_epoll;
 extern struct acceptor acceptor_kqueue;
 #endif
 
-#if defined(HAVE_POLL)
 extern struct acceptor acceptor_poll;
+
+#if defined(HAVE_PORT_CREATE)
+extern struct acceptor acceptor_ports;
 #endif
 
 /* vca_acceptor.c */
index 195123e9b5387b543d1878fc4da7b1ce9452c78f..d9a0b19fe8bc801b17f7c41c66a62bcc7c7d01b9 100644 (file)
@@ -32,8 +32,6 @@
 
 #include "config.h"
 
-#if defined(HAVE_POLL)
-
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -167,5 +165,3 @@ struct acceptor acceptor_poll = {
        .name =         "poll",
        .init =         vca_poll_init,
 };
-
-#endif /* defined(HAVE_POLL) */
diff --git a/varnish-cache/bin/varnishd/cache_acceptor_ports.c b/varnish-cache/bin/varnishd/cache_acceptor_ports.c
new file mode 100644 (file)
index 0000000..12d29ec
--- /dev/null
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006 Linpro AS
+ * Copyright (c) 2007 OmniTI Computer Consulting, Inc.
+ * Copyright (c) 2007 Theo Schlossnagle
+ * All rights reserved.
+ *
+ * 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 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.
+ *
+ * $Id$
+ *
+ * XXX: We need to pass sessions back into the event engine when they are
+ * reused.  Not sure what the most efficient way is for that.  For now
+ * write the session pointer to a pipe which the event engine monitors.
+ */
+
+#include "config.h"
+#if defined(HAVE_PORT_CREATE)
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <port.h>
+
+#ifndef HAVE_CLOCK_GETTIME
+#include "compat/clock_gettime.h"
+#endif
+
+#include "shmlog.h"
+#include "cache.h"
+#include "cache_acceptor.h"
+
+#define MAX_EVENTS 256
+static pthread_t vca_ports_thread;
+int solaris_dport = -1;
+
+static VTAILQ_HEAD(,sess) sesshead = VTAILQ_HEAD_INITIALIZER(sesshead);
+
+static void
+vca_add(int fd, void *data)
+{
+       AZ(port_associate(solaris_dport, PORT_SOURCE_FD, fd, POLLIN | POLLERR | POLLPRI, data));
+}
+
+static void
+vca_del(int fd)
+{
+       port_dissociate(solaris_dport, PORT_SOURCE_FD, fd);
+}
+
+static void
+vca_port_ev(port_event_t *ev) {
+       struct sess *sp;
+       if(ev->portev_source == PORT_SOURCE_USER) {
+               sp = ev->portev_user;
+               CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+               assert(sp->fd >= 0);
+               AZ(sp->obj);
+               VTAILQ_INSERT_TAIL(&sesshead, sp, list);
+               vca_add(sp->fd, sp);
+       } else {
+               int i;
+               CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC);
+               if(ev->portev_events & POLLERR) {
+                       VTAILQ_REMOVE(&sesshead, sp, list);
+                       vca_close_session(sp, "EOF");
+                       SES_Delete(sp);
+                       return;
+               }
+               i = HTC_Rx(sp->htc);
+               if (i == 0)
+                       return;
+               if (i > 0) {
+                       VTAILQ_REMOVE(&sesshead, sp, list);
+                       if (sp->fd != -1)
+                               vca_del(sp->fd);
+                       vca_handover(sp, i);
+               }
+       }
+       return;
+}
+
+static void *
+vca_main(void *arg)
+{
+       struct sess *sp;
+
+       (void)arg;
+
+       solaris_dport = port_create();
+       assert(solaris_dport >= 0);
+
+       while (1) {
+               port_event_t ev[MAX_EVENTS];
+               int nevents, ei;
+               double deadline;
+               struct timespec ts;
+               ts.tv_sec = 0L;
+               ts.tv_nsec = 50L /*ms*/  * 1000L /*us*/  * 1000L /*ns*/;
+               nevents = 1;
+               if (port_getn(solaris_dport, ev, MAX_EVENTS, &nevents, &ts) == 0) {
+                       for (ei=0; ei<nevents; ei++) {
+                               vca_port_ev(ev + ei);
+                       }
+               }
+               /* check for timeouts */
+               deadline = TIM_real() - params->sess_timeout;
+               for (;;) {
+                       sp = VTAILQ_FIRST(&sesshead);
+                       if (sp == NULL)
+                               break;
+                       if (sp->t_open > deadline)
+                               break;
+                       VTAILQ_REMOVE(&sesshead, sp, list);
+                       if(sp->fd != -1)
+                               vca_del(sp->fd);
+                       vca_close_session(sp, "timeout");
+                       SES_Delete(sp);
+               }
+       }
+}
+
+static void
+vca_ports_pass(struct sess *sp)
+{
+       int r;
+       while((r = port_send(solaris_dport, 0, sp)) == -1 &&
+               errno == EAGAIN);
+       AZ(r);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+vca_ports_init(void)
+{
+
+       AZ(pthread_create(&vca_ports_thread, NULL, vca_main, NULL));
+}
+
+struct acceptor acceptor_ports = {
+       .name =         "ports",
+       .init =         vca_ports_init,
+       .pass =         vca_ports_pass
+};
+
+#endif /* defined(HAVE_PORT_CREATE) */
index 704b043e429a63c1f5ac18c4e97d10f14b78c20d..c12825a0642f3f88de4cf99448729383ec1a8a48 100644 (file)
@@ -52,6 +52,8 @@
 #include <sys/socket.h>
 #elif defined(__linux__)
 #include <sys/sendfile.h>
+#elif defined(__sun)
+#include <sys/sendfile.h>
 #else
 #error Unknown sendfile() implementation
 #endif
@@ -191,6 +193,37 @@ WRK_Sendfile(struct worker *w, int fd, off_t off, unsigned len)
                    sendfile(*w->wfd, fd, &off, len) != len)
                        w->werr++;
        } while (0);
+#elif defined(__sun)
+#ifdef HAVE_SENDFILEV
+       do {
+               sendfilevec_t svvec[HTTP_HDR_MAX * 2 + 1];
+               size_t xferred = 0, expected = 0;
+               int i;
+               for (i = 0; i < w->niov; i++) {
+                       svvec[i].sfv_fd = SFV_FD_SELF;
+                       svvec[i].sfv_flag = 0;
+                       svvec[i].sfv_off = (off_t) w->iov[i].iov_base;
+                       svvec[i].sfv_len = w->iov[i].iov_len;
+                       expected += svvec[i].sfv_len;
+               }
+               svvec[i].sfv_fd = fd;
+               svvec[i].sfv_flag = 0;
+               svvec[i].sfv_off = off;
+               svvec[i].sfv_len = len;
+               expected += svvec[i].sfv_len;
+               if (sendfilev(*w->wfd, svvec, i, &xferred) == -1 ||
+                   xferred != expected)
+                       w->werr++;
+               w->liov = 0;
+               w->niov = 0;
+       } while (0);
+#else
+       do {
+               if (WRK_Flush(w) == 0 &&
+                   sendfile(*w->wfd, fd, &off, len) != len)
+                       w->werr++;
+       } while (0);
+#endif
 #else
 #error Unknown sendfile() implementation
 #endif
diff --git a/varnish-cache/bin/varnishd/storage_umem.c b/varnish-cache/bin/varnishd/storage_umem.c
new file mode 100644 (file)
index 0000000..a1cf9a4
--- /dev/null
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2008 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk@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.
+ *
+ * $Id: storage_umem.c 3036 2008-07-31 09:24:25Z phk $
+ *
+ * Storage method based on umem_alloc(3MALLOC)
+ */
+
+#include "config.h"
+
+#ifdef HAVE_UMEM_H
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <umem.h>
+
+#include "config.h"
+#include "shmlog.h"
+#include "cache.h"
+#include "stevedore.h"
+
+static size_t                  smu_max = SIZE_MAX;
+static MTX                     smu_mtx;
+
+struct smu {
+       struct storage          s;
+       size_t                  sz;
+};
+
+static struct storage *
+smu_alloc(struct stevedore *st, size_t size)
+{
+       struct smu *smu;
+
+       LOCK(&smu_mtx);
+       VSL_stats->sma_nreq++;
+       if (VSL_stats->sma_nbytes + size > smu_max)
+               size = 0;
+       else {
+               VSL_stats->sma_nobj++;
+               VSL_stats->sma_nbytes += size;
+               VSL_stats->sma_balloc += size;
+       }
+       UNLOCK(&smu_mtx);
+
+       if (size == 0)
+               return (NULL);
+
+       smu = umem_zalloc(sizeof *smu, UMEM_DEFAULT);
+       if (smu == NULL)
+               return (NULL);
+       smu->sz = size;
+       smu->s.priv = smu;
+       smu->s.ptr = umem_alloc(size, UMEM_DEFAULT);
+       XXXAN(smu->s.ptr);
+       smu->s.len = 0;
+       smu->s.space = size;
+       smu->s.fd = -1;
+       smu->s.stevedore = st;
+       smu->s.magic = STORAGE_MAGIC;
+       return (&smu->s);
+}
+
+/*lint -e{818} not const-able */
+static void
+smu_free(struct storage *s)
+{
+       struct smu *smu;
+
+       CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC);
+       smu = s->priv;
+       assert(smu->sz == smu->s.space);
+       LOCK(&smu_mtx);
+       VSL_stats->sma_nobj--;
+       VSL_stats->sma_nbytes -= smu->sz;
+       VSL_stats->sma_bfree += smu->sz;
+       UNLOCK(&smu_mtx);
+       umem_free(smu->s.ptr, smu->s.space);
+       umem_free(smu, sizeof *smu);
+}
+
+static void
+smu_trim(const struct storage *s, size_t size)
+{
+       struct smu *smu;
+       void *p;
+
+       CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC);
+       smu = s->priv;
+       assert(smu->sz == smu->s.space);
+       if ((p = umem_alloc(size, UMEM_DEFAULT)) != NULL) {
+               memcpy(p, smu->s.ptr, size);
+               umem_free(smu->s.ptr, smu->s.space);
+               LOCK(&smu_mtx);
+               VSL_stats->sma_nbytes -= (smu->sz - size);
+               VSL_stats->sma_bfree += smu->sz - size;
+               smu->sz = size;
+               UNLOCK(&smu_mtx);
+               smu->s.ptr = p;
+               smu->s.space = size;
+       }
+}
+
+static void
+smu_init(struct stevedore *parent, int ac, char * const *av)
+{
+       const char *e;
+       uintmax_t u;
+
+       (void)parent;
+
+       AZ(av[ac]);
+       if (ac > 1) 
+               ARGV_ERR("(-sumem) too many arguments\n");
+
+       if (ac == 0 || *av[0] == '\0')
+                return;
+
+       e = str2bytes(av[0], &u, 0);
+       if (e != NULL)
+               ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e);
+       if ((u != (uintmax_t)(size_t)u)) 
+               ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]);
+       smu_max = u;
+}
+
+static void
+smu_open(const struct stevedore *st)
+{
+       (void)st;
+       AZ(pthread_mutex_init(&smu_mtx, NULL));
+}
+
+struct stevedore smu_stevedore = {
+       .magic  =       STEVEDORE_MAGIC,
+       .name   =       "umem",
+       .init   =       smu_init,
+       .open   =       smu_open,
+       .alloc  =       smu_alloc,
+       .free   =       smu_free,
+       .trim   =       smu_trim,
+};
+
+#endif /* HAVE_UMEM_H */
index ad95b7bd5c9cac2baaccf4e98b3be40584750eb3..af54042a40dc76c4aaa69900d007a0e13b4d1873 100644 (file)
@@ -38,6 +38,9 @@
 
 #include <errno.h>
 #include <sys/ioctl.h>
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
 #include <netdb.h>
 #include <poll.h>
 #include <stdio.h>
index 9f57f8138855b4c51b0a815378d5e6915288fb80..0782137168ec266a27829dd0a4ae7d835f581e6b 100644 (file)
@@ -113,10 +113,16 @@ arg_ul(const char *p)
 /*--------------------------------------------------------------------*/
 extern struct stevedore sma_stevedore;
 extern struct stevedore smf_stevedore;
+#ifdef HAVE_LIBUMEM
+extern struct stevedore smu_stevedore;
+#endif
 
 static struct choice stv_choice[] = {
        { "file",       &smf_stevedore },
        { "malloc",     &sma_stevedore },
+#ifdef HAVE_LIBUMEM
+       { "umem",       &smu_stevedore },
+#endif
        { NULL,         NULL }
 };
 
@@ -214,6 +220,9 @@ usage(void)
        fprintf(stderr, FMT,
            "-s kind[,storageoptions]", "Backend storage specification");
        fprintf(stderr, FMT, "", "  -s malloc");
+#ifdef HAVE_LIBUMEM
+       fprintf(stderr, FMT, "", "  -s umem");
+#endif
        fprintf(stderr, FMT, "", "  -s file  [default: use /tmp]");
        fprintf(stderr, FMT, "", "  -s file,<dir_or_file>");
        fprintf(stderr, FMT, "", "  -s file,<dir_or_file>,<size>");
index 45f57586378853f1bf75c3c91ec27aa370a3b755..0a8bc0ba504155491992ff7e0bf46f02799609b0 100644 (file)
@@ -129,6 +129,20 @@ case $host in
           AC_DEFINE([SENDFILE_WORKS], [1], [Define if SENDFILE works])
        fi
        ;;
+*-*-solaris*)
+       AC_CHECK_HEADERS([sys/filio.h])
+       AC_CHECK_LIB(sendfile, sendfile)
+       AC_CHECK_LIB(umem, malloc)
+       AC_CHECK_HEADERS([umem.h])
+
+       if test "$ac_cv_lib_sendfile_sendfile" = yes; then
+               save_LIBS="${LIBS}"
+               LIBS="${NET_LIBS}"
+               AC_CHECK_FUNCS([sendfile])
+               AC_CHECK_FUNCS([sendfilev])
+               LIBS="${save_LIBS}"
+       fi
+       ;;
 *)
        AC_MSG_WARN([won't look for sendfile() on $host])
        ;;
@@ -191,23 +205,17 @@ else
        ac_cv_func_epoll_ctl=no
 fi
 
-# --enable-poll
-AC_ARG_ENABLE(poll,
-    AS_HELP_STRING([--enable-poll],
-       [use poll if available (default is YES)]),
+# --enable-ports
+AC_ARG_ENABLE(ports,
+    AS_HELP_STRING([--enable-ports],
+       [use ports if available (default is YES)]),
     ,
-    [enable_poll=yes])
+    [enable_ports=yes])
 
-if test "$enable_poll" = yes; then
-       AC_CHECK_FUNCS([poll])
+if test "$enable_ports" = yes; then
+       AC_CHECK_FUNCS([port_create])
 else
-       ac_cv_func_poll=no
-fi
-
-if test "$ac_cv_func_kqueue" != yes &&
-   test "$ac_cv_func_epoll_ctl" != yes &&
-   test "$ac_cv_func_poll" != yes; then
-       AC_MSG_ERROR([no usable acceptor mechanism])
+       ac_cv_func_port_create=no
 fi
 
 # Solaris defines SO_{RCV,SND}TIMEO, but does not implement them.