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
36
#include "vcc_if.h"
37
38
#include "vdir.h"
39
40
struct vmod_directors_fallback {
41
        unsigned                                magic;
42
#define VMOD_DIRECTORS_FALLBACK_MAGIC           0xad4e26ba
43
        struct vdir                             *vd;
44
        VCL_BOOL                                st;
45
        unsigned                                cur;
46
};
47
48
static VCL_BOOL v_matchproto_(vdi_healthy)
49 0
vmod_fallback_healthy(VRT_CTX, VCL_BACKEND dir, VCL_TIME *changed)
50
{
51
        struct vmod_directors_fallback *fb;
52
53 0
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
54 0
        CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
55 0
        CAST_OBJ_NOTNULL(fb, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
56 0
        return (vdir_any_healthy(ctx, fb->vd, changed));
57
}
58
59
static VCL_BACKEND v_matchproto_(vdi_resolve_f)
60 46
vmod_fallback_resolve(VRT_CTX, VCL_BACKEND dir)
61
{
62
        struct vmod_directors_fallback *fb;
63
        unsigned u;
64 46
        VCL_BACKEND be = NULL;
65
66 46
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
67 46
        CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
68 46
        CAST_OBJ_NOTNULL(fb, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
69
70 46
        vdir_wrlock(fb->vd);
71 46
        if (!fb->st)
72 28
                fb->cur = 0;
73 74
        for (u = 0; u < fb->vd->n_backend; u++) {
74 72
                be = fb->vd->backend[fb->cur];
75 72
                CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
76 72
                if (VRT_Healthy(ctx, be, NULL))
77 44
                        break;
78 28
                if (++fb->cur == fb->vd->n_backend)
79 4
                        fb->cur = 0;
80
        }
81 46
        vdir_unlock(fb->vd);
82 46
        if (u == fb->vd->n_backend)
83 2
                be = NULL;
84 46
        return (be);
85
}
86
87
static void v_matchproto_(vdi_destroy_f)
88 0
vmod_fallback_destroy(VCL_BACKEND dir)
89
{
90
        struct vmod_directors_fallback *fallback;
91
92 0
        CAST_OBJ_NOTNULL(fallback, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
93 0
        vdir_delete(&fallback->vd);
94 0
        FREE_OBJ(fallback);
95 0
}
96
97
static const struct vdi_methods vmod_fallback_methods[1] = {{
98
        .magic =                VDI_METHODS_MAGIC,
99
        .type =                 "fallback",
100
        .healthy =              vmod_fallback_healthy,
101
        .resolve =              vmod_fallback_resolve,
102
        .destroy =              vmod_fallback_destroy
103
}};
104
105
106
VCL_VOID v_matchproto_()
107 8
vmod_fallback__init(VRT_CTX,
108
    struct vmod_directors_fallback **fbp, const char *vcl_name, VCL_BOOL sticky)
109
{
110
        struct vmod_directors_fallback *fb;
111
112 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
113 8
        AN(fbp);
114 8
        AZ(*fbp);
115 8
        ALLOC_OBJ(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
116 8
        AN(fb);
117 8
        *fbp = fb;
118 8
        vdir_new(ctx, &fb->vd, vcl_name, vmod_fallback_methods, fb);
119 8
        fb->st = sticky;
120 8
}
121
122
VCL_VOID v_matchproto_()
123 0
vmod_fallback__fini(struct vmod_directors_fallback **fbp)
124
{
125
        struct vmod_directors_fallback *fb;
126
127
        // XXX 2297
128 0
        if (*fbp == NULL)
129 0
                return;
130
131 0
        TAKE_OBJ_NOTNULL(fb, fbp, VMOD_DIRECTORS_FALLBACK_MAGIC);
132 0
        VRT_DelDirector(&fb->vd->dir);
133
}
134
135
VCL_VOID v_matchproto_()
136 24
vmod_fallback_add_backend(VRT_CTX,
137
    struct vmod_directors_fallback *fb, VCL_BACKEND be)
138
{
139
140 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
141 24
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
142 24
        vdir_add_backend(ctx, fb->vd, be, 0.0);
143 24
}
144
145
VCL_VOID v_matchproto_()
146 8
vmod_fallback_remove_backend(VRT_CTX,
147
    struct vmod_directors_fallback *fb, VCL_BACKEND be)
148
{
149 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
150 8
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
151 8
        vdir_remove_backend(ctx, fb->vd, be, &fb->cur);
152 8
}
153
154
VCL_BACKEND v_matchproto_()
155 46
vmod_fallback_backend(VRT_CTX,
156
    struct vmod_directors_fallback *fb)
157
{
158 46
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
159 46
        CHECK_OBJ_NOTNULL(fb, VMOD_DIRECTORS_FALLBACK_MAGIC);
160 46
        return (fb->vd->dir);
161
}