varnish-cache/bin/varnishd/cache/cache_backend.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
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
 * The director implementation for VCL backends.
30
 *
31
 */
32
33
#include "config.h"
34
35
#include <stdlib.h>
36
#include <errno.h>
37
38
#include "cache_varnishd.h"
39
40
#include "vtcp.h"
41
#include "vtim.h"
42
43
#include "cache_backend.h"
44
#include "cache_tcp_pool.h"
45
#include "cache_transport.h"
46
#include "cache_vcl.h"
47
#include "http1/cache_http1.h"
48
49
#include "VSC_vbe.h"
50
51
/*--------------------------------------------------------------------*/
52
53
static const char * const vbe_proto_ident = "HTTP Backend";
54
55
static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends);
56
static VTAILQ_HEAD(, backend) cool_backends =
57
    VTAILQ_HEAD_INITIALIZER(cool_backends);
58
static struct lock backends_mtx;
59
60
/*--------------------------------------------------------------------*/
61
62
void
63 367
VBE_Connect_Error(struct VSC_vbe *vsc, int err)
64
{
65
66 367
        switch(err) {
67
        case 0:
68
                /*
69
                 * This is kind of brittle, but zero is the only
70
                 * value of errno we can trust to have no meaning.
71
                 */
72 80
                vsc->helddown++;
73 80
                break;
74
        case EACCES:
75
        case EPERM:
76 0
                vsc->fail_eacces++;
77 0
                break;
78
        case EADDRNOTAVAIL:
79 0
                vsc->fail_eaddrnotavail++;
80 0
                break;
81
        case ECONNREFUSED:
82 287
                vsc->fail_econnrefused++;
83 287
                break;
84
        case ENETUNREACH:
85 0
                vsc->fail_enetunreach++;
86 0
                break;
87
        case ETIMEDOUT:
88 0
                vsc->fail_etimedout++;
89 0
                break;
90
        default:
91 0
                vsc->fail_other++;
92
        }
93 367
}
94
95
/*--------------------------------------------------------------------*/
96
97
#define FIND_TMO(tmx, dst, bo, be)                                      \
98
        do {                                                            \
99
                CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);                   \
100
                dst = bo->tmx;                                          \
101
                if (dst == 0.0)                                         \
102
                        dst = be->tmx;                                  \
103
                if (dst == 0.0)                                         \
104
                        dst = cache_param->tmx;                         \
105
        } while (0)
106
107
/*--------------------------------------------------------------------
108
 * Get a connection to the backend
109
 */
110
111
static struct pfd *
112 6704
vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo,
113
    unsigned force_fresh)
114
{
115
        struct pfd *pfd;
116
        int *fdp, err;
117
        vtim_dur tmod;
118
        char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE];
119
        char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE];
120
121 6704
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
122 6704
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
123 6704
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
124 6704
        AN(bp->vsc);
125
126 6704
        if (bp->director->sick) {
127 20
                VSLb(bo->vsl, SLT_FetchError,
128
                     "backend %s: unhealthy", VRT_BACKEND_string(bp->director));
129 20
                bp->vsc->unhealthy++;
130 20
                VSC_C_main->backend_unhealthy++;
131 20
                return (NULL);
132
        }
133
134 6684
        if (bp->max_connections > 0 && bp->n_conn >= bp->max_connections) {
135 8
                VSLb(bo->vsl, SLT_FetchError,
136
                     "backend %s: busy", VRT_BACKEND_string(bp->director));
137 8
                bp->vsc->busy++;
138 8
                VSC_C_main->backend_busy++;
139 8
                return (NULL);
140
        }
141
142 6676
        AZ(bo->htc);
143 6676
        bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc);
144 6676
        if (bo->htc == NULL) {
145 112
                VSLb(bo->vsl, SLT_FetchError, "out of workspace");
146
                /* XXX: counter ? */
147 112
                return (NULL);
148
        }
149 6564
        bo->htc->doclose = SC_NULL;
