varnish-cache/bin/varnishd/storage/storage_persistent_subr.c
0
/*-
1
 * Copyright (c) 2008-2011 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
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
 * Persistent storage method
30
 *
31
 * XXX: Before we start the client or maybe after it stops, we should give the
32
 * XXX: stevedores a chance to examine their storage for consistency.
33
 *
34
 * XXX: Do we ever free the LRU-lists ?
35
 */
36
37
#include "config.h"
38
39
#include "cache/cache_varnishd.h"
40
#include "common/heritage.h"
41
42
#include <sys/mman.h>
43
44
#include <stdio.h>
45
#include <stdlib.h>
46
47
#include "storage/storage.h"
48
49
#include "vrnd.h"
50
#include "vsha256.h"
51
52
#include "storage/storage_persistent.h"
53
54
static void smp_msync(const void *addr, size_t length);
55
56
/*--------------------------------------------------------------------
57
 * SIGNATURE functions
58
 * The signature is SHA256 over:
59
 *    1. The smp_sign struct up to but not including the length field.
60
 *    2. smp_sign->length bytes, starting after the smp_sign structure
61
 *    3. The smp-sign->length field.
62
 * The signature is stored after the byte-range from step 2.
63
 */
64
65
/*--------------------------------------------------------------------
66
 * Define a signature by location and identifier.
67
 */
68
69
void
70 14700
smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
71
    uint64_t off, const char *id)
72
{
73
74 14700
        AZ(off & 7);                    /* Alignment */
75 14700
        assert(strlen(id) < sizeof ctx->ss->ident);
76
77 14700
        memset(ctx, 0, sizeof *ctx);
78 14700
        ctx->ss = (void*)(sc->base + off);
79 14700
        ctx->unique = sc->unique;
80 14700
        ctx->id = id;
81 14700
}
82
83
/*--------------------------------------------------------------------
84
 * Check that a signature is good, leave state ready for append
85
 */
86
int
87 15775
smp_chk_sign(struct smp_signctx *ctx)
88
{
89
        struct VSHA256Context cx;
90
        unsigned char sign[VSHA256_LEN];
91 15775
        int r = 0;
92
93 15775
        if (strncmp(ctx->id, ctx->ss->ident, sizeof ctx->ss->ident))
94 425
                r = 1;
95 15350
        else if (ctx->unique != ctx->ss->unique)
96 0
                r = 2;
97 15350
        else if (!ctx->ss->mapped)
98 0
                r = 3;
99
        else {
100 15350
                VSHA256_Init(&ctx->ctx);
101 15350
                VSHA256_Update(&ctx->ctx, ctx->ss,
102
                    offsetof(struct smp_sign, length));
103 15350
                VSHA256_Update(&ctx->ctx, SIGN_DATA(ctx), ctx->ss->length);
104 15350
                cx = ctx->ctx;
105 15350
                VSHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
106 15350
                VSHA256_Final(sign, &cx);
107 15350
                if (memcmp(sign, SIGN_END(ctx), sizeof sign))
108 0
                        r = 4;
109
        }
110 15775
        if (r) {
111 850
                fprintf(stderr, "CHK(%p %s %p %s) = %d\n",
112 425
                    ctx, ctx->id, ctx->ss,
113 425
                    r > 1 ? ctx->ss->ident : "<invalid>", r);
114 425
        }
115 15775
        return (r);
116
}
117
118
/*--------------------------------------------------------------------
119
 * Append data to a signature
120
 */
121
static void
122 22114
smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len)
123
{
124
        struct VSHA256Context cx;
125
        unsigned char sign[VSHA256_LEN];
126
127 22114
        if (len != 0) {
128 9546
                VSHA256_Update(&ctx->ctx, ptr, len);
129 9546
                ctx->ss->length += len;
130 9546
        }
131 22114
        cx = ctx->ctx;
132 22114
        VSHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
133 22114
        VSHA256_Final(sign, &cx);
134 22114
        memcpy(SIGN_END(ctx), sign, sizeof sign);
135 22114
}
136
137
/*--------------------------------------------------------------------
138
 * Reset a signature to empty, prepare for appending.
139
 */
140
141
void
142 11694
smp_reset_sign(struct smp_signctx *ctx)
143
{
144
145 11694
        memset(ctx->ss, 0, sizeof *ctx->ss);
146 11694
        assert(strlen(ctx->id) < sizeof *ctx->ss);
147 11694
        strcpy(ctx->ss->ident, ctx->id);
148 11694
        ctx->ss->unique = ctx->unique;
149 11694
        ctx->ss->mapped = (uintptr_t)ctx->ss;
150 11694
        VSHA256_Init(&ctx->ctx);
151 11694
        VSHA256_Update(&ctx->ctx, ctx->ss,
152
            offsetof(struct smp_sign, length));
153 11694
        smp_append_sign(ctx, NULL, 0);
154 11694
}
155
156
/*--------------------------------------------------------------------
157
 * Force a write of a signature block to the backing store.
158
 */
