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 271
VBE_Connect_Error(struct VSC_vbe *vsc, int err)
64
{
65
66 271
        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 55
                vsc->helddown++;
73 55
                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 216
                vsc->fail_econnrefused++;
83 216
                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 271
}
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 5007
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
        double tmod;
118
        char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE];
119
        char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE];
120
121 5007
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
122 5007
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
123 5007
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
124 5007
        AN(bp->vsc);
125
126 5007
        if (bp->director->sick) {
127 15
                VSLb(bo->vsl, SLT_FetchError,
128
                     "backend %s: unhealthy", VRT_BACKEND_string(bp->director));
129 15
                bp->vsc->unhealthy++;
130 15
                VSC_C_main->backend_unhealthy++;
131 15
                return (NULL);
132
        }
133
134 4992
        if (bp->max_connections > 0 && bp->n_conn >= bp->max_connections) {
135 6
                VSLb(bo->vsl, SLT_FetchError,
136
                     "backend %s: busy", VRT_BACKEND_string(bp->director));
137 6
                bp->vsc->busy++;
138 6
                VSC_C_main->backend_busy++;
139 6
                return (NULL);
140
        }
141
142 4986
        AZ(bo->htc);
143 4986
        bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc);
144 4986
        if (bo->htc == NULL) {
145 84
                VSLb(bo->vsl, SLT_FetchError, "out of workspace");
146
                /* XXX: counter ? */
147 84
                return (NULL);
148
        }
149 4902
        bo->htc->doclose = SC_NULL;
150
151 4902
        FIND_TMO(connect_timeout, tmod, bo, bp);
152 4902
        pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh, &err);
153 4902
        if (pfd == NULL) {
154 45
                VBE_Connect_Error(bp->vsc, err);
155 45
                VSLb(bo->vsl, SLT_FetchError,
156
                     "backend %s: fail errno %d (%s)",
157
                     VRT_BACKEND_string(bp->director), err, strerror(err));
158 45
                VSC_C_main->backend_fail++;
159 45
                bo->htc = NULL;
160 45
                return (NULL);
161
        }
162
163 4857
        fdp = PFD_Fd(pfd);
164 4857
        AN(fdp);
165 4857
        assert(*fdp >= 0);
166
167 4857
        Lck_Lock(&bp->mtx);
168 4857
        bp->n_conn++;
169 4857
        bp->vsc->conn++;
170 4857
        bp->vsc->req++;
171 4857
        Lck_Unlock(&bp->mtx);
172
173 4857
        if (bp->proxy_header != 0)
174 15
                VPX_Send_Proxy(*fdp, bp->proxy_header, bo->sp);
