2 # Copyright (C) 2002 Cluster File Systems, Inc.
3 # Author: Robert Read <rread@clusterfs.com>
5 # This file is part of Lustre, http://www.lustre.org.
7 # Lustre is free software; you can redistribute it and/or
8 # modify it under the terms of version 2 of the GNU General Public
9 # License as published by the Free Software Foundation.
11 # Lustre is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Lustre; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 lmc - lustre configuration data manager
24 See Lustre book (http://www.lustre.org/docs/lustre.pdf) for documentation on lmc.
28 import sys, os, getopt, string, exceptions, re
29 import xml.dom.minidom
31 def printDoc(doc, stream=sys.stdout):
33 from xml.dom.ext import PrettyPrint
34 PrettyPrint(doc, stream)
36 stream.write(doc.toxml())
40 PYMOD_DIR = "/usr/lib/lustre/python"
42 def development_mode():
43 base = os.path.dirname(sys.argv[0])
44 if os.access(base+"/Makefile.am", os.R_OK):
48 if not development_mode():
49 sys.path.append(PYMOD_DIR)
54 DEFAULT_STRIPE_SZ = 1048576
55 DEFAULT_STRIPE_CNT = 1
56 DEFAULT_STRIPE_PATTERN = 0
60 print """usage: lmc --add object [object parameters]
62 Object creation command summary:
70 --ptldebug debug_level
71 --subsystem subsystem_name
91 --backfstype ldiskfs|ext3|tmpfs
98 --mountfsoptions options
117 --fstype ldiskfs|ext3
118 --backfstype ldiskfs|ext3|tmpfs
121 --osdtype obdecho|obdfilter
123 --mkfsoptions options
124 --mountfsoptions options
134 --add mtpt - Mountpoint
139 --ost ost_name OR --lov lov_name
145 --gateway_cluster_id nid
146 --target_cluster_id nid
153 --add mgmt - Management/monitoring service
155 --mgmt mgmt_service_name
167 --master_dev obd_name
170 --commit - Close a configuration version, and start a new one
173 PARAM = Lustre.Options.PARAM
175 # lmc input/output options
176 ('reference', "Print short reference for commands."),
177 ('verbose,v', "Print system commands as they are run."),
178 ('merge,m', "Append to the specified config file.", PARAM),
179 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
180 ('input,i', "", PARAM),
181 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
185 ('delete', "", PARAM),
186 ('deactivate', "", PARAM),
187 ('commit', "Commit all config changes and start a new version"),
190 ('node', "Add a new node in the cluster configuration.", PARAM),
191 ('timeout', "Set timeout to initiate recovery.", PARAM),
192 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
193 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
194 ('portals_upcall', "Set location of portals upcall script.", PARAM),
195 ('ptldebug', "Set the portals debug level", PARAM),
196 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
199 ('nettype', "Specify the network type. This can be tcp/elan/gm.", PARAM),
200 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
201 ('tcpbuf', "Optional argument to specify the TCP buffer size.", PARAM, "0"),
202 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
203 ('irq_affinity', "Optional argument.", PARAM, 0),
204 ('hostaddr', "", PARAM,""),
205 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
208 ('route', "Add a new route for the cluster.", PARAM),
209 ('router', "Optional flag to mark a node as router."),
210 ('gw', "Specify the nid of the gateway for a route.", PARAM),
211 ('gateway_cluster_id', "", PARAM, "0"),
212 ('target_cluster_id', "", PARAM, "0"),
213 ('lo', "For a range route, this is the low value nid.", PARAM),
214 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
216 # servers: mds and ost
217 ('mds', "Specify MDS name.", PARAM,""),
218 ('ost', "Specify the OST name.", PARAM,""),
219 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
220 ('failover', "Enable failover support on OSTs or MDS?"),
221 ('group', "", PARAM),
222 ('dev', "Path of the device on local system.", PARAM,""),
223 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
224 ('size', "Specify the size of the device if needed.", PARAM,"0"),
225 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
226 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
227 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
228 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
229 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
230 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
231 ('ostuuid', "", PARAM,""),
232 ('nspath', "Local mount point of server namespace.", PARAM,""),
235 # clients: mountpoint and echo
236 ('echo_client', "", PARAM),
237 ('path', "Specify the mountpoint for Lustre.", PARAM),
238 ('filesystem', "Lustre filesystem name", PARAM,""),
241 ('lov', "Specify LOV name.", PARAM,""),
242 ('index', "Specify index for OBD in LOV target table.", PARAM),
243 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
244 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
245 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
249 ('real_obd', "Specify the real device for the cache obd system.", PARAM),
250 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
251 ('cobd', "Specify COBD name", PARAM),
254 ('master_dev', "Specify the master device for the cmobd system.", PARAM),
255 ('cache_dev', "Specify the cache device for the cmobd obd system.", PARAM),
256 ('cmobd', "Specify COBD name", PARAM),
259 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
262 ('lmv', "Specify LMV name.", PARAM,""),
266 msg = string.join(map(str,args))
267 raise OptionError("Error: " + msg)
276 msg = string.join(map(str,args))
277 print "Warning: ", msg
280 # manage names and uuids
281 # need to initialize this by walking tree to ensure
282 # no duplicate names or uuids are created.
283 # this are just place holders for now.
284 # consider changing this to be like OBD-dev-host
288 while names.has_key(ret):
289 ret = "%s_%d" % (base, ctr)
296 ret = "%s_UUID" % (name)
297 if len(ret) > UUID_MAX_LENGTH:
298 ret = ret[-UUID_MAX_LENGTH:]
299 while uuids.has_key(ret):
300 ret = "%s_UUID_%d" % (name, ctr)
302 if len(ret) > UUID_MAX_LENGTH:
303 ret = ret[-UUID_MAX_LENGTH:]
309 ldlm_uuid = 'ldlm_UUID'
312 """Create a new empty lustre document"""
313 # adding ldlm here is a bit of a hack, but one is enough.
314 str = """<lustre version="%s">
315 <ldlm name="%s" uuid="%s"/>
316 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
317 return dom.parseString(str)
323 """initialize auto-name generation tables"""
325 # get all elements that contain a name attribute
326 for n in doc.childNodes:
327 if n.nodeType == n.ELEMENT_NODE:
329 names[getName(n)] = 1
330 uuids[getUUID(n)] = 1
333 def get_format_flag(options):
338 ############################################################
339 # Build config objects using DOM
344 def __init__(self, doc):
347 def ref(self, type, uuid):
348 """ generate <[type]_ref uuidref="[uuid]"/> """
349 tag = "%s_ref" % (type)
350 ref = self.doc.createElement(tag)
351 ref.setAttribute("uuidref", uuid)
354 def dev(self, devname):
355 """ generate <dev devpath="[devname]"/> """
356 tgt = self.doc.createElement('dev')
357 tgt.setAttribute("dev", devname)
360 def newService(self, tag, name, uuid):
361 """ create a new service elmement, which requires name and uuid attributes """
362 new = self.doc.createElement(tag)
363 new.setAttribute("uuid", uuid);
364 new.setAttribute("name", name);
367 def addText(self, node, str):
368 txt = self.doc.createTextNode(str)
369 node.appendChild(txt)
371 def addElement(self, node, tag, str=None):
372 """ create a new element and add it as a child to node. If str is passed,
373 a text node is created for the new element"""
374 new = self.doc.createElement(tag)
376 self.addText(new, str)
377 node.appendChild(new)
380 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
381 port=0, tcpbuf=0, irq_aff=0):
382 """create <network> node"""
383 network = self.newService("network", name, uuid)
384 network.setAttribute("nettype", net);
385 self.addElement(network, "nid", nid)
386 self.addElement(network, "clusterid", cluster_id)
388 self.addElement(network, "hostaddr", hostaddr)
390 self.addElement(network, "port", "%d" %(port))
392 self.addElement(network, "sendmem", "%d" %(tcpbuf))
393 self.addElement(network, "recvmem", "%d" %(tcpbuf))
395 self.addElement(network, "irqaffinity", "%d" %(irq_aff))
399 def routetbl(self, name, uuid):
400 """create <routetbl> node"""
401 rtbl = self.newService("routetbl", name, uuid)
404 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
405 """ create one entry for the route table """
406 ref = self.doc.createElement('route')
407 ref.setAttribute("type", gw_net_type)
408 ref.setAttribute("gw", gw)
409 ref.setAttribute("gwclusterid", gw_cluster_id)
410 ref.setAttribute("tgtclusterid", tgt_cluster_id)
411 ref.setAttribute("lo", lo)
413 ref.setAttribute("hi", hi)
416 def profile(self, name, uuid):
417 """ create a host """
418 profile = self.newService("profile", name, uuid)
421 def node(self, name, uuid, prof_uuid):
422 """ create a host """
423 node = self.newService("node", name, uuid)
424 node.appendChild(self.ref("profile", prof_uuid))
427 def ldlm(self, name, uuid):
428 """ create a ldlm """
429 ldlm = self.newService("ldlm", name, uuid)
432 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
433 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
434 mkfsoptions="", mountfsoptions="", backfstype="", backdevname=""):
435 osd = self.newService("osd", name, uuid)
436 osd.setAttribute('osdtype', osdtype)
437 osd.appendChild(self.ref("target", ost_uuid))
438 osd.appendChild(self.ref("node", node_uuid))
439 osd.appendChild(self.dev(devname))
442 self.addElement(osd, "fstype", fstype)
444 self.addElement(osd, "backfstype", backfstype)
446 self.addElement(osd, "backdevpath", backdevname)
448 dev = self.addElement(osd, "devpath", devname)
449 self.addElement(osd, "autoformat", format)
451 self.addElement(osd, "devsize", "%s" % (dev_size))
453 self.addElement(osd, "journalsize", "%s" % (journal_size))
455 self.addElement(osd, "inodesize", "%s" % (inode_size))
457 self.addElement(osd, "mkfsoptions", mkfsoptions)
459 self.addElement(osd, "mountfsoptions", mountfsoptions)
461 self.addElement(osd, "nspath", nspath)
464 def cobd(self, name, uuid, real_uuid, cache_uuid):
465 cobd = self.newService("cobd", name, uuid)
466 cobd.appendChild(self.ref("realobd",real_uuid))
467 cobd.appendChild(self.ref("cacheobd",cache_uuid))
470 def cmobd(self, name, uuid, real_uuid, cache_uuid):
471 cmobd = self.newService("cmobd", name, uuid)
472 cmobd.appendChild(self.ref("masterobd",real_uuid))
473 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
476 def ost(self, name, uuid, osd_uuid, group=""):
477 ost = self.newService("ost", name, uuid)
478 ost.appendChild(self.ref("active", osd_uuid))
480 self.addElement(ost, "group", group)
483 def oss(self, name, uuid):
484 oss = self.newService("oss", name, uuid)
487 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
488 lov = self.newService("lov", name, uuid)
489 lov.appendChild(self.ref("mds", mds_uuid))
490 lov.setAttribute("stripesize", str(stripe_sz))
491 lov.setAttribute("stripecount", str(stripe_cnt))
492 lov.setAttribute("stripepattern", str(pattern))
495 def lov_tgt(self, obd_uuid, index, generation):
496 tgt = self.doc.createElement('lov_tgt')
497 tgt.setAttribute("uuidref", obd_uuid)
498 tgt.setAttribute("index", index)
499 tgt.setAttribute("generation", generation)
500 tgt.setAttribute("active", '1')
503 def lovconfig(self, name, uuid, lov_uuid):
504 lovconfig = self.newService("lovconfig", name, uuid)
505 lovconfig.appendChild(self.ref("lov", lov_uuid))
508 def lmv(self, name, uuid):
509 lmv = self.newService("lmv", name, uuid)
512 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
513 mds = self.newService("mds", name, uuid)
514 mds.appendChild(self.ref("active",mdd_uuid))
516 self.addElement(mds, "group", group)
519 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
520 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
521 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
522 backdevname="", lmv_uuid=""):
523 mdd = self.newService("mdsdev", name, uuid)
524 self.addElement(mdd, "fstype", fstype)
526 self.addElement(mdd, "backfstype", backfstype)
527 dev = self.addElement(mdd, "devpath", devname)
529 self.addElement(mdd, "backdevpath", backdevname)
530 self.addElement(mdd, "autoformat", format)
532 self.addElement(mdd, "devsize", "%s" % (dev_size))
534 self.addElement(mdd, "journalsize", "%s" % (journal_size))
536 self.addElement(mdd, "inodesize", "%s" % (inode_size))
538 self.addElement(mdd, "nspath", nspath)
540 self.addElement(mdd, "mkfsoptions", mkfsoptions)
542 self.addElement(mdd, "mountfsoptions", mountfsoptions)
544 mdd.appendChild(self.ref("node", node_uuid))
545 mdd.appendChild(self.ref("target", mds_uuid))
546 mdd.appendChild(self.dev(devname))
549 mdd.appendChild(self.ref("lmv", lmv_uuid))
550 self.addElement(mdd, "lmv", lmv_uuid)
554 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
555 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
556 mgmt.appendChild(self.ref("node", node_uuid))
557 # Placeholder until mgmt-service failover.
558 mgmt.appendChild(self.ref("active", mgmt_uuid))
561 def mountpoint(self, name, uuid, fs_uuid, path):
562 mtpt = self.newService("mountpoint", name, uuid)
563 mtpt.appendChild(self.ref("filesystem", fs_uuid))
564 self.addElement(mtpt, "path", path)
567 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
568 fs = self.newService("filesystem", name, uuid)
569 fs.appendChild(self.ref("mds", mds_uuid))
570 fs.appendChild(self.ref("obd", obd_uuid))
572 fs.appendChild(self.ref("mgmt", mgmt_uuid))
575 def echo_client(self, name, uuid, osc_uuid):
576 ec = self.newService("echoclient", name, uuid)
577 ec.appendChild(self.ref("obd", osc_uuid))
580 def update(self, version):
581 new = self.doc.createElement("update")
582 new.setAttribute("version", version)
585 def add(self, lov, ost, index, gen):
586 new = self.doc.createElement("add")
587 new.setAttribute("lov_uuidref", lov)
588 new.setAttribute("ost_uuidref", ost)
589 new.setAttribute("index", index)
590 new.setAttribute("generation", gen)
593 def delete(self, lov, ost, index, gen, options):
595 new = self.doc.createElement("delete")
597 new = self.doc.createElement("deactivate")
598 new.setAttribute("lov_uuidref", lov)
599 new.setAttribute("ost_uuidref", ost)
600 new.setAttribute("index", index)
601 new.setAttribute("generation", gen)
604 ############################################################
605 # Utilities to query a DOM tree
606 # Using this functions we can treat use config information
607 # directly as a database.
609 return n.getAttribute('name')
612 return node.getAttribute('uuid')
614 def findLastUpdate(lustre):
617 for n in lustre.childNodes:
618 if n.nodeType == n.ELEMENT_NODE:
619 if n.nodeName != 'update':
621 tmp = int(n.getAttribute('version'))
623 error('malformed XML: update tag without a version attribute')
624 if tmp != version + 1:
625 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
630 def addUpdate(gen, lustre, node):
631 update = findLastUpdate(lustre)
634 #add_record = update.getElementsByTagName('add')
636 # add_record = gen.add()
637 # update.appendChild(add_record)
639 # add_record = add_record[0]
640 #add_record.appendChild(node)
641 update.appendChild(node)
643 def delUpdate(gen, lustre, node):
644 update = findLastUpdate(lustre)
647 update.appendChild(node)
649 def findByName(lustre, name, tag = ""):
650 for n in lustre.childNodes:
651 if n.nodeType == n.ELEMENT_NODE:
652 if tag and n.nodeName != tag:
654 if getName(n) == name:
657 n = findByName(n, name)
662 def lookup(node, uuid):
663 for n in node.childNodes:
664 if n.nodeType == n.ELEMENT_NODE:
665 if getUUID(n) == uuid:
673 def name2uuid(lustre, name, tag="", fatal=1):
674 ret = findByName(lustre, name, tag)
677 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
682 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
683 for n in lustre.childNodes:
684 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
685 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
689 # XXX: assumes only one network element per node. will fix this
690 # as soon as support for routers is added
691 def get_net_uuid(lustre, node_name):
692 """ get a network uuid for a node_name """
693 node = findByName(lustre, node_name, "node")
695 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
696 net = node.getElementsByTagName('network')
698 return getUUID(net[0])
701 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
702 lov_name = getName(lov)
704 lov_index = get_option_int(options, 'index')
705 for tgt in lustre.getElementsByTagName('lov_tgt'):
706 if str(lov_index) == tgt.getAttribute('index'):
707 uuidref = tgt.getAttribute('uuidref')
709 raise OptionError("%s --index %d is still in use: %s" %
710 (lov_name, lov_index, uuidref))
711 tgt.setAttribute('uuidref', osc_uuid)
712 gener = int(tgt.getAttribute('generation')) + 1
713 tgt.setAttribute('generation', str(gener))
714 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid,
715 str(lov_index), str(gener)))
718 lov.appendChild(gen.lov_tgt(osc_uuid, str(lov_index), '1'))
719 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
724 for tgt in lov.getElementsByTagName('lov_tgt'):
725 uuidref = tgt.getAttribute('uuidref')
726 tmp = int(tgt.getAttribute('index'))
728 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(index + 1)+'.')
731 lov.appendChild(gen.lov_tgt(osc_uuid, str(index + 1), '1'))
732 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(index + 1), '1'))
734 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
735 lov_name = getName(lov)
737 lov_index = get_option_int(options, 'index')
738 for tgt in lustre.getElementsByTagName('lov_tgt'):
739 index = tgt.getAttribute('index')
740 if index == lov_index:
741 uuidref = tgt.getAttribute('uuidref')
742 if uuidref != osc_uuid:
743 raise OptionError("%s --index %d contains %s, not %s" %
744 (lov_name, lov_index, osc_uuid, uuidref))
746 tgt.setAttribute('uuidref', '')
748 tgt.setAttribute('active', '0')
749 # bump the generation just in case...
750 gen = int(tgt.getAttribute('generation')) + 1
751 tgt.setAttribute('generation', str(gen))
753 raise OptionError("%s --index %d not in use by %s." %
754 (lov_name, lov_index, osc_uuid))
756 for tgt in lustre.getElementsByTagName('lov_tgt'):
757 uuidref = tgt.getAttribute('uuidref')
758 if uuidref == osc_uuid:
759 genera = int(tgt.getAttribute('generation'))
760 delete_rec = gen.delete(getUUID(lov),
761 osc_uuid,tgt.getAttribute('index'),
762 str(genera), options)
763 delUpdate(gen, lustre, delete_rec)
766 tgt.setAttribute('uuidref', '')
768 tgt.setAttribute('active', '0')
770 tgt.setAttribute('generation', str(genera))
772 def lmv_add_obd(gen, lmv, mdc_uuid):
773 lmv.appendChild(gen.ref("mds", mdc_uuid))
775 def ref_exists(profile, uuid):
776 elist = profile.childNodes
778 if e.nodeType == e.ELEMENT_NODE:
779 ref = e.getAttribute('uuidref')
784 # ensure that uuid is not already in the profile
785 # return true if uuid is added
786 def node_add_profile(gen, node, ref, uuid):
787 refname = "%s_ref" % "profile"
788 ret = node.getElementsByTagName(refname)
790 error('node has no profile ref:', node)
791 prof_uuid = ret[0].getAttribute('uuidref')
792 profile = lookup(node.parentNode, prof_uuid)
794 error("no profile found:", prof_uuid)
795 if ref_exists(profile, uuid):
797 profile.appendChild(gen.ref(ref, uuid))
800 # ensure that uuid is not already in the profile
801 # return true if uuid is added
802 def node_found_target_by_dev(gen, lustre, node, devname):
803 refname = "%s_ref" % "profile"
804 ret = node.getElementsByTagName(refname)
806 error('node has no profile ref:', node)
807 prof_uuid = ret[0].getAttribute('uuidref')
808 profile = lookup(node.parentNode, prof_uuid)
810 error("no profile found:", prof_uuid)
812 osd_list = lustre.getElementsByTagName('osd')
815 obd_dev = osd.getElementsByTagName('dev')
816 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
817 for ost in lustre.getElementsByTagName('ost'):
818 active_ret = ost.getElementsByTagName('active_ref')
819 if active_ret[0].getAttribute('uuidref') == osd.getAttribute('uuid'):
820 return ost.getAttribute('uuid')
822 mdsdev_list = lustre.getElementsByTagName('mdsdev')
824 for mdsdev in mdsdev_list:
825 obd_dev = mdsdev.getElementsByTagName('dev')
826 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
827 for mds in lustre.getElementsByTagName('mds'):
828 active_ret = mds.getElementsByTagName('active_ref')
829 if active_ret[0].getAttribute('uuidref') == mdsdev.getAttribute('uuid'):
830 return mds.getAttribute('uuid')
834 def get_attr(dom_node, attr, default=""):
835 v = dom_node.getAttribute(attr)
840 ############################################################
843 def set_node_options(gen, node, options):
845 node.setAttribute('router', '1')
847 gen.addElement(node, "timeout", get_option(options, 'timeout'))
849 default_upcall = get_option(options, 'upcall')
852 if default_upcall or options.lustre_upcall:
853 if options.lustre_upcall:
854 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
856 gen.addElement(node, 'lustreUpcall', default_upcall)
857 if default_upcall or options.portals_upcall:
858 if options.portals_upcall:
859 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
861 gen.addElement(node, 'portalsUpcall', default_upcall)
863 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
864 if options.subsystem:
865 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
868 def do_add_node(gen, lustre, options, node_name):
869 uuid = new_uuid(node_name)
870 prof_name = new_name("PROFILE_" + node_name)
871 prof_uuid = new_uuid(prof_name)
872 profile = gen.profile(prof_name, prof_uuid)
873 node = gen.node(node_name, uuid, prof_uuid)
874 lustre.appendChild(node)
875 lustre.appendChild(profile)
877 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
878 set_node_options(gen, node, options)
883 def add_node(gen, lustre, options):
884 """ create a node with a network config """
886 node_name = get_option(options, 'node')
887 ret = findByName(lustre, node_name, "node")
889 print "Node:", node_name, "exists."
891 do_add_node(gen, lustre, options, node_name)
894 def add_net(gen, lustre, options):
895 """ create a node with a network config """
897 node_name = get_option(options, 'node')
898 nid = get_option(options, 'nid')
899 cluster_id = get_option(options, 'cluster_id')
900 hostaddr = get_option(options, 'hostaddr')
901 net_type = get_option(options, 'nettype')
903 if net_type in ('tcp',):
904 port = get_option_int(options, 'port')
905 tcpbuf = get_option_int(options, 'tcpbuf')
906 irq_aff = get_option_int(options, 'irq_affinity')
907 elif net_type in ('elan', 'gm'):
912 print "Unknown net_type: ", net_type
915 ret = findByName(lustre, node_name, "node")
917 node = do_add_node(gen, lustre, options, node_name)
920 set_node_options(gen, node, options)
922 net_name = new_name('NET_'+ node_name +'_'+ net_type)
923 net_uuid = new_uuid(net_name)
924 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
925 hostaddr, port, tcpbuf, irq_aff))
926 node_add_profile(gen, node, "network", net_uuid)
929 def add_route(gen, lustre, options):
930 """ create a node with a network config """
932 node_name = get_option(options, 'node')
933 gw_net_type = get_option(options, 'nettype')
934 gw = get_option(options, 'gw')
935 gw_cluster_id = get_option(options, 'gateway_cluster_id')
936 tgt_cluster_id = get_option(options, 'target_cluster_id')
937 lo = get_option(options, 'lo')
938 hi = get_option(options, 'hi')
942 node = findByName(lustre, node_name, "node")
944 error (node_name, " not found.")
946 rlist = node.getElementsByTagName('routetbl')
950 rtbl_name = new_name("RTBL_" + node_name)
951 rtbl_uuid = new_uuid(rtbl_name)
952 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
953 node.appendChild(rtbl)
954 node_add_profile(gen, node, "routetbl", rtbl_uuid)
955 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
959 def add_mds(gen, lustre, options):
960 node_name = get_option(options, 'node')
961 mds_name = get_option(options, 'mds')
962 lmv_name = get_option(options, 'lmv')
963 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
964 mdd_uuid = new_uuid(mdd_name)
968 lmv = findByName(lustre, lmv_name, "lmv")
970 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
971 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
973 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
975 mds_uuid = new_uuid(mds_name)
976 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
977 lustre.appendChild(mds)
979 lmv_add_obd(gen, lmv, mds_uuid)
981 mds = lookup(lustre, mds_uuid)
984 mds.setAttribute('failover', "1")
986 devname = get_option(options, 'dev')
987 backdevname = get_option(options, 'backdev')
988 size = get_option(options, 'size')
989 fstype = get_option(options, 'fstype')
990 backfstype = get_option(options, 'backfstype')
991 journal_size = get_option(options, 'journal_size')
992 inode_size = get_option(options, 'inode_size')
993 nspath = get_option(options, 'nspath')
994 mkfsoptions = get_option(options, 'mkfsoptions')
995 mountfsoptions = get_option(options, 'mountfsoptions')
997 node_uuid = name2uuid(lustre, node_name, 'node')
999 node = findByName(lustre, node_name, "node")
1000 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1001 net_uuid = get_net_uuid(lustre, node_name)
1003 error("NODE: ", node_name, "not found")
1006 mds.appendChild(gen.ref("lmv", lmv_uuid))
1008 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1009 get_format_flag(options), node_uuid, mds_uuid,
1010 size, journal_size, inode_size, nspath, mkfsoptions,
1011 mountfsoptions, backfstype, backdevname, lmv_uuid)
1012 lustre.appendChild(mdd)
1015 def add_mgmt(gen, lustre, options):
1016 node_name = get_option(options, 'node')
1017 node_uuid = name2uuid(lustre, node_name, 'node')
1018 mgmt_name = get_option(options, 'mgmt')
1020 mgmt_name = new_name('MGMT_' + node_name)
1021 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1023 mgmt_uuid = new_uuid(mgmt_name)
1024 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1025 lustre.appendChild(mgmt)
1027 mgmt = lookup(lustre, mgmt_uuid)
1029 node = findByName(lustre, node_name, "node")
1030 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1032 def add_ost(gen, lustre, options):
1033 node_name = get_option(options, 'node')
1034 lovname = get_option(options, 'lov')
1035 osdtype = get_option(options, 'osdtype')
1037 node_uuid = name2uuid(lustre, node_name, 'node')
1039 if osdtype == 'obdecho':
1050 devname = get_option(options, 'dev') # can be unset for bluearcs
1051 backdevname = get_option(options, 'backdev')
1052 size = get_option(options, 'size')
1053 fstype = get_option(options, 'fstype')
1054 backfstype = get_option(options, 'backfstype')
1055 journal_size = get_option(options, 'journal_size')
1056 inode_size = get_option(options, 'inode_size')
1057 mkfsoptions = get_option(options, 'mkfsoptions')
1058 mountfsoptions = get_option(options, 'mountfsoptions')
1060 nspath = get_option(options, 'nspath')
1062 ostname = get_option(options, 'ost')
1064 ostname = new_name('OST_'+ node_name)
1066 osdname = new_name("OSD_" + ostname + "_" + node_name)
1067 osd_uuid = new_uuid(osdname)
1069 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1071 ost_uuid = get_option(options, 'ostuuid')
1073 if lookup(lustre, ost_uuid):
1074 error("Duplicate OST UUID:", ost_uuid)
1076 ost_uuid = new_uuid(ostname)
1078 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1079 lustre.appendChild(ost)
1082 lov = findByName(lustre, lovname, "lov")
1084 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1085 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1087 ost = lookup(lustre, ost_uuid)
1089 if options.failover:
1090 ost.setAttribute('failover', "1")
1093 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1094 get_format_flag(options), ost_uuid, node_uuid, size,
1095 journal_size, inode_size, nspath, mkfsoptions,
1096 mountfsoptions, backfstype, backdevname)
1098 node = findByName(lustre, node_name, "node")
1100 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1102 ## oss_uuid = new_uuid(ossname)
1103 ## oss = gen.oss(ossname, oss_uuid)
1104 ## lustre.appendChild(oss)
1106 node_add_profile(gen, node, 'osd', osd_uuid)
1107 lustre.appendChild(osd)
1109 def del_ost(gen, lustre, options):
1110 ostname = get_option(options, 'ost')
1112 raise OptionError("del_ost: --ost requires a <ost name>")
1113 ost = findByName(lustre, ostname, "ost")
1115 error('del_ost: ', 'Unable to find ', ostname)
1116 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1118 error('del_ost: ', 'Unable to find uuid for ', ostname)
1119 lovname = get_option(options, 'lov')
1121 lov = findByName(lustre, lovname, "lov")
1123 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1124 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1125 # if the user specified a speficic LOV don't delete the OST itself
1128 # remove OSD references from all LOVs
1129 for n in lustre.getElementsByTagName('lov'):
1130 lov_del_obd(gen, lustre, n, ost_uuid, options)
1133 for osd in lustre.getElementsByTagName('osd'):
1134 if ref_exists(osd, ost_uuid):
1135 osd_uuid = osd.getAttribute('uuid')
1136 # delete all profile references to this OSD
1137 for profile in lustre.getElementsByTagName('profile'):
1138 for osd_ref in profile.getElementsByTagName('osd_ref'):
1139 if osd_uuid == osd_ref.getAttribute('uuidref'):
1140 profile.removeChild(osd_ref)
1141 lustre.removeChild(osd)
1144 lustre.removeChild(ost)
1146 def add_cmobd(gen, lustre, options):
1147 node_name = get_option(options, 'node')
1148 name = get_option(options, 'cmobd')
1149 uuid = new_uuid(name)
1151 real_name = get_option(options, 'master_dev')
1152 cache_name = get_option(options, 'cache_dev')
1154 node = findByName(lustre, node_name, "node")
1155 node_add_profile(gen, node, "cmobd", uuid)
1156 real_uuid = node_found_target_by_dev(gen, lustre, node, real_name)
1157 cache_uuid = node_found_target_by_dev(gen, lustre, node, cache_name)
1159 panic("add_cmobd", "can not find real_uuid")
1161 panic("add_cmobd", "can not find cache_uuid")
1162 cmobd = gen.cmobd(name, uuid, real_uuid, cache_uuid)
1163 lustre.appendChild(cmobd)
1165 def add_cobd(gen, lustre, options):
1166 node_name = get_option(options, 'node')
1167 name = get_option(options, 'cobd')
1168 uuid = new_uuid(name)
1170 real_name = get_option(options, 'real_obd')
1171 cache_name = get_option(options, 'cache_obd')
1173 real_uuid = name2uuid(lustre, real_name, tag='lov', fatal=0)
1174 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1177 node = lookup(lustre, real_uuid)
1178 rets = node.getElementsByTagName('lov_tgt')
1180 ost_uuid = ret.getAttribute('uuidref')
1181 ost_node = lookup(lustre, ost_uuid)
1182 ret = ost_node.getElementsByTagName('active_ref')
1184 osd_uuid = ret[0].getAttribute('uuidref')
1185 osd_node = lookup(lustre, osd_uuid)
1186 gen.addElement(osd_node, 'cachetype', 'master')
1189 node = lookup(lustre, cache_uuid)
1190 rets = node.getElementsByTagName('lov_tgt')
1192 ost_uuid = ret.getAttribute('uuidref')
1193 ost_node = lookup(lustre, ost_uuid)
1194 ret = ost_node.getElementsByTagName('active_ref')
1196 osd_uuid = ret[0].getAttribute('uuidref')
1197 osd_node = lookup(lustre, osd_uuid)
1198 gen.addElement(osd_node, 'cachetype', 'cache')
1200 if not real_uuid or not cache_uuid:
1201 real_uuid = name2uuid(lustre,real_name, tag='mds')
1202 cache_uuid = name2uuid(lustre,cache_name, tag='mds')
1204 mds_node = lookup(lustre, real_uuid)
1205 ret = mds_node.getElementsByTagName('active_ref')
1207 mdsdev_uuid = ret[0].getAttribute('uuidref')
1208 mdsdev_node = lookup(lustre, mdsdev_uuid)
1209 gen.addElement(mdsdev_node, 'cachetype', 'master')
1211 mds_node = lookup(lustre, cache_uuid)
1212 ret = mds_node.getElementsByTagName('active_ref')
1214 mdsdev_uuid = ret[0].getAttribute('uuidref')
1215 mdsdev_node = lookup(lustre, mdsdev_uuid)
1216 gen.addElement(mdsdev_node, 'cachetype', 'cache')
1218 node = findByName(lustre, node_name, "node")
1219 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
1220 lustre.appendChild(cobd)
1223 def add_echo_client(gen, lustre, options):
1224 """ add an echo client to the profile for this node. """
1225 node_name = get_option(options, 'node')
1226 lov_name = get_option(options, 'ost')
1228 node = findByName(lustre, node_name, 'node')
1230 echoname = new_name('ECHO_'+ node_name)
1231 echo_uuid = new_uuid(echoname)
1232 node_add_profile(gen, node, 'echoclient', echo_uuid)
1234 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1236 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1238 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1239 lustre.appendChild(echo)
1242 def add_lov(gen, lustre, options):
1243 """ create a lov """
1245 lmv_name = get_option(options, 'lmv')
1246 lov_orig = get_option(options, 'lov')
1247 name = new_name(lov_orig)
1248 if name != lov_orig:
1249 warning("name:", lov_orig, "already used. using:", name)
1251 mds_name = get_option(options, 'mds')
1254 error("LOV: MDS or LMV must be specified.");
1256 stripe_sz = get_option_int(options, 'stripe_sz')
1257 stripe_cnt = get_option_int(options, 'stripe_cnt')
1258 pattern = get_option_int(options, 'stripe_pattern')
1259 uuid = new_uuid(name)
1261 ret = findByName(lustre, name, "lov")
1263 error("LOV: ", name, " already exists.")
1266 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1268 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1270 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1271 lustre.appendChild(lov)
1273 # add an lovconfig entry to the active mdsdev profile
1274 lovconfig_name = new_name('LVCFG_' + name)
1275 lovconfig_uuid = new_uuid(lovconfig_name)
1277 mds = findByName(lustre, mds_name, "mds")
1278 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1280 lmv = findByName(lustre, lmv_name, "lmv")
1281 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1282 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1283 lustre.appendChild(lovconfig)
1285 def add_default_lov(gen, lustre, mds_name, lov_name):
1286 """ create a default lov """
1288 stripe_sz = DEFAULT_STRIPE_SZ
1289 stripe_cnt = DEFAULT_STRIPE_CNT
1290 pattern = DEFAULT_STRIPE_PATTERN
1291 uuid = new_uuid(lov_name)
1293 ret = findByName(lustre, lov_name, "lov")
1295 error("LOV: ", lov_name, " already exists.")
1297 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1298 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1299 lustre.appendChild(lov)
1301 # add an lovconfig entry to the active mdsdev profile
1302 lovconfig_name = new_name('LVCFG_' + lov_name)
1303 lovconfig_uuid = new_uuid(lovconfig_name)
1304 mds = findByName(lustre, mds_name)
1305 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1306 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1307 lustre.appendChild(lovconfig)
1309 def add_lmv(gen, lustre, options):
1310 """ create a lmv """
1312 lmv_orig = get_option(options, 'lmv')
1313 name = new_name(lmv_orig)
1314 if name != lmv_orig:
1315 warning("name:", lmv_orig, "already used. using:", name)
1317 uuid = new_uuid(name)
1318 ret = findByName(lustre, name, "lmv")
1320 error("LMV: ", name, " already exists.")
1322 lmv = gen.lmv(name, uuid)
1323 lustre.appendChild(lmv)
1325 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1326 fs_name = new_name("FS_fsname")
1327 fs_uuid = new_uuid(fs_name)
1328 cobd = lookup(lustre, mds_uuid)
1329 #SHOULD appendChild filesystem to real mds not cobd
1330 ret = cobd.getElementsByTagName("cacheobd_ref")
1332 cacheobd_uuid = ret[0].getAttribute('uuidref')
1333 cacheobd = lookup(lustre, cacheobd_uuid)
1334 cacheobd.appendChild(gen.ref("filesystem", fs_uuid))
1335 ret = cobd.getElementsByTagName("realobd_ref")
1337 realobd_uuid = ret[0].getAttribute('uuidref')
1338 realobd = lookup(lustre, realobd_uuid)
1339 realobd.appendChild(gen.ref("filesystem", fs_uuid))
1341 cobd.appendChild(gen.ref("filesystem", fs_uuid))
1342 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid, mgmt_uuid)
1343 lustre.appendChild(fs)
1346 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1347 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1349 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1351 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=1)
1352 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1354 obd_uuid = name2uuid(lustre, obd_name, tag='cobd')
1356 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1359 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1361 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid)
1364 def add_mtpt(gen, lustre, options):
1365 """ create mtpt on a node """
1366 node_name = get_option(options, 'node')
1368 path = get_option(options, 'path')
1369 fs_name = get_option(options, 'filesystem')
1371 lov_name = get_option(options, 'lov')
1372 ost_name = get_option(options, 'ost')
1373 mds_name = get_option(options, 'mds')
1375 mds_name = get_option(options, 'lmv')
1377 error("--add mtpt requires either --mds or --lmv.")
1380 error("--add mtpt requires --lov lov_name or --ost ost_name")
1382 warning("use default value for lov, due no --lov lov_name provided")
1383 lov_name = new_name("lov_default")
1384 add_default_lov(gen, lustre, mds_name, lov_name)
1385 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1387 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1388 lov = findByName(lustre, lov_name, "lov")
1389 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1392 mgmt_name = get_option(options, 'mgmt')
1393 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1395 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1397 name = new_name('MNT_'+ node_name)
1399 ret = findByName(lustre, name, "mountpoint")
1401 # this can't happen, because new_name creates unique names
1402 error("MOUNTPOINT: ", name, " already exists.")
1404 uuid = new_uuid(name)
1405 mtpt = gen.mountpoint(name, uuid, fs_uuid, path)
1406 node = findByName(lustre, node_name, "node")
1408 error('node:', node_name, "not found.")
1409 node_add_profile(gen, node, "mountpoint", uuid)
1410 lustre.appendChild(mtpt)
1412 def commit_version(gen, lustre):
1413 update = findLastUpdate(lustre)
1415 version = int(update.getAttribute("version")) + 1
1419 new = gen.update(str(version))
1420 lustre.appendChild(new)
1423 ############################################################
1424 # Command line processing
1426 class OptionError (exceptions.Exception):
1427 def __init__(self, args):
1430 def get_option(options, tag):
1431 """Look for tag in options hash and return the value if set. If not
1432 set, then if return default it is set, otherwise exception."""
1433 if options.__getattr__(tag) != None:
1434 return options.__getattr__(tag)
1436 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1438 def get_option_int(options, tag):
1439 """Return an integer option. Raise exception if the value is not an int"""
1440 val = get_option(options, tag)
1444 raise OptionError("--%s <num> (value must be integer)" % (tag))
1447 # simple class for profiling
1454 self._start = time.time()
1455 def stop(self, msg=''):
1456 self._stop = time.time()
1460 return self._stop - self._start
1461 def display(self, msg):
1463 str = '%s: %g secs' % (msg, d)
1466 #################################################################
1467 # function cmdlinesplit used to split cmd line from batch file
1469 def cmdlinesplit(cmdline):
1471 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1472 single_quote = re.compile(r"'(.*?)'")
1473 escaped = re.compile(r'\\(.)')
1474 esc_quote = re.compile(r'\\([\\"])')
1475 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1479 while i < len(cmdline):
1482 match = double_quote.match(cmdline, i)
1484 print "Unmatched double quote:", cmdline
1487 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1488 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1491 match = single_quote.match(cmdline, i)
1493 print "Unmatched single quote:", cmdline
1496 if arg is None: arg = match.group(1)
1497 else: arg = arg + match.group(1)
1500 match = escaped.match(cmdline, i)
1502 print "Unmatched backslash", cmdline
1505 if arg is None: arg = match.group(1)
1506 else: arg = arg + match.group(1)
1508 elif c in string.whitespace:
1510 arg_list.append(str(arg))
1512 while i < len(cmdline) and cmdline[i] in string.whitespace:
1515 match = outside.match(cmdline, i)
1518 if arg is None: arg = match.group()
1519 else: arg = arg + match.group()
1521 if arg != None: arg_list.append(str(arg))
1525 ############################################################
1529 def add(devtype, gen, lustre, options):
1530 if devtype == 'net':
1531 add_net(gen, lustre, options)
1532 elif devtype == 'mtpt':
1533 add_mtpt(gen, lustre, options)
1534 elif devtype == 'mds':
1535 add_mds(gen, lustre, options)
1536 elif devtype == 'ost':
1537 add_ost(gen, lustre, options)
1538 elif devtype == 'lov':
1539 add_lov(gen, lustre, options)
1540 elif devtype == 'route':
1541 add_route(gen, lustre, options)
1542 elif devtype == 'node':
1543 add_node(gen, lustre, options)
1544 elif devtype == 'echo_client':
1545 add_echo_client(gen, lustre, options)
1546 elif devtype == 'cobd':
1547 add_cobd(gen, lustre, options)
1548 elif devtype == 'cmobd':
1549 add_cmobd(gen, lustre, options)
1550 elif devtype == 'mgmt':
1551 add_mgmt(gen, lustre, options)
1552 elif devtype == 'lmv':
1553 add_lmv(gen, lustre, options)
1555 error("unknown device type:", devtype)
1557 def delete(devtype, gen, lustre, options):
1558 if devtype == 'ost':
1559 del_ost(gen, lustre, options)
1560 elif options.delete:
1561 error("delete not supported for device type:", devtype)
1562 elif options.deactivate:
1563 error("deactivate not supported for device type:", devtype)
1565 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1567 def commit(gen, lustre):
1568 commit_version(gen, lustre)
1570 def do_command(gen, lustre, options, args):
1572 add(options.add, gen, lustre, options)
1573 elif options.delete:
1574 delete(options.delete, gen, lustre, options)
1575 elif options.deactivate:
1576 delete(options.deactivate, gen, lustre, options)
1577 elif options.commit:
1580 error("Missing command")
1583 cl = Lustre.Options("lmc", "", lmc_options)
1585 options, args = cl.parse(sys.argv[1:])
1586 except Lustre.OptionError, e:
1590 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1592 if options.reference:
1599 outFile = options.merge
1600 if os.access(outFile, os.R_OK):
1601 doc = xml.dom.minidom.parse(outFile)
1603 doc = new_lustre(xml.dom.minidom)
1605 doc = xml.dom.minidom.parse(options.input)
1607 doc = new_lustre(xml.dom.minidom)
1610 outFile = options.output
1612 lustre = doc.documentElement
1614 if lustre.tagName != "lustre":
1615 print "Existing config not valid."
1618 gen = GenConfig(doc)
1621 fp = open(options.batch)
1622 batchCommands = fp.readlines()
1624 for cmd in batchCommands:
1626 options, args = cl.parse(cmdlinesplit(cmd))
1627 if options.merge or options.input or options.output:
1628 print "The batchfile should not contain --merge, --input or --output."
1630 do_command(gen, lustre, options, args)
1631 except OptionError, e:
1633 except Lustre.OptionError, e:
1637 do_command(gen, lustre, options, args)
1638 except OptionError, e:
1639 panic(string.join(sys.argv),e)
1640 except Lustre.OptionError, e:
1646 printDoc(doc, open(outFile,"w"))
1648 if __name__ == "__main__":