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