175
176 4857
        PFD_LocalName(pfd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
177 4857
        PFD_RemoteName(pfd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
178 4857
        VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s",
179
            *fdp, VRT_BACKEND_string(bp->director), abuf2, pbuf2, abuf1, pbuf1);
180
181 4857
        INIT_OBJ(bo->htc, HTTP_CONN_MAGIC);
182 4857
        bo->htc->priv = pfd;
183 4857
        bo->htc->rfd = fdp;
184 4857
        FIND_TMO(first_byte_timeout,
185
            bo->htc->first_byte_timeout, bo, bp);
186 4857
        FIND_TMO(between_bytes_timeout,
187
            bo->htc->between_bytes_timeout, bo, bp);
188 4857
        return (pfd);
189
}
190
191
static void v_matchproto_(vdi_finish_f)
192 4854
vbe_dir_finish(VRT_CTX, VCL_BACKEND d)
193
{
194
        struct backend *bp;
195
        struct busyobj *bo;
196
        struct pfd *pfd;
197
198 4854
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
199 4854
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
200 4854
        bo = ctx->bo;
201 4854
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
202 4854
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
203
204 4854
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
205 4854
        pfd = bo->htc->priv;
206 4854
        bo->htc->priv = NULL;
207 4854
        if (PFD_State(pfd) != PFD_STATE_USED)
208 3
                assert(bo->htc->doclose == SC_TX_PIPE ||
209
                    bo->htc->doclose == SC_RX_TIMEOUT);
210 4854
        if (bo->htc->doclose != SC_NULL || bp->proxy_header != 0) {
211 619
                VSLb(bo->vsl, SLT_BackendClose, "%d %s", *PFD_Fd(pfd),
212
                    VRT_BACKEND_string(bp->director));
213 619
                VTP_Close(&pfd);
214 619
                AZ(pfd);
215 619
                Lck_Lock(&bp->mtx);
216
        } else {
217 4235
                assert (PFD_State(pfd) == PFD_STATE_USED);
218 4235
                VSLb(bo->vsl, SLT_BackendReuse, "%d %s", *PFD_Fd(pfd),
219
                    VRT_BACKEND_string(bp->director));
220 4235
                Lck_Lock(&bp->mtx);
221 4235
                VSC_C_main->backend_recycle++;
222 4235
                VTP_Recycle(bo->wrk, &pfd);
223
        }
224 4854
        assert(bp->n_conn > 0);
225 4854
        bp->n_conn--;
226 4854
        AN(bp->vsc);
227 4854
        bp->vsc->conn--;
228
#define ACCT(foo)       bp->vsc->foo += bo->acct.foo;
229
#include "tbl/acct_fields_bereq.h"
230 4854
        Lck_Unlock(&bp->mtx);
231 4854
        bo->htc = NULL;
232 4854
}
233
234
static int v_matchproto_(vdi_gethdrs_f)
235 4956
vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d)
236
{
237 4956
        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 4956
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
245 4956
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
246 4956
        bo = ctx->bo;
247 4956
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
248 4956
        wrk = ctx->bo->wrk;
249 4956
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
250 4956
        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 4956
        if (!http_GetHdr(bo->bereq, H_Host, NULL) && bp->hosthdr != NULL)
258 114
                http_PrintfHeader(bo->bereq, "Host: %s", bp->hosthdr);
259
260
        do {
261 4971
                pfd = vbe_dir_getfd(wrk, bp, bo, extrachance == 0);
262 4971
                if (pfd == NULL)
263 147
                        return (-1);
264 4824
                AN(bo->htc);
265 4824
                if (PFD_State(pfd) != PFD_STATE_STOLEN)
266 3171
                        extrachance = 0;
267
268 4824
                PFD_RemoteName(pfd, abuf, sizeof abuf, pbuf, sizeof pbuf);
269 4824
                i = V1F_SendReq(wrk, bo, &bo->acct.bereq_hdrbytes,
270
                                &bo->acct.bereq_bodybytes, 0, abuf, pbuf);
271
272 4824
                if (PFD_State(pfd) != PFD_STATE_USED) {
273 3144
                        if (VTP_Wait(wrk, pfd, VTIM_real() +
274 1572
                            bo->htc->first_byte_timeout) != 0) {
275 3
                                bo->htc->doclose = SC_RX_TIMEOUT;
276 3
                                VSLb(bo->vsl, SLT_FetchError,
277
                                     "Timed out reusing backend connection");
278 3
                                extrachance = 0;
279
                        }
280
                }
281
282 4824
                if (bo->htc->doclose == SC_NULL) {
283 4794
                        assert(PFD_State(pfd) == PFD_STATE_USED);
284 4794
                        if (i == 0)
285 4794
                                i = V1F_FetchRespHdr(bo);
286 4794
                        if (i == 0) {
287 4611
                                AN(bo->htc->priv);
288 4611
                                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 213
                vbe_dir_finish(ctx, d);
298 213
                AZ(bo->htc);
299 213
                if (i < 0 || extrachance == 0)
300
                        break;
301 15
                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 15
                VSC_C_main->backend_retry++;
306 15
        } while (extrachance--);
307 198
        return (-1);
308
}
309
310
static VCL_IP v_matchproto_(vdi_getip_f)
311 3
vbe_dir_getip(VRT_CTX, VCL_BACKEND d)
312
{
313
        struct pfd *pfd;
314
315 3
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
316 3
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
317 3
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
318 3
        CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
319 3
        pfd = ctx->bo->htc->priv;
320
321 3
        return (VTP_getip(pfd));
322
}
323
324
/*--------------------------------------------------------------------*/
325
326
static enum sess_close v_matchproto_(vdi_http1pipe_f)
327 36
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 36
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
337 36
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
338 36
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
339 36
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
340 36
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
341
342 36
        memset(&v1a, 0, sizeof v1a);
343
344
        /* This is hackish... */
345 36
        v1a.req = ctx->req->acct.req_hdrbytes;
346 36
        ctx->req->acct.req_hdrbytes = 0;
347
348 36
        ctx->req->res_mode = RES_PIPE;
349
350 36
        pfd = vbe_dir_getfd(ctx->req->wrk, bp, ctx->bo, 0);
351
352 36
        if (pfd == NULL) {
353 3
                retval = SC_TX_ERROR;
354
        } else {
355 33
                CHECK_OBJ_NOTNULL(ctx->bo->htc, HTTP_CONN_MAGIC);
356 33
                PFD_RemoteName(pfd, abuf, sizeof abuf, pbuf, sizeof pbuf);
357 33
                i = V1F_SendReq(ctx->req->wrk, ctx->bo,
358
                    &v1a.bereq, &v1a.out, 1, abuf, pbuf);
359 33
                VSLb_ts_req(ctx->req, "Pipe", W_TIM_real(ctx->req->wrk));
360 33
                if (i == 0)
361 33
                        V1P_Process(ctx->req, *PFD_Fd(pfd), &v1a);
362 33
                VSLb_ts_req(ctx->req, "PipeSess", W_TIM_real(ctx->req->wrk));
363 33
                ctx->bo->htc->doclose = SC_TX_PIPE;
364 33
                vbe_dir_finish(ctx, d);
365 33
                retval = SC_TX_PIPE;
366
        }
367 36
        V1P_Charge(ctx->req, &v1a, bp->vsc);
368 36
        return (retval);
369
}
370
371
/*--------------------------------------------------------------------*/
372
373
static void
374 3153
vbe_dir_event(const struct director *d, enum vcl_event_e ev)
375
{
376
        struct backend *bp;
377
378 3153
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
379 3153
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
380
381 3153
        if (ev == VCL_EVENT_WARM)
382 3054
                VRT_VSC_Reveal(bp->vsc_seg);
383
384 3153
        if (bp->probe != NULL && ev == VCL_EVENT_WARM)
385 66
                VBP_Control(bp, 1);
386
387 3153
        if (bp->probe != NULL && ev == VCL_EVENT_COLD)
388 18
                VBP_Control(bp, 0);
389
390 3153
        if (ev == VCL_EVENT_COLD)
391 99
                VRT_VSC_Hide(bp->vsc_seg);
392 3153
}
393
394
/*---------------------------------------------------------------------*/
395
396
static void v_matchproto_(vdi_destroy_f)
397 183
vbe_destroy(const struct director *d)
398
{
399
        struct backend *be;
400
401 183
        ASSERT_CLI();
402 183
        CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
403
404 183
        if (be->probe != NULL)
405 12
                VBP_Remove(be);
406
407 183
        VSC_vbe_Destroy(&be->vsc_seg);
408 183
        Lck_Lock(&backends_mtx);
409 183
        if (be->cooled > 0)
410 177
                VTAILQ_REMOVE(&cool_backends, be, list);
411
        else
412 6
                VTAILQ_REMOVE(&backends, be, list);
413 183
        VSC_C_main->n_backend--;
414 183
        VTP_Rel(&be->tcp_pool);
415 183
        Lck_Unlock(&backends_mtx);
416
417
#define DA(x)   do { if (be->x != NULL) free(be->x); } while (0)
418
#define DN(x)   /**/
419 183
        VRT_BACKEND_HANDLE();
420
#undef DA
421
#undef DN
422
423 183
        Lck_Delete(&be->mtx);
424 183
        FREE_OBJ(be);
425 183
}
426
427
/*--------------------------------------------------------------------*/
428
429
static void
430 3
vbe_panic(const struct director *d, struct vsb *vsb)
431
{
432
        struct backend *bp;
433
434 3
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
435 3
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
436
437 3
        if (bp->ipv4_addr != NULL)
438 3
                VSB_printf(vsb, "ipv4 = %s,\n", bp->ipv4_addr);
439 3
        if (bp->ipv6_addr != NULL)
440 0
                VSB_printf(vsb, "ipv6 = %s,\n", bp->ipv6_addr);
441 3
        VSB_printf(vsb, "port = %s,\n", bp->port);
442 3
        VSB_printf(vsb, "hosthdr = %s,\n", bp->hosthdr);
443 3
        VSB_printf(vsb, "n_conn = %u,\n", bp->n_conn);
444 3
}
445
446
/*--------------------------------------------------------------------
447
 */
448
449
static void
450 2724
vbe_list(const struct director *d, struct vsb *vsb, int vflag, int pflag,
451
    int jflag)
452
{
453
        struct backend *bp;
454
455 2724
        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
456 2724
        CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
457
458 2724
        if (bp->probe != NULL)
459 159
                VBP_Status(vsb, bp, vflag | pflag, jflag);
460 2565
        else if ((vflag | pflag) == 0 && jflag)
461 15
                VSB_printf(vsb, "\"%s\"", d->sick ? "sick" : "healthy");
462
        else
463 2550
                VSB_printf(vsb, "%-10s", d->sick ? "sick" : "healthy");
464 2724
}
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 2535
VRT_backend_vsm_need(VRT_CTX)
488
{
489
        (void)ctx;
490 2535
        return (VRT_VSC_Overhead(VSC_vbe_size));
491
}
492
493
VCL_BACKEND v_matchproto_()
494 3150
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 3150
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
502 3150
        CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC);
