varnish-cache/bin/varnishd/cache/cache_filter.h
0
/*-
1
 * Copyright (c) 2013-2015 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 */
30
31
struct req;
32
struct vfp_entry;
33
struct vfp_ctx;
34
struct vdp_ctx;
35
struct vdp_entry;
36
37
/* Fetch processors --------------------------------------------------*/
38
39
#define VFP_DEBUG(ctx, fmt, ...)                                        \
40
        do {                                                            \
41
                if (!DO_DEBUG(DBG_PROCESSORS))                          \
42
                        break;                                          \
43
                VSLb((ctx)->wrk->vsl, SLT_Debug, "VFP:%s:%d: " fmt,     \
44
                    __func__, __LINE__, __VA_ARGS__);                   \
45
        } while (0)
46
47
enum vfp_status {
48
        VFP_ERROR = -1,
49
        VFP_OK = 0,
50
        VFP_END = 1,
51
        VFP_NULL = 2,   // signal bypass, never returned by VFP_Suck()
52
};
53
54
typedef enum vfp_status vfp_init_f(VRT_CTX, struct vfp_ctx *,
55
    struct vfp_entry *);
56
typedef enum vfp_status
57
    vfp_pull_f(struct vfp_ctx *, struct vfp_entry *, void *ptr, ssize_t *len);
58
typedef void vfp_fini_f(struct vfp_ctx *, struct vfp_entry *);
59
60
struct vfp {
61
        const char              *name;
62
        vfp_init_f              *init;
63
        vfp_pull_f              *pull;
64
        vfp_fini_f              *fini;
65
        const void              *priv1;
66
};
67
68
struct vfp_entry {
69
        unsigned                magic;
70
#define VFP_ENTRY_MAGIC         0xbe32a027
71
        enum vfp_status         closed;
72
        const struct vfp        *vfp;
73
        void                    *priv1; // XXX ambiguous with priv1 in struct vfp
74
        ssize_t                 priv2;
75
        VTAILQ_ENTRY(vfp_entry) list;
76
        uint64_t                calls;
77
        uint64_t                bytes_out;
78
};
79
80
/*--------------------------------------------------------------------
81
 * VFP filter state
82
 */
83
84
VTAILQ_HEAD(vfp_entry_s, vfp_entry);
85
86
struct vfp_ctx {
87
        unsigned                magic;
88
#define VFP_CTX_MAGIC           0x61d9d3e5
89
        int                     failed;
90
        struct http             *req;
91
        struct http             *resp;
92
        struct worker           *wrk;
93
        struct objcore          *oc; // Only first filter, if at all
94
95
        struct vfp_entry_s      vfp;
96
        struct vfp_entry        *vfp_nxt;
97
        unsigned                obj_flags;
98
};
99
100
enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp);
101
enum vfp_status VFP_Error(struct vfp_ctx *, const char *fmt, ...)
102
    v_printflike_(2, 3);
103
104
/* Deliver processors ------------------------------------------------*/
105
106
enum vdp_action {
107
        VDP_NULL,               /* Input buffer valid after call */
108
        VDP_FLUSH,              /* Input buffer will be invalidated */
109
        VDP_END,                /* Last buffer or after, implies VDP_FLUSH */
110
};
111
112
113
typedef int vdp_init_f(VRT_CTX, struct vdp_ctx *, void **priv);
114
/*
115
 * Return value:
116
 *      negative:       Error - abandon delivery
117
 *      zero:           OK
118
 *      positive:       Don't push this VDP anyway
119
 */
120
121
typedef int vdp_fini_f(struct vdp_ctx *, void **priv);
122
typedef int vdp_bytes_f(struct vdp_ctx *, enum vdp_action, void **priv,
123
    const void *ptr, ssize_t len);
124
125
/*
126
 * ============================================================
127
 * vdpio io-vector interface
128
 */