150
151 6564
        FIND_TMO(connect_timeout, tmod, bo, bp);
152 6564
        pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh, &err);
153 6564
        if (pfd == NULL) {
154 60
                VBE_Connect_Error(bp->vsc, err);
155 60
                VSLb(bo->vsl, SLT_FetchError,
156
                     "backend %s: fail errno %d (%s)",
157
                     VRT_BACKEND_string(bp->director), err, strerror(err));
158 60
                VSC_C_main->backend_fail++;
159 60
                bo->htc = NULL;
160 60
                return (NULL);
161
        }
162
163 6504
        fdp = PFD_Fd(pfd);
164 6504
        AN(fdp);
165 6504
        assert(*fdp >= 0);
166
167 6504
        Lck_Lock(&bp->mtx);
168 6504
        bp->n_conn++;
169 6504
        bp->vsc->conn++;
170 6504
        bp->vsc->req++;
171 6504
        Lck_Unlock(&bp->mtx);
172
173 6503
        if (bp->proxy_header != 0)
174 20
                VPX_Send_Proxy(*fdp, bp->proxy_header, bo->sp);
175
176 6503
        PFD_LocalName(pfd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
177 6504
        PFD_RemoteName(pfd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
178 6504
        VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s",
179
            *fdp, VRT_BACKEND_string(bp->director), abuf2, pbuf2, abuf1, pbuf1);
180
181 6503
        INIT_OBJ(bo->htc, HTTP_CONN_MAGIC);
182 6503
        bo->htc->priv = pfd;
183 6503
        bo->htc->rfd = fdp;
184 6503
        FIND_TMO(first_byte_timeout,
185
            bo->htc->first_byte_timeout, bo, bp);
186 6503
        FIND_TMO(between_bytes_timeout,
187
            bo->htc->between_bytes_timeout, bo, bp);
188 6503
        return (pfd);
189
}
190
191
static void v_matchproto_(vdi_finish_f)
192 6500
vbe_dir_finish(VRT_CTX, VCL_BACKEND d)
193
{
194
        struct backend *bp;
195
        struct busyobj *bo;
196
        struct pfd *pfd;
197
198 6500
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
199 6500
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
200 6500
        bo = ctx->bo;
201 6500
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
202 6500
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
203
204 6500
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
205 6500
        pfd = bo->htc->priv;
206 6500
        bo->htc->priv = NULL;
207 6500
        if (PFD_State(pfd) != PFD_STATE_USED)
208 4
                assert(bo->htc->doclose == SC_TX_PIPE ||
209
                    bo->htc->doclose == SC_RX_TIMEOUT);
210 6500
        if (bo->htc->doclose != SC_NULL || bp->proxy_header != 0) {
211 824
                VSLb(bo->vsl, SLT_BackendClose, "%d %s", *PFD_Fd(pfd),
212
                    VRT_BACKEND_string(bp->director));
213 824
                VTP_Close(&pfd);
214 824
                AZ(pfd);
215 824
                Lck_Lock(&bp->mtx);
216
        } else {
217 5676
                assert (PFD_State(pfd) == PFD_STATE_USED);
218 5676
                VSLb(bo->vsl, SLT_BackendReuse, "%d %s", *PFD_Fd(pfd),
219
                    VRT_BACKEND_string(bp->director));
220 5676
                Lck_Lock(&bp->mtx);
221 5676
                VSC_C_main->backend_recycle++;
222 5676
                VTP_Recycle(bo->wrk, &pfd);
223
        }
224 6500
        assert(bp->n_conn > 0);
225 6500
        bp->n_conn--;
226 6500
        AN(bp->vsc);
227 6500
        bp->vsc->conn--;
228
#define ACCT(foo)       bp->vsc->foo += bo->acct.foo;
229
#include "tbl/acct_fields_bereq.h"
230 6500
        Lck_Unlock(&bp->mtx);
231 6500
        bo->htc = NULL;
232 6500
}
233
234
static int v_matchproto_(vdi_gethdrs_f)
235 6636
vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d)
236
{
237 6636
        int i, extrachance = 1;
238
        struct backend *bp;
239
        struct pfd *pfd;
240
        struct busyobj *bo;
241
        struct worker *wrk;
242
        char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
243
244 6636
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
245 6636
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
246 6636
        bo = ctx->bo;
247 6636
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
248 6636
        wrk = ctx->bo->wrk;
249 6636
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
250 6636
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
251
252
        /*
253
         * Now that we know our backend, we can set a default Host:
254
         * header if one is necessary.  This cannot be done in the VCL
255
         * because the backend may be chosen by a director.
256
         */
257 6636
        if (!http_GetHdr(bo->bereq, H_Host, NULL) && bp->hosthdr != NULL)
258 160
                http_PrintfHeader(bo->bereq, "Host: %s", bp->hosthdr);
259
260
        do {
261 6656
                pfd = vbe_dir_getfd(wrk, bp, bo, extrachance == 0);
262 6656
                if (pfd == NULL)
263 196
                        return (-1);
264 6460
                AN(bo->htc);
265 6460
                if (PFD_State(pfd) != PFD_STATE_STOLEN)
266 3882
                        extrachance = 0;
267
268 6460
                PFD_RemoteName(pfd, abuf, sizeof abuf, pbuf, sizeof pbuf);
269 6460
                i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes,
270
                                &bo->acct.bereq_bodybytes, 0, abuf, pbuf);
271
272 6460
                if (PFD_State(pfd) != PFD_STATE_USED) {
273 4932
                        if (VTP_Wait(wrk, pfd, VTIM_real() +
274 2466
                            bo->htc->first_byte_timeout) != 0) {
275 4
                                bo->htc->doclose = SC_RX_TIMEOUT;
276 4
                                VSLb(bo->vsl, SLT_FetchError,
277
                                     "Timed out reusing backend connection");
278 4
                                extrachance = 0;
279
                        }
280
                }
281
282 6460
                if (bo->htc->doclose == SC_NULL) {
283 6420
                        assert(PFD_State(pfd) == PFD_STATE_USED);
284 6420
                        if (i == 0)
285 6420
                                i = V1F_FetchRespHdr(bo);
286 6420
                        if (i == 0) {
287 6176
                                AN(bo->htc->priv);
288 6176
                                return (0);
289
                        }
290
                }
291
292
                /*
293
                 * If we recycled a backend connection, there is a finite chance
294
                 * that the backend closed it before we got the bereq to it.
295
                 * In that case do a single automatic retry if req.body allows.
296
                 */
297 284
                vbe_dir_finish(ctx, d);
298 284
                AZ(bo->htc);
299 284
                if (i < 0 || extrachance == 0)
300
                        break;
301 20
                if (bo->req != NULL &&
302 0
                    bo->req->req_body_status != REQ_BODY_NONE &&
303 0
                    bo->req->req_body_status != REQ_BODY_CACHED)
304 0
                        break;
305 20
                VSC_C_main->backend_retry++;
306 20
        } while (extrachance--);
