vinyl-cache/bin/vinyld/cache/cache_main.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2011 Varnish Software AS
3
 * All rights reserved.
4
 *
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
31
#include "config.h"
32
33
#include "cache_int.h"
34
#include "acceptor/cache_acceptor.h"
35
36
#include <signal.h>
37
#include <stdio.h>
38
#include <stdlib.h>
39
40
#include <sys/mman.h>
41
#include <sys/resource.h>
42
43
#ifdef HAVE_PTHREAD_NP_H
44
#  include <pthread_np.h>
45
#endif
46
47
#include "common/heritage.h"
48
49
#include "vcli_serve.h"
50
#include "vnum.h"
51
#include "vtim.h"
52
#include "vrnd.h"
53
54
#include "hash/hash_slinger.h"
55
56
volatile struct params          *cache_param;
57
static pthread_mutex_t          cache_vrnd_mtx;
58
static vtim_dur                 shutdown_delay = 0;
59
60
pthread_mutexattr_t mtxattr_errorcheck;
61
62
static void
63 214436
cache_vrnd_lock(void)
64
{
65 214436
        PTOK(pthread_mutex_lock(&cache_vrnd_mtx));
66 214436
}
67
68
static void
69 214436
cache_vrnd_unlock(void)
70
{
71 214436
        PTOK(pthread_mutex_unlock(&cache_vrnd_mtx));
72 214436
}
73
74
/*--------------------------------------------------------------------
75
 * Per thread storage for the session currently being processed by
76
 * the thread.  This is used for panic messages.
77
 */
78
79
static pthread_key_t req_key;
80
static pthread_key_t bo_key;
81
static pthread_key_t wrk_key;
82
pthread_key_t witness_key;
83
pthread_key_t panic_key;
84
85
void
86 37954
THR_SetBusyobj(const struct busyobj *bo)
87
{
88
89 37954
        PTOK(pthread_setspecific(bo_key, bo));
90 37954
}
91
92
struct busyobj *
93 44
THR_GetBusyobj(void)
94
{
95
96 44
        return (pthread_getspecific(bo_key));
97
}
98
99
void
100 25130
THR_SetRequest(const struct req *req)
101
{
102
103 25130
        PTOK(pthread_setspecific(req_key, req));
104 25130
}
105
106
struct req *
107 2188
THR_GetRequest(void)
108
{
109
110 2188
        return (pthread_getspecific(req_key));
111
}
112
113
void
114 78290
THR_SetWorker(const struct worker *wrk)
115
{
116
117 78290
        PTOK(pthread_setspecific(wrk_key, wrk));
118 78290
}
119
120
struct worker *
121 17382
THR_GetWorker(void)
122
{
123
124 17382
        return (pthread_getspecific(wrk_key));
125
}
126
127
/*--------------------------------------------------------------------
128
 * Name threads if our pthreads implementation supports it.
129
 */
130
131
static pthread_key_t name_key;
132
133
#if defined(HAVE_PTHREAD_SETNAME_NP) && !defined(__APPLE__) &&  \
134
    !defined(__NetBSD__)
135
static void
136 140334
thr_setname_generic(const char *name)
137
{
138
        char buf[16];
139
140
        /* The Linux kernel enforces a strict limitation of 15 bytes name,
141
         * truncate the name if we would overflow it.
142
         */
143 140334
        if (vstrlen(name) > 15) {
144 3892
                bprintf(buf, "%.14s~", name);
145 3892
                name = buf;
146 3892
        }
147
148
        //lint --e{438} Last value assigned not used
149 140334
        PTOK(pthread_setname_np(pthread_self(), name));
150 140334
}
151
#endif
152
153
void
154 140334
THR_SetName(const char *name)
155
{
156
157 140334
        PTOK(pthread_setspecific(name_key, name));
158
#if defined(HAVE_PTHREAD_SETNAME_NP)
159
#  if defined(__APPLE__)
160
        (void)pthread_setname_np(name);
161
#  elif defined(__NetBSD__)
162
        (void)pthread_setname_np(pthread_self(), "%s", (char *)(uintptr_t)name);
163
#  else
164 140334
        thr_setname_generic(name);
165
#  endif
166
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
167
        (void)pthread_set_name_np(pthread_self(), name);
168
#endif
169 140334
}
170
171
const char *
172 44
THR_GetName(void)
173
{
174
175 44
        return (pthread_getspecific(name_key));
176
}
177
178
/*--------------------------------------------------------------------
179
 * Generic setup all our threads should call
180
 */
