self.run(cmds)
- # create a new connection
- def connect(self, net, nid, port, servuuid, send_buf, read_buf):
- # XXX: buf size params not used yet
- cmds = """
+ # create a new connection
+ def connect(self, net, nid, port, servuuid, send_mem, recv_mem):
+ if net == 'tcp':
+ cmds = """
network %s
+ add_uuid %s %s
+ send_mem %d
+ recv_mem %d
connect %s %d
+ quit""" % (net, servuuid, nid, send_mem, recv_mem, nid, port, )
+ else:
+ cmds = """
+ network %s
add_uuid %s %s
- quit""" % (net, nid, port, servuuid, nid)
+ connect %s %d
+ quit""" % (net, servuuid, nid, nid, port, )
+
self.run(cmds)
- # create a new connection
- def add_route(self, net, to, via):
+ # add a route to a range
+ def add_route(self, net, gw, lo, hi):
+ cmds = """
+ network %s
+ add_route %s %s %s
+ """ % (net, gw, lo, hi)
+ self.run(cmds)
+
+ # add a route to a host
+ def add_route_host(self, net, uuid, gw, tgt):
cmds = """
- """
- #self.run(cmds)
+ network %s
+ add_uuid %s %s
+ add_route %s %s
+ """ % (net, uuid, tgt, gw, tgt)
+ self.run(cmds)
# disconnect one connection
def disconnect(self, net, nid, port, servuuid):
""" Base class for the rest of the modules. The default cleanup method is
defined here, as well as some utilitiy funcs.
"""
- def __init__(self, tag_name, node):
- self.dom_node = node
- self.tag_name = tag_name
- self.name = node.getAttribute('name')
- self.uuid = node.getAttribute('uuid')
+ def __init__(self, module_name, dom_node):
+ self.dom_node = dom_node
+ self.module_name = module_name
+ self.name = get_attr(dom_node, 'name')
+ self.uuid = get_attr(dom_node, 'uuid')
self.kmodule_list = []
+ self._server = None
+ self._connected = 0
def info(self, *args):
msg = string.join(map(str,args))
- print self.tag_name + ":", self.name, self.uuid, msg
+ print self.module_name + ":", self.name, self.uuid, msg
+
+
+ def lookup_server(self, srv_uuid):
+ """ Lookup a server's network information """
+ net = get_ost_net(self.dom_node.parentNode, srv_uuid)
+ self._server = Network(net)
+
+ def get_server(self):
+ return self._server
def cleanup(self):
""" default cleanup, used for most modules """
self.info()
+ srv = self.get_server()
+ if srv:
+ try:
+ lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
+ except CommandError, e:
+ log(self.module_name, "disconnect failed: ", self.name)
+ e.dump()
try:
lctl.cleanup(self.name, self.uuid)
except CommandError, e:
- print "cleanup failed: ", self.name
+ log(self.module_name, "cleanup failed: ", self.name)
+ e.dump()
def add_module(self, modname):
"""Append a module to list of modules to load."""
class Network(Module):
- def __init__(self,node):
- Module.__init__(self, 'NETWORK', node)
- self.net_type = node.getAttribute('type')
- self.nid = getText(node, 'server', '*')
- self.port = int(getText(node, 'port', 0))
- self.send_buf = int(getText(node, 'send_buf', 0))
- self.read_buf = int(getText(node, 'read_buf', 0))
+ def __init__(self,dom_node):
+ Module.__init__(self, 'NETWORK', dom_node)
+ self.net_type = get_attr(dom_node,'type')
+ self.nid = get_text(dom_node, 'server', '*')
+ self.port = get_text_int(dom_node, 'port', 0)
+ self.send_buf = get_text_int(dom_node, 'send_buf', 65536)
+ self.read_buf = get_text_int(dom_node, 'read_buf', 65536)
if self.nid == '*':
self.nid = get_local_address(self.net_type)
if not self.nid:
ret = run_daemon(TCP_ACCEPTOR, self.port)
if ret:
raise CommandError(TCP_ACCEPTOR, 'failed', ret)
+
+ ret = self.dom_node.getElementsByTagName('route_tbl')
+ for a in ret:
+ for r in a.getElementsByTagName('route'):
+ lctl.add_route(self.net_type, self.nid, get_attr(r, 'lo'),
+ get_attr(r,'hi', ''))
+
lctl.network(self.net_type, self.nid)
lctl.newdev(attach = "ptlrpc RPCDEV")
lctl.cleanup("RPCDEV", "")
except CommandError, e:
print "cleanup failed: ", self.name
+ e.dump()
try:
lctl.disconnectAll(self.net_type)
except CommandError, e:
- print "cleanup failed: ", self.name
+ print "disconnectAll failed: ", self.name
+ e.dump()
if self.net_type == 'tcp':
# yikes, this ugly! need to save pid in /var/something
run("killall acceptor")
class LDLM(Module):
- def __init__(self,node):
- Module.__init__(self, 'LDLM', node)
+ def __init__(self,dom_node):
+ Module.__init__(self, 'LDLM', dom_node)
self.add_module('ldlm')
def prepare(self):
self.info()
setup ="")
class LOV(Module):
- def __init__(self,node):
- Module.__init__(self, 'LOV', node)
- devs = node.getElementsByTagName('devices')[0]
- self.stripe_sz = int(devs.getAttribute('stripesize'))
- self.stripe_off = int(devs.getAttribute('stripeoffset'))
- self.pattern = int(devs.getAttribute('pattern'))
- mdsref = node.getElementsByTagName('mds_ref')[0]
- self.mdsuuid = mdsref.getAttribute('uuidref')
- mds= lookup(node.parentNode, self.mdsuuid)
+ def __init__(self,dom_node):
+ Module.__init__(self, 'LOV', dom_node)
+ self.stripe_sz = get_attr_int(dom_node, 'stripesize', 65536)
+ self.stripe_off = get_attr_int(dom_node, 'stripeoffset', 0)
+ self.pattern = get_attr_int(dom_node, 'pattern', 0)
+ self.mdsuuid = get_first_ref(dom_node, 'mds')
+ mds= lookup(dom_node.parentNode, self.mdsuuid)
self.mdsname = getName(mds)
- devlist = ""
- stripe_cnt = 0
- for child in devs.childNodes:
- if child.nodeName == 'osc_ref':
- devlist = devlist + child.getAttribute('uuidref') + " "
- stripe_cnt = stripe_cnt + 1
- self.devlist = devlist
- self.stripe_cnt = stripe_cnt
+ self.devlist = get_all_refs(dom_node, 'osc')
+ self.stripe_cnt = len(self.devlist)
self.add_module('osc')
self.add_module('lov')
self.devlist, self.mdsname)
lctl.lovconfig(self.uuid, self.mdsname, self.stripe_cnt,
self.stripe_sz, self.stripe_off, self.pattern,
- self.devlist)
+ string.join(self.devlist))
- def cleanup(self):
- pass
class MDS(Module):
- def __init__(self,node):
- Module.__init__(self, 'MDS', node)
- self.devname, self.size = getDevice(node)
- self.fstype = getText(node, 'fstype')
- self.format = getText(node, 'autoformat', "no")
+ def __init__(self,dom_node):
+ Module.__init__(self, 'MDS', dom_node)
+ self.devname, self.size = get_device(dom_node)
+ self.fstype = get_text(dom_node, 'fstype')
+ self.format = get_text(dom_node, 'autoformat', "no")
if self.fstype == 'extN':
self.add_module('extN')
self.add_module('mds')
clean_loop(self.devname)
class MDC(Module):
- def __init__(self,node):
- Module.__init__(self, 'MDC', node)
- ref = node.getElementsByTagName('mds_ref')[0]
- self.mds_uuid = ref.getAttribute('uuidref')
+ def __init__(self,dom_node):
+ Module.__init__(self, 'MDC', dom_node)
+ self.mds_uuid = get_first_ref(dom_node, 'mds')
+ self.lookup_server(self.mds_uuid)
self.add_module('mdc')
def prepare(self):
self.info(self.mds_uuid)
- mds = lookup(self.dom_node.parentNode, self.mds_uuid)
- if mds == None:
- panic(self.mdsuuid, "not found.")
- net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
- srv = Network(net)
+ srv = self.get_server()
lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid),
setup ="%s %s" %(self.mds_uuid, srv.uuid))
- def cleanup(self):
- self.info(self.mds_uuid)
- net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
- srv = Network(net)
- try:
- lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
- except CommandError:
- print "disconnect failed: ", self.name
- try:
- lctl.cleanup(self.name, self.uuid)
- except CommandError:
- print "cleanup failed: ", self.name
-
class OBD(Module):
- def __init__(self, node):
- Module.__init__(self, 'OBD', node)
- self.obdtype = node.getAttribute('type')
- self.devname, self.size = getDevice(node)
- self.fstype = getText(node, 'fstype')
- self.format = getText(node, 'autoformat', 'yes')
+ def __init__(self, dom_node):
+ Module.__init__(self, 'OBD', dom_node)
+ self.obdtype = get_attr(dom_node, 'type')
+ self.devname, self.size = get_device(dom_node)
+ self.fstype = get_text(dom_node, 'fstype')
+ self.format = get_text(dom_node, 'autoformat', 'yes')
if self.fstype == 'extN':
self.add_module('extN')
self.add_module(self.obdtype)
clean_loop(self.devname)
class OST(Module):
- def __init__(self,node):
- Module.__init__(self, 'OST', node)
- ref = node.getElementsByTagName('obd_ref')[0]
- self.obd_uuid = ref.getAttribute('uuidref')
+ def __init__(self,dom_node):
+ Module.__init__(self, 'OST', dom_node)
+ self.obd_uuid = get_first_ref(dom_node, 'obd')
self.add_module('ost')
def prepare(self):
setup ="%s" % (self.obd_uuid))
class OSC(Module):
- def __init__(self,node):
- Module.__init__(self, 'OSC', node)
- ref = node.getElementsByTagName('obd_ref')[0]
- self.obd_uuid = ref.getAttribute('uuidref')
- ref = node.getElementsByTagName('ost_ref')[0]
- self.ost_uuid = ref.getAttribute('uuidref')
+ def __init__(self,dom_node):
+ Module.__init__(self, 'OSC', dom_node)
+ self.obd_uuid = get_first_ref(dom_node, 'obd')
+ self.ost_uuid = get_first_ref(dom_node, 'ost')
+ self.lookup_server(self.ost_uuid)
self.add_module('osc')
def prepare(self):
self.info(self.obd_uuid, self.ost_uuid)
- net = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
- srv = Network(net)
- lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
+ srv = self.get_server()
+ if local_net(srv):
+ lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
+ else:
+ r = find_route(srv)
+ lctl.add_route_host(r[0], srv.uuid, r[1], r[2])
+
lctl.newdev(attach="osc %s %s" % (self.name, self.uuid),
setup ="%s %s" %(self.obd_uuid, srv.uuid))
- def cleanup(self):
- self.info(self.obd_uuid, self.ost_uuid)
- net_uuid = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
- srv = Network(net_uuid)
- try:
- lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
- except CommandError:
- print " failed: ", self.name
- try:
- lctl.cleanup(self.name, self.uuid)
- except CommandError:
- print "cleanup failed: ", self.name
class Mountpoint(Module):
- def __init__(self,node):
- Module.__init__(self, 'MTPT', node)
- self.path = getText(node, 'path')
- ref = node.getElementsByTagName('mdc_ref')[0]
- self.mdc_uuid = ref.getAttribute('uuidref')
- ref = node.getElementsByTagName('osc_ref')[0]
- self.lov_uuid = ref.getAttribute('uuidref')
+ def __init__(self,dom_node):
+ Module.__init__(self, 'MTPT', dom_node)
+ self.path = get_text(dom_node, 'path')
+ self.mdc_uuid = get_first_ref(dom_node, 'mdc')
+ self.lov_uuid = get_first_ref(dom_node, 'osc')
self.add_module('osc')
self.add_module('llite')
l = lookup(self.dom_node.parentNode, self.lov_uuid)
if l.nodeName == 'lov':
lov = LOV(l)
- for osc_uuid in string.split(lov.devlist):
+ for osc_uuid in lov.devlist:
osc = lookup(self.dom_node.parentNode, osc_uuid)
if osc:
n = OSC(osc)
panic("mount failed:", self.path)
def cleanup(self):
self.info(self.path, self.mdc_uuid,self.lov_uuid)
- run("umount", self.path)
+ (rc, out) = run("umount", self.path)
+ if rc:
+ log("umount failed, cleanup will most likely not work.")
l = lookup(self.dom_node.parentNode, self.lov_uuid)
if l.nodeName == 'lov':
lov = LOV(l)
- for osc_uuid in string.split(lov.devlist):
+ for osc_uuid in lov.devlist:
osc = lookup(self.dom_node.parentNode, osc_uuid)
if osc:
n = OSC(osc)
n.cleanup()
else:
panic('osc not found:', osc_uuid)
- lov.cleanup()
else:
osc = OSC(l)
osc.cleanup()
+class Router(Module):
+ def __init__(self,dom_node):
+ Module.__init__(self, 'ROUTER', dom_node)
+ self.add_module('kptlrouter')
+
+ def prepare(self):
+ self.info()
+
+
# ============================================================
# XML processing and query
# TODO: Change query funcs to use XPath, which is muc cleaner
-def getDevice(obd):
+def get_device(obd):
list = obd.getElementsByTagName('device')
if len(list) > 0:
dev = list[0]
dev.normalize();
- try:
- size = int(dev.getAttribute('size'))
- except ValueError:
- size = 0
+ size = get_attr_int(dev, 'size', 0)
return dev.firstChild.data, size
return '', 0
# Get the text content from the first matching child
# If there is no content (or it is all whitespace), return
# the default
-def getText(node, tag, default=""):
- list = node.getElementsByTagName(tag)
+def get_text(dom_node, tag, default=""):
+ list = dom_node.getElementsByTagName(tag)
if len(list) > 0:
- node = list[0]
- node.normalize()
- if node.firstChild:
- txt = string.strip(node.firstChild.data)
+ dom_node = list[0]
+ dom_node.normalize()
+ if dom_node.firstChild:
+ txt = string.strip(dom_node.firstChild.data)
if txt:
return txt
return default
-def get_ost_net(node, uuid):
- ost = lookup(node, uuid)
- list = ost.getElementsByTagName('network_ref')
- if list:
- uuid = list[0].getAttribute('uuidref')
- else:
+def get_text_int(dom_node, tag, default=0):
+ list = dom_node.getElementsByTagName(tag)
+ n = default
+ if len(list) > 0:
+ dom_node = list[0]
+ dom_node.normalize()
+ if dom_node.firstChild:
+ txt = string.strip(dom_node.firstChild.data)
+ if txt:
+ try:
+ n = int(txt)
+ except ValueError:
+ panic("text value is not integer:", txt)
+ return n
+
+def get_attr(dom_node, attr, default=""):
+ v = dom_node.getAttribute(attr)
+ if v:
+ return v
+ return default
+
+def get_attr_int(dom_node, attr, default=0):
+ n = default
+ v = dom_node.getAttribute(attr)
+ if v:
+ try:
+ n = int(v)
+ except ValueError:
+ panic("attr value is not integer", v)
+ return n
+
+def get_first_ref(dom_node, tag):
+ """ Get the first uuidref of the type TAG. Used one only
+ one is expected. Returns the uuid."""
+ uuid = None
+ refname = '%s_ref' % tag
+ list = dom_node.getElementsByTagName(refname)
+ if len(list) > 0:
+ uuid = getRef(list[0])
+ return uuid
+
+def get_all_refs(dom_node, tag):
+ """ Get all the refs of type TAG. Returns list of uuids. """
+ uuids = []
+ refname = '%s_ref' % tag
+ list = dom_node.getElementsByTagName(refname)
+ if len(list) > 0:
+ for i in list:
+ uuids.append(getRef(i))
+ return uuids
+
+def get_ost_net(dom_node, uuid):
+ ost = lookup(dom_node, uuid)
+ uuid = get_first_ref(ost, 'network')
+ if not uuid:
return None
- return lookup(node, uuid)
+ return lookup(dom_node, uuid)
-def lookup(node, uuid):
- for n in node.childNodes:
+def lookup(dom_node, uuid):
+ for n in dom_node.childNodes:
if n.nodeType == n.ELEMENT_NODE:
if getUUID(n) == uuid:
return n
if n: return n
return None
-# Get name attribute of node
-def getName(node):
- return node.getAttribute('name')
+# Get name attribute of dom_node
+def getName(dom_node):
+ return dom_node.getAttribute('name')
-def getRef(node):
- return node.getAttribute('uuidref')
+def getRef(dom_node):
+ return dom_node.getAttribute('uuidref')
-# Get name attribute of node
-def getUUID(node):
- return node.getAttribute('uuid')
+# Get name attribute of dom_node
+def getUUID(dom_node):
+ return dom_node.getAttribute('uuid')
# the tag name is the service type
-# fixme: this should do some checks to make sure the node is a service
-def getServiceType(node):
- return node.nodeName
+# fixme: this should do some checks to make sure the dom_node is a service
+def getServiceType(dom_node):
+ return dom_node.nodeName
#
# determine what "level" a particular node is at.
-# the order of iniitailization is based on level. objects
-# are assigned a level based on type:
-# net,devices,ldlm:1, obd, mdd:2 mds,ost:3 osc,mdc:4 mounts:5
-def getServiceLevel(node):
- type = getServiceType(node)
- if type in ('network',):
+# the order of iniitailization is based on level.
+def getServiceLevel(dom_node):
+ type = getServiceType(dom_node)
+ if type in ('ptlrouter',):
return 1
- if type in ('device', 'ldlm'):
- return 2
+ if type in ('network',):
+ return 10
+ elif type in ('device', 'ldlm'):
+ return 20
elif type in ('obd', 'mdd'):
- return 3
+ return 30
elif type in ('mds','ost'):
- return 4
+ return 40
elif type in ('mdc','osc'):
- return 5
+ return 50
elif type in ('lov',):
- return 6
+ return 60
elif type in ('mountpoint',):
- return 7
+ return 70
return 0
#
# return list of services in a profile. list is a list of tuples
-# [(level, node),]
+# [(level, dom_node),]
def getServices(lustreNode, profileNode):
list = []
for n in profileNode.childNodes:
list.sort()
return list
-def getByName(lustreNode, tag, name):
+def getByName(lustreNode, name, tag):
ndList = lustreNode.getElementsByTagName(tag)
for nd in ndList:
if getName(nd) == name:
return None
-# ============================================================
+
+
+############################################################
+# routing ("rooting")
+#
+routes = []
+local_node = []
+
+def init_node(dom_node):
+ global local_node
+ netlist = dom_node.getElementsByTagName('network')
+ for dom_net in netlist:
+ type = get_attr(dom_net, 'type')
+ gw = get_text(dom_net, 'server')
+ local_node.append((type, gw))
+
+
+def get_routes(type, gw, dom_net):
+ """ Return the routes as a list of tuples of the form:
+ [(type, gw, lo, hi),]"""
+ res = []
+ tbl = dom_net.getElementsByTagName('route_tbl')
+ routes = tbl[0].getElementsByTagName('route')
+ for r in routes:
+ lo = get_attr(r, 'lo')
+ hi = get_attr(r, 'hi', '')
+ res.append((type, gw, lo, hi))
+ return res
+
+
+def init_route_config(lustre):
+ """ Scan the lustre config looking for routers. Build list of
+ routes. """
+ global routes
+ routes = []
+ list = lustre.getElementsByTagName('node')
+ for node in list:
+ if get_attr(node, 'router'):
+ for (local_type, local_nid) in local_node:
+ gw = None
+ netlist = node.getElementsByTagName('network')
+ for dom_net in netlist:
+ if local_type == get_attr(dom_net, 'type'):
+ gw = get_text(dom_net, 'server')
+ break
+ if not gw:
+ continue
+ for dom_net in netlist:
+ if local_type != get_attr(dom_net, 'type'):
+ for route in get_routes(local_type, gw, dom_net):
+ routes.append(route)
+
+
+def local_net(net):
+ global local_node
+ for iface in local_node:
+ if net.net_type == iface[0]:
+ return 1
+ return 0
+
+def find_route(net):
+ global local_node, routes
+ frm_type = local_node[0][0]
+ to_type = net.net_type
+ to = net.nid
+ debug ('looking for route to', to_type,to)
+ for r in routes:
+ if r[2] == to:
+ return r
+ return None
+
+
+
+
+############################################################
# lconf level logic
# Start a service.
-def startService(node, clean_flag, module_flag):
- type = getServiceType(node)
- debug('Service:', type, getName(node), getUUID(node))
+def startService(dom_node, module_flag):
+ type = getServiceType(dom_node)
+ debug('Service:', type, getName(dom_node), getUUID(dom_node))
# there must be a more dynamic way of doing this...
n = None
if type == 'ldlm':
- n = LDLM(node)
+ n = LDLM(dom_node)
elif type == 'lov':
- n = LOV(node)
+ n = LOV(dom_node)
elif type == 'network':
- n = Network(node)
+ n = Network(dom_node)
elif type == 'obd':
- n = OBD(node)
+ n = OBD(dom_node)
elif type == 'ost':
- n = OST(node)
+ n = OST(dom_node)
elif type == 'mds':
- n = MDS(node)
+ n = MDS(dom_node)
elif type == 'osc':
- n = OSC(node)
+ n = OSC(dom_node)
elif type == 'mdc':
- n = MDC(node)
+ n = MDC(dom_node)
elif type == 'mountpoint':
- n = Mountpoint(node)
+ n = Mountpoint(dom_node)
+ elif type == 'ptlrouter':
+ n = Router(dom_node)
else:
panic ("unknown service type:", type)
if module_flag:
if config.nomod():
return
- if clean_flag:
+ if config.cleanup():
n.cleanup_module()
else:
n.load_module()
else:
if config.nosetup():
return
- if clean_flag:
+ if config.cleanup():
n.cleanup()
else:
n.prepare()
# * make sure partitions are in place and prepared
# * initialize devices with lctl
# Levels is important, and needs to be enforced.
-def startProfile(lustreNode, profileNode, clean_flag, module_flag):
+def startProfile(lustreNode, profileNode, module_flag):
if not profileNode:
panic("profile:", profile, "not found.")
services = getServices(lustreNode, profileNode)
- if clean_flag:
+ if config.cleanup():
services.reverse()
for s in services:
- startService(s[1], clean_flag, module_flag)
+ startService(s[1], module_flag)
+
#
# Load profile for
-def doHost(lustreNode, hosts, clean_flag):
- node = None
+def doHost(lustreNode, hosts):
+ global routes
+ dom_node = None
for h in hosts:
- node = getByName(lustreNode, 'node', h)
- if node:
+ dom_node = getByName(lustreNode, h, 'node')
+ if dom_node:
break
- if not node:
+ if not dom_node:
print 'No host entry found.'
return
+ if not get_attr(dom_node, 'router'):
+ init_node(dom_node)
+ init_route_config(lustreNode)
+
# Two step process: (1) load modules, (2) setup lustre
# if not cleaning, load modules first.
- module_flag = not clean_flag
- reflist = node.getElementsByTagName('profile')
+ module_flag = not config.cleanup()
+ reflist = dom_node.getElementsByTagName('profile')
for profile in reflist:
- startProfile(lustreNode, profile, clean_flag, module_flag)
+ startProfile(lustreNode, profile, module_flag)
- if not clean_flag:
- setDebugPath()
+ if not config.cleanup():
+ sys_set_debug_path()
script = config.gdb_script()
run(lctl.lctl, ' modules >', script)
if config.gdb():
module_flag = not module_flag
for profile in reflist:
- startProfile(lustreNode, profile, clean_flag, module_flag)
+ startProfile(lustreNode, profile, module_flag)
+############################################################
# Command line processing
#
def parse_cmdline(argv):
if os.access(base+"/Makefile", os.R_OK):
config.src_dir(base + "/../../")
-def setDebugPath():
+def sys_set_debug_path():
debug("debug path: ", config.debug_path())
if config.noexec():
return
print e
-def makeDevices():
+def sys_make_devices():
if not os.access('/dev/portals', os.R_OK):
run('mknod /dev/portals c 10 240')
if not os.access('/dev/obd', os.R_OK):
lctl = LCTLInterface('lctl')
setupModulePath(sys.argv[0])
- makeDevices()
- doHost(dom.documentElement, node_list, config.cleanup())
+ sys_make_devices()
+ doHost(dom.documentElement, node_list)
if __name__ == "__main__":
try:
#!/usr/bin/env python
-#
-# Copyright (C) 2002 Cluster File Systems, Inc.
-# Author: Robert Read <rread@clusterfs.com>
+# Copyright (C) 2002 Cluster File Systems, Inc.
+# Author: Robert Read <rread@clusterfs.com>
# This file is part of Lustre, http://www.lustre.org.
#
# create nodes
./lmc --output config.xml --node server --net server1 tcp
./lmc --merge config.xml --node client --net client1 tcp
+./lmc --merge config.xml --node client --route gw lo [hi]
+./lmc --merge config.xml --router --node gw1 --net gw1 tcp
+./lmc --merge config.xml --node gw1 --net 1 elan
+
+./lmc --merge config.xml --route elan 1 1 100
+./lmc --merge config.xml --route tcp gw1 ba1
+
# configure server
print """usage: lmc [--node --ost | --mtpt | --lov] args
Commands:
--node node_name
- Node_name by itself it will create a new node. When used with other
- commands it specifies the node to modify
+ Node_name by itself it will create a new node. If the --router
+ option is used when creating a new node, then that node will also
+ be configured as a router. When used with other commands it
+ specifies the node to modify.
--net hostname nettype [port, recv_buf, send_buf]
Nettype is either tcp, elan, or gm.
- Requires a node argument
+ Requires --node
+
+--route net gw lo [hi]
+ This command is used to create routes. NET is the
+ network type this route will be used on. The GW is an address of
+ one of the local interfaces. LO and HI represent a range of
+ addresses that can be reached through the gateway. If HI is not
+ set, then a route to the specific host in LO is created.
--mds device [size]
Create a MDS using the device
names[ret] = 1
return ret
-def get_uuid(name):
+def new_uuid(name):
return "%s_UUID" % (name)
ldlm_name = 'ldlm'
def new_lustre(dom):
"""Create a new empty lustre document"""
# adding ldlm here is a bit of a hack, but one is enough.
- str = """<lustre> <ldlm name="%s" uuid="%s"/> </lustre>""" % (ldlm_name, ldlm_uuid)
+ str = """<lustre>
+ <ldlm name="%s" uuid="%s"/>
+ <ptlrouter name="PTLROUTER" uuid="PTLROUTER_UUID"/>
+ </lustre>""" % (ldlm_name, ldlm_uuid)
return dom.parseString(str)
names = {}
return 'yes'
return 'no'
+############################################################
+# Build config objects using DOM
+#
class GenConfig:
doc = None
dom = None
self.addElement(network, "port", "%d" %(port))
return network
+ def route(self, lo, hi):
+ """ create one entry for the route table """
+ ref = self.doc.createElement('route')
+ ref.setAttribute("lo", lo)
+ if hi:
+ ref.setAttribute("hi", hi)
+ return ref
+
def node(self, name, uuid):
""" create a host """
node = self.newService("node", name, uuid)
self.addElement(mtpt, "path", path)
return mtpt
+############################################################
+# Utilities to query a DOM tree
+# Using this functions we can treat use config information
+# directly as a database.
def getName(n):
return n.getAttribute('name')
if n: return n
return None
+
def lookup(node, uuid):
for n in node.childNodes:
if n.nodeType == n.ELEMENT_NODE:
error("no node found for :", mds_name)
return node
+
def name2uuid(lustre, name, tag="", fatal=1):
ret = findByName(lustre, name, tag)
if not ret:
return ""
return getUUID(ret)
+
# XXX: assumes only one network element per node. will fix this
# as soon as support for routers is added
def get_net_uuid(lustre, node_name):
return getUUID(net[0])
return None
+
def lov_add_osc(gen, lov, osc_uuid):
devs = lov.getElementsByTagName('devices')
if len(devs) == 1:
devs[0].appendChild(gen.ref("osc", osc_uuid))
else:
error("No devices element found for LOV:", lov)
+
def node_add_profile(gen, node, ref, uuid):
ret = node.getElementsByTagName('profile')
error('node has no profile:', node)
ret[0].appendChild(gen.ref(ref, uuid))
+def get_attr(dom_node, attr, default=""):
+ v = dom_node.getAttribute(attr)
+ if v:
+ return v
+ return default
+
+############################################################
+# Top level commands
#
-# Create a new obd, osc, and ost. Add them to the DOM.
-#
+def do_add_node(gen, lustre, options, node_name):
+ uuid = new_uuid(node_name)
+ node = gen.node(node_name, uuid)
+ node_add_profile(gen, node, 'ldlm', ldlm_uuid)
+ if options.has_key('router'):
+ node.setAttribute('router', '1')
+ node_add_profile(gen, node, "ptlrouter", 'PTLROUTER_UUID')
+ lustre.appendChild(node)
+ return node
+
+
+def add_node(gen, lustre, options, args):
+ """ create a node with a network config """
+ if len(args) > 1:
+ usage()
+
+ node_name = options['node']
+
+ ret = findByName(lustre, node_name, "node")
+ if ret:
+ print "Node:", node_name, "exists."
+ return
+ do_add_node(gen, lustre, options, node_name)
+
+
+def add_net(gen, lustre, options, args):
+ """ create a node with a network config """
+ if len(args) < 2:
+ usage()
+
+ node_name = options['node']
+ nid = args[0]
+ net_type = args[1]
+
+ if net_type == 'tcp':
+ if len(args) > 2:
+ port = int(args[2])
+ else:
+ port = DEFAULT_PORT
+ # add send, recv buffer size here
+ elif net_type in ('elan', 'gm'):
+ port = 0
+ else:
+ print "Unknown net_type: ", net_type
+ sys.exit(2)
+
+ ret = findByName(lustre, node_name, "node")
+ if not ret:
+ node = do_add_node(gen, lustre, options, node_name)
+ else:
+ node = ret
+ net_name = new_name('NET_'+ node_name +'_'+ net_type)
+ net_uuid = new_uuid(net_name)
+ node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port))
+ node_add_profile(gen, node, "network", net_uuid)
+
+
+def add_route(gen, lustre, options, args):
+ """ create a node with a network config """
+ if len(args) < 3:
+ usage()
+
+ node_name = options['node']
+ net_type= args[0]
+ gw = args[1]
+ lo = args[2]
+ hi = ''
+
+ if len(args) > 3:
+ hi = args[3]
+
+ node = findByName(lustre, node_name, "node")
+ if not node:
+ error (node_name, " not found.")
+
+ netlist = node.getElementsByTagName('network')
+ for net in netlist:
+ if get_attr(net, 'type') == net_type:
+ rlist = net.getElementsByTagName('route_tbl')
+ if len(rlist) > 0:
+ rtbl = rlist[0]
+ else:
+ rtbl = gen.addElement(net, 'route_tbl')
+ rtbl.appendChild(gen.route(lo, hi))
+
+
+def add_mds(gen, lustre, options, args):
+ if len(args) < 1:
+ usage()
+
+ if options.has_key('node'):
+ node_name = options['node']
+ else:
+ error("--mds requires a --node argument")
+
+ mds_name = new_name(options['mds'])
+ devname = args[0]
+ if len(args) > 1:
+ size = args[1]
+ else:
+ size = 0
+
+ mdc_name = 'MDC_' + mds_name
+ mds_uuid = new_uuid(mds_name)
+ mdc_uuid = new_uuid(mdc_name)
+
+ node_uuid = name2uuid(lustre, node_name)
+
+ node = findByName(lustre, node_name, "node")
+ node_add_profile(gen, node, "mds", mds_uuid)
+ net_uuid = get_net_uuid(lustre, node_name)
+ if not net_uuid:
+ error("NODE: ", node_name, "not found")
+
+
+ mds = gen.mds(mds_name, mds_uuid, "extN", devname, get_format_flag(options),
+ net_uuid, node_uuid, dev_size=size)
+ mdc = gen.mdc(mdc_name, mdc_uuid, mds_uuid)
+ lustre.appendChild(mds)
+ lustre.appendChild(mdc)
+
+
+def add_mdc(gen, lustre, options, args):
+ """ create mtpt on a node """
+ if len(args) < 1:
+ usage()
+
+ if options.has_key('node'):
+ node_name = options['node']
+ else:
+ error("--mdc requires a --node argument")
+
+ mdc_name = args[0]
+ mdc_uuid = name2uuid(lustre, mdc_name)
+
+ node = findByName(lustre, node_name, "node")
+ if not node:
+ error('node:', node_name, "not found.")
+ node_add_profile(gen, node, "mdc", mdc_uuid)
+
+
def add_ost(gen, lustre, options, args):
lovname = ''
obdtype = 'obdfilter'
obdname = new_name('OBD_'+ node_name)
oscname = new_name('OSC_'+ node_name)
ostname = new_name('OST_'+ node_name)
- obd_uuid = get_uuid(obdname)
- ost_uuid = get_uuid(ostname)
- osc_uuid = get_uuid(oscname)
+ obd_uuid = new_uuid(obdname)
+ ost_uuid = new_uuid(ostname)
+ osc_uuid = new_uuid(oscname)
net_uuid = get_net_uuid(lustre, node_name)
if not net_uuid:
lustre.appendChild(obd)
lustre.appendChild(osc)
lustre.appendChild(ost)
+
# this is generally only used by llecho.sh
def add_osc(gen, lustre, options, args):
node = findByName(lustre, node_name, "node")
node_add_profile(gen, node, 'osc', osc_uuid)
-def add_net(gen, lustre, options, args):
- """ create a node with a network config """
- if len(args) < 2:
- usage()
-
- node_name = options['node']
- nid = args[0]
- net_type = args[1]
-
- if net_type == 'tcp':
- if len(args) > 2:
- port = int(args[2])
- else:
- port = DEFAULT_PORT
- # add send, recv buffer size here
- elif net_type in ('elan', 'gm'):
- port = 0
- else:
- print "Unknown net_type: ", net_type
- sys.exit(2)
-
- ret = findByName(lustre, node_name, "node")
- if not ret:
- node = do_add_node(gen, lustre, node_name)
- else:
- node = ret
- net_name = new_name('NET_'+ node_name +'_'+ net_type)
- net_uuid = get_uuid(net_name)
- node.appendChild(gen.network(net_name, net_uuid, nid, net_type, port))
- node_add_profile(gen, node, "network", net_uuid)
-
-def do_add_node(gen, lustre, node_name):
- uuid = get_uuid(node_name)
- node = gen.node(node_name, uuid)
- node_add_profile(gen, node, 'ldlm', ldlm_uuid)
- lustre.appendChild(node)
- return node
-
-def add_node(gen, lustre, options, args):
- """ create a node with a network config """
- if len(args) > 1:
- usage()
-
- node_name = options['node']
-
- ret = findByName(lustre, node_name, "node")
- if ret:
- print "Node:", node_name, "exists."
- return
- do_add_node(gen, lustre, node_name)
-
def add_lov(gen, lustre, options, args):
""" create a lov """
stripe_sz = args[1]
stripe_off = args[2]
pattern = args[3]
- uuid = get_uuid(name)
+ uuid = new_uuid(name)
ret = findByName(lustre, name, "lov")
if ret:
lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_off, pattern)
lustre.appendChild(lov)
+
def add_mtpt(gen, lustre, options, args):
""" create mtpt on a node """
if len(args) < 3:
if not lov_uuid:
lov_uuid = name2uuid(lustre, lov_name, tag='osc', fatal=1)
- uuid = get_uuid(name)
+ uuid = new_uuid(name)
mtpt = gen.mountpoint(name, uuid, mdc_uuid, lov_uuid, path)
node = findByName(lustre, node_name, "node")
if not node:
node_add_profile(gen, node, "mdc", mdc_uuid)
lustre.appendChild(mtpt)
-def add_mdc(gen, lustre, options, args):
- """ create mtpt on a node """
- if len(args) < 1:
- usage()
-
- if options.has_key('node'):
- node_name = options['node']
- else:
- error("--mdc requires a --node argument")
-
- mdc_name = args[0]
- mdc_uuid = name2uuid(lustre, mdc_name)
-
- node = findByName(lustre, node_name, "node")
- if not node:
- error('node:', node_name, "not found.")
- node_add_profile(gen, node, "mdc", mdc_uuid)
-
-def add_mds(gen, lustre, options, args):
- if len(args) < 1:
- usage()
-
- if options.has_key('node'):
- node_name = options['node']
- else:
- error("--mds requires a --node argument")
-
- mds_name = new_name(options['mds'])
- devname = args[0]
- if len(args) > 1:
- size = args[1]
- else:
- size = 0
- mdc_name = 'MDC_' + mds_name
- mds_uuid = get_uuid(mds_name)
- mdc_uuid = get_uuid(mdc_name)
-
- node_uuid = name2uuid(lustre, node_name)
-
- node = findByName(lustre, node_name, "node")
- node_add_profile(gen, node, "mds", mds_uuid)
- net_uuid = get_net_uuid(lustre, node_name)
- if not net_uuid:
- error("NODE: ", node_name, "not found")
-
-
- mds = gen.mds(mds_name, mds_uuid, "extN", devname, get_format_flag(options),
- net_uuid, node_uuid, dev_size=size)
- mdc = gen.mdc(mdc_name, mdc_uuid, mds_uuid)
- lustre.appendChild(mds)
- lustre.appendChild(mdc)
-
-
-#
+############################################################
# Command line processing
#
-
def parse_cmdline(argv):
short_opts = "ho:i:m:"
long_opts = ["ost", "osc", "mtpt", "lov=", "node=", "mds=", "net",
- "mdc", "merge=", "format", "reformat", "output=",
+ "mdc", "route", "router", "merge=", "format", "reformat", "output=",
"obdtype=", "in=", "help"]
opts = []
args = []
options['mtpt'] = 1
if o == "--node":
options['node'] = a
+ if o == "--route":
+ options['route'] = 1
+ if o == "--router":
+ options['router'] = 1
if o == "--lov":
options['lov'] = a
if o in ("-m", "--merge"):
return options, args
+# simple class for profiling
import time
class chrono:
def __init__(self):
str = '%s: %g secs' % (msg, d)
print str
-
+############################################################
+# Main
+#
def main():
options, args = parse_cmdline(sys.argv[1:])
outFile = '-'
add_net(gen, lustre, options, args)
elif options.has_key('lov'):
add_lov(gen, lustre, options, args)
+ elif options.has_key('route'):
+ add_route(gen, lustre, options, args)
elif options.has_key('node'):
add_node(gen, lustre, options, args)
else: