varnish-cache/bin/varnishd/storage/storage_persistent_subr.c
1
/*-
2
 * Copyright (c) 2008-2011 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 *
28
 * Persistent storage method
29
 *
30
 * XXX: Before we start the client or maybe after it stops, we should give the
31
 * XXX: stevedores a chance to examine their storage for consistency.
32
 *
33
 * XXX: Do we ever free the LRU-lists ?
34
 */
35
36
#include "config.h"
37
38
#include "cache/cache_varnishd.h"
39
#include "common/heritage.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 1359
smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
70
    uint64_t off, const char *id)
71
{
72
73 1359
        AZ(off & 7);                    /* Alignment */
74 1359
        assert(strlen(id) < sizeof ctx->ss->ident);
75
76 1359
        memset(ctx, 0, sizeof *ctx);
77 1359
        ctx->ss = (void*)(sc->base + off);
78 1359
        ctx->unique = sc->unique;
79 1359
        ctx->id = id;
80 1359
}
81
82
/*--------------------------------------------------------------------
83
 * Check that a signature is good, leave state ready for append
84
 */
85
int
86 1443
smp_chk_sign(struct smp_signctx *ctx)
87
{
88
        struct VSHA256Context cx;
89
        unsigned char sign[VSHA256_LEN];
90 1443
        int r = 0;
91
92 1443
        if (strncmp(ctx->id, ctx->ss->ident, sizeof ctx->ss->ident))
93 51
                r = 1;
94 1392
        else if (ctx->unique != ctx->ss->unique)
95 0
                r = 2;
96 1392
        else if ((uintptr_t)ctx->ss != ctx->ss->mapped)
97 0
                r = 3;
98
        else {
99 1392
                VSHA256_Init(&ctx->ctx);
100 1392
                VSHA256_Update(&ctx->ctx, ctx->ss,
101
                    offsetof(struct smp_sign, length));
102 1392
                VSHA256_Update(&ctx->ctx, SIGN_DATA(ctx), ctx->ss->length);
103 1392
                cx = ctx->ctx;
104 1392
                VSHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
105 1392
                VSHA256_Final(sign, &cx);
106 1392
                if (memcmp(sign, SIGN_END(ctx), sizeof sign))
107 0
                        r = 4;
108
        }
109 1443
        if (r) {
110 51
                fprintf(stderr, "CHK(%p %s %p %s) = %d\n",
111
                    ctx, ctx->id, ctx->ss,
112 0
                    r > 1 ? ctx->ss->ident : "<invalid>", r);
113
        }
114 1443
        return (r);
115
}
116
117
/*--------------------------------------------------------------------
118
 * Append data to a signature
119
 */
120
static void
121 2655
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 2655
        if (len != 0) {
127 1146
                VSHA256_Update(&ctx->ctx, ptr, len);
128 1146
                ctx->ss->length += len;
129
        }
130 2655
        cx = ctx->ctx;
131 2655
        VSHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
132 2655
        VSHA256_Final(sign, &cx);
133 2655
        memcpy(SIGN_END(ctx), sign, sizeof sign);
134 2655
}
135
136
/*--------------------------------------------------------------------
137
 * Reset a signature to empty, prepare for appending.
138
 */
139
140
void
141 1404
smp_reset_sign(struct smp_signctx *ctx)
142
{
143
144 1404
        memset(ctx->ss, 0, sizeof *ctx->ss);
145 1404
        assert(strlen(ctx->id) < sizeof *ctx->ss);
146 1404
        strcpy(ctx->ss->ident, ctx->id);
147 1404
        ctx->ss->unique = ctx->unique;
148 1404
        ctx->ss->mapped = (uintptr_t)ctx->ss;
149 1404
        VSHA256_Init(&ctx->ctx);
150 1404
        VSHA256_Update(&ctx->ctx, ctx->ss,
151
            offsetof(struct smp_sign, length));
152 1404
        smp_append_sign(ctx, NULL, 0);
153 1404
}
154
155
/*--------------------------------------------------------------------
156
 * Force a write of a signature block to the backing store.
157
 */
158
159
void
160 1404
smp_sync_sign(const struct smp_signctx *ctx)
161
{
162 1404
        smp_msync(ctx->ss, SMP_SIGN_SPACE + ctx->ss->length);
163 1404
}
164
165
/*--------------------------------------------------------------------
166
 * Create and force a new signature to backing store
167
 */
