Commit 55f1241e authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move various subroutines to storage_persistent_subr.c, these are the

ones that later may find usage in a separate silo-maintenance utility.
parent 1b33b0f4
......@@ -65,6 +65,7 @@ varnishd_SOURCES = \
storage_malloc.c \
storage_persistent.c \
storage_persistent_mgt.c \
storage_persistent_subr.c \
storage_synth.c \
storage_umem.c \
stevedore_utils.c \
......
......@@ -41,7 +41,6 @@ SVNID("$Id$")
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
......@@ -66,258 +65,6 @@ SVNID("$Id$")
*/
static VTAILQ_HEAD(,smp_sc) silos = VTAILQ_HEAD_INITIALIZER(silos);
/*--------------------------------------------------------------------
* SIGNATURE functions
* The signature is SHA256 over:
* 1. The smp_sign struct up to but not including the length field.
* 2. smp_sign->length bytes, starting after the smp_sign structure
* 3. The smp-sign->length field.
* The signature is stored after the byte-range from step 2.
*/
/*--------------------------------------------------------------------
* Define a signature by location and identifier.
*/
void
smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
uint64_t off, const char *id)
{
AZ(off & 7); /* Alignment */
assert(strlen(id) < sizeof ctx->ss->ident);
memset(ctx, 0, sizeof ctx);
ctx->ss = (void*)(sc->base + off);
ctx->unique = sc->unique;
ctx->id = id;
}
/*--------------------------------------------------------------------
* Check that a signature is good, leave state ready for append
*/
static int
smp_chk_sign(struct smp_signctx *ctx)
{
struct SHA256Context cx;
unsigned char sign[SHA256_LEN];
int r = 0;
if (strncmp(ctx->id, ctx->ss->ident, sizeof ctx->ss->ident))
r = 1;
else if (ctx->unique != ctx->ss->unique)
r = 2;
else if ((uintptr_t)ctx->ss != ctx->ss->mapped)
r = 3;
else {
SHA256_Init(&ctx->ctx);
SHA256_Update(&ctx->ctx, ctx->ss,
offsetof(struct smp_sign, length));
SHA256_Update(&ctx->ctx, SIGN_DATA(ctx), ctx->ss->length);
cx = ctx->ctx;
SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
SHA256_Final(sign, &cx);
if (memcmp(sign, SIGN_END(ctx), sizeof sign))
r = 4;
}
if (r) {
fprintf(stderr, "CHK(%p %s %p %s) = %d\n",
ctx, ctx->id, ctx->ss,
r > 1 ? ctx->ss->ident : "<invalid>", r);
}
return (r);
}
/*--------------------------------------------------------------------
* Append data to a signature
*/
static void
smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len)
{
struct SHA256Context cx;
unsigned char sign[SHA256_LEN];
if (len != 0) {
SHA256_Update(&ctx->ctx, ptr, len);
ctx->ss->length += len;
}
cx = ctx->ctx;
SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length));
SHA256_Final(sign, &cx);
memcpy(SIGN_END(ctx), sign, sizeof sign);
XXXAZ(smp_chk_sign(ctx));
}
/*--------------------------------------------------------------------
* Reset a signature to empty, prepare for appending.
*/
static void
smp_reset_sign(struct smp_signctx *ctx)
{
memset(ctx->ss, 0, sizeof *ctx->ss);
strcpy(ctx->ss->ident, ctx->id);
ctx->ss->unique = ctx->unique;
ctx->ss->mapped = (uintptr_t)ctx->ss;
SHA256_Init(&ctx->ctx);
SHA256_Update(&ctx->ctx, ctx->ss,
offsetof(struct smp_sign, length));
smp_append_sign(ctx, NULL, 0);
}
/*--------------------------------------------------------------------
* Force a write of a signature block to the backing store.
*/
static void
smp_sync_sign(const struct smp_signctx *ctx)
{
int i;
/* XXX: round to pages */
i = msync((void*)ctx->ss, ctx->ss->length + SHA256_LEN, MS_SYNC);
if (i && 0)
fprintf(stderr, "SyncSign(%p %s) = %d %s\n",
ctx->ss, ctx->id, i, strerror(errno));
}
/*--------------------------------------------------------------------
* Create and force a new signature to backing store
*/
static void
smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
uint64_t off, const char *id)
{
smp_def_sign(sc, ctx, off, id);
smp_reset_sign(ctx);
smp_sync_sign(ctx);
}
/*-------------------------------------------------------------------:e
* Initialize a Silo with a valid but empty structure.
*
* XXX: more intelligent sizing of things.
*/
void
smp_newsilo(struct smp_sc *sc)
{
struct smp_ident *si;
ASSERT_MGT();
assert(strlen(SMP_IDENT_STRING) < sizeof si->ident);
/* Choose a new random number */
sc->unique = random();
smp_reset_sign(&sc->idn);
si = sc->ident;
memset(si, 0, sizeof *si);
strcpy(si->ident, SMP_IDENT_STRING);
si->byte_order = 0x12345678;
si->size = sizeof *si;
si->major_version = 2;
si->unique = sc->unique;
si->mediasize = sc->mediasize;
si->granularity = sc->granularity;
/*
* Aim for cache-line-width
*/
si->align = sizeof(void*) * 2;
sc->align = si->align;
si->stuff[SMP_BAN1_STUFF] = sc->granularity;
si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024;
si->stuff[SMP_SEG1_STUFF] = si->stuff[SMP_BAN2_STUFF] + 1024*1024;
si->stuff[SMP_SEG2_STUFF] = si->stuff[SMP_SEG1_STUFF] + 1024*1024;
si->stuff[SMP_SPC_STUFF] = si->stuff[SMP_SEG2_STUFF] + 1024*1024;
si->stuff[SMP_END_STUFF] = si->mediasize;
assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]);
smp_new_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1");
smp_new_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2");
smp_new_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1");
smp_new_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2");
smp_append_sign(&sc->idn, si, sizeof *si);
smp_sync_sign(&sc->idn);
}
/*--------------------------------------------------------------------
* Check if a silo is valid.
*/
int
smp_valid_silo(struct smp_sc *sc)
{
struct smp_ident *si;
int i, j;
assert(strlen(SMP_IDENT_STRING) < sizeof si->ident);
if (smp_chk_sign(&sc->idn))
return (1);
si = sc->ident;
if (strcmp(si->ident, SMP_IDENT_STRING))
return (2);
if (si->byte_order != 0x12345678)
return (3);
if (si->size != sizeof *si)
return (4);
if (si->major_version != 2)
return (5);
if (si->mediasize != sc->mediasize)
return (7);
if (si->granularity != sc->granularity)
return (8);
if (si->align < sizeof(void*))
return (9);
if (!PWR2(si->align))
return (10);
sc->align = si->align;
sc->unique = si->unique;
/* XXX: Sanity check stuff[6] */
assert(si->stuff[SMP_BAN1_STUFF] > sizeof *si + SHA256_LEN);
assert(si->stuff[SMP_BAN2_STUFF] > si->stuff[SMP_BAN1_STUFF]);
assert(si->stuff[SMP_SEG1_STUFF] > si->stuff[SMP_BAN2_STUFF]);
assert(si->stuff[SMP_SEG2_STUFF] > si->stuff[SMP_SEG1_STUFF]);
assert(si->stuff[SMP_SPC_STUFF] > si->stuff[SMP_SEG2_STUFF]);
assert(si->stuff[SMP_END_STUFF] == sc->mediasize);
assert(smp_stuff_len(sc, SMP_SEG1_STUFF) > 65536);
assert(smp_stuff_len(sc, SMP_SEG1_STUFF) ==
smp_stuff_len(sc, SMP_SEG2_STUFF));
assert(smp_stuff_len(sc, SMP_BAN1_STUFF) > 65536);
assert(smp_stuff_len(sc, SMP_BAN1_STUFF) ==
smp_stuff_len(sc, SMP_BAN2_STUFF));
smp_def_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1");
smp_def_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2");
smp_def_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1");
smp_def_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2");
/* We must have one valid BAN table */
i = smp_chk_sign(&sc->ban1);
j = smp_chk_sign(&sc->ban2);
if (i && j)
return (100 + i * 10 + j);
/* We must have one valid SEG table */
i = smp_chk_sign(&sc->seg1);
j = smp_chk_sign(&sc->seg2);
if (i && j)
return (200 + i * 10 + j);
return (0);
}
/*--------------------------------------------------------------------
* Write the segmentlist back to the silo.
*
......
......@@ -175,16 +175,21 @@ struct smp_sc {
#define SIGN_END(ctx) ((void *)((int8_t *)SIGN_DATA(ctx) + (ctx)->ss->length))
/* storage_persistent.c */
void smp_newsilo(struct smp_sc *sc);
int smp_valid_silo(struct smp_sc *sc);
void smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
uint64_t off, const char *id);
/* storage_persistent_mgt.c */
void smp_mgt_init(struct stevedore *parent, int ac, char * const *av);
/*--------------------------------------------------------------------*/
/* storage_persistent_subr.c */
void smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
uint64_t off, const char *id);
int smp_chk_sign(struct smp_signctx *ctx);
void smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len);
void smp_reset_sign(struct smp_signctx *ctx);
void smp_sync_sign(const struct smp_signctx *ctx);
void smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
uint64_t off, const char *id);
void smp_newsilo(struct smp_sc *sc);
int smp_valid_silo(struct smp_sc *sc);
/*--------------------------------------------------------------------
* Caculate payload of some stuff
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment