varnish-cache/bin/varnishd/cache/cache_main.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2011 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
30
#include "config.h"
31
32
#include "cache_varnishd.h"
33
34
#include <stdio.h>
35
#include <stdlib.h>
36
#ifdef HAVE_SIGALTSTACK
37
#  include <sys/mman.h>
38
#endif
39
40
#ifdef HAVE_PTHREAD_NP_H
41
#  include <pthread_np.h>
42
#endif
43
44
#include "common/heritage.h"
45
46
#include "vcli_serve.h"
47
#include "vrnd.h"
48
49
#include "hash/hash_slinger.h"
50
51
52
volatile struct params          *cache_param;
53
// XXX generic solution?
54
volatile struct vre_limits      *vparam_vre_limits;
55
56
/*--------------------------------------------------------------------
57
 * Per thread storage for the session currently being processed by
58
 * the thread.  This is used for panic messages.
59
 */
60
61
static pthread_key_t req_key;
62
static pthread_key_t bo_key;
63
pthread_key_t witness_key;
64
65
void
66 5340
THR_SetBusyobj(const struct busyobj *bo)
67
{
68
69 5340
        AZ(pthread_setspecific(bo_key, bo));
70 5338
}
71
72
struct busyobj *
73 5
THR_GetBusyobj(void)
74
{
75
76 5
        return (pthread_getspecific(bo_key));
77
}
78
79
void
80 2984
THR_SetRequest(const struct req *req)
81
{
82
83 2984
        AZ(pthread_setspecific(req_key, req));
84 2984
}
85
86
struct req *
87 5
THR_GetRequest(void)
88
{
89
90 5
        return (pthread_getspecific(req_key));
91
}
92
93
/*--------------------------------------------------------------------
94
 * Name threads if our pthreads implementation supports it.
95
 */
96
97
static pthread_key_t name_key;
98
99
void
100 22202
THR_SetName(const char *name)
101
{
102
103 22202
        AZ(pthread_setspecific(name_key, name));
104
#if defined(HAVE_PTHREAD_SET_NAME_NP)
105 22202
        pthread_set_name_np(pthread_self(), name);
106
#elif defined(HAVE_PTHREAD_SETNAME_NP)
107
#if defined(__APPLE__)
108
        pthread_setname_np(name);
109
#elif defined(__NetBSD__)
110
        pthread_setname_np(pthread_self(), "%s", (char *)(uintptr_t)name);
111
#else
112
        pthread_setname_np(pthread_self(), name);
113
#endif
114
#endif
115 22202
}
116
117
const char *
118 5
THR_GetName(void)
119
{
120
121 5
        return (pthread_getspecific(name_key));
122
}
123
124
/*--------------------------------------------------------------------
125
 * Generic setup all our threads should call
126
 */
127
#ifdef HAVE_SIGALTSTACK
128
#include <signal.h>
129
static stack_t altstack;
130
#endif
131
132
void
133 22201
THR_Init(void)
134
{
135
#ifdef HAVE_SIGALTSTACK
136 22201
        if (altstack.ss_sp != NULL)
137 22166
                AZ(sigaltstack(&altstack, NULL));
138
#endif
139 22201
}
140
141
/*--------------------------------------------------------------------
142
 * VXID's are unique transaction numbers allocated with a minimum of
143
 * locking overhead via pools in the worker threads.
144
 *
145
 * VXID's are mostly for use in VSL and for that reason we never return
146
 * zero vxid, in order to reserve that for "unassociated" VSL records.
147
 */
148
149
static uint32_t vxid_base;
150
static uint32_t vxid_chunk = 32768;
151
static struct lock vxid_lock;
152
153
uint32_t
154 4451
VXID_Get(struct worker *wrk, uint32_t mask)
155
{
156
        struct vxid_pool *v;
157
158 4451
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
159 4451
        v = &wrk->vxid_pool;
160 4451
        AZ(VXID(mask));
161
        do {
162 4451
                if (v->count == 0) {
163 4442
                        Lck_Lock(&vxid_lock);
164 4442
                        v->next = vxid_base;
165 4442
                        v->count = vxid_chunk;
166 4442
                        vxid_base = (vxid_base + v->count) & VSL_IDENTMASK;
167 4442
                        Lck_Unlock(&vxid_lock);
168
                }
169 4452
                v->count--;
170 4452
                v->next++;
171 4452
        } while (v->next == 0);
172 4452
        return (v->next | mask);
173
}
174
175
/*--------------------------------------------------------------------
176
 * Debugging aids
177
 */
178
179
/*
180
 * Dumb down the VXID allocation to make it predictable for
181
 * varnishtest cases
182
 */
183
static void v_matchproto_(cli_func_t)
184 612
cli_debug_xid(struct cli *cli, const char * const *av, void *priv)
185
{
186
        (void)priv;
187 612
        if (av[2] != NULL) {
188 612
                vxid_base = strtoul(av[2], NULL, 0);
189 612
                vxid_chunk = 1;
190
        }
191 612
        VCLI_Out(cli, "XID is %u", vxid_base);
192 612
}
193
194
/*
195
 * Default to seed=1, this is the only seed value POSIXl guarantees will
196
 * result in a reproducible random number sequence.
197
 */