168
169
static void
170 204
smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
171
    uint64_t off, const char *id)
172
{
173 204
        smp_def_sign(sc, ctx, off, id);
174 204
        smp_reset_sign(ctx);
175 204
        smp_sync_sign(ctx);
176 204
}
177
178
/*--------------------------------------------------------------------
179
 * Define a signature space by location, size and identifier
180
 */
181
182
static void
183 804
smp_def_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
184
                  uint64_t off, uint64_t size, const char *id)
185
{
186 804
        smp_def_sign(sc, &spc->ctx, off, id);
187 804
        spc->start = SIGN_DATA(&spc->ctx);
188 804
        spc->size = size - SMP_SIGN_SPACE;
189 804
}
190
191
/*--------------------------------------------------------------------
192
 * Check that a signspace's signature space is good, leave state ready
193
 * for append
194
 */
195
196
int
197 1146
smp_chk_signspace(struct smp_signspace *spc)
198
{
199 1146
        return (smp_chk_sign(&spc->ctx));
200
}
201
202
/*--------------------------------------------------------------------
203
 * Append data to a signature space
204
 */
205
206
void
207 1200
smp_append_signspace(struct smp_signspace *spc, uint32_t len)
208
{
209 1200
        assert(len <= SIGNSPACE_FREE(spc));
210 1200
        smp_append_sign(&spc->ctx, SIGNSPACE_FRONT(spc), len);
211 1200
}
212
213
/*--------------------------------------------------------------------
214
 * Reset a signature space to empty, prepare for appending.
215
 */
216
217
void
218 912
smp_reset_signspace(struct smp_signspace *spc)
219
{
220 912
        smp_reset_sign(&spc->ctx);
221 912
}
222
223
/*--------------------------------------------------------------------
224
 * Copy the contents of one signspace to another. Prepare for
225
 * appending.
226
 */
227
228
void
229 114
smp_copy_signspace(struct smp_signspace *dst, const struct smp_signspace *src)
230
{
231 114
        assert(SIGNSPACE_LEN(src) <= dst->size);
232 114
        smp_reset_signspace(dst);
233 114
        memcpy(SIGNSPACE_DATA(dst), SIGNSPACE_DATA(src), SIGNSPACE_LEN(src));
234 114
        smp_append_signspace(dst, SIGNSPACE_LEN(src));
235 114
        assert(SIGNSPACE_LEN(src) == SIGNSPACE_LEN(dst));
236 114
}
237
238
/*--------------------------------------------------------------------
239
 * Create a new signature space and force the signature to backing store.
240
 */
241
242
static void
243 204
smp_new_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
244
                  uint64_t off, uint64_t size, const char *id)
245
{
246 204
        smp_new_sign(sc, &spc->ctx, off, id);
247 204
        spc->start = SIGN_DATA(&spc->ctx);
248 204
        spc->size = size - SMP_SIGN_SPACE;
249 204
}
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 1404
smp_msync(const void *addr, size_t length)
258
{
259
        uintptr_t start, end, pagesize;
260
261 1404
        pagesize = getpagesize();
262 1404
        assert(pagesize > 0 && PWR2(pagesize));
263 1404
        start = RDN2((uintptr_t)addr, pagesize);
264 1404
        end = RUP2((uintptr_t)addr + length, pagesize);
265 1404
        assert(start < end);
266 1404
        AZ(msync((void *)start, end - start, MS_SYNC));
267 1404
}
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 51
smp_newsilo(struct smp_sc *sc)
277
{
278
        struct smp_ident        *si;
279
280 51
        ASSERT_MGT();
281
        assert(strlen(SMP_IDENT_STRING) < sizeof si->ident);
282
283
        /* Choose a new random number */
284 51
        AZ(VRND_RandomCrypto(&sc->unique, sizeof sc->unique));
285
286 51
        smp_reset_sign(&sc->idn);
287 51
        si = sc->ident;
288
289 51
        memset(si, 0, sizeof *si);
290 51
        strcpy(si->ident, SMP_IDENT_STRING);
291 51
        si->byte_order = 0x12345678;
292 51
        si->size = sizeof *si;
293 51
        si->major_version = 2;
294 51
        si->unique = sc->unique;
295 51
        si->mediasize = sc->mediasize;
296 51
        si->granularity = sc->granularity;
297
        /*
298
         * Aim for cache-line-width
299
         */
300 51
        si->align = sizeof(void*) * 2;
301 51
        sc->align = si->align;
302
303 51
        si->stuff[SMP_BAN1_STUFF] = sc->granularity;
304 51
        si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024;
305 51
        si->stuff[SMP_SEG1_STUFF] = si->stuff[SMP_BAN2_STUFF] + 1024*1024;
306 51
        si->stuff[SMP_SEG2_STUFF] = si->stuff[SMP_SEG1_STUFF] + 1024*1024;
307 51
        si->stuff[SMP_SPC_STUFF] = si->stuff[SMP_SEG2_STUFF] + 1024*1024;
308 51
        si->stuff[SMP_END_STUFF] = si->mediasize;
309 51
        assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]);