159
160
void
161 11696
smp_sync_sign(const struct smp_signctx *ctx)
162
{
163 11696
        smp_msync(ctx->ss, SMP_SIGN_SPACE + ctx->ss->length);
164 11696
}
165
166
/*--------------------------------------------------------------------
167
 * Create and force a new signature to backing store
168
 */
169
170
static void
171 1700
smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
172
    uint64_t off, const char *id)
173
{
174 1700
        smp_def_sign(sc, ctx, off, id);
175 1700
        smp_reset_sign(ctx);
176 1700
        smp_sync_sign(ctx);
177 1700
}
178
179
/*--------------------------------------------------------------------
180
 * Define a signature space by location, size and identifier
181
 */
182
183
static void
184 9700
smp_def_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
185
                  uint64_t off, uint64_t size, const char *id)
186
{
187 9700
        smp_def_sign(sc, &spc->ctx, off, id);
188 9700
        spc->start = SIGN_DATA(&spc->ctx);
189 9700
        spc->size = size - SMP_SIGN_SPACE;
190 9700
}
191
192
/*--------------------------------------------------------------------
193
 * Check that a signspace's signature space is good, leave state ready
194
 * for append
195
 */
196
197
int
198 12550
smp_chk_signspace(struct smp_signspace *spc)
199
{
200 12550
        return (smp_chk_sign(&spc->ctx));
201
}
202
203
/*--------------------------------------------------------------------
204
 * Append data to a signature space
205
 */
206
207
void
208 9995
smp_append_signspace(struct smp_signspace *spc, uint32_t len)
209
{
210 9995
        assert(len <= SIGNSPACE_FREE(spc));
211 9995
        smp_append_sign(&spc->ctx, SIGNSPACE_FRONT(spc), len);
212 9995
}
213
214
/*--------------------------------------------------------------------
215
 * Reset a signature space to empty, prepare for appending.
216
 */
217
218
void
219 7596
smp_reset_signspace(struct smp_signspace *spc)
220
{
221 7596
        smp_reset_sign(&spc->ctx);
222 7596
}
223
224
/*--------------------------------------------------------------------
225
 * Copy the contents of one signspace to another. Prepare for
226
 * appending.
227
 */
228
229
void
230 950
smp_copy_signspace(struct smp_signspace *dst, const struct smp_signspace *src)
231
{
232 950
        assert(SIGNSPACE_LEN(src) <= dst->size);
233 950
        smp_reset_signspace(dst);
234 950
        memcpy(SIGNSPACE_DATA(dst), SIGNSPACE_DATA(src), SIGNSPACE_LEN(src));
235 950
        smp_append_signspace(dst, SIGNSPACE_LEN(src));
236 950
        assert(SIGNSPACE_LEN(src) == SIGNSPACE_LEN(dst));
237 950
}
238
239
/*--------------------------------------------------------------------
240
 * Create a new signature space and force the signature to backing store.
241
 */
242
243
static void
244 1700
smp_new_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
245
                  uint64_t off, uint64_t size, const char *id)
246
{
247 1700
        smp_new_sign(sc, &spc->ctx, off, id);
248 1700
        spc->start = SIGN_DATA(&spc->ctx);
249 1700
        spc->size = size - SMP_SIGN_SPACE;
250 1700
}
251
252
/*--------------------------------------------------------------------
253
 * Force a write of a memory block (rounded to nearest pages) to
254
 * the backing store.
255
 */
256
257
static void
258 11696
smp_msync(const void *addr, size_t length)
259
{
260
        uintptr_t start, end, pagesize;
261
262 11696
        pagesize = getpagesize();
263 11696
        assert(pagesize > 0 && PWR2(pagesize));
264 11696
        start = RDN2((uintptr_t)addr, pagesize);
265 11696
        end = RUP2((uintptr_t)addr + length, pagesize);
266 11696
        assert(start < end);
267 11696
        AZ(msync((void *)start, end - start, MS_SYNC));
268 11696
}
269
270
/*--------------------------------------------------------------------
271
 * Initialize a Silo with a valid but empty structure.
272
 *
273
 * XXX: more intelligent sizing of things.
274
 */
