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
140 --clientoptions options
146 --gateway_cluster_id nid
147 --target_cluster_id nid
154 --add mgmt - Management/monitoring service
156 --mgmt mgmt_service_name
168 --master_dev obd_name
171 --commit - Close a configuration version, and start a new one
174 PARAM = Lustre.Options.PARAM
176 # lmc input/output options
177 ('reference', "Print short reference for commands."),
178 ('verbose,v', "Print system commands as they are run."),
179 ('merge,m', "Append to the specified config file.", PARAM),
180 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
181 ('input,i', "", PARAM),
182 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
186 ('delete', "", PARAM),
187 ('deactivate', "", PARAM),
188 ('commit', "Commit all config changes and start a new version"),
191 ('node', "Add a new node in the cluster configuration.", PARAM),
192 ('timeout', "Set timeout to initiate recovery.", PARAM),
193 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
194 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
195 ('portals_upcall', "Set location of portals upcall script.", PARAM),
196 ('ptldebug', "Set the portals debug level", PARAM),
197 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
200 ('nettype', "Specify the network type. This can be tcp/elan/gm.", PARAM),
201 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
202 ('tcpbuf', "Optional argument to specify the TCP buffer size.", PARAM, "0"),
203 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
204 ('irq_affinity', "Optional argument.", PARAM, 0),
205 ('hostaddr', "", PARAM,""),
206 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
209 ('route', "Add a new route for the cluster.", PARAM),
210 ('router', "Optional flag to mark a node as router."),
211 ('gw', "Specify the nid of the gateway for a route.", PARAM),
212 ('gateway_cluster_id', "", PARAM, "0"),
213 ('target_cluster_id', "", PARAM, "0"),
214 ('lo', "For a range route, this is the low value nid.", PARAM),
215 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
217 # servers: mds and ost
218 ('mds', "Specify MDS name.", PARAM,""),
219 ('ost', "Specify the OST name.", PARAM,""),
220 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
221 ('failover', "Enable failover support on OSTs or MDS?"),
222 ('group', "", PARAM),
223 ('dev', "Path of the device on local system.", PARAM,""),
224 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
225 ('size', "Specify the size of the device if needed.", PARAM,"0"),
226 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
227 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
228 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
229 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
230 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
231 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
232 ('ostuuid', "", PARAM,""),
233 ('nspath', "Local mount point of server namespace.", PARAM,""),
236 # clients: mountpoint and echo
237 ('echo_client', "", PARAM),
238 ('path', "Specify the mountpoint for Lustre.", PARAM),
239 ('filesystem', "Lustre filesystem name", PARAM,""),
240 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
243 ('lov', "Specify LOV name.", PARAM,""),
244 ('index', "Specify index for OBD in LOV target table.", PARAM),
245 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
246 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
247 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
251 ('real_obd', "Specify the real device for the cache obd system.", PARAM),
252 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
253 ('cobd', "Specify COBD name", PARAM),
256 ('master_dev', "Specify the master device for the cmobd system.", PARAM),
257 ('cache_dev', "Specify the cache device for the cmobd obd system.", PARAM),
258 ('cmobd', "Specify COBD name", PARAM),
261 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
264 ('lmv', "Specify LMV name.", PARAM,""),
268 msg = string.join(map(str,args))
269 raise OptionError("Error: " + msg)
278 msg = string.join(map(str,args))
279 print "Warning: ", msg
282 # manage names and uuids
283 # need to initialize this by walking tree to ensure
284 # no duplicate names or uuids are created.
285 # this are just place holders for now.
286 # consider changing this to be like OBD-dev-host
290 while names.has_key(ret):
291 ret = "%s_%d" % (base, ctr)
298 ret = "%s_UUID" % (name)
299 if len(ret) > UUID_MAX_LENGTH:
300 ret = ret[-UUID_MAX_LENGTH:]
301 while uuids.has_key(ret):
302 ret = "%s_UUID_%d" % (name, ctr)
304 if len(ret) > UUID_MAX_LENGTH:
305 ret = ret[-UUID_MAX_LENGTH:]
311 ldlm_uuid = 'ldlm_UUID'
314 """Create a new empty lustre document"""
315 # adding ldlm here is a bit of a hack, but one is enough.
316 str = """<lustre version="%s">
317 <ldlm name="%s" uuid="%s"/>
318 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
319 return dom.parseString(str)
325 """initialize auto-name generation tables"""
327 # get all elements that contain a name attribute
328 for n in doc.childNodes:
329 if n.nodeType == n.ELEMENT_NODE:
331 names[getName(n)] = 1
332 uuids[getUUID(n)] = 1
335 def get_format_flag(options):
340 ############################################################
341 # Build config objects using DOM
346 def __init__(self, doc):
349 def ref(self, type, uuid):
350 """ generate <[type]_ref uuidref="[uuid]"/> """
351 tag = "%s_ref" % (type)
352 ref = self.doc.createElement(tag)
353 ref.setAttribute("uuidref", uuid)
356 def dev(self, devname):
357 """ generate <dev devpath="[devname]"/> """
358 tgt = self.doc.createElement('dev')
359 tgt.setAttribute("dev", devname)
362 def newService(self, tag, name, uuid):
363 """ create a new service elmement, which requires name and uuid attributes """
364 new = self.doc.createElement(tag)
365 new.setAttribute("uuid", uuid);
366 new.setAttribute("name", name);
369 def addText(self, node, str):
370 txt = self.doc.createTextNode(str)
371 node.appendChild(txt)
373 def addElement(self, node, tag, str=None):
374 """ create a new element and add it as a child to node. If str is passed,
375 a text node is created for the new element"""
376 new = self.doc.createElement(tag)
378 self.addText(new, str)
379 node.appendChild(new)
382 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
383 port=0, tcpbuf=0, irq_aff=0):
384 """create <network> node"""
385 network = self.newService("network", name, uuid)
386 network.setAttribute("nettype", net);
387 self.addElement(network, "nid", nid)
388 self.addElement(network, "clusterid", cluster_id)
390 self.addElement(network, "hostaddr", hostaddr)
392 self.addElement(network, "port", "%d" %(port))
394 self.addElement(network, "sendmem", "%d" %(tcpbuf))
395 self.addElement(network, "recvmem", "%d" %(tcpbuf))
397 self.addElement(network, "irqaffinity", "%d" %(irq_aff))
401 def routetbl(self, name, uuid):
402 """create <routetbl> node"""
403 rtbl = self.newService("routetbl", name, uuid)
406 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
407 """ create one entry for the route table """
408 ref = self.doc.createElement('route')
409 ref.setAttribute("type", gw_net_type)
410 ref.setAttribute("gw", gw)
411 ref.setAttribute("gwclusterid", gw_cluster_id)
412 ref.setAttribute("tgtclusterid", tgt_cluster_id)
413 ref.setAttribute("lo", lo)
415 ref.setAttribute("hi", hi)
418 def profile(self, name, uuid):
419 """ create a host """
420 profile = self.newService("profile", name, uuid)
423 def node(self, name, uuid, prof_uuid):
424 """ create a host """
425 node = self.newService("node", name, uuid)
426 node.appendChild(self.ref("profile", prof_uuid))
429 def ldlm(self, name, uuid):
430 """ create a ldlm """
431 ldlm = self.newService("ldlm", name, uuid)
434 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
435 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
436 mkfsoptions="", mountfsoptions="", backfstype="", backdevname=""):
437 osd = self.newService("osd", name, uuid)
438 osd.setAttribute('osdtype', osdtype)
439 osd.appendChild(self.ref("target", ost_uuid))
440 osd.appendChild(self.ref("node", node_uuid))
441 osd.appendChild(self.dev(devname))
444 self.addElement(osd, "fstype", fstype)
446 self.addElement(osd, "backfstype", backfstype)
448 self.addElement(osd, "backdevpath", backdevname)
450 dev = self.addElement(osd, "devpath", devname)
451 self.addElement(osd, "autoformat", format)
453 self.addElement(osd, "devsize", "%s" % (dev_size))
455 self.addElement(osd, "journalsize", "%s" % (journal_size))
457 self.addElement(osd, "inodesize", "%s" % (inode_size))
459 self.addElement(osd, "mkfsoptions", mkfsoptions)
461 self.addElement(osd, "mountfsoptions", mountfsoptions)
463 self.addElement(osd, "nspath", nspath)
466 def cobd(self, name, uuid, real_uuid, cache_uuid):
467 cobd = self.newService("cobd", name, uuid)
468 cobd.appendChild(self.ref("realobd",real_uuid))
469 cobd.appendChild(self.ref("cacheobd",cache_uuid))
472 def cmobd(self, name, uuid, real_uuid, cache_uuid):
473 cmobd = self.newService("cmobd", name, uuid)
474 cmobd.appendChild(self.ref("masterobd",real_uuid))
475 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
478 def ost(self, name, uuid, osd_uuid, group=""):
479 ost = self.newService("ost", name, uuid)
480 ost.appendChild(self.ref("active", osd_uuid))
482 self.addElement(ost, "group", group)
485 def oss(self, name, uuid):
486 oss = self.newService("oss", name, uuid)
489 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
490 lov = self.newService("lov", name, uuid)
491 lov.appendChild(self.ref("mds", mds_uuid))
492 lov.setAttribute("stripesize", str(stripe_sz))
493 lov.setAttribute("stripecount", str(stripe_cnt))
494 lov.setAttribute("stripepattern", str(pattern))
497 def lov_tgt(self, obd_uuid, index, generation):
498 tgt = self.doc.createElement('lov_tgt')
499 tgt.setAttribute("uuidref", obd_uuid)
500 tgt.setAttribute("index", index)
501 tgt.setAttribute("generation", generation)
502 tgt.setAttribute("active", '1')
505 def lovconfig(self, name, uuid, lov_uuid):
506 lovconfig = self.newService("lovconfig", name, uuid)
507 lovconfig.appendChild(self.ref("lov", lov_uuid))
510 def lmv(self, name, uuid):
511 lmv = self.newService("lmv", name, uuid)
514 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
515 mds = self.newService("mds", name, uuid)
516 mds.appendChild(self.ref("active",mdd_uuid))
518 self.addElement(mds, "group", group)
521 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
522 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
523 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
524 backdevname="", lmv_uuid=""):
525 mdd = self.newService("mdsdev", name, uuid)
526 self.addElement(mdd, "fstype", fstype)
528 self.addElement(mdd, "backfstype", backfstype)
529 dev = self.addElement(mdd, "devpath", devname)
531 self.addElement(mdd, "backdevpath", backdevname)
532 self.addElement(mdd, "autoformat", format)
534 self.addElement(mdd, "devsize", "%s" % (dev_size))
536 self.addElement(mdd, "journalsize", "%s" % (journal_size))
538 self.addElement(mdd, "inodesize", "%s" % (inode_size))
540 self.addElement(mdd, "nspath", nspath)
542 self.addElement(mdd, "mkfsoptions", mkfsoptions)
544 self.addElement(mdd, "mountfsoptions", mountfsoptions)
546 mdd.appendChild(self.ref("node", node_uuid))
547 mdd.appendChild(self.ref("target", mds_uuid))
548 mdd.appendChild(self.dev(devname))
551 mdd.appendChild(self.ref("lmv", lmv_uuid))
552 self.addElement(mdd, "lmv", lmv_uuid)
556 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
557 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
558 mgmt.appendChild(self.ref("node", node_uuid))
559 # Placeholder until mgmt-service failover.
560 mgmt.appendChild(self.ref("active", mgmt_uuid))
563 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
564 mtpt = self.newService("mountpoint", name, uuid)
565 mtpt.appendChild(self.ref("filesystem", fs_uuid))
566 self.addElement(mtpt, "path", path)
568 self.addElement(mtpt, "clientoptions", clientoptions)
571 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
572 fs = self.newService("filesystem", name, uuid)
573 fs.appendChild(self.ref("mds", mds_uuid))
574 fs.appendChild(self.ref("obd", obd_uuid))
576 fs.appendChild(self.ref("mgmt", mgmt_uuid))
579 def echo_client(self, name, uuid, osc_uuid):
580 ec = self.newService("echoclient", name, uuid)
581 ec.appendChild(self.ref("obd", osc_uuid))
584 def update(self, version):
585 new = self.doc.createElement("update")
586 new.setAttribute("version", version)
589 def add(self, lov, ost, index, gen):
590 new = self.doc.createElement("add")
591 new.setAttribute("lov_uuidref", lov)
592 new.setAttribute("ost_uuidref", ost)
593 new.setAttribute("index", index)
594 new.setAttribute("generation", gen)
597 def delete(self, lov, ost, index, gen, options):
599 new = self.doc.createElement("delete")
601 new = self.doc.createElement("deactivate")
602 new.setAttribute("lov_uuidref", lov)
603 new.setAttribute("ost_uuidref", ost)
604 new.setAttribute("index", index)
605 new.setAttribute("generation", gen)
608 ############################################################
609 # Utilities to query a DOM tree
610 # Using this functions we can treat use config information
611 # directly as a database.
613 return n.getAttribute('name')
616 return node.getAttribute('uuid')
618 def findLastUpdate(lustre):
621 for n in lustre.childNodes:
622 if n.nodeType == n.ELEMENT_NODE:
623 if n.nodeName != 'update':
625 tmp = int(n.getAttribute('version'))
627 error('malformed XML: update tag without a version attribute')
628 if tmp != version + 1:
629 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
634 def addUpdate(gen, lustre, node):
635 update = findLastUpdate(lustre)
638 #add_record = update.getElementsByTagName('add')
640 # add_record = gen.add()
641 # update.appendChild(add_record)
643 # add_record = add_record[0]
644 #add_record.appendChild(node)
645 update.appendChild(node)
647 def delUpdate(gen, lustre, node):
648 update = findLastUpdate(lustre)
651 update.appendChild(node)
653 def findByName(lustre, name, tag = ""):
654 for n in lustre.childNodes:
655 if n.nodeType == n.ELEMENT_NODE:
656 if tag and n.nodeName != tag:
658 if getName(n) == name:
661 n = findByName(n, name)
666 def lookup(node, uuid):
667 for n in node.childNodes:
668 if n.nodeType == n.ELEMENT_NODE:
669 if getUUID(n) == uuid:
677 def name2uuid(lustre, name, tag="", fatal=1):
678 ret = findByName(lustre, name, tag)
681 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
686 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
687 for n in lustre.childNodes:
688 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
689 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
693 # XXX: assumes only one network element per node. will fix this
694 # as soon as support for routers is added
695 def get_net_uuid(lustre, node_name):
696 """ get a network uuid for a node_name """
697 node = findByName(lustre, node_name, "node")
699 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
700 net = node.getElementsByTagName('network')
702 return getUUID(net[0])
705 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
706 lov_name = getName(lov)
708 lov_index = get_option_int(options, 'index')
709 for tgt in lustre.getElementsByTagName('lov_tgt'):
710 if str(lov_index) == tgt.getAttribute('index'):
711 uuidref = tgt.getAttribute('uuidref')
713 raise OptionError("%s --index %d is still in use: %s" %
714 (lov_name, lov_index, uuidref))
715 tgt.setAttribute('uuidref', osc_uuid)
716 gener = int(tgt.getAttribute('generation')) + 1
717 tgt.setAttribute('generation', str(gener))
718 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid,
719 str(lov_index), str(gener)))
722 lov.appendChild(gen.lov_tgt(osc_uuid, str(lov_index), '1'))
723 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
728 for tgt in lov.getElementsByTagName('lov_tgt'):
729 uuidref = tgt.getAttribute('uuidref')
730 tmp = int(tgt.getAttribute('index'))
732 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(index + 1)+'.')
735 lov.appendChild(gen.lov_tgt(osc_uuid, str(index + 1), '1'))
736 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(index + 1), '1'))
738 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
739 lov_name = getName(lov)
741 lov_index = get_option_int(options, 'index')
742 for tgt in lustre.getElementsByTagName('lov_tgt'):
743 index = tgt.getAttribute('index')
744 if index == lov_index:
745 uuidref = tgt.getAttribute('uuidref')
746 if uuidref != osc_uuid:
747 raise OptionError("%s --index %d contains %s, not %s" %
748 (lov_name, lov_index, osc_uuid, uuidref))
750 tgt.setAttribute('uuidref', '')
752 tgt.setAttribute('active', '0')
753 # bump the generation just in case...
754 gen = int(tgt.getAttribute('generation')) + 1
755 tgt.setAttribute('generation', str(gen))
757 raise OptionError("%s --index %d not in use by %s." %
758 (lov_name, lov_index, osc_uuid))
760 for tgt in lustre.getElementsByTagName('lov_tgt'):
761 uuidref = tgt.getAttribute('uuidref')
762 if uuidref == osc_uuid:
763 genera = int(tgt.getAttribute('generation'))
764 delete_rec = gen.delete(getUUID(lov),
765 osc_uuid,tgt.getAttribute('index'),
766 str(genera), options)
767 delUpdate(gen, lustre, delete_rec)
770 tgt.setAttribute('uuidref', '')
772 tgt.setAttribute('active', '0')
774 tgt.setAttribute('generation', str(genera))
776 def lmv_add_obd(gen, lmv, mdc_uuid):
777 lmv.appendChild(gen.ref("mds", mdc_uuid))
779 def ref_exists(profile, uuid):
780 elist = profile.childNodes
782 if e.nodeType == e.ELEMENT_NODE:
783 ref = e.getAttribute('uuidref')
788 # ensure that uuid is not already in the profile
789 # return true if uuid is added
790 def node_add_profile(gen, node, ref, uuid):
791 refname = "%s_ref" % "profile"
792 ret = node.getElementsByTagName(refname)
794 error('node has no profile ref:', node)
795 prof_uuid = ret[0].getAttribute('uuidref')
796 profile = lookup(node.parentNode, prof_uuid)
798 error("no profile found:", prof_uuid)
799 if ref_exists(profile, uuid):
801 profile.appendChild(gen.ref(ref, uuid))
804 # ensure that uuid is not already in the profile
805 # return true if uuid is added
806 def node_found_target_by_dev(gen, lustre, node, devname):
807 refname = "%s_ref" % "profile"
808 ret = node.getElementsByTagName(refname)
810 error('node has no profile ref:', node)
811 prof_uuid = ret[0].getAttribute('uuidref')
812 profile = lookup(node.parentNode, prof_uuid)
814 error("no profile found:", prof_uuid)
816 osd_list = lustre.getElementsByTagName('osd')
819 obd_dev = osd.getElementsByTagName('dev')
820 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
821 for ost in lustre.getElementsByTagName('ost'):
822 active_ret = ost.getElementsByTagName('active_ref')
823 if active_ret[0].getAttribute('uuidref') == osd.getAttribute('uuid'):
824 return ost.getAttribute('uuid')
826 mdsdev_list = lustre.getElementsByTagName('mdsdev')
828 for mdsdev in mdsdev_list:
829 obd_dev = mdsdev.getElementsByTagName('dev')
830 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
831 for mds in lustre.getElementsByTagName('mds'):
832 active_ret = mds.getElementsByTagName('active_ref')
833 if active_ret[0].getAttribute('uuidref') == mdsdev.getAttribute('uuid'):
834 return mds.getAttribute('uuid')
838 def get_attr(dom_node, attr, default=""):
839 v = dom_node.getAttribute(attr)
844 ############################################################
847 def set_node_options(gen, node, options):
849 node.setAttribute('router', '1')
851 gen.addElement(node, "timeout", get_option(options, 'timeout'))
853 default_upcall = get_option(options, 'upcall')
856 if default_upcall or options.lustre_upcall:
857 if options.lustre_upcall:
858 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
860 gen.addElement(node, 'lustreUpcall', default_upcall)
861 if default_upcall or options.portals_upcall:
862 if options.portals_upcall:
863 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
865 gen.addElement(node, 'portalsUpcall', default_upcall)
867 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
868 if options.subsystem:
869 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
872 def do_add_node(gen, lustre, options, node_name):
873 uuid = new_uuid(node_name)
874 prof_name = new_name("PROFILE_" + node_name)
875 prof_uuid = new_uuid(prof_name)
876 profile = gen.profile(prof_name, prof_uuid)
877 node = gen.node(node_name, uuid, prof_uuid)
878 lustre.appendChild(node)
879 lustre.appendChild(profile)
881 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
882 set_node_options(gen, node, options)
887 def add_node(gen, lustre, options):
888 """ create a node with a network config """
890 node_name = get_option(options, 'node')
891 ret = findByName(lustre, node_name, "node")
893 print "Node:", node_name, "exists."
895 do_add_node(gen, lustre, options, node_name)
898 def add_net(gen, lustre, options):
899 """ create a node with a network config """
901 node_name = get_option(options, 'node')
902 nid = get_option(options, 'nid')
903 cluster_id = get_option(options, 'cluster_id')
904 hostaddr = get_option(options, 'hostaddr')
905 net_type = get_option(options, 'nettype')
907 if net_type in ('tcp',):
908 port = get_option_int(options, 'port')
909 tcpbuf = get_option_int(options, 'tcpbuf')
910 irq_aff = get_option_int(options, 'irq_affinity')
911 elif net_type in ('elan', 'gm'):
916 print "Unknown net_type: ", net_type
919 ret = findByName(lustre, node_name, "node")
921 node = do_add_node(gen, lustre, options, node_name)
924 set_node_options(gen, node, options)
926 net_name = new_name('NET_'+ node_name +'_'+ net_type)
927 net_uuid = new_uuid(net_name)
928 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
929 hostaddr, port, tcpbuf, irq_aff))
930 node_add_profile(gen, node, "network", net_uuid)
933 def add_route(gen, lustre, options):
934 """ create a node with a network config """
936 node_name = get_option(options, 'node')
937 gw_net_type = get_option(options, 'nettype')
938 gw = get_option(options, 'gw')
939 gw_cluster_id = get_option(options, 'gateway_cluster_id')
940 tgt_cluster_id = get_option(options, 'target_cluster_id')
941 lo = get_option(options, 'lo')
942 hi = get_option(options, 'hi')
946 node = findByName(lustre, node_name, "node")
948 error (node_name, " not found.")
950 rlist = node.getElementsByTagName('routetbl')
954 rtbl_name = new_name("RTBL_" + node_name)
955 rtbl_uuid = new_uuid(rtbl_name)
956 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
957 node.appendChild(rtbl)
958 node_add_profile(gen, node, "routetbl", rtbl_uuid)
959 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
963 def add_mds(gen, lustre, options):
964 node_name = get_option(options, 'node')
965 mds_name = get_option(options, 'mds')
966 lmv_name = get_option(options, 'lmv')
967 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
968 mdd_uuid = new_uuid(mdd_name)
972 lmv = findByName(lustre, lmv_name, "lmv")
974 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
975 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
977 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
979 mds_uuid = new_uuid(mds_name)
980 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
981 lustre.appendChild(mds)
983 lmv_add_obd(gen, lmv, mds_uuid)
985 mds = lookup(lustre, mds_uuid)
988 mds.setAttribute('failover', "1")
990 devname = get_option(options, 'dev')
991 backdevname = get_option(options, 'backdev')
992 size = get_option(options, 'size')
993 fstype = get_option(options, 'fstype')
994 backfstype = get_option(options, 'backfstype')
995 journal_size = get_option(options, 'journal_size')
996 inode_size = get_option(options, 'inode_size')
997 nspath = get_option(options, 'nspath')
998 mkfsoptions = get_option(options, 'mkfsoptions')
999 mountfsoptions = get_option(options, 'mountfsoptions')
1001 node_uuid = name2uuid(lustre, node_name, 'node')
1003 node = findByName(lustre, node_name, "node")
1004 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1005 net_uuid = get_net_uuid(lustre, node_name)
1007 error("NODE: ", node_name, "not found")
1010 mds.appendChild(gen.ref("lmv", lmv_uuid))
1012 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1013 get_format_flag(options), node_uuid, mds_uuid,
1014 size, journal_size, inode_size, nspath, mkfsoptions,
1015 mountfsoptions, backfstype, backdevname, lmv_uuid)
1016 lustre.appendChild(mdd)
1019 def add_mgmt(gen, lustre, options):
1020 node_name = get_option(options, 'node')
1021 node_uuid = name2uuid(lustre, node_name, 'node')
1022 mgmt_name = get_option(options, 'mgmt')
1024 mgmt_name = new_name('MGMT_' + node_name)
1025 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1027 mgmt_uuid = new_uuid(mgmt_name)
1028 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1029 lustre.appendChild(mgmt)
1031 mgmt = lookup(lustre, mgmt_uuid)
1033 node = findByName(lustre, node_name, "node")
1034 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1036 def add_ost(gen, lustre, options):
1037 node_name = get_option(options, 'node')
1038 lovname = get_option(options, 'lov')
1039 osdtype = get_option(options, 'osdtype')
1041 node_uuid = name2uuid(lustre, node_name, 'node')
1043 if osdtype == 'obdecho':
1054 devname = get_option(options, 'dev') # can be unset for bluearcs
1055 backdevname = get_option(options, 'backdev')
1056 size = get_option(options, 'size')
1057 fstype = get_option(options, 'fstype')
1058 backfstype = get_option(options, 'backfstype')
1059 journal_size = get_option(options, 'journal_size')
1060 inode_size = get_option(options, 'inode_size')
1061 mkfsoptions = get_option(options, 'mkfsoptions')
1062 mountfsoptions = get_option(options, 'mountfsoptions')
1064 nspath = get_option(options, 'nspath')
1066 ostname = get_option(options, 'ost')
1068 ostname = new_name('OST_'+ node_name)
1070 osdname = new_name("OSD_" + ostname + "_" + node_name)
1071 osd_uuid = new_uuid(osdname)
1073 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1075 ost_uuid = get_option(options, 'ostuuid')
1077 if lookup(lustre, ost_uuid):
1078 error("Duplicate OST UUID:", ost_uuid)
1080 ost_uuid = new_uuid(ostname)
1082 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1083 lustre.appendChild(ost)
1086 lov = findByName(lustre, lovname, "lov")
1088 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1089 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1091 ost = lookup(lustre, ost_uuid)
1093 if options.failover:
1094 ost.setAttribute('failover', "1")
1097 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1098 get_format_flag(options), ost_uuid, node_uuid, size,
1099 journal_size, inode_size, nspath, mkfsoptions,
1100 mountfsoptions, backfstype, backdevname)
1102 node = findByName(lustre, node_name, "node")
1104 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1106 ## oss_uuid = new_uuid(ossname)
1107 ## oss = gen.oss(ossname, oss_uuid)
1108 ## lustre.appendChild(oss)
1110 node_add_profile(gen, node, 'osd', osd_uuid)
1111 lustre.appendChild(osd)
1113 def del_ost(gen, lustre, options):
1114 ostname = get_option(options, 'ost')
1116 raise OptionError("del_ost: --ost requires a <ost name>")
1117 ost = findByName(lustre, ostname, "ost")
1119 error('del_ost: ', 'Unable to find ', ostname)
1120 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1122 error('del_ost: ', 'Unable to find uuid for ', ostname)
1123 lovname = get_option(options, 'lov')
1125 lov = findByName(lustre, lovname, "lov")
1127 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1128 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1129 # if the user specified a speficic LOV don't delete the OST itself
1132 # remove OSD references from all LOVs
1133 for n in lustre.getElementsByTagName('lov'):
1134 lov_del_obd(gen, lustre, n, ost_uuid, options)
1137 for osd in lustre.getElementsByTagName('osd'):
1138 if ref_exists(osd, ost_uuid):
1139 osd_uuid = osd.getAttribute('uuid')
1140 # delete all profile references to this OSD
1141 for profile in lustre.getElementsByTagName('profile'):
1142 for osd_ref in profile.getElementsByTagName('osd_ref'):
1143 if osd_uuid == osd_ref.getAttribute('uuidref'):
1144 profile.removeChild(osd_ref)
1145 lustre.removeChild(osd)
1148 lustre.removeChild(ost)
1150 def add_cmobd(gen, lustre, options):
1151 node_name = get_option(options, 'node')
1152 name = get_option(options, 'cmobd')
1153 uuid = new_uuid(name)
1155 real_name = get_option(options, 'master_dev')
1156 cache_name = get_option(options, 'cache_dev')
1158 node = findByName(lustre, node_name, "node")
1159 node_add_profile(gen, node, "cmobd", uuid)
1160 real_uuid = node_found_target_by_dev(gen, lustre, node, real_name)
1161 cache_uuid = node_found_target_by_dev(gen, lustre, node, cache_name)
1163 panic("add_cmobd", "can not find real_uuid")
1165 panic("add_cmobd", "can not find cache_uuid")
1166 cmobd = gen.cmobd(name, uuid, real_uuid, cache_uuid)
1167 lustre.appendChild(cmobd)
1169 def add_cobd(gen, lustre, options):
1170 node_name = get_option(options, 'node')
1171 name = get_option(options, 'cobd')
1172 uuid = new_uuid(name)
1174 real_name = get_option(options, 'real_obd')
1175 cache_name = get_option(options, 'cache_obd')
1177 real_uuid = name2uuid(lustre, real_name, tag='lov', fatal=0)
1178 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1181 node = lookup(lustre, real_uuid)
1182 rets = node.getElementsByTagName('lov_tgt')
1184 ost_uuid = ret.getAttribute('uuidref')
1185 ost_node = lookup(lustre, ost_uuid)
1186 ret = ost_node.getElementsByTagName('active_ref')
1188 osd_uuid = ret[0].getAttribute('uuidref')
1189 osd_node = lookup(lustre, osd_uuid)
1190 gen.addElement(osd_node, 'cachetype', 'master')
1193 node = lookup(lustre, cache_uuid)
1194 rets = node.getElementsByTagName('lov_tgt')
1196 ost_uuid = ret.getAttribute('uuidref')
1197 ost_node = lookup(lustre, ost_uuid)
1198 ret = ost_node.getElementsByTagName('active_ref')
1200 osd_uuid = ret[0].getAttribute('uuidref')
1201 osd_node = lookup(lustre, osd_uuid)
1202 gen.addElement(osd_node, 'cachetype', 'cache')
1204 if not real_uuid or not cache_uuid:
1205 real_uuid = name2uuid(lustre,real_name, tag='mds')
1206 cache_uuid = name2uuid(lustre,cache_name, tag='mds')
1208 mds_node = lookup(lustre, real_uuid)
1209 ret = mds_node.getElementsByTagName('active_ref')
1211 mdsdev_uuid = ret[0].getAttribute('uuidref')
1212 mdsdev_node = lookup(lustre, mdsdev_uuid)
1213 gen.addElement(mdsdev_node, 'cachetype', 'master')
1215 mds_node = lookup(lustre, cache_uuid)
1216 ret = mds_node.getElementsByTagName('active_ref')
1218 mdsdev_uuid = ret[0].getAttribute('uuidref')
1219 mdsdev_node = lookup(lustre, mdsdev_uuid)
1220 gen.addElement(mdsdev_node, 'cachetype', 'cache')
1222 node = findByName(lustre, node_name, "node")
1223 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
1224 lustre.appendChild(cobd)
1227 def add_echo_client(gen, lustre, options):
1228 """ add an echo client to the profile for this node. """
1229 node_name = get_option(options, 'node')
1230 lov_name = get_option(options, 'ost')
1232 node = findByName(lustre, node_name, 'node')
1234 echoname = new_name('ECHO_'+ node_name)
1235 echo_uuid = new_uuid(echoname)
1236 node_add_profile(gen, node, 'echoclient', echo_uuid)
1238 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1240 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1242 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1243 lustre.appendChild(echo)
1246 def add_lov(gen, lustre, options):
1247 """ create a lov """
1249 lmv_name = get_option(options, 'lmv')
1250 lov_orig = get_option(options, 'lov')
1251 name = new_name(lov_orig)
1252 if name != lov_orig:
1253 warning("name:", lov_orig, "already used. using:", name)
1255 mds_name = get_option(options, 'mds')
1258 error("LOV: MDS or LMV must be specified.");
1260 stripe_sz = get_option_int(options, 'stripe_sz')
1261 stripe_cnt = get_option_int(options, 'stripe_cnt')
1262 pattern = get_option_int(options, 'stripe_pattern')
1263 uuid = new_uuid(name)
1265 ret = findByName(lustre, name, "lov")
1267 error("LOV: ", name, " already exists.")
1270 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1272 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1274 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1275 lustre.appendChild(lov)
1277 # add an lovconfig entry to the active mdsdev profile
1278 lovconfig_name = new_name('LVCFG_' + name)
1279 lovconfig_uuid = new_uuid(lovconfig_name)
1281 mds = findByName(lustre, mds_name, "mds")
1282 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1284 lmv = findByName(lustre, lmv_name, "lmv")
1285 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1286 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1287 lustre.appendChild(lovconfig)
1289 def add_default_lov(gen, lustre, mds_name, lov_name):
1290 """ create a default lov """
1292 stripe_sz = DEFAULT_STRIPE_SZ
1293 stripe_cnt = DEFAULT_STRIPE_CNT
1294 pattern = DEFAULT_STRIPE_PATTERN
1295 uuid = new_uuid(lov_name)
1297 ret = findByName(lustre, lov_name, "lov")
1299 error("LOV: ", lov_name, " already exists.")
1301 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1302 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1303 lustre.appendChild(lov)
1305 # add an lovconfig entry to the active mdsdev profile
1306 lovconfig_name = new_name('LVCFG_' + lov_name)
1307 lovconfig_uuid = new_uuid(lovconfig_name)
1308 mds = findByName(lustre, mds_name)
1309 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1310 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1311 lustre.appendChild(lovconfig)
1313 def add_lmv(gen, lustre, options):
1314 """ create a lmv """
1316 lmv_orig = get_option(options, 'lmv')
1317 name = new_name(lmv_orig)
1318 if name != lmv_orig:
1319 warning("name:", lmv_orig, "already used. using:", name)
1321 uuid = new_uuid(name)
1322 ret = findByName(lustre, name, "lmv")
1324 error("LMV: ", name, " already exists.")
1326 lmv = gen.lmv(name, uuid)
1327 lustre.appendChild(lmv)
1329 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1330 fs_name = new_name("FS_fsname")
1331 fs_uuid = new_uuid(fs_name)
1332 cobd = lookup(lustre, mds_uuid)
1333 #SHOULD appendChild filesystem to real mds not cobd
1334 ret = cobd.getElementsByTagName("cacheobd_ref")
1336 cacheobd_uuid = ret[0].getAttribute('uuidref')
1337 cacheobd = lookup(lustre, cacheobd_uuid)
1338 cacheobd.appendChild(gen.ref("filesystem", fs_uuid))
1339 ret = cobd.getElementsByTagName("realobd_ref")
1341 realobd_uuid = ret[0].getAttribute('uuidref')
1342 realobd = lookup(lustre, realobd_uuid)
1343 realobd.appendChild(gen.ref("filesystem", fs_uuid))
1345 cobd.appendChild(gen.ref("filesystem", fs_uuid))
1346 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid, mgmt_uuid)
1347 lustre.appendChild(fs)
1350 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1351 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1353 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1355 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=1)
1356 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1358 obd_uuid = name2uuid(lustre, obd_name, tag='cobd')
1360 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1363 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1365 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid)
1368 def add_mtpt(gen, lustre, options):
1369 """ create mtpt on a node """
1370 node_name = get_option(options, 'node')
1372 path = get_option(options, 'path')
1373 clientoptions = get_option(options, "clientoptions")
1374 fs_name = get_option(options, 'filesystem')
1376 lov_name = get_option(options, 'lov')
1377 ost_name = get_option(options, 'ost')
1378 mds_name = get_option(options, 'mds')
1380 mds_name = get_option(options, 'lmv')
1382 error("--add mtpt requires either --mds or --lmv.")
1385 error("--add mtpt requires --lov lov_name or --ost ost_name")
1387 warning("use default value for lov, due no --lov lov_name provided")
1388 lov_name = new_name("lov_default")
1389 add_default_lov(gen, lustre, mds_name, lov_name)
1390 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1392 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1393 lov = findByName(lustre, lov_name, "lov")
1394 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1397 mgmt_name = get_option(options, 'mgmt')
1398 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1400 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1402 name = new_name('MNT_'+ node_name)
1404 ret = findByName(lustre, name, "mountpoint")
1406 # this can't happen, because new_name creates unique names
1407 error("MOUNTPOINT: ", name, " already exists.")
1409 uuid = new_uuid(name)
1410 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
1411 node = findByName(lustre, node_name, "node")
1413 error('node:', node_name, "not found.")
1414 node_add_profile(gen, node, "mountpoint", uuid)
1415 lustre.appendChild(mtpt)
1417 def commit_version(gen, lustre):
1418 update = findLastUpdate(lustre)
1420 version = int(update.getAttribute("version")) + 1
1424 new = gen.update(str(version))
1425 lustre.appendChild(new)
1428 ############################################################
1429 # Command line processing
1431 class OptionError (exceptions.Exception):
1432 def __init__(self, args):
1435 def get_option(options, tag):
1436 """Look for tag in options hash and return the value if set. If not
1437 set, then if return default it is set, otherwise exception."""
1438 if options.__getattr__(tag) != None:
1439 return options.__getattr__(tag)
1441 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1443 def get_option_int(options, tag):
1444 """Return an integer option. Raise exception if the value is not an int"""
1445 val = get_option(options, tag)
1449 raise OptionError("--%s <num> (value must be integer)" % (tag))
1452 # simple class for profiling
1459 self._start = time.time()
1460 def stop(self, msg=''):
1461 self._stop = time.time()
1465 return self._stop - self._start
1466 def display(self, msg):
1468 str = '%s: %g secs' % (msg, d)
1471 #################################################################
1472 # function cmdlinesplit used to split cmd line from batch file
1474 def cmdlinesplit(cmdline):
1476 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1477 single_quote = re.compile(r"'(.*?)'")
1478 escaped = re.compile(r'\\(.)')
1479 esc_quote = re.compile(r'\\([\\"])')
1480 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1484 while i < len(cmdline):
1487 match = double_quote.match(cmdline, i)
1489 print "Unmatched double quote:", cmdline
1492 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1493 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1496 match = single_quote.match(cmdline, i)
1498 print "Unmatched single quote:", cmdline
1501 if arg is None: arg = match.group(1)
1502 else: arg = arg + match.group(1)
1505 match = escaped.match(cmdline, i)
1507 print "Unmatched backslash", cmdline
1510 if arg is None: arg = match.group(1)
1511 else: arg = arg + match.group(1)
1513 elif c in string.whitespace:
1515 arg_list.append(str(arg))
1517 while i < len(cmdline) and cmdline[i] in string.whitespace:
1520 match = outside.match(cmdline, i)
1523 if arg is None: arg = match.group()
1524 else: arg = arg + match.group()
1526 if arg != None: arg_list.append(str(arg))
1530 ############################################################
1534 def add(devtype, gen, lustre, options):
1535 if devtype == 'net':
1536 add_net(gen, lustre, options)
1537 elif devtype == 'mtpt':
1538 add_mtpt(gen, lustre, options)
1539 elif devtype == 'mds':
1540 add_mds(gen, lustre, options)
1541 elif devtype == 'ost':
1542 add_ost(gen, lustre, options)
1543 elif devtype == 'lov':
1544 add_lov(gen, lustre, options)
1545 elif devtype == 'route':
1546 add_route(gen, lustre, options)
1547 elif devtype == 'node':
1548 add_node(gen, lustre, options)
1549 elif devtype == 'echo_client':
1550 add_echo_client(gen, lustre, options)
1551 elif devtype == 'cobd':
1552 add_cobd(gen, lustre, options)
1553 elif devtype == 'cmobd':
1554 add_cmobd(gen, lustre, options)
1555 elif devtype == 'mgmt':
1556 add_mgmt(gen, lustre, options)
1557 elif devtype == 'lmv':
1558 add_lmv(gen, lustre, options)
1560 error("unknown device type:", devtype)
1562 def delete(devtype, gen, lustre, options):
1563 if devtype == 'ost':
1564 del_ost(gen, lustre, options)
1565 elif options.delete:
1566 error("delete not supported for device type:", devtype)
1567 elif options.deactivate:
1568 error("deactivate not supported for device type:", devtype)
1570 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1572 def commit(gen, lustre):
1573 commit_version(gen, lustre)
1575 def do_command(gen, lustre, options, args):
1577 add(options.add, gen, lustre, options)
1578 elif options.delete:
1579 delete(options.delete, gen, lustre, options)
1580 elif options.deactivate:
1581 delete(options.deactivate, gen, lustre, options)
1582 elif options.commit:
1585 error("Missing command")
1588 cl = Lustre.Options("lmc", "", lmc_options)
1590 options, args = cl.parse(sys.argv[1:])
1591 except Lustre.OptionError, e:
1595 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1597 if options.reference:
1604 outFile = options.merge
1605 if os.access(outFile, os.R_OK):
1606 doc = xml.dom.minidom.parse(outFile)
1608 doc = new_lustre(xml.dom.minidom)
1610 doc = xml.dom.minidom.parse(options.input)
1612 doc = new_lustre(xml.dom.minidom)
1615 outFile = options.output
1617 lustre = doc.documentElement
1619 if lustre.tagName != "lustre":
1620 print "Existing config not valid."
1623 gen = GenConfig(doc)
1626 fp = open(options.batch)
1627 batchCommands = fp.readlines()
1629 for cmd in batchCommands:
1631 options, args = cl.parse(cmdlinesplit(cmd))
1632 if options.merge or options.input or options.output:
1633 print "The batchfile should not contain --merge, --input or --output."
1635 do_command(gen, lustre, options, args)
1636 except OptionError, e:
1638 except Lustre.OptionError, e:
1642 do_command(gen, lustre, options, args)
1643 except OptionError, e:
1644 panic(string.join(sys.argv),e)
1645 except Lustre.OptionError, e:
1651 printDoc(doc, open(outFile,"w"))
1653 if __name__ == "__main__":