181
static stack_t altstack;
182
183
void
184 140325
THR_Init(void)
185
{
186 140325
        if (altstack.ss_sp != NULL)
187 140182
                AZ(sigaltstack(&altstack, NULL));
188 140325
}
189
190
/*--------------------------------------------------------------------
191
 * VXID's are unique transaction numbers allocated with a minimum of
192
 * locking overhead via pools in the worker threads.
193
 *
194
 * VXID's are mostly for use in VSL and for that reason we never return
195
 * zero vxid, in order to reserve that for "unassociated" VSL records.
196
 */
197
198
static uint64_t vxid_base = 1;
199
static uint32_t vxid_chunk = 32768;
200
static struct lock vxid_lock;
201
202
vxid_t
203 34945
VXID_Get(const struct worker *wrk, uint64_t mask)
204
{
205
        struct vxid_pool *v;
206
        vxid_t retval;
207
208 34945
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
209 34945
        CHECK_OBJ_NOTNULL(wrk->wpriv, WORKER_PRIV_MAGIC);
210 34945
        v = wrk->wpriv->vxid_pool;
211 34945
        AZ(mask & VSL_IDENTMASK);
212 69851
        while (v->count == 0 || v->next >= VRT_INTEGER_MAX) {
213 34906
                Lck_Lock(&vxid_lock);
214 34906
                v->next = vxid_base;
215 34906
                v->count = vxid_chunk;
216 34906
                vxid_base += v->count;
217 34906
                if (vxid_base >= VRT_INTEGER_MAX)
218 8
                        vxid_base = 1;
219 34906
                Lck_Unlock(&vxid_lock);
220
        }
221 34945
        v->count--;
222 34945
        assert(v->next > 0);
223 34945
        assert(v->next < VSL_CLIENTMARKER);
224 34945
        retval.vxid = v->next | mask;
225 34945
        v->next++;
226 34945
        return (retval);
227
}
228
229
/*--------------------------------------------------------------------
230
 * Debugging aids
231
 */
232
233
/*
234
 * Dumb down the VXID allocation to make it predictable for
235
 * vinyltest cases
236
 */
237
static void v_matchproto_(cli_func_t)
238 3868
cli_debug_xid(struct cli *cli, const char * const *av, void *priv)
239
{
240 3868
        (void)priv;
241 3868
        if (av[2] != NULL) {
242 3868
                vxid_base = strtoull(av[2], NULL, 0);
243 3868
                vxid_chunk = 0;
244 3868
                if (av[3] != NULL)
245 0
                        vxid_chunk = strtoul(av[3], NULL, 0);
246 3868
                if (vxid_chunk == 0)
247 3868
                        vxid_chunk = 1;
248 3868
        }
249 3868
        VCLI_Out(cli, "XID is %ju chunk %u", (uintmax_t)vxid_base, vxid_chunk);
250 3868
}
251
252
/*
253
 * Artificially slow down the process shutdown.
254
 */
255
static void v_matchproto_(cli_func_t)
256 0
cli_debug_shutdown_delay(struct cli *cli, const char * const *av, void *priv)
257
{
258
259 0
        (void)cli;
260 0
        (void)priv;
261 0
        shutdown_delay = VNUM_duration(av[2]);
262 0
}
263
264
/*
265
 * Default to seed=1, this is the only seed value POSIX guarantees will
266
 * result in a reproducible random number sequence.
267
 */
268
static void v_matchproto_(cli_func_t)
269 12
cli_debug_srandom(struct cli *cli, const char * const *av, void *priv)
270
{
271 12
        unsigned seed = 1;
272
273 12
        (void)priv;
274 12
        (void)cli;
275 12
        if (av[2] != NULL)
276 0
                seed = strtoul(av[2], NULL, 0);
277 12
        VRND_SeedTestable(seed);
278 12
}
279
280
static struct cli_proto debug_cmds[] = {
281
        { CLICMD_DEBUG_XID,             "d", cli_debug_xid },
282
        { CLICMD_DEBUG_SHUTDOWN_DELAY,  "d", cli_debug_shutdown_delay },
283
        { CLICMD_DEBUG_SRANDOM,         "d", cli_debug_srandom },
284
        { NULL }
285
};
286
287
/*--------------------------------------------------------------------
288
 * XXX: Think more about which order we start things
289
 */
290
291
#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
292
static void
293 0
child_malloc_fail(void *p, const char *s)
294
{
295 0
        VSL(SLT_Error, NO_VXID, "MALLOC ERROR: %s (%p)", s, p);
296 0
        fprintf(stderr, "MALLOC ERROR: %s (%p)\n", s, p);
297 0
        WRONG("Malloc Error");
298 0
}
299
#endif
300
301
/*=====================================================================
302
 * signal handler for child process
303
 */
