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 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * STEVEDORE: one who works at or is responsible for loading and
31 * unloading ships in port. Example: "on the wharves, stevedores were
32 * unloading cargo from the far corners of the world." Origin: Spanish
33 * estibador, from estibar to pack. First Known Use: 1788
34 */
35
36 #include "config.h"
37
38 #include "cache/cache_varnishd.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42
43 #include "storage/storage.h"
44 #include "vrt_obj.h"
45
46 static pthread_mutex_t stv_mtx;
47
48 /*--------------------------------------------------------------------
49 * XXX: trust pointer writes to be atomic
50 */
51
52 const struct stevedore *
STV_next()53 STV_next()
54 {
55 static struct stevedore *stv;
56 struct stevedore *r;
57
58 AZ(pthread_mutex_lock(&stv_mtx));
59 if (!STV__iter(&stv))
60 AN(STV__iter(&stv));
61 if (stv == stv_transient) {
62 stv = NULL;
63 AN(STV__iter(&stv));
64 }
65 r = stv;
66 AZ(pthread_mutex_unlock(&stv_mtx));
67 AN(r);
68 return (r);
69 }
70
71 /*-------------------------------------------------------------------
72 * Allocate storage for an object, based on the header information.
73 * XXX: If we know (a hint of) the length, we could allocate space
74 * XXX: for the body in the same allocation while we are at it.
75 */
76
77 int
STV_NewObject(struct worker * wrk,struct objcore * oc,const struct stevedore * stv,unsigned wsl)78 STV_NewObject(struct worker *wrk, struct objcore *oc,
79 const struct stevedore *stv, unsigned wsl)
80 {
81 CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
82 CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
83 CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
84 assert(wsl > 0);
85
86 wrk->strangelove = cache_param->nuke_limit;
87 AN(stv->allocobj);
88 if (stv->allocobj(wrk, stv, oc, wsl) == 0)
89 return (0);
90 oc->oa_present = 0;
91 wrk->stats->n_object++;
92 VSLb(wrk->vsl, SLT_Storage, "%s %s",
93 oc->stobj->stevedore->name, oc->stobj->stevedore->ident);
94 return (1);
95 }
96
97 /*-------------------------------------------------------------------*/
98
99 void
STV_open(void)100 STV_open(void)
101 {
102 struct stevedore *stv;
103 char buf[1024];
104
105 ASSERT_CLI();
106 AZ(pthread_mutex_init(&stv_mtx, NULL));
107 STV_Foreach(stv) {
108 bprintf(buf, "storage.%s", stv->ident);
109 stv->vclname = strdup(buf);
110 AN(stv->vclname);
111 if (stv->open != NULL)
112 stv->open(stv);
113 }
114 }
115
116 void
STV_close(void)117 STV_close(void)
118 {
119 struct stevedore *stv;
120 int i;
121
122 ASSERT_CLI();
123 for (i = 1; i >= 0; i--) {
124 /* First send close warning */
125 STV_Foreach(stv)
126 if (stv->close != NULL)
127 stv->close(stv, i);
128 }
129 }
130
131 /*-------------------------------------------------------------------
132 * Notify the stevedores of BAN related events. A non-zero return
133 * value indicates that the stevedore is unable to persist the
134 * event.
135 */
136
137 int
STV_BanInfoDrop(const uint8_t * ban,unsigned len)138 STV_BanInfoDrop(const uint8_t *ban, unsigned len)
139 {
140 struct stevedore *stv;
141 int r = 0;
142
143 STV_Foreach(stv)
144 if (stv->baninfo != NULL)
145 r |= stv->baninfo(stv, BI_DROP, ban, len);
146
147 return (r);
148 }
149
150 int
STV_BanInfoNew(const uint8_t * ban,unsigned len)151 STV_BanInfoNew(const uint8_t *ban, unsigned len)
152 {
153 struct stevedore *stv;
154 int r = 0;
155
156 STV_Foreach(stv)
157 if (stv->baninfo != NULL)
158 r |= stv->baninfo(stv, BI_NEW, ban, len);
159
160 return (r);
161 }
162
163 /*-------------------------------------------------------------------
164 * Export a complete ban list to the stevedores for persistence.
165 * The stevedores should clear any previous ban lists and replace
166 * them with this list.
167 */
168
169 void
STV_BanExport(const uint8_t * bans,unsigned len)170 STV_BanExport(const uint8_t *bans, unsigned len)
171 {
172 struct stevedore *stv;
173
174 STV_Foreach(stv)
175 if (stv->banexport != NULL)
176 stv->banexport(stv, bans, len);
177 }
178
179 /*--------------------------------------------------------------------
180 * VRT functions for stevedores
181 */
182
183 static const struct stevedore *
stv_find(const char * nm)184 stv_find(const char *nm)
185 {
186 struct stevedore *stv;
187
188 STV_Foreach(stv)
189 if (!strcmp(stv->ident, nm))
190 return (stv);
191 return (NULL);
192 }
193
194 int
VRT_Stv(const char * nm)195 VRT_Stv(const char *nm)
196 {
197
198 if (stv_find(nm) != NULL)
199 return (1);
200 return (0);
201 }
202
v_matchproto_()203 const char * v_matchproto_()
204 VRT_STEVEDORE_string(VCL_STEVEDORE s)
205 {
206 if (s == NULL)
207 return (NULL);
208 CHECK_OBJ_NOTNULL(s, STEVEDORE_MAGIC);
209 return (s->vclname);
210 }
211
212 VCL_STEVEDORE
VRT_stevedore(const char * nm)213 VRT_stevedore(const char *nm)
214 {
215 return (stv_find(nm));
216 }
217
218 #define VRTSTVVAR(nm, vtype, ctype, dval) \
219 ctype \
220 VRT_stevedore_##nm(VCL_STEVEDORE stv) \
221 { \
222 if (stv == NULL) \
223 return (0); \
224 CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC); \
225 return (stv->var_##nm(stv)); \
226 }
227 #include "tbl/vrt_stv_var.h"
228