| | varnish-cache/bin/varnishd/cache/cache_busyobj.c |
0 |
|
/*- |
1 |
|
* Copyright (c) 2013-2015 Varnish Software AS |
2 |
|
* All rights reserved. |
3 |
|
* |
4 |
|
* Author: Martin Blix Grydeland <martin@varnish-software.com> |
5 |
|
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk> |
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 |
|
* Handle backend connections and backend request structures. |
31 |
|
* |
32 |
|
*/ |
33 |
|
|
34 |
|
#include "config.h" |
35 |
|
|
36 |
|
#include <stdlib.h> |
37 |
|
|
38 |
|
#include "cache_varnishd.h" |
39 |
|
#include "cache_filter.h" |
40 |
|
#include "cache_objhead.h" |
41 |
|
|
42 |
|
static struct mempool *vbopool; |
43 |
|
|
44 |
|
/*-------------------------------------------------------------------- |
45 |
|
*/ |
46 |
|
|
47 |
|
void |
48 |
36629 |
VBO_Init(void) |
49 |
|
{ |
50 |
|
|
51 |
73258 |
vbopool = MPL_New("busyobj", &cache_param->pool_vbo, |
52 |
36629 |
&cache_param->workspace_backend); |
53 |
36629 |
AN(vbopool); |
54 |
36629 |
} |
55 |
|
|
56 |
|
/*-------------------------------------------------------------------- |
57 |
|
* BusyObj handling |
58 |
|
*/ |
59 |
|
|
60 |
|
static struct busyobj * |
61 |
89160 |
vbo_New(void) |
62 |
|
{ |
63 |
|
struct busyobj *bo; |
64 |
|
unsigned sz; |
65 |
|
|
66 |
89160 |
bo = MPL_Get(vbopool, &sz); |
67 |
89160 |
XXXAN(bo); |
68 |
89160 |
bo->magic = BUSYOBJ_MAGIC; |
69 |
89160 |
bo->end = (char *)bo + sz; |
70 |
89160 |
return (bo); |
71 |
|
} |
72 |
|
|
73 |
|
static void |
74 |
89120 |
vbo_Free(struct busyobj **bop) |
75 |
|
{ |
76 |
|
struct busyobj *bo; |
77 |
|
|
78 |
89120 |
TAKE_OBJ_NOTNULL(bo, bop, BUSYOBJ_MAGIC); |
79 |
89120 |
AZ(bo->htc); |
80 |
89120 |
MPL_Free(vbopool, bo); |
81 |
89120 |
} |
82 |
|
|
83 |
|
struct busyobj * |
84 |
89159 |
VBO_GetBusyObj(const struct worker *wrk, const struct req *req) |
85 |
|
{ |
86 |
|
struct busyobj *bo; |
87 |
|
uint16_t nhttp; |
88 |
|
unsigned sz; |
89 |
|
char *p; |
90 |
|
|
91 |
89159 |
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); |
92 |
|
|
93 |
89159 |
bo = vbo_New(); |
94 |
89159 |
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); |
95 |
|
|
96 |
89159 |
p = (void*)(bo + 1); |
97 |
89159 |
p = (void*)PRNDUP(p); |
98 |
89159 |
assert(p < bo->end); |
99 |
|
|
100 |
89159 |
nhttp = (uint16_t)cache_param->http_max_hdr; |
101 |
89159 |
sz = HTTP_estimate(nhttp); |
102 |
|
|
103 |
89159 |
bo->bereq0 = HTTP_create(p, nhttp, sz); |
104 |
89159 |
p += sz; |
105 |
89159 |
p = (void*)PRNDUP(p); |
106 |
89159 |
assert(p < bo->end); |
107 |
|
|
108 |
89159 |
bo->bereq = HTTP_create(p, nhttp, sz); |
109 |
89159 |
p += sz; |
110 |
89159 |
p = (void*)PRNDUP(p); |
111 |
89159 |
assert(p < bo->end); |
112 |
|
|
113 |
89159 |
bo->beresp = HTTP_create(p, nhttp, sz); |
114 |
89159 |
p += sz; |
115 |
89159 |
p = (void*)PRNDUP(p); |
116 |
89159 |
assert(p < bo->end); |
117 |
|
|
118 |
89159 |
sz = cache_param->vsl_buffer; |
119 |
89159 |
VSL_Setup(bo->vsl, p, sz); |
120 |
89159 |
bo->vsl->wid = VXID_Get(wrk, VSL_BACKENDMARKER); |
121 |
89159 |
p += sz; |
122 |
89159 |
p = (void*)PRNDUP(p); |
123 |
89159 |
assert(p < bo->end); |
124 |
|
|
125 |
89159 |
bo->vfc = (void*)p; |
126 |
89159 |
p += sizeof (*bo->vfc); |
127 |
89159 |
p = (void*)PRNDUP(p); |
128 |
89159 |
INIT_OBJ(bo->vfc, VFP_CTX_MAGIC); |
129 |
|
|
130 |
89159 |
WS_Init(bo->ws, "bo", p, bo->end - p); |
131 |
|
|
132 |
89159 |
bo->do_stream = 1; |
133 |
|
|
134 |
89159 |
if (req->client_identity != NULL) { |
135 |
40 |
bo->client_identity = WS_Copy(bo->ws, req->client_identity, -1); |
136 |
40 |
XXXAN(bo->client_identity); |
137 |
40 |
} |
138 |
|
|
139 |
89159 |
VRT_Assign_Backend(&bo->director_req, req->director_hint); |
140 |
89159 |
bo->vcl = req->vcl; |
141 |
89159 |
VCL_Ref(bo->vcl); |
142 |
|
|
143 |
89159 |
bo->t_first = bo->t_prev = NAN; |
144 |
89159 |
bo->connect_timeout = NAN; |
145 |
89159 |
bo->first_byte_timeout = NAN; |
146 |
89159 |
bo->between_bytes_timeout = NAN; |
147 |
|
|
148 |
89159 |
memcpy(bo->digest, req->digest, sizeof bo->digest); |
149 |
|
|
150 |
89159 |
return (bo); |
151 |
|
} |
152 |
|
|
153 |
|
void |
154 |
89120 |
VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **pbo) |
155 |
|
{ |
156 |
|
struct busyobj *bo; |
157 |
|
|
158 |
89120 |
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); |
159 |
89120 |
TAKE_OBJ_NOTNULL(bo, pbo, BUSYOBJ_MAGIC); |
160 |
89120 |
CHECK_OBJ_ORNULL(bo->fetch_objcore, OBJCORE_MAGIC); |
161 |
|
|
162 |
89120 |
AZ(bo->htc); |
163 |
89120 |
AZ(bo->stale_oc); |
164 |
|
|
165 |
178240 |
VSLb(bo->vsl, SLT_BereqAcct, "%ju %ju %ju %ju %ju %ju", |
166 |
89120 |
(uintmax_t)bo->acct.bereq_hdrbytes, |
167 |
89120 |
(uintmax_t)bo->acct.bereq_bodybytes, |
168 |
89120 |
(uintmax_t)(bo->acct.bereq_hdrbytes + bo->acct.bereq_bodybytes), |
169 |
89120 |
(uintmax_t)bo->acct.beresp_hdrbytes, |
170 |
89120 |
(uintmax_t)bo->acct.beresp_bodybytes, |
171 |
89120 |
(uintmax_t)(bo->acct.beresp_hdrbytes + bo->acct.beresp_bodybytes)); |
172 |
|
|
173 |
89120 |
VSL_End(bo->vsl); |
174 |
|
|
175 |
89120 |
AZ(bo->htc); |
176 |
|
|
177 |
89120 |
if (WS_Overflowed(bo->ws)) |
178 |
6800 |
wrk->stats->ws_backend_overflow++; |
179 |
|
|
180 |
89120 |
if (bo->fetch_objcore != NULL) { |
181 |
87880 |
(void)HSH_DerefObjCore(wrk, &bo->fetch_objcore, |
182 |
|
HSH_RUSH_POLICY); |
183 |
87880 |
} |
184 |
|
|
185 |
89120 |
VRT_Assign_Backend(&bo->director_req, NULL); |
186 |
89120 |
VRT_Assign_Backend(&bo->director_resp, NULL); |
187 |
89120 |
VCL_Rel(&bo->vcl); |
188 |
|
#ifdef ENABLE_WORKSPACE_EMULATOR |
189 |
|
WS_Rollback(bo->ws, 0); |
190 |
|
#endif |
191 |
|
|
192 |
89120 |
memset(&bo->retries, 0, |
193 |
|
sizeof *bo - offsetof(struct busyobj, retries)); |
194 |
|
|
195 |
89120 |
vbo_Free(&bo); |
196 |
89120 |
} |