9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* Re: [9fans] watch command
@ 2005-04-20  2:09 YAMANASHI Takeshi
  2005-04-20  5:14 ` Ronald G. Minnich
  2005-04-20 15:06 ` Ronald G. Minnich
  0 siblings, 2 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-20  2:09 UTC (permalink / raw)
  To: 9fans

> now that is cool. Could you beat on iostats to do similar things?

How do you want to beat iostats?  I'm not familiar with iostats...
Thanks.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-21  0:37 YAMANASHI Takeshi
  0 siblings, 0 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-21  0:37 UTC (permalink / raw)
  To: 9fans

> > How do you want to beat iostats?  I'm not familiar with iostats...
> Check it out, it's very cool. man iostats. The people on this list clued 
> me in to it.

Yeah.  I think I got your point.  It should be trivial to add an option to
iostats so that it posts /srv/iostatsctl and messages should appear there
whenever file metadata changes are occured.

One might even be as ambitious as adding another option to indicate iostats
of which files should be notified by proto(2) file.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-20  2:07 YAMANASHI Takeshi
  0 siblings, 0 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-20  2:07 UTC (permalink / raw)
  To: 9fans

> But what about a file that the server can provide that provides info about
> metadata changes

This would solve the problem that the "real" file might be changed
bypassing the watch file server.

The implementation need to be careful about not letting give the
information of files under permission guarded directories, though.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-20  1:55 YAMANASHI Takeshi
  0 siblings, 0 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-20  1:55 UTC (permalink / raw)
  To: 9fans

Anyway, it's here:
	% mk install
	% watchfs main.c

"cat /n/watch/ctl" will block until a change has been made
to /n/watch/data/main.c.

KNOWN BUGS:
	- it doesn't care about Tflush yet.
	- it only accepts files in the current directory.


