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