275
276
void
277 425
smp_newsilo(struct smp_sc *sc)
278
{
279
        struct smp_ident        *si;
280
281
        /* Choose a new random number */
282 425
        AZ(VRND_RandomCrypto(&sc->unique, sizeof sc->unique));
283
284 425
        smp_reset_sign(&sc->idn);
285 425
        si = sc->ident;
286
287 425
        memset(si, 0, sizeof *si);
288 425
        bstrcpy(si->ident, SMP_IDENT_STRING);
289 425
        si->byte_order = 0x12345678;
290 425
        si->size = sizeof *si;
291 425
        si->major_version = 2;
292 425
        si->unique = sc->unique;
293 425
        si->mediasize = sc->mediasize;
294 425
        si->granularity = sc->granularity;
295
        /*
296
         * Aim for cache-line-width
297
         */
298 425
        si->align = sizeof(void*) * 2;
299 425
        sc->align = si->align;
300
301 425
        si->stuff[SMP_BAN1_STUFF] = sc->granularity;
302 425
        si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024;
303 425
        si->stuff[SMP_SEG1_STUFF] = si->stuff[SMP_BAN2_STUFF] + 1024*1024;
304 425
        si->stuff[SMP_SEG2_STUFF] = si->stuff[SMP_SEG1_STUFF] + 1024*1024;
305 425
        si->stuff[SMP_SPC_STUFF] = si->stuff[SMP_SEG2_STUFF] + 1024*1024;
306 425
        si->stuff[SMP_END_STUFF] = si->mediasize;
307 425
        assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]);
308
309 850
        smp_new_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
310 425
                          smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
311 850
        smp_new_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
312 425
                          smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
313 850
        smp_new_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
314 425
                          smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
315 850
        smp_new_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
316 425
                          smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
317
318 425
        smp_append_sign(&sc->idn, si, sizeof *si);
319 425
        smp_sync_sign(&sc->idn);
320 425
}
321
322
/*--------------------------------------------------------------------
323
 * Check if a silo is valid.
324
 */
325
326
int
327 2850
smp_valid_silo(struct smp_sc *sc)
328
{
329
        struct smp_ident        *si;
330
        int i, j;
331
332 2850
        assert(strlen(SMP_IDENT_STRING) < sizeof si->ident);
333
334 2850
        i = smp_chk_sign(&sc->idn);
335 2850
        if (i)
336 425
                return (i);
337
338 2425
        si = sc->ident;
339 2425
        if (strcmp(si->ident, SMP_IDENT_STRING))
340 0
                return (12);
341 2425
        if (si->byte_order != 0x12345678)
342 0
                return (13);
343 2425
        if (si->size != sizeof *si)
344 0
                return (14);
345 2425
        if (si->major_version != 2)
346 0
                return (15);
347 2425
        if (si->mediasize != sc->mediasize)
348 0
                return (17);
349 2425
        if (si->granularity != sc->granularity)
350 0
                return (18);
351 2425
        if (si->align < sizeof(void*))
352 0
                return (19);
353 2425
        if (!PWR2(si->align))
354 0
                return (20);
355 2425
        sc->align = si->align;
356 2425
        sc->unique = si->unique;
357
358
        /* XXX: Sanity check stuff[6] */
359
360 2425
        assert(si->stuff[SMP_BAN1_STUFF] > sizeof *si + VSHA256_LEN);
361 2425
        assert(si->stuff[SMP_BAN2_STUFF] > si->stuff[SMP_BAN1_STUFF]);
362 2425
        assert(si->stuff[SMP_SEG1_STUFF] > si->stuff[SMP_BAN2_STUFF]);
363 2425
        assert(si->stuff[SMP_SEG2_STUFF] > si->stuff[SMP_SEG1_STUFF]);
364 2425
        assert(si->stuff[SMP_SPC_STUFF] > si->stuff[SMP_SEG2_STUFF]);
365 2425
        assert(si->stuff[SMP_END_STUFF] == sc->mediasize);
366
367 2425
        assert(smp_stuff_len(sc, SMP_SEG1_STUFF) > 65536);
368 2425
        assert(smp_stuff_len(sc, SMP_SEG1_STUFF) ==
369
          smp_stuff_len(sc, SMP_SEG2_STUFF));
370
371 2425
        assert(smp_stuff_len(sc, SMP_BAN1_STUFF) > 65536);
372 2425
        assert(smp_stuff_len(sc, SMP_BAN1_STUFF) ==
373
          smp_stuff_len(sc, SMP_BAN2_STUFF));
374
375 4850
        smp_def_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
376 2425
                          smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
377 4850
        smp_def_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
378 2425
                          smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
379 4850
        smp_def_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
380 2425
                          smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
381 4850
        smp_def_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
382 2425
                          smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
383
384
        /* We must have one valid BAN table */
385 2425
        i = smp_chk_signspace(&sc->ban1);
386 2425
        j = smp_chk_signspace(&sc->ban2);
387 2425
        if (i && j)
388 0
                return (100 + i * 10 + j);
389
390
        /* We must have one valid SEG table */
391 2425
        i = smp_chk_signspace(&sc->seg1);
392 2425
        j = smp_chk_signspace(&sc->seg2);
393 2425
        if (i && j)
394 0
                return (200 + i * 10 + j);
395 2425
        return (0);
396 2850
}