From: Jacob Moody <moody@mail.posixcafe.org>
To: 9front@9front.org
Subject: [9front] Pitch for devskel
Date: Sat, 4 Jun 2022 18:57:50 -0600 [thread overview]
Message-ID: <59355e7b-9c12-90f8-d4b4-989f1fa30f26@posixcafe.org> (raw)
I have been trying to find ergonomic ways of building
restricted namespaces. One issue that I keep running
in to, and that I've discussed before, is the need
for skeleton directories. Devskel is an iteration
on making these skeleton directories easier to create.
This adds a new device, '#z', that can be walked to
produce a single skeleton file or directory. For example walking
#z/ls
gives you a directory with a single empty 'ls' file within it.
A 'd' attach argument can be given to have this 'ls' file become
a empty directory instead:
#zd/ls
Each attach of '#z' can at most 'make up' one skeleton;
after the first walk from the root the hierarchy becomes stable.
The 'e' attach option instead makes the root directory always
empty.
An example of using this to build a /bin with only bind and ls.
term% bind -b '#zd/bin.new' /bin
term% bind '#z/ls' /bin/bin.new
term% bind -a '#z/bind' /bin/bin.new
term% ls /bin/bin.new
/bin/bin.new/bind
/bin/bin.new/ls
term% bind /bin/bind /bin/bin.new/bind
term% bind /bin/ls /bin/bin.new/ls
term% bind /bin/bin.new /bin
term% ls /bin/
/bin/bind
/bin/ls
term%
Why devskel instead of mntgen?
1. mntgen only exposes directories
2. mntgen permits more then a single directory to be made up
3. mntgen shows folders that other clients have walked to.
3 could just be labeled as a bug. 1 and 2 could be specified
in attach options but I am not sure what the semantics should be
for specifying both. Using mntgen would also require the use
of /srv, and I do prefer having this separated from /srv.
thanks,
moody
diff 926be5e34eb633bc3e22b013705f5474d21aa735 uncommitted
--- /dev/null
+++ b//sys/src/9/port/devskel.c
@@ -1,0 +1,237 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#include "netif.h"
+
+typedef struct Skel Skel;
+struct Skel {
+ int ref;
+ QLock lk;
+ char name[KNAMELEN];
+ char mode;
+};
+
+struct
+{
+ QLock lk;
+ ulong path;
+} skelalloc;
+
+enum{
+ Qroot,
+ Qdir,
+ Qskel,
+};
+
+static Chan*
+skelattach(char *spec)
+{
+ Chan *c;
+ Skel *f;
+ uvlong path;
+
+ c = devattach('z', spec);
+
+ f = smalloc(sizeof *f);
+ if(spec != nil && spec[0] != '\0' && strchr("de", spec[0]) != nil)
+ f->mode = spec[0];
+ else
+ f->mode = 'f';
+
+ f->ref = 1;
+
+ qlock(&skelalloc.lk);
+ path = skelalloc.path++;
+ qunlock(&skelalloc.lk);
+
+ mkqid(&c->qid, NETQID(path, Qroot), 0, QTDIR);
+ c->aux = f;
+ return c;
+}
+
+static int
+step(Chan *c, Dir *dp, int direction)
+{
+ Skel *f;
+ Qid qid;
+ ulong perm;
+ uvlong path;
+ char *name;
+
+ perm = 0555|DMDIR;
+ path = NETTYPE(c->qid.path);
+ f = c->aux;
+ name = f->name;
+
+ path += direction;
+ if(!f->name[0] && path != Qroot)
+ return -1;
+
+ switch(path){
+ case Qroot:
+ mkqid(&qid, Qroot, 0, QTDIR);
+ name = "#z";
+ break;
+ case Qdir:
+ mkqid(&qid, Qdir, 0, QTDIR);
+ break;
+ case Qskel:
+ switch(f->mode){
+ case 'd':
+ mkqid(&qid, Qskel, 0, QTDIR);
+ break;
+ case 'f':
+ default:
+ mkqid(&qid, Qskel, 0, QTFILE);
+ perm = 0666;
+ break;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ qid.path = NETQID(NETID(c->qid.path), qid.path);
+ devdir(c, qid, name, 0, eve, perm, dp);
+ return 1;
+}
+
+
+static int
+skelgen(Chan *c, char *name, Dirtab *, int, int s, Dir *dp)
+{
+ Skel *f;
+
+ f = c->aux;
+ //First walk away from root
+ if(name && !f->name[0] && f->mode != 'e' && NETTYPE(c->qid.path) == Qroot)
+ utfecpy(f->name, f->name + sizeof f->name, name);
+
+ if(s != DEVDOTDOT)
+ s++;
+
+ return step(c, dp, s);
+}
+
+static Walkqid*
+skelwalk(Chan *c, Chan *nc, char **name, int nname)
+{
+ Walkqid *wq;
+ Skel *f;
+
+ f = c->aux;
+ qlock(&f->lk);
+ if(waserror()){
+ qunlock(&f->lk);
+ nexterror();
+ }
+
+ wq = devwalk(c, nc, name, nname, nil, 0, skelgen);
+ if(wq != nil && wq->clone != nil && wq->clone != c){
+ if(f->ref <= 0)
+ panic("devskel ref");
+ f->ref++;
+ }
+ qunlock(&f->lk);
+ poperror();
+ return wq;
+}
+
+static Chan*
+skelopen(Chan *c, int omode)
+{
+ if(!(c->qid.type & QTDIR))
+ error(Eperm);
+ if(omode != OREAD)
+ error(Ebadarg);
+
+ c->mode = omode;
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+}
+
+static void
+skelclose(Chan *c)
+{
+ Skel *f;
+
+ f = c->aux;
+ qlock(&f->lk);
+ f->ref--;
+ if(f->ref == 0){
+ qunlock(&f->lk);
+ free(f);
+ } else
+ qunlock(&f->lk);
+}
+
+static long
+skelread(Chan *c, void *va, long n, vlong)
+{
+ Skel *f;
+ long nout;
+
+ if(!(c->qid.type & QTDIR))
+ error(Eperm);
+
+ f = c->aux;
+ qlock(&f->lk);
+ if(waserror()){
+ qunlock(&f->lk);
+ nexterror();
+ }
+ nout = devdirread(c, va, n, nil, 0, skelgen);
+ qunlock(&f->lk);
+ poperror();
+ return nout;
+}
+
+static long
+skelwrite(Chan *, void *, long, vlong)
+{
+ error(Eperm);
+ return 0;
+}
+
+static int
+skelstat(Chan *c, uchar *db, int n)
+{
+ Skel *f;
+ Dir dir;
+
+ f = c->aux;
+ qlock(&f->lk);
+ step(c, &dir, 0);
+ qunlock(&f->lk);
+
+ n = convD2M(&dir, db, n);
+ if(n < BIT16SZ)
+ error(Eshortstat);
+ return n;
+}
+
+Dev skeldevtab = {
+ 'z',
+ "skel",
+
+ devreset,
+ devinit,
+ devshutdown,
+ skelattach,
+ skelwalk,
+ skelstat,
+ skelopen,
+ devcreate,
+ skelclose,
+ skelread,
+ devbread,
+ skelwrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};
next reply other threads:[~2022-06-05 1:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-05 0:57 Jacob Moody [this message]
2022-06-06 3:16 ` Jacob Moody
2022-06-06 6:41 ` Jacob Moody
2022-06-06 14:40 ` ori
2022-06-06 15:08 ` Jacob Moody
2022-06-06 15:24 ` ori
2022-06-06 15:31 ` Jacob Moody
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=59355e7b-9c12-90f8-d4b4-989f1fa30f26@posixcafe.org \
--to=moody@mail.posixcafe.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).