xref: /plan9/sys/src/cmd/snap/snapfs.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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