# Global parameters
TCP_ACCEPTOR = 'acceptor'
-LCTL = './lctl' # fix this...
options = {}
+
#
# Maximum number of devices to search for.
# (the /dev/loop* nodes need to be created beforehand)
def usage():
- print """usage: lconf --ldap server | config.xml
+ print """usage: lconf config.xml
config.xml Lustre configuration in xml format.
+-v | --verbose Print system commands as they are run
+-d | --debug Print system commands, but does not run them
+--host <hostname> Load config for <hostname>
+--cleanup Cleans up config. (Shutdown)
+-h | --help Print this help
+"""
+ TODO = """
--ldap server LDAP server with lustre config database
-
-Options:
--v|--verbose
---debug Don't send lctl commenads
--reformat Reformat all devices (will confirm)
--lustre="src dir" Base directory of lustre sources. Used to search
for modules.
--portals=src Portals source
--makeldiff Translate xml source to LDIFF
---cleanup Cleans up config. (Shutdown)
--iam myname ??
-
-(SCRIPT STILL UNDER DEVELOPMENT, MOST FUNCTIONALITY UNIMPLEMENTED)
"""
+ sys.exit()
# ============================================================
# debugging and error funcs
self.args = args
# ============================================================
+# handle lctl interface
+class LCTLInterface:
+ """
+ Manage communication with lctl
+ """
+
+ def __init__(self, cmd):
+ """
+ Initialize close by finding the lctl binary.
+ """
+ syspath = string.split(os.environ['PATH'], ':')
+ syspath.insert(0, "../utils");
+ self.lctlcmd = None
+ for d in syspath:
+ lctl = os.path.join(d,cmd)
+ if os.access(lctl, os.X_OK):
+ self.lctl = lctl
+ break
+ if not self.lctl:
+ raise RuntimeError, "unable to find lctl binary."
+
+ def run(self, cmds):
+ """
+ run lctl
+ the cmds are written to stdin of lctl
+ lctl doesn't return errors when run in script mode, so
+ stderr is checked
+ should modify command line to accept multiple commands, or
+ create complex command line options
+ """
+ debug("+", self.lctl, cmds)
+ if isnotouch(): return ([], 0)
+ p = popen2.Popen3(self.lctl, 1)
+ p.tochild.write(cmds + "\n")
+ p.tochild.close()
+ out = p.fromchild.readlines()
+ ret = p.poll()
+ err = p.childerr.readlines()
+ if ret or len(err):
+ log (self.lctl, "error:", ret)
+ logall(err)
+ raise CommandError, err
+ return ret, out
+
+
+ # create a new device with lctl
+ def network(self, net, nid):
+ cmds = """
+ network %s
+ mynid %s
+ quit""" % (net, nid)
+ self.run(cmds)
+
+ # create a new connection
+ def connect(self, net, nid, port, servuuid):
+ cmds = """
+ network %s
+ connect %s %d
+ add_uuid %s %s
+ quit""" % (net, nid, port, servuuid, nid)
+ self.run(cmds)
+
+ # create a new device with lctl
+ def disconnect(self, net, nid, port, servuuid):
+ cmds = """
+ network %s
+ disconnect %s
+ quit""" % (net, nid)
+ self.run(cmds)
+
+ # create a new device with lctl
+ def newdev(self, attach, setup):
+ cmds = """
+ newdev
+ attach %s
+ setup %s
+ quit""" % (attach, setup)
+ self.run(cmds)
+
+ # cleanup a device
+ def cleanup(self, name, uuid):
+ cmds = """
+ device $%s
+ cleanup
+ detach
+ quit""" % (name)
+ self.run(cmds)
+
+ # create an lov
+ def lovconfig(self, uuid, mdcuuid, stripe_cnt, stripe_sz, pattern, devlist):
+ cmds = """
+ device $%s
+ probe
+ lovconfig %s %d %d %s %s
+ quit""" % (mdcuuid, uuid, stripe_cnt, stripe_sz, pattern, devlist)
+ self.run(cmds)
+
+# ============================================================
# Various system-level functions
# (ideally moved to their own module)
ret = 0
return (ret, out)
-# run lctl
-# the cmds are written to stdin of lctl
-# lctl doesn't return errors when run in script mode, so
-# stderr is checked
-# should modify command line to accept multiple commands, or
-# create complex command line options
-def run_lctl(cmds):
- debug("+", LCTL, cmds)
- if isnotouch(): return ([], 0)
- p = popen2.Popen3(LCTL, 1)
- p.tochild.write(cmds + "\n")
- p.tochild.close()
- out = p.fromchild.readlines()
- ret = p.poll()
- err = p.childerr.readlines()
- if ret or len(err):
- log (LCTL, "error:", ret)
- logall(err)
- raise CommandError, err
- return ret, out
-
# is the path a block device?
def is_block(path):
# fixme: dangerous
def mkfs(fstype, dev):
if(fstype == 'ext3'):
- mkfs = 'mkfs.ext2 -j'
+ mkfs = 'mkfs.ext2 -j -b 4096'
elif (fstype == 'extN'):
- mkfs = 'mkfs.ext2 -j'
+ mkfs = 'mkfs.ext2 -j -b 4096'
else:
print 'unsupported fs type: ', fstype
if not is_block(dev):
mkfs(fstype, dev)
return dev
-# create a new device with lctl
-def lctl_network(net, nid):
- cmds = """
- network %s
- mynid %s
- quit""" % (net, nid)
- run_lctl(cmds)
-
-# create a new connection
-def lctl_connect(net, nid, port, servuuid):
- cmds = """
- network %s
- connect %s %d
- add_uuid %s %s
- quit""" % (net, nid, port, servuuid, nid)
- run_lctl(cmds)
-
-# create a new device with lctl
-def lctl_disconnect(net, nid, port, servuuid):
- cmds = """
- network %s
- disconnect %s
- quit""" % (net, nid)
- run_lctl(cmds)
-
-# create a new device with lctl
-def lctl_newdev(attach, setup):
- cmds = """
- newdev
- attach %s
- setup %s
- quit""" % (attach, setup)
- run_lctl(cmds)
-
-# cleanup a device
-def lctl_cleanup(name, uuid):
- cmds = """
- device $%s
- cleanup
- detach
- quit""" % (name)
- run_lctl(cmds)
-
-# create an lov
-def lctl_lovconfig(uuid, mdcuuid, stripe_cnt, stripe_sz, pattern, devlist):
- cmds = """
- device $%s
- probe
- lovconfig %s %d %d %s %s
- quit""" % (mdcuuid, uuid, stripe_cnt, stripe_sz, pattern, devlist)
- run_lctl(cmds)
-
# ============================================================
# Functions to prepare the various objects
def prepare_ldlm(node):
(name, uuid) = getNodeAttr(node)
print 'LDLM:', name, uuid
- lctl_newdev(attach="ldlm %s %s" % (name, uuid),
+ lctl.newdev(attach="ldlm %s %s" % (name, uuid),
setup ="")
def prepare_lov(node):
- (name, uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist) = getLOVInfo(node)
- print 'LOV:', name, uuid
- lctl_lovconfig(uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist)
+ (name, uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist, mdsname) = getLOVInfo(node)
+ print 'LOV:', name, uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist, mdsname
+ lctl.lovconfig(uuid, mdsname, stripe_cnt, strip_sz, pattern, devlist)
+ lctl.newdev(attach="lov %s %s" % (name, uuid),
+ setup ="%s" % (mdcuuid))
def prepare_network(node):
(name, uuid, type, nid, port) = getNetworkInfo(node)
- print 'NETWORK:', type, nid, port
+ print 'NETWORK:', name, uuid, type, nid, port
if type == 'tcp':
run(TCP_ACCEPTOR, port)
- lctl_network(type, nid)
+ lctl.network(type, nid)
# need to check /proc/mounts and /etc/mtab before
# FIXME: check if device is already formatted.
def prepare_obd(obd):
(name, uuid, obdtype, dev, size, fstype, format) = getOBDInfo(obd)
- print "OBD: ", name, obdtype, dev, size, fstype, format
+ print 'OBD:', name, uuid, obdtype, dev, size, fstype, format
dev = block_dev(dev, size, fstype, format)
- lctl_newdev(attach="%s %s %s" % (obdtype, name, uuid),
+ lctl.newdev(attach="%s %s %s" % (obdtype, name, uuid),
setup ="%s %s" %(dev, fstype))
def prepare_ost(ost):
name, uuid, obd = getOSTInfo(ost)
- print "OST: ", name, uuid, obd
- lctl_newdev(attach="ost %s %s" % (name, uuid),
+ print 'OST:', name, uuid, obd
+ lctl.newdev(attach="ost %s %s" % (name, uuid),
setup ="$%s" % (obd))
def prepare_mds(node):
(name, uuid, dev, size, fstype, format) = getMDSInfo(node)
- print "MDS: ", name, dev, size, fstype
+ print 'MDS:', name, uuid, dev, size, fstype
# setup network for mds, too
dev = block_dev(dev, size, fstype, format)
- lctl_newdev(attach="mds %s %s" % (name, uuid),
+ lctl.newdev(attach="mds %s %s" % (name, uuid),
setup ="%s %s" %(dev, fstype))
def prepare_osc(node):
- (name, uuid, obduuid, srvuuid) = getOSCInfo(node)
- print 'OSC:', name, uuid, obduuid, srvuuid
- net = lookup(node.parentNode, srvuuid)
+ (name, uuid, obduuid, ostuuid) = getOSCInfo(node)
+ print 'OSC:', name, uuid, obduuid, ostuuid
+ net = lookup(node.parentNode, ostuuid)
srvname, srvuuid, net, server, port = getNetworkInfo(net)
- lctl_connect(net, server, port, srvuuid)
- lctl_newdev(attach="osc %s %s" % (name, uuid),
- setup ="%s %s" %(obduuid, srvuuid))
+ lctl.connect(net, server, port, ostuuid)
+ lctl.newdev(attach="osc %s %s" % (name, uuid),
+ setup ="%s %s" %(obduuid, ostuuid))
def prepare_mdc(node):
(name, uuid, mdsuuid, netuuid) = getMDCInfo(node)
print 'MDC:', name, uuid, mdsuuid, netuuid
- lctl_newdev(attach="mdc %s %s" % (name, uuid),
+ net = lookup(node.parentNode, netuuid)
+ srvname, srvuuid, net, server, port = getNetworkInfo(net)
+ lctl.connect(net, server, port, netuuid)
+ lctl.newdev(attach="mdc %s %s" % (name, uuid),
setup ="%s %s" %(mdsuuid, netuuid))
def prepare_mountpoint(node):
- print 'MTPT:'
-
+ name, uuid, oscuuid, mdcuuid, mtpt = getMTPTInfo(node)
+ print 'MTPT:', name, uuid, oscuuid, mdcuuid, mtpt
+ cmd = "mount -t lustre_lite -o ost=%s,mds=%s none %s" % \
+ (oscuuid, mdcuuid, mtpt)
+ run("mkdir", mtpt)
+ run(cmd)
# ============================================================
# Functions to cleanup the various objects
(name, uuid) = getNodeAttr(node)
print 'LDLM:', name, uuid
try:
- lctl_cleanup(name, uuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
def cleanup_lov(node):
- (name, uuid) = getNodeAttr(node)
- print 'LOV:', name, uuid
-
- #lctl_cleanup(name, uuid)
+ (name, uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist, mdsname) = getLOVInfo(node)
+ print 'LOV:', name, uuid, mdcuuid, stripe_cnt, strip_sz, pattern, devlist, mdsname
+ try:
+ lctl.cleanup(name, uuid)
+ except CommandError:
+ print "cleanup failed: ", name
def cleanup_network(node):
(name, uuid, type, nid, port) = getNetworkInfo(node)
- print 'NETWORK:', type, nid, port
- #lctl_network(type, nid)
+ print 'NETWORK:', name, uuid, type, nid, port
+ #lctl.network(type, nid)
# need to check /proc/mounts and /etc/mtab before
# formatting anything.
(name, uuid, obdtype, dev, size, fstype, format) = getOBDInfo(obd)
print "OBD: ", name, obdtype, dev, size, fstype, format
try:
- lctl_cleanup(name, uuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
clean_loop(dev)
name, uuid, obd = getOSTInfo(ost)
print "OST: ", name, uuid, obd
try:
- lctl_cleanup(name, uuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
(name, uuid, dev, size, fstype, format) = getMDSInfo(node)
print "MDS: ", name, dev, size, fstype
try:
- lctl_cleanup(name, uuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
clean_loop(dev)
def cleanup_mdc(node):
(name, uuid, mdsuuid, netuuid) = getMDCInfo(node)
print 'MDC:', name, uuid, mdsuuid, netuuid
+ net = lookup(node.parentNode, netuuid)
+ srvname, srvuuid, net, server, port = getNetworkInfo(net)
try:
- lctl_cleanup(name, uuid)
+ lctl.disconnect(net, server, port, netuuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
def cleanup_osc(node):
- (name, uuid, obduuid, srvuuid) = getOSCInfo(node)
- print 'OSC:', name, uuid, obduuid, srvuuid
- net = lookup(node.parentNode, srvuuid)
- netname, netuuid, net, server, port = getNetworkInfo(net)
+ (name, uuid, obduuid, ostuuid) = getOSCInfo(node)
+ print 'OSC:', name, uuid, obduuid, ostuuid
+ net = lookup(node.parentNode, ostuuid)
+ srvname, srvuuid, net, server, port = getNetworkInfo(net)
try:
- lctl_disconnect(net, server, port, srvuuid)
- lctl_cleanup(name, uuid)
+ lctl.disconnect(net, server, port, ostuuid)
+ lctl.cleanup(name, uuid)
except CommandError:
print "cleanup failed: ", name
def cleanup_mountpoint(node):
- print 'MTPT:'
+ name, uuid, oscuuid, mdcuuid, mtpt = getMTPTInfo(node)
+ print 'MTPT:', name, uuid, oscuuid, mdcuuid, mtpt
+ run("umount", mtpt)
# ============================================================
# XML processing and query
mdcref = node.getElementsByTagName('mdc_ref')[0]
mdcuuid = mdcref.getAttribute('uuidref')
mdc= lookup(node.parentNode, mdcuuid)
- mdcname = getName(mdc)
+ mdsref = mdc.getElementsByTagName('mds_ref')[0]
+ mdsuuid = mdsref.getAttribute('uuidref')
+ mds= lookup(node.parentNode, mdsuuid)
+ mdsname = getName(mds)
devlist = ""
stripe_cnt = 0
for child in devs.childNodes:
- if child.nodeName == 'obd_ref':
+ if child.nodeName == 'osc_ref':
devlist = devlist + child.getAttribute('uuidref') + " "
strip_cnt = stripe_cnt + 1
- return (name, uuid, mdcname, stripe_cnt, stripe_sz, pattern, devlist)
+ return (name, uuid, mdcuuid, stripe_cnt, stripe_sz, pattern, devlist, mdsname)
# extract device attributes for an obd
def getMDSInfo(node):
ostuuid = ref.getAttribute('uuidref')
return (name, uuid, obduuid, ostuuid)
+# extract device attributes for an obd
+def getMTPTInfo(node):
+ name, uuid = getNodeAttr(node)
+ path = getText(node, 'path')
+ ref = node.getElementsByTagName('mdc_ref')[0]
+ mdcuuid = ref.getAttribute('uuidref')
+ ref = node.getElementsByTagName('osc_ref')[0]
+ lovuuid = ref.getAttribute('uuidref')
+ return (name, uuid, lovuuid, mdcuuid, path)
+
# Get the text content from the first matching child
def getText(node, tag, default=""):
# 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:1, obd, mdd:2 mds,ost:3 osc,mdc:4 mounts:5
+# 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', 'device', 'ldlm'):
list.sort()
return list
-def getProfile(lustreNode, profile):
- profList = lustreNode.getElementsByTagName('profile')
- for prof in profList:
- if getName(prof) == profile:
- return prof
+def getByName(lustreNode, tag, name):
+ ndList = lustreNode.getElementsByTagName(tag)
+ for nd in ndList:
+ if getName(nd) == name:
+ return nd
return None
+
# ============================================================
# lconf type level logic
# * make sure partitions are in place and prepared
# * initialize devices with lctl
# Levels is important, and needs to be enforced.
-def startProfile(lustreNode, profile):
- profileNode = getProfile(lustreNode, profile)
+def startProfile(lustreNode, profileNode):
if not profileNode:
panic("profile:", profile, "not found.")
services = getServices(lustreNode, profileNode)
cleanup_mountpoint(node)
# Shutdown services in reverse order than they were started
-def cleanupProfile(lustreNode, profile):
- profileNode = getProfile(lustreNode, profile)
+def cleanupProfile(lustreNode, profileNode):
if not profileNode:
panic("profile:", profile, "not found.")
services = getServices(lustreNode, profileNode)
for s in services:
stopService(s[1])
+
+#
+# Load profile for
+def doHost(lustreNode, hosts, cleanFlag):
+ for h in hosts:
+ node = getByName(lustreNode, 'node', h)
+ if node:
+ break
+
+ reflist = node.getElementsByTagName('profile_ref')
+ for r in reflist:
+ if cleanFlag:
+ cleanupProfile(lustreNode, lookup(lustreNode, getRef(r)))
+ else:
+ startProfile(lustreNode, lookup(lustreNode, getRef(r)))
+
#
# Command line processing
#
def parse_cmdline(argv):
- short_opts = "hv"
+ short_opts = "hdv"
long_opts = ["ldap", "reformat", "lustre=",
"portals=", "makeldiff", "cleanup", "iam=",
- "help", "debug"]
+ "help", "debug", "host="]
opts = []
args = []
global options
except getopt.GetoptError:
print "invalid opt"
usage()
- sys.exit(2)
for o, a in opts:
if o in ("-h", "--help"):
usage()
- sys.exit()
if o == "--cleanup":
options['cleanup'] = 1
- if o in ("-v", "--verbose"):
+ if o in ("-v", "--verbose"):
options['verbose'] = 1
- if o == "--debug":
+ if o in ("-d", "--debug"):
options['debug'] = 1
+ options['verbose'] = 1
if o == "--portals":
options['portals'] = a
if o == "--lustre":
options['lustre'] = a
if o == "--reformat":
options['reformat'] = 1
+ if o == "--host":
+ options['hostname'] = [a]
return args
#
# * configure devices with lctl
# Shutdown does steps in reverse
#
+lctl = LCTLInterface('lctl')
def main():
global options
args = parse_cmdline(sys.argv[1:])
dom = xml.dom.minidom.parse(args[0])
else:
usage()
- fixme("ldap not implemented yet")
- if options.has_key('cleanup'):
- cleanupProfile(dom.childNodes[0], 'local-profile')
- else:
- startProfile(dom.childNodes[0], 'local-profile')
-
-#
-# try a different traceback style. (dare ya to try this in java)
-def my_traceback(file=None):
- """Print the list of tuples as returned by extract_tb() or
- extract_stack() as a formatted stack trace to the given file."""
- import traceback
- (t,v, tb) = sys.exc_info()
- list = traceback.extract_tb(tb)
- if not file:
- file = sys.stderr
- for filename, lineno, name, line in list:
- if line:
- print '%s:%04d %-14s %s' % (filename,lineno, name, line.strip())
+ if not options.has_key('hostname'):
+ ret, host = run('hostname')
+ if ret:
+ print "unable to determine hostname"
else:
- print '%s:%04d %s' % (filename,lineno, name)
- print '%s: %s' % (t, v)
+ options['hostname'] = [host]
+ options['hostname'].append('localhost')
+ doHost(dom.childNodes[0], options['hostname'], options.has_key('cleanup') )
if __name__ == "__main__":
- try:
- main()
- except:
- my_traceback()
-
+ main()
+
+