varnish-cache/lib/libvmod_directors/fall_back.c
1
/*-
2
 * Copyright (c) 2013-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
31
#include <stdlib.h>
32
#include <string.h>
33
34
#include "cache/cache.h"
35
#include "cache/cache_director.h"
36
37
#include "vcc_if.h"
38
39
#include "vdir.h"
40
41
struct vmod_directors_fallback {
42
        unsigned                                magic;
43
#define VMOD_DIRECTORS_FALLBACK_MAGIC           0xad4e26ba
44
        struct vdir                             *vd;
45
        VCL_BOOL                                st;
46
        unsigned                                cur;
47
};
48
49
static unsigned v_matchproto_(vdi_healthy)
50 0
vmod_fallback_healthy(const struct director *dir, const struct busyobj *bo,
51
    double *changed)
52
{
53
        struct vmod_directors_fallback *fb;
54
55 0
        CAST_OBJ_NOTNULL(fb, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
56 0
        return (vdir_any_healthy(fb->vd, bo, changed));
57
}
58
59
static const struct director * v_matchproto_(vdi_resolve_f)
60 46
vmod_fallback_resolve(const struct director *dir, struct worker *wrk,
61
    struct busyobj *bo)
62
{
63
        struct vmod_directors_fallback *fb;
64
        unsigned u;
65 46
        VCL_BACKEND be = NULL;
66
67 46
        CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
68 46
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
69 46
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
70 46
        CAST_OBJ_NOTNULL(fb, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
71
72 46
        vdir_wrlock(fb->vd);
73 46
        if (!fb->st)
74 28
                fb->cur = 0;
75 74
        for (u = 0; u < fb->vd->n_backend; u++) {
76 72
                be = fb->vd->backend[fb->cur];
77 72
                CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
78 72
                if (be->healthy(be, bo, NULL))
79 44
                        break;
80 28
                if (++fb->cur == fb->vd->n_backend)
81 4
                        fb->cur = 0;
82
        }
83 46
        vdir_unlock(fb->vd);
84 46
        if (u == fb->vd->n_backend)
85 2
                be = NULL;
86 46
        return (be);
87
}
88
89
VCL_VOID v_matchproto_()
90 8
vmod_fallback__init(VRT_CTX,
91
    struct vmod_directors_fallback **fbp, const char *vcl_name, VCL_BOOL sticky)
92
{
93
        struct vmod_directors_fallback *fb;
94
95 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
96 8
        AN(fbp);
97 8
        AZ(*fbp);
98 8
        ALLOC_OBJ(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
99 8
        AN(fb);
100 8
        *fbp = fb;
101 8
        vdir_new(&fb->vd, "fallback", vcl_name, vmod_fallback_healthy,
102
            vmod_fallback_resolve, fb);
103 8
        fb->st = sticky;
104 8
}
105
106
VCL_VOID v_matchproto_()
107 0
vmod_fallback__fini(struct vmod_directors_fallback **fbp)
108
{
109
        struct vmod_directors_fallback *fb;
110
111 0
        fb = *fbp;
112 0
        *fbp = NULL;
113 0
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
114 0
        vdir_delete(&fb->vd);
115 0
        FREE_OBJ(fb);
116 0
}
117
118
VCL_VOID v_matchproto_()
119 24
vmod_fallback_add_backend(VRT_CTX,
120
    struct vmod_directors_fallback *fb, VCL_BACKEND be)
121
{
122
123 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
124 24
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
125 24
        vdir_add_backend(ctx, fb->vd, be, 0.0);
126 24
}
127
128
VCL_VOID v_matchproto_()
129 8
vmod_fallback_remove_backend(VRT_CTX,
130
    struct vmod_directors_fallback *fb, VCL_BACKEND be)
131
{
132 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
133 8
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
134 8
        vdir_remove_backend(ctx, fb->vd, be, &fb->cur);
135 8
}
136
137
VCL_BACKEND v_matchproto_()
138 46
vmod_fallback_backend(VRT_CTX,
139
    struct vmod_directors_fallback *fb)
140
{
141 46
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
142 46
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
143 46
        return (fb->vd->dir);
144
}