1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4
5 Index *mainindex;
6 int paranoid = 1; /* should verify hashes on disk read */
7
8 static ArenaPart *configarenas(char *file);
9 static ISect *configisect(char *file);
10 static Bloom *configbloom(char *file);
11
12 int
initventi(char * file,Config * conf)13 initventi(char *file, Config *conf)
14 {
15 statsinit();
16
17 if(file == nil){
18 seterr(EOk, "no configuration file");
19 return -1;
20 }
21 if(runconfig(file, conf) < 0){
22 seterr(EOk, "can't initialize venti: %r");
23 return -1;
24 }
25 mainindex = initindex(conf->index, conf->sects, conf->nsects);
26 if(mainindex == nil)
27 return -1;
28 mainindex->bloom = conf->bloom;
29 return 0;
30 }
31
32 static int
numok(char * s)33 numok(char *s)
34 {
35 char *p;
36
37 strtoull(s, &p, 0);
38 if(p == s)
39 return -1;
40 if(*p == 0)
41 return 0;
42 if(p[1] == 0 && strchr("MmGgKk", *p))
43 return 0;
44 return 0;
45 }
46
47 /*
48 * configs :
49 * | configs config
50 * config : "isect" filename
51 * | "arenas" filename
52 * | "index" name
53 * | "bcmem" num
54 * | "mem" num
55 * | "icmem" num
56 * | "queuewrites"
57 * | "httpaddr" address
58 * | "addr" address
59 *
60 * '#' and \n delimit comments
61 */
62 enum
63 {
64 MaxArgs = 2
65 };
66 int
runconfig(char * file,Config * config)67 runconfig(char *file, Config *config)
68 {
69 ArenaPart **av;
70 ISect **sv;
71 IFile f;
72 char *s, *line, *flds[MaxArgs + 1];
73 int i, ok;
74
75 if(readifile(&f, file) < 0)
76 return -1;
77 memset(config, 0, sizeof *config);
78 config->mem = Unspecified;
79 ok = -1;
80 line = nil;
81 for(;;){
82 s = ifileline(&f);
83 if(s == nil){
84 ok = 0;
85 break;
86 }
87 line = estrdup(s);
88 i = getfields(s, flds, MaxArgs + 1, 1, " \t\r");
89 if(i == 2 && strcmp(flds[0], "isect") == 0){
90 sv = MKN(ISect*, config->nsects + 1);
91 for(i = 0; i < config->nsects; i++)
92 sv[i] = config->sects[i];
93 free(config->sects);
94 config->sects = sv;
95 config->sects[config->nsects] = configisect(flds[1]);
96 if(config->sects[config->nsects] == nil)
97 break;
98 config->nsects++;
99 }else if(i == 2 && strcmp(flds[0], "arenas") == 0){
100 av = MKN(ArenaPart*, config->naparts + 1);
101 for(i = 0; i < config->naparts; i++)
102 av[i] = config->aparts[i];
103 free(config->aparts);
104 config->aparts = av;
105 config->aparts[config->naparts] = configarenas(flds[1]);
106 if(config->aparts[config->naparts] == nil)
107 break;
108 config->naparts++;
109 }else if(i == 2 && strcmp(flds[0], "bloom") == 0){
110 if(config->bloom){
111 seterr(EAdmin, "duplicate bloom lines in configuration file %s", file);
112 break;
113 }
114 if((config->bloom = configbloom(flds[1])) == nil)
115 break;
116 }else if(i == 2 && strcmp(flds[0], "index") == 0){
117 if(nameok(flds[1]) < 0){
118 seterr(EAdmin, "illegal index name %s in config file %s", flds[1], file);
119 break;
120 }
121 if(config->index != nil){
122 seterr(EAdmin, "duplicate indices in config file %s", file);
123 break;
124 }
125 config->index = estrdup(flds[1]);
126 }else if(i == 2 && strcmp(flds[0], "bcmem") == 0){
127 if(numok(flds[1]) < 0){
128 seterr(EAdmin, "illegal size %s in config file %s",
129 flds[1], file);
130 break;
131 }
132 if(config->bcmem != 0){
133 seterr(EAdmin, "duplicate bcmem lines in config file %s", file);
134 break;
135 }
136 config->bcmem = unittoull(flds[1]);
137 }else if(i == 2 && strcmp(flds[0], "mem") == 0){
138 if(numok(flds[1]) < 0){
139 seterr(EAdmin, "illegal size %s in config file %s",
140 flds[1], file);
141 break;
142 }
143 if(config->mem != Unspecified){
144 seterr(EAdmin, "duplicate mem lines in config file %s", file);
145 break;
146 }
147 config->mem = unittoull(flds[1]);
148 }else if(i == 2 && strcmp(flds[0], "icmem") == 0){
149 if(numok(flds[1]) < 0){
150 seterr(EAdmin, "illegal size %s in config file %s",
151 flds[1], file);
152 break;
153 }
154 if(config->icmem != 0){
155 seterr(EAdmin, "duplicate icmem lines in config file %s", file);
156 break;
157 }
158 config->icmem = unittoull(flds[1]);
159 }else if(i == 1 && strcmp(flds[0], "queuewrites") == 0){
160 config->queuewrites = 1;
161 }else if(i == 2 && strcmp(flds[0], "httpaddr") == 0){
162 if(config->haddr){
163 seterr(EAdmin, "duplicate httpaddr lines in configuration file %s", file);
164 break;
165 }
166 config->haddr = estrdup(flds[1]);
167 }else if(i == 2 && strcmp(flds[0], "webroot") == 0){
168 if(config->webroot){
169 seterr(EAdmin, "duplicate webroot lines in configuration file %s", file);
170 break;
171 }
172 config->webroot = estrdup(flds[1]);
173 }else if(i == 2 && strcmp(flds[0], "addr") == 0){
174 if(config->vaddr){
175 seterr(EAdmin, "duplicate addr lines in configuration file %s", file);
176 break;
177 }
178 config->vaddr = estrdup(flds[1]);
179 }else{
180 /*
181 * this is insanely paranoid. a single typo should not
182 * prevent venti from starting.
183 */
184 seterr(EAdmin, "illegal line '%s' in configuration file %s", line, file);
185 break;
186 }
187 free(line);
188 line = nil;
189 }
190 free(line);
191 freeifile(&f);
192 if(ok < 0){
193 free(config->sects);
194 config->sects = nil;
195 free(config->aparts);
196 config->aparts = nil;
197 }
198 return ok;
199 }
200
201 static ISect*
configisect(char * file)202 configisect(char *file)
203 {
204 Part *part;
205 ISect *is;
206
207 if(0) fprint(2, "configure index section in %s\n", file);
208
209 part = initpart(file, ORDWR|ODIRECT);
210 if(part == nil)
211 return nil;
212 is = initisect(part);
213 if(is == nil)
214 werrstr("%s: %r", file);
215 return is;
216 }
217
218 static ArenaPart*
configarenas(char * file)219 configarenas(char *file)
220 {
221 ArenaPart *ap;
222 Part *part;
223
224 if(0) fprint(2, "configure arenas in %s\n", file);
225 part = initpart(file, ORDWR|ODIRECT);
226 if(part == nil)
227 return nil;
228 ap = initarenapart(part);
229 if(ap == nil)
230 werrstr("%s: %r", file);
231 return ap;
232 }
233
234 static Bloom*
configbloom(char * file)235 configbloom(char *file)
236 {
237 Bloom *b;
238 Part *part;
239
240 if(0) fprint(2, "configure bloom in %s\n", file);
241 part = initpart(file, ORDWR|ODIRECT);
242 if(part == nil)
243 return nil;
244 b = readbloom(part);
245 if(b == nil){
246 werrstr("%s: %r", file);
247 freepart(part);
248 }
249 return b;
250 }
251
252 /* for OS X linker, which only resolves functions, not data */
253 void
needmainindex(void)254 needmainindex(void)
255 {
256 }
257
258