xref: /plan9/sys/src/cmd/venti/srv/config.c (revision cebd3b46303b6884206200c08c0d8b3fb8dc989e)
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