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
77 --nettype tcp|elan|gm|openib
91 --backfstype ldiskfs|ext3|tmpfs
99 --mountfsoptions options
100 --root_squash uid:gid
101 --no_root_squash ptl_nid
120 --fstype ldiskfs|ext3
121 --backfstype ldiskfs|ext3|tmpfs
124 --osdtype obdecho|obdfilter
126 --mkfsoptions options
127 --mountfsoptions options
138 --add mtpt - Mountpoint
143 --ost ost_name OR --lov lov_name
144 --clientoptions options
150 --gateway_cluster_id nid
151 --target_cluster_id nid
158 --add mgmt - Management/monitoring service
160 --mgmt mgmt_service_name
172 --master_dev obd_name
175 --commit - Close a configuration version, and start a new one
178 PARAM = Lustre.Options.PARAM
180 # lmc input/output options
181 ('reference', "Print short reference for commands."),
182 ('verbose,v', "Print system commands as they are run."),
183 ('merge,m', "Append to the specified config file.", PARAM),
184 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
185 ('input,i', "", PARAM),
186 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
190 ('delete', "", PARAM),
191 ('deactivate', "", PARAM),
192 ('commit', "Commit all config changes and start a new version"),
195 ('node', "Add a new node in the cluster configuration.", PARAM),
196 ('timeout', "Set timeout to initiate recovery.", PARAM),
197 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
198 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
199 ('portals_upcall', "Set location of portals upcall script.", PARAM),
200 ('ptldebug', "Set the portals debug level", PARAM),
201 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
204 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib.", PARAM),
205 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
206 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
207 ('hostaddr', "", PARAM,""),
208 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
211 ('route', "Add a new route for the cluster.", PARAM),
212 ('router', "Optional flag to mark a node as router."),
213 ('gw', "Specify the nid of the gateway for a route.", PARAM),
214 ('gateway_cluster_id', "", PARAM, "0"),
215 ('target_cluster_id', "", PARAM, "0"),
216 ('lo', "For a range route, this is the low value nid.", PARAM),
217 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
219 # servers: mds and ost
220 ('mds', "Specify MDS name.", PARAM,""),
221 ('ost', "Specify the OST name.", PARAM,""),
222 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
223 ('failover', "Enable failover support on OSTs or MDS?"),
224 ('group', "", PARAM),
225 ('dev', "Path of the device on local system.", PARAM,""),
226 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
227 ('size', "Specify the size of the device if needed.", PARAM,"0"),
228 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
229 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
230 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
231 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
232 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
233 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
234 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
235 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
236 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
237 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
238 ('nspath', "Local mount point of server namespace.", PARAM,""),
240 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
242 # clients: mountpoint and echo
243 ('echo_client', "", PARAM),
244 ('path', "Specify the mountpoint for Lustre.", PARAM),
245 ('filesystem', "Lustre filesystem name", PARAM,""),
246 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
249 ('lov', "Specify LOV name.", PARAM,""),
250 ('index', "Specify index for OBD in LOV target table.", PARAM),
251 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
252 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
253 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
257 ('real_obd', "Specify the real device for the cache obd system.", PARAM),
258 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
259 ('cobd', "Specify COBD name", PARAM),
262 ('master_dev', "Specify the master device for the cmobd system.", PARAM),
263 ('cache_dev', "Specify the cache device for the cmobd obd system.", PARAM),
264 ('cmobd', "Specify COBD name", PARAM),
267 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
270 ('lmv', "Specify LMV name.", PARAM,""),
274 msg = string.join(map(str,args))
275 raise OptionError("Error: " + msg)
284 msg = string.join(map(str,args))
285 print "Warning: ", msg
288 # manage names and uuids
289 # need to initialize this by walking tree to ensure
290 # no duplicate names or uuids are created.
291 # this are just place holders for now.
292 # consider changing this to be like OBD-dev-host
296 while names.has_key(ret):
297 ret = "%s_%d" % (base, ctr)
304 ret = "%s_UUID" % (name)
305 if len(ret) > UUID_MAX_LENGTH:
306 ret = ret[-UUID_MAX_LENGTH:]
307 while uuids.has_key(ret):
308 ret = "%s_UUID_%d" % (name, ctr)
310 if len(ret) > UUID_MAX_LENGTH:
311 ret = ret[-UUID_MAX_LENGTH:]
317 ldlm_uuid = 'ldlm_UUID'
320 """Create a new empty lustre document"""
321 # adding ldlm here is a bit of a hack, but one is enough.
322 str = """<lustre version="%s">
323 <ldlm name="%s" uuid="%s"/>
324 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
325 return dom.parseString(str)
331 """initialize auto-name generation tables"""
333 # get all elements that contain a name attribute
334 for n in doc.childNodes:
335 if n.nodeType == n.ELEMENT_NODE:
337 names[getName(n)] = 1
338 uuids[getUUID(n)] = 1
341 def get_format_flag(options):
346 ############################################################
347 # Build config objects using DOM
352 def __init__(self, doc):
355 def ref(self, type, uuid):
356 """ generate <[type]_ref uuidref="[uuid]"/> """
357 tag = "%s_ref" % (type)
358 ref = self.doc.createElement(tag)
359 ref.setAttribute("uuidref", uuid)
362 def dev(self, devname):
363 """ generate <dev devpath="[devname]"/> """
364 tgt = self.doc.createElement('dev')
365 tgt.setAttribute("dev", devname)
368 def newService(self, tag, name, uuid):
369 """ create a new service elmement, which requires name and uuid attributes """
370 new = self.doc.createElement(tag)
371 new.setAttribute("uuid", uuid);
372 new.setAttribute("name", name);
375 def addText(self, node, str):
376 txt = self.doc.createTextNode(str)
377 node.appendChild(txt)
379 def addElement(self, node, tag, str=None):
380 """ create a new element and add it as a child to node. If str is passed,
381 a text node is created for the new element"""
382 new = self.doc.createElement(tag)
384 self.addText(new, str)
385 node.appendChild(new)
388 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
390 """create <network> node"""
391 network = self.newService("network", name, uuid)
392 network.setAttribute("nettype", net);
393 self.addElement(network, "nid", nid)
394 self.addElement(network, "clusterid", cluster_id)
396 self.addElement(network, "hostaddr", hostaddr)
398 self.addElement(network, "port", "%d" %(port))
402 def routetbl(self, name, uuid):
403 """create <routetbl> node"""
404 rtbl = self.newService("routetbl", name, uuid)
407 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
408 """ create one entry for the route table """
409 ref = self.doc.createElement('route')
410 ref.setAttribute("type", gw_net_type)
411 ref.setAttribute("gw", gw)
412 ref.setAttribute("gwclusterid", gw_cluster_id)
413 ref.setAttribute("tgtclusterid", tgt_cluster_id)
414 ref.setAttribute("lo", lo)
416 ref.setAttribute("hi", hi)
419 def profile(self, name, uuid):
420 """ create a host """
421 profile = self.newService("profile", name, uuid)
424 def node(self, name, uuid, prof_uuid):
425 """ create a host """
426 node = self.newService("node", name, uuid)
427 node.appendChild(self.ref("profile", prof_uuid))
430 def ldlm(self, name, uuid):
431 """ create a ldlm """
432 ldlm = self.newService("ldlm", name, uuid)
435 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
436 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
437 mkfsoptions="", mountfsoptions="", backfstype="", backdevname=""):
438 osd = self.newService("osd", name, uuid)
439 osd.setAttribute('osdtype', osdtype)
440 osd.appendChild(self.ref("target", ost_uuid))
441 osd.appendChild(self.ref("node", node_uuid))
442 osd.appendChild(self.dev(devname))
445 self.addElement(osd, "fstype", fstype)
447 self.addElement(osd, "backfstype", backfstype)
449 self.addElement(osd, "backdevpath", backdevname)
451 dev = self.addElement(osd, "devpath", devname)
452 self.addElement(osd, "autoformat", format)
454 self.addElement(osd, "devsize", "%s" % (dev_size))
456 self.addElement(osd, "journalsize", "%s" % (journal_size))
458 self.addElement(osd, "inodesize", "%s" % (inode_size))
460 self.addElement(osd, "mkfsoptions", mkfsoptions)
462 self.addElement(osd, "mountfsoptions", mountfsoptions)
464 self.addElement(osd, "nspath", nspath)
467 def cobd(self, name, uuid, real_uuid, cache_uuid):
468 cobd = self.newService("cobd", name, uuid)
469 cobd.appendChild(self.ref("realobd",real_uuid))
470 cobd.appendChild(self.ref("cacheobd",cache_uuid))
473 def cmobd(self, name, uuid, real_uuid, cache_uuid):
474 cmobd = self.newService("cmobd", name, uuid)
475 cmobd.appendChild(self.ref("masterobd",real_uuid))
476 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
479 def ost(self, name, uuid, osd_uuid, group=""):
480 ost = self.newService("ost", name, uuid)
481 ost.appendChild(self.ref("active", osd_uuid))
483 self.addElement(ost, "group", group)
486 def oss(self, name, uuid):
487 oss = self.newService("oss", name, uuid)
490 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
491 lov = self.newService("lov", name, uuid)
492 lov.appendChild(self.ref("mds", mds_uuid))
493 lov.setAttribute("stripesize", str(stripe_sz))
494 lov.setAttribute("stripecount", str(stripe_cnt))
495 lov.setAttribute("stripepattern", str(pattern))
498 def lov_tgt(self, obd_uuid, index, generation):
499 tgt = self.doc.createElement('lov_tgt')
500 tgt.setAttribute("uuidref", obd_uuid)
501 tgt.setAttribute("index", index)
502 tgt.setAttribute("generation", generation)
503 tgt.setAttribute("active", '1')
506 def lovconfig(self, name, uuid, lov_uuid):
507 lovconfig = self.newService("lovconfig", name, uuid)
508 lovconfig.appendChild(self.ref("lov", lov_uuid))
511 def lmv(self, name, uuid):
512 lmv = self.newService("lmv", name, uuid)
515 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
516 mds = self.newService("mds", name, uuid)
517 mds.appendChild(self.ref("active",mdd_uuid))
519 self.addElement(mds, "group", group)
522 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
523 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
524 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
525 backdevname="",lmv_uuid="", root_squash="", no_root_squash=""):
526 mdd = self.newService("mdsdev", name, uuid)
527 self.addElement(mdd, "fstype", fstype)
529 self.addElement(mdd, "backfstype", backfstype)
530 dev = self.addElement(mdd, "devpath", devname)
532 self.addElement(mdd, "backdevpath", backdevname)
533 self.addElement(mdd, "autoformat", format)
535 self.addElement(mdd, "devsize", "%s" % (dev_size))
537 self.addElement(mdd, "journalsize", "%s" % (journal_size))
539 self.addElement(mdd, "inodesize", "%s" % (inode_size))
541 self.addElement(mdd, "nspath", nspath)
543 self.addElement(mdd, "mkfsoptions", mkfsoptions)
545 self.addElement(mdd, "mountfsoptions", mountfsoptions)
547 self.addElement(mdd, "root_squash", root_squash)
549 self.addElement(mdd, "no_root_squash", no_root_squash)
550 mdd.appendChild(self.ref("node", node_uuid))
551 mdd.appendChild(self.ref("target", mds_uuid))
552 mdd.appendChild(self.dev(devname))
555 mdd.appendChild(self.ref("lmv", lmv_uuid))
556 self.addElement(mdd, "lmv", lmv_uuid)
560 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
561 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
562 mgmt.appendChild(self.ref("node", node_uuid))
563 # Placeholder until mgmt-service failover.
564 mgmt.appendChild(self.ref("active", mgmt_uuid))
567 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
568 mtpt = self.newService("mountpoint", name, uuid)
569 mtpt.appendChild(self.ref("filesystem", fs_uuid))
570 self.addElement(mtpt, "path", path)
572 self.addElement(mtpt, "clientoptions", clientoptions)
575 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
576 fs = self.newService("filesystem", name, uuid)
577 fs.appendChild(self.ref("mds", mds_uuid))
578 fs.appendChild(self.ref("obd", obd_uuid))
580 fs.appendChild(self.ref("mgmt", mgmt_uuid))
583 def echo_client(self, name, uuid, osc_uuid):
584 ec = self.newService("echoclient", name, uuid)
585 ec.appendChild(self.ref("obd", osc_uuid))
588 def update(self, version):
589 new = self.doc.createElement("update")
590 new.setAttribute("version", version)
593 def add(self, lov, ost, index, gen):
594 new = self.doc.createElement("add")
595 new.setAttribute("lov_uuidref", lov)
596 new.setAttribute("ost_uuidref", ost)
597 new.setAttribute("index", index)
598 new.setAttribute("generation", gen)
601 def delete(self, lov, ost, index, gen, options):
603 new = self.doc.createElement("delete")
605 new = self.doc.createElement("deactivate")
606 new.setAttribute("lov_uuidref", lov)
607 new.setAttribute("ost_uuidref", ost)
608 new.setAttribute("index", index)
609 new.setAttribute("generation", gen)
612 ############################################################
613 # Utilities to query a DOM tree
614 # Using this functions we can treat use config information
615 # directly as a database.
617 return n.getAttribute('name')
620 return node.getAttribute('uuid')
622 def findLastUpdate(lustre):
625 for n in lustre.childNodes:
626 if n.nodeType == n.ELEMENT_NODE:
627 if n.nodeName != 'update':
629 tmp = int(n.getAttribute('version'))
631 error('malformed XML: update tag without a version attribute')
632 if tmp != version + 1:
633 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
638 def addUpdate(gen, lustre, node):
639 update = findLastUpdate(lustre)
642 #add_record = update.getElementsByTagName('add')
644 # add_record = gen.add()
645 # update.appendChild(add_record)
647 # add_record = add_record[0]
648 #add_record.appendChild(node)
649 update.appendChild(node)
651 def delUpdate(gen, lustre, node):
652 update = findLastUpdate(lustre)
655 update.appendChild(node)
657 def findByName(lustre, name, tag = ""):
658 for n in lustre.childNodes:
659 if n.nodeType == n.ELEMENT_NODE:
660 if tag and n.nodeName != tag:
662 if getName(n) == name:
665 n = findByName(n, name)
670 def lookup(node, uuid):
671 for n in node.childNodes:
672 if n.nodeType == n.ELEMENT_NODE:
673 if getUUID(n) == uuid:
681 def name2uuid(lustre, name, tag="", fatal=1):
682 ret = findByName(lustre, name, tag)
685 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
690 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
691 for n in lustre.childNodes:
692 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
693 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
697 # XXX: assumes only one network element per node. will fix this
698 # as soon as support for routers is added
699 def get_net_uuid(lustre, node_name):
700 """ get a network uuid for a node_name """
701 node = findByName(lustre, node_name, "node")
703 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
704 net = node.getElementsByTagName('network')
706 return getUUID(net[0])
709 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
710 tgt.setAttribute('uuidref', osc_uuid)
712 gener = int(tgt.getAttribute('generation'))
714 gener = int(tgt.getAttribute('generation')) + 1
715 tgt.setAttribute('generation', str(gener))
716 tgt.setAttribute('active', '1')
717 lov_index = int(tgt.getAttribute('index'))
718 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
722 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
723 lov_name = getName(lov)
725 lov_index = get_option_int(options, 'index')
726 for tgt in lustre.getElementsByTagName('lov_tgt'):
727 if str(lov_index) == tgt.getAttribute('index'):
728 uuidref = tgt.getAttribute('uuidref')
730 raise OptionError("%s --index %d is still in use: %s" %
731 (lov_name, lov_index, uuidref))
732 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
736 for tgt in lustre.getElementsByTagName('lov_tgt'):
737 uuidref = tgt.getAttribute('uuidref')
738 tmp = int(tgt.getAttribute('index'))
740 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
741 uuidref = tgt.getAttribute('uuidref')
743 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
745 lov_index = lov_index + 1
747 lov.appendChild(gen.lov_tgt(osc_uuid, str(lov_index), '1'))
748 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index), '1'))
750 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
751 lov_name = getName(lov)
753 lov_index = get_option_int(options, 'index')
754 for tgt in lustre.getElementsByTagName('lov_tgt'):
755 index = tgt.getAttribute('index')
756 if index == lov_index:
757 uuidref = tgt.getAttribute('uuidref')
758 if uuidref != osc_uuid:
759 raise OptionError("%s --index %d contains %s, not %s" %
760 (lov_name, lov_index, osc_uuid, uuidref))
762 tgt.setAttribute('uuidref', '')
764 # bump the generation just in case...
766 gen = int(tgt.getAttribute('generation'))
768 gen = int(tgt.getAttribute('generation')) + 1
770 tgt.setAttribute('active', '0')
771 tgt.setAttribute('generation', str(gen))
773 raise OptionError("%s --index %d not in use by %s." %
774 (lov_name, lov_index, osc_uuid))
776 for tgt in lustre.getElementsByTagName('lov_tgt'):
777 uuidref = tgt.getAttribute('uuidref')
778 if uuidref == osc_uuid:
779 genera = int(tgt.getAttribute('generation'))
780 delete_rec = gen.delete(getUUID(lov),
781 osc_uuid,tgt.getAttribute('index'),
782 str(genera), options)
783 delUpdate(gen, lustre, delete_rec)
786 tgt.setAttribute('uuidref', '')
787 if not options.migrate:
789 tgt.setAttribute('active', '0')
790 tgt.setAttribute('generation', str(genera))
792 def lmv_add_obd(gen, lmv, mdc_uuid):
793 lmv.appendChild(gen.ref("mds", mdc_uuid))
795 def ref_exists(profile, uuid):
796 elist = profile.childNodes
798 if e.nodeType == e.ELEMENT_NODE:
799 ref = e.getAttribute('uuidref')
804 # ensure that uuid is not already in the profile
805 # return true if uuid is added
806 def node_add_profile(gen, node, ref, uuid):
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)
815 if ref_exists(profile, uuid):
817 profile.appendChild(gen.ref(ref, uuid))
820 # ensure that uuid is not already in the profile
821 # return true if uuid is added
822 def node_found_target_by_dev(gen, lustre, node, devname):
823 refname = "%s_ref" % "profile"
824 ret = node.getElementsByTagName(refname)
826 error('node has no profile ref:', node)
827 prof_uuid = ret[0].getAttribute('uuidref')
828 profile = lookup(node.parentNode, prof_uuid)
830 error("no profile found:", prof_uuid)
832 osd_list = lustre.getElementsByTagName('osd')
835 obd_dev = osd.getElementsByTagName('dev')
836 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
837 for ost in lustre.getElementsByTagName('ost'):
838 active_ret = ost.getElementsByTagName('active_ref')
839 if active_ret[0].getAttribute('uuidref') == osd.getAttribute('uuid'):
840 return ost.getAttribute('uuid')
842 mdsdev_list = lustre.getElementsByTagName('mdsdev')
844 for mdsdev in mdsdev_list:
845 obd_dev = mdsdev.getElementsByTagName('dev')
846 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
847 for mds in lustre.getElementsByTagName('mds'):
848 active_ret = mds.getElementsByTagName('active_ref')
849 if active_ret[0].getAttribute('uuidref') == mdsdev.getAttribute('uuid'):
850 return mds.getAttribute('uuid')
854 def get_attr(dom_node, attr, default=""):
855 v = dom_node.getAttribute(attr)
860 ############################################################
863 def set_node_options(gen, node, options):
865 node.setAttribute('router', '1')
867 gen.addElement(node, "timeout", get_option(options, 'timeout'))
869 default_upcall = get_option(options, 'upcall')
872 if default_upcall or options.lustre_upcall:
873 if options.lustre_upcall:
874 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
876 gen.addElement(node, 'lustreUpcall', default_upcall)
877 if default_upcall or options.portals_upcall:
878 if options.portals_upcall:
879 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
881 gen.addElement(node, 'portalsUpcall', default_upcall)
883 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
884 if options.subsystem:
885 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
888 def do_add_node(gen, lustre, options, node_name):
889 uuid = new_uuid(node_name)
890 prof_name = new_name("PROFILE_" + node_name)
891 prof_uuid = new_uuid(prof_name)
892 profile = gen.profile(prof_name, prof_uuid)
893 node = gen.node(node_name, uuid, prof_uuid)
894 lustre.appendChild(node)
895 lustre.appendChild(profile)
897 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
898 set_node_options(gen, node, options)
903 def add_node(gen, lustre, options):
904 """ create a node with a network config """
906 node_name = get_option(options, 'node')
907 ret = findByName(lustre, node_name, "node")
909 print "Node:", node_name, "exists."
911 do_add_node(gen, lustre, options, node_name)
914 def add_net(gen, lustre, options):
915 """ create a node with a network config """
917 node_name = get_option(options, 'node')
918 nid = get_option(options, 'nid')
919 cluster_id = get_option(options, 'cluster_id')
920 hostaddr = get_option(options, 'hostaddr')
921 net_type = get_option(options, 'nettype')
923 if net_type in ('tcp',):
924 port = get_option_int(options, 'port')
925 elif net_type in ('elan', 'gm', 'openib'):
928 print "Unknown net_type: ", net_type
931 ret = findByName(lustre, node_name, "node")
933 node = do_add_node(gen, lustre, options, node_name)
936 set_node_options(gen, node, options)
938 net_name = new_name('NET_'+ node_name +'_'+ net_type)
939 net_uuid = new_uuid(net_name)
940 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
942 node_add_profile(gen, node, "network", net_uuid)
945 def add_route(gen, lustre, options):
946 """ create a node with a network config """
948 node_name = get_option(options, 'node')
949 gw_net_type = get_option(options, 'nettype')
950 gw = get_option(options, 'gw')
951 gw_cluster_id = get_option(options, 'gateway_cluster_id')
952 tgt_cluster_id = get_option(options, 'target_cluster_id')
953 lo = get_option(options, 'lo')
954 hi = get_option(options, 'hi')
958 node = findByName(lustre, node_name, "node")
960 error (node_name, " not found.")
962 rlist = node.getElementsByTagName('routetbl')
966 rtbl_name = new_name("RTBL_" + node_name)
967 rtbl_uuid = new_uuid(rtbl_name)
968 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
969 node.appendChild(rtbl)
970 node_add_profile(gen, node, "routetbl", rtbl_uuid)
971 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
975 def add_mds(gen, lustre, options):
976 node_name = get_option(options, 'node')
977 mds_name = get_option(options, 'mds')
978 lmv_name = get_option(options, 'lmv')
979 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
980 mdd_uuid = new_uuid(mdd_name)
984 lmv = findByName(lustre, lmv_name, "lmv")
986 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
987 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
989 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
991 mds_uuid = get_option(options, 'mdsuuid')
993 if lookup(lustre, mds_uuid):
994 error("Duplicate MDS UUID:", mds_uuid)
996 mds_uuid = new_uuid(mds_name)
997 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
998 lustre.appendChild(mds)
1000 lmv_add_obd(gen, lmv, mds_uuid)
1002 mds = lookup(lustre, mds_uuid)
1004 if options.failover:
1005 mds.setAttribute('failover', "1")
1007 devname = get_option(options, 'dev')
1008 backdevname = get_option(options, 'backdev')
1009 size = get_option(options, 'size')
1010 fstype = get_option(options, 'fstype')
1011 backfstype = get_option(options, 'backfstype')
1012 journal_size = get_option(options, 'journal_size')
1013 inode_size = get_option(options, 'inode_size')
1014 nspath = get_option(options, 'nspath')
1015 mkfsoptions = get_option(options, 'mkfsoptions')
1016 mountfsoptions = get_option(options, 'mountfsoptions')
1017 root_squash = get_option(options, 'root_squash')
1018 no_root_squash = get_option(options, 'no_root_squash')
1020 node_uuid = name2uuid(lustre, node_name, 'node')
1022 node = findByName(lustre, node_name, "node")
1023 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1024 net_uuid = get_net_uuid(lustre, node_name)
1026 error("NODE: ", node_name, "not found")
1029 mds.appendChild(gen.ref("lmv", lmv_uuid))
1031 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1032 get_format_flag(options), node_uuid, mds_uuid,
1033 size, journal_size, inode_size, nspath, mkfsoptions,
1034 mountfsoptions, backfstype, backdevname,lmv_uuid,
1035 root_squash, no_root_squash)
1036 lustre.appendChild(mdd)
1039 def add_mgmt(gen, lustre, options):
1040 node_name = get_option(options, 'node')
1041 node_uuid = name2uuid(lustre, node_name, 'node')
1042 mgmt_name = get_option(options, 'mgmt')
1044 mgmt_name = new_name('MGMT_' + node_name)
1045 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1047 mgmt_uuid = new_uuid(mgmt_name)
1048 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1049 lustre.appendChild(mgmt)
1051 mgmt = lookup(lustre, mgmt_uuid)
1053 node = findByName(lustre, node_name, "node")
1054 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1056 def add_ost(gen, lustre, options):
1057 node_name = get_option(options, 'node')
1058 lovname = get_option(options, 'lov')
1059 osdtype = get_option(options, 'osdtype')
1061 node_uuid = name2uuid(lustre, node_name, 'node')
1063 if osdtype == 'obdecho':
1074 devname = get_option(options, 'dev') # can be unset for bluearcs
1075 backdevname = get_option(options, 'backdev')
1076 size = get_option(options, 'size')
1077 fstype = get_option(options, 'fstype')
1078 backfstype = get_option(options, 'backfstype')
1079 journal_size = get_option(options, 'journal_size')
1080 inode_size = get_option(options, 'inode_size')
1081 mkfsoptions = get_option(options, 'mkfsoptions')
1082 mountfsoptions = get_option(options, 'mountfsoptions')
1084 nspath = get_option(options, 'nspath')
1086 ostname = get_option(options, 'ost')
1088 ostname = new_name('OST_'+ node_name)
1090 osdname = new_name("OSD_" + ostname + "_" + node_name)
1091 osd_uuid = new_uuid(osdname)
1093 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1095 ost_uuid = get_option(options, 'ostuuid')
1097 if lookup(lustre, ost_uuid):
1098 error("Duplicate OST UUID:", ost_uuid)
1100 ost_uuid = new_uuid(ostname)
1102 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1103 lustre.appendChild(ost)
1105 ost = lookup(lustre, ost_uuid)
1108 lov = findByName(lustre, lovname, "lov")
1110 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1111 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1113 if options.failover:
1114 ost.setAttribute('failover', "1")
1117 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1118 get_format_flag(options), ost_uuid, node_uuid, size,
1119 journal_size, inode_size, nspath, mkfsoptions,
1120 mountfsoptions, backfstype, backdevname)
1122 node = findByName(lustre, node_name, "node")
1124 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1126 ## oss_uuid = new_uuid(ossname)
1127 ## oss = gen.oss(ossname, oss_uuid)
1128 ## lustre.appendChild(oss)
1130 node_add_profile(gen, node, 'osd', osd_uuid)
1131 lustre.appendChild(osd)
1133 def del_ost(gen, lustre, options):
1134 ostname = get_option(options, 'ost')
1136 raise OptionError("del_ost: --ost requires a <ost name>")
1137 ost = findByName(lustre, ostname, "ost")
1139 error('del_ost: ', 'Unable to find ', ostname)
1140 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1142 error('del_ost: ', 'Unable to find uuid for ', ostname)
1143 lovname = get_option(options, 'lov')
1145 lov = findByName(lustre, lovname, "lov")
1147 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1148 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1149 # if the user specified a speficic LOV don't delete the OST itself
1152 # remove OSD references from all LOVs
1153 for n in lustre.getElementsByTagName('lov'):
1154 lov_del_obd(gen, lustre, n, ost_uuid, options)
1155 if not options.migrate:
1158 for osd in lustre.getElementsByTagName('osd'):
1159 if ref_exists(osd, ost_uuid):
1160 osd_uuid = osd.getAttribute('uuid')
1161 # delete all profile references to this OSD
1162 for profile in lustre.getElementsByTagName('profile'):
1163 for osd_ref in profile.getElementsByTagName('osd_ref'):
1164 if osd_uuid == osd_ref.getAttribute('uuidref'):
1165 profile.removeChild(osd_ref)
1166 lustre.removeChild(osd)
1169 lustre.removeChild(ost)
1171 def add_cmobd(gen, lustre, options):
1172 node_name = get_option(options, 'node')
1173 name = get_option(options, 'cmobd')
1174 uuid = new_uuid(name)
1176 real_name = get_option(options, 'master_dev')
1177 cache_name = get_option(options, 'cache_dev')
1179 node = findByName(lustre, node_name, "node")
1180 node_add_profile(gen, node, "cmobd", uuid)
1181 real_uuid = node_found_target_by_dev(gen, lustre, node, real_name)
1182 cache_uuid = node_found_target_by_dev(gen, lustre, node, cache_name)
1184 panic("add_cmobd", "can not find real_uuid")
1186 panic("add_cmobd", "can not find cache_uuid")
1187 cmobd = gen.cmobd(name, uuid, real_uuid, cache_uuid)
1188 lustre.appendChild(cmobd)
1190 def add_cobd(gen, lustre, options):
1191 node_name = get_option(options, 'node')
1192 name = get_option(options, 'cobd')
1193 uuid = new_uuid(name)
1195 real_name = get_option(options, 'real_obd')
1196 cache_name = get_option(options, 'cache_obd')
1198 real_uuid = name2uuid(lustre, real_name, tag='lov', fatal=0)
1199 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1202 node = lookup(lustre, real_uuid)
1203 rets = node.getElementsByTagName('lov_tgt')
1205 ost_uuid = ret.getAttribute('uuidref')
1206 ost_node = lookup(lustre, ost_uuid)
1207 ret = ost_node.getElementsByTagName('active_ref')
1209 osd_uuid = ret[0].getAttribute('uuidref')
1210 osd_node = lookup(lustre, osd_uuid)
1211 gen.addElement(osd_node, 'cachetype', 'master')
1214 node = lookup(lustre, cache_uuid)
1215 rets = node.getElementsByTagName('lov_tgt')
1217 ost_uuid = ret.getAttribute('uuidref')
1218 ost_node = lookup(lustre, ost_uuid)
1219 ret = ost_node.getElementsByTagName('active_ref')
1221 osd_uuid = ret[0].getAttribute('uuidref')
1222 osd_node = lookup(lustre, osd_uuid)
1223 gen.addElement(osd_node, 'cachetype', 'cache')
1225 if not real_uuid or not cache_uuid:
1226 real_uuid = name2uuid(lustre,real_name, tag='mds')
1227 cache_uuid = name2uuid(lustre,cache_name, tag='mds')
1229 mds_node = lookup(lustre, real_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', 'master')
1236 mds_node = lookup(lustre, cache_uuid)
1237 ret = mds_node.getElementsByTagName('active_ref')
1239 mdsdev_uuid = ret[0].getAttribute('uuidref')
1240 mdsdev_node = lookup(lustre, mdsdev_uuid)
1241 gen.addElement(mdsdev_node, 'cachetype', 'cache')
1243 node = findByName(lustre, node_name, "node")
1244 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
1245 lustre.appendChild(cobd)
1248 def add_echo_client(gen, lustre, options):
1249 """ add an echo client to the profile for this node. """
1250 node_name = get_option(options, 'node')
1251 lov_name = get_option(options, 'ost')
1253 node = findByName(lustre, node_name, 'node')
1255 echoname = new_name('ECHO_'+ node_name)
1256 echo_uuid = new_uuid(echoname)
1257 node_add_profile(gen, node, 'echoclient', echo_uuid)
1259 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1261 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1263 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1264 lustre.appendChild(echo)
1267 def add_lov(gen, lustre, options):
1268 """ create a lov """
1270 lmv_name = get_option(options, 'lmv')
1271 lov_orig = get_option(options, 'lov')
1272 name = new_name(lov_orig)
1273 if name != lov_orig:
1274 warning("name:", lov_orig, "already used. using:", name)
1276 mds_name = get_option(options, 'mds')
1279 error("LOV: MDS or LMV must be specified.");
1281 stripe_sz = get_option_int(options, 'stripe_sz')
1282 stripe_cnt = get_option_int(options, 'stripe_cnt')
1283 pattern = get_option_int(options, 'stripe_pattern')
1284 uuid = new_uuid(name)
1286 ret = findByName(lustre, name, "lov")
1288 error("LOV: ", name, " already exists.")
1291 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1293 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1295 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1296 lustre.appendChild(lov)
1298 # add an lovconfig entry to the active mdsdev profile
1299 lovconfig_name = new_name('LVCFG_' + name)
1300 lovconfig_uuid = new_uuid(lovconfig_name)
1302 mds = findByName(lustre, mds_name, "mds")
1303 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1305 lmv = findByName(lustre, lmv_name, "lmv")
1306 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1307 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1308 lustre.appendChild(lovconfig)
1310 def add_default_lov(gen, lustre, mds_name, lov_name):
1311 """ create a default lov """
1313 stripe_sz = DEFAULT_STRIPE_SZ
1314 stripe_cnt = DEFAULT_STRIPE_CNT
1315 pattern = DEFAULT_STRIPE_PATTERN
1316 uuid = new_uuid(lov_name)
1318 ret = findByName(lustre, lov_name, "lov")
1320 error("LOV: ", lov_name, " already exists.")
1322 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1323 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1324 lustre.appendChild(lov)
1326 # add an lovconfig entry to the active mdsdev profile
1327 lovconfig_name = new_name('LVCFG_' + lov_name)
1328 lovconfig_uuid = new_uuid(lovconfig_name)
1329 mds = findByName(lustre, mds_name)
1330 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1331 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1332 lustre.appendChild(lovconfig)
1334 def add_lmv(gen, lustre, options):
1335 """ create a lmv """
1337 lmv_orig = get_option(options, 'lmv')
1338 name = new_name(lmv_orig)
1339 if name != lmv_orig:
1340 warning("name:", lmv_orig, "already used. using:", name)
1342 uuid = new_uuid(name)
1343 ret = findByName(lustre, name, "lmv")
1345 error("LMV: ", name, " already exists.")
1347 lmv = gen.lmv(name, uuid)
1348 lustre.appendChild(lmv)
1350 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1351 fs_name = new_name("FS_fsname")
1352 fs_uuid = new_uuid(fs_name)
1353 cobd = lookup(lustre, mds_uuid)
1354 #SHOULD appendChild filesystem to real mds not cobd
1355 ret = cobd.getElementsByTagName("cacheobd_ref")
1357 cacheobd_uuid = ret[0].getAttribute('uuidref')
1358 cacheobd = lookup(lustre, cacheobd_uuid)
1359 cacheobd.appendChild(gen.ref("filesystem", fs_uuid))
1360 ret = cobd.getElementsByTagName("realobd_ref")
1362 realobd_uuid = ret[0].getAttribute('uuidref')
1363 realobd = lookup(lustre, realobd_uuid)
1364 realobd.appendChild(gen.ref("filesystem", fs_uuid))
1366 cobd.appendChild(gen.ref("filesystem", fs_uuid))
1367 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid, mgmt_uuid)
1368 lustre.appendChild(fs)
1371 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1372 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1374 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1376 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=1)
1377 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1379 obd_uuid = name2uuid(lustre, obd_name, tag='cobd')
1381 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1384 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1386 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid)
1389 def add_mtpt(gen, lustre, options):
1390 """ create mtpt on a node """
1391 node_name = get_option(options, 'node')
1393 path = get_option(options, 'path')
1394 clientoptions = get_option(options, "clientoptions")
1395 fs_name = get_option(options, 'filesystem')
1397 lov_name = get_option(options, 'lov')
1398 ost_name = get_option(options, 'ost')
1399 mds_name = get_option(options, 'mds')
1401 mds_name = get_option(options, 'lmv')
1403 error("--add mtpt requires either --mds or --lmv.")
1406 error("--add mtpt requires --lov lov_name or --ost ost_name")
1408 warning("use default value for lov, due no --lov lov_name provided")
1409 lov_name = new_name("lov_default")
1410 add_default_lov(gen, lustre, mds_name, lov_name)
1411 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1413 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1414 lov = findByName(lustre, lov_name, "lov")
1415 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1418 mgmt_name = get_option(options, 'mgmt')
1419 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1421 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1423 name = new_name('MNT_'+ node_name)
1425 ret = findByName(lustre, name, "mountpoint")
1427 # this can't happen, because new_name creates unique names
1428 error("MOUNTPOINT: ", name, " already exists.")
1430 uuid = new_uuid(name)
1431 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
1432 node = findByName(lustre, node_name, "node")
1434 error('node:', node_name, "not found.")
1435 node_add_profile(gen, node, "mountpoint", uuid)
1436 lustre.appendChild(mtpt)
1438 def commit_version(gen, lustre):
1439 update = findLastUpdate(lustre)
1441 version = int(update.getAttribute("version")) + 1
1445 new = gen.update(str(version))
1446 lustre.appendChild(new)
1449 ############################################################
1450 # Command line processing
1452 class OptionError (exceptions.Exception):
1453 def __init__(self, args):
1456 def get_option(options, tag):
1457 """Look for tag in options hash and return the value if set. If not
1458 set, then if return default it is set, otherwise exception."""
1459 if options.__getattr__(tag) != None:
1460 return options.__getattr__(tag)
1462 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1464 def get_option_int(options, tag):
1465 """Return an integer option. Raise exception if the value is not an int"""
1466 val = get_option(options, tag)
1470 raise OptionError("--%s <num> (value must be integer)" % (tag))
1473 # simple class for profiling
1480 self._start = time.time()
1481 def stop(self, msg=''):
1482 self._stop = time.time()
1486 return self._stop - self._start
1487 def display(self, msg):
1489 str = '%s: %g secs' % (msg, d)
1492 #################################################################
1493 # function cmdlinesplit used to split cmd line from batch file
1495 def cmdlinesplit(cmdline):
1497 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1498 single_quote = re.compile(r"'(.*?)'")
1499 escaped = re.compile(r'\\(.)')
1500 esc_quote = re.compile(r'\\([\\"])')
1501 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1505 while i < len(cmdline):
1508 match = double_quote.match(cmdline, i)
1510 print "Unmatched double quote:", cmdline
1513 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1514 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1517 match = single_quote.match(cmdline, i)
1519 print "Unmatched single quote:", cmdline
1522 if arg is None: arg = match.group(1)
1523 else: arg = arg + match.group(1)
1526 match = escaped.match(cmdline, i)
1528 print "Unmatched backslash", cmdline
1531 if arg is None: arg = match.group(1)
1532 else: arg = arg + match.group(1)
1534 elif c in string.whitespace:
1536 arg_list.append(str(arg))
1538 while i < len(cmdline) and cmdline[i] in string.whitespace:
1541 match = outside.match(cmdline, i)
1544 if arg is None: arg = match.group()
1545 else: arg = arg + match.group()
1547 if arg != None: arg_list.append(str(arg))
1551 ############################################################
1555 def add(devtype, gen, lustre, options):
1556 if devtype == 'net':
1557 add_net(gen, lustre, options)
1558 elif devtype == 'mtpt':
1559 add_mtpt(gen, lustre, options)
1560 elif devtype == 'mds':
1561 add_mds(gen, lustre, options)
1562 elif devtype == 'ost':
1563 add_ost(gen, lustre, options)
1564 elif devtype == 'lov':
1565 add_lov(gen, lustre, options)
1566 elif devtype == 'route':
1567 add_route(gen, lustre, options)
1568 elif devtype == 'node':
1569 add_node(gen, lustre, options)
1570 elif devtype == 'echo_client':
1571 add_echo_client(gen, lustre, options)
1572 elif devtype == 'cobd':
1573 add_cobd(gen, lustre, options)
1574 elif devtype == 'cmobd':
1575 add_cmobd(gen, lustre, options)
1576 elif devtype == 'mgmt':
1577 add_mgmt(gen, lustre, options)
1578 elif devtype == 'lmv':
1579 add_lmv(gen, lustre, options)
1581 error("unknown device type:", devtype)
1583 def delete(devtype, gen, lustre, options):
1584 if devtype == 'ost':
1585 del_ost(gen, lustre, options)
1586 elif options.delete:
1587 error("delete not supported for device type:", devtype)
1588 elif options.deactivate:
1589 error("deactivate not supported for device type:", devtype)
1591 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1593 def commit(gen, lustre):
1594 commit_version(gen, lustre)
1596 def do_command(gen, lustre, options, args):
1598 add(options.add, gen, lustre, options)
1599 elif options.delete:
1600 delete(options.delete, gen, lustre, options)
1601 elif options.deactivate:
1602 delete(options.deactivate, gen, lustre, options)
1603 elif options.commit:
1606 error("Missing command")
1609 cl = Lustre.Options("lmc", "", lmc_options)
1611 options, args = cl.parse(sys.argv[1:])
1612 except Lustre.OptionError, e:
1616 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1618 if options.reference:
1625 outFile = options.merge
1626 if os.access(outFile, os.R_OK):
1627 doc = xml.dom.minidom.parse(outFile)
1629 doc = new_lustre(xml.dom.minidom)
1631 doc = xml.dom.minidom.parse(options.input)
1633 doc = new_lustre(xml.dom.minidom)
1636 outFile = options.output
1638 lustre = doc.documentElement
1640 if lustre.tagName != "lustre":
1641 print "Existing config not valid."
1644 gen = GenConfig(doc)
1647 fp = open(options.batch)
1648 batchCommands = fp.readlines()
1650 for cmd in batchCommands:
1652 options, args = cl.parse(cmdlinesplit(cmd))
1653 if options.merge or options.input or options.output:
1654 print "The batchfile should not contain --merge, --input or --output."
1656 do_command(gen, lustre, options, args)
1657 except OptionError, e:
1659 except Lustre.OptionError, e:
1663 do_command(gen, lustre, options, args)
1664 except OptionError, e:
1665 panic(string.join(sys.argv),e)
1666 except Lustre.OptionError, e:
1672 printDoc(doc, open(outFile,"w"))
1674 if __name__ == "__main__":