307 264
        return (-1);
308
}
309
310
static VCL_IP v_matchproto_(vdi_getip_f)
311 4
vbe_dir_getip(VRT_CTX, VCL_BACKEND d)
312
{
313
        struct pfd *pfd;
314
315 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
316 4
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
317 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
318 4
        CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
319 4
        pfd = ctx->bo->htc->priv;
320
321 4
        return (VTP_getip(pfd));
322
}
323
324
/*--------------------------------------------------------------------*/
325
326
static enum sess_close v_matchproto_(vdi_http1pipe_f)
327 48
vbe_dir_http1pipe(VRT_CTX, VCL_BACKEND d)
328
{
329
        int i;
330
        enum sess_close retval;
331
        struct backend *bp;
332
        struct v1p_acct v1a;
333
        struct pfd *pfd;
334
        char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
335
336 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
337 48
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
338 48
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
339 48
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
340 48
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
341
342 48
        memset(&v1a, 0, sizeof v1a);
343
344
        /* This is hackish... */
345 48
        v1a.req = ctx->req->acct.req_hdrbytes;
346 48
        ctx->req->acct.req_hdrbytes = 0;
347
348 48
        ctx->req->res_mode = RES_PIPE;
349
350 48
        pfd = vbe_dir_getfd(ctx->req->wrk, bp, ctx->bo, 0);
351
352 48
        if (pfd == NULL) {
353 4
                retval = SC_TX_ERROR;
354
        } else {
355 44
                CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
356 44
                PFD_RemoteName(pfd, abuf, sizeof abuf, pbuf, sizeof pbuf);
357 44
                i = V1F_SendReq(ctx->req->wrk, ctx->bo,
358
                    &v1a.bereq, &v1a.out, 1, abuf, pbuf);
359 44
                VSLb_ts_req(ctx->req, "Pipe", W_TIM_real(ctx->req->wrk));
360 44
                if (i == 0)
361 44
                        V1P_Process(ctx->req, *PFD_Fd(pfd), &v1a);
362 44
                VSLb_ts_req(ctx->req, "PipeSess", W_TIM_real(ctx->req->wrk));
363 44
                ctx->bo->htc->doclose = SC_TX_PIPE;
364 44
                vbe_dir_finish(ctx, d);
365 44
                retval = SC_TX_PIPE;
366
        }
367 48
        V1P_Charge(ctx->req, &v1a, bp->vsc);
368 48
        return (retval);
369
}
370
371
/*--------------------------------------------------------------------*/
372
373
static void
374 4256
vbe_dir_event(const struct director *d, enum vcl_event_e ev)
375
{
376
        struct backend *bp;
377
378 4256
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
379 4256
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
380
381 4256
        if (ev == VCL_EVENT_WARM)
382 4112
                VRT_VSC_Reveal(bp->vsc_seg);
383
384 4256
        if (bp->probe != NULL && ev == VCL_EVENT_WARM)
385 92
                VBP_Control(bp, 1);
386
387 4256
        if (bp->probe != NULL && ev == VCL_EVENT_COLD)
388 24
                VBP_Control(bp, 0);
389
390 4256
        if (ev == VCL_EVENT_COLD)
391 144
                VRT_VSC_Hide(bp->vsc_seg);
392 4256
}
393
394
/*---------------------------------------------------------------------*/
395
396
static void v_matchproto_(vdi_destroy_f)
397 260
vbe_destroy(const struct director *d)
398
{
399
        struct backend *be;
400
401 260
        ASSERT_CLI();
402 260
        CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
403
404 260
        if (be->probe != NULL)
405 16
                VBP_Remove(be);
406
407 260
        VSC_vbe_Destroy(&be->vsc_seg);
408 260
        Lck_Lock(&backends_mtx);
409 260
        if (be->cooled > 0)
410 252
                VTAILQ_REMOVE(&cool_backends, be, list);
411
        else
412 8
                VTAILQ_REMOVE(&backends, be, list);
413 260
        VSC_C_main->n_backend--;
414 260
        VTP_Rel(&be->tcp_pool);
415 260
        Lck_Unlock(&backends_mtx);
416
417
#define DA(x)   do { if (be->x != NULL) free(be->x); } while (0)
418
#define DN(x)   /**/
419 260
        VRT_BACKEND_HANDLE();
420
#undef DA
421
#undef DN
422
423 260
        Lck_Delete(&be->mtx);
424 260
        FREE_OBJ(be);
425 260
}
426
427
/*--------------------------------------------------------------------*/
428
429
static void
430 4
vbe_panic(const struct director *d, struct vsb *vsb)
431
{
432
        struct backend *bp;
433
434 4
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
435 4
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
436
437 4
        if (bp->ipv4_addr != NULL)
438 4
                VSB_printf(vsb, "ipv4 = %s,\n", bp->ipv4_addr);
439 4
        if (bp->ipv6_addr != NULL)
440 0
                VSB_printf(vsb, "ipv6 = %s,\n", bp->ipv6_addr);
441 4
        VSB_printf(vsb, "port = %s,\n", bp->port);
442 4
        VSB_printf(vsb, "hosthdr = %s,\n", bp->hosthdr);
443 4
        VSB_printf(vsb, "n_conn = %u,\n", bp->n_conn);
444 4
}
445
446
/*--------------------------------------------------------------------
447
 */
