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; }