9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] mycroftiv's zrv and rfork V, patch for current 9front
@ 2021-01-06 10:17 sirjofri+ml-9front
  2021-01-06 19:05 ` cinap_lenrek
  0 siblings, 1 reply; 8+ messages in thread
From: sirjofri+ml-9front @ 2021-01-06 10:17 UTC (permalink / raw)
  To: 9front

[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

Hello all,

since some people asked mycroftiv about rfork V (and zrv) here's a
patch for current (yesterday) 9front.

Some things changed since the last official ants diffs, so manual
adjustments were needed.  Also don't forget backups!

The patch should apply cleanly.  Rebuilding libc, rc and kernel is
needed (libc before rc!).

This patch does _not_ include the changes to postmountsrv, which make
it possible to srv directly to /zrv (`application -s name` vs
`application -s /zrv/name`).


All credits go to mycroftiv for this.


sirjofri

.

[-- Attachment #2: Type: text/plain, Size: 7461 bytes --]

diff -r d1a5cac82bd7 sys/include/libc.h
--- a/sys/include/libc.h	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/include/libc.h	Tue Jan 05 17:22:13 2021 +0100
@@ -624,6 +624,7 @@
 	RFPROC		= (1<<4),
 	RFMEM		= (1<<5),
 	RFNOWAIT	= (1<<6),
+	RFCSRVG		= (1<<9),
 	RFCNAMEG	= (1<<10),
 	RFCENVG		= (1<<11),
 	RFCFDG		= (1<<12),
diff -r d1a5cac82bd7 sys/lib/dist/cfg/plan9.ini
--- a/sys/lib/dist/cfg/plan9.ini	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/lib/dist/cfg/plan9.ini	Tue Jan 05 17:22:13 2021 +0100
@@ -3,3 +3,4 @@
 mouseport=ask
 monitor=ask
 vgasize=ask
+bootfile=/amd64/9pc64
diff -r d1a5cac82bd7 sys/src/9/pc64/pc64
--- a/sys/src/9/pc64/pc64	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/pc64/pc64	Tue Jan 05 17:22:13 2021 +0100
@@ -10,6 +10,7 @@
 	proc
 	mnt
 	srv
+	zrv
 	shr
 	dup
 	rtc
diff -r d1a5cac82bd7 sys/src/9/port/auth.c
--- a/sys/src/9/port/auth.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/auth.c	Tue Jan 05 17:22:13 2021 +0100
@@ -141,6 +141,7 @@
 
 	renameuser(eve, buf);
 	srvrenameuser(eve, buf);
+	zrvrenameuser(eve, buf);
 	shrrenameuser(eve, buf);
 	kstrdup(&eve, buf);
 	procsetuser(buf);
diff -r d1a5cac82bd7 sys/src/9/port/devroot.c
--- a/sys/src/9/port/devroot.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/devroot.c	Tue Jan 05 17:22:13 2021 +0100
@@ -108,6 +108,7 @@
 	addrootdir("root");
 	addrootdir("srv");
 	addrootdir("shr");
+	addrootdir("zrv");
 }
 
 static Chan*
diff -r d1a5cac82bd7 sys/src/9/port/devsrv.c
--- a/sys/src/9/port/devsrv.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/devsrv.c	Tue Jan 05 17:22:13 2021 +0100
@@ -6,19 +6,7 @@
 #include	"../port/error.h"
 
 
-typedef struct Srv Srv;
-struct Srv
-{
-	char	*name;
-	char	*owner;
-	ulong	perm;
-	Chan	*chan;
-	Srv	*link;
-	ulong	path;
-};
-
 static QLock	srvlk;
-static Srv	*srv;
 static int	qidpath;
 
 static Srv*
@@ -26,7 +14,7 @@
 {
 	Srv *sp;
 
-	for(sp = srv; sp != nil; sp = sp->link) {
+	for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
 		if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0))
 			return sp;
 	}
@@ -48,7 +36,7 @@
 	if(name != nil)
 		sp = srvlookup(name, -1);
 	else {
-		for(sp = srv; sp != nil && s > 0; sp = sp->link)
+		for(sp = up->sgrp->srvgrp; sp != nil && s > 0; sp = sp->link)
 			s--;
 	}
 	if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) {
@@ -95,7 +83,7 @@
 
 	s = nil;
 	qlock(&srvlk);
-	for(sp = srv; sp != nil; sp = sp->link) {
+	for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
 		if(sp->chan == c){
 			s = malloc(3+strlen(sp->name)+1);
 			if(s != nil)
@@ -183,8 +171,8 @@
 	c->qid.path = sp->path;
 	c->qid.type = QTFILE;
 
-	sp->link = srv;
-	srv = sp;
+	sp->link = up->sgrp->srvgrp;
+	up->sgrp->srvgrp = sp;
 
 	qunlock(&srvlk);
 	poperror();
@@ -208,7 +196,7 @@
 		qunlock(&srvlk);
 		nexterror();
 	}
-	l = &srv;
+	l = &up->sgrp->srvgrp;
 	for(sp = *l; sp != nil; sp = *l) {
 		if(sp->path == c->qid.path)
 			break;
@@ -378,12 +366,30 @@
 };
 
 void
+closesgrp(Sgrp *sg)
+{
+	Srv *sp;
+	Srv *tsp;
+
+	if(decref(sg) == 0){
+		sp = sg->srvgrp;
+		while(sp!=nil){
+			tsp=sp;
+			sp=sp->link;
+			free(tsp);
+		}
+		free(sg);
+	}
+	return;
+}
+
+void
 srvrenameuser(char *old, char *new)
 {
 	Srv *sp;
 
 	qlock(&srvlk);
-	for(sp = srv; sp != nil; sp = sp->link) {
+	for(sp = up->sgrp->srvgrp; sp != nil; sp = sp->link) {
 		if(sp->owner != nil && strcmp(old, sp->owner) == 0)
 			kstrdup(&sp->owner, new);
 	}
diff -r d1a5cac82bd7 sys/src/9/port/portdat.h
--- a/sys/src/9/port/portdat.h	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/portdat.h	Tue Jan 05 17:22:13 2021 +0100
@@ -44,6 +44,8 @@
 typedef struct Segment	Segment;
 typedef struct Segio	Segio;
 typedef struct Sema	Sema;
+typedef struct Sgrp Sgrp;
+typedef struct Srv Srv;
 typedef struct Timer	Timer;
 typedef struct Timers	Timers;
 typedef struct Uart	Uart;
@@ -468,6 +470,21 @@
 	Page	*pghash[PGHSIZE];	/* page cache */
 };
 
+struct Srv
+{
+	char	*name;
+	char	*owner;
+	ulong	perm;
+	Chan	*chan;
+	Srv	*link;
+	ulong	path;
+};
+
+struct Sgrp
+{
+	Ref;
+	Srv	*srvgrp;
+};
 
 struct Pgrp
 {
@@ -576,6 +593,7 @@
 	RFPROC		= (1<<4),
 	RFMEM		= (1<<5),
 	RFNOWAIT	= (1<<6),
+	RFCSRVG		= (1<<9),
 	RFCNAMEG	= (1<<10),
 	RFCENVG		= (1<<11),
 	RFCFDG		= (1<<12),
@@ -678,6 +696,7 @@
 	Egrp 	*egrp;		/* Environment group */
 	Fgrp	*fgrp;		/* File descriptor group */
 	Rgrp	*rgrp;		/* Rendez group */
+	Sgrp	*sgrp;		/* Srv group */
 
 	Fgrp	*closingfgrp;	/* used during teardown */
 
diff -r d1a5cac82bd7 sys/src/9/port/portfns.h
--- a/sys/src/9/port/portfns.h	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/portfns.h	Tue Jan 05 17:22:13 2021 +0100
@@ -34,6 +34,7 @@
 void		closefgrp(Fgrp*);
 void		closepgrp(Pgrp*);
 void		closergrp(Rgrp*);
+void		closesgrp(Sgrp*);
 long		clrfpintr(void);
 void		cmderror(Cmdbuf*, char*);
 int		cmount(Chan**, Chan*, int, char*);
@@ -340,6 +341,8 @@
 void		splxpc(int);
 char*		srvname(Chan*);
 void		srvrenameuser(char*, char*);
+char*		zrvname(Chan*);
+void		zrvrenameuser(char*, char*);
 void		shrrenameuser(char*, char*);
 int		swapcount(uintptr);
 int		swapfull(void);
diff -r d1a5cac82bd7 sys/src/9/port/proc.c
--- a/sys/src/9/port/proc.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/proc.c	Tue Jan 05 17:22:13 2021 +0100
@@ -1092,6 +1092,7 @@
 	Egrp *egrp;
 	Rgrp *rgrp;
 	Pgrp *pgrp;
+	Sgrp *sgrp;
 	Chan *dot;
 	void (*pt)(Proc*, int, vlong);
 
@@ -1122,6 +1123,13 @@
 		closeegrp(egrp);
 	if(rgrp != nil)
 		closergrp(rgrp);
+	/* sgrp is nilled out here because closefgrp may need srvclose */
+	qlock(&up->debug);
+	sgrp = up->sgrp;
+	up->sgrp = nil;
+	qunlock(&up->debug);
+	if(sgrp != nil)
+		closesgrp(sgrp);
 	if(dot != nil)
 		cclose(dot);
 	if(pgrp != nil)
diff -r d1a5cac82bd7 sys/src/9/port/sysproc.c
--- a/sys/src/9/port/sysproc.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/sysproc.c	Tue Jan 05 17:22:13 2021 +0100
@@ -32,6 +32,7 @@
 	Pgrp *opg;
 	Rgrp *org;
 	Egrp *oeg;
+	Sgrp *osg;
 	ulong pid, flag;
 	Mach *wm;
 
@@ -71,6 +72,12 @@
 			up->rgrp = newrgrp();
 			closergrp(org);
 		}
+		if(flag & RFCSRVG) {
+			osg = up->sgrp;
+			up->sgrp = smalloc(sizeof(Sgrp));
+			up->sgrp->ref = 1;
+			closesgrp(osg);
+		}
 		if(flag & (RFENVG|RFCENVG)) {
 			oeg = up->egrp;
 			up->egrp = smalloc(sizeof(Egrp));
@@ -187,6 +194,15 @@
 		p->rgrp = up->rgrp;
 	}
 
+	/* Srv group */
+	if(flag & RFCSRVG) {
+		p->sgrp = smalloc(sizeof(Sgrp));
+		p->sgrp->ref = 1;
+	} else {
+		p->sgrp = up->sgrp;
+		incref(p->sgrp);
+	}
+
 	/* Environment group */
 	if(flag & (RFENVG|RFCENVG)) {
 		p->egrp = smalloc(sizeof(Egrp));
diff -r d1a5cac82bd7 sys/src/9/port/userinit.c
--- a/sys/src/9/port/userinit.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/9/port/userinit.c	Tue Jan 05 17:22:13 2021 +0100
@@ -31,6 +31,8 @@
 	up->pgrp = newpgrp();
 	up->egrp = smalloc(sizeof(Egrp));
 	up->egrp->ref = 1;
+	up->sgrp = smalloc(sizeof(Sgrp));
+	up->sgrp->ref = 1;
 	up->fgrp = dupfgrp(nil);
 	up->rgrp = newrgrp();
 
diff -r d1a5cac82bd7 sys/src/cmd/rc/plan9.c
--- a/sys/src/cmd/rc/plan9.c	Tue Jan 05 22:36:03 2021 +1030
+++ b/sys/src/cmd/rc/plan9.c	Tue Jan 05 17:22:13 2021 +0100
@@ -81,11 +81,13 @@
 			arg|=RFFDG;    break;
 		case 'F':
 			arg|=RFCFDG;   break;
+		case 'V':
+			arg|=RFCSRVG;  break;
 		}
 		break;
 	default:
 	Usage:
-		pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word);
+		pfmt(err, "Usage: %s [fnesFNEmV]\n", runq->argv->words->word);
 		setstatus("rfork usage");
 		poplist();
 		return;

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 10:17 [9front] mycroftiv's zrv and rfork V, patch for current 9front sirjofri+ml-9front
@ 2021-01-06 19:05 ` cinap_lenrek
  2021-01-06 19:11   ` ori
  0 siblings, 1 reply; 8+ messages in thread
From: cinap_lenrek @ 2021-01-06 19:05 UTC (permalink / raw)
  To: 9front

this implementation seemes flawed to me.

closesgrp() appears only to free the memory of the Srv*
nodes, but doesnt actually free srv->chan, srv->owner
and srv->name.

also the locking seems suspicious. as the global Srv*
list was just replaced with per process one, but we'r
still only have a single srvlock to serialize
concurrent access to it.

so far, the srvgrp can only be reset or shared depending
of the RFCSRVG flag. once you implement copying you'd
need a lock per Sgrp. i'd prefer to have a lock per
Sgrp right now and remove the global srvlock.

pexit() should move the sgrp = up->sgrp; up->sgrp = nil
in the exiting qlock(&up->debug);... block instead of
making its own.

why do we need /zrv? is there a new devzrv.c device that
was missing in the diff?

--
cinap

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 19:05 ` cinap_lenrek
@ 2021-01-06 19:11   ` ori
  2021-01-06 20:02     ` sirjofri
  2021-01-07  1:12     ` [9front] happy new year cinap_lenrek
  0 siblings, 2 replies; 8+ messages in thread
From: ori @ 2021-01-06 19:11 UTC (permalink / raw)
  To: 9front

Quoth cinap_lenrek@felloff.net:
> this implementation seemes flawed to me.
> 
> closesgrp() appears only to free the memory of the Srv*
> nodes, but doesnt actually free srv->chan, srv->owner
> and srv->name.
> 
> also the locking seems suspicious. as the global Srv*
> list was just replaced with per process one, but we'r
> still only have a single srvlock to serialize
> concurrent access to it.
> 
> so far, the srvgrp can only be reset or shared depending
> of the RFCSRVG flag. once you implement copying you'd
> need a lock per Sgrp. i'd prefer to have a lock per
> Sgrp right now and remove the global srvlock.
> 
> pexit() should move the sgrp = up->sgrp; up->sgrp = nil
> in the exiting qlock(&up->debug);... block instead of
> making its own.
> 
> why do we need /zrv? is there a new devzrv.c device that
> was missing in the diff?
> 
> --
> cinap
> 

On top of that, I think rfork flags aren't a very
nice semantic. What about reworking to

	bind '#s/clone' /srv

to create a new fork of a srv, without adding new
special namespace cases?

That also eliminates the need for zrv, since you
can just keep the old /srv bound somewhere else.

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 19:11   ` ori
@ 2021-01-06 20:02     ` sirjofri
  2021-01-06 22:28       ` cinap_lenrek
  2021-01-07 14:04       ` sirjofri+ml-9front
  2021-01-07  1:12     ` [9front] happy new year cinap_lenrek
  1 sibling, 2 replies; 8+ messages in thread
