ref: 122eaf84ccbf1c6694943bfcce99b47c8c19440b
dir: /appl/cmd/dddb.b/
implement Dddb;
include "sys.m";
sys: Sys;
include "arg.m";
include "draw.m";
include "string.m";
strm: String;
include "lists.m";
lists: Lists;
include "config.b";
include "ctlfs.b";
include "nodereg.b";
stderr: ref Sys->FD;
debug: int;
DBVER: con "v0.1.0";
error(s: string)
{
sys->fprint(stderr, "dddb: %s\n", s);
raise "dddb:error";
}
Epoolnotfound : con "pool not found";
Epoolavail : con "pool not available";
Dddb: module {
init: fn(nil: ref Draw->Context, args: list of string);
# Configuration section
Config: adt {
name: string;
sysn: string;
addr: string;
storage: string;
fswrks: int;
nodes: list of NodeConfig;
open: fn(nodename: string, mtpt: string): Config;
};
NodeConfig: adt {
name: string;
sysn: string;
addr: string;
keyfile: string;
storage: string;
psize: int;
fswrks: int;
new: fn(entry: ref Dbentry): NodeConfig;
};
# Registry section
RegTMsg: adt {
pick {
GetNodes =>
ChanClose =>
Check or Refresh or Close =>
nodename: string;
}
};
RegRMsg: adt {
pick {
Error =>
err: string;
Status =>
count: int;
poolsize: int;
NodeList =>
names: list of string;
}
};
NodePool: adt {
cfg: NodeConfig;
instances: list of string;
init: fn(r: self ref NodePool): int;
check: fn(r: self ref NodePool): int;
refresh: fn(r: self ref NodePool): int;
newinst: fn(r: self ref NodePool, mtpt: string): string;
close: fn(r: self ref NodePool);
};
DbRegistry: adt {
nodepools: list of ref NodePool;
# rchans: list of chan of ref RegRMsg;
# tchans: list of chan of ref RegTMsg;
new: fn(cfgs: list of NodeConfig): ref DbRegistry;
init: fn(r: self ref DbRegistry);
# run: fn(r: self ref DbRegistry);
changen: fn(r: self ref DbRegistry): (chan of ref RegTMsg, chan of ref RegRMsg);
close: fn(r: self ref DbRegistry);
};
};
init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
arg := load Arg Arg->PATH;
strm = load String String->PATH;
lists = load Lists Lists->PATH;
dial = load Dial Dial->PATH;
auth = load Auth Auth->PATH;
keyring = load Keyring Keyring->PATH;
if(sys == nil)
error("dddb: sys module not found");
if(arg == nil)
error("dddb: arg module not found");
if(strm == nil)
error("dddb: strm module not found");
if(lists == nil)
error("dddb: lists module not found");
if(dial == nil)
error("dddb: dial module not found");
if(auth == nil)
error("dddb: auth module not found");
if(keyring == nil)
error("dddb: keyring module not found");
stderr = sys->fildes(2);
cfgpath: string = "";
keyfile: string = nil;
algs: list of string = nil;
arg->init(args);
arg->setusage(arg->progname()+ " [-d] [-k keyfile] [-C algs] [-c config] nodename");
while((c := arg->opt()) != 0)
case c {
'd' => debug++;
'c' => cfgpath = arg->earg();
'k' => keyfile = arg->earg();
'C' =>
algsstr := arg->earg();
(nil, algs) = sys->tokenize(algsstr, ",");
* =>
sys->fprint(stderr, "bad option: -%c\n", c);
arg->usage();
}
args = arg->argv();
nodename := hd args;
if(nodename == nil) {
sys->fprint(stderr, "dddb: no nodename supplied\n");
arg->usage();
}
if(debug)
sys->fprint(stderr, "dddb: opening config file\n");
cfg := Config.open(nodename, cfgpath);
if(debug) {
sys->fprint(stderr, "dddb: database parms:\n");
sys->fprint(stderr, "cfg.name: %s\n", cfg.name);
sys->fprint(stderr, "cfg.sysn: %s\n", cfg.sysn);
sys->fprint(stderr, "cfg.storage: %s\n", cfg.storage);
sys->fprint(stderr, "cfg.fswrks: %d\n", cfg.fswrks);
}
if(debug)
sys->fprint(stderr, "dddb: creating and running node registry\n");
sys->pctl(Sys->NEWPGRP, nil);
dbreg := DbRegistry.new(cfg.nodes);
spawn dbreg.init();
# spawn dbreg.run();
if(debug)
sys->fprint(stderr, "dddb: running ctlfs\n");
run_ctlfs(cfg, dbreg, keyfile, algs);
sys->fprint(stderr, "dddb: performing shutdown\n");
dbreg.close();
sys->fprint(stderr, "dddb: all components shut off\n");
}
user(): string
{
user := readfile("#c/user");
if(user == nil)
return "none";
return user;
}
readfile(file: string): string
{
fd := sys->open(file, Sys->OREAD);
if(fd == nil)
return nil;
buf := array[1024] of byte;
n := sys->read(fd, buf, len buf);
if(n < 0)
return nil;
return string buf[0:n];
}
writefile(file: string, s: string): int
{
fd := sys->open(file, Sys->OWRITE);
if(fd == nil)
return -1;
buf := array of byte s;
n := sys->write(fd, buf, len buf);
return n;
}
dir(name: string, perm: int, qid: big): Sys->Dir
{
d := sys->zerodir;
user := user();
d.name = name;
d.uid = user;
d.gid = user;
d.qid.path = qid;
if (perm & Sys->DMDIR)
d.qid.qtype = Sys->QTDIR;
else
d.qid.qtype = Sys->QTFILE;
d.mode = perm;
return d;
}
joinstr(items: list of string, sep: string): string
{
s := "";
citem := hd items;
items = tl items;
s = s + citem;
while(items != nil) {
citem = hd items;
items = tl items;
s = s + sep + citem;
}
return s;
}