503 3150
        if (vrt->path == NULL)
504 3030
                assert(vrt->ipv4_suckaddr != NULL ||
505
                    vrt->ipv6_suckaddr != NULL);
506
        else
507 120
                assert(vrt->ipv4_suckaddr == NULL &&
508
                    vrt->ipv6_suckaddr == NULL);
509
510 3150
        vcl = ctx->vcl;
511 3150
        AN(vcl);
512 3150
        AN(vrt->vcl_name);
513
514
        /* Create new backend */
515 3150
        ALLOC_OBJ(be, BACKEND_MAGIC);
516 3150
        XXXAN(be);
517 3150
        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 3150
        VRT_BACKEND_HANDLE();
522
#undef DA
523
#undef DN
524
525 6300
        be->vsc = VSC_vbe_New(vc, &be->vsc_seg,
526 3150
            "%s.%s", VCL_Name(ctx->vcl), vrt->vcl_name);
527 3150
        AN(be->vsc);
528
529 3150
        be->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr,
530
            vrt->path, vbe_proto_ident);
531 3150
        AN(be->tcp_pool);
532
533 3150
        vbp = vrt->probe;
534 3150
        if (vbp == NULL)
535 3102
                vbp = VCL_DefaultProbe(vcl);
536
537 3150
        if (vbp != NULL)