From: sirjofri @ 2021-01-06 20:02 UTC (permalink / raw)
  To: 9front

Hello again,

the included patch is indeed mycroftiv's work without many adjustments. 
We just made it work in current 9front code.

Also I did forget to attach the devzrv.c. devzrv btw is the same as srv 
but doesn't fork. It is possible to srvfs the forked srvs in zrv.

Sure, there are much cleaner solutions. Using #s/clone as ori suggested 
would be a nice kernel-based solution (instead of a fully userspace 
implementation I can also imagine).

Another idea I can think of would be similar to #σ. Imagine mkdir 
'#s/newsrv' && bind -c '#/newsrv' /srv or even like some mntgen without 
the mkdir. This would break compatibility!

More compatible would be something like echo newsrv > '#sc' && bind '#s' 
/srv. This would be more compatible to current implementation.

In both ideas the newsrv is just an arbitrary name.

sirjofri

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 20:02     ` sirjofri
@ 2021-01-06 22:28       ` cinap_lenrek
  2021-01-07 20:55         ` Stuart Morrow
  2021-01-07 14:04       ` sirjofri+ml-9front
  1 sibling, 1 reply; 8+ messages in thread
From: cinap_lenrek @ 2021-01-06 22:28 UTC (permalink / raw)
  To: 9front