310
311 51
        smp_new_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
312
                          smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
313 51
        smp_new_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
314
                          smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
315 51
        smp_new_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
316
                          smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
317 51
        smp_new_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
318
                          smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
319
320 51
        smp_append_sign(&sc->idn, si, sizeof *si);
321 51
        smp_sync_sign(&sc->idn);
322 51
}
323
324
/*--------------------------------------------------------------------
325
 * Check if a silo is valid.
326
 */
327
328
int
329 252
smp_valid_silo(struct smp_sc *sc)
330
{
331
        struct smp_ident        *si;
332
        int i, j;
333
334
        assert(strlen(SMP_IDENT_STRING) < sizeof si->ident);
335
336 252
        i = smp_chk_sign(&sc->idn);
337 252
        if (i)
338 51
                return (i);
339
340 201
        si = sc->ident;
341 201
        if (strcmp(si->ident, SMP_IDENT_STRING))
342 0
                return (12);
343 201
        if (si->byte_order != 0x12345678)
344 0
                return (13);
345 201
        if (si->size != sizeof *si)
346 0
                return (14);
347 201
        if (si->major_version != 2)
348 0
                return (15);
349 201
        if (si->mediasize != sc->mediasize)
350 0
                return (17);
351 201
        if (si->granularity != sc->granularity)
352 0
                return (18);
353 201
        if (si->align < sizeof(void*))
354 0
                return (19);
355 201
        if (!PWR2(si->align))
356 0
                return (20);
357 201
        sc->align = si->align;
358 201
        sc->unique = si->unique;
359
360
        /* XXX: Sanity check stuff[6] */
361
362 201
        assert(si->stuff[SMP_BAN1_STUFF] > sizeof *si + VSHA256_LEN);
363 201
        assert(si->stuff[SMP_BAN2_STUFF] > si->stuff[SMP_BAN1_STUFF]);
364 201
        assert(si->stuff[SMP_SEG1_STUFF] > si->stuff[SMP_BAN2_STUFF]);
365 201
        assert(si->stuff[SMP_SEG2_STUFF] > si->stuff[SMP_SEG1_STUFF]);
366 201
        assert(si->stuff[SMP_SPC_STUFF] > si->stuff[SMP_SEG2_STUFF]);
367 201
        assert(si->stuff[SMP_END_STUFF] == sc->mediasize);
368
369 201
        assert(smp_stuff_len(sc, SMP_SEG1_STUFF) > 65536);
370 201
        assert(smp_stuff_len(sc, SMP_SEG1_STUFF) ==
371
          smp_stuff_len(sc, SMP_SEG2_STUFF));
372
373 201
        assert(smp_stuff_len(sc, SMP_BAN1_STUFF) > 65536);
374 201
        assert(smp_stuff_len(sc, SMP_BAN1_STUFF) ==
375
          smp_stuff_len(sc, SMP_BAN2_STUFF));
376
377 201
        smp_def_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
378
                          smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
379 201
        smp_def_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
380
                          smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
381 201
        smp_def_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
382
                          smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
383 201
        smp_def_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
384
                          smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
385
386
        /* We must have one valid BAN table */
387 201
        i = smp_chk_signspace(&sc->ban1);
388 201
        j = smp_chk_signspace(&sc->ban2);
389 201
        if (i && j)
390 0
                return (100 + i * 10 + j);
391
392
        /* We must have one valid SEG table */
393 201
        i = smp_chk_signspace(&sc->seg1);
394 201
        j = smp_chk_signspace(&sc->seg2);
395 201
        if (i && j)
396 0
                return (200 + i * 10 + j);
397 201
        return (0);
398
}