1 a0d146ed 2005-07-12 devnull #include "stdinc.h"
2 a0d146ed 2005-07-12 devnull #include "dat.h"
3 a0d146ed 2005-07-12 devnull #include "fns.h"
4 a0d146ed 2005-07-12 devnull #include "xml.h"
6 a0d146ed 2005-07-12 devnull typedef struct HttpObj HttpObj;
7 a0d146ed 2005-07-12 devnull extern QLock memdrawlock;
11 a0d146ed 2005-07-12 devnull ObjNameSize = 64,
12 a0d146ed 2005-07-12 devnull MaxObjs = 16
15 a0d146ed 2005-07-12 devnull struct HttpObj
17 a0d146ed 2005-07-12 devnull char name[ObjNameSize];
18 a0d146ed 2005-07-12 devnull int (*f)(HConnect*);
21 a0d146ed 2005-07-12 devnull static HttpObj objs[MaxObjs];
23 a0d146ed 2005-07-12 devnull static char *webroot;
25 a0d146ed 2005-07-12 devnull static void listenproc(void*);
26 a0d146ed 2005-07-12 devnull static int estats(HConnect *c);
27 a0d146ed 2005-07-12 devnull static int dindex(HConnect *c);
28 a0d146ed 2005-07-12 devnull static int xindex(HConnect *c);
29 a0d146ed 2005-07-12 devnull static int xlog(HConnect *c);
30 a0d146ed 2005-07-12 devnull static int sindex(HConnect *c);
31 a0d146ed 2005-07-12 devnull static int hicacheflush(HConnect *c);
32 a0d146ed 2005-07-12 devnull static int hdcacheflush(HConnect *c);
33 a0d146ed 2005-07-12 devnull static int notfound(HConnect *c);
34 a0d146ed 2005-07-12 devnull static int httpdobj(char *name, int (*f)(HConnect*));
35 a0d146ed 2005-07-12 devnull static int xgraph(HConnect *c);
36 a0d146ed 2005-07-12 devnull static int xset(HConnect *c);
37 a0d146ed 2005-07-12 devnull static int fromwebdir(HConnect *c);
40 a0d146ed 2005-07-12 devnull httpdinit(char *address, char *dir)
42 a0d146ed 2005-07-12 devnull fmtinstall('D', hdatefmt);
43 a0d146ed 2005-07-12 devnull /* fmtinstall('H', httpfmt); */
44 a0d146ed 2005-07-12 devnull fmtinstall('U', hurlfmt);
46 a0d146ed 2005-07-12 devnull if(address == nil)
47 a0d146ed 2005-07-12 devnull address = "tcp!*!http";
48 a0d146ed 2005-07-12 devnull webroot = dir;
50 a0d146ed 2005-07-12 devnull httpdobj("/stats", estats);
51 a0d146ed 2005-07-12 devnull httpdobj("/index", dindex);
52 a0d146ed 2005-07-12 devnull httpdobj("/storage", sindex);
53 a0d146ed 2005-07-12 devnull httpdobj("/xindex", xindex);
54 a0d146ed 2005-07-12 devnull httpdobj("/flushicache", hicacheflush);
55 a0d146ed 2005-07-12 devnull httpdobj("/flushdcache", hdcacheflush);
56 a0d146ed 2005-07-12 devnull httpdobj("/graph/", xgraph);
57 a0d146ed 2005-07-12 devnull httpdobj("/set/", xset);
58 a0d146ed 2005-07-12 devnull httpdobj("/log", xlog);
59 a0d146ed 2005-07-12 devnull httpdobj("/log/", xlog);
61 a0d146ed 2005-07-12 devnull if(vtproc(listenproc, address) < 0)
62 a0d146ed 2005-07-12 devnull return -1;
63 a0d146ed 2005-07-12 devnull return 0;
66 a0d146ed 2005-07-12 devnull static int
67 a0d146ed 2005-07-12 devnull httpdobj(char *name, int (*f)(HConnect*))
71 a0d146ed 2005-07-12 devnull if(name == nil || strlen(name) >= ObjNameSize)
72 a0d146ed 2005-07-12 devnull return -1;
73 a0d146ed 2005-07-12 devnull for(i = 0; i < MaxObjs; i++){
74 a0d146ed 2005-07-12 devnull if(objs[i].name[0] == '\0'){
75 a0d146ed 2005-07-12 devnull strcpy(objs[i].name, name);
76 a0d146ed 2005-07-12 devnull objs[i].f = f;
77 a0d146ed 2005-07-12 devnull return 0;
79 a0d146ed 2005-07-12 devnull if(strcmp(objs[i].name, name) == 0)
80 a0d146ed 2005-07-12 devnull return -1;
82 a0d146ed 2005-07-12 devnull return -1;
85 a0d146ed 2005-07-12 devnull static HConnect*
86 a0d146ed 2005-07-12 devnull mkconnect(void)
88 a0d146ed 2005-07-12 devnull HConnect *c;
90 a0d146ed 2005-07-12 devnull c = mallocz(sizeof(HConnect), 1);
91 a0d146ed 2005-07-12 devnull if(c == nil)
92 a0d146ed 2005-07-12 devnull sysfatal("out of memory");
93 a0d146ed 2005-07-12 devnull c->replog = nil;
94 a0d146ed 2005-07-12 devnull c->hpos = c->header;
95 a0d146ed 2005-07-12 devnull c->hstop = c->header;
96 a0d146ed 2005-07-12 devnull return c;
99 a0d146ed 2005-07-12 devnull void httpproc(void*);
101 a0d146ed 2005-07-12 devnull static void
102 a0d146ed 2005-07-12 devnull listenproc(void *vaddress)
104 a0d146ed 2005-07-12 devnull HConnect *c;
105 a0d146ed 2005-07-12 devnull char *address, ndir[NETPATHLEN], dir[NETPATHLEN];
106 a0d146ed 2005-07-12 devnull int ctl, nctl, data;
108 a0d146ed 2005-07-12 devnull //sleep(1000); /* let strace find us */
110 a0d146ed 2005-07-12 devnull address = vaddress;
111 a0d146ed 2005-07-12 devnull ctl = announce(address, dir);
112 a0d146ed 2005-07-12 devnull if(ctl < 0){
113 a0d146ed 2005-07-12 devnull fprint(2, "venti: httpd can't announce on %s: %r\n", address);
117 a0d146ed 2005-07-12 devnull if(0) print("announce ctl %d dir %s\n", ctl, dir);
118 a0d146ed 2005-07-12 devnull for(;;){
120 a0d146ed 2005-07-12 devnull * wait for a call (or an error)
122 a0d146ed 2005-07-12 devnull nctl = listen(dir, ndir);
123 a0d146ed 2005-07-12 devnull if(0) print("httpd listen %d %s...\n", nctl, ndir);
124 a0d146ed 2005-07-12 devnull if(nctl < 0){
125 a0d146ed 2005-07-12 devnull fprint(2, "venti: httpd can't listen on %s: %r\n", address);
129 a0d146ed 2005-07-12 devnull data = accept(ctl, ndir);
130 a0d146ed 2005-07-12 devnull if(0) print("httpd accept %d...\n", data);
131 a0d146ed 2005-07-12 devnull if(data < 0){
132 a0d146ed 2005-07-12 devnull fprint(2, "venti: httpd accept: %r\n");
133 a0d146ed 2005-07-12 devnull close(nctl);
134 a0d146ed 2005-07-12 devnull continue;
136 a0d146ed 2005-07-12 devnull if(0) print("httpd close nctl %d\n", nctl);
137 a0d146ed 2005-07-12 devnull close(nctl);
138 a0d146ed 2005-07-12 devnull c = mkconnect();
139 a0d146ed 2005-07-12 devnull hinit(&c->hin, data, Hread);
140 a0d146ed 2005-07-12 devnull hinit(&c->hout, data, Hwrite);
141 a0d146ed 2005-07-12 devnull vtproc(httpproc, c);
146 a0d146ed 2005-07-12 devnull httpproc(void *v)
148 a0d146ed 2005-07-12 devnull HConnect *c;
149 a0d146ed 2005-07-12 devnull int ok, i, n;
151 a0d146ed 2005-07-12 devnull //sleep(1000); /* let strace find us */
154 a0d146ed 2005-07-12 devnull for(;;){
156 a0d146ed 2005-07-12 devnull * No timeout because the signal appears to hit every
157 a0d146ed 2005-07-12 devnull * proc, not just us.
159 a0d146ed 2005-07-12 devnull if(hparsereq(c, 0) < 0)
162 a0d146ed 2005-07-12 devnull for(i = 0; i < MaxObjs && objs[i].name[0]; i++){
163 a0d146ed 2005-07-12 devnull n = strlen(objs[i].name);
164 a0d146ed 2005-07-12 devnull if((objs[i].name[n-1] == '/' && strncmp(c->req.uri, objs[i].name, n) == 0)
165 a0d146ed 2005-07-12 devnull || (objs[i].name[n-1] != '/' && strcmp(c->req.uri, objs[i].name) == 0)){
166 a0d146ed 2005-07-12 devnull ok = (*objs[i].f)(c);
167 a0d146ed 2005-07-12 devnull goto found;
170 a0d146ed 2005-07-12 devnull ok = fromwebdir(c);
172 a0d146ed 2005-07-12 devnull if(c->head.closeit)
173 a0d146ed 2005-07-12 devnull ok = -1;
174 a0d146ed 2005-07-12 devnull hreqcleanup(c);
176 a0d146ed 2005-07-12 devnull if(ok < 0)
179 a0d146ed 2005-07-12 devnull hreqcleanup(c);
180 a0d146ed 2005-07-12 devnull close(c->hin.fd);
181 a0d146ed 2005-07-12 devnull free(c);
184 a0d146ed 2005-07-12 devnull static int
185 a0d146ed 2005-07-12 devnull percent(long v, long total)
187 a0d146ed 2005-07-12 devnull if(total == 0)
188 a0d146ed 2005-07-12 devnull total = 1;
189 a0d146ed 2005-07-12 devnull if(v < 1000*1000)
190 a0d146ed 2005-07-12 devnull return (v * 100) / total;
191 a0d146ed 2005-07-12 devnull total /= 100;
192 a0d146ed 2005-07-12 devnull if(total == 0)
193 a0d146ed 2005-07-12 devnull total = 1;
194 a0d146ed 2005-07-12 devnull return v / total;
197 a0d146ed 2005-07-12 devnull static int
198 a0d146ed 2005-07-12 devnull preq(HConnect *c)
200 a0d146ed 2005-07-12 devnull if(hparseheaders(c, 0) < 0)
201 a0d146ed 2005-07-12 devnull return -1;
202 a0d146ed 2005-07-12 devnull if(strcmp(c->req.meth, "GET") != 0
203 a0d146ed 2005-07-12 devnull && strcmp(c->req.meth, "HEAD") != 0)
204 a0d146ed 2005-07-12 devnull return hunallowed(c, "GET, HEAD");
205 a0d146ed 2005-07-12 devnull if(c->head.expectother || c->head.expectcont)
206 a0d146ed 2005-07-12 devnull return hfail(c, HExpectFail, nil);
207 a0d146ed 2005-07-12 devnull return 0;
210 a0d146ed 2005-07-12 devnull static int
211 a0d146ed 2005-07-12 devnull preqtype(HConnect *c, char *type)
213 a0d146ed 2005-07-12 devnull Hio *hout;
216 a0d146ed 2005-07-12 devnull r = preq(c);
217 a0d146ed 2005-07-12 devnull if(r < 0)
218 a0d146ed 2005-07-12 devnull return r;
220 a0d146ed 2005-07-12 devnull hout = &c->hout;
221 a0d146ed 2005-07-12 devnull if(c->req.vermaj){
222 a0d146ed 2005-07-12 devnull hokheaders(c);
223 a0d146ed 2005-07-12 devnull hprint(hout, "Content-type: %s\r\n", type);
224 a0d146ed 2005-07-12 devnull if(http11(c))
225 a0d146ed 2005-07-12 devnull hprint(hout, "Transfer-Encoding: chunked\r\n");
226 a0d146ed 2005-07-12 devnull hprint(hout, "\r\n");
229 a0d146ed 2005-07-12 devnull if(http11(c))
230 a0d146ed 2005-07-12 devnull hxferenc(hout, 1);
232 a0d146ed 2005-07-12 devnull c->head.closeit = 1;
233 a0d146ed 2005-07-12 devnull return 0;
236 a0d146ed 2005-07-12 devnull static int
237 a0d146ed 2005-07-12 devnull preqtext(HConnect *c)
239 a0d146ed 2005-07-12 devnull return preqtype(c, "text/plain");
242 a0d146ed 2005-07-12 devnull static int
243 a0d146ed 2005-07-12 devnull notfound(HConnect *c)
247 a0d146ed 2005-07-12 devnull r = preq(c);
248 a0d146ed 2005-07-12 devnull if(r < 0)
249 a0d146ed 2005-07-12 devnull return r;
250 a0d146ed 2005-07-12 devnull return hfail(c, HNotFound, c->req.uri);
253 a0d146ed 2005-07-12 devnull struct {
254 a0d146ed 2005-07-12 devnull char *ext;
255 a0d146ed 2005-07-12 devnull char *type;
256 a0d146ed 2005-07-12 devnull } exttab[] = {
257 a0d146ed 2005-07-12 devnull ".html", "text/html",
258 a0d146ed 2005-07-12 devnull ".txt", "text/plain",
259 a0d146ed 2005-07-12 devnull ".xml", "text/xml",
260 a0d146ed 2005-07-12 devnull ".png", "image/png",
261 a0d146ed 2005-07-12 devnull ".gif", "image/gif",
265 a0d146ed 2005-07-12 devnull static int
266 a0d146ed 2005-07-12 devnull fromwebdir(HConnect *c)
268 a0d146ed 2005-07-12 devnull char buf[4096], *p, *ext, *type;
269 a0d146ed 2005-07-12 devnull int i, fd, n, defaulted;
272 a0d146ed 2005-07-12 devnull if(webroot == nil || strstr(c->req.uri, ".."))
273 a0d146ed 2005-07-12 devnull return notfound(c);
274 a0d146ed 2005-07-12 devnull snprint(buf, sizeof buf-20, "%s/%s", webroot, c->req.uri+1);
275 a0d146ed 2005-07-12 devnull defaulted = 0;
277 a0d146ed 2005-07-12 devnull if((fd = open(buf, OREAD)) < 0)
278 a0d146ed 2005-07-12 devnull return notfound(c);
279 a0d146ed 2005-07-12 devnull d = dirfstat(fd);
280 a0d146ed 2005-07-12 devnull if(d == nil){
281 a0d146ed 2005-07-12 devnull close(fd);
282 a0d146ed 2005-07-12 devnull return notfound(c);
284 a0d146ed 2005-07-12 devnull if(d->mode&DMDIR){
285 a0d146ed 2005-07-12 devnull if(!defaulted){
286 a0d146ed 2005-07-12 devnull defaulted = 1;
287 a0d146ed 2005-07-12 devnull strcat(buf, "/index.html");
288 a0d146ed 2005-07-12 devnull free(d);
289 a0d146ed 2005-07-12 devnull close(fd);
290 a0d146ed 2005-07-12 devnull goto reopen;
292 a0d146ed 2005-07-12 devnull free(d);
293 a0d146ed 2005-07-12 devnull return notfound(c);
295 a0d146ed 2005-07-12 devnull free(d);
296 a0d146ed 2005-07-12 devnull p = buf+strlen(buf);
297 a0d146ed 2005-07-12 devnull type = "application/octet-stream";
298 a0d146ed 2005-07-12 devnull for(i=0; exttab[i].ext; i++){
299 a0d146ed 2005-07-12 devnull ext = exttab[i].ext;
300 a0d146ed 2005-07-12 devnull if(p-strlen(ext) >= buf && strcmp(p-strlen(ext), ext) == 0){
301 a0d146ed 2005-07-12 devnull type = exttab[i].type;
305 a0d146ed 2005-07-12 devnull if(preqtype(c, type) < 0){
306 a0d146ed 2005-07-12 devnull close(fd);
307 a0d146ed 2005-07-12 devnull return 0;
309 a0d146ed 2005-07-12 devnull while((n = read(fd, buf, sizeof buf)) > 0)
310 a0d146ed 2005-07-12 devnull if(hwrite(&c->hout, buf, n) < 0)
312 a0d146ed 2005-07-12 devnull close(fd);
313 a0d146ed 2005-07-12 devnull hflush(&c->hout);
314 a0d146ed 2005-07-12 devnull return 0;
317 a0d146ed 2005-07-12 devnull static struct
319 a0d146ed 2005-07-12 devnull char *name;
321 a0d146ed 2005-07-12 devnull } namedints[] =
323 a0d146ed 2005-07-12 devnull "compress", &compressblocks,
324 a0d146ed 2005-07-12 devnull "devnull", &writestodevnull,
325 a0d146ed 2005-07-12 devnull "logging", &ventilogging,
326 a0d146ed 2005-07-12 devnull "stats", &collectstats,
327 a0d146ed 2005-07-12 devnull "icachesleeptime", &icachesleeptime,
328 a0d146ed 2005-07-12 devnull "arenasumsleeptime", &arenasumsleeptime,
332 a0d146ed 2005-07-12 devnull static int
333 a0d146ed 2005-07-12 devnull xset(HConnect *c)
335 a0d146ed 2005-07-12 devnull int i, nf, r;
336 a0d146ed 2005-07-12 devnull char *f[10], *s;
338 a0d146ed 2005-07-12 devnull s = estrdup(c->req.uri);
339 a0d146ed 2005-07-12 devnull nf = getfields(s+strlen("/set/"), f, nelem(f), 1, "/");
341 a0d146ed 2005-07-12 devnull if(nf < 1)
342 a0d146ed 2005-07-12 devnull return notfound(c);
343 a0d146ed 2005-07-12 devnull for(i=0; namedints[i].name; i++){
344 a0d146ed 2005-07-12 devnull if(strcmp(f[0], namedints[i].name) == 0){
345 a0d146ed 2005-07-12 devnull if(nf >= 2)
346 a0d146ed 2005-07-12 devnull *namedints[i].p = atoi(f[1]);
347 a0d146ed 2005-07-12 devnull r = preqtext(c);
348 a0d146ed 2005-07-12 devnull if(r < 0)
349 a0d146ed 2005-07-12 devnull return r;
350 a0d146ed 2005-07-12 devnull hprint(&c->hout, "%s = %d\n", f[0], *namedints[i].p);
351 a0d146ed 2005-07-12 devnull hflush(&c->hout);
352 a0d146ed 2005-07-12 devnull return 0;
355 a0d146ed 2005-07-12 devnull return notfound(c);
358 a0d146ed 2005-07-12 devnull static int
359 a0d146ed 2005-07-12 devnull estats(HConnect *c)
361 a0d146ed 2005-07-12 devnull Hio *hout;
364 a0d146ed 2005-07-12 devnull r = preqtext(c);
365 a0d146ed 2005-07-12 devnull if(r < 0)
366 a0d146ed 2005-07-12 devnull return r;
369 a0d146ed 2005-07-12 devnull hout = &c->hout;
371 a0d146ed 2005-07-12 devnull hprint(hout, "lump writes=%,ld\n", stats.lumpwrites);
372 a0d146ed 2005-07-12 devnull hprint(hout, "lump reads=%,ld\n", stats.lumpreads);
373 a0d146ed 2005-07-12 devnull hprint(hout, "lump cache read hits=%,ld\n", stats.lumphit);
374 a0d146ed 2005-07-12 devnull hprint(hout, "lump cache read misses=%,ld\n", stats.lumpmiss);
376 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk writes=%,ld\n", stats.clumpwrites);
377 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes written=%,lld\n", stats.clumpbwrites);
378 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes compressed=%,lld\n", stats.clumpbcomp);
379 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk reads=%,ld\n", stats.clumpreads);
380 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes read=%,lld\n", stats.clumpbreads);
381 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes uncompressed=%,lld\n", stats.clumpbuncomp);
383 a0d146ed 2005-07-12 devnull hprint(hout, "clump directory disk writes=%,ld\n", stats.ciwrites);
384 a0d146ed 2005-07-12 devnull hprint(hout, "clump directory disk reads=%,ld\n", stats.cireads);
386 a0d146ed 2005-07-12 devnull hprint(hout, "index disk writes=%,ld\n", stats.indexwrites);
387 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads=%,ld\n", stats.indexreads);
388 a0d146ed 2005-07-12 devnull hprint(hout, "index disk bloom filter hits=%,ld %d%% falsemisses=%,ld %d%%\n",
389 a0d146ed 2005-07-12 devnull stats.indexbloomhits,
390 a0d146ed 2005-07-12 devnull percent(stats.indexbloomhits, stats.indexreads),
391 a0d146ed 2005-07-12 devnull stats.indexbloomfalsemisses,
392 a0d146ed 2005-07-12 devnull percent(stats.indexbloomfalsemisses, stats.indexreads));
393 a0d146ed 2005-07-12 devnull hprint(hout, "bloom filter bits=%,ld of %,ld %d%%\n",
394 a0d146ed 2005-07-12 devnull stats.bloomones, stats.bloombits, percent(stats.bloomones, stats.bloombits));
395 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads for modify=%,ld\n", stats.indexwreads);
396 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads for allocation=%,ld\n", stats.indexareads);
397 a0d146ed 2005-07-12 devnull hprint(hout, "index block splits=%,ld\n", stats.indexsplits);
399 a0d146ed 2005-07-12 devnull hprint(hout, "index cache lookups=%,ld\n", stats.iclookups);
400 a0d146ed 2005-07-12 devnull hprint(hout, "index cache hits=%,ld %d%%\n", stats.ichits,
401 a0d146ed 2005-07-12 devnull percent(stats.ichits, stats.iclookups));
402 a0d146ed 2005-07-12 devnull hprint(hout, "index cache fills=%,ld %d%%\n", stats.icfills,
403 a0d146ed 2005-07-12 devnull percent(stats.icfills, stats.iclookups));
404 a0d146ed 2005-07-12 devnull hprint(hout, "index cache inserts=%,ld\n", stats.icinserts);
406 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache hits=%,ld\n", stats.pchit);
407 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache misses=%,ld\n", stats.pcmiss);
408 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache reads=%,ld\n", stats.pcreads);
409 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache bytes read=%,lld\n", stats.pcbreads);
411 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache writes=%,ld\n", stats.dirtydblocks);
412 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache writes absorbed=%,ld %d%%\n", stats.absorbedwrites,
413 a0d146ed 2005-07-12 devnull percent(stats.absorbedwrites, stats.dirtydblocks));
415 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache flushes=%,ld\n", stats.dcacheflushes);
416 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache flush writes=%,ld (%,ld per flush)\n",
417 a0d146ed 2005-07-12 devnull stats.dcacheflushwrites,
418 a0d146ed 2005-07-12 devnull stats.dcacheflushwrites/(stats.dcacheflushes ? stats.dcacheflushes : 1));
420 a0d146ed 2005-07-12 devnull hprint(hout, "disk writes=%,ld\n", stats.diskwrites);
421 a0d146ed 2005-07-12 devnull hprint(hout, "disk bytes written=%,lld\n", stats.diskbwrites);
422 a0d146ed 2005-07-12 devnull hprint(hout, "disk reads=%,ld\n", stats.diskreads);
423 a0d146ed 2005-07-12 devnull hprint(hout, "disk bytes read=%,lld\n", stats.diskbreads);
426 a0d146ed 2005-07-12 devnull hflush(hout);
427 a0d146ed 2005-07-12 devnull return 0;
430 a0d146ed 2005-07-12 devnull static int
431 a0d146ed 2005-07-12 devnull sindex(HConnect *c)
433 a0d146ed 2005-07-12 devnull Hio *hout;
434 a0d146ed 2005-07-12 devnull Index *ix;
435 a0d146ed 2005-07-12 devnull Arena *arena;
436 a0d146ed 2005-07-12 devnull vlong clumps, cclumps, uncsize, used, size;
437 a0d146ed 2005-07-12 devnull int i, r, active;
439 a0d146ed 2005-07-12 devnull r = preqtext(c);
440 a0d146ed 2005-07-12 devnull if(r < 0)
441 a0d146ed 2005-07-12 devnull return r;
442 a0d146ed 2005-07-12 devnull hout = &c->hout;
444 a0d146ed 2005-07-12 devnull ix = mainindex;
446 a0d146ed 2005-07-12 devnull hprint(hout, "index=%s\n", ix->name);
448 a0d146ed 2005-07-12 devnull active = 0;
449 a0d146ed 2005-07-12 devnull clumps = 0;
450 a0d146ed 2005-07-12 devnull cclumps = 0;
451 a0d146ed 2005-07-12 devnull uncsize = 0;
452 a0d146ed 2005-07-12 devnull used = 0;
453 a0d146ed 2005-07-12 devnull size = 0;
454 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->narenas; i++){
455 a0d146ed 2005-07-12 devnull arena = ix->arenas[i];
456 a0d146ed 2005-07-12 devnull if(arena != nil && arena->memstats.clumps != 0){
457 a0d146ed 2005-07-12 devnull active++;
458 a0d146ed 2005-07-12 devnull clumps += arena->memstats.clumps;
459 a0d146ed 2005-07-12 devnull cclumps += arena->memstats.cclumps;
460 a0d146ed 2005-07-12 devnull uncsize += arena->memstats.uncsize;
461 a0d146ed 2005-07-12 devnull used += arena->memstats.used;
463 a0d146ed 2005-07-12 devnull size += arena->size;
465 a0d146ed 2005-07-12 devnull hprint(hout, "total arenas=%,d active=%,d\n", ix->narenas, active);
466 a0d146ed 2005-07-12 devnull hprint(hout, "total space=%,lld used=%,lld\n", size, used + clumps * ClumpInfoSize);
467 a0d146ed 2005-07-12 devnull hprint(hout, "clumps=%,lld compressed clumps=%,lld data=%,lld compressed data=%,lld\n",
468 a0d146ed 2005-07-12 devnull clumps, cclumps, uncsize, used - clumps * ClumpSize);
469 a0d146ed 2005-07-12 devnull hflush(hout);
470 a0d146ed 2005-07-12 devnull return 0;
473 a0d146ed 2005-07-12 devnull static void
474 a0d146ed 2005-07-12 devnull darena(Hio *hout, Arena *arena)
476 a0d146ed 2005-07-12 devnull hprint(hout, "arena='%s' on %s at [%lld,%lld)\n\tversion=%d created=%d modified=%d",
477 a0d146ed 2005-07-12 devnull arena->name, arena->part->name, arena->base, arena->base + arena->size + 2 * arena->blocksize,
478 a0d146ed 2005-07-12 devnull arena->version, arena->ctime, arena->wtime);
479 a0d146ed 2005-07-12 devnull if(arena->memstats.sealed)
480 a0d146ed 2005-07-12 devnull hprint(hout, " mem=sealed");
481 a0d146ed 2005-07-12 devnull if(arena->diskstats.sealed)
482 a0d146ed 2005-07-12 devnull hprint(hout, " disk=sealed");
483 a0d146ed 2005-07-12 devnull hprint(hout, "\n");
484 a0d146ed 2005-07-12 devnull if(scorecmp(zeroscore, arena->score) != 0)
485 a0d146ed 2005-07-12 devnull hprint(hout, "\tscore=%V\n", arena->score);
487 a0d146ed 2005-07-12 devnull hprint(hout, "\tmem: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n",
488 a0d146ed 2005-07-12 devnull arena->memstats.clumps, arena->memstats.cclumps, arena->memstats.uncsize,
489 a0d146ed 2005-07-12 devnull arena->memstats.used - arena->memstats.clumps * ClumpSize,
490 a0d146ed 2005-07-12 devnull arena->memstats.used + arena->memstats.clumps * ClumpInfoSize);
491 a0d146ed 2005-07-12 devnull hprint(hout, "\tdisk: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n",
492 a0d146ed 2005-07-12 devnull arena->diskstats.clumps, arena->diskstats.cclumps, arena->diskstats.uncsize,
493 a0d146ed 2005-07-12 devnull arena->diskstats.used - arena->diskstats.clumps * ClumpSize,
494 a0d146ed 2005-07-12 devnull arena->diskstats.used + arena->diskstats.clumps * ClumpInfoSize);
497 a0d146ed 2005-07-12 devnull static int
498 a0d146ed 2005-07-12 devnull hicacheflush(HConnect *c)
500 a0d146ed 2005-07-12 devnull Hio *hout;
503 a0d146ed 2005-07-12 devnull r = preqtext(c);
504 a0d146ed 2005-07-12 devnull if(r < 0)
505 a0d146ed 2005-07-12 devnull return r;
506 a0d146ed 2005-07-12 devnull hout = &c->hout;
508 a0d146ed 2005-07-12 devnull flushicache();
509 a0d146ed 2005-07-12 devnull hprint(hout, "flushed icache\n");
510 a0d146ed 2005-07-12 devnull hflush(hout);
511 a0d146ed 2005-07-12 devnull return 0;
514 a0d146ed 2005-07-12 devnull static int
515 a0d146ed 2005-07-12 devnull hdcacheflush(HConnect *c)
517 a0d146ed 2005-07-12 devnull Hio *hout;
520 a0d146ed 2005-07-12 devnull r = preqtext(c);
521 a0d146ed 2005-07-12 devnull if(r < 0)
522 a0d146ed 2005-07-12 devnull return r;
523 a0d146ed 2005-07-12 devnull hout = &c->hout;
525 a0d146ed 2005-07-12 devnull flushdcache();
526 a0d146ed 2005-07-12 devnull hprint(hout, "flushed dcache\n");
527 a0d146ed 2005-07-12 devnull hflush(hout);
528 a0d146ed 2005-07-12 devnull return 0;
531 a0d146ed 2005-07-12 devnull static int
532 a0d146ed 2005-07-12 devnull dindex(HConnect *c)
534 a0d146ed 2005-07-12 devnull Hio *hout;
535 a0d146ed 2005-07-12 devnull Index *ix;
536 a0d146ed 2005-07-12 devnull int i, r;
538 a0d146ed 2005-07-12 devnull r = preqtext(c);
539 a0d146ed 2005-07-12 devnull if(r < 0)
540 a0d146ed 2005-07-12 devnull return r;
541 a0d146ed 2005-07-12 devnull hout = &c->hout;
544 a0d146ed 2005-07-12 devnull ix = mainindex;
545 a0d146ed 2005-07-12 devnull hprint(hout, "index=%s version=%d blocksize=%d tabsize=%d\n",
546 a0d146ed 2005-07-12 devnull ix->name, ix->version, ix->blocksize, ix->tabsize);
547 a0d146ed 2005-07-12 devnull hprint(hout, "\tbuckets=%d div=%d\n", ix->buckets, ix->div);
548 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->nsects; i++)
549 a0d146ed 2005-07-12 devnull hprint(hout, "\tsect=%s for buckets [%lld,%lld) buckmax=%d\n", ix->smap[i].name, ix->smap[i].start, ix->smap[i].stop, ix->sects[i]->buckmax);
550 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->narenas; i++){
551 a0d146ed 2005-07-12 devnull if(ix->arenas[i] != nil && ix->arenas[i]->memstats.clumps != 0){
552 a0d146ed 2005-07-12 devnull hprint(hout, "arena=%s at index [%lld,%lld)\n\t", ix->amap[i].name, ix->amap[i].start, ix->amap[i].stop);
553 a0d146ed 2005-07-12 devnull darena(hout, ix->arenas[i]);
556 a0d146ed 2005-07-12 devnull hflush(hout);
557 a0d146ed 2005-07-12 devnull return 0;
560 a0d146ed 2005-07-12 devnull typedef struct Arg Arg;
561 a0d146ed 2005-07-12 devnull struct Arg
563 a0d146ed 2005-07-12 devnull int index;
564 a0d146ed 2005-07-12 devnull int index2;
567 a0d146ed 2005-07-12 devnull static long
568 a0d146ed 2005-07-12 devnull rawgraph(Stats *s, Stats *t, void *va)
573 a0d146ed 2005-07-12 devnull return t->n[a->index];
576 a0d146ed 2005-07-12 devnull static long
577 a0d146ed 2005-07-12 devnull diffgraph(Stats *s, Stats *t, void *va)
582 a0d146ed 2005-07-12 devnull return t->n[a->index] - s->n[a->index];
585 a0d146ed 2005-07-12 devnull static long
586 a0d146ed 2005-07-12 devnull pctgraph(Stats *s, Stats *t, void *va)
591 a0d146ed 2005-07-12 devnull return percent(t->n[a->index], t->n[a->index2]);
594 a0d146ed 2005-07-12 devnull static long
595 a0d146ed 2005-07-12 devnull pctdiffgraph(Stats *s, Stats *t, void *va)
600 a0d146ed 2005-07-12 devnull return percent(t->n[a->index]-s->n[a->index], t->n[a->index2]-s->n[a->index2]);
603 a0d146ed 2005-07-12 devnull static long
604 a0d146ed 2005-07-12 devnull netbw(Stats *s)
606 a0d146ed 2005-07-12 devnull ulong *n;
608 a0d146ed 2005-07-12 devnull n = s->n;
609 a0d146ed 2005-07-12 devnull return n[StatRpcReadBytes]+n[StatRpcWriteBytes]; /* not exactly right */
612 a0d146ed 2005-07-12 devnull static long
613 a0d146ed 2005-07-12 devnull diskbw(Stats *s)
615 a0d146ed 2005-07-12 devnull ulong *n;
617 a0d146ed 2005-07-12 devnull n = s->n;
618 a0d146ed 2005-07-12 devnull return n[StatApartReadBytes]+n[StatApartWriteBytes]
619 a0d146ed 2005-07-12 devnull + n[StatIsectReadBytes]+n[StatIsectWriteBytes]
620 a0d146ed 2005-07-12 devnull + n[StatSumReadBytes];
623 a0d146ed 2005-07-12 devnull static long
624 a0d146ed 2005-07-12 devnull iobw(Stats *s)
626 a0d146ed 2005-07-12 devnull return netbw(s)+diskbw(s);
629 a0d146ed 2005-07-12 devnull static long
630 a0d146ed 2005-07-12 devnull diskgraph(Stats *s, Stats *t, void *va)
632 a0d146ed 2005-07-12 devnull USED(va);
633 a0d146ed 2005-07-12 devnull return diskbw(t)-diskbw(s);
636 a0d146ed 2005-07-12 devnull static long
637 a0d146ed 2005-07-12 devnull netgraph(Stats *s, Stats *t, void *va)
639 a0d146ed 2005-07-12 devnull USED(va);
640 a0d146ed 2005-07-12 devnull return netbw(t)-netbw(s);
643 a0d146ed 2005-07-12 devnull static long
644 a0d146ed 2005-07-12 devnull iograph(Stats *s, Stats *t, void *va)
646 a0d146ed 2005-07-12 devnull USED(va);
647 a0d146ed 2005-07-12 devnull return iobw(t)-iobw(s);
651 a0d146ed 2005-07-12 devnull static char* graphname[] =
653 a0d146ed 2005-07-12 devnull "rpctotal",
654 a0d146ed 2005-07-12 devnull "rpcread",
655 a0d146ed 2005-07-12 devnull "rpcreadok",
656 a0d146ed 2005-07-12 devnull "rpcreadfail",
657 a0d146ed 2005-07-12 devnull "rpcreadbyte",
658 a0d146ed 2005-07-12 devnull "rpcreadtime",
659 a0d146ed 2005-07-12 devnull "rpcreadcached",
660 a0d146ed 2005-07-12 devnull "rpcreadcachedtime",
661 a0d146ed 2005-07-12 devnull "rpcreaduncached",
662 a0d146ed 2005-07-12 devnull "rpcreaduncachedtime",
663 a0d146ed 2005-07-12 devnull "rpcwrite",
664 a0d146ed 2005-07-12 devnull "rpcwritenew",
665 a0d146ed 2005-07-12 devnull "rpcwriteold",
666 a0d146ed 2005-07-12 devnull "rpcwritefail",
667 a0d146ed 2005-07-12 devnull "rpcwritebyte",
668 a0d146ed 2005-07-12 devnull "rpcwritetime",
669 a0d146ed 2005-07-12 devnull "rpcwritenewtime",
670 a0d146ed 2005-07-12 devnull "rpcwriteoldtime",
672 a0d146ed 2005-07-12 devnull "lcachehit",
673 a0d146ed 2005-07-12 devnull "lcachemiss",
674 a0d146ed 2005-07-12 devnull "lcachelookup",
675 a0d146ed 2005-07-12 devnull "lcachewrite",
676 a0d146ed 2005-07-12 devnull "lcachesize",
677 a0d146ed 2005-07-12 devnull "lcachestall",
678 a0d146ed 2005-07-12 devnull "lcachelookuptime",
680 a0d146ed 2005-07-12 devnull "dcachehit",
681 a0d146ed 2005-07-12 devnull "dcachemiss",
682 a0d146ed 2005-07-12 devnull "dcachelookup",
683 a0d146ed 2005-07-12 devnull "dcacheread",
684 a0d146ed 2005-07-12 devnull "dcachewrite",
685 a0d146ed 2005-07-12 devnull "dcachedirty",
686 a0d146ed 2005-07-12 devnull "dcachesize",
687 a0d146ed 2005-07-12 devnull "dcacheflush",
688 a0d146ed 2005-07-12 devnull "dcachestall",
689 a0d146ed 2005-07-12 devnull "dcachelookuptime",
691 a0d146ed 2005-07-12 devnull "dblockstall",
692 a0d146ed 2005-07-12 devnull "lumpstall",
694 a0d146ed 2005-07-12 devnull "icachehit",
695 a0d146ed 2005-07-12 devnull "icachemiss",
696 a0d146ed 2005-07-12 devnull "icachelookup",
697 a0d146ed 2005-07-12 devnull "icachewrite",
698 a0d146ed 2005-07-12 devnull "icachefill",
699 a0d146ed 2005-07-12 devnull "icacheprefetch",
700 a0d146ed 2005-07-12 devnull "icachedirty",
701 a0d146ed 2005-07-12 devnull "icachesize",
702 a0d146ed 2005-07-12 devnull "icacheflush",
703 a0d146ed 2005-07-12 devnull "icachestall",
704 a0d146ed 2005-07-12 devnull "icachelookuptime",
706 a0d146ed 2005-07-12 devnull "bloomhit",
707 a0d146ed 2005-07-12 devnull "bloommiss",
708 a0d146ed 2005-07-12 devnull "bloomfalsemiss",
709 a0d146ed 2005-07-12 devnull "bloomlookup",
710 a0d146ed 2005-07-12 devnull "bloomones",
711 a0d146ed 2005-07-12 devnull "bloombits",
712 a0d146ed 2005-07-12 devnull "bloomlookuptime",
714 a0d146ed 2005-07-12 devnull "apartread",
715 a0d146ed 2005-07-12 devnull "apartreadbyte",
716 a0d146ed 2005-07-12 devnull "apartwrite",
717 a0d146ed 2005-07-12 devnull "apartwritebyte",
719 a0d146ed 2005-07-12 devnull "isectread",
720 a0d146ed 2005-07-12 devnull "isectreadbyte",
721 a0d146ed 2005-07-12 devnull "isectwrite",
722 a0d146ed 2005-07-12 devnull "isectwritebyte",
724 a0d146ed 2005-07-12 devnull "sumread",
725 a0d146ed 2005-07-12 devnull "sumreadbyte",
728 a0d146ed 2005-07-12 devnull static int
729 a0d146ed 2005-07-12 devnull findname(char *s)
733 a0d146ed 2005-07-12 devnull for(i=0; i<nelem(graphname); i++)
734 a0d146ed 2005-07-12 devnull if(strcmp(graphname[i], s) == 0)
735 a0d146ed 2005-07-12 devnull return i;
736 a0d146ed 2005-07-12 devnull fprint(2, "no name '%s'\n", s);
737 a0d146ed 2005-07-12 devnull return -1;
740 a0d146ed 2005-07-12 devnull static void
741 a0d146ed 2005-07-12 devnull dotextbin(Hio *io, Graph *g)
743 a0d146ed 2005-07-12 devnull int i, nbin;
744 a0d146ed 2005-07-12 devnull Statbin *b, bin[2000]; /* 32 kB, but whack is worse */
746 a0d146ed 2005-07-12 devnull needstack(8192); /* double check that bin didn't kill us */
747 a0d146ed 2005-07-12 devnull nbin = 100;
748 a0d146ed 2005-07-12 devnull binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);
750 a0d146ed 2005-07-12 devnull hprint(io, "stats\n\n");
751 a0d146ed 2005-07-12 devnull for(i=0; i<nbin; i++){
752 a0d146ed 2005-07-12 devnull b = &bin[i];
753 a0d146ed 2005-07-12 devnull hprint(io, "%d: nsamp=%d min=%d max=%d avg=%d\n",
754 a0d146ed 2005-07-12 devnull i, b->nsamp, b->min, b->max, b->avg);
758 a0d146ed 2005-07-12 devnull static int
759 a0d146ed 2005-07-12 devnull xgraph(HConnect *c)
761 a0d146ed 2005-07-12 devnull char *f[20], *s;
762 a0d146ed 2005-07-12 devnull Hio *hout;
763 a0d146ed 2005-07-12 devnull Memimage *m;
764 a0d146ed 2005-07-12 devnull int i, nf, dotext;
765 a0d146ed 2005-07-12 devnull Graph g;
766 a0d146ed 2005-07-12 devnull Arg arg;
768 a0d146ed 2005-07-12 devnull s = estrdup(c->req.uri);
769 a0d146ed 2005-07-12 devnull if(0) fprint(2, "graph %s\n" ,s);
770 a0d146ed 2005-07-12 devnull memset(&g, 0, sizeof g);
771 a0d146ed 2005-07-12 devnull nf = getfields(s+strlen("/graph/"), f, nelem(f), 1, "/");
772 a0d146ed 2005-07-12 devnull if(nf < 1)
773 a0d146ed 2005-07-12 devnull goto notfound;
774 a0d146ed 2005-07-12 devnull if((arg.index = findname(f[0])) == -1 && strcmp(f[0], "*") != 0)
775 a0d146ed 2005-07-12 devnull goto notfound;
776 a0d146ed 2005-07-12 devnull g.arg = &arg;
777 a0d146ed 2005-07-12 devnull g.t0 = -120;
778 a0d146ed 2005-07-12 devnull g.t1 = 0;
779 a0d146ed 2005-07-12 devnull g.min = -1;
780 a0d146ed 2005-07-12 devnull g.max = -1;
781 a0d146ed 2005-07-12 devnull g.fn = rawgraph;
782 a0d146ed 2005-07-12 devnull g.wid = -1;
783 a0d146ed 2005-07-12 devnull g.ht = -1;
784 a0d146ed 2005-07-12 devnull dotext = 0;
785 a0d146ed 2005-07-12 devnull g.fill = -1;
786 a0d146ed 2005-07-12 devnull for(i=1; i<nf; i++){
787 a0d146ed 2005-07-12 devnull if(strncmp(f[i], "t0=", 3) == 0)
788 a0d146ed 2005-07-12 devnull g.t0 = atoi(f[i]+3);
789 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "t1=", 3) == 0)
790 a0d146ed 2005-07-12 devnull g.t1 = atoi(f[i]+3);
791 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "min=", 4) == 0)
792 a0d146ed 2005-07-12 devnull g.min = atoi(f[i]+4);
793 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "max=", 4) == 0)
794 a0d146ed 2005-07-12 devnull g.max = atoi(f[i]+4);
795 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "pct=", 4) == 0){
796 a0d146ed 2005-07-12 devnull if((arg.index2 = findname(f[i]+4)) == -1)
797 a0d146ed 2005-07-12 devnull goto notfound;
798 a0d146ed 2005-07-12 devnull g.fn = pctgraph;
799 a0d146ed 2005-07-12 devnull g.min = 0;
800 a0d146ed 2005-07-12 devnull g.max = 100;
801 a0d146ed 2005-07-12 devnull }else if(strncmp(f[i], "pctdiff=", 8) == 0){
802 a0d146ed 2005-07-12 devnull if((arg.index2 = findname(f[i]+8)) == -1)
803 a0d146ed 2005-07-12 devnull goto notfound;
804 a0d146ed 2005-07-12 devnull g.fn = pctdiffgraph;
805 a0d146ed 2005-07-12 devnull g.min = 0;
806 a0d146ed 2005-07-12 devnull g.max = 100;
807 a0d146ed 2005-07-12 devnull }else if(strcmp(f[i], "diff") == 0)
808 a0d146ed 2005-07-12 devnull g.fn = diffgraph;
809 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "text") == 0)
810 a0d146ed 2005-07-12 devnull dotext = 1;
811 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "wid=", 4) == 0)
812 a0d146ed 2005-07-12 devnull g.wid = atoi(f[i]+4);
813 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "ht=", 3) == 0)
814 a0d146ed 2005-07-12 devnull g.ht = atoi(f[i]+3);
815 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "fill=", 5) == 0)
816 a0d146ed 2005-07-12 devnull g.fill = atoi(f[i]+5);
817 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "diskbw") == 0)
818 a0d146ed 2005-07-12 devnull g.fn = diskgraph;
819 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "iobw") == 0)
820 a0d146ed 2005-07-12 devnull g.fn = iograph;
821 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "netbw") == 0)
822 a0d146ed 2005-07-12 devnull g.fn = netgraph;
824 a0d146ed 2005-07-12 devnull if(dotext){
825 a0d146ed 2005-07-12 devnull preqtype(c, "text/plain");
826 a0d146ed 2005-07-12 devnull dotextbin(&c->hout, &g);
827 a0d146ed 2005-07-12 devnull hflush(&c->hout);
828 a0d146ed 2005-07-12 devnull return 0;
831 a0d146ed 2005-07-12 devnull m = statgraph(&g);
832 a0d146ed 2005-07-12 devnull if(m == nil)
833 a0d146ed 2005-07-12 devnull goto notfound;
835 a0d146ed 2005-07-12 devnull if(preqtype(c, "image/png") < 0)
836 a0d146ed 2005-07-12 devnull return -1;
837 a0d146ed 2005-07-12 devnull hout = &c->hout;
838 a0d146ed 2005-07-12 devnull writepng(hout, m);
839 a0d146ed 2005-07-12 devnull qlock(&memdrawlock);
840 a0d146ed 2005-07-12 devnull freememimage(m);
841 a0d146ed 2005-07-12 devnull qunlock(&memdrawlock);
842 a0d146ed 2005-07-12 devnull hflush(hout);
843 a0d146ed 2005-07-12 devnull free(s);
844 a0d146ed 2005-07-12 devnull return 0;
846 a0d146ed 2005-07-12 devnull notfound:
847 a0d146ed 2005-07-12 devnull free(s);
848 a0d146ed 2005-07-12 devnull return notfound(c);
851 a0d146ed 2005-07-12 devnull static int
852 a0d146ed 2005-07-12 devnull xloglist(HConnect *c)
854 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/html") < 0)
855 a0d146ed 2005-07-12 devnull return -1;
856 a0d146ed 2005-07-12 devnull vtloghlist(&c->hout);
857 a0d146ed 2005-07-12 devnull hflush(&c->hout);
858 a0d146ed 2005-07-12 devnull return 0;
861 a0d146ed 2005-07-12 devnull static int
862 a0d146ed 2005-07-12 devnull xlog(HConnect *c)
864 a0d146ed 2005-07-12 devnull char *name;
865 a0d146ed 2005-07-12 devnull VtLog *l;
867 a0d146ed 2005-07-12 devnull if(strcmp(c->req.uri, "/log") == 0 || strcmp(c->req.uri, "/log/") == 0)
868 a0d146ed 2005-07-12 devnull return xloglist(c);
869 a0d146ed 2005-07-12 devnull if(strncmp(c->req.uri, "/log/", 5) != 0)
870 a0d146ed 2005-07-12 devnull return notfound(c);
871 a0d146ed 2005-07-12 devnull name = c->req.uri + strlen("/log/");
872 a0d146ed 2005-07-12 devnull l = vtlogopen(name, 0);
873 a0d146ed 2005-07-12 devnull if(l == nil)
874 a0d146ed 2005-07-12 devnull return notfound(c);
875 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/html") < 0){
876 a0d146ed 2005-07-12 devnull vtlogclose(l);
877 a0d146ed 2005-07-12 devnull return -1;
879 a0d146ed 2005-07-12 devnull vtloghdump(&c->hout, l);
880 a0d146ed 2005-07-12 devnull vtlogclose(l);
881 a0d146ed 2005-07-12 devnull hflush(&c->hout);
882 a0d146ed 2005-07-12 devnull return 0;
885 a0d146ed 2005-07-12 devnull static int
886 a0d146ed 2005-07-12 devnull xindex(HConnect *c)
888 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/xml") < 0)
889 a0d146ed 2005-07-12 devnull return -1;
890 a0d146ed 2005-07-12 devnull xmlindex(&c->hout, mainindex, "index", 0);
891 a0d146ed 2005-07-12 devnull hflush(&c->hout);
892 a0d146ed 2005-07-12 devnull return 0;
896 a0d146ed 2005-07-12 devnull xmlindent(Hio *hout, int indent)
900 a0d146ed 2005-07-12 devnull for(i = 0; i < indent; i++)
901 a0d146ed 2005-07-12 devnull hputc(hout, '\t');
905 a0d146ed 2005-07-12 devnull xmlaname(Hio *hout, char *v, char *tag)
907 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%s\"", tag, v);
911 a0d146ed 2005-07-12 devnull xmlscore(Hio *hout, u8int *v, char *tag)
913 a0d146ed 2005-07-12 devnull if(scorecmp(zeroscore, v) == 0)
915 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%V\"", tag, v);
919 a0d146ed 2005-07-12 devnull xmlsealed(Hio *hout, int v, char *tag)
923 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"yes\"", tag);
927 a0d146ed 2005-07-12 devnull xmlu32int(Hio *hout, u32int v, char *tag)
929 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%ud\"", tag, v);
933 a0d146ed 2005-07-12 devnull xmlu64int(Hio *hout, u64int v, char *tag)
935 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%llud\"", tag, v);
939 a0d146ed 2005-07-12 devnull vtloghdump(Hio *h, VtLog *l)
942 a0d146ed 2005-07-12 devnull VtLogChunk *c;
943 a0d146ed 2005-07-12 devnull char *name;
945 a0d146ed 2005-07-12 devnull name = l ? l->name : "<nil>";
947 a0d146ed 2005-07-12 devnull fprint(2, "hdump xfer %d\n", h->xferenc);
948 a0d146ed 2005-07-12 devnull hprint(h, "<html><head>\n");
949 a0d146ed 2005-07-12 devnull hprint(h, "<title>Venti Server Log: %s</title>\n", name);
950 a0d146ed 2005-07-12 devnull hprint(h, "</head><body>\n");
951 a0d146ed 2005-07-12 devnull hprint(h, "<b>Venti Server Log: %s</b>\n<p>\n", name);
954 a0d146ed 2005-07-12 devnull c = l->w;
955 a0d146ed 2005-07-12 devnull for(i=0; i<l->nchunk; i++){
956 a0d146ed 2005-07-12 devnull if(++c == l->chunk+l->nchunk)
957 a0d146ed 2005-07-12 devnull c = l->chunk;
958 a0d146ed 2005-07-12 devnull hwrite(h, c->p, c->wp-c->p);
961 a0d146ed 2005-07-12 devnull hprint(h, "</body></html>\n");
964 a0d146ed 2005-07-12 devnull static int
965 a0d146ed 2005-07-12 devnull strpcmp(const void *va, const void *vb)
967 a0d146ed 2005-07-12 devnull return strcmp(*(char**)va, *(char**)vb);
971 a0d146ed 2005-07-12 devnull vtloghlist(Hio *h)
973 a0d146ed 2005-07-12 devnull char **p;
974 a0d146ed 2005-07-12 devnull int i, n;
976 a0d146ed 2005-07-12 devnull hprint(h, "<html><head>\n");
977 a0d146ed 2005-07-12 devnull hprint(h, "<title>Venti Server Logs</title>\n");
978 a0d146ed 2005-07-12 devnull hprint(h, "</head><body>\n");
979 a0d146ed 2005-07-12 devnull hprint(h, "<b>Venti Server Logs</b>\n<p>\n");
981 a0d146ed 2005-07-12 devnull p = vtlognames(&n);
982 a0d146ed 2005-07-12 devnull qsort(p, n, sizeof(p[0]), strpcmp);
983 a0d146ed 2005-07-12 devnull for(i=0; i<n; i++)
984 a0d146ed 2005-07-12 devnull hprint(h, "<a href=\"/log/%s\">%s</a><br>\n", p[i], p[i]);
985 a0d146ed 2005-07-12 devnull vtfree(p);
986 a0d146ed 2005-07-12 devnull hprint(h, "</body></html>\n");