129
typedef int vdpio_init_f(VRT_CTX, struct vdp_ctx *, void **priv, int capacity);
130
/*
131
 * the vdpio_init_f() are called front (object iterator) to back (consumer).
132
 *
133
 * each init function returns the minimum number of io vectors (vscarab
134
 * capacity) that it requires the next filter to accept. This capacity is
135
 * passed to the next init function such that it can allocate sufficient
136
 * space to fulfil the requirement of the previous filter.
137
 *
138
 * Return values:
139
 *   < 0 : Error
140
 *  == 0 ; NOOP, do not push this filter
141
 *  >= 1 : capacity requirement
142
 *
143
 * typedef is shared with upgrade
144
 */
145
146
typedef int vdpio_lease_f(struct vdp_ctx *, struct vdp_entry *, struct vscarab *scarab);
147
/*
148
 * vdpio_lease_f() returns leases provided by this filter layer in the vscarab
149
 * probided by the caller.
150
 *
151
 * called via vdpio_pull(): the last filter is called first by delivery. Each
152
 * filter calls the previous layer for leases. The first filter calls storage.
153
 *
154
 * return values are as for ObjVAIlease()
155
 *
156
 * Other notable differences to vdp_bytes_f:
157
 * - responsible for updating (struct vdp_entry).bytes_in and .calls
158
 *
159
 */
160
161
typedef void vdpio_fini_f(struct vdp_ctx *, void **priv);
162
163
struct vdp {
164
        const char              *name;
165
        vdp_init_f              *init;
166
        vdp_bytes_f             *bytes;
167
        vdp_fini_f              *fini;
168
        const void              *priv1;
169
170
        vdpio_init_f            *io_init;
171
        vdpio_init_f            *io_upgrade;
172
        vdpio_lease_f           *io_lease;
173
        vdpio_fini_f            *io_fini;
174
};
175
176
struct vdp_entry {
177
        unsigned                magic;
178
#define VDP_ENTRY_MAGIC         0x353eb781
179
        enum vdp_action         end;    // VDP_NULL or VDP_END
180
        const struct vdp        *vdp;
181
        void                    *priv;
182
        VTAILQ_ENTRY(vdp_entry) list;
183
        uint64_t                calls;
184
        uint64_t                bytes_in;
185
};
186
187
VTAILQ_HEAD(vdp_entry_s, vdp_entry);
188
189
struct vdp_ctx {
190
        unsigned                magic;
191
#define VDP_CTX_MAGIC           0xee501df7
192
        int                     retval;         // vdpio: error or capacity
193
        uint64_t                bytes_done;     // not used with vdpio
194
        struct vdp_entry_s      vdp;
195
        struct vdp_entry        *nxt;           // not needed for vdpio
196
        struct worker           *wrk;
197
        struct vsl_log          *vsl;
198
        // NULL'ed after the first filter has been pushed
199
        struct objcore          *oc;
200
        // NULL'ed for delivery
201
        struct http             *hp;
202
        intmax_t                *clen;
203
        // only for vdpio
204
        vai_hdl                 vai_hdl;
205
        struct vscaret          *scaret;
206
};
207
208
int VDP_bytes(struct vdp_ctx *, enum vdp_action act, const void *, ssize_t);
209
210
/*
211
 * vdpe == NULL: get lesaes from the last layer
212
 * vdpe != NULL: get leases from the previous layer or storage
213
 *
214
 * conversely to VDP_bytes, vdpio calls happen back (delivery) to front (storage)
215
 *
216
 * ends up in a tail call to the previous layer to save stack space
217
 */
