]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/venti/srv/config.c
venti: fix memory layers
[plan9front.git] / sys / src / cmd / venti / srv / config.c
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
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
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
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 = vtstrdup(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 = vtstrdup(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 = vtstrdup(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 = vtstrdup(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 = vtstrdup(flds[1]);
179                 }else{
180                         seterr(EAdmin, "illegal line '%s' in configuration file %s", line, file);
181                         break;
182                 }
183                 free(line);
184                 line = nil;
185         }
186         free(line);
187         freeifile(&f);
188         if(ok < 0){
189                 free(config->sects);
190                 config->sects = nil;
191                 free(config->aparts);
192                 config->aparts = nil;
193         }
194         return ok;
195 }
196
197 static ISect*
198 configisect(char *file)
199 {
200         Part *part;
201         ISect *is;
202         
203         if(0) fprint(2, "configure index section in %s\n", file);
204
205         part = initpart(file, ORDWR|ODIRECT);
206         if(part == nil)
207                 return nil;
208         is = initisect(part);
209         if(is == nil)
210                 werrstr("%s: %r", file);
211         return is;
212 }
213
214 static ArenaPart*
215 configarenas(char *file)
216 {
217         ArenaPart *ap;
218         Part *part;
219
220         if(0) fprint(2, "configure arenas in %s\n", file);
221         part = initpart(file, ORDWR|ODIRECT);
222         if(part == nil)
223                 return nil;
224         ap = initarenapart(part);
225         if(ap == nil)
226                 werrstr("%s: %r", file);
227         return ap;
228 }
229
230 static Bloom*
231 configbloom(char *file)
232 {
233         Bloom *b;
234         Part *part;
235
236         if(0) fprint(2, "configure bloom in %s\n", file);
237         part = initpart(file, ORDWR|ODIRECT);
238         if(part == nil)
239                 return nil;
240         b = readbloom(part);
241         if(b == nil){
242                 werrstr("%s: %r", file);
243                 freepart(part);
244         }
245         return b;
246 }
247
248 /* for OS X linker, which only resolves functions, not data */
249 void
250 needmainindex(void)
251 {
252 }
253