198
static void v_matchproto_(cli_func_t)
199 3
cli_debug_srandom(struct cli *cli, const char * const *av, void *priv)
200
{
201 3
        unsigned seed = 1;
202
203
        (void)priv;
204
        (void)cli;
205 3
        if (av[2] != NULL)
206 0
                seed = strtoul(av[2], NULL, 0);
207 3
        VRND_SeedTestable(seed);
208 3
}
209
210
static struct cli_proto debug_cmds[] = {
211
        { CLICMD_DEBUG_XID,                     "d", cli_debug_xid },
212
        { CLICMD_DEBUG_SRANDOM,                 "d", cli_debug_srandom },
213
        { NULL }
214
};
215
216
/*--------------------------------------------------------------------
217
 * XXX: Think more about which order we start things
218
 */
219
220
#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
221
static void
222 0
child_malloc_fail(void *p, const char *s)
223
{
224 0
        VSL(SLT_Error, 0, "MALLOC ERROR: %s (%p)", s, p);
225 0
        fprintf(stderr, "MALLOC ERROR: %s (%p)\n", s, p);
226 0
        WRONG("Malloc Error");
227
}
228
#endif
229
230
/*=====================================================================
231
 * signal handler for child process
232
 */
233
234
static void v_matchproto_()
235 1
child_signal_handler(int s, siginfo_t *si, void *c)
236
{
237
        char buf[1024];
238
        struct sigaction sa;
239
240
        (void)c;
241
242
        /* Don't come back */
243 1
        memset(&sa, 0, sizeof sa);
244 1
        sa.sa_handler = SIG_DFL;
245 1
        (void)sigaction(SIGSEGV, &sa, NULL);
246 1
        (void)sigaction(SIGABRT, &sa, NULL);
247
248 1
        bprintf(buf, "Signal %d (%s) received at %p si_code %d",
249
                s, strsignal(s), si->si_addr, si->si_code);
250 1
        VAS_Fail(__func__,
251
                 __FILE__,
252
                 __LINE__,
253
                 buf,
254
                 VAS_WRONG);
255
}
256
257
/*=====================================================================
258
 * Magic for panicing properly on signals
259
 */
260
261
static void
262 613
child_sigmagic(size_t altstksz)
263
{
264
        struct sigaction sa;
265
266 613
        memset(&sa, 0, sizeof sa);
267
268
#ifdef HAVE_SIGALTSTACK
269 613
        size_t sz = SIGSTKSZ + 4096;
270 613
        if (sz < altstksz)
271 613
                sz = altstksz;
272 613
        altstack.ss_sp = mmap(NULL, sz,  PROT_READ | PROT_WRITE,
273
                              MAP_PRIVATE | MAP_ANONYMOUS,
274
                              -1, 0);
275 613
        AN(altstack.ss_sp != MAP_FAILED);
276 613
        AN(altstack.ss_sp);
277 613
        altstack.ss_size = sz;
278 613
        altstack.ss_flags = 0;
279 613
        sa.sa_flags |= SA_ONSTACK;
280
#endif
281
282 613
        THR_Init();
283
284 613
        sa.sa_sigaction = child_signal_handler;
285 613
        sa.sa_flags |= SA_SIGINFO;
286 613
        (void)sigaction(SIGBUS, &sa, NULL);
287 613
        (void)sigaction(SIGABRT, &sa, NULL);
288 613
        (void)sigaction(SIGSEGV, &sa, NULL);
289 613
}
290
291
292
/*=====================================================================
293
 * Run the child process
294
 */
295
296
void
297 614
child_main(int sigmagic, size_t altstksz)
298
{
299
300 614
        if (sigmagic)
301 613
                child_sigmagic(altstksz);
302 614
        (void)signal(SIGINT, SIG_DFL);
303 614
        (void)signal(SIGTERM, SIG_DFL);
304
305 614
        setbuf(stdout, NULL);
306 614
        setbuf(stderr, NULL);
307 614
        printf("Child starts\n");
308
#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
309 614
        malloc_message = child_malloc_fail;
310
#endif
311
312 614
        cache_param = heritage.param;
313
        // XXX TODO - generic solution?
314 614
        vparam_vre_limits = &cache_param->vre_limits;
315
316 614
        AZ(pthread_key_create(&req_key, NULL));
317 614
        AZ(pthread_key_create(&bo_key, NULL));
318 614
        AZ(pthread_key_create(&witness_key, NULL));
319 614
        AZ(pthread_key_create(&name_key, NULL));
320
321 614
        THR_SetName("cache-main");
322
323 614
        VSM_Init();     /* First, LCK needs it. */
324
325 614
        LCK_Init();     /* Second, locking */
326
327 614
        Lck_New(&vxid_lock, lck_vxid);
328
329 614
        CLI_Init();
330 614
        PAN_Init();
331 614
        VFP_Init();
332
333 614
        ObjInit();
334
335 614
        VCL_Init();
336
337 614
        HTTP_Init();
338
339 614
        VBO_Init();
340 614
        VTP_Init();
341 614
        VBP_Init();
342 614
        VDI_Init();
343 614
        VBE_InitCfg();
344 614
        Pool_Init();
345 614
        V1P_Init();
346 614
        V2D_Init();
347
348 614
        EXP_Init();
349 614
        HSH_Init(heritage.hash);
350 614
        BAN_Init();
351
352 614
        VCA_Init();
353
354 614
        STV_open();
355
356 614
        VMOD_Init();
357
358 614
        BAN_Compile();
359
360 614
        VRND_SeedAll();
361
362 614
        CLI_AddFuncs(debug_cmds);
363
364
        /* Wait for persistent storage to load if asked to */
365 614
        if (FEATURE(FEATURE_WAIT_SILO))
366 24
                SMP_Ready();
367
368 614
        CLI_Run();
369
370 609
        VCA_Shutdown();
371 609
        BAN_Shutdown();
372 609
        STV_close();
373
374 609
        printf("Child dies\n");
375 609
}