xref: /plan9/sys/src/cmd/venti/srv/config.c (revision cebd3b46303b6884206200c08c0d8b3fb8dc989e)
1368c31abSDavid du Colombier #include "stdinc.h"
2368c31abSDavid du Colombier #include "dat.h"
3368c31abSDavid du Colombier #include "fns.h"
4368c31abSDavid du Colombier 
5368c31abSDavid du Colombier Index			*mainindex;
6368c31abSDavid du Colombier int			paranoid = 1;		/* should verify hashes on disk read */
7368c31abSDavid du Colombier 
8368c31abSDavid du Colombier static ArenaPart	*configarenas(char *file);
9368c31abSDavid du Colombier static ISect		*configisect(char *file);
10368c31abSDavid du Colombier static Bloom		*configbloom(char *file);
11368c31abSDavid du Colombier 
12368c31abSDavid du Colombier int
initventi(char * file,Config * conf)13368c31abSDavid du Colombier initventi(char *file, Config *conf)
14368c31abSDavid du Colombier {
15368c31abSDavid du Colombier 	statsinit();
16368c31abSDavid du Colombier 
17368c31abSDavid du Colombier 	if(file == nil){
18368c31abSDavid du Colombier 		seterr(EOk, "no configuration file");
19368c31abSDavid du Colombier 		return -1;
20368c31abSDavid du Colombier 	}
21368c31abSDavid du Colombier 	if(runconfig(file, conf) < 0){
22368c31abSDavid du Colombier 		seterr(EOk, "can't initialize venti: %r");
23368c31abSDavid du Colombier 		return -1;
24368c31abSDavid du Colombier 	}
25368c31abSDavid du Colombier 	mainindex = initindex(conf->index, conf->sects, conf->nsects);
26368c31abSDavid du Colombier 	if(mainindex == nil)
27368c31abSDavid du Colombier 		return -1;
28368c31abSDavid du Colombier 	mainindex->bloom = conf->bloom;
29368c31abSDavid du Colombier 	return 0;
30368c31abSDavid du Colombier }
31368c31abSDavid du Colombier 
32368c31abSDavid du Colombier static int
numok(char * s)33368c31abSDavid du Colombier numok(char *s)
34368c31abSDavid du Colombier {
35368c31abSDavid du Colombier 	char *p;
36368c31abSDavid du Colombier 
37368c31abSDavid du Colombier 	strtoull(s, &p, 0);
38368c31abSDavid du Colombier 	if(p == s)
39368c31abSDavid du Colombier 		return -1;
40368c31abSDavid du Colombier 	if(*p == 0)
41368c31abSDavid du Colombier 		return 0;
42368c31abSDavid du Colombier 	if(p[1] == 0 && strchr("MmGgKk", *p))
43368c31abSDavid du Colombier 		return 0;
44368c31abSDavid du Colombier 	return 0;
45368c31abSDavid du Colombier }
46368c31abSDavid du Colombier 
47368c31abSDavid du Colombier /*
48368c31abSDavid du Colombier  * configs	:
49368c31abSDavid du Colombier  *		| configs config
50368c31abSDavid du Colombier  * config	: "isect" filename
51368c31abSDavid du Colombier  *		| "arenas" filename
52368c31abSDavid du Colombier  *		| "index" name
53368c31abSDavid du Colombier  *		| "bcmem" num
54368c31abSDavid du Colombier  *		| "mem" num
55368c31abSDavid du Colombier  *		| "icmem" num
56368c31abSDavid du Colombier  *		| "queuewrites"
57368c31abSDavid du Colombier  *		| "httpaddr" address
58368c31abSDavid du Colombier  *		| "addr" address
59368c31abSDavid du Colombier  *
60368c31abSDavid du Colombier  * '#' and \n delimit comments
61368c31abSDavid du Colombier  */
62368c31abSDavid du Colombier enum
63368c31abSDavid du Colombier {
64368c31abSDavid du Colombier 	MaxArgs	= 2
65368c31abSDavid du Colombier };
66368c31abSDavid du Colombier int
runconfig(char * file,Config * config)67368c31abSDavid du Colombier runconfig(char *file, Config *config)
68368c31abSDavid du Colombier {
69368c31abSDavid du Colombier 	ArenaPart **av;
70368c31abSDavid du Colombier 	ISect **sv;
71368c31abSDavid du Colombier 	IFile f;
72368c31abSDavid du Colombier 	char *s, *line, *flds[MaxArgs + 1];
73368c31abSDavid du Colombier 	int i, ok;
74368c31abSDavid du Colombier 
75368c31abSDavid du Colombier 	if(readifile(&f, file) < 0)
76368c31abSDavid du Colombier 		return -1;
77368c31abSDavid du Colombier 	memset(config, 0, sizeof *config);
78c18ab83fSDavid du Colombier 	config->mem = Unspecified;
79368c31abSDavid du Colombier 	ok = -1;
80368c31abSDavid du Colombier 	line = nil;
81368c31abSDavid du Colombier 	for(;;){
82368c31abSDavid du Colombier 		s = ifileline(&f);
83368c31abSDavid du Colombier 		if(s == nil){
84368c31abSDavid du Colombier 			ok = 0;
85368c31abSDavid du Colombier 			break;
86368c31abSDavid du Colombier 		}
87368c31abSDavid du Colombier 		line = estrdup(s);
88368c31abSDavid du Colombier 		i = getfields(s, flds, MaxArgs + 1, 1, " \t\r");
89368c31abSDavid du Colombier 		if(i == 2 && strcmp(flds[0], "isect") == 0){
90368c31abSDavid du Colombier 			sv = MKN(ISect*, config->nsects + 1);
91368c31abSDavid du Colombier 			for(i = 0; i < config->nsects; i++)
92368c31abSDavid du Colombier 				sv[i] = config->sects[i];
93368c31abSDavid du Colombier 			free(config->sects);
94368c31abSDavid du Colombier 			config->sects = sv;
95368c31abSDavid du Colombier 			config->sects[config->nsects] = configisect(flds[1]);
96368c31abSDavid du Colombier 			if(config->sects[config->nsects] == nil)
97368c31abSDavid du Colombier 				break;
98368c31abSDavid du Colombier 			config->nsects++;
99368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "arenas") == 0){
100368c31abSDavid du Colombier 			av = MKN(ArenaPart*, config->naparts + 1);
101368c31abSDavid du Colombier 			for(i = 0; i < config->naparts; i++)
102368c31abSDavid du Colombier 				av[i] = config->aparts[i];
103368c31abSDavid du Colombier 			free(config->aparts);
104368c31abSDavid du Colombier 			config->aparts = av;
105368c31abSDavid du Colombier 			config->aparts[config->naparts] = configarenas(flds[1]);
106368c31abSDavid du Colombier 			if(config->aparts[config->naparts] == nil)
107368c31abSDavid du Colombier 				break;
108368c31abSDavid du Colombier 			config->naparts++;
109368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "bloom") == 0){
110368c31abSDavid du Colombier 			if(config->bloom){
111368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate bloom lines in configuration file %s", file);
112368c31abSDavid du Colombier 				break;
113368c31abSDavid du Colombier 			}
114368c31abSDavid du Colombier 			if((config->bloom = configbloom(flds[1])) == nil)
115368c31abSDavid du Colombier 				break;
116368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "index") == 0){
117368c31abSDavid du Colombier 			if(nameok(flds[1]) < 0){
118368c31abSDavid du Colombier 				seterr(EAdmin, "illegal index name %s in config file %s", flds[1], file);
119368c31abSDavid du Colombier 				break;
120368c31abSDavid du Colombier 			}
121368c31abSDavid du Colombier 			if(config->index != nil){
122368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate indices in config file %s", file);
123368c31abSDavid du Colombier 				break;
124368c31abSDavid du Colombier 			}
125368c31abSDavid du Colombier 			config->index = estrdup(flds[1]);
126368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "bcmem") == 0){
127368c31abSDavid du Colombier 			if(numok(flds[1]) < 0){
128368c31abSDavid du Colombier 				seterr(EAdmin, "illegal size %s in config file %s",
129368c31abSDavid du Colombier 					flds[1], file);
130368c31abSDavid du Colombier 				break;
131368c31abSDavid du Colombier 			}
132368c31abSDavid du Colombier 			if(config->bcmem != 0){
133368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate bcmem lines in config file %s", file);
134368c31abSDavid du Colombier 				break;
135368c31abSDavid du Colombier 			}
136368c31abSDavid du Colombier 			config->bcmem = unittoull(flds[1]);
137368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "mem") == 0){
138368c31abSDavid du Colombier 			if(numok(flds[1]) < 0){
139368c31abSDavid du Colombier 				seterr(EAdmin, "illegal size %s in config file %s",
140368c31abSDavid du Colombier 					flds[1], file);
141368c31abSDavid du Colombier 				break;
142368c31abSDavid du Colombier 			}
143c18ab83fSDavid du Colombier 			if(config->mem != Unspecified){
144368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate mem lines in config file %s", file);
145368c31abSDavid du Colombier 				break;
146368c31abSDavid du Colombier 			}
147368c31abSDavid du Colombier 			config->mem = unittoull(flds[1]);
148368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "icmem") == 0){
149368c31abSDavid du Colombier 			if(numok(flds[1]) < 0){
150368c31abSDavid du Colombier 				seterr(EAdmin, "illegal size %s in config file %s",
151368c31abSDavid du Colombier 					flds[1], file);
152368c31abSDavid du Colombier 				break;
153368c31abSDavid du Colombier 			}
154368c31abSDavid du Colombier 			if(config->icmem != 0){
155368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate icmem lines in config file %s", file);
156368c31abSDavid du Colombier 				break;
157368c31abSDavid du Colombier 			}
158368c31abSDavid du Colombier 			config->icmem = unittoull(flds[1]);
159368c31abSDavid du Colombier 		}else if(i == 1 && strcmp(flds[0], "queuewrites") == 0){
160368c31abSDavid du Colombier 			config->queuewrites = 1;
161368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "httpaddr") == 0){
162368c31abSDavid du Colombier 			if(config->haddr){
163368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate httpaddr lines in configuration file %s", file);
164368c31abSDavid du Colombier 				break;
165368c31abSDavid du Colombier 			}
166368c31abSDavid du Colombier 			config->haddr = estrdup(flds[1]);
167368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "webroot") == 0){
168368c31abSDavid du Colombier 			if(config->webroot){
169368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate webroot lines in configuration file %s", file);
170368c31abSDavid du Colombier 				break;
171368c31abSDavid du Colombier 			}
172368c31abSDavid du Colombier 			config->webroot = estrdup(flds[1]);
173368c31abSDavid du Colombier 		}else if(i == 2 && strcmp(flds[0], "addr") == 0){
174368c31abSDavid du Colombier 			if(config->vaddr){
175368c31abSDavid du Colombier 				seterr(EAdmin, "duplicate addr lines in configuration file %s", file);
176368c31abSDavid du Colombier 				break;
177368c31abSDavid du Colombier 			}
178368c31abSDavid du Colombier 			config->vaddr = estrdup(flds[1]);
179368c31abSDavid du Colombier 		}else{
180*cebd3b46SDavid du Colombier 			/*
181*cebd3b46SDavid du Colombier 			 * this is insanely paranoid.  a single typo should not
182*cebd3b46SDavid du Colombier 			 * prevent venti from starting.
183*cebd3b46SDavid du Colombier 			 */
184368c31abSDavid du Colombier 			seterr(EAdmin, "illegal line '%s' in configuration file %s", line, file);
185368c31abSDavid du Colombier 			break;
186368c31abSDavid du Colombier 		}
187368c31abSDavid du Colombier 		free(line);
188368c31abSDavid du Colombier 		line = nil;
189368c31abSDavid du Colombier 	}
190368c31abSDavid du Colombier 	free(line);
191368c31abSDavid du Colombier 	freeifile(&f);
192368c31abSDavid du Colombier 	if(ok < 0){
193368c31abSDavid du Colombier 		free(config->sects);
194368c31abSDavid du Colombier 		config->sects = nil;
195368c31abSDavid du Colombier 		free(config->aparts);
196368c31abSDavid du Colombier 		config->aparts = nil;
197368c31abSDavid du Colombier 	}
198368c31abSDavid du Colombier 	return ok;
199368c31abSDavid du Colombier }
200368c31abSDavid du Colombier 
201368c31abSDavid du Colombier static ISect*
configisect(char * file)202368c31abSDavid du Colombier configisect(char *file)
203368c31abSDavid du Colombier {
204368c31abSDavid du Colombier 	Part *part;
205368c31abSDavid du Colombier 	ISect *is;
206368c31abSDavid du Colombier 
207368c31abSDavid du Colombier 	if(0) fprint(2, "configure index section in %s\n", file);
208368c31abSDavid du Colombier 
209368c31abSDavid du Colombier 	part = initpart(file, ORDWR|ODIRECT);
210368c31abSDavid du Colombier 	if(part == nil)
211368c31abSDavid du Colombier 		return nil;
212368c31abSDavid du Colombier 	is = initisect(part);
213368c31abSDavid du Colombier 	if(is == nil)
214368c31abSDavid du Colombier 		werrstr("%s: %r", file);
215368c31abSDavid du Colombier 	return is;
216368c31abSDavid du Colombier }
217368c31abSDavid du Colombier 
218368c31abSDavid du Colombier static ArenaPart*
configarenas(char * file)219368c31abSDavid du Colombier configarenas(char *file)
220368c31abSDavid du Colombier {
221368c31abSDavid du Colombier 	ArenaPart *ap;
222368c31abSDavid du Colombier 	Part *part;
223368c31abSDavid du Colombier 
224368c31abSDavid du Colombier 	if(0) fprint(2, "configure arenas in %s\n", file);
225368c31abSDavid du Colombier 	part = initpart(file, ORDWR|ODIRECT);
226368c31abSDavid du Colombier 	if(part == nil)
227368c31abSDavid du Colombier 		return nil;
228368c31abSDavid du Colombier 	ap = initarenapart(part);
229368c31abSDavid du Colombier 	if(ap == nil)
230368c31abSDavid du Colombier 		werrstr("%s: %r", file);
231368c31abSDavid du Colombier 	return ap;
232368c31abSDavid du Colombier }
233368c31abSDavid du Colombier 
234368c31abSDavid du Colombier static Bloom*
configbloom(char * file)235368c31abSDavid du Colombier configbloom(char *file)
236368c31abSDavid du Colombier {
237368c31abSDavid du Colombier 	Bloom *b;
238368c31abSDavid du Colombier 	Part *part;
239368c31abSDavid du Colombier 
240368c31abSDavid du Colombier 	if(0) fprint(2, "configure bloom in %s\n", file);
241368c31abSDavid du Colombier 	part = initpart(file, ORDWR|ODIRECT);
242368c31abSDavid du Colombier 	if(part == nil)
243368c31abSDavid du Colombier 		return nil;
244368c31abSDavid du Colombier 	b = readbloom(part);
245368c31abSDavid du Colombier 	if(b == nil){
246368c31abSDavid du Colombier 		werrstr("%s: %r", file);
247368c31abSDavid du Colombier 		freepart(part);
248368c31abSDavid du Colombier 	}
249368c31abSDavid du Colombier 	return b;
250368c31abSDavid du Colombier }
251368c31abSDavid du Colombier 
252f9e1cf08SDavid du Colombier /* for OS X linker, which only resolves functions, not data */
253f9e1cf08SDavid du Colombier void
needmainindex(void)254f9e1cf08SDavid du Colombier needmainindex(void)
255f9e1cf08SDavid du Colombier {
256f9e1cf08SDavid du Colombier }
257f9e1cf08SDavid du Colombier 
258