538 63
                VBP_Insert(be, vbp, be->tcp_pool);
539
540 3150
        be->director = VRT_AddDirector(ctx, vbe_methods, be,
541
            "%s", vrt->vcl_name);
542
543 3150
        if (be->director != NULL) {
544
                /* for cold VCL, update initial director state */
545 3150
                if (be->probe != NULL && ! VCL_WARM(vcl))
546 63
                        VBP_Update_Backend(be->probe);
547
548 3150
                Lck_Lock(&backends_mtx);
549 3150
                VTAILQ_INSERT_TAIL(&backends, be, list);
550 3150
                VSC_C_main->n_backend++;
551 3150
                Lck_Unlock(&backends_mtx);
552 3150
                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 78
VRT_new_backend(VRT_CTX, const struct vrt_backend *vrt)
574
{
575 78
        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 207
VRT_delete_backend(VRT_CTX, VCL_BACKEND *dp)
585
{
586
        VCL_BACKEND d;
587
        struct backend *be;
588
589 207
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
590 207
        TAKE_OBJ_NOTNULL(d, dp, DIRECTOR_MAGIC);
591 207
        CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
592 207
        Lck_Lock(&be->mtx);
593 207
        VRT_DisableDirector(be->director);
594 207
        be->cooled = VTIM_real() + 60.;
595 207
        Lck_Unlock(&be->mtx);
596 207
        Lck_Lock(&backends_mtx);
597 207
        VTAILQ_REMOVE(&backends, be, list);
598 207
        VTAILQ_INSERT_TAIL(&cool_backends, be, list);
599 207
        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 207
}
604
605
void
606 871
VBE_SetHappy(const struct backend *be, uint64_t happy)
607
{
608
609 871
        CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
610 871
        Lck_Lock(&backends_mtx);
611 871
        if (be->vsc != NULL)
612 871
                be->vsc->happy = happy;
613 871
        Lck_Unlock(&backends_mtx);
614 871
}
615
616
/*---------------------------------------------------------------------*/
617
618
void
619 16852
VBE_Poll(void)
620
{
621
        struct backend *be, *be2;
622 16852
        double now = VTIM_real();
623
624 16852
        ASSERT_CLI();
625 16852
        Lck_Lock(&backends_mtx);
626 16852
        VTAILQ_FOREACH_SAFE(be, &cool_backends, list, be2) {
627 48
                CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
628 48
                if (be->cooled > now)
629 48
                        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 16852
        Lck_Unlock(&backends_mtx);
637 16852
}
638
639
/*---------------------------------------------------------------------*/
640
641
void
642 2055
VBE_InitCfg(void)
643
{
644
645 2055
        Lck_New(&backends_mtx, lck_vbe);
646 2055
}