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