or you could use the mntspec when binding #s.

having srvspace like fork also has the disadvantage that you have
the previous namespace now all bullshit. all the mount channels
become inaccessible as you RFCSRV.

at some point, i'd really like to have dedicated 9p opertation and
syscall to "post" a file descriptor to a fileserver, instead of
having more process specific magic wormholes which doesnt
transcent across exportfs. no code yet unfortunately :(

there are a bunch of other fileservers that need it. like
when you want to add another channel to a devbridge. also
think about stuff like dossrv. you can pass it a filename
to the dos partition on mount, but it needs to be in its
namespace. or stuff like devtls. grabbing into the calling
process filedescriptor table or namespace should be avoided
at all cost.

--
cinap

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

* [9front] happy new year
  2021-01-06 19:11   ` ori
  2021-01-06 20:02     ` sirjofri
@ 2021-01-07  1:12     ` cinap_lenrek
  1 sibling, 0 replies; 8+ messages in thread
From: cinap_lenrek @ 2021-01-07  1:12 UTC (permalink / raw)
  To: iju, ori, 9front

hope you are all right!

--
cinap

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 20:02     ` sirjofri
  2021-01-06 22:28       ` cinap_lenrek
@ 2021-01-07 14:04       ` sirjofri+ml-9front
  1 sibling, 0 replies; 8+ messages in thread
From: sirjofri+ml-9front @ 2021-01-07 14:04 UTC (permalink / raw)
  To: 9front

[-- Attachment #1: Type: text/plain, Size: 216 bytes --]

> Also I did forget to attach the devzrv.c. devzrv btw is the same as srv 
> but doesn't fork. It is possible to srvfs the forked srvs in zrv.

Attached is the missing devzrv.c that's missing in the patch.

sirjofri

[-- Attachment #2: devzrv.c --]
[-- Type: text/plain, Size: 6049 bytes --]

#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"

static QLock	srvlk;
static Srv	*srv;
static int	qidpath;

static Srv*
srvlookup(char *name, ulong qidpath)
{
	Srv *sp;

	for(sp = srv; sp != nil; sp = sp->link) {
		if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0))
			return sp;
	}
	return nil;
}

static int
srvgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
{
	Srv *sp;
	Qid q;

	if(s == DEVDOTDOT){
		devdir(c, c->qid, "#z", 0, eve, 0555, dp);
		return 1;
	}

	qlock(&srvlk);
	if(name != nil)
		sp = srvlookup(name, -1);
	else {
		for(sp = srv; sp != nil && s > 0; sp = sp->link)
			s--;
	}
	if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) {
		qunlock(&srvlk);
		return -1;
	}
	mkqid(&q, sp->path, 0, QTFILE);
	/* make sure name string continues to exist after we release lock */
	kstrcpy(up->genbuf, sp->name, sizeof up->genbuf);
	devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp);
	qunlock(&srvlk);
	return 1;
}

