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