304
305
static void v_noreturn_ v_matchproto_()
306 8
child_signal_handler(int s, siginfo_t *si, void *c)
307
{
308
        char buf[1024];
309
        struct sigaction sa;
310
        struct req *req;
311 8
        const char *a, *p, *info = NULL;
312
313 8
        (void)c;
314
        /* Don't come back */
315 8
        memset(&sa, 0, sizeof sa);
316 8
        sa.sa_handler = SIG_DFL;
317 8
        (void)sigaction(SIGSEGV, &sa, NULL);
318 8
        (void)sigaction(SIGBUS, &sa, NULL);
319 8
        (void)sigaction(SIGABRT, &sa, NULL);
320
321 8
        while (s == SIGSEGV || s == SIGBUS) {
322 8
                req = THR_GetRequest();
323 8
                if (req == NULL || req->wrk == NULL)
324 0
                        break;
325 8
                a = TRUST_ME(si->si_addr);
326 8
                p = TRUST_ME(req->wrk);
327 8
                p += sizeof *req->wrk;
328
                // rough safe estimate - top of stack
329 8
                if (a > p + cache_param->wthread_stacksize)
330 0
                        break;
331 8
                if (a < p - 2 * cache_param->wthread_stacksize)
332 4
                        break;
333 4
                info = "\nTHIS PROBABLY IS A STACK OVERFLOW - "
334
                        "check thread_pool_stack parameter";
335 4
                break;
336
        }
337 8
        bprintf(buf, "Signal %d (%s) received at %p si_code %d%s",
338
                s, strsignal(s), si->si_addr, si->si_code,
339
                info ? info : "");
340
341 8
        VAS_Fail(__func__,
342
                 __FILE__,
343
                 __LINE__,
344 8
                 buf,
345
                 VAS_WRONG);
346
}
347
348
/*=====================================================================
349
 * Magic for panicking properly on signals
350
 */
351
352
static void
353 3888
child_sigmagic(size_t altstksz)
354
{
355
        struct sigaction sa;
356
357 3888
        memset(&sa, 0, sizeof sa);
358
359 3888
        size_t sz = vmax_t(size_t, SIGSTKSZ + 4096, altstksz);
360 3888
        altstack.ss_sp = mmap(NULL, sz,  PROT_READ | PROT_WRITE,
361
                              MAP_PRIVATE | MAP_ANONYMOUS,
362
                              -1, 0);
363 3888
        AN(altstack.ss_sp != MAP_FAILED);
364 3888
        AN(altstack.ss_sp);
365 3888
        altstack.ss_size = sz;
366 3888
        altstack.ss_flags = 0;
367 3888
        sa.sa_flags |= SA_ONSTACK;
368
369 3888
        THR_Init();
370
371 3888
        sa.sa_sigaction = child_signal_handler;
372 3888
        sa.sa_flags |= SA_SIGINFO;
373 3888
        (void)sigaction(SIGBUS, &sa, NULL);
374 3888
        (void)sigaction(SIGABRT, &sa, NULL);
375 3888
        (void)sigaction(SIGSEGV, &sa, NULL);
376 3888
}
377
378
static void
379 8
cli_quit(int sig)
380
{
381
382 8
        if (!IS_CLI()) {
383 0
                PTOK(pthread_kill(cli_thread, sig));
384 0
                return;
385
        }
386
387 8
        WRONG("It's time for the big quit");
388 0
}
389
390
/*=====================================================================
391
 * XXX Generalize?
392
 */
393
394
static void
395 3848
bit_set(volatile uint8_t *p, unsigned no)
396
{
397
        uint8_t b;
398
399 3848
        p += (no >> 3);
400 3848
        b = (0x80 >> (no & 7));
401 3848
        *p |= b;
402 3848
}
403
404
/*=====================================================================
405
 * Run the child process
406
 */