static void
srvinit(void)
{
	qidpath = 1;
}

static Chan*
srvattach(char *spec)
{
	return devattach('z', spec);
}

static Walkqid*
srvwalk(Chan *c, Chan *nc, char **name, int nname)
{
	return devwalk(c, nc, name, nname, 0, 0, srvgen);
}

static int
srvstat(Chan *c, uchar *db, int n)
{
	return devstat(c, db, n, 0, 0, srvgen);
}

char*
zrvname(Chan *c)
{
	Srv *sp;
	char *s;

	s = nil;
	qlock(&srvlk);
	for(sp = srv; sp != nil; sp = sp->link) {
		if(sp->chan == c){
			s = malloc(3+strlen(sp->name)+1);
			if(s != nil)
				sprint(s, "#z/%s", sp->name);
			break;
		}
	}
	qunlock(&srvlk);
	return s;
}

static Chan*
srvopen(Chan *c, int omode)
{
	Srv *sp;
	Chan *nc;

	if(c->qid.type == QTDIR){
		if(omode & ORCLOSE)
			error(Eperm);
		if(omode != OREAD)
			error(Eisdir);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	qlock(&srvlk);
	if(waserror()){
		qunlock(&srvlk);
		nexterror();
	}

	sp = srvlookup(nil, c->qid.path);
	if(sp == nil || sp->chan == nil)
		error(Eshutdown);

	if(omode&OTRUNC)
		error(Eexist);
	if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR)
		error(Eperm);
	devpermcheck(sp->owner, sp->perm, omode);

	nc = sp->chan;
	incref(nc);

	qunlock(&srvlk);
	poperror();

	cclose(c);
	return nc;
}