448
449
static void
450 3636
vbe_list(const struct director *d, struct vsb *vsb, int vflag, int pflag,
451
    int jflag)
452
{
453
        struct backend *bp;
454
455 3636
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
456 3636
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
457
458 3636
        if (bp->probe != NULL)
459 216
                VBP_Status(vsb, bp, vflag | pflag, jflag);
460 3420
        else if ((vflag | pflag) == 0 && jflag)
461 20
                VSB_printf(vsb, "\"%s\"", d->sick ? "sick" : "healthy");
462
        else
463 3400
                VSB_printf(vsb, "%-10s", d->sick ? "sick" : "healthy");
464 3636
}
465
466
/*--------------------------------------------------------------------
467
 */
468
469
static const struct vdi_methods vbe_methods[1] = {{
470
        .magic =                VDI_METHODS_MAGIC,
471
        .type =                 "backend",
472
        .http1pipe =            vbe_dir_http1pipe,
473
        .gethdrs =              vbe_dir_gethdrs,
474
        .getip =                vbe_dir_getip,
475
        .finish =               vbe_dir_finish,
476
        .event =                vbe_dir_event,
477
        .destroy =              vbe_destroy,
478
        .panic =                vbe_panic,
479
        .list =                 vbe_list,
480
}};
481
482
/*--------------------------------------------------------------------
483
 * Create a new static or dynamic director::backend instance.
484
 */
