ref: 5a8080ba42efa1fe75d286fec5e94b7aa004959d
parent: 6bbc20102b8c32cb055b22d19736820e1f987f7f
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Apr 17 11:24:09 EDT 2023
ream: add special "adm" snapshot for users file Until now, we loaded users from /adm/users in the main snapshot; this made main more special than necessary, and made it ambiguous which snapshot users would get permissions from when traveling through time. Now, the adm label makes it unambiguous.
--- a/load.c
+++ b/load.c
@@ -105,8 +105,9 @@
fprint(2, "\tnextgen:\t%lld\n", fs->nextgen);
fprint(2, "\tblocksize:\t%lld\n", Blksz);
fprint(2, "\tcachesz:\t%lld MiB\n", fs->cmax*Blksz/MiB);
- if((t = opensnap("main")) == nil)
+ if((t = opensnap("adm")) == nil)
sysfatal("load users: no main label");
if((e = loadusers(2, t)) != nil)
sysfatal("load users: %s\n", e);
+ closesnap(t);
}
--- a/ream.c
+++ b/ream.c
@@ -6,8 +6,80 @@
#include "dat.h"
#include "fns.h"
+enum {
+ Qmainroot,
+ Qadmroot,
+ Qadmuser,
+ Nreamqid,
+};
+char *defaultusers =
+ "-1:adm::glenda\n"
+ "0:none::\n"
+ "1:tor:tor:\n"
+ "2:glenda:glenda:\n"
+ "10000:sys::\n"
+ "10001:map:map:\n"
+ "10002:doc::\n"
+ "10003:upas:upas:\n"
+ "10004:font::\n"
+ "10005:bootes:bootes:\n";
+
static void
+fillxdir(Xdir *d, vlong qid, char *name, int type, int mode)
+{
+ memset(d, 0, sizeof(Xdir));
+ d->qid = (Qid){qid, 0, type};
+ d->mode = mode;
+ d->atime = 0;
+ d->mtime = 0;
+ d->length = 0;
+ d->name = name;
+ d->uid = -1;
+ d->gid = -1;
+ d->muid = 0;
+}
+
+static void
+initadm(Blk *r, Blk *u)
+{
+ char *p, kbuf[Keymax], vbuf[Inlmax];
+ Kvp kv;
+ Xdir d;
+
+ /* nb: values must be inserted in key order */
+ kv.k = kbuf;
+ kv.nk = Offksz;
+ kv.v = vbuf;
+ kv.nv = Ptrsz;
+ kbuf[0] = Kdat;
+ PACK64(kbuf+1, (uvlong)Qadmuser);
+ PACK64(kbuf+9, 0ULL);
+ packbp(kv.v, kv.nv, &u->bp);
+ setval(r, &kv);
+
+ fillxdir(&d, Qadmuser, "users", QTFILE, 0664);
+ d.length = strlen(defaultusers);
+ if(dir2kv(Qadmroot, &d, &kv, vbuf, sizeof(vbuf)) == -1)
+ sysfatal("ream: pack users: %r");
+ setval(r, &kv);
+ fillxdir(&d, Qadmroot, "", QTDIR, DMDIR|0775);
+ if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
+ sysfatal("ream: pack root: %r");
+ setval(r, &kv);
+
+ if((p = packsuper(kbuf, sizeof(kbuf), 0)) == nil)
+ sysfatal("ream: pack super");
+ kv.k = kbuf;
+ kv.nk = p - kbuf;
+ if((p = packdkey(vbuf, sizeof(vbuf), -1, "")) == nil)
+ sysfatal("ream: pack super");
+ kv.v = vbuf;
+ kv.nv = p - vbuf;
+ setval(r, &kv);
+}
+
+static void
initroot(Blk *r)
{
char *p, kbuf[Keymax], vbuf[Inlmax];
@@ -15,16 +87,7 @@
Xdir d;
/* nb: values must be inserted in key order */
- memset(&d, 0, sizeof(Xdir));
- d.qid = (Qid){fs->nextqid++, 0, QTDIR};
- d.mode = DMDIR|0775;
- d.atime = 0;
- d.mtime = 0;
- d.length = 0;
- d.name = "";
- d.uid = -1;
- d.gid = -1;
- d.muid = 0;
+ fillxdir(&d, Qmainroot, "", QTDIR, DMDIR|0775);
if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
sysfatal("ream: pack root: %r");
setval(r, &kv);
@@ -41,12 +104,20 @@
}
static void
-initsnap(Blk *s, Blk *r)
+initsnap(Blk *s, Blk *r, Blk *a)
{
char *p, kbuf[Keymax], vbuf[Treesz];
Tree t;
Kvp kv;
+ p = packlabel(kbuf, sizeof(kbuf), "adm");
+ kv.k = kbuf;
+ kv.nk = p - kbuf;
+ p = packsnap(vbuf, sizeof(vbuf), 1);
+ kv.v = vbuf;
+ kv.nv = p - vbuf;
+ setval(s, &kv);
+
p = packlabel(kbuf, sizeof(kbuf), "empty");
kv.k = kbuf;
kv.nk = p - kbuf;
@@ -54,6 +125,7 @@
kv.v = vbuf;
kv.nv = p - vbuf;
setval(s, &kv);
+
p = packlabel(kbuf, sizeof(kbuf), "main");
kv.k = kbuf;
kv.nk = p - kbuf;
@@ -67,7 +139,7 @@
kv.nk = p - kbuf;
memset(&t, 0, sizeof(Tree));
- t.nsucc = 0;
+ t.nsucc = 1;
t.nlbl = 2;
t.ht = 1;
t.gen = fs->nextgen++;
@@ -77,6 +149,22 @@
kv.v = vbuf;
kv.nv = p - vbuf;
setval(s, &kv);
+
+ p = packsnap(kbuf, sizeof(kbuf), 1);
+ kv.k = kbuf;
+ kv.nk = p - kbuf;
+
+ memset(&t, 0, sizeof(Tree));
+ t.nsucc = 0;
+ t.nlbl = 1;
+ t.ht = 1;
+ t.gen = fs->nextgen++;
+ t.prev = -1ULL;
+ t.bp = a->bp;
+ p = packtree(vbuf, sizeof(vbuf), &t);
+ kv.v = vbuf;
+ kv.nv = p - vbuf;
+ setval(s, &kv);
}
static void
@@ -135,9 +223,9 @@
void
reamfs(char *dev)
{
+ Blk *sb, *mb, *ab, *ub;
vlong sz, asz, off;
- Blk *rb, *tb;
- Mount *mnt;
+ Mount *mnt, *adm;
Arena *a;
Dir *d;
int i;
@@ -155,6 +243,11 @@
if((mnt->root = mallocz(sizeof(Tree), 1)) == nil)
sysfatal("ream: alloc tree: %r");
+ if((adm = mallocz(sizeof(Mount), 1)) == nil)
+ sysfatal("ream: alloc mount: %r");
+ if((adm->root = mallocz(sizeof(Tree), 1)) == nil)
+ sysfatal("ream: alloc tree: %r");
+
fs->narena = (sz + 64ULL*GiB - 1) / (64ULL*GiB);
if(fs->narena < 8)
fs->narena = 8;
@@ -182,33 +275,53 @@
if(compresslog(a) == -1)
sysfatal("compress log: %r");
}
- if((tb = newblk(mnt->root, Tleaf)) == nil)
+ if((mb = newblk(mnt->root, Tleaf)) == nil)
sysfatal("ream: allocate root: %r");
- holdblk(tb);
- initroot(tb);
- finalize(tb);
- syncblk(tb);
+ holdblk(mb);
+ initroot(mb);
+ finalize(mb);
+ syncblk(mb);
mnt->root->ht = 1;
- mnt->root->bp = tb->bp;
+ mnt->root->bp = mb->bp;
+ if((ab = newblk(adm->root, Tleaf)) == nil)
+ sysfatal("ream: allocate root: %r");
+ if((ub = newblk(adm->root, Tdat)) == nil)
+ sysfatal("ream: allocate root: %r");
+ holdblk(ab);
+ holdblk(ub);
+ memcpy(ub->data, defaultusers, strlen(defaultusers));
+ finalize(ub);
+ syncblk(ub);
+ initadm(ab, ub);
+ finalize(ab);
+ syncblk(ab);
+
+ adm->root->ht = 1;
+ adm->root->bp = ab->bp;
+
/*
* Now that we have a completely empty fs, give it
* a single snap block that the tree will insert
* into, and take a snapshot as the initial state.
*/
- if((rb = newblk(mnt->root, Tleaf)) == nil)
+ if((sb = newblk(mnt->root, Tleaf)) == nil)
sysfatal("ream: allocate snaps: %r");
- holdblk(rb);
- initsnap(rb, tb);
- finalize(rb);
- syncblk(rb);
+ holdblk(sb);
+ initsnap(sb, mb, ab);
+ finalize(sb);
+ syncblk(sb);
- fs->snap.bp = rb->bp;
+ fs->snap.bp = sb->bp;
fs->snap.ht = 1;
- dropblk(tb);
- dropblk(rb);
+ dropblk(mb);
+ dropblk(ab);
+ dropblk(ub);
+ dropblk(sb);
+ fs->nextqid = Nreamqid;
+
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
finalize(a->tail);
--- a/snap.c
+++ b/snap.c
@@ -315,7 +315,7 @@
Msg m[2];
int nm;
- if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0)
+ if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0 || strcmp(name, "adm") == 0)
return Ename;
nm = 0;
@@ -363,7 +363,7 @@
char buf[2][Kvmax];
Msg m[2];
- if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0)
+ if(strcmp(name, "dump") == 0 || strcmp(name, "empty") == 0 || strcmp(name, "adm") == 0)
return Ename;
t->nlbl++;
m[0].op = Oinsert;
--- a/user.c
+++ b/user.c
@@ -6,18 +6,6 @@
#include "dat.h"
#include "fns.h"
-char *defaultusers =
- "-1:adm::glenda\n"
- "0:none::\n"
- "1:tor:tor:\n"
- "2:glenda:glenda:\n"
- "10000:sys::\n"
- "10001:map:map:\n"
- "10002:doc::\n"
- "10003:upas:upas:\n"
- "10004:font::\n"
- "10005:bootes:bootes:\n";
-
static int
walk1(Tree *t, vlong up, char *name, Qid *qid, vlong *len)
{
@@ -260,13 +248,10 @@
vlong len;
Qid q;
- s = defaultusers;
if(walk1(t, -1, "", &q, &len) == -1)
return Efs;
- if(walk1(t, q.path, "adm", &q, &len) == -1)
- goto Defaulted;
if(walk1(t, q.path, "users", &q, &len) == -1)
- goto Defaulted;
+ return Eio;
if(q.type != QTFILE)
return Etype;
if(len >= 1*MiB)
@@ -273,9 +258,7 @@
return Efsize;
if((s = slurp(t, q.path, len)) == nil)
return Eio;
-Defaulted:
e = parseusers(fd, s);
- if(s != defaultusers)
- free(s);
+ free(s);
return e;
}