static Chan*
srvcreate(Chan *c, char *name, int omode, ulong perm)
{
	Srv *sp;

	if(openmode(omode) != OWRITE)
		error(Eperm);

	if(strlen(name) >= sizeof(up->genbuf))
		error(Etoolong);

	sp = smalloc(sizeof *sp);
	kstrdup(&sp->name, name);
	kstrdup(&sp->owner, up->user);

	qlock(&srvlk);
	if(waserror()){
		qunlock(&srvlk);
		free(sp->owner);
		free(sp->name);
		free(sp);
		nexterror();
	}
	if(srvlookup(name, -1) != nil)
		error(Eexist);

	sp->perm = perm&0777;
	sp->path = qidpath++;

	c->qid.path = sp->path;
	c->qid.type = QTFILE;

	sp->link = srv;
	srv = sp;

	qunlock(&srvlk);
	poperror();

	c->flag |= COPEN;
	c->mode = OWRITE;

	return c;
}

static void
srvremove(Chan *c)
{
	Srv *sp, **l;

	if(c->qid.type == QTDIR)
		error(Eperm);

	qlock(&srvlk);
	if(waserror()){
		qunlock(&srvlk);
		nexterror();
	}
	l = &srv;
	for(sp = *l; sp != nil; sp = *l) {
		if(sp->path == c->qid.path)
			break;
		l = &sp->link;
	}
	if(sp == nil)
		error(Enonexist);

	/*
	 * Only eve can remove system services.
	 */
	if(strcmp(sp->owner, eve) == 0 && !iseve())
		error(Eperm);

	/*
	 * No removing personal services.
	 */
	if((sp->perm&7) != 7 && strcmp(sp->owner, up->user) && !iseve())
		error(Eperm);

	*l = sp->link;
	sp->link = nil;

	qunlock(&srvlk);
	poperror();

	if(sp->chan != nil)
		cclose(sp->chan);
	free(sp->owner);
	free(sp->name);
	free(sp);
}

