shithub: dddb

ref: 122eaf84ccbf1c6694943bfcce99b47c8c19440b
dir: /appl/cmd/config.b/

View raw version
include "bufio.m";
include "attrdb.m";
	attrdb: Attrdb;
	Attr, Db, Dbptr, Dbentry: import attrdb;

# Default configuration values
DCFGPATH:	con "/lib/ndb/dddbcfg";

DADDR:		con "tcp!*!dddbctl";
DPSIZE:		con 3;
DFSWRKS:	con 10;

# Attrdb constants 
KNAME:		con "nodename";
KSYSNAME:	con "nodesysn";
KADDR:		con "addr";
KKEYFILE:	con "keyfile";
KSTORAGE:	con "storage";
KPSIZE:		con "psize";
KFSWRKS:	con "readworkers";

Config.open(nodename: string, path: string): Config
{
	sys = load Sys Sys->PATH;

	n: int;
	sysname: string;
	buf := array[Sys->NAMEMAX] of byte;

	attrdb = load Attrdb Attrdb->PATH;
	if(attrdb == nil)
		error("Attrb not found");
	attrdb->init();

	if(len path == 0)
		path = DCFGPATH;

	if(debug)
		sys->fprint(stderr, "config: opening %s\n", path);
	db := Db.open(path);

	if(db == nil)
		error(sys->sprint("ndb file %s could not be opened", path));

	sysname_fd := sys->open("#c/sysname", Sys->OREAD);
	if(sysname_fd == nil)
		error(sys->sprint("#c/sysname could not be read"));
	n = sys->read(sysname_fd, buf, len buf);
	if(n <= 0)
		error(sys->sprint("could not read sysname"));
	sysname = string buf[0:n];

	if(len nodename == 0) {
		nodename = sysname;
	}

	thiscfg: ref NodeConfig;
	nodecfgs: list of NodeConfig;
	entry: ref Dbentry;
	dbptr: ref Dbptr;

	(entry, dbptr) = db.find(dbptr, KNAME);
	while(entry != nil) {
		nodecfg := NodeConfig.new(entry);

		if(debug)
			sys->fprint(stderr, "config: found node %s\n", nodecfg.name);
		if(nodecfg.name == nodename) {
			thiscfg = ref nodecfg;
		}
		else
			nodecfgs = nodecfg :: nodecfgs;

		(entry, dbptr) = db.find(dbptr, KNAME);
	}

	if(thiscfg == nil)
		error("could not find config for nodename");

	if(thiscfg.addr == "")
		error("node lacks an address");

	if(thiscfg.storage == "")
		error("node lacks a storage path");

	if(thiscfg.sysn != sysname)
		error("node and system sysname do not match");

	return Config(
		thiscfg.name, thiscfg.sysn, thiscfg.addr,	# own configuration
		thiscfg.storage, thiscfg.fswrks,
		nodecfgs);									# configured nodes
}

NodeConfig.new(entry: ref Dbentry): NodeConfig
{
	name := entry.findfirst(KNAME);
	sysname := entry.findfirst(KSYSNAME);
	addr := entry.findfirst(KADDR);
	storage := entry.findfirst(KSTORAGE);
	keyfile := entry.findfirst(KKEYFILE);
	psize_s := entry.findfirst(KPSIZE);
	fswrks_s := entry.findfirst(KFSWRKS);

	psize := DPSIZE;
	fswrks := DFSWRKS;

	if(len name == 0)
		error("entry has no name");
	if(len sysname == 0)
		error("entry has no sysname");
	if(len addr == 0)
		addr = DADDR;
	if(len fswrks_s != 0) {
		(fswrks_i, rm) := strm->toint(fswrks_s, 10);
		if(rm != "")
			error(sys->sprint("malformed fs workers count: %s", fswrks_s));
		fswrks = fswrks_i;
	}
	if(len psize_s != 0) {
		(psize_i, rm) := strm->toint(psize_s, 10);
		if(rm != "")
			error(sys->sprint("malformed pool size: %s", psize_s));
		psize = psize_i;
	}

	return NodeConfig(
		name, sysname, addr, keyfile, storage,	# basic information
		psize, fswrks);							# tunable options
}