485
486
size_t v_matchproto_()
487 3424
VRT_backend_vsm_need(VRT_CTX)
488
{
489
        (void)ctx;
490 3424
        return (VRT_VSC_Overhead(VSC_vbe_size));
491
}
492
493
VCL_BACKEND v_matchproto_()
494 4244
VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc,
495
    const struct vrt_backend *vrt)
496
{
497
        struct backend *be;
498
        struct vcl *vcl;
499
        const struct vrt_backend_probe *vbp;
500
501 4244
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
502 4244
        CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC);
503 4244
        if (vrt->path == NULL)
504 4084
                assert(vrt->ipv4_suckaddr != NULL ||
505
                    vrt->ipv6_suckaddr != NULL);
506
        else
507 160
                assert(vrt->ipv4_suckaddr == NULL &&
508
                    vrt->ipv6_suckaddr == NULL);
509
510 4244
        vcl = ctx->vcl;
511 4244
        AN(vcl);
512 4244
        AN(vrt->vcl_name);
513
514
        /* Create new backend */
515 4244
        ALLOC_OBJ(be, BACKEND_MAGIC);
516 4244
        XXXAN(be);
517 4244
        Lck_New(&be->mtx, lck_backend);
518
519
#define DA(x)   do { if (vrt->x != NULL) REPLACE((be->x), (vrt->x)); } while (0)
520
#define DN(x)   do { be->x = vrt->x; } while (0)
521 4244
        VRT_BACKEND_HANDLE();
522
#undef DA
523
#undef DN
524
525 8488
        be->vsc = VSC_vbe_New(vc, &be->vsc_seg,
526 4244
            "%s.%s", VCL_Name(ctx->vcl), vrt->vcl_name);
527 4244
        AN(be->vsc);
528
529 4244
        be->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr,
530
            vrt->path, vbe_proto_ident);
531 4244
        AN(be->tcp_pool);
532
533 4244
        vbp = vrt->probe;
534 4244
        if (vbp == NULL)
535 4176
                vbp = VCL_DefaultProbe(vcl);
536
537 4244
        if (vbp != NULL)
538 88
                VBP_Insert(be, vbp, be->tcp_pool);
539
540 4244
        be->director = VRT_AddDirector(ctx, vbe_methods, be,
541
            "%s", vrt->vcl_name);
542
543 4244
        if (be->director != NULL) {
544
                /* for cold VCL, update initial director state */
545 4244
                if (be->probe != NULL && ! VCL_WARM(vcl))
546 84
                        VBP_Update_Backend(be->probe);
547
548 4244
                Lck_Lock(&backends_mtx);
549 4244
                VTAILQ_INSERT_TAIL(&backends, be, list);
550 4244
                VSC_C_main->n_backend++;
551 4244
                Lck_Unlock(&backends_mtx);
552 4244
                return (be->director);
553
        }
554
555
        /* undo */
556 0
        if (vbp != NULL)
557 0
                VBP_Remove(be);
558
559 0
        VTP_Rel(&be->tcp_pool);
560
561 0
        VSC_vbe_Destroy(&be->vsc_seg);
562
#define DA(x)   do { if (be->x != NULL) free(be->x); } while (0)
563
#define DN(x)   /**/
564 0
        VRT_BACKEND_HANDLE();
565
#undef DA
566
#undef DN
567 0
        Lck_Delete(&be->mtx);
568 0
        FREE_OBJ(be);
569 0
        return (NULL);
570
}
571
572
VCL_BACKEND v_matchproto_()
573 108
VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt)
574
{
575 108
        return (VRT_new_backend_clustered(ctx, NULL, vrt));
576
}
577
578
/*--------------------------------------------------------------------
579
 * Delete a dynamic director::backend instance.  Undeleted dynamic and
580
 * static instances are GC'ed when the VCL is discarded (in cache_vcl.c)
581
 */
582
583
void
584 296
VRT_delete_backend(VRT_CTX, VCL_BACKEND *dp)
585
{
586
        VCL_BACKEND d;
587
        struct backend *be;
588
589 296
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
590 296
        TAKE_OBJ_NOTNULL(d, dp, DIRECTOR_MAGIC);
591 296
        CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
592 296
        Lck_Lock(&be->mtx);
593 296
        VRT_DisableDirector(be->director);
594 296
        be->cooled = VTIM_real() + 60.;
595 296
        Lck_Unlock(&be->mtx);
596 296
        Lck_Lock(&backends_mtx);
597 296
        VTAILQ_REMOVE(&backends, be, list);
598 296
        VTAILQ_INSERT_TAIL(&cool_backends, be, list);
599 296
        Lck_Unlock(&backends_mtx);
600
601
        // NB. The backend is still usable for the ongoing transactions,
602
        // this is why we don't bust the director's magic number.
603 296
}
604
605
void
606 1172
VBE_SetHappy(const struct backend *be, uint64_t happy)
607
{
608
609 1172
        CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
610 1172
        Lck_Lock(&backends_mtx);
611 1172
        if (be->vsc != NULL)
612 1172
                be->vsc->happy = happy;
613 1172
        Lck_Unlock(&backends_mtx);
614 1172
}
615
616
/*---------------------------------------------------------------------*/
617
618
void
619 22766
VBE_Poll(void)
620
{
621
        struct backend *be, *be2;
622 22766
        vtim_real now = VTIM_real();
623
624 22766
        ASSERT_CLI();
625 22766
        Lck_Lock(&backends_mtx);
626 22766
        VTAILQ_FOREACH_SAFE(be, &cool_backends, list, be2) {
627 68
                CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
628 68
                if (be->cooled > now)
629 68
                        break;
630 0
                if (be->n_conn > 0)
631 0
                        continue;
632 0
                Lck_Unlock(&backends_mtx);
633 0
                VRT_DelDirector(&be->director);
634 0
                Lck_Lock(&backends_mtx);
635
        }
636 22766
        Lck_Unlock(&backends_mtx);
637 22766
}
638
639
/*---------------------------------------------------------------------*/
640
641
void
642 2752
VBE_InitCfg(void)
643
{
644
645 2752
        Lck_New(&backends_mtx, lck_vbe);
646 2752
}