407
408
static void v_matchproto_(cli_func_t)
409 3880
ccf_child_start(struct cli *cli, const char * const *av, void *priv)
410
{
411 3880
        (void)av;
412 3880
        (void)priv;
413
414 3880
        VCA_Start(cli);
415 3880
}
416
417
static struct cli_proto child_cmds[] = {
418
        { CLICMD_SERVER_START,          "", ccf_child_start },
419
        { NULL }
420
};
421
422
#define CAP 17U
423
424
static void
425 11676
t_vscarab1(struct vscarab *scarab)
426
{
427
        struct viov *v;
428
        uint64_t sum;
429
430 11676
        VSCARAB_CHECK_NOTNULL(scarab);
431 11676
        AZ(scarab->used);
432
433 11676
        v = VSCARAB_GET(scarab);
434 11676
        AN(v);
435 11676
        v->lease = 12;
436
437 11676
        VSCARAB_ADD(scarab, (struct viov){.lease = 30});
438
439 11676
        sum = 0;
440 35028
        VSCARAB_FOREACH(v, scarab)
441 23352
                sum += v->lease;
442
443 11676
        assert(sum == 42);
444 11676
}
445
446
static void
447 3892
t_vscarab(void)
448
{
449
        char testbuf[VSCARAB_SIZE(CAP)];
450 3892
        struct vscarab *frombuf = (void *)testbuf;
451 3892
        VSCARAB_INIT(frombuf, CAP);
452 3892
        t_vscarab1(frombuf);
453
454
        // ---
455
456 3892
        VSCARAB_LOCAL(scarab, CAP);
457 3892
        t_vscarab1(scarab);
458
459
        // ---
460
461
        struct vscarab *heap;
462 3892
        VSCARAB_ALLOC(heap, CAP);
463 3892
        t_vscarab1(heap);
464 3892
        free(heap);
465 3892
}
466
467
void
468 3928
child_main(int sigmagic, size_t altstksz)
469
{
470 3928
        t_vscarab();
471
472 3928
        if (sigmagic)
473 3888
                child_sigmagic(altstksz);
474 3928
        (void)signal(SIGINT, SIG_DFL);
475 3928
        (void)signal(SIGTERM, SIG_DFL);
476 3928
        (void)signal(SIGQUIT, cli_quit);
477
478
#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
479 3928
        malloc_message = child_malloc_fail;
480
#endif
481
482
        /* Before anything uses pthreads in anger */
483 3928
        PTOK(pthread_mutexattr_init(&mtxattr_errorcheck));
484 3848
        PTOK(pthread_mutexattr_settype(&mtxattr_errorcheck, PTHREAD_MUTEX_ERRORCHECK));
485
486 3848
        cache_param = heritage.param;
487
488 3848
        PTOK(pthread_key_create(&req_key, NULL));
489 3848
        PTOK(pthread_key_create(&bo_key, NULL));
490 3848
        PTOK(pthread_key_create(&wrk_key, NULL));
491 3848
        PTOK(pthread_key_create(&witness_key, free));
492 3848
        PTOK(pthread_key_create(&name_key, NULL));
493 3848
        PTOK(pthread_key_create(&panic_key, NULL));
494
495 3848
        THR_SetName("cache-main");
496
497 3848
        PTOK(pthread_mutex_init(&cache_vrnd_mtx, &mtxattr_errorcheck));
498 3848
        VRND_Lock = cache_vrnd_lock;
499 3848
        VRND_Unlock = cache_vrnd_unlock;
500
501 3848
        VSM_Init();     /* First, LCK needs it. */
502
503 3848
        LCK_Init();     /* Second, locking */
504
505 3848
        Lck_New(&vxid_lock, lck_vxid);
506
507 3848
        CLI_Init();
508 3848
        PAN_Init();
509 3848
        VFP_Init();
510
511 3848
        ObjInit();
512
513 3848
        WRK_Init();
514
515 3848
        VCL_Init();
516 3848
        VCL_VRT_Init();
517
518 3848
        HTTP_Init();
519
520 3848
        VBO_Init();
521 3848
        VCP_Init();
522 3848
        VBP_Init();
523 3848
        VDI_Init();
524 3848
        VBE_InitCfg();
525 3848
        Pool_Init();
526 3848
        V1P_Init();
527 3848
        V2D_Init();
528
529 3848
        EXP_Init();
530 3848
        HSH_Init(heritage.hash);
531 3848
        BAN_Init();
532
533 3848
        VCA_Init();
534
535 3848
        STV_open();
536
537 3848
        VMOD_Init();
538
539 3848
        BAN_Compile();
540
541 3848
        VRND_SeedAll();
542
543
544 3848
        CLI_AddFuncs(debug_cmds);
545 3848
        CLI_AddFuncs(child_cmds);
546
547
#ifdef WITH_PERSISTENT_STORAGE
548
        /* Wait for persistent storage to load if asked to */
549 3848
        if (FEATURE(FEATURE_WAIT_SILO))
550 96
                SMP_Ready();
551
#endif
552
553 3848
        CLI_Run();
554
555 3848
        bit_set(cache_param->debug_bits, DBG_VCLREL);
556
557 3848
        if (shutdown_delay > 0)
558 0
                VTIM_sleep(shutdown_delay);
559
560 3848
        VCA_Shutdown();
561 3848
        cache_param->wthread_pools = 0;
562 3848
        BAN_Shutdown();
563 3848
        STV_warn();
564 3848
        VCL_Shutdown();
565 3848
        EXP_Shutdown();
566 3848
        STV_close();
567
568 3848
        struct rusage usage = {0};
569 3848
        if (! getrusage(RUSAGE_SELF, &usage)) {
570 3848
                printf("Child dies usr=%f sys=%f\n",
571 3848
                    tv_vtim(usage.ru_utime),
572 3848
                    tv_vtim(usage.ru_stime));
573 3848
        } else
574 0
                printf("Child dies\n");
575 3848
}