# To unbundle, run this file
echo mkfile
sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile'
-</$objtype/mkfile
-BIN=$home/bin/$objtype
-
-TARG=watchfs
-OFILES=\
-	main.$O\
-
-</sys/src/cmd/mkone
//GO.SYSIN DD mkfile
echo main.c
sed 's/.//' >main.c <<'//GO.SYSIN DD main.c'
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-
-int dbg;
-
-char *uname;
-Channel *cctl, *cctlwait;
-Channel *pctl, *pctlwait;
-Channel *creq;
-
-typedef struct Watchfile	Watchfile;
-struct Watchfile {
-	Ref;
-	Qid qid;
-	int fd;
-	char *name;
-	int dirty;
-};
-
-Watchfile wtab[10];
-int nw;
-
-void wtopen(Req*);
-void wtread(Req*);
-void wtwrite(Req*);
-void wtdestroyfid(Fid*);
-void takedown(Srv*);
-
-enum{
-	Qdata= 0,
-	Qctl= 1,
-
-	STACK = 8192,
-};
-
-int chatty9p;
-Srv fs = {
-	.open= wtopen,
-	.read= wtread,
-	.write= wtwrite,
-	.destroyfid = wtdestroyfid,
-	.end= takedown,
-};
-
-static void
-dumpQid(Dir *d)
-{
-	ulong path;
-	path = d->qid.path;
-	fprint(2, "name=%s qid=%lux\n", d->name, path);
-}
-
-static void
-dumpWF(void)
-{
-	int i;
-
-	for(i=0; i<nw; i++)
-		fprint(2, "dumpWF: %s %llud\n", wtab[i].name, wtab[i].qid.path);
-}	
-
-Watchfile *
-findtab(ulong path)
-{
-	int i;
-	for(i=0; i<nw; i++)
-		if(wtab[i].qid.path == path)
-			return &wtab[i];
-	return nil;
-}
-
-void
-wtopen(Req *r)
-{
-	ulong path;
-	Watchfile *wf;
-
-	path = r->fid->qid.path;
-	switch(path){
-	case Qctl:
-	case Qdata:
-		respond(r, nil);
-		return;
-	}
-
-	/* data/... */
-	wf = findtab(path);
-	if(wf == nil){
-		respond(r, "no file");
-		return;
-	}
-	if(dbg)
-		fprint(2, "wtopen: %s %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
-	incref(wf);
-	if(wf->fd < 0){
-		wf->fd = open(wf->name, r->ifcall.mode);
-		wf->dirty = 0;
-	}
-	if(r->ifcall.mode&OTRUNC)
-		r->fid->file->length = 0;
-	respond(r, nil);
-}
-
-void
-wtread(Req *r)
-{
-	char buf[512];
-	int n;
-	ulong path;
-	Watchfile *wf;
-
-	path = r->fid->qid.path;
-	switch(path){
-	case Qdata:
-	case Qctl:
-		sendp(creq, r);
-		return;
-	}
-
-	/* data/... */
-	wf = findtab(r->fid->qid.path);
-	if(wf == nil){
-		respond(r, "no such qid");
-		return;
-	}
-	if(wf->fd < 0){
-		respond(r, "no fd");
-		return;
-	}
-	if(dbg)
-		fprint(2, "wtread: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
-	n = pread(wf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
-	if(n < 0){
-		rerrstr(buf, sizeof buf);
-		respond(r, buf);
-		return;
-	}
-	r->ofcall.count = n;
-	respond(r, nil);
-}
-
-void
-wtwrite(Req *r)
-{
-	char buf[512];
-	int n;
-	ulong path;
-	vlong offset;
-	Watchfile *wf;
-
-	path = r->fid->qid.path;
-	offset = r->ifcall.offset;
-
-	switch(path){
-	case Qdata:
-	case Qctl:
-		snprint(buf, sizeof buf, "not yet %lux", path);
-		respond(r, buf);
-		return;
-	}
-
-	/* data/... */
-	wf = findtab(path);
-	if(wf == nil){
-		respond(r, "no such qid");
-		return;
-	}
-	if(dbg)
-		fprint(2, "wtwrite: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
-	if(wf->fd < 0){
-		respond(r, "no fd");
-		return;
-	}
-
-	n = pwrite(wf->fd, r->ifcall.data, r->ifcall.count, r->ifcall.offset);
-	if(n < 0){
-		rerrstr(buf, sizeof buf);
-		respond(r, buf);
-		return;
-	}
-	if(n+offset >= r->fid->file->length)
-		r->fid->file->length = n+offset;
-	wf->dirty++;
-	r->ofcall.count = n;
-	respond(r, nil);
-
-}
-
-void
-wtdestroyfid(Fid *fid)
-{
-	ulong path;
-	Watchfile *wf;
-
-	path = fid->qid.path;
-	wf = findtab(path);
-	if(wf == nil)
-		return;
-
-	if(dbg)
-		fprint(2, "wtdestroyfid: %s ref %ld fd %d\n", wf->name, wf->ref, wf->fd);
-
-	if(wf->fd >= 0){
-		if(decref(wf) == 0){
-			if(wf->dirty){
-				sendp(cctl, wf);
-				recvp(cctlwait);
-			}
-			close(wf->fd);
-			wf->fd = -1;
-			wf->dirty = 0;
-		}
-	}
-}
-
-Tree *
-inittree(char **argv)
-{
-	Tree *tree;
-	File *df;
-
-	tree = alloctree(uname, uname, DMDIR|0555, nil);
-	df = createfile(tree->root, "data", uname, DMDIR|0555, nil);
-	createfile(tree->root, "ctl", uname, 0660, nil);
-
-	for(;*argv;argv++){
-		File *f;
-		Dir *d;
-		d = dirstat(*argv);
-		if(d == nil)
-			continue;
-		if(dbg)
-			fprint(2, "dir: name %s len %lld\n", d->name, d->length);
-		f = createfile(df, *argv, uname, 0660, nil);
-		wtab[nw].qid = f->qid;
-		wtab[nw].name = estrdup9p(*argv);
-		wtab[nw].fd = -1;
-		f->length = d->length;
-		nw++;
-	}
-
-	return tree;
-}
-
-static void
-pollthread(void*)
-{
-	for(;;){
-		sleep(1);
-	}
-}
-
-static void
-ctlthread(void*)
-{
-	int i, np = 0;
-	Alt a[4];
-	Req *r, *rtab[10];
-	Watchfile *wf;
-
-	threadsetname("ctlthread");
-
-	a[0].op = CHANRCV;
-	a[0].c = creq;
-	a[0].v = &r;
-	a[1].op = CHANRCV;
-	a[1].c = cctl;
-	a[1].v = &wf;
-	a[2].op = CHANRCV;
-	a[2].c = pctl;
-	a[2].v = &wf;
-	a[3].op = CHANEND;
-
-	for(;;){
-		switch(alt(a)){
-		case 0: /* creq: someone tries to read ctl */
-			rtab[np++] = r;
-			break;
-
-		case 1: /* cctl: ready to serve ctl */
-			for(i=0; i<np; i++){
-				r = rtab[i];
-				snprint(r->ofcall.data, r->ifcall.count,
-					"%s %llud\n", wf->name, wf->qid.path);
-				r->ofcall.count = strlen(r->ofcall.data);
-				respond(r, nil);
-			}
-			np = 0;
-			sendp(cctlwait, 0);
-			break;
-
-		case 2: /* pctl: poll says modified */
-			for(i=0; i<np; i++){
-				r = rtab[i];
-				snprint(r->ofcall.data, r->ifcall.count,
-					"%s %llud\n", wf->name, wf->qid.path);
-				r->ofcall.count = strlen(r->ofcall.data);
-				respond(r, nil);
-			}
-			np = 0;
-			sendp(pctlwait, 0);
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-
-void
-initctl(void)
-{
-	cctl = chancreate(sizeof(void*), 0);
-	cctlwait = chancreate(sizeof(void*), 0);
-	pctl = chancreate(sizeof(void*), 0);
-	pctlwait = chancreate(sizeof(void*), 0);
-	creq = chancreate(sizeof(void*), 0);
-	procrfork(ctlthread, nil, STACK, RFNAMEG);
-	procrfork(pollthread, nil, STACK, RFNAMEG);
-}
-
-void
-usage(void)
-{
-	fprint(2, "usage:  watchfs files...\n");
-}
-
-void
-threadmain(int argc, char *argv[])
-{
-
-	ARGBEGIN{
-	case 'd':
-		dbg++;
-		break;
-	case 'D':
-		chatty9p++;
-		break;
-	}ARGEND;
-
-	uname = getuser();
-
-	fs.tree = inittree(&argv[0]);
-	if(dbg)
-		dumpWF();
-
-	initctl();
-	threadpostmountsrv(&fs, nil, "/n/watch", MREPL|MCREATE);
-	threadexits(0);
-}
-
-void
-takedown(Srv*)
-{
-	threadexitsall("done");
-}
-
-
-
-
//GO.SYSIN DD main.c




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-19 10:50 YAMANASHI Takeshi
  0 siblings, 0 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19 10:50 UTC (permalink / raw)
  To: 9fans

On Tue Apr 19 19:06:59 JST 2005, Charles Forsyth wrote:
> >>What am I missing?
> 
> nothing technical, just that he's probably willing to assume that all
> the accesses he cares about in this case will happen through that
> interposed file server, and in particular other users aren't involved.

Exactly. :)

Adding to the above points, it would work as a good introductory for me
to write a tiny file server using 9p(2).
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-19  8:59 YAMANASHI Takeshi
  2005-04-19  9:19 ` Fco. J. Ballesteros
  2005-04-19 15:00 ` Ronald G. Minnich
  0 siblings, 2 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19  8:59 UTC (permalink / raw)
  To: 9fans

On Tue Apr 19 17:37:07 JST 2005, Fco. J. Ballesteros wrote:
> This is how we do it.
 :
>      NAME
>           poll - poll files for changes

Nice. :)

BTW, watchfs won't poll files.  Watchfs interposes itself
in the middle of a 9p transaction and send a message to
activate a program whenever it sees Tclunk on modified files.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-19  7:13 YAMANASHI Takeshi
  0 siblings, 0 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19  7:13 UTC (permalink / raw)
  To: 9fans

> i'd forgotten about watch, but iirc it was meant to
> keep an eye on 1 file.

Yes.  But keeping both eyes on several files is a natural
extension to the original idea, isn't it?

> i would think hard before embarking on a mkfs.

Just executing "Put; mk" should fine for acme users.
Sadly enough, acme doesn't like the combination of
internal and external command.

	Put: '/bin/Put' file does not exist
	mk: nothing to mk
	rc 8436: mk 8438: error
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-19  6:57 YAMANASHI Takeshi
  2005-04-19 10:47 ` Abhey Shah
  0 siblings, 1 reply; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19  6:57 UTC (permalink / raw)
  To: 9fans

> Then, what is the purpose for?

Just as same as the original watch (troff type setting).
Actually, I'm doing a LaTeX work now, and thought it would be
handy if the "platex; xdvi" command chain is run automatically.

> I thought you are going to watch, say, kernel sources changed by
> someone else...

oh, it would be fun to see diff whenever some changed some file, too.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: [9fans] watch command
@ 2005-04-19  6:49 YAMANASHI Takeshi
  2005-04-19  6:50 ` Kenji Okamoto
  2005-04-19  6:55 ` boyd, rounin
  0 siblings, 2 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19  6:49 UTC (permalink / raw)
  To: 9fans

> In your example, are you going to have a huge list of files to be watched?

I tend to keep my working list rather small (~5 files).
I'm not such smart that I can manage a huge list of files.
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread
* [9fans] watch command
@ 2005-04-19  6:17 YAMANASHI Takeshi
  2005-04-19  6:37 ` Kenji Okamoto
  2005-04-19  8:35 ` Fco. J. Ballesteros
  0 siblings, 2 replies; 26+ messages in thread
From: YAMANASHI Takeshi @ 2005-04-19  6:17 UTC (permalink / raw)
  To: 9fans

I read about "watch" command in the mpx paper (*) and thought
it's interesting.  The paper mentions the commandline:
	watch fig1.pic | pic | troff | proof
and the pipe line runs whenever fig1.pic is modified.
Does anyone have a similar program in his pocket?

(*) hget http://cm.bell-labs.com/cm/cs/doc/83/mpx.ps.gz | gunzip | page


I'm thinking of writing a file server (watchfs) which will serve:
  /n/watch/ctl
  /n/watch/data/a.c
  /n/watch/data/b.c

Whenever a.c and b.c are changed, a text will appear on the ctl file.
Thus, you can do something like:
	% while(){read /n/watch/ctl; mk}

How's this idea?
-- 




^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2005-04-21  0:37 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-20  2:09 [9fans] watch command YAMANASHI Takeshi
2005-04-20  5:14 ` Ronald G. Minnich
2005-04-20 15:06 ` Ronald G. Minnich
  -- strict thread matches above, loose matches on Subject: below --
2005-04-21  0:37 YAMANASHI Takeshi
2005-04-20  2:07 YAMANASHI Takeshi
2005-04-20  1:55 YAMANASHI Takeshi
2005-04-19 10:50 YAMANASHI Takeshi
2005-04-19  8:59 YAMANASHI Takeshi
2005-04-19  9:19 ` Fco. J. Ballesteros
2005-04-19 10:06   ` Charles Forsyth
2005-04-19 15:01   ` Ronald G. Minnich
2005-04-19 15:23     ` Fco. J. Ballesteros
2005-04-19 15:53       ` Lucio De Re
2005-04-19 15:59         ` Dan Cross
2005-04-19 16:02     ` Steve Simon
2005-04-19 16:23     ` boyd, rounin
2005-04-19 15:00 ` Ronald G. Minnich
2005-04-19  7:13 YAMANASHI Takeshi
2005-04-19  6:57 YAMANASHI Takeshi
2005-04-19 10:47 ` Abhey Shah
2005-04-19  6:49 YAMANASHI Takeshi
2005-04-19  6:50 ` Kenji Okamoto
2005-04-19  6:55 ` boyd, rounin
2005-04-19  6:17 YAMANASHI Takeshi
2005-04-19  6:37 ` Kenji Okamoto
2005-04-19  8:35 ` Fco. J. Ballesteros

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).