static void smp_def_signspace(const struct smp_sc *sc, struct smp_signspace *spc, uint64_t off, uint64_t size, const char *id) { smp_def_sign(sc, &spc->ctx, off, id); spc->start = SIGN_DATA(&spc->ctx); spc->size = size - SMP_SIGN_SPACE; }
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); }
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); }
void smp_mgt_init(struct stevedore *parent, int ac, char * const *av) { struct smp_sc *sc; struct smp_sign sgn; void *target; int i; ASSERT_MGT(); AZ(av[ac]); /* Necessary alignment. See also smp_object::__filler__ */ assert(sizeof(struct smp_object) % 8 == 0); #define SIZOF(foo) fprintf(stderr, \ "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); SIZOF(struct smp_ident); SIZOF(struct smp_sign); SIZOF(struct smp_segptr); SIZOF(struct smp_object); #undef SIZOF /* See comments in storage_persistent.h */ assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE); /* Allocate softc */ ALLOC_OBJ(sc, SMP_SC_MAGIC); XXXAN(sc); sc->parent = parent; sc->fd = -1; VTAILQ_INIT(&sc->segments); /* Argument processing */ if (ac != 2) ARGV_ERR("(-spersistent) wrong number of arguments\n"); i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent"); if (i == 2) ARGV_ERR("(-spersistent) need filename (not directory)\n"); sc->align = sizeof(void*) * 2; sc->granularity = getpagesize(); sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity, "-spersistent"); AZ(ftruncate(sc->fd, sc->mediasize)); /* Try to determine correct mmap address */ i = read(sc->fd, &sgn, sizeof sgn); assert(i == sizeof sgn); if (!strcmp(sgn.ident, "SILO")) target = (void*)(uintptr_t)sgn.mapped; else target = NULL; sc->base = (void*)mmap(target, sc->mediasize, PROT_READ|PROT_WRITE, MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0); if (sc->base == MAP_FAILED) ARGV_ERR("(-spersistent) failed to mmap (%s)\n", strerror(errno)); smp_def_sign(sc, &sc->idn, 0, "SILO"); sc->ident = SIGN_DATA(&sc->idn); i = smp_valid_silo(sc); if (i) { printf("Warning SILO (%s) not reloaded (reason=%d)\n", sc->filename, i); smp_newsilo(sc); } AZ(smp_valid_silo(sc)); smp_metrics(sc); parent->priv = sc; /* XXX: only for sendfile I guess... */ mgt_child_inherit(sc->fd, "storage_persistent"); }