17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <auth.h>
57dd7cddfSDavid du Colombier #include <fcall.h>
67dd7cddfSDavid du Colombier #include <thread.h>
77dd7cddfSDavid du Colombier #include <9p.h>
87dd7cddfSDavid du Colombier #include "snap.h"
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier typedef struct PD PD;
117dd7cddfSDavid du Colombier struct PD {
127dd7cddfSDavid du Colombier int isproc;
137dd7cddfSDavid du Colombier union {
147dd7cddfSDavid du Colombier Proc *p;
157dd7cddfSDavid du Colombier Data *d;
167dd7cddfSDavid du Colombier };
177dd7cddfSDavid du Colombier };
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier PD*
PDProc(Proc * p)207dd7cddfSDavid du Colombier PDProc(Proc *p)
217dd7cddfSDavid du Colombier {
227dd7cddfSDavid du Colombier PD *pd;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier pd = emalloc(sizeof(*pd));
257dd7cddfSDavid du Colombier pd->isproc = 1;
267dd7cddfSDavid du Colombier pd->p = p;
277dd7cddfSDavid du Colombier return pd;
287dd7cddfSDavid du Colombier }
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier PD*
PDData(Data * d)317dd7cddfSDavid du Colombier PDData(Data *d)
327dd7cddfSDavid du Colombier {
337dd7cddfSDavid du Colombier PD *pd;
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier pd = emalloc(sizeof(*pd));
367dd7cddfSDavid du Colombier pd->isproc = 0;
377dd7cddfSDavid du Colombier pd->d = d;
387dd7cddfSDavid du Colombier return pd;
397dd7cddfSDavid du Colombier }
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier void
usage(void)427dd7cddfSDavid du Colombier usage(void)
437dd7cddfSDavid du Colombier {
44*9a747e4fSDavid du Colombier fprint(2, "usage: snapfs [-a] [-m mtpt] file\n");
457dd7cddfSDavid du Colombier exits("usage");
467dd7cddfSDavid du Colombier }
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier char*
memread(Proc * p,File * f,void * buf,long * count,vlong offset)497dd7cddfSDavid du Colombier memread(Proc *p, File *f, void *buf, long *count, vlong offset)
507dd7cddfSDavid du Colombier {
517dd7cddfSDavid du Colombier Page *pg;
527dd7cddfSDavid du Colombier int po;
537dd7cddfSDavid du Colombier
547dd7cddfSDavid du Colombier po = offset%Pagesize;
557dd7cddfSDavid du Colombier if(!(pg = findpage(p, p->pid, f->name[0], offset-po)))
567dd7cddfSDavid du Colombier return "address not mapped";
577dd7cddfSDavid du Colombier
587dd7cddfSDavid du Colombier if(*count > Pagesize-po)
597dd7cddfSDavid du Colombier *count = Pagesize-po;
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier memmove(buf, pg->data+po, *count);
627dd7cddfSDavid du Colombier return nil;
637dd7cddfSDavid du Colombier }
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier char*
dataread(Data * d,void * buf,long * count,vlong offset)667dd7cddfSDavid du Colombier dataread(Data *d, void *buf, long *count, vlong offset)
677dd7cddfSDavid du Colombier {
687dd7cddfSDavid du Colombier assert(d != nil);
697dd7cddfSDavid du Colombier
707dd7cddfSDavid du Colombier if(offset >= d->len) {
717dd7cddfSDavid du Colombier *count = 0;
727dd7cddfSDavid du Colombier return nil;
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier if(offset+*count >= d->len)
767dd7cddfSDavid du Colombier *count = d->len - offset;
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier memmove(buf, d->data+offset, *count);
797dd7cddfSDavid du Colombier return nil;
807dd7cddfSDavid du Colombier }
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier void
fsread(Req * r)83*9a747e4fSDavid du Colombier fsread(Req *r)
847dd7cddfSDavid du Colombier {
85*9a747e4fSDavid du Colombier char *e;
867dd7cddfSDavid du Colombier PD *pd;
87*9a747e4fSDavid du Colombier Fid *fid;
88*9a747e4fSDavid du Colombier void *data;
89*9a747e4fSDavid du Colombier vlong offset;
90*9a747e4fSDavid du Colombier long count;
917dd7cddfSDavid du Colombier
92*9a747e4fSDavid du Colombier fid = r->fid;
93*9a747e4fSDavid du Colombier data = r->ofcall.data;
94*9a747e4fSDavid du Colombier offset = r->ifcall.offset;
95*9a747e4fSDavid du Colombier count = r->ifcall.count;
967dd7cddfSDavid du Colombier pd = fid->file->aux;
97*9a747e4fSDavid du Colombier
987dd7cddfSDavid du Colombier if(pd->isproc)
99*9a747e4fSDavid du Colombier e = memread(pd->p, fid->file, data, &count, offset);
1007dd7cddfSDavid du Colombier else
101*9a747e4fSDavid du Colombier e = dataread(pd->d, data, &count, offset);
102*9a747e4fSDavid du Colombier
103*9a747e4fSDavid du Colombier if(e == nil)
104*9a747e4fSDavid du Colombier r->ofcall.count = count;
105*9a747e4fSDavid du Colombier respond(r, e);
1067dd7cddfSDavid du Colombier }
1077dd7cddfSDavid du Colombier
108*9a747e4fSDavid du Colombier Srv fs = {
109*9a747e4fSDavid du Colombier .read = fsread,
1107dd7cddfSDavid du Colombier };
1117dd7cddfSDavid du Colombier
112*9a747e4fSDavid du Colombier File*
ecreatefile(File * a,char * b,char * c,ulong d,void * e)113*9a747e4fSDavid du Colombier ecreatefile(File *a, char *b, char *c, ulong d, void *e)
114*9a747e4fSDavid du Colombier {
115*9a747e4fSDavid du Colombier File *f;
116*9a747e4fSDavid du Colombier
117*9a747e4fSDavid du Colombier f = createfile(a, b, c, d, e);
118*9a747e4fSDavid du Colombier if(f == nil)
119*9a747e4fSDavid du Colombier sysfatal("error creating snap tree: %r");
120*9a747e4fSDavid du Colombier return f;
121*9a747e4fSDavid du Colombier }
122*9a747e4fSDavid du Colombier
1237dd7cddfSDavid du Colombier void
main(int argc,char ** argv)1247dd7cddfSDavid du Colombier main(int argc, char **argv)
1257dd7cddfSDavid du Colombier {
1267dd7cddfSDavid du Colombier Biobuf *b;
1277dd7cddfSDavid du Colombier Data *d;
1287dd7cddfSDavid du Colombier File *fdir, *f;
1297dd7cddfSDavid du Colombier Proc *p, *plist;
1307dd7cddfSDavid du Colombier Tree *tree;
131*9a747e4fSDavid du Colombier char *mtpt, buf[32];
1327dd7cddfSDavid du Colombier int i, mflag;
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier mtpt = "/proc";
1357dd7cddfSDavid du Colombier mflag = MBEFORE;
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier ARGBEGIN{
138*9a747e4fSDavid du Colombier case 'D':
139*9a747e4fSDavid du Colombier chatty9p++;
140*9a747e4fSDavid du Colombier break;
141*9a747e4fSDavid du Colombier case 'd':
142*9a747e4fSDavid du Colombier debug = 1;
143*9a747e4fSDavid du Colombier break;
1447dd7cddfSDavid du Colombier case 'a':
1457dd7cddfSDavid du Colombier mflag = MAFTER;
1467dd7cddfSDavid du Colombier break;
1477dd7cddfSDavid du Colombier case 'm':
1487dd7cddfSDavid du Colombier mtpt = ARGF();
1497dd7cddfSDavid du Colombier break;
1507dd7cddfSDavid du Colombier default:
1517dd7cddfSDavid du Colombier usage();
1527dd7cddfSDavid du Colombier }ARGEND
1537dd7cddfSDavid du Colombier
1547dd7cddfSDavid du Colombier if(argc != 1)
1557dd7cddfSDavid du Colombier usage();
1567dd7cddfSDavid du Colombier
1577dd7cddfSDavid du Colombier b = Bopen(argv[0], OREAD);
1587dd7cddfSDavid du Colombier if(b == nil) {
1597dd7cddfSDavid du Colombier fprint(2, "cannot open \"%s\": %r\n", argv[0]);
1607dd7cddfSDavid du Colombier exits("Bopen");
1617dd7cddfSDavid du Colombier }
1627dd7cddfSDavid du Colombier
1637dd7cddfSDavid du Colombier if((plist = readsnap(b)) == nil) {
1647dd7cddfSDavid du Colombier fprint(2, "readsnap fails\n");
1657dd7cddfSDavid du Colombier exits("readsnap");
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier
168*9a747e4fSDavid du Colombier tree = alloctree(nil, nil, DMDIR|0555, nil);
169*9a747e4fSDavid du Colombier fs.tree = tree;
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier for(p=plist; p; p=p->link) {
172*9a747e4fSDavid du Colombier print("process %ld %.*s\n", p->pid, 28, p->d[Pstatus] ? p->d[Pstatus]->data : "");
1737dd7cddfSDavid du Colombier
174*9a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%ld", p->pid);
175*9a747e4fSDavid du Colombier fdir = ecreatefile(tree->root, buf, nil, DMDIR|0555, nil);
176*9a747e4fSDavid du Colombier ecreatefile(fdir, "ctl", nil, 0777, nil);
177*9a747e4fSDavid du Colombier if(p->text)
178*9a747e4fSDavid du Colombier ecreatefile(fdir, "text", nil, 0777, PDProc(p));
1797dd7cddfSDavid du Colombier
180*9a747e4fSDavid du Colombier ecreatefile(fdir, "mem", nil, 0666, PDProc(p));
1817dd7cddfSDavid du Colombier for(i=0; i<Npfile; i++) {
1827dd7cddfSDavid du Colombier if(d = p->d[i]) {
183*9a747e4fSDavid du Colombier f = ecreatefile(fdir, pfile[i], nil, 0666, PDData(d));
1847dd7cddfSDavid du Colombier f->length = d->len;
1857dd7cddfSDavid du Colombier }
1867dd7cddfSDavid du Colombier }
1877dd7cddfSDavid du Colombier }
1887dd7cddfSDavid du Colombier
189*9a747e4fSDavid du Colombier postmountsrv(&fs, nil, mtpt, mflag);
1907dd7cddfSDavid du Colombier exits(0);
1917dd7cddfSDavid du Colombier }
192