218
static inline int
219 70
vdpio_pull(struct vdp_ctx *vdc, struct vdp_entry *vdpe, struct vscarab *scarab)
220
{
221
222 70
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
223
224 70
        if (vdpe == NULL)
225 0
                vdpe = VTAILQ_LAST(&vdc->vdp, vdp_entry_s);
226
        else {
227 70
                CHECK_OBJ(vdpe, VDP_ENTRY_MAGIC);
228 70
                vdpe = VTAILQ_PREV(vdpe, vdp_entry_s, list);
229
        }
230
231 70
        if (vdpe != NULL)
232 52
                return (vdpe->vdp->io_lease(vdc, vdpe, scarab));
233
        else
234 18
                return (ObjVAIlease(vdc->wrk, vdc->vai_hdl, scarab));
235 70
}
236
237
uint64_t VDPIO_Close1(struct vdp_ctx *, struct vdp_entry *vdpe);
238
239
/*
240
 * ============================================================
241
 * VDPIO helpers
242
 */
243
244
/*
245
 * l bytes have been written to buf. save these to out and checkpoint buf for
246
 * the remaining free space
247
 */
248
static inline void
249
iovec_collect(struct iovec *buf, struct iovec *out, size_t l)
250
{
251
        if (out->iov_base == NULL)
252
                out->iov_base = buf->iov_base;
253
        assert((char *)out->iov_base + out->iov_len == buf->iov_base);
254
        out->iov_len += l;
255
        buf->iov_base = (char *)buf->iov_base + l;
256
        buf->iov_len -= l;
257
}
258
259
/*
260
 * return a single lease via the vdc vscaret
261
 */
262
static inline
263
void vdpio_return_lease(const struct vdp_ctx *vdc, uint64_t lease)
264
{
265
        struct vscaret *scaret;
266
267
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
268
        scaret = vdc->scaret;
269
        VSCARET_CHECK_NOTNULL(scaret);
270
271
        if (scaret->used == scaret->capacity)
272
                ObjVAIreturn(vdc->wrk, vdc->vai_hdl, scaret);
273
        VSCARET_ADD(scaret, lease);
274
}
275
276
/*
277
 * add all leases from the vscarab to the vscaret
278
 */
279
static inline
280
void vdpio_return_vscarab(const struct vdp_ctx *vdc, struct vscarab *scarab)
281
{
282
        struct viov *v;
283
284
        VSCARAB_CHECK_NOTNULL(scarab);
285
        VSCARAB_FOREACH(v, scarab)
286
                vdpio_return_lease(vdc, v->lease);
287
        AZ(v);
288
        VSCARAB_INIT(scarab, scarab->capacity);
289
}
290
291
/*
292
 * return used up iovs (len == 0)
293
 * move remaining to the beginning of the scarab
294
 */
295
static inline void
296
vdpio_consolidate_vscarab(const struct vdp_ctx *vdc, struct vscarab *scarab)
297
{
298
        struct viov *v, *f = NULL;
299
300
        VSCARAB_CHECK_NOTNULL(scarab);
301
        VSCARAB_FOREACH(v, scarab) {
302
                if (v->iov.iov_len == 0) {
303
                        AN(v->iov.iov_base);
304
                        vdpio_return_lease(vdc, v->lease);
305
                        if (f == NULL)
306
                                f = v;
307
                        continue;
308
                }
309
                else if (f == NULL)
310
                        continue;
311
                memmove(f, v, scarab->used - (v - scarab->s) * sizeof (*v));
312
                break;
313
        }
314
        if (f != NULL)
315
                scarab->used = f - scarab->s;
316
}
317
318
// Lifecycle management in cache_deliver_proc.c
319
int VDPIO_Init(struct vdp_ctx *vdc, struct objcore *oc, struct ws *ws,
320
    vai_notify_cb *notify_cb, void *notify_priv, struct vscaret *scaret);
321
void VDPIO_Return(const struct vdp_ctx *vdc);
322
void VDPIO_Fini(struct vdp_ctx *vdc);
323
324
/* Registry functions -------------------------------------------------*/
325
const char *VRT_AddFilter(VRT_CTX, const struct vfp *, const struct vdp *);
326
void VRT_RemoveFilter(VRT_CTX, const struct vfp *, const struct vdp *);