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
135 --add mtpt - Mountpoint
140 --ost ost_name OR --lov lov_name
141 --clientoptions options
147 --gateway_cluster_id nid
148 --target_cluster_id nid
155 --add mgmt - Management/monitoring service
157 --mgmt mgmt_service_name
169 --master_dev obd_name
172 --commit - Close a configuration version, and start a new one
175 PARAM = Lustre.Options.PARAM
177 # lmc input/output options
178 ('reference', "Print short reference for commands."),
179 ('verbose,v', "Print system commands as they are run."),
180 ('merge,m', "Append to the specified config file.", PARAM),
181 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
182 ('input,i', "", PARAM),
183 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
187 ('delete', "", PARAM),
188 ('deactivate', "", PARAM),
189 ('commit', "Commit all config changes and start a new version"),
192 ('node', "Add a new node in the cluster configuration.", PARAM),
193 ('timeout', "Set timeout to initiate recovery.", PARAM),
194 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
195 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
196 ('portals_upcall', "Set location of portals upcall script.", PARAM),
197 ('ptldebug', "Set the portals debug level", PARAM),
198 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
201 ('nettype', "Specify the network type. This can be tcp/elan/gm.", PARAM),
202 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
203 ('tcpbuf', "Optional argument to specify the TCP buffer size.", PARAM, "0"),
204 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
205 ('irq_affinity', "Optional argument.", PARAM, 0),
206 ('hostaddr', "", PARAM,""),
207 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
210 ('route', "Add a new route for the cluster.", PARAM),
211 ('router', "Optional flag to mark a node as router."),
212 ('gw', "Specify the nid of the gateway for a route.", PARAM),
213 ('gateway_cluster_id', "", PARAM, "0"),
214 ('target_cluster_id', "", PARAM, "0"),
215 ('lo', "For a range route, this is the low value nid.", PARAM),
216 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
218 # servers: mds and ost
219 ('mds', "Specify MDS name.", PARAM,""),
220 ('ost', "Specify the OST name.", PARAM,""),
221 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
222 ('failover', "Enable failover support on OSTs or MDS?"),
223 ('group', "", PARAM),
224 ('dev', "Path of the device on local system.", PARAM,""),
225 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
226 ('size', "Specify the size of the device if needed.", PARAM,"0"),
227 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
228 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
229 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
230 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
231 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
232 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
233 ('ostuuid', "", PARAM,""),
234 ('nspath', "Local mount point of server namespace.", PARAM,""),
236 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
238 # clients: mountpoint and echo
239 ('echo_client', "", PARAM),
240 ('path', "Specify the mountpoint for Lustre.", PARAM),
241 ('filesystem', "Lustre filesystem name", PARAM,""),
242 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
245 ('lov', "Specify LOV name.", PARAM,""),
246 ('index', "Specify index for OBD in LOV target table.", PARAM),
247 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
248 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
249 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
253 ('real_obd', "Specify the real device for the cache obd system.", PARAM),
254 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
255 ('cobd', "Specify COBD name", PARAM),
258 ('master_dev', "Specify the master device for the cmobd system.", PARAM),
259 ('cache_dev', "Specify the cache device for the cmobd obd system.", PARAM),
260 ('cmobd', "Specify COBD name", PARAM),
263 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
266 ('lmv', "Specify LMV name.", PARAM,""),
270 msg = string.join(map(str,args))
271 raise OptionError("Error: " + msg)
280 msg = string.join(map(str,args))
281 print "Warning: ", msg
284 # manage names and uuids
285 # need to initialize this by walking tree to ensure
286 # no duplicate names or uuids are created.
287 # this are just place holders for now.
288 # consider changing this to be like OBD-dev-host
292 while names.has_key(ret):
293 ret = "%s_%d" % (base, ctr)
300 ret = "%s_UUID" % (name)
301 if len(ret) > UUID_MAX_LENGTH:
302 ret = ret[-UUID_MAX_LENGTH:]
303 while uuids.has_key(ret):
304 ret = "%s_UUID_%d" % (name, ctr)
306 if len(ret) > UUID_MAX_LENGTH:
307 ret = ret[-UUID_MAX_LENGTH:]
313 ldlm_uuid = 'ldlm_UUID'
316 """Create a new empty lustre document"""
317 # adding ldlm here is a bit of a hack, but one is enough.
318 str = """<lustre version="%s">
319 <ldlm name="%s" uuid="%s"/>
320 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
321 return dom.parseString(str)
327 """initialize auto-name generation tables"""
329 # get all elements that contain a name attribute
330 for n in doc.childNodes:
331 if n.nodeType == n.ELEMENT_NODE:
333 names[getName(n)] = 1
334 uuids[getUUID(n)] = 1
337 def get_format_flag(options):
342 ############################################################
343 # Build config objects using DOM
348 def __init__(self, doc):
351 def ref(self, type, uuid):
352 """ generate <[type]_ref uuidref="[uuid]"/> """
353 tag = "%s_ref" % (type)
354 ref = self.doc.createElement(tag)
355 ref.setAttribute("uuidref", uuid)
358 def dev(self, devname):
359 """ generate <dev devpath="[devname]"/> """
360 tgt = self.doc.createElement('dev')
361 tgt.setAttribute("dev", devname)
364 def newService(self, tag, name, uuid):
365 """ create a new service elmement, which requires name and uuid attributes """
366 new = self.doc.createElement(tag)
367 new.setAttribute("uuid", uuid);
368 new.setAttribute("name", name);
371 def addText(self, node, str):
372 txt = self.doc.createTextNode(str)
373 node.appendChild(txt)
375 def addElement(self, node, tag, str=None):
376 """ create a new element and add it as a child to node. If str is passed,
377 a text node is created for the new element"""
378 new = self.doc.createElement(tag)
380 self.addText(new, str)
381 node.appendChild(new)
384 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
385 port=0, tcpbuf=0, irq_aff=0):
386 """create <network> node"""
387 network = self.newService("network", name, uuid)
388 network.setAttribute("nettype", net);
389 self.addElement(network, "nid", nid)
390 self.addElement(network, "clusterid", cluster_id)
392 self.addElement(network, "hostaddr", hostaddr)
394 self.addElement(network, "port", "%d" %(port))
396 self.addElement(network, "sendmem", "%d" %(tcpbuf))
397 self.addElement(network, "recvmem", "%d" %(tcpbuf))
399 self.addElement(network, "irqaffinity", "%d" %(irq_aff))
403 def routetbl(self, name, uuid):
404 """create <routetbl> node"""
405 rtbl = self.newService("routetbl", name, uuid)
408 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
409 """ create one entry for the route table """
410 ref = self.doc.createElement('route')
411 ref.setAttribute("type", gw_net_type)
412 ref.setAttribute("gw", gw)
413 ref.setAttribute("gwclusterid", gw_cluster_id)
414 ref.setAttribute("tgtclusterid", tgt_cluster_id)
415 ref.setAttribute("lo", lo)
417 ref.setAttribute("hi", hi)
420 def profile(self, name, uuid):
421 """ create a host """
422 profile = self.newService("profile", name, uuid)
425 def node(self, name, uuid, prof_uuid):
426 """ create a host """
427 node = self.newService("node", name, uuid)
428 node.appendChild(self.ref("profile", prof_uuid))
431 def ldlm(self, name, uuid):
432 """ create a ldlm """
433 ldlm = self.newService("ldlm", name, uuid)
436 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
437 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
438 mkfsoptions="", mountfsoptions="", backfstype="", backdevname=""):
439 osd = self.newService("osd", name, uuid)
440 osd.setAttribute('osdtype', osdtype)
441 osd.appendChild(self.ref("target", ost_uuid))
442 osd.appendChild(self.ref("node", node_uuid))
443 osd.appendChild(self.dev(devname))
446 self.addElement(osd, "fstype", fstype)
448 self.addElement(osd, "backfstype", backfstype)
450 self.addElement(osd, "backdevpath", backdevname)
452 dev = self.addElement(osd, "devpath", devname)
453 self.addElement(osd, "autoformat", format)
455 self.addElement(osd, "devsize", "%s" % (dev_size))
457 self.addElement(osd, "journalsize", "%s" % (journal_size))
459 self.addElement(osd, "inodesize", "%s" % (inode_size))
461 self.addElement(osd, "mkfsoptions", mkfsoptions)
463 self.addElement(osd, "mountfsoptions", mountfsoptions)
465 self.addElement(osd, "nspath", nspath)
468 def cobd(self, name, uuid, real_uuid, cache_uuid):
469 cobd = self.newService("cobd", name, uuid)
470 cobd.appendChild(self.ref("realobd",real_uuid))
471 cobd.appendChild(self.ref("cacheobd",cache_uuid))
474 def cmobd(self, name, uuid, real_uuid, cache_uuid):
475 cmobd = self.newService("cmobd", name, uuid)
476 cmobd.appendChild(self.ref("masterobd",real_uuid))
477 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
480 def ost(self, name, uuid, osd_uuid, group=""):
481 ost = self.newService("ost", name, uuid)
482 ost.appendChild(self.ref("active", osd_uuid))
484 self.addElement(ost, "group", group)
487 def oss(self, name, uuid):
488 oss = self.newService("oss", name, uuid)
491 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
492 lov = self.newService("lov", name, uuid)
493 lov.appendChild(self.ref("mds", mds_uuid))
494 lov.setAttribute("stripesize", str(stripe_sz))
495 lov.setAttribute("stripecount", str(stripe_cnt))
496 lov.setAttribute("stripepattern", str(pattern))
499 def lov_tgt(self, obd_uuid, index, generation):
500 tgt = self.doc.createElement('lov_tgt')
501 tgt.setAttribute("uuidref", obd_uuid)
502 tgt.setAttribute("index", index)
503 tgt.setAttribute("generation", generation)
504 tgt.setAttribute("active", '1')
507 def lovconfig(self, name, uuid, lov_uuid):
508 lovconfig = self.newService("lovconfig", name, uuid)
509 lovconfig.appendChild(self.ref("lov", lov_uuid))
512 def lmv(self, name, uuid):
513 lmv = self.newService("lmv", name, uuid)
516 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
517 mds = self.newService("mds", name, uuid)
518 mds.appendChild(self.ref("active",mdd_uuid))
520 self.addElement(mds, "group", group)
523 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
524 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
525 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
526 backdevname="", lmv_uuid=""):
527 mdd = self.newService("mdsdev", name, uuid)
528 self.addElement(mdd, "fstype", fstype)
530 self.addElement(mdd, "backfstype", backfstype)
531 dev = self.addElement(mdd, "devpath", devname)
533 self.addElement(mdd, "backdevpath", backdevname)
534 self.addElement(mdd, "autoformat", format)
536 self.addElement(mdd, "devsize", "%s" % (dev_size))
538 self.addElement(mdd, "journalsize", "%s" % (journal_size))
540 self.addElement(mdd, "inodesize", "%s" % (inode_size))
542 self.addElement(mdd, "nspath", nspath)
544 self.addElement(mdd, "mkfsoptions", mkfsoptions)
546 self.addElement(mdd, "mountfsoptions", mountfsoptions)
548 mdd.appendChild(self.ref("node", node_uuid))
549 mdd.appendChild(self.ref("target", mds_uuid))
550 mdd.appendChild(self.dev(devname))
553 mdd.appendChild(self.ref("lmv", lmv_uuid))
554 self.addElement(mdd, "lmv", lmv_uuid)
558 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
559 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
560 mgmt.appendChild(self.ref("node", node_uuid))
561 # Placeholder until mgmt-service failover.
562 mgmt.appendChild(self.ref("active", mgmt_uuid))
565 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
566 mtpt = self.newService("mountpoint", name, uuid)
567 mtpt.appendChild(self.ref("filesystem", fs_uuid))
568 self.addElement(mtpt, "path", path)
570 self.addElement(mtpt, "clientoptions", clientoptions)
573 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
574 fs = self.newService("filesystem", name, uuid)
575 fs.appendChild(self.ref("mds", mds_uuid))
576 fs.appendChild(self.ref("obd", obd_uuid))
578 fs.appendChild(self.ref("mgmt", mgmt_uuid))
581 def echo_client(self, name, uuid, osc_uuid):
582 ec = self.newService("echoclient", name, uuid)
583 ec.appendChild(self.ref("obd", osc_uuid))
586 def update(self, version):
587 new = self.doc.createElement("update")
588 new.setAttribute("version", version)
591 def add(self, lov, ost, index, gen):
592 new = self.doc.createElement("add")
593 new.setAttribute("lov_uuidref", lov)
594 new.setAttribute("ost_uuidref", ost)
595 new.setAttribute("index", index)
596 new.setAttribute("generation", gen)
599 def delete(self, lov, ost, index, gen, options):
601 new = self.doc.createElement("delete")
603 new = self.doc.createElement("deactivate")
604 new.setAttribute("lov_uuidref", lov)
605 new.setAttribute("ost_uuidref", ost)
606 new.setAttribute("index", index)
607 new.setAttribute("generation", gen)
610 ############################################################
611 # Utilities to query a DOM tree
612 # Using this functions we can treat use config information
613 # directly as a database.
615 return n.getAttribute('name')
618 return node.getAttribute('uuid')
620 def findLastUpdate(lustre):
623 for n in lustre.childNodes:
624 if n.nodeType == n.ELEMENT_NODE:
625 if n.nodeName != 'update':
627 tmp = int(n.getAttribute('version'))
629 error('malformed XML: update tag without a version attribute')
630 if tmp != version + 1:
631 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
636 def addUpdate(gen, lustre, node):
637 update = findLastUpdate(lustre)
640 #add_record = update.getElementsByTagName('add')
642 # add_record = gen.add()
643 # update.appendChild(add_record)
645 # add_record = add_record[0]
646 #add_record.appendChild(node)
647 update.appendChild(node)
649 def delUpdate(gen, lustre, node):
650 update = findLastUpdate(lustre)
653 update.appendChild(node)
655 def findByName(lustre, name, tag = ""):
656 for n in lustre.childNodes:
657 if n.nodeType == n.ELEMENT_NODE:
658 if tag and n.nodeName != tag:
660 if getName(n) == name:
663 n = findByName(n, name)
668 def lookup(node, uuid):
669 for n in node.childNodes:
670 if n.nodeType == n.ELEMENT_NODE:
671 if getUUID(n) == uuid:
679 def name2uuid(lustre, name, tag="", fatal=1):
680 ret = findByName(lustre, name, tag)
683 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
688 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
689 for n in lustre.childNodes:
690 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
691 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
695 # XXX: assumes only one network element per node. will fix this
696 # as soon as support for routers is added
697 def get_net_uuid(lustre, node_name):
698 """ get a network uuid for a node_name """
699 node = findByName(lustre, node_name, "node")
701 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
702 net = node.getElementsByTagName('network')
704 return getUUID(net[0])
707 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
708 tgt.setAttribute('uuidref', osc_uuid)
710 gener = int(tgt.getAttribute('generation'))
712 gener = int(tgt.getAttribute('generation')) + 1
713 tgt.setAttribute('generation', str(gener))
714 lov_index = int(tgt.getAttribute('index'))
715 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
719 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
720 lov_name = getName(lov)
722 lov_index = get_option_int(options, 'index')
723 for tgt in lustre.getElementsByTagName('lov_tgt'):
724 if str(lov_index) == tgt.getAttribute('index'):
725 uuidref = tgt.getAttribute('uuidref')
727 raise OptionError("%s --index %d is still in use: %s" %
728 (lov_name, lov_index, uuidref))
729 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
733 for tgt in lustre.getElementsByTagName('lov_tgt'):
734 uuidref = tgt.getAttribute('uuidref')
735 tmp = int(tgt.getAttribute('index'))
737 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
738 uuidref = tgt.getAttribute('uuidref')
740 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
742 lov_index = lov_index + 1
744 lov.appendChild(gen.lov_tgt(osc_uuid, str(lov_index), '1'))
745 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index), '1'))
747 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
748 lov_name = getName(lov)
750 lov_index = get_option_int(options, 'index')
751 for tgt in lustre.getElementsByTagName('lov_tgt'):
752 index = tgt.getAttribute('index')
753 if index == lov_index:
754 uuidref = tgt.getAttribute('uuidref')
755 if uuidref != osc_uuid:
756 raise OptionError("%s --index %d contains %s, not %s" %
757 (lov_name, lov_index, osc_uuid, uuidref))
759 tgt.setAttribute('uuidref', '')
761 # bump the generation just in case...
763 gen = int(tgt.getAttribute('generation'))
765 gen = int(tgt.getAttribute('generation')) + 1
767 tgt.setAttribute('active', '0')
768 tgt.setAttribute('generation', str(gen))
770 raise OptionError("%s --index %d not in use by %s." %
771 (lov_name, lov_index, osc_uuid))
773 for tgt in lustre.getElementsByTagName('lov_tgt'):
774 uuidref = tgt.getAttribute('uuidref')
775 if uuidref == osc_uuid:
776 genera = int(tgt.getAttribute('generation'))
777 delete_rec = gen.delete(getUUID(lov),
778 osc_uuid,tgt.getAttribute('index'),
779 str(genera), options)
780 delUpdate(gen, lustre, delete_rec)
783 tgt.setAttribute('uuidref', '')
784 if not options.migrate:
786 tgt.setAttribute('active', '0')
787 tgt.setAttribute('generation', str(genera))
789 def lmv_add_obd(gen, lmv, mdc_uuid):
790 lmv.appendChild(gen.ref("mds", mdc_uuid))
792 def ref_exists(profile, uuid):
793 elist = profile.childNodes
795 if e.nodeType == e.ELEMENT_NODE:
796 ref = e.getAttribute('uuidref')
801 # ensure that uuid is not already in the profile
802 # return true if uuid is added
803 def node_add_profile(gen, node, ref, uuid):
804 refname = "%s_ref" % "profile"
805 ret = node.getElementsByTagName(refname)
807 error('node has no profile ref:', node)
808 prof_uuid = ret[0].getAttribute('uuidref')
809 profile = lookup(node.parentNode, prof_uuid)
811 error("no profile found:", prof_uuid)
812 if ref_exists(profile, uuid):
814 profile.appendChild(gen.ref(ref, uuid))
817 # ensure that uuid is not already in the profile
818 # return true if uuid is added
819 def node_found_target_by_dev(gen, lustre, node, devname):
820 refname = "%s_ref" % "profile"
821 ret = node.getElementsByTagName(refname)
823 error('node has no profile ref:', node)
824 prof_uuid = ret[0].getAttribute('uuidref')
825 profile = lookup(node.parentNode, prof_uuid)
827 error("no profile found:", prof_uuid)
829 osd_list = lustre.getElementsByTagName('osd')
832 obd_dev = osd.getElementsByTagName('dev')
833 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
834 for ost in lustre.getElementsByTagName('ost'):
835 active_ret = ost.getElementsByTagName('active_ref')
836 if active_ret[0].getAttribute('uuidref') == osd.getAttribute('uuid'):
837 return ost.getAttribute('uuid')
839 mdsdev_list = lustre.getElementsByTagName('mdsdev')
841 for mdsdev in mdsdev_list:
842 obd_dev = mdsdev.getElementsByTagName('dev')
843 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
844 for mds in lustre.getElementsByTagName('mds'):
845 active_ret = mds.getElementsByTagName('active_ref')
846 if active_ret[0].getAttribute('uuidref') == mdsdev.getAttribute('uuid'):
847 return mds.getAttribute('uuid')
851 def get_attr(dom_node, attr, default=""):
852 v = dom_node.getAttribute(attr)
857 ############################################################
860 def set_node_options(gen, node, options):
862 node.setAttribute('router', '1')
864 gen.addElement(node, "timeout", get_option(options, 'timeout'))
866 default_upcall = get_option(options, 'upcall')
869 if default_upcall or options.lustre_upcall:
870 if options.lustre_upcall:
871 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
873 gen.addElement(node, 'lustreUpcall', default_upcall)
874 if default_upcall or options.portals_upcall:
875 if options.portals_upcall:
876 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
878 gen.addElement(node, 'portalsUpcall', default_upcall)
880 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
881 if options.subsystem:
882 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
885 def do_add_node(gen, lustre, options, node_name):
886 uuid = new_uuid(node_name)
887 prof_name = new_name("PROFILE_" + node_name)
888 prof_uuid = new_uuid(prof_name)
889 profile = gen.profile(prof_name, prof_uuid)
890 node = gen.node(node_name, uuid, prof_uuid)
891 lustre.appendChild(node)
892 lustre.appendChild(profile)
894 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
895 set_node_options(gen, node, options)
900 def add_node(gen, lustre, options):
901 """ create a node with a network config """
903 node_name = get_option(options, 'node')
904 ret = findByName(lustre, node_name, "node")
906 print "Node:", node_name, "exists."
908 do_add_node(gen, lustre, options, node_name)
911 def add_net(gen, lustre, options):
912 """ create a node with a network config """
914 node_name = get_option(options, 'node')
915 nid = get_option(options, 'nid')
916 cluster_id = get_option(options, 'cluster_id')
917 hostaddr = get_option(options, 'hostaddr')
918 net_type = get_option(options, 'nettype')
920 if net_type in ('tcp',):
921 port = get_option_int(options, 'port')
922 tcpbuf = get_option_int(options, 'tcpbuf')
923 irq_aff = get_option_int(options, 'irq_affinity')
924 elif net_type in ('elan', 'gm'):
929 print "Unknown net_type: ", net_type
932 ret = findByName(lustre, node_name, "node")
934 node = do_add_node(gen, lustre, options, node_name)
937 set_node_options(gen, node, options)
939 net_name = new_name('NET_'+ node_name +'_'+ net_type)
940 net_uuid = new_uuid(net_name)
941 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
942 hostaddr, port, tcpbuf, irq_aff))
943 node_add_profile(gen, node, "network", net_uuid)
946 def add_route(gen, lustre, options):
947 """ create a node with a network config """
949 node_name = get_option(options, 'node')
950 gw_net_type = get_option(options, 'nettype')
951 gw = get_option(options, 'gw')
952 gw_cluster_id = get_option(options, 'gateway_cluster_id')
953 tgt_cluster_id = get_option(options, 'target_cluster_id')
954 lo = get_option(options, 'lo')
955 hi = get_option(options, 'hi')
959 node = findByName(lustre, node_name, "node")
961 error (node_name, " not found.")
963 rlist = node.getElementsByTagName('routetbl')
967 rtbl_name = new_name("RTBL_" + node_name)
968 rtbl_uuid = new_uuid(rtbl_name)
969 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
970 node.appendChild(rtbl)
971 node_add_profile(gen, node, "routetbl", rtbl_uuid)
972 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
976 def add_mds(gen, lustre, options):
977 node_name = get_option(options, 'node')
978 mds_name = get_option(options, 'mds')
979 lmv_name = get_option(options, 'lmv')
980 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
981 mdd_uuid = new_uuid(mdd_name)
985 lmv = findByName(lustre, lmv_name, "lmv")
987 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
988 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
990 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
992 mds_uuid = new_uuid(mds_name)
993 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
994 lustre.appendChild(mds)
996 lmv_add_obd(gen, lmv, mds_uuid)
998 mds = lookup(lustre, mds_uuid)
1000 if options.failover:
1001 mds.setAttribute('failover', "1")
1003 devname = get_option(options, 'dev')
1004 backdevname = get_option(options, 'backdev')
1005 size = get_option(options, 'size')
1006 fstype = get_option(options, 'fstype')
1007 backfstype = get_option(options, 'backfstype')
1008 journal_size = get_option(options, 'journal_size')
1009 inode_size = get_option(options, 'inode_size')
1010 nspath = get_option(options, 'nspath')
1011 mkfsoptions = get_option(options, 'mkfsoptions')
1012 mountfsoptions = get_option(options, 'mountfsoptions')
1014 node_uuid = name2uuid(lustre, node_name, 'node')
1016 node = findByName(lustre, node_name, "node")
1017 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1018 net_uuid = get_net_uuid(lustre, node_name)
1020 error("NODE: ", node_name, "not found")
1023 mds.appendChild(gen.ref("lmv", lmv_uuid))
1025 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1026 get_format_flag(options), node_uuid, mds_uuid,
1027 size, journal_size, inode_size, nspath, mkfsoptions,
1028 mountfsoptions, backfstype, backdevname, lmv_uuid)
1029 lustre.appendChild(mdd)
1032 def add_mgmt(gen, lustre, options):
1033 node_name = get_option(options, 'node')
1034 node_uuid = name2uuid(lustre, node_name, 'node')
1035 mgmt_name = get_option(options, 'mgmt')
1037 mgmt_name = new_name('MGMT_' + node_name)
1038 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1040 mgmt_uuid = new_uuid(mgmt_name)
1041 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1042 lustre.appendChild(mgmt)
1044 mgmt = lookup(lustre, mgmt_uuid)
1046 node = findByName(lustre, node_name, "node")
1047 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1049 def add_ost(gen, lustre, options):
1050 node_name = get_option(options, 'node')
1051 lovname = get_option(options, 'lov')
1052 osdtype = get_option(options, 'osdtype')
1054 node_uuid = name2uuid(lustre, node_name, 'node')
1056 if osdtype == 'obdecho':
1067 devname = get_option(options, 'dev') # can be unset for bluearcs
1068 backdevname = get_option(options, 'backdev')
1069 size = get_option(options, 'size')
1070 fstype = get_option(options, 'fstype')
1071 backfstype = get_option(options, 'backfstype')
1072 journal_size = get_option(options, 'journal_size')
1073 inode_size = get_option(options, 'inode_size')
1074 mkfsoptions = get_option(options, 'mkfsoptions')
1075 mountfsoptions = get_option(options, 'mountfsoptions')
1077 nspath = get_option(options, 'nspath')
1079 ostname = get_option(options, 'ost')
1081 ostname = new_name('OST_'+ node_name)
1083 osdname = new_name("OSD_" + ostname + "_" + node_name)
1084 osd_uuid = new_uuid(osdname)
1086 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1088 ost_uuid = get_option(options, 'ostuuid')
1090 if lookup(lustre, ost_uuid):
1091 error("Duplicate OST UUID:", ost_uuid)
1093 ost_uuid = new_uuid(ostname)
1095 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1096 lustre.appendChild(ost)
1098 ost = lookup(lustre, ost_uuid)
1101 lov = findByName(lustre, lovname, "lov")
1103 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1104 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1106 if options.failover:
1107 ost.setAttribute('failover', "1")
1110 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1111 get_format_flag(options), ost_uuid, node_uuid, size,
1112 journal_size, inode_size, nspath, mkfsoptions,
1113 mountfsoptions, backfstype, backdevname)
1115 node = findByName(lustre, node_name, "node")
1117 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1119 ## oss_uuid = new_uuid(ossname)
1120 ## oss = gen.oss(ossname, oss_uuid)
1121 ## lustre.appendChild(oss)
1123 node_add_profile(gen, node, 'osd', osd_uuid)
1124 lustre.appendChild(osd)
1126 def del_ost(gen, lustre, options):
1127 ostname = get_option(options, 'ost')
1129 raise OptionError("del_ost: --ost requires a <ost name>")
1130 ost = findByName(lustre, ostname, "ost")
1132 error('del_ost: ', 'Unable to find ', ostname)
1133 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1135 error('del_ost: ', 'Unable to find uuid for ', ostname)
1136 lovname = get_option(options, 'lov')
1138 lov = findByName(lustre, lovname, "lov")
1140 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1141 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1142 # if the user specified a speficic LOV don't delete the OST itself
1145 # remove OSD references from all LOVs
1146 for n in lustre.getElementsByTagName('lov'):
1147 lov_del_obd(gen, lustre, n, ost_uuid, options)
1148 if not options.migrate:
1151 for osd in lustre.getElementsByTagName('osd'):
1152 if ref_exists(osd, ost_uuid):
1153 osd_uuid = osd.getAttribute('uuid')
1154 # delete all profile references to this OSD
1155 for profile in lustre.getElementsByTagName('profile'):
1156 for osd_ref in profile.getElementsByTagName('osd_ref'):
1157 if osd_uuid == osd_ref.getAttribute('uuidref'):
1158 profile.removeChild(osd_ref)
1159 lustre.removeChild(osd)
1162 lustre.removeChild(ost)
1164 def add_cmobd(gen, lustre, options):
1165 node_name = get_option(options, 'node')
1166 name = get_option(options, 'cmobd')
1167 uuid = new_uuid(name)
1169 real_name = get_option(options, 'master_dev')
1170 cache_name = get_option(options, 'cache_dev')
1172 node = findByName(lustre, node_name, "node")
1173 node_add_profile(gen, node, "cmobd", uuid)
1174 real_uuid = node_found_target_by_dev(gen, lustre, node, real_name)
1175 cache_uuid = node_found_target_by_dev(gen, lustre, node, cache_name)
1177 panic("add_cmobd", "can not find real_uuid")
1179 panic("add_cmobd", "can not find cache_uuid")
1180 cmobd = gen.cmobd(name, uuid, real_uuid, cache_uuid)
1181 lustre.appendChild(cmobd)
1183 def add_cobd(gen, lustre, options):
1184 node_name = get_option(options, 'node')
1185 name = get_option(options, 'cobd')
1186 uuid = new_uuid(name)
1188 real_name = get_option(options, 'real_obd')
1189 cache_name = get_option(options, 'cache_obd')
1191 real_uuid = name2uuid(lustre, real_name, tag='lov', fatal=0)
1192 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1195 node = lookup(lustre, real_uuid)
1196 rets = node.getElementsByTagName('lov_tgt')
1198 ost_uuid = ret.getAttribute('uuidref')
1199 ost_node = lookup(lustre, ost_uuid)
1200 ret = ost_node.getElementsByTagName('active_ref')
1202 osd_uuid = ret[0].getAttribute('uuidref')
1203 osd_node = lookup(lustre, osd_uuid)
1204 gen.addElement(osd_node, 'cachetype', 'master')
1207 node = lookup(lustre, cache_uuid)
1208 rets = node.getElementsByTagName('lov_tgt')
1210 ost_uuid = ret.getAttribute('uuidref')
1211 ost_node = lookup(lustre, ost_uuid)
1212 ret = ost_node.getElementsByTagName('active_ref')
1214 osd_uuid = ret[0].getAttribute('uuidref')
1215 osd_node = lookup(lustre, osd_uuid)
1216 gen.addElement(osd_node, 'cachetype', 'cache')
1218 if not real_uuid or not cache_uuid:
1219 real_uuid = name2uuid(lustre,real_name, tag='mds')
1220 cache_uuid = name2uuid(lustre,cache_name, tag='mds')
1222 mds_node = lookup(lustre, real_uuid)
1223 ret = mds_node.getElementsByTagName('active_ref')
1225 mdsdev_uuid = ret[0].getAttribute('uuidref')
1226 mdsdev_node = lookup(lustre, mdsdev_uuid)
1227 gen.addElement(mdsdev_node, 'cachetype', 'master')
1229 mds_node = lookup(lustre, cache_uuid)
1230 ret = mds_node.getElementsByTagName('active_ref')
1232 mdsdev_uuid = ret[0].getAttribute('uuidref')
1233 mdsdev_node = lookup(lustre, mdsdev_uuid)
1234 gen.addElement(mdsdev_node, 'cachetype', 'cache')
1236 node = findByName(lustre, node_name, "node")
1237 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
1238 lustre.appendChild(cobd)
1241 def add_echo_client(gen, lustre, options):
1242 """ add an echo client to the profile for this node. """
1243 node_name = get_option(options, 'node')
1244 lov_name = get_option(options, 'ost')
1246 node = findByName(lustre, node_name, 'node')
1248 echoname = new_name('ECHO_'+ node_name)
1249 echo_uuid = new_uuid(echoname)
1250 node_add_profile(gen, node, 'echoclient', echo_uuid)
1252 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1254 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1256 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1257 lustre.appendChild(echo)
1260 def add_lov(gen, lustre, options):
1261 """ create a lov """
1263 lmv_name = get_option(options, 'lmv')
1264 lov_orig = get_option(options, 'lov')
1265 name = new_name(lov_orig)
1266 if name != lov_orig:
1267 warning("name:", lov_orig, "already used. using:", name)
1269 mds_name = get_option(options, 'mds')
1272 error("LOV: MDS or LMV must be specified.");
1274 stripe_sz = get_option_int(options, 'stripe_sz')
1275 stripe_cnt = get_option_int(options, 'stripe_cnt')
1276 pattern = get_option_int(options, 'stripe_pattern')
1277 uuid = new_uuid(name)
1279 ret = findByName(lustre, name, "lov")
1281 error("LOV: ", name, " already exists.")
1284 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1286 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1288 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1289 lustre.appendChild(lov)
1291 # add an lovconfig entry to the active mdsdev profile
1292 lovconfig_name = new_name('LVCFG_' + name)
1293 lovconfig_uuid = new_uuid(lovconfig_name)
1295 mds = findByName(lustre, mds_name, "mds")
1296 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1298 lmv = findByName(lustre, lmv_name, "lmv")
1299 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1300 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1301 lustre.appendChild(lovconfig)
1303 def add_default_lov(gen, lustre, mds_name, lov_name):
1304 """ create a default lov """
1306 stripe_sz = DEFAULT_STRIPE_SZ
1307 stripe_cnt = DEFAULT_STRIPE_CNT
1308 pattern = DEFAULT_STRIPE_PATTERN
1309 uuid = new_uuid(lov_name)
1311 ret = findByName(lustre, lov_name, "lov")
1313 error("LOV: ", lov_name, " already exists.")
1315 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1316 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1317 lustre.appendChild(lov)
1319 # add an lovconfig entry to the active mdsdev profile
1320 lovconfig_name = new_name('LVCFG_' + lov_name)
1321 lovconfig_uuid = new_uuid(lovconfig_name)
1322 mds = findByName(lustre, mds_name)
1323 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1324 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1325 lustre.appendChild(lovconfig)
1327 def add_lmv(gen, lustre, options):
1328 """ create a lmv """
1330 lmv_orig = get_option(options, 'lmv')
1331 name = new_name(lmv_orig)
1332 if name != lmv_orig:
1333 warning("name:", lmv_orig, "already used. using:", name)
1335 uuid = new_uuid(name)
1336 ret = findByName(lustre, name, "lmv")
1338 error("LMV: ", name, " already exists.")
1340 lmv = gen.lmv(name, uuid)
1341 lustre.appendChild(lmv)
1343 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1344 fs_name = new_name("FS_fsname")
1345 fs_uuid = new_uuid(fs_name)
1346 cobd = lookup(lustre, mds_uuid)
1347 #SHOULD appendChild filesystem to real mds not cobd
1348 ret = cobd.getElementsByTagName("cacheobd_ref")
1350 cacheobd_uuid = ret[0].getAttribute('uuidref')
1351 cacheobd = lookup(lustre, cacheobd_uuid)
1352 cacheobd.appendChild(gen.ref("filesystem", fs_uuid))
1353 ret = cobd.getElementsByTagName("realobd_ref")
1355 realobd_uuid = ret[0].getAttribute('uuidref')
1356 realobd = lookup(lustre, realobd_uuid)
1357 realobd.appendChild(gen.ref("filesystem", fs_uuid))
1359 cobd.appendChild(gen.ref("filesystem", fs_uuid))
1360 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid, mgmt_uuid)
1361 lustre.appendChild(fs)
1364 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1365 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1367 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1369 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=1)
1370 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1372 obd_uuid = name2uuid(lustre, obd_name, tag='cobd')
1374 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1377 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1379 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid)
1382 def add_mtpt(gen, lustre, options):
1383 """ create mtpt on a node """
1384 node_name = get_option(options, 'node')
1386 path = get_option(options, 'path')
1387 clientoptions = get_option(options, "clientoptions")
1388 fs_name = get_option(options, 'filesystem')
1390 lov_name = get_option(options, 'lov')
1391 ost_name = get_option(options, 'ost')
1392 mds_name = get_option(options, 'mds')
1394 mds_name = get_option(options, 'lmv')
1396 error("--add mtpt requires either --mds or --lmv.")
1399 error("--add mtpt requires --lov lov_name or --ost ost_name")
1401 warning("use default value for lov, due no --lov lov_name provided")
1402 lov_name = new_name("lov_default")
1403 add_default_lov(gen, lustre, mds_name, lov_name)
1404 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1406 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1407 lov = findByName(lustre, lov_name, "lov")
1408 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1411 mgmt_name = get_option(options, 'mgmt')
1412 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1414 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1416 name = new_name('MNT_'+ node_name)
1418 ret = findByName(lustre, name, "mountpoint")
1420 # this can't happen, because new_name creates unique names
1421 error("MOUNTPOINT: ", name, " already exists.")
1423 uuid = new_uuid(name)
1424 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
1425 node = findByName(lustre, node_name, "node")
1427 error('node:', node_name, "not found.")
1428 node_add_profile(gen, node, "mountpoint", uuid)
1429 lustre.appendChild(mtpt)
1431 def commit_version(gen, lustre):
1432 update = findLastUpdate(lustre)
1434 version = int(update.getAttribute("version")) + 1
1438 new = gen.update(str(version))
1439 lustre.appendChild(new)
1442 ############################################################
1443 # Command line processing
1445 class OptionError (exceptions.Exception):
1446 def __init__(self, args):
1449 def get_option(options, tag):
1450 """Look for tag in options hash and return the value if set. If not
1451 set, then if return default it is set, otherwise exception."""
1452 if options.__getattr__(tag) != None:
1453 return options.__getattr__(tag)
1455 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1457 def get_option_int(options, tag):
1458 """Return an integer option. Raise exception if the value is not an int"""
1459 val = get_option(options, tag)
1463 raise OptionError("--%s <num> (value must be integer)" % (tag))
1466 # simple class for profiling
1473 self._start = time.time()
1474 def stop(self, msg=''):
1475 self._stop = time.time()
1479 return self._stop - self._start
1480 def display(self, msg):
1482 str = '%s: %g secs' % (msg, d)
1485 #################################################################
1486 # function cmdlinesplit used to split cmd line from batch file
1488 def cmdlinesplit(cmdline):
1490 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1491 single_quote = re.compile(r"'(.*?)'")
1492 escaped = re.compile(r'\\(.)')
1493 esc_quote = re.compile(r'\\([\\"])')
1494 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1498 while i < len(cmdline):
1501 match = double_quote.match(cmdline, i)
1503 print "Unmatched double quote:", cmdline
1506 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1507 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1510 match = single_quote.match(cmdline, i)
1512 print "Unmatched single quote:", cmdline
1515 if arg is None: arg = match.group(1)
1516 else: arg = arg + match.group(1)
1519 match = escaped.match(cmdline, i)
1521 print "Unmatched backslash", cmdline
1524 if arg is None: arg = match.group(1)
1525 else: arg = arg + match.group(1)
1527 elif c in string.whitespace:
1529 arg_list.append(str(arg))
1531 while i < len(cmdline) and cmdline[i] in string.whitespace:
1534 match = outside.match(cmdline, i)
1537 if arg is None: arg = match.group()
1538 else: arg = arg + match.group()
1540 if arg != None: arg_list.append(str(arg))
1544 ############################################################
1548 def add(devtype, gen, lustre, options):
1549 if devtype == 'net':
1550 add_net(gen, lustre, options)
1551 elif devtype == 'mtpt':
1552 add_mtpt(gen, lustre, options)
1553 elif devtype == 'mds':
1554 add_mds(gen, lustre, options)
1555 elif devtype == 'ost':
1556 add_ost(gen, lustre, options)
1557 elif devtype == 'lov':
1558 add_lov(gen, lustre, options)
1559 elif devtype == 'route':
1560 add_route(gen, lustre, options)
1561 elif devtype == 'node':
1562 add_node(gen, lustre, options)
1563 elif devtype == 'echo_client':
1564 add_echo_client(gen, lustre, options)
1565 elif devtype == 'cobd':
1566 add_cobd(gen, lustre, options)
1567 elif devtype == 'cmobd':
1568 add_cmobd(gen, lustre, options)
1569 elif devtype == 'mgmt':
1570 add_mgmt(gen, lustre, options)
1571 elif devtype == 'lmv':
1572 add_lmv(gen, lustre, options)
1574 error("unknown device type:", devtype)
1576 def delete(devtype, gen, lustre, options):
1577 if devtype == 'ost':
1578 del_ost(gen, lustre, options)
1579 elif options.delete:
1580 error("delete not supported for device type:", devtype)
1581 elif options.deactivate:
1582 error("deactivate not supported for device type:", devtype)
1584 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1586 def commit(gen, lustre):
1587 commit_version(gen, lustre)
1589 def do_command(gen, lustre, options, args):
1591 add(options.add, gen, lustre, options)
1592 elif options.delete:
1593 delete(options.delete, gen, lustre, options)
1594 elif options.deactivate:
1595 delete(options.deactivate, gen, lustre, options)
1596 elif options.commit:
1599 error("Missing command")
1602 cl = Lustre.Options("lmc", "", lmc_options)
1604 options, args = cl.parse(sys.argv[1:])
1605 except Lustre.OptionError, e:
1609 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1611 if options.reference:
1618 outFile = options.merge
1619 if os.access(outFile, os.R_OK):
1620 doc = xml.dom.minidom.parse(outFile)
1622 doc = new_lustre(xml.dom.minidom)
1624 doc = xml.dom.minidom.parse(options.input)
1626 doc = new_lustre(xml.dom.minidom)
1629 outFile = options.output
1631 lustre = doc.documentElement
1633 if lustre.tagName != "lustre":
1634 print "Existing config not valid."
1637 gen = GenConfig(doc)
1640 fp = open(options.batch)
1641 batchCommands = fp.readlines()
1643 for cmd in batchCommands:
1645 options, args = cl.parse(cmdlinesplit(cmd))
1646 if options.merge or options.input or options.output:
1647 print "The batchfile should not contain --merge, --input or --output."
1649 do_command(gen, lustre, options, args)
1650 except OptionError, e:
1652 except Lustre.OptionError, e:
1656 do_command(gen, lustre, options, args)
1657 except OptionError, e:
1658 panic(string.join(sys.argv),e)
1659 except Lustre.OptionError, e:
1665 printDoc(doc, open(outFile,"w"))
1667 if __name__ == "__main__":