#include "stdinc.h" #include "dat.h" #include "fns.h" Index *mainindex; int paranoid = 1; /* should verify hashes on disk read */ static ArenaPart *configarenas(char *file); static ISect *configisect(char *file); static Bloom *configbloom(char *file); int initventi(char *file, Config *conf) { statsinit(); if(file == nil){ seterr(EOk, "no configuration file"); return -1; } if(runconfig(file, conf) < 0){ seterr(EOk, "can't initialize venti: %r"); return -1; } mainindex = initindex(conf->index, conf->sects, conf->nsects); if(mainindex == nil) return -1; mainindex->bloom = conf->bloom; return 0; } static int numok(char *s) { char *p; strtoull(s, &p, 0); if(p == s) return -1; if(*p == 0) return 0; if(p[1] == 0 && strchr("MmGgKk", *p)) return 0; return 0; } /* * configs : * | configs config * config : "isect" filename * | "arenas" filename * | "index" name * | "bcmem" num * | "mem" num * | "icmem" num * | "queuewrites" * | "httpaddr" address * | "addr" address * * '#' and \n delimit comments */ enum { MaxArgs = 2 }; int runconfig(char *file, Config *config) { ArenaPart **av; ISect **sv; IFile f; char *s, *line, *flds[MaxArgs + 1]; int i, ok; if(readifile(&f, file) < 0) return -1; memset(config, 0, sizeof *config); config->mem = Unspecified; ok = -1; line = nil; for(;;){ s = ifileline(&f); if(s == nil){ ok = 0; break; } line = estrdup(s); i = getfields(s, flds, MaxArgs + 1, 1, " \t\r"); if(i == 2 && strcmp(flds[0], "isect") == 0){ sv = MKN(ISect*, config->nsects + 1); for(i = 0; i < config->nsects; i++) sv[i] = config->sects[i]; free(config->sects); config->sects = sv; config->sects[config->nsects] = configisect(flds[1]); if(config->sects[config->nsects] == nil) break; config->nsects++; }else if(i == 2 && strcmp(flds[0], "arenas") == 0){ av = MKN(ArenaPart*, config->naparts + 1); for(i = 0; i < config->naparts; i++) av[i] = config->aparts[i]; free(config->aparts); config->aparts = av; config->aparts[config->naparts] = configarenas(flds[1]); if(config->aparts[config->naparts] == nil) break; config->naparts++; }else if(i == 2 && strcmp(flds[0], "bloom") == 0){ if(config->bloom){ seterr(EAdmin, "duplicate bloom lines in configuration file %s", file); break; } if((config->bloom = configbloom(flds[1])) == nil) break; }else if(i == 2 && strcmp(flds[0], "index") == 0){ if(nameok(flds[1]) < 0){ seterr(EAdmin, "illegal index name %s in config file %s", flds[1], file); break; } if(config->index != nil){ seterr(EAdmin, "duplicate indices in config file %s", file); break; } config->index = estrdup(flds[1]); }else if(i == 2 && strcmp(flds[0], "bcmem") == 0){ if(numok(flds[1]) < 0){ seterr(EAdmin, "illegal size %s in config file %s", flds[1], file); break; } if(config->bcmem != 0){ seterr(EAdmin, "duplicate bcmem lines in config file %s", file); break; } config->bcmem = unittoull(flds[1]); }else if(i == 2 && strcmp(flds[0], "mem") == 0){ if(numok(flds[1]) < 0){ seterr(EAdmin, "illegal size %s in config file %s", flds[1], file); break; } if(config->mem != Unspecified){ seterr(EAdmin, "duplicate mem lines in config file %s", file); break; } config->mem = unittoull(flds[1]); }else if(i == 2 && strcmp(flds[0], "icmem") == 0){ if(numok(flds[1]) < 0){ seterr(EAdmin, "illegal size %s in config file %s", flds[1], file); break; } if(config->icmem != 0){ seterr(EAdmin, "duplicate icmem lines in config file %s", file); break; } config->icmem = unittoull(flds[1]); }else if(i == 1 && strcmp(flds[0], "queuewrites") == 0){ config->queuewrites = 1; }else if(i == 2 && strcmp(flds[0], "httpaddr") == 0){ if(config->haddr){ seterr(EAdmin, "duplicate httpaddr lines in configuration file %s", file); break; } config->haddr = estrdup(flds[1]); }else if(i == 2 && strcmp(flds[0], "webroot") == 0){ if(config->webroot){ seterr(EAdmin, "duplicate webroot lines in configuration file %s", file); break; } config->webroot = estrdup(flds[1]); }else if(i == 2 && strcmp(flds[0], "addr") == 0){ if(config->vaddr){ seterr(EAdmin, "duplicate addr lines in configuration file %s", file); break; } config->vaddr = estrdup(flds[1]); }else{ /* * this is insanely paranoid. a single typo should not * prevent venti from starting. */ seterr(EAdmin, "illegal line '%s' in configuration file %s", line, file); break; } free(line); line = nil; } free(line); freeifile(&f); if(ok < 0){ free(config->sects); config->sects = nil; free(config->aparts); config->aparts = nil; } return ok; } static ISect* configisect(char *file) { Part *part; ISect *is; if(0) fprint(2, "configure index section in %s\n", file); part = initpart(file, ORDWR|ODIRECT); if(part == nil) return nil; is = initisect(part); if(is == nil) werrstr("%s: %r", file); return is; } static ArenaPart* configarenas(char *file) { ArenaPart *ap; Part *part; if(0) fprint(2, "configure arenas in %s\n", file); part = initpart(file, ORDWR|ODIRECT); if(part == nil) return nil; ap = initarenapart(part); if(ap == nil) werrstr("%s: %r", file); return ap; } static Bloom* configbloom(char *file) { Bloom *b; Part *part; if(0) fprint(2, "configure bloom in %s\n", file); part = initpart(file, ORDWR|ODIRECT); if(part == nil) return nil; b = readbloom(part); if(b == nil){ werrstr("%s: %r", file); freepart(part); } return b; } /* for OS X linker, which only resolves functions, not data */ void needmainindex(void) { }