Blame


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"
5 a0d146ed 2005-07-12 devnull
6 a0d146ed 2005-07-12 devnull typedef struct HttpObj HttpObj;
7 a0d146ed 2005-07-12 devnull extern QLock memdrawlock;
8 a0d146ed 2005-07-12 devnull
9 a0d146ed 2005-07-12 devnull enum
10 a0d146ed 2005-07-12 devnull {
11 a0d146ed 2005-07-12 devnull ObjNameSize = 64,
12 a0d146ed 2005-07-12 devnull MaxObjs = 16
13 a0d146ed 2005-07-12 devnull };
14 a0d146ed 2005-07-12 devnull
15 a0d146ed 2005-07-12 devnull struct HttpObj
16 a0d146ed 2005-07-12 devnull {
17 a0d146ed 2005-07-12 devnull char name[ObjNameSize];
18 a0d146ed 2005-07-12 devnull int (*f)(HConnect*);
19 a0d146ed 2005-07-12 devnull };
20 a0d146ed 2005-07-12 devnull
21 a0d146ed 2005-07-12 devnull static HttpObj objs[MaxObjs];
22 a0d146ed 2005-07-12 devnull
23 a0d146ed 2005-07-12 devnull static char *webroot;
24 a0d146ed 2005-07-12 devnull
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);
38 a0d146ed 2005-07-12 devnull
39 a0d146ed 2005-07-12 devnull int
40 a0d146ed 2005-07-12 devnull httpdinit(char *address, char *dir)
41 a0d146ed 2005-07-12 devnull {
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);
45 a0d146ed 2005-07-12 devnull
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;
49 a0d146ed 2005-07-12 devnull
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);
60 a0d146ed 2005-07-12 devnull
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;
64 a0d146ed 2005-07-12 devnull }
65 a0d146ed 2005-07-12 devnull
66 a0d146ed 2005-07-12 devnull static int
67 a0d146ed 2005-07-12 devnull httpdobj(char *name, int (*f)(HConnect*))
68 a0d146ed 2005-07-12 devnull {
69 a0d146ed 2005-07-12 devnull int i;
70 a0d146ed 2005-07-12 devnull
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;
78 a0d146ed 2005-07-12 devnull }
79 a0d146ed 2005-07-12 devnull if(strcmp(objs[i].name, name) == 0)
80 a0d146ed 2005-07-12 devnull return -1;
81 a0d146ed 2005-07-12 devnull }
82 a0d146ed 2005-07-12 devnull return -1;
83 a0d146ed 2005-07-12 devnull }
84 a0d146ed 2005-07-12 devnull
85 a0d146ed 2005-07-12 devnull static HConnect*
86 a0d146ed 2005-07-12 devnull mkconnect(void)
87 a0d146ed 2005-07-12 devnull {
88 a0d146ed 2005-07-12 devnull HConnect *c;
89 a0d146ed 2005-07-12 devnull
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;
97 a0d146ed 2005-07-12 devnull }
98 a0d146ed 2005-07-12 devnull
99 a0d146ed 2005-07-12 devnull void httpproc(void*);
100 a0d146ed 2005-07-12 devnull
101 a0d146ed 2005-07-12 devnull static void
102 a0d146ed 2005-07-12 devnull listenproc(void *vaddress)
103 a0d146ed 2005-07-12 devnull {
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;
107 a0d146ed 2005-07-12 devnull
108 a0d146ed 2005-07-12 devnull //sleep(1000); /* let strace find us */
109 a0d146ed 2005-07-12 devnull
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);
114 a0d146ed 2005-07-12 devnull return;
115 a0d146ed 2005-07-12 devnull }
116 a0d146ed 2005-07-12 devnull
117 a0d146ed 2005-07-12 devnull if(0) print("announce ctl %d dir %s\n", ctl, dir);
118 a0d146ed 2005-07-12 devnull for(;;){
119 a0d146ed 2005-07-12 devnull /*
120 a0d146ed 2005-07-12 devnull * wait for a call (or an error)
121 a0d146ed 2005-07-12 devnull */
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);
126 a0d146ed 2005-07-12 devnull return;
127 a0d146ed 2005-07-12 devnull }
128 a0d146ed 2005-07-12 devnull
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;
135 a0d146ed 2005-07-12 devnull }
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);
142 a0d146ed 2005-07-12 devnull }
143 a0d146ed 2005-07-12 devnull }
144 a0d146ed 2005-07-12 devnull
145 a0d146ed 2005-07-12 devnull void
146 a0d146ed 2005-07-12 devnull httpproc(void *v)
147 a0d146ed 2005-07-12 devnull {
148 a0d146ed 2005-07-12 devnull HConnect *c;
149 a0d146ed 2005-07-12 devnull int ok, i, n;
150 a0d146ed 2005-07-12 devnull
151 a0d146ed 2005-07-12 devnull //sleep(1000); /* let strace find us */
152 a0d146ed 2005-07-12 devnull c = v;
153 a0d146ed 2005-07-12 devnull
154 a0d146ed 2005-07-12 devnull for(;;){
155 a0d146ed 2005-07-12 devnull /*
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.
158 a0d146ed 2005-07-12 devnull */
159 a0d146ed 2005-07-12 devnull if(hparsereq(c, 0) < 0)
160 a0d146ed 2005-07-12 devnull break;
161 a0d146ed 2005-07-12 devnull
162 a0d146ed 2005-07-12 devnull ok = -1;
163 a0d146ed 2005-07-12 devnull for(i = 0; i < MaxObjs && objs[i].name[0]; i++){
164 a0d146ed 2005-07-12 devnull n = strlen(objs[i].name);
165 a0d146ed 2005-07-12 devnull if((objs[i].name[n-1] == '/' && strncmp(c->req.uri, objs[i].name, n) == 0)
166 a0d146ed 2005-07-12 devnull || (objs[i].name[n-1] != '/' && strcmp(c->req.uri, objs[i].name) == 0)){
167 a0d146ed 2005-07-12 devnull ok = (*objs[i].f)(c);
168 a0d146ed 2005-07-12 devnull goto found;
169 a0d146ed 2005-07-12 devnull }
170 a0d146ed 2005-07-12 devnull }
171 a0d146ed 2005-07-12 devnull ok = fromwebdir(c);
172 a0d146ed 2005-07-12 devnull found:
173 a0d146ed 2005-07-12 devnull if(c->head.closeit)
174 a0d146ed 2005-07-12 devnull ok = -1;
175 a0d146ed 2005-07-12 devnull hreqcleanup(c);
176 a0d146ed 2005-07-12 devnull
177 a0d146ed 2005-07-12 devnull if(ok < 0)
178 a0d146ed 2005-07-12 devnull break;
179 a0d146ed 2005-07-12 devnull }
180 a0d146ed 2005-07-12 devnull hreqcleanup(c);
181 a0d146ed 2005-07-12 devnull close(c->hin.fd);
182 a0d146ed 2005-07-12 devnull free(c);
183 a0d146ed 2005-07-12 devnull }
184 a0d146ed 2005-07-12 devnull
185 a0d146ed 2005-07-12 devnull static int
186 a0d146ed 2005-07-12 devnull percent(long v, long total)
187 a0d146ed 2005-07-12 devnull {
188 a0d146ed 2005-07-12 devnull if(total == 0)
189 a0d146ed 2005-07-12 devnull total = 1;
190 a0d146ed 2005-07-12 devnull if(v < 1000*1000)
191 a0d146ed 2005-07-12 devnull return (v * 100) / total;
192 a0d146ed 2005-07-12 devnull total /= 100;
193 a0d146ed 2005-07-12 devnull if(total == 0)
194 a0d146ed 2005-07-12 devnull total = 1;
195 a0d146ed 2005-07-12 devnull return v / total;
196 a0d146ed 2005-07-12 devnull }
197 a0d146ed 2005-07-12 devnull
198 a0d146ed 2005-07-12 devnull static int
199 a0d146ed 2005-07-12 devnull preq(HConnect *c)
200 a0d146ed 2005-07-12 devnull {
201 a0d146ed 2005-07-12 devnull if(hparseheaders(c, 0) < 0)
202 a0d146ed 2005-07-12 devnull return -1;
203 a0d146ed 2005-07-12 devnull if(strcmp(c->req.meth, "GET") != 0
204 a0d146ed 2005-07-12 devnull && strcmp(c->req.meth, "HEAD") != 0)
205 a0d146ed 2005-07-12 devnull return hunallowed(c, "GET, HEAD");
206 a0d146ed 2005-07-12 devnull if(c->head.expectother || c->head.expectcont)
207 a0d146ed 2005-07-12 devnull return hfail(c, HExpectFail, nil);
208 a0d146ed 2005-07-12 devnull return 0;
209 a0d146ed 2005-07-12 devnull }
210 a0d146ed 2005-07-12 devnull
211 a0d146ed 2005-07-12 devnull static int
212 a0d146ed 2005-07-12 devnull preqtype(HConnect *c, char *type)
213 a0d146ed 2005-07-12 devnull {
214 a0d146ed 2005-07-12 devnull Hio *hout;
215 a0d146ed 2005-07-12 devnull int r;
216 a0d146ed 2005-07-12 devnull
217 a0d146ed 2005-07-12 devnull r = preq(c);
218 a0d146ed 2005-07-12 devnull if(r < 0)
219 a0d146ed 2005-07-12 devnull return r;
220 a0d146ed 2005-07-12 devnull
221 a0d146ed 2005-07-12 devnull hout = &c->hout;
222 a0d146ed 2005-07-12 devnull if(c->req.vermaj){
223 a0d146ed 2005-07-12 devnull hokheaders(c);
224 a0d146ed 2005-07-12 devnull hprint(hout, "Content-type: %s\r\n", type);
225 a0d146ed 2005-07-12 devnull if(http11(c))
226 a0d146ed 2005-07-12 devnull hprint(hout, "Transfer-Encoding: chunked\r\n");
227 a0d146ed 2005-07-12 devnull hprint(hout, "\r\n");
228 a0d146ed 2005-07-12 devnull }
229 a0d146ed 2005-07-12 devnull
230 a0d146ed 2005-07-12 devnull if(http11(c))
231 a0d146ed 2005-07-12 devnull hxferenc(hout, 1);
232 a0d146ed 2005-07-12 devnull else
233 a0d146ed 2005-07-12 devnull c->head.closeit = 1;
234 a0d146ed 2005-07-12 devnull return 0;
235 a0d146ed 2005-07-12 devnull }
236 a0d146ed 2005-07-12 devnull
237 a0d146ed 2005-07-12 devnull static int
238 a0d146ed 2005-07-12 devnull preqtext(HConnect *c)
239 a0d146ed 2005-07-12 devnull {
240 a0d146ed 2005-07-12 devnull return preqtype(c, "text/plain");
241 a0d146ed 2005-07-12 devnull }
242 a0d146ed 2005-07-12 devnull
243 a0d146ed 2005-07-12 devnull static int
244 a0d146ed 2005-07-12 devnull notfound(HConnect *c)
245 a0d146ed 2005-07-12 devnull {
246 a0d146ed 2005-07-12 devnull int r;
247 a0d146ed 2005-07-12 devnull
248 a0d146ed 2005-07-12 devnull r = preq(c);
249 a0d146ed 2005-07-12 devnull if(r < 0)
250 a0d146ed 2005-07-12 devnull return r;
251 a0d146ed 2005-07-12 devnull return hfail(c, HNotFound, c->req.uri);
252 a0d146ed 2005-07-12 devnull }
253 a0d146ed 2005-07-12 devnull
254 a0d146ed 2005-07-12 devnull struct {
255 a0d146ed 2005-07-12 devnull char *ext;
256 a0d146ed 2005-07-12 devnull char *type;
257 a0d146ed 2005-07-12 devnull } exttab[] = {
258 a0d146ed 2005-07-12 devnull ".html", "text/html",
259 a0d146ed 2005-07-12 devnull ".txt", "text/plain",
260 a0d146ed 2005-07-12 devnull ".xml", "text/xml",
261 a0d146ed 2005-07-12 devnull ".png", "image/png",
262 a0d146ed 2005-07-12 devnull ".gif", "image/gif",
263 a0d146ed 2005-07-12 devnull 0
264 a0d146ed 2005-07-12 devnull };
265 a0d146ed 2005-07-12 devnull
266 a0d146ed 2005-07-12 devnull static int
267 a0d146ed 2005-07-12 devnull fromwebdir(HConnect *c)
268 a0d146ed 2005-07-12 devnull {
269 a0d146ed 2005-07-12 devnull char buf[4096], *p, *ext, *type;
270 a0d146ed 2005-07-12 devnull int i, fd, n, defaulted;
271 a0d146ed 2005-07-12 devnull Dir *d;
272 a0d146ed 2005-07-12 devnull
273 a0d146ed 2005-07-12 devnull if(webroot == nil || strstr(c->req.uri, ".."))
274 a0d146ed 2005-07-12 devnull return notfound(c);
275 a0d146ed 2005-07-12 devnull snprint(buf, sizeof buf-20, "%s/%s", webroot, c->req.uri+1);
276 a0d146ed 2005-07-12 devnull defaulted = 0;
277 a0d146ed 2005-07-12 devnull reopen:
278 a0d146ed 2005-07-12 devnull if((fd = open(buf, OREAD)) < 0)
279 a0d146ed 2005-07-12 devnull return notfound(c);
280 a0d146ed 2005-07-12 devnull d = dirfstat(fd);
281 a0d146ed 2005-07-12 devnull if(d == nil){
282 a0d146ed 2005-07-12 devnull close(fd);
283 a0d146ed 2005-07-12 devnull return notfound(c);
284 a0d146ed 2005-07-12 devnull }
285 a0d146ed 2005-07-12 devnull if(d->mode&DMDIR){
286 a0d146ed 2005-07-12 devnull if(!defaulted){
287 a0d146ed 2005-07-12 devnull defaulted = 1;
288 a0d146ed 2005-07-12 devnull strcat(buf, "/index.html");
289 a0d146ed 2005-07-12 devnull free(d);
290 a0d146ed 2005-07-12 devnull close(fd);
291 a0d146ed 2005-07-12 devnull goto reopen;
292 a0d146ed 2005-07-12 devnull }
293 a0d146ed 2005-07-12 devnull free(d);
294 a0d146ed 2005-07-12 devnull return notfound(c);
295 a0d146ed 2005-07-12 devnull }
296 a0d146ed 2005-07-12 devnull free(d);
297 a0d146ed 2005-07-12 devnull p = buf+strlen(buf);
298 a0d146ed 2005-07-12 devnull type = "application/octet-stream";
299 a0d146ed 2005-07-12 devnull for(i=0; exttab[i].ext; i++){
300 a0d146ed 2005-07-12 devnull ext = exttab[i].ext;
301 a0d146ed 2005-07-12 devnull if(p-strlen(ext) >= buf && strcmp(p-strlen(ext), ext) == 0){
302 a0d146ed 2005-07-12 devnull type = exttab[i].type;
303 a0d146ed 2005-07-12 devnull break;
304 a0d146ed 2005-07-12 devnull }
305 a0d146ed 2005-07-12 devnull }
306 a0d146ed 2005-07-12 devnull if(preqtype(c, type) < 0){
307 a0d146ed 2005-07-12 devnull close(fd);
308 a0d146ed 2005-07-12 devnull return 0;
309 a0d146ed 2005-07-12 devnull }
310 a0d146ed 2005-07-12 devnull while((n = read(fd, buf, sizeof buf)) > 0)
311 a0d146ed 2005-07-12 devnull if(hwrite(&c->hout, buf, n) < 0)
312 a0d146ed 2005-07-12 devnull break;
313 a0d146ed 2005-07-12 devnull close(fd);
314 a0d146ed 2005-07-12 devnull hflush(&c->hout);
315 a0d146ed 2005-07-12 devnull return 0;
316 a0d146ed 2005-07-12 devnull }
317 a0d146ed 2005-07-12 devnull
318 a0d146ed 2005-07-12 devnull static struct
319 a0d146ed 2005-07-12 devnull {
320 a0d146ed 2005-07-12 devnull char *name;
321 a0d146ed 2005-07-12 devnull int *p;
322 a0d146ed 2005-07-12 devnull } namedints[] =
323 a0d146ed 2005-07-12 devnull {
324 a0d146ed 2005-07-12 devnull "compress", &compressblocks,
325 a0d146ed 2005-07-12 devnull "devnull", &writestodevnull,
326 a0d146ed 2005-07-12 devnull "logging", &ventilogging,
327 a0d146ed 2005-07-12 devnull "stats", &collectstats,
328 a0d146ed 2005-07-12 devnull "icachesleeptime", &icachesleeptime,
329 a0d146ed 2005-07-12 devnull "arenasumsleeptime", &arenasumsleeptime,
330 a0d146ed 2005-07-12 devnull 0
331 a0d146ed 2005-07-12 devnull };
332 a0d146ed 2005-07-12 devnull
333 a0d146ed 2005-07-12 devnull static int
334 a0d146ed 2005-07-12 devnull xset(HConnect *c)
335 a0d146ed 2005-07-12 devnull {
336 a0d146ed 2005-07-12 devnull int i, nf, r;
337 a0d146ed 2005-07-12 devnull char *f[10], *s;
338 a0d146ed 2005-07-12 devnull
339 a0d146ed 2005-07-12 devnull s = estrdup(c->req.uri);
340 a0d146ed 2005-07-12 devnull nf = getfields(s+strlen("/set/"), f, nelem(f), 1, "/");
341 a0d146ed 2005-07-12 devnull
342 a0d146ed 2005-07-12 devnull if(nf < 1)
343 a0d146ed 2005-07-12 devnull return notfound(c);
344 a0d146ed 2005-07-12 devnull for(i=0; namedints[i].name; i++){
345 a0d146ed 2005-07-12 devnull if(strcmp(f[0], namedints[i].name) == 0){
346 a0d146ed 2005-07-12 devnull if(nf >= 2)
347 a0d146ed 2005-07-12 devnull *namedints[i].p = atoi(f[1]);
348 a0d146ed 2005-07-12 devnull r = preqtext(c);
349 a0d146ed 2005-07-12 devnull if(r < 0)
350 a0d146ed 2005-07-12 devnull return r;
351 a0d146ed 2005-07-12 devnull hprint(&c->hout, "%s = %d\n", f[0], *namedints[i].p);
352 a0d146ed 2005-07-12 devnull hflush(&c->hout);
353 a0d146ed 2005-07-12 devnull return 0;
354 a0d146ed 2005-07-12 devnull }
355 a0d146ed 2005-07-12 devnull }
356 a0d146ed 2005-07-12 devnull return notfound(c);
357 a0d146ed 2005-07-12 devnull }
358 a0d146ed 2005-07-12 devnull
359 a0d146ed 2005-07-12 devnull static int
360 a0d146ed 2005-07-12 devnull estats(HConnect *c)
361 a0d146ed 2005-07-12 devnull {
362 a0d146ed 2005-07-12 devnull Hio *hout;
363 a0d146ed 2005-07-12 devnull int r;
364 a0d146ed 2005-07-12 devnull
365 a0d146ed 2005-07-12 devnull r = preqtext(c);
366 a0d146ed 2005-07-12 devnull if(r < 0)
367 a0d146ed 2005-07-12 devnull return r;
368 a0d146ed 2005-07-12 devnull
369 a0d146ed 2005-07-12 devnull
370 a0d146ed 2005-07-12 devnull hout = &c->hout;
371 a0d146ed 2005-07-12 devnull /*
372 a0d146ed 2005-07-12 devnull hprint(hout, "lump writes=%,ld\n", stats.lumpwrites);
373 a0d146ed 2005-07-12 devnull hprint(hout, "lump reads=%,ld\n", stats.lumpreads);
374 a0d146ed 2005-07-12 devnull hprint(hout, "lump cache read hits=%,ld\n", stats.lumphit);
375 a0d146ed 2005-07-12 devnull hprint(hout, "lump cache read misses=%,ld\n", stats.lumpmiss);
376 a0d146ed 2005-07-12 devnull
377 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk writes=%,ld\n", stats.clumpwrites);
378 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes written=%,lld\n", stats.clumpbwrites);
379 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes compressed=%,lld\n", stats.clumpbcomp);
380 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk reads=%,ld\n", stats.clumpreads);
381 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes read=%,lld\n", stats.clumpbreads);
382 a0d146ed 2005-07-12 devnull hprint(hout, "clump disk bytes uncompressed=%,lld\n", stats.clumpbuncomp);
383 a0d146ed 2005-07-12 devnull
384 a0d146ed 2005-07-12 devnull hprint(hout, "clump directory disk writes=%,ld\n", stats.ciwrites);
385 a0d146ed 2005-07-12 devnull hprint(hout, "clump directory disk reads=%,ld\n", stats.cireads);
386 a0d146ed 2005-07-12 devnull
387 a0d146ed 2005-07-12 devnull hprint(hout, "index disk writes=%,ld\n", stats.indexwrites);
388 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads=%,ld\n", stats.indexreads);
389 a0d146ed 2005-07-12 devnull hprint(hout, "index disk bloom filter hits=%,ld %d%% falsemisses=%,ld %d%%\n",
390 a0d146ed 2005-07-12 devnull stats.indexbloomhits,
391 a0d146ed 2005-07-12 devnull percent(stats.indexbloomhits, stats.indexreads),
392 a0d146ed 2005-07-12 devnull stats.indexbloomfalsemisses,
393 a0d146ed 2005-07-12 devnull percent(stats.indexbloomfalsemisses, stats.indexreads));
394 a0d146ed 2005-07-12 devnull hprint(hout, "bloom filter bits=%,ld of %,ld %d%%\n",
395 a0d146ed 2005-07-12 devnull stats.bloomones, stats.bloombits, percent(stats.bloomones, stats.bloombits));
396 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads for modify=%,ld\n", stats.indexwreads);
397 a0d146ed 2005-07-12 devnull hprint(hout, "index disk reads for allocation=%,ld\n", stats.indexareads);
398 a0d146ed 2005-07-12 devnull hprint(hout, "index block splits=%,ld\n", stats.indexsplits);
399 a0d146ed 2005-07-12 devnull
400 a0d146ed 2005-07-12 devnull hprint(hout, "index cache lookups=%,ld\n", stats.iclookups);
401 a0d146ed 2005-07-12 devnull hprint(hout, "index cache hits=%,ld %d%%\n", stats.ichits,
402 a0d146ed 2005-07-12 devnull percent(stats.ichits, stats.iclookups));
403 a0d146ed 2005-07-12 devnull hprint(hout, "index cache fills=%,ld %d%%\n", stats.icfills,
404 a0d146ed 2005-07-12 devnull percent(stats.icfills, stats.iclookups));
405 a0d146ed 2005-07-12 devnull hprint(hout, "index cache inserts=%,ld\n", stats.icinserts);
406 a0d146ed 2005-07-12 devnull
407 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache hits=%,ld\n", stats.pchit);
408 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache misses=%,ld\n", stats.pcmiss);
409 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache reads=%,ld\n", stats.pcreads);
410 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache bytes read=%,lld\n", stats.pcbreads);
411 a0d146ed 2005-07-12 devnull
412 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache writes=%,ld\n", stats.dirtydblocks);
413 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache writes absorbed=%,ld %d%%\n", stats.absorbedwrites,
414 a0d146ed 2005-07-12 devnull percent(stats.absorbedwrites, stats.dirtydblocks));
415 a0d146ed 2005-07-12 devnull
416 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache flushes=%,ld\n", stats.dcacheflushes);
417 a0d146ed 2005-07-12 devnull hprint(hout, "disk cache flush writes=%,ld (%,ld per flush)\n",
418 a0d146ed 2005-07-12 devnull stats.dcacheflushwrites,
419 a0d146ed 2005-07-12 devnull stats.dcacheflushwrites/(stats.dcacheflushes ? stats.dcacheflushes : 1));
420 a0d146ed 2005-07-12 devnull
421 a0d146ed 2005-07-12 devnull hprint(hout, "disk writes=%,ld\n", stats.diskwrites);
422 a0d146ed 2005-07-12 devnull hprint(hout, "disk bytes written=%,lld\n", stats.diskbwrites);
423 a0d146ed 2005-07-12 devnull hprint(hout, "disk reads=%,ld\n", stats.diskreads);
424 a0d146ed 2005-07-12 devnull hprint(hout, "disk bytes read=%,lld\n", stats.diskbreads);
425 a0d146ed 2005-07-12 devnull */
426 a0d146ed 2005-07-12 devnull
427 a0d146ed 2005-07-12 devnull hflush(hout);
428 a0d146ed 2005-07-12 devnull return 0;
429 a0d146ed 2005-07-12 devnull }
430 a0d146ed 2005-07-12 devnull
431 a0d146ed 2005-07-12 devnull static int
432 a0d146ed 2005-07-12 devnull sindex(HConnect *c)
433 a0d146ed 2005-07-12 devnull {
434 a0d146ed 2005-07-12 devnull Hio *hout;
435 a0d146ed 2005-07-12 devnull Index *ix;
436 a0d146ed 2005-07-12 devnull Arena *arena;
437 a0d146ed 2005-07-12 devnull vlong clumps, cclumps, uncsize, used, size;
438 a0d146ed 2005-07-12 devnull int i, r, active;
439 a0d146ed 2005-07-12 devnull
440 a0d146ed 2005-07-12 devnull r = preqtext(c);
441 a0d146ed 2005-07-12 devnull if(r < 0)
442 a0d146ed 2005-07-12 devnull return r;
443 a0d146ed 2005-07-12 devnull hout = &c->hout;
444 a0d146ed 2005-07-12 devnull
445 a0d146ed 2005-07-12 devnull ix = mainindex;
446 a0d146ed 2005-07-12 devnull
447 a0d146ed 2005-07-12 devnull hprint(hout, "index=%s\n", ix->name);
448 a0d146ed 2005-07-12 devnull
449 a0d146ed 2005-07-12 devnull active = 0;
450 a0d146ed 2005-07-12 devnull clumps = 0;
451 a0d146ed 2005-07-12 devnull cclumps = 0;
452 a0d146ed 2005-07-12 devnull uncsize = 0;
453 a0d146ed 2005-07-12 devnull used = 0;
454 a0d146ed 2005-07-12 devnull size = 0;
455 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->narenas; i++){
456 a0d146ed 2005-07-12 devnull arena = ix->arenas[i];
457 a0d146ed 2005-07-12 devnull if(arena != nil && arena->memstats.clumps != 0){
458 a0d146ed 2005-07-12 devnull active++;
459 a0d146ed 2005-07-12 devnull clumps += arena->memstats.clumps;
460 a0d146ed 2005-07-12 devnull cclumps += arena->memstats.cclumps;
461 a0d146ed 2005-07-12 devnull uncsize += arena->memstats.uncsize;
462 a0d146ed 2005-07-12 devnull used += arena->memstats.used;
463 a0d146ed 2005-07-12 devnull }
464 a0d146ed 2005-07-12 devnull size += arena->size;
465 a0d146ed 2005-07-12 devnull }
466 a0d146ed 2005-07-12 devnull hprint(hout, "total arenas=%,d active=%,d\n", ix->narenas, active);
467 a0d146ed 2005-07-12 devnull hprint(hout, "total space=%,lld used=%,lld\n", size, used + clumps * ClumpInfoSize);
468 a0d146ed 2005-07-12 devnull hprint(hout, "clumps=%,lld compressed clumps=%,lld data=%,lld compressed data=%,lld\n",
469 a0d146ed 2005-07-12 devnull clumps, cclumps, uncsize, used - clumps * ClumpSize);
470 a0d146ed 2005-07-12 devnull hflush(hout);
471 a0d146ed 2005-07-12 devnull return 0;
472 a0d146ed 2005-07-12 devnull }
473 a0d146ed 2005-07-12 devnull
474 a0d146ed 2005-07-12 devnull static void
475 a0d146ed 2005-07-12 devnull darena(Hio *hout, Arena *arena)
476 a0d146ed 2005-07-12 devnull {
477 a0d146ed 2005-07-12 devnull hprint(hout, "arena='%s' on %s at [%lld,%lld)\n\tversion=%d created=%d modified=%d",
478 a0d146ed 2005-07-12 devnull arena->name, arena->part->name, arena->base, arena->base + arena->size + 2 * arena->blocksize,
479 a0d146ed 2005-07-12 devnull arena->version, arena->ctime, arena->wtime);
480 a0d146ed 2005-07-12 devnull if(arena->memstats.sealed)
481 a0d146ed 2005-07-12 devnull hprint(hout, " mem=sealed");
482 a0d146ed 2005-07-12 devnull if(arena->diskstats.sealed)
483 a0d146ed 2005-07-12 devnull hprint(hout, " disk=sealed");
484 a0d146ed 2005-07-12 devnull hprint(hout, "\n");
485 a0d146ed 2005-07-12 devnull if(scorecmp(zeroscore, arena->score) != 0)
486 a0d146ed 2005-07-12 devnull hprint(hout, "\tscore=%V\n", arena->score);
487 a0d146ed 2005-07-12 devnull
488 a0d146ed 2005-07-12 devnull hprint(hout, "\tmem: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n",
489 a0d146ed 2005-07-12 devnull arena->memstats.clumps, arena->memstats.cclumps, arena->memstats.uncsize,
490 a0d146ed 2005-07-12 devnull arena->memstats.used - arena->memstats.clumps * ClumpSize,
491 a0d146ed 2005-07-12 devnull arena->memstats.used + arena->memstats.clumps * ClumpInfoSize);
492 a0d146ed 2005-07-12 devnull hprint(hout, "\tdisk: clumps=%d compressed clumps=%d data=%,lld compressed data=%,lld storage=%,lld\n",
493 a0d146ed 2005-07-12 devnull arena->diskstats.clumps, arena->diskstats.cclumps, arena->diskstats.uncsize,
494 a0d146ed 2005-07-12 devnull arena->diskstats.used - arena->diskstats.clumps * ClumpSize,
495 a0d146ed 2005-07-12 devnull arena->diskstats.used + arena->diskstats.clumps * ClumpInfoSize);
496 a0d146ed 2005-07-12 devnull }
497 a0d146ed 2005-07-12 devnull
498 a0d146ed 2005-07-12 devnull static int
499 a0d146ed 2005-07-12 devnull hicacheflush(HConnect *c)
500 a0d146ed 2005-07-12 devnull {
501 a0d146ed 2005-07-12 devnull Hio *hout;
502 a0d146ed 2005-07-12 devnull int r;
503 a0d146ed 2005-07-12 devnull
504 a0d146ed 2005-07-12 devnull r = preqtext(c);
505 a0d146ed 2005-07-12 devnull if(r < 0)
506 a0d146ed 2005-07-12 devnull return r;
507 a0d146ed 2005-07-12 devnull hout = &c->hout;
508 a0d146ed 2005-07-12 devnull
509 a0d146ed 2005-07-12 devnull flushicache();
510 a0d146ed 2005-07-12 devnull hprint(hout, "flushed icache\n");
511 a0d146ed 2005-07-12 devnull hflush(hout);
512 a0d146ed 2005-07-12 devnull return 0;
513 a0d146ed 2005-07-12 devnull }
514 a0d146ed 2005-07-12 devnull
515 a0d146ed 2005-07-12 devnull static int
516 a0d146ed 2005-07-12 devnull hdcacheflush(HConnect *c)
517 a0d146ed 2005-07-12 devnull {
518 a0d146ed 2005-07-12 devnull Hio *hout;
519 a0d146ed 2005-07-12 devnull int r;
520 a0d146ed 2005-07-12 devnull
521 a0d146ed 2005-07-12 devnull r = preqtext(c);
522 a0d146ed 2005-07-12 devnull if(r < 0)
523 a0d146ed 2005-07-12 devnull return r;
524 a0d146ed 2005-07-12 devnull hout = &c->hout;
525 a0d146ed 2005-07-12 devnull
526 a0d146ed 2005-07-12 devnull flushdcache();
527 a0d146ed 2005-07-12 devnull hprint(hout, "flushed dcache\n");
528 a0d146ed 2005-07-12 devnull hflush(hout);
529 a0d146ed 2005-07-12 devnull return 0;
530 a0d146ed 2005-07-12 devnull }
531 a0d146ed 2005-07-12 devnull
532 a0d146ed 2005-07-12 devnull static int
533 a0d146ed 2005-07-12 devnull dindex(HConnect *c)
534 a0d146ed 2005-07-12 devnull {
535 a0d146ed 2005-07-12 devnull Hio *hout;
536 a0d146ed 2005-07-12 devnull Index *ix;
537 a0d146ed 2005-07-12 devnull int i, r;
538 a0d146ed 2005-07-12 devnull
539 a0d146ed 2005-07-12 devnull r = preqtext(c);
540 a0d146ed 2005-07-12 devnull if(r < 0)
541 a0d146ed 2005-07-12 devnull return r;
542 a0d146ed 2005-07-12 devnull hout = &c->hout;
543 a0d146ed 2005-07-12 devnull
544 a0d146ed 2005-07-12 devnull
545 a0d146ed 2005-07-12 devnull ix = mainindex;
546 a0d146ed 2005-07-12 devnull hprint(hout, "index=%s version=%d blocksize=%d tabsize=%d\n",
547 a0d146ed 2005-07-12 devnull ix->name, ix->version, ix->blocksize, ix->tabsize);
548 a0d146ed 2005-07-12 devnull hprint(hout, "\tbuckets=%d div=%d\n", ix->buckets, ix->div);
549 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->nsects; i++)
550 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);
551 a0d146ed 2005-07-12 devnull for(i = 0; i < ix->narenas; i++){
552 a0d146ed 2005-07-12 devnull if(ix->arenas[i] != nil && ix->arenas[i]->memstats.clumps != 0){
553 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);
554 a0d146ed 2005-07-12 devnull darena(hout, ix->arenas[i]);
555 a0d146ed 2005-07-12 devnull }
556 a0d146ed 2005-07-12 devnull }
557 a0d146ed 2005-07-12 devnull hflush(hout);
558 a0d146ed 2005-07-12 devnull return 0;
559 a0d146ed 2005-07-12 devnull }
560 a0d146ed 2005-07-12 devnull
561 a0d146ed 2005-07-12 devnull typedef struct Arg Arg;
562 a0d146ed 2005-07-12 devnull struct Arg
563 a0d146ed 2005-07-12 devnull {
564 a0d146ed 2005-07-12 devnull int index;
565 a0d146ed 2005-07-12 devnull int index2;
566 a0d146ed 2005-07-12 devnull };
567 a0d146ed 2005-07-12 devnull
568 a0d146ed 2005-07-12 devnull static long
569 a0d146ed 2005-07-12 devnull rawgraph(Stats *s, Stats *t, void *va)
570 a0d146ed 2005-07-12 devnull {
571 a0d146ed 2005-07-12 devnull Arg *a;
572 a0d146ed 2005-07-12 devnull
573 a0d146ed 2005-07-12 devnull a = va;
574 a0d146ed 2005-07-12 devnull return t->n[a->index];
575 a0d146ed 2005-07-12 devnull }
576 a0d146ed 2005-07-12 devnull
577 a0d146ed 2005-07-12 devnull static long
578 a0d146ed 2005-07-12 devnull diffgraph(Stats *s, Stats *t, void *va)
579 a0d146ed 2005-07-12 devnull {
580 a0d146ed 2005-07-12 devnull Arg *a;
581 a0d146ed 2005-07-12 devnull
582 a0d146ed 2005-07-12 devnull a = va;
583 a0d146ed 2005-07-12 devnull return t->n[a->index] - s->n[a->index];
584 a0d146ed 2005-07-12 devnull }
585 a0d146ed 2005-07-12 devnull
586 a0d146ed 2005-07-12 devnull static long
587 a0d146ed 2005-07-12 devnull pctgraph(Stats *s, Stats *t, void *va)
588 a0d146ed 2005-07-12 devnull {
589 a0d146ed 2005-07-12 devnull Arg *a;
590 a0d146ed 2005-07-12 devnull
591 a0d146ed 2005-07-12 devnull a = va;
592 a0d146ed 2005-07-12 devnull return percent(t->n[a->index], t->n[a->index2]);
593 a0d146ed 2005-07-12 devnull }
594 a0d146ed 2005-07-12 devnull
595 a0d146ed 2005-07-12 devnull static long
596 a0d146ed 2005-07-12 devnull pctdiffgraph(Stats *s, Stats *t, void *va)
597 a0d146ed 2005-07-12 devnull {
598 a0d146ed 2005-07-12 devnull Arg *a;
599 a0d146ed 2005-07-12 devnull
600 a0d146ed 2005-07-12 devnull a = va;
601 a0d146ed 2005-07-12 devnull return percent(t->n[a->index]-s->n[a->index], t->n[a->index2]-s->n[a->index2]);
602 a0d146ed 2005-07-12 devnull }
603 a0d146ed 2005-07-12 devnull
604 a0d146ed 2005-07-12 devnull static long
605 a0d146ed 2005-07-12 devnull netbw(Stats *s)
606 a0d146ed 2005-07-12 devnull {
607 a0d146ed 2005-07-12 devnull ulong *n;
608 a0d146ed 2005-07-12 devnull
609 a0d146ed 2005-07-12 devnull n = s->n;
610 a0d146ed 2005-07-12 devnull return n[StatRpcReadBytes]+n[StatRpcWriteBytes]; /* not exactly right */
611 a0d146ed 2005-07-12 devnull }
612 a0d146ed 2005-07-12 devnull
613 a0d146ed 2005-07-12 devnull static long
614 a0d146ed 2005-07-12 devnull diskbw(Stats *s)
615 a0d146ed 2005-07-12 devnull {
616 a0d146ed 2005-07-12 devnull ulong *n;
617 a0d146ed 2005-07-12 devnull
618 a0d146ed 2005-07-12 devnull n = s->n;
619 a0d146ed 2005-07-12 devnull return n[StatApartReadBytes]+n[StatApartWriteBytes]
620 a0d146ed 2005-07-12 devnull + n[StatIsectReadBytes]+n[StatIsectWriteBytes]
621 a0d146ed 2005-07-12 devnull + n[StatSumReadBytes];
622 a0d146ed 2005-07-12 devnull }
623 a0d146ed 2005-07-12 devnull
624 a0d146ed 2005-07-12 devnull static long
625 a0d146ed 2005-07-12 devnull iobw(Stats *s)
626 a0d146ed 2005-07-12 devnull {
627 a0d146ed 2005-07-12 devnull return netbw(s)+diskbw(s);
628 a0d146ed 2005-07-12 devnull }
629 a0d146ed 2005-07-12 devnull
630 a0d146ed 2005-07-12 devnull static long
631 a0d146ed 2005-07-12 devnull diskgraph(Stats *s, Stats *t, void *va)
632 a0d146ed 2005-07-12 devnull {
633 a0d146ed 2005-07-12 devnull USED(va);
634 a0d146ed 2005-07-12 devnull return diskbw(t)-diskbw(s);
635 a0d146ed 2005-07-12 devnull }
636 a0d146ed 2005-07-12 devnull
637 a0d146ed 2005-07-12 devnull static long
638 a0d146ed 2005-07-12 devnull netgraph(Stats *s, Stats *t, void *va)
639 a0d146ed 2005-07-12 devnull {
640 a0d146ed 2005-07-12 devnull USED(va);
641 a0d146ed 2005-07-12 devnull return netbw(t)-netbw(s);
642 a0d146ed 2005-07-12 devnull }
643 a0d146ed 2005-07-12 devnull
644 a0d146ed 2005-07-12 devnull static long
645 a0d146ed 2005-07-12 devnull iograph(Stats *s, Stats *t, void *va)
646 a0d146ed 2005-07-12 devnull {
647 a0d146ed 2005-07-12 devnull USED(va);
648 a0d146ed 2005-07-12 devnull return iobw(t)-iobw(s);
649 a0d146ed 2005-07-12 devnull }
650 a0d146ed 2005-07-12 devnull
651 a0d146ed 2005-07-12 devnull
652 a0d146ed 2005-07-12 devnull static char* graphname[] =
653 a0d146ed 2005-07-12 devnull {
654 a0d146ed 2005-07-12 devnull "rpctotal",
655 a0d146ed 2005-07-12 devnull "rpcread",
656 a0d146ed 2005-07-12 devnull "rpcreadok",
657 a0d146ed 2005-07-12 devnull "rpcreadfail",
658 a0d146ed 2005-07-12 devnull "rpcreadbyte",
659 a0d146ed 2005-07-12 devnull "rpcreadtime",
660 a0d146ed 2005-07-12 devnull "rpcreadcached",
661 a0d146ed 2005-07-12 devnull "rpcreadcachedtime",
662 a0d146ed 2005-07-12 devnull "rpcreaduncached",
663 a0d146ed 2005-07-12 devnull "rpcreaduncachedtime",
664 a0d146ed 2005-07-12 devnull "rpcwrite",
665 a0d146ed 2005-07-12 devnull "rpcwritenew",
666 a0d146ed 2005-07-12 devnull "rpcwriteold",
667 a0d146ed 2005-07-12 devnull "rpcwritefail",
668 a0d146ed 2005-07-12 devnull "rpcwritebyte",
669 a0d146ed 2005-07-12 devnull "rpcwritetime",
670 a0d146ed 2005-07-12 devnull "rpcwritenewtime",
671 a0d146ed 2005-07-12 devnull "rpcwriteoldtime",
672 a0d146ed 2005-07-12 devnull
673 a0d146ed 2005-07-12 devnull "lcachehit",
674 a0d146ed 2005-07-12 devnull "lcachemiss",
675 a0d146ed 2005-07-12 devnull "lcachelookup",
676 a0d146ed 2005-07-12 devnull "lcachewrite",
677 a0d146ed 2005-07-12 devnull "lcachesize",
678 a0d146ed 2005-07-12 devnull "lcachestall",
679 a0d146ed 2005-07-12 devnull "lcachelookuptime",
680 a0d146ed 2005-07-12 devnull
681 a0d146ed 2005-07-12 devnull "dcachehit",
682 a0d146ed 2005-07-12 devnull "dcachemiss",
683 a0d146ed 2005-07-12 devnull "dcachelookup",
684 a0d146ed 2005-07-12 devnull "dcacheread",
685 a0d146ed 2005-07-12 devnull "dcachewrite",
686 a0d146ed 2005-07-12 devnull "dcachedirty",
687 a0d146ed 2005-07-12 devnull "dcachesize",
688 a0d146ed 2005-07-12 devnull "dcacheflush",
689 a0d146ed 2005-07-12 devnull "dcachestall",
690 a0d146ed 2005-07-12 devnull "dcachelookuptime",
691 a0d146ed 2005-07-12 devnull
692 a0d146ed 2005-07-12 devnull "dblockstall",
693 a0d146ed 2005-07-12 devnull "lumpstall",
694 a0d146ed 2005-07-12 devnull
695 a0d146ed 2005-07-12 devnull "icachehit",
696 a0d146ed 2005-07-12 devnull "icachemiss",
697 a0d146ed 2005-07-12 devnull "icachelookup",
698 a0d146ed 2005-07-12 devnull "icachewrite",
699 a0d146ed 2005-07-12 devnull "icachefill",
700 a0d146ed 2005-07-12 devnull "icacheprefetch",
701 a0d146ed 2005-07-12 devnull "icachedirty",
702 a0d146ed 2005-07-12 devnull "icachesize",
703 a0d146ed 2005-07-12 devnull "icacheflush",
704 a0d146ed 2005-07-12 devnull "icachestall",
705 a0d146ed 2005-07-12 devnull "icachelookuptime",
706 a0d146ed 2005-07-12 devnull
707 a0d146ed 2005-07-12 devnull "bloomhit",
708 a0d146ed 2005-07-12 devnull "bloommiss",
709 a0d146ed 2005-07-12 devnull "bloomfalsemiss",
710 a0d146ed 2005-07-12 devnull "bloomlookup",
711 a0d146ed 2005-07-12 devnull "bloomones",
712 a0d146ed 2005-07-12 devnull "bloombits",
713 a0d146ed 2005-07-12 devnull "bloomlookuptime",
714 a0d146ed 2005-07-12 devnull
715 a0d146ed 2005-07-12 devnull "apartread",
716 a0d146ed 2005-07-12 devnull "apartreadbyte",
717 a0d146ed 2005-07-12 devnull "apartwrite",
718 a0d146ed 2005-07-12 devnull "apartwritebyte",
719 a0d146ed 2005-07-12 devnull
720 a0d146ed 2005-07-12 devnull "isectread",
721 a0d146ed 2005-07-12 devnull "isectreadbyte",
722 a0d146ed 2005-07-12 devnull "isectwrite",
723 a0d146ed 2005-07-12 devnull "isectwritebyte",
724 a0d146ed 2005-07-12 devnull
725 a0d146ed 2005-07-12 devnull "sumread",
726 a0d146ed 2005-07-12 devnull "sumreadbyte",
727 a0d146ed 2005-07-12 devnull };
728 a0d146ed 2005-07-12 devnull
729 a0d146ed 2005-07-12 devnull static int
730 a0d146ed 2005-07-12 devnull findname(char *s)
731 a0d146ed 2005-07-12 devnull {
732 a0d146ed 2005-07-12 devnull int i;
733 a0d146ed 2005-07-12 devnull
734 a0d146ed 2005-07-12 devnull for(i=0; i<nelem(graphname); i++)
735 a0d146ed 2005-07-12 devnull if(strcmp(graphname[i], s) == 0)
736 a0d146ed 2005-07-12 devnull return i;
737 a0d146ed 2005-07-12 devnull fprint(2, "no name '%s'\n", s);
738 a0d146ed 2005-07-12 devnull return -1;
739 a0d146ed 2005-07-12 devnull }
740 a0d146ed 2005-07-12 devnull
741 a0d146ed 2005-07-12 devnull static void
742 a0d146ed 2005-07-12 devnull dotextbin(Hio *io, Graph *g)
743 a0d146ed 2005-07-12 devnull {
744 a0d146ed 2005-07-12 devnull int i, nbin;
745 a0d146ed 2005-07-12 devnull Statbin *b, bin[2000]; /* 32 kB, but whack is worse */
746 a0d146ed 2005-07-12 devnull
747 a0d146ed 2005-07-12 devnull needstack(8192); /* double check that bin didn't kill us */
748 a0d146ed 2005-07-12 devnull nbin = 100;
749 a0d146ed 2005-07-12 devnull binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);
750 a0d146ed 2005-07-12 devnull
751 a0d146ed 2005-07-12 devnull hprint(io, "stats\n\n");
752 a0d146ed 2005-07-12 devnull for(i=0; i<nbin; i++){
753 a0d146ed 2005-07-12 devnull b = &bin[i];
754 a0d146ed 2005-07-12 devnull hprint(io, "%d: nsamp=%d min=%d max=%d avg=%d\n",
755 a0d146ed 2005-07-12 devnull i, b->nsamp, b->min, b->max, b->avg);
756 a0d146ed 2005-07-12 devnull }
757 a0d146ed 2005-07-12 devnull }
758 a0d146ed 2005-07-12 devnull
759 a0d146ed 2005-07-12 devnull static int
760 a0d146ed 2005-07-12 devnull xgraph(HConnect *c)
761 a0d146ed 2005-07-12 devnull {
762 a0d146ed 2005-07-12 devnull char *f[20], *s;
763 a0d146ed 2005-07-12 devnull Hio *hout;
764 a0d146ed 2005-07-12 devnull Memimage *m;
765 a0d146ed 2005-07-12 devnull int i, nf, dotext;
766 a0d146ed 2005-07-12 devnull Graph g;
767 a0d146ed 2005-07-12 devnull Arg arg;
768 a0d146ed 2005-07-12 devnull
769 a0d146ed 2005-07-12 devnull s = estrdup(c->req.uri);
770 a0d146ed 2005-07-12 devnull if(0) fprint(2, "graph %s\n" ,s);
771 a0d146ed 2005-07-12 devnull memset(&g, 0, sizeof g);
772 a0d146ed 2005-07-12 devnull nf = getfields(s+strlen("/graph/"), f, nelem(f), 1, "/");
773 a0d146ed 2005-07-12 devnull if(nf < 1)
774 a0d146ed 2005-07-12 devnull goto notfound;
775 a0d146ed 2005-07-12 devnull if((arg.index = findname(f[0])) == -1 && strcmp(f[0], "*") != 0)
776 a0d146ed 2005-07-12 devnull goto notfound;
777 a0d146ed 2005-07-12 devnull g.arg = &arg;
778 a0d146ed 2005-07-12 devnull g.t0 = -120;
779 a0d146ed 2005-07-12 devnull g.t1 = 0;
780 a0d146ed 2005-07-12 devnull g.min = -1;
781 a0d146ed 2005-07-12 devnull g.max = -1;
782 a0d146ed 2005-07-12 devnull g.fn = rawgraph;
783 a0d146ed 2005-07-12 devnull g.wid = -1;
784 a0d146ed 2005-07-12 devnull g.ht = -1;
785 a0d146ed 2005-07-12 devnull dotext = 0;
786 a0d146ed 2005-07-12 devnull g.fill = -1;
787 a0d146ed 2005-07-12 devnull for(i=1; i<nf; i++){
788 a0d146ed 2005-07-12 devnull if(strncmp(f[i], "t0=", 3) == 0)
789 a0d146ed 2005-07-12 devnull g.t0 = atoi(f[i]+3);
790 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "t1=", 3) == 0)
791 a0d146ed 2005-07-12 devnull g.t1 = atoi(f[i]+3);
792 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "min=", 4) == 0)
793 a0d146ed 2005-07-12 devnull g.min = atoi(f[i]+4);
794 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "max=", 4) == 0)
795 a0d146ed 2005-07-12 devnull g.max = atoi(f[i]+4);
796 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "pct=", 4) == 0){
797 a0d146ed 2005-07-12 devnull if((arg.index2 = findname(f[i]+4)) == -1)
798 a0d146ed 2005-07-12 devnull goto notfound;
799 a0d146ed 2005-07-12 devnull g.fn = pctgraph;
800 a0d146ed 2005-07-12 devnull g.min = 0;
801 a0d146ed 2005-07-12 devnull g.max = 100;
802 a0d146ed 2005-07-12 devnull }else if(strncmp(f[i], "pctdiff=", 8) == 0){
803 a0d146ed 2005-07-12 devnull if((arg.index2 = findname(f[i]+8)) == -1)
804 a0d146ed 2005-07-12 devnull goto notfound;
805 a0d146ed 2005-07-12 devnull g.fn = pctdiffgraph;
806 a0d146ed 2005-07-12 devnull g.min = 0;
807 a0d146ed 2005-07-12 devnull g.max = 100;
808 a0d146ed 2005-07-12 devnull }else if(strcmp(f[i], "diff") == 0)
809 a0d146ed 2005-07-12 devnull g.fn = diffgraph;
810 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "text") == 0)
811 a0d146ed 2005-07-12 devnull dotext = 1;
812 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "wid=", 4) == 0)
813 a0d146ed 2005-07-12 devnull g.wid = atoi(f[i]+4);
814 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "ht=", 3) == 0)
815 a0d146ed 2005-07-12 devnull g.ht = atoi(f[i]+3);
816 a0d146ed 2005-07-12 devnull else if(strncmp(f[i], "fill=", 5) == 0)
817 a0d146ed 2005-07-12 devnull g.fill = atoi(f[i]+5);
818 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "diskbw") == 0)
819 a0d146ed 2005-07-12 devnull g.fn = diskgraph;
820 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "iobw") == 0)
821 a0d146ed 2005-07-12 devnull g.fn = iograph;
822 a0d146ed 2005-07-12 devnull else if(strcmp(f[i], "netbw") == 0)
823 a0d146ed 2005-07-12 devnull g.fn = netgraph;
824 a0d146ed 2005-07-12 devnull }
825 a0d146ed 2005-07-12 devnull if(dotext){
826 a0d146ed 2005-07-12 devnull preqtype(c, "text/plain");
827 a0d146ed 2005-07-12 devnull dotextbin(&c->hout, &g);
828 a0d146ed 2005-07-12 devnull hflush(&c->hout);
829 a0d146ed 2005-07-12 devnull return 0;
830 a0d146ed 2005-07-12 devnull }
831 a0d146ed 2005-07-12 devnull
832 a0d146ed 2005-07-12 devnull m = statgraph(&g);
833 a0d146ed 2005-07-12 devnull if(m == nil)
834 a0d146ed 2005-07-12 devnull goto notfound;
835 a0d146ed 2005-07-12 devnull
836 a0d146ed 2005-07-12 devnull if(preqtype(c, "image/png") < 0)
837 a0d146ed 2005-07-12 devnull return -1;
838 a0d146ed 2005-07-12 devnull hout = &c->hout;
839 a0d146ed 2005-07-12 devnull writepng(hout, m);
840 a0d146ed 2005-07-12 devnull qlock(&memdrawlock);
841 a0d146ed 2005-07-12 devnull freememimage(m);
842 a0d146ed 2005-07-12 devnull qunlock(&memdrawlock);
843 a0d146ed 2005-07-12 devnull hflush(hout);
844 a0d146ed 2005-07-12 devnull free(s);
845 a0d146ed 2005-07-12 devnull return 0;
846 a0d146ed 2005-07-12 devnull
847 a0d146ed 2005-07-12 devnull notfound:
848 a0d146ed 2005-07-12 devnull free(s);
849 a0d146ed 2005-07-12 devnull return notfound(c);
850 a0d146ed 2005-07-12 devnull }
851 a0d146ed 2005-07-12 devnull
852 a0d146ed 2005-07-12 devnull static int
853 a0d146ed 2005-07-12 devnull xloglist(HConnect *c)
854 a0d146ed 2005-07-12 devnull {
855 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/html") < 0)
856 a0d146ed 2005-07-12 devnull return -1;
857 a0d146ed 2005-07-12 devnull vtloghlist(&c->hout);
858 a0d146ed 2005-07-12 devnull hflush(&c->hout);
859 a0d146ed 2005-07-12 devnull return 0;
860 a0d146ed 2005-07-12 devnull }
861 a0d146ed 2005-07-12 devnull
862 a0d146ed 2005-07-12 devnull static int
863 a0d146ed 2005-07-12 devnull xlog(HConnect *c)
864 a0d146ed 2005-07-12 devnull {
865 a0d146ed 2005-07-12 devnull char *name;
866 a0d146ed 2005-07-12 devnull VtLog *l;
867 a0d146ed 2005-07-12 devnull
868 a0d146ed 2005-07-12 devnull if(strcmp(c->req.uri, "/log") == 0 || strcmp(c->req.uri, "/log/") == 0)
869 a0d146ed 2005-07-12 devnull return xloglist(c);
870 a0d146ed 2005-07-12 devnull if(strncmp(c->req.uri, "/log/", 5) != 0)
871 a0d146ed 2005-07-12 devnull return notfound(c);
872 a0d146ed 2005-07-12 devnull name = c->req.uri + strlen("/log/");
873 a0d146ed 2005-07-12 devnull l = vtlogopen(name, 0);
874 a0d146ed 2005-07-12 devnull if(l == nil)
875 a0d146ed 2005-07-12 devnull return notfound(c);
876 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/html") < 0){
877 a0d146ed 2005-07-12 devnull vtlogclose(l);
878 a0d146ed 2005-07-12 devnull return -1;
879 a0d146ed 2005-07-12 devnull }
880 a0d146ed 2005-07-12 devnull vtloghdump(&c->hout, l);
881 a0d146ed 2005-07-12 devnull vtlogclose(l);
882 a0d146ed 2005-07-12 devnull hflush(&c->hout);
883 a0d146ed 2005-07-12 devnull return 0;
884 a0d146ed 2005-07-12 devnull }
885 a0d146ed 2005-07-12 devnull
886 a0d146ed 2005-07-12 devnull static int
887 a0d146ed 2005-07-12 devnull xindex(HConnect *c)
888 a0d146ed 2005-07-12 devnull {
889 a0d146ed 2005-07-12 devnull if(preqtype(c, "text/xml") < 0)
890 a0d146ed 2005-07-12 devnull return -1;
891 a0d146ed 2005-07-12 devnull xmlindex(&c->hout, mainindex, "index", 0);
892 a0d146ed 2005-07-12 devnull hflush(&c->hout);
893 a0d146ed 2005-07-12 devnull return 0;
894 a0d146ed 2005-07-12 devnull }
895 a0d146ed 2005-07-12 devnull
896 a0d146ed 2005-07-12 devnull void
897 a0d146ed 2005-07-12 devnull xmlindent(Hio *hout, int indent)
898 a0d146ed 2005-07-12 devnull {
899 a0d146ed 2005-07-12 devnull int i;
900 a0d146ed 2005-07-12 devnull
901 a0d146ed 2005-07-12 devnull for(i = 0; i < indent; i++)
902 a0d146ed 2005-07-12 devnull hputc(hout, '\t');
903 a0d146ed 2005-07-12 devnull }
904 a0d146ed 2005-07-12 devnull
905 a0d146ed 2005-07-12 devnull void
906 a0d146ed 2005-07-12 devnull xmlaname(Hio *hout, char *v, char *tag)
907 a0d146ed 2005-07-12 devnull {
908 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%s\"", tag, v);
909 a0d146ed 2005-07-12 devnull }
910 a0d146ed 2005-07-12 devnull
911 a0d146ed 2005-07-12 devnull void
912 a0d146ed 2005-07-12 devnull xmlscore(Hio *hout, u8int *v, char *tag)
913 a0d146ed 2005-07-12 devnull {
914 a0d146ed 2005-07-12 devnull if(scorecmp(zeroscore, v) == 0)
915 a0d146ed 2005-07-12 devnull return;
916 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%V\"", tag, v);
917 a0d146ed 2005-07-12 devnull }
918 a0d146ed 2005-07-12 devnull
919 a0d146ed 2005-07-12 devnull void
920 a0d146ed 2005-07-12 devnull xmlsealed(Hio *hout, int v, char *tag)
921 a0d146ed 2005-07-12 devnull {
922 a0d146ed 2005-07-12 devnull if(!v)
923 a0d146ed 2005-07-12 devnull return;
924 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"yes\"", tag);
925 a0d146ed 2005-07-12 devnull }
926 a0d146ed 2005-07-12 devnull
927 a0d146ed 2005-07-12 devnull void
928 a0d146ed 2005-07-12 devnull xmlu32int(Hio *hout, u32int v, char *tag)
929 a0d146ed 2005-07-12 devnull {
930 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%ud\"", tag, v);
931 a0d146ed 2005-07-12 devnull }
932 a0d146ed 2005-07-12 devnull
933 a0d146ed 2005-07-12 devnull void
934 a0d146ed 2005-07-12 devnull xmlu64int(Hio *hout, u64int v, char *tag)
935 a0d146ed 2005-07-12 devnull {
936 a0d146ed 2005-07-12 devnull hprint(hout, " %s=\"%llud\"", tag, v);
937 a0d146ed 2005-07-12 devnull }
938 a0d146ed 2005-07-12 devnull
939 a0d146ed 2005-07-12 devnull void
940 a0d146ed 2005-07-12 devnull vtloghdump(Hio *h, VtLog *l)
941 a0d146ed 2005-07-12 devnull {
942 a0d146ed 2005-07-12 devnull int i;
943 a0d146ed 2005-07-12 devnull VtLogChunk *c;
944 a0d146ed 2005-07-12 devnull char *name;
945 a0d146ed 2005-07-12 devnull
946 a0d146ed 2005-07-12 devnull name = l ? l->name : "&lt;nil&gt;";
947 a0d146ed 2005-07-12 devnull
948 a0d146ed 2005-07-12 devnull fprint(2, "hdump xfer %d\n", h->xferenc);
949 a0d146ed 2005-07-12 devnull hprint(h, "<html><head>\n");
950 a0d146ed 2005-07-12 devnull hprint(h, "<title>Venti Server Log: %s</title>\n", name);
951 a0d146ed 2005-07-12 devnull hprint(h, "</head><body>\n");
952 a0d146ed 2005-07-12 devnull hprint(h, "<b>Venti Server Log: %s</b>\n<p>\n", name);
953 a0d146ed 2005-07-12 devnull
954 a0d146ed 2005-07-12 devnull if(l){
955 a0d146ed 2005-07-12 devnull c = l->w;
956 a0d146ed 2005-07-12 devnull for(i=0; i<l->nchunk; i++){
957 a0d146ed 2005-07-12 devnull if(++c == l->chunk+l->nchunk)
958 a0d146ed 2005-07-12 devnull c = l->chunk;
959 a0d146ed 2005-07-12 devnull hwrite(h, c->p, c->wp-c->p);
960 a0d146ed 2005-07-12 devnull }
961 a0d146ed 2005-07-12 devnull }
962 a0d146ed 2005-07-12 devnull hprint(h, "</body></html>\n");
963 a0d146ed 2005-07-12 devnull }
964 a0d146ed 2005-07-12 devnull
965 a0d146ed 2005-07-12 devnull static int
966 a0d146ed 2005-07-12 devnull strpcmp(const void *va, const void *vb)
967 a0d146ed 2005-07-12 devnull {
968 a0d146ed 2005-07-12 devnull return strcmp(*(char**)va, *(char**)vb);
969 a0d146ed 2005-07-12 devnull }
970 a0d146ed 2005-07-12 devnull
971 a0d146ed 2005-07-12 devnull void
972 a0d146ed 2005-07-12 devnull vtloghlist(Hio *h)
973 a0d146ed 2005-07-12 devnull {
974 a0d146ed 2005-07-12 devnull char **p;
975 a0d146ed 2005-07-12 devnull int i, n;
976 a0d146ed 2005-07-12 devnull
977 a0d146ed 2005-07-12 devnull hprint(h, "<html><head>\n");
978 a0d146ed 2005-07-12 devnull hprint(h, "<title>Venti Server Logs</title>\n");
979 a0d146ed 2005-07-12 devnull hprint(h, "</head><body>\n");
980 a0d146ed 2005-07-12 devnull hprint(h, "<b>Venti Server Logs</b>\n<p>\n");
981 a0d146ed 2005-07-12 devnull
982 a0d146ed 2005-07-12 devnull p = vtlognames(&n);
983 a0d146ed 2005-07-12 devnull qsort(p, n, sizeof(p[0]), strpcmp);
984 a0d146ed 2005-07-12 devnull for(i=0; i<n; i++)
985 a0d146ed 2005-07-12 devnull hprint(h, "<a href=\"/log/%s\">%s</a><br>\n", p[i], p[i]);
986 a0d146ed 2005-07-12 devnull vtfree(p);
987 a0d146ed 2005-07-12 devnull hprint(h, "</body></html>\n");
988 a0d146ed 2005-07-12 devnull }