varnish-cache/bin/varnishd/storage/stevedore.c
1
/*-
2
 * Copyright (c) 2007-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Dag-Erling Smørgav <des@des.no>
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
 * STEVEDORE: one who works at or is responsible for loading and
29
 * unloading ships in port.  Example: "on the wharves, stevedores were
30
 * unloading cargo from the far corners of the world." Origin: Spanish
31
 * estibador, from estibar to pack.  First Known Use: 1788
32
 */
33
34
#include "config.h"
35
36
#include "cache/cache_varnishd.h"
37
38
#include <stdio.h>
39
#include <stdlib.h>
40
41
#include "storage/storage.h"
42
#include "vrt_obj.h"
43
44
45
static pthread_mutex_t stv_mtx;
46
47
/*--------------------------------------------------------------------
48
 * XXX: trust pointer writes to be atomic
49
 */
50
51
const struct stevedore *
52 4560
STV_next()
53
{
54
        static struct stevedore *stv;
55
        struct stevedore *r;
56
57 4560
        AZ(pthread_mutex_lock(&stv_mtx));
58 4560
        if (!STV__iter(&stv))
59 16
                AN(STV__iter(&stv));
60 4560
        if (stv == stv_transient) {
61 2456
                stv = NULL;
62 2456
                AN(STV__iter(&stv));
63
        }
64 4560
        r = stv;
65 4560
        AZ(pthread_mutex_unlock(&stv_mtx));
66 4560
        AN(r);
67 4560
        return (r);
68
}
69
70
/*-------------------------------------------------------------------
71
 * Allocate storage for an object, based on the header information.
72
 * XXX: If we know (a hint of) the length, we could allocate space
73
 * XXX: for the body in the same allocation while we are at it.
74
 */
75
76
int
77 7816
STV_NewObject(struct worker *wrk, struct objcore *oc,
78
    const struct stevedore *stv, unsigned wsl)
79
{
80 7816
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
81 7816
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
82 7816
        CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
83 7816
        assert(wsl > 0);
84
85 7816
        wrk->strangelove = cache_param->nuke_limit;
86 7816
        AN(stv->allocobj);
87 7816
        if (stv->allocobj(wrk, stv, oc, wsl) == 0)
88 20
                return (0);
89 7796
        oc->oa_present = 0;
90 7796
        wrk->stats->n_object++;
91 15592
        VSLb(wrk->vsl, SLT_Storage, "%s %s",
92 15592
            oc->stobj->stevedore->name, oc->stobj->stevedore->ident);
93 7795
        return (1);
94
}
95
96
/*-------------------------------------------------------------------*/
97
98
void
99 2752
STV_open(void)
100
{
101
        struct stevedore *stv;
102
        char buf[1024];
103
104 2752
        ASSERT_CLI();
105 2752
        AZ(pthread_mutex_init(&stv_mtx, NULL));
106 11056
        STV_Foreach(stv) {
107 5552
                bprintf(buf, "storage.%s", stv->ident);
108 5552
                stv->vclname = strdup(buf);
109 5552
                AN(stv->vclname);
110 5552
                if (stv->open != NULL)
111 5552
                        stv->open(stv);
112
        }
113 2752
}
114
115
void
116 2724
STV_close(void)
117
{
118
        struct stevedore *stv;
119
        int i;
120
121 2724
        ASSERT_CLI();
122 8172
        for (i = 1; i >= 0; i--) {
123
                /* First send close warning */
124 21888
                STV_Foreach(stv)
125 10992
                        if (stv->close != NULL)
126 296
                                stv->close(stv, i);
127
        }
128 2724
}
129
130
/*-------------------------------------------------------------------
131
 * Notify the stevedores of BAN related events. A non-zero return
132
 * value indicates that the stevedore is unable to persist the
133
 * event.
134
 */
135
136
int
137 201
STV_BanInfoDrop(const uint8_t *ban, unsigned len)
138
{
139
        struct stevedore *stv;
140 201
        int r = 0;
141
142 824
        STV_Foreach(stv)
143 422
                if (stv->baninfo != NULL)
144 88
                        r |= stv->baninfo(stv, BI_DROP, ban, len);
145
146 201
        return (r);
147
}
148
149
int
150 2976
STV_BanInfoNew(const uint8_t *ban, unsigned len)
151
{
152
        struct stevedore *stv;
153 2976
        int r = 0;
154
155 11964
        STV_Foreach(stv)
156 6012
                if (stv->baninfo != NULL)
157 192
                        r |= stv->baninfo(stv, BI_NEW, ban, len);
158
159 2976
        return (r);
160
}
161
162
/*-------------------------------------------------------------------
163
 * Export a complete ban list to the stevedores for persistence.
164
 * The stevedores should clear any previous ban lists and replace
165
 * them with this list.
166
 */
167
168
void
169 5476
STV_BanExport(const uint8_t *bans, unsigned len)
170
{
171
        struct stevedore *stv;
172
173 22000
        STV_Foreach(stv)
174 11048
                if (stv->banexport != NULL)
175 300
                        stv->banexport(stv, bans, len);
176 5476
}
177
178
/*--------------------------------------------------------------------
179
 * VRT functions for stevedores
180
 */
181
182
static const struct stevedore *
183 108
stv_find(const char *nm)
184
{
185
        struct stevedore *stv;
186
187 252
        STV_Foreach(stv)
188 144
                if (!strcmp(stv->ident, nm))
189 108
                        return (stv);
190 0
        return (NULL);
191
}
192
193
int
194 0
VRT_Stv(const char *nm)
195
{
196
197 0
        if (stv_find(nm) != NULL)
198 0
                return (1);
199 0
        return (0);
200
}
201
202
const char * v_matchproto_()
203 68
VRT_STEVEDORE_string(VCL_STEVEDORE s)
204
{
205 68
        if (s == NULL)
206 4
                return (NULL);
207 64
        CHECK_OBJ_NOTNULL(s, STEVEDORE_MAGIC);
208 64
        return (s->vclname);
209
}
210
211
VCL_STEVEDORE
212 92
VRT_stevedore(const char *nm)
213
{
214 92
        return (stv_find(nm));
215
}
216
217
#define VRTSTVVAR(nm, vtype, ctype, dval)       \
218
ctype                                           \
219
VRT_Stv_##nm(const char *nm)                    \
220
{                                               \
221
        const struct stevedore *stv;            \
222
                                                \
223
        stv = stv_find(nm);                     \
224
        if (stv == NULL)                        \
225
                return (dval);                  \
226
        if (stv->var_##nm == NULL)              \
227
                return (dval);                  \
228
        return (stv->var_##nm(stv));            \
229
}
230
231
#include "tbl/vrt_stv_var.h"