static void smp_metrics(struct smp_sc *sc) { /* * We do not want to loose too big chunks of the silos * content when we are forced to clean a segment. * * For now insist that a segment covers no more than 1% of the silo. * * XXX: This should possibly depend on the size of the silo so * XXX: trivially small silos do not run into trouble along * XXX: the lines of "one object per segment". */ sc->min_nseg = 10; sc->max_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->min_nseg; fprintf(stderr, "min_nseg = %u, max_segl = %ju\n", sc->min_nseg, (uintmax_t)sc->max_segl); /* * The number of segments are limited by the size of the segment * table(s) and from that follows the minimum size of a segmement. */ sc->max_nseg = smp_stuff_len(sc, SMP_SEG1_STUFF) / sc->min_nseg; sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; while (sc->min_segl < sizeof(struct object)) { sc->max_nseg /= 2; sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; } fprintf(stderr, "max_nseg = %u, min_segl = %ju\n", sc->max_nseg, (uintmax_t)sc->min_segl); /* * Set our initial aim point at the exponential average of the * two extremes. * * XXX: This is a pretty arbitrary choice, but having no idea * XXX: object count, size distribution or ttl pattern at this * XXX: point, we have to do something. */ sc->aim_nseg = (unsigned) exp((log(sc->min_nseg) + log(sc->max_nseg))*.5); sc->aim_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->aim_nseg; fprintf(stderr, "aim_nseg = %u, aim_segl = %ju\n", sc->aim_nseg, (uintmax_t)sc->aim_segl); /* * How much space in the free reserve pool ? */ sc->free_reserve = sc->aim_segl * 10; fprintf(stderr, "free_reserve = %ju\n", (uintmax_t)sc->free_reserve); }
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 */ AZ(VRND_RandomCrypto(&sc->unique, sizeof sc->unique)); 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_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1"); smp_new_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2"); smp_new_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1"); smp_new_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2"); smp_append_sign(&sc->idn, si, sizeof *si); smp_sync_sign(&sc->idn); }
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); }