static int
srvwstat(Chan *c, uchar *dp, int n)
{
	char *strs;
	Srv *sp;
	Dir d;

	if(c->qid.type & QTDIR)
		error(Eperm);

	strs = smalloc(n);
	if(waserror()){
		free(strs);
		nexterror();
	}
	n = convM2D(dp, n, &d, strs);
	if(n == 0)
		error(Eshortstat);

	qlock(&srvlk);
	if(waserror()){
		qunlock(&srvlk);
		nexterror();
	}

	sp = srvlookup(nil, c->qid.path);
	if(sp == nil)
		error(Enonexist);

	if(strcmp(sp->owner, up->user) != 0 && !iseve())
		error(Eperm);

	if(d.name != nil && *d.name && strcmp(sp->name, d.name) != 0) {
		if(strchr(d.name, '/') != nil)
			error(Ebadchar);
		if(strlen(d.name) >= sizeof(up->genbuf))
			error(Etoolong);
		kstrdup(&sp->name, d.name);
	}
	if(d.uid != nil && *d.uid)
		kstrdup(&sp->owner, d.uid);
	if(d.mode != ~0UL)
		sp->perm = d.mode & 0777;

	qunlock(&srvlk);
	poperror();

	free(strs);
	poperror();

	return n;
}

static void
srvclose(Chan *c)
{
	/*
	 * in theory we need to override any changes in removability
	 * since open, but since all that's checked is the owner,
	 * which is immutable, all is well.
	 */
	if(c->flag & CRCLOSE){
		if(waserror())
			return;
		srvremove(c);
		poperror();
	}
}

static long
srvread(Chan *c, void *va, long n, vlong)
{
	isdir(c);
	return devdirread(c, va, n, 0, 0, srvgen);
}

static long
srvwrite(Chan *c, void *va, long n, vlong)
{
	Srv *sp;
	Chan *c1;
	int fd;
	char buf[32];

	if(n >= sizeof buf)
		error(Etoobig);
	memmove(buf, va, n);	/* so we can NUL-terminate */
	buf[n] = 0;
	fd = strtoul(buf, 0, 0);

	c1 = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */

	qlock(&srvlk);
	if(waserror()) {
		qunlock(&srvlk);
		cclose(c1);
		nexterror();
	}
	if(c1->flag & (CCEXEC|CRCLOSE))
		error("posted fd has remove-on-close or close-on-exec");
	if(c1->qid.type & QTAUTH)
		error("cannot post auth file in zrv");
	sp = srvlookup(nil, c->qid.path);
	if(sp == nil)
		error(Enonexist);

	if(sp->chan != nil)
		error(Ebadusefd);

	sp->chan = c1;

	qunlock(&srvlk);
	poperror();
	return n;
}

Dev zrvdevtab = {
	'z',
	"zrv",

	devreset,
	srvinit,	
	devshutdown,
	srvattach,
	srvwalk,
	srvstat,
	srvopen,
	srvcreate,
	srvclose,
	srvread,
	devbread,
	srvwrite,
	devbwrite,
	srvremove,
	srvwstat,
};

void
zrvrenameuser(char *old, char *new)
{
	Srv *sp;

	qlock(&srvlk);
	for(sp = srv; sp != nil; sp = sp->link) {
		if(sp->owner != nil && strcmp(old, sp->owner) == 0)
			kstrdup(&sp->owner, new);
	}
	qunlock(&srvlk);
}

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

* Re: [9front] mycroftiv's zrv and rfork V, patch for current 9front
  2021-01-06 22:28       ` cinap_lenrek
@ 2021-01-07 20:55         ` Stuart Morrow
  0 siblings, 0 replies; 8+ messages in thread
From: Stuart Morrow @ 2021-01-07 20:55 UTC (permalink / raw)
  To: 9front

> i'd really like to have dedicated 9p opertation and
> syscall to "post" a file descriptor to a fileserver, ...
> think about stuff like dossrv.

Would make the *srv fs's (run once, stays resident and handles all
mounts of that type) feel more like loadable kernel modules. In terms
of usage, I mean.

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

end of thread, other threads:[~2021-01-07 21:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-06 10:17 [9front] mycroftiv's zrv and rfork V, patch for current 9front sirjofri+ml-9front
2021-01-06 19:05 ` cinap_lenrek
2021-01-06 19:11   ` ori
2021-01-06 20:02     ` sirjofri
2021-01-06 22:28       ` cinap_lenrek
2021-01-07 20:55         ` Stuart Morrow
2021-01-07 14:04       ` sirjofri+ml-9front
2021-01-07  1:12     ` [9front] happy new year cinap_lenrek

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).