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|iib
78 --hostaddr ip[/netmask]
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
179 PARAMLIST = Lustre.Options.PARAMLIST
181 # lmc input/output options
182 ('reference', "Print short reference for commands."),
183 ('verbose,v', "Print system commands as they are run."),
184 ('merge,m', "Append to the specified config file.", PARAM),
185 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
186 ('input,i', "", PARAM),
187 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
191 ('delete', "", PARAM),
192 ('deactivate', "", PARAM),
193 ('commit', "Commit all config changes and start a new version"),
196 ('node', "Add a new node in the cluster configuration.", PARAM),
197 ('timeout', "Set timeout to initiate recovery.", PARAM),
198 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
199 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
200 ('portals_upcall', "Set location of portals upcall script.", PARAM),
201 ('ptldebug', "Set the portals debug level", PARAM),
202 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
205 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib/iib.", PARAM),
206 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
207 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
208 ('hostaddr', "Optional argument to specify the host address.", PARAMLIST),
209 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
212 ('route', "Add a new route for the cluster.", PARAM),
213 ('router', "Optional flag to mark a node as router."),
214 ('gw', "Specify the nid of the gateway for a route.", PARAM),
215 ('gateway_cluster_id', "", PARAM, "0"),
216 ('target_cluster_id', "", PARAM, "0"),
217 ('lo', "For a range route, this is the low value nid.", PARAM),
218 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
220 # servers: mds and ost
221 ('mds', "Specify MDS name.", PARAM,""),
222 ('ost', "Specify the OST name.", PARAM,""),
223 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
224 ('failover', "Enable failover support on OSTs or MDS?"),
225 ('group', "", PARAM),
226 ('dev', "Path of the device on local system.", PARAM,""),
227 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
228 ('size', "Specify the size of the device if needed.", PARAM,"0"),
229 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
230 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
231 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
232 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
233 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
234 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
235 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
236 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
237 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
238 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
239 ('nspath', "Local mount point of server namespace.", PARAM,""),
241 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
243 # clients: mountpoint and echo
244 ('echo_client', "", PARAM),
245 ('path', "Specify the mountpoint for Lustre.", PARAM),
246 ('filesystem', "Lustre filesystem name", PARAM,""),
247 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
250 ('lov', "Specify LOV name.", PARAM,""),
251 ('index', "Specify index for OBD in LOV target table.", PARAM),
252 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
253 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
254 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
258 ('real_obd', "Specify the real device for the cache obd system.", PARAM),
259 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
260 ('cobd', "Specify COBD name", PARAM),
263 ('master_dev', "Specify the master device for the cmobd system.", PARAM),
264 ('cache_dev', "Specify the cache device for the cmobd obd system.", PARAM),
265 ('cmobd', "Specify COBD name", PARAM),
268 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
271 ('lmv', "Specify LMV name.", PARAM,""),
275 msg = string.join(map(str,args))
276 raise OptionError("Error: " + msg)
285 msg = string.join(map(str,args))
286 print "Warning: ", msg
289 # manage names and uuids
290 # need to initialize this by walking tree to ensure
291 # no duplicate names or uuids are created.
292 # this are just place holders for now.
293 # consider changing this to be like OBD-dev-host
297 while names.has_key(ret):
298 ret = "%s_%d" % (base, ctr)
305 ret = "%s_UUID" % (name)
306 if len(ret) > UUID_MAX_LENGTH:
307 ret = ret[-UUID_MAX_LENGTH:]
308 while uuids.has_key(ret):
309 ret = "%s_UUID_%d" % (name, ctr)
311 if len(ret) > UUID_MAX_LENGTH:
312 ret = ret[-UUID_MAX_LENGTH:]
318 ldlm_uuid = 'ldlm_UUID'
321 """Create a new empty lustre document"""
322 # adding ldlm here is a bit of a hack, but one is enough.
323 str = """<lustre version="%s">
324 <ldlm name="%s" uuid="%s"/>
325 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
326 return dom.parseString(str)
332 """initialize auto-name generation tables"""
334 # get all elements that contain a name attribute
335 for n in doc.childNodes:
336 if n.nodeType == n.ELEMENT_NODE:
338 names[getName(n)] = 1
339 uuids[getUUID(n)] = 1
342 def get_format_flag(options):
347 ############################################################
348 # Build config objects using DOM
353 def __init__(self, doc):
356 def ref(self, type, uuid):
357 """ generate <[type]_ref uuidref="[uuid]"/> """
358 tag = "%s_ref" % (type)
359 ref = self.doc.createElement(tag)
360 ref.setAttribute("uuidref", uuid)
363 def dev(self, devname):
364 """ generate <dev devpath="[devname]"/> """
365 tgt = self.doc.createElement('dev')
366 tgt.setAttribute("dev", devname)
369 def newService(self, tag, name, uuid):
370 """ create a new service elmement, which requires name and uuid attributes """
371 new = self.doc.createElement(tag)
372 new.setAttribute("uuid", uuid);
373 new.setAttribute("name", name);
376 def addText(self, node, str):
377 txt = self.doc.createTextNode(str)
378 node.appendChild(txt)
380 def addElement(self, node, tag, str=None):
381 """ create a new element and add it as a child to node. If str is passed,
382 a text node is created for the new element"""
383 new = self.doc.createElement(tag)
385 self.addText(new, str)
386 node.appendChild(new)
389 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
391 """create <network> node"""
392 network = self.newService("network", name, uuid)
393 network.setAttribute("nettype", net);
394 self.addElement(network, "nid", nid)
395 self.addElement(network, "clusterid", cluster_id)
396 for host in hostaddr:
397 self.addElement(network, "hostaddr", host)
399 self.addElement(network, "port", "%d" %(port))
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="", root_squash="", no_root_squash=""):
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 self.addElement(mdd, "root_squash", root_squash)
550 self.addElement(mdd, "no_root_squash", no_root_squash)
551 mdd.appendChild(self.ref("node", node_uuid))
552 mdd.appendChild(self.ref("target", mds_uuid))
553 mdd.appendChild(self.dev(devname))
556 mdd.appendChild(self.ref("lmv", lmv_uuid))
557 self.addElement(mdd, "lmv", lmv_uuid)
561 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
562 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
563 mgmt.appendChild(self.ref("node", node_uuid))
564 # Placeholder until mgmt-service failover.
565 mgmt.appendChild(self.ref("active", mgmt_uuid))
568 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
569 mtpt = self.newService("mountpoint", name, uuid)
570 mtpt.appendChild(self.ref("filesystem", fs_uuid))
571 self.addElement(mtpt, "path", path)
573 self.addElement(mtpt, "clientoptions", clientoptions)
576 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
577 fs = self.newService("filesystem", name, uuid)
578 fs.appendChild(self.ref("mds", mds_uuid))
579 fs.appendChild(self.ref("obd", obd_uuid))
581 fs.appendChild(self.ref("mgmt", mgmt_uuid))
584 def echo_client(self, name, uuid, osc_uuid):
585 ec = self.newService("echoclient", name, uuid)
586 ec.appendChild(self.ref("obd", osc_uuid))
589 def update(self, version):
590 new = self.doc.createElement("update")
591 new.setAttribute("version", version)
594 def add(self, lov, ost, index, gen):
595 new = self.doc.createElement("add")
596 new.setAttribute("lov_uuidref", lov)
597 new.setAttribute("ost_uuidref", ost)
598 new.setAttribute("index", index)
599 new.setAttribute("generation", gen)
602 def delete(self, lov, ost, index, gen, options):
604 new = self.doc.createElement("delete")
606 new = self.doc.createElement("deactivate")
607 new.setAttribute("lov_uuidref", lov)
608 new.setAttribute("ost_uuidref", ost)
609 new.setAttribute("index", index)
610 new.setAttribute("generation", gen)
613 ############################################################
614 # Utilities to query a DOM tree
615 # Using this functions we can treat use config information
616 # directly as a database.
618 return n.getAttribute('name')
621 return node.getAttribute('uuid')
623 def findLastUpdate(lustre):
626 for n in lustre.childNodes:
627 if n.nodeType == n.ELEMENT_NODE:
628 if n.nodeName != 'update':
630 tmp = int(n.getAttribute('version'))
632 error('malformed XML: update tag without a version attribute')
633 if tmp != version + 1:
634 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
639 def addUpdate(gen, lustre, node):
640 update = findLastUpdate(lustre)
643 #add_record = update.getElementsByTagName('add')
645 # add_record = gen.add()
646 # update.appendChild(add_record)
648 # add_record = add_record[0]
649 #add_record.appendChild(node)
650 update.appendChild(node)
652 def delUpdate(gen, lustre, node):
653 update = findLastUpdate(lustre)
656 update.appendChild(node)
658 def findByName(lustre, name, tag = ""):
659 for n in lustre.childNodes:
660 if n.nodeType == n.ELEMENT_NODE:
661 if tag and n.nodeName != tag:
663 if getName(n) == name:
666 n = findByName(n, name)
671 def lookup(node, uuid):
672 for n in node.childNodes:
673 if n.nodeType == n.ELEMENT_NODE:
674 if getUUID(n) == uuid:
682 def name2uuid(lustre, name, tag="", fatal=1):
683 ret = findByName(lustre, name, tag)
686 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
691 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
692 for n in lustre.childNodes:
693 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
694 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
698 # XXX: assumes only one network element per node. will fix this
699 # as soon as support for routers is added
700 def get_net_uuid(lustre, node_name):
701 """ get a network uuid for a node_name """
702 node = findByName(lustre, node_name, "node")
704 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
705 net = node.getElementsByTagName('network')
707 return getUUID(net[0])
710 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
711 tgt.setAttribute('uuidref', osc_uuid)
713 gener = int(tgt.getAttribute('generation'))
715 gener = int(tgt.getAttribute('generation')) + 1
716 tgt.setAttribute('generation', str(gener))
717 tgt.setAttribute('active', '1')
718 lov_index = int(tgt.getAttribute('index'))
719 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
723 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
724 lov_name = getName(lov)
726 lov_index = get_option_int(options, 'index')
727 for tgt in lustre.getElementsByTagName('lov_tgt'):
728 if str(lov_index) == tgt.getAttribute('index'):
729 uuidref = tgt.getAttribute('uuidref')
731 raise OptionError("%s --index %d is still in use: %s" %
732 (lov_name, lov_index, uuidref))
733 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
737 for tgt in lustre.getElementsByTagName('lov_tgt'):
738 uuidref = tgt.getAttribute('uuidref')
739 tmp = int(tgt.getAttribute('index'))
741 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
742 uuidref = tgt.getAttribute('uuidref')
744 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
746 lov_index = lov_index + 1
748 lov.appendChild(gen.lov_tgt(osc_uuid, str(lov_index), '1'))
749 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index), '1'))
751 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
752 lov_name = getName(lov)
754 lov_index = get_option_int(options, 'index')
755 for tgt in lustre.getElementsByTagName('lov_tgt'):
756 index = tgt.getAttribute('index')
757 if index == lov_index:
758 uuidref = tgt.getAttribute('uuidref')
759 if uuidref != osc_uuid:
760 raise OptionError("%s --index %d contains %s, not %s" %
761 (lov_name, lov_index, osc_uuid, uuidref))
763 tgt.setAttribute('uuidref', '')
765 # bump the generation just in case...
767 gen = int(tgt.getAttribute('generation'))
769 gen = int(tgt.getAttribute('generation')) + 1
771 tgt.setAttribute('active', '0')
772 tgt.setAttribute('generation', str(gen))
774 raise OptionError("%s --index %d not in use by %s." %
775 (lov_name, lov_index, osc_uuid))
777 for tgt in lustre.getElementsByTagName('lov_tgt'):
778 uuidref = tgt.getAttribute('uuidref')
779 if uuidref == osc_uuid:
780 genera = int(tgt.getAttribute('generation'))
781 delete_rec = gen.delete(getUUID(lov),
782 osc_uuid,tgt.getAttribute('index'),
783 str(genera), options)
784 delUpdate(gen, lustre, delete_rec)
787 tgt.setAttribute('uuidref', '')
788 if not options.migrate:
790 tgt.setAttribute('active', '0')
791 tgt.setAttribute('generation', str(genera))
793 def lmv_add_obd(gen, lmv, mdc_uuid):
794 lmv.appendChild(gen.ref("mds", mdc_uuid))
796 def ref_exists(profile, uuid):
797 elist = profile.childNodes
799 if e.nodeType == e.ELEMENT_NODE:
800 ref = e.getAttribute('uuidref')
805 # ensure that uuid is not already in the profile
806 # return true if uuid is added
807 def node_add_profile(gen, node, ref, uuid):
808 refname = "%s_ref" % "profile"
809 ret = node.getElementsByTagName(refname)
811 error('node has no profile ref:', node)
812 prof_uuid = ret[0].getAttribute('uuidref')
813 profile = lookup(node.parentNode, prof_uuid)
815 error("no profile found:", prof_uuid)
816 if ref_exists(profile, uuid):
818 profile.appendChild(gen.ref(ref, uuid))
821 # ensure that uuid is not already in the profile
822 # return true if uuid is added
823 def node_found_target_by_dev(gen, lustre, node, devname):
824 refname = "%s_ref" % "profile"
825 ret = node.getElementsByTagName(refname)
827 error('node has no profile ref:', node)
828 prof_uuid = ret[0].getAttribute('uuidref')
829 profile = lookup(node.parentNode, prof_uuid)
831 error("no profile found:", prof_uuid)
833 osd_list = lustre.getElementsByTagName('osd')
836 obd_dev = osd.getElementsByTagName('dev')
837 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
838 for ost in lustre.getElementsByTagName('ost'):
839 active_ret = ost.getElementsByTagName('active_ref')
840 if active_ret[0].getAttribute('uuidref') == osd.getAttribute('uuid'):
841 return ost.getAttribute('uuid')
843 mdsdev_list = lustre.getElementsByTagName('mdsdev')
845 for mdsdev in mdsdev_list:
846 obd_dev = mdsdev.getElementsByTagName('dev')
847 if obd_dev and obd_dev[0].getAttribute('dev') == devname:
848 for mds in lustre.getElementsByTagName('mds'):
849 active_ret = mds.getElementsByTagName('active_ref')
850 if active_ret[0].getAttribute('uuidref') == mdsdev.getAttribute('uuid'):
851 return mds.getAttribute('uuid')
855 def get_attr(dom_node, attr, default=""):
856 v = dom_node.getAttribute(attr)
861 ############################################################
864 def set_node_options(gen, node, options):
866 node.setAttribute('router', '1')
868 gen.addElement(node, "timeout", get_option(options, 'timeout'))
870 default_upcall = get_option(options, 'upcall')
873 if default_upcall or options.lustre_upcall:
874 if options.lustre_upcall:
875 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
877 gen.addElement(node, 'lustreUpcall', default_upcall)
878 if default_upcall or options.portals_upcall:
879 if options.portals_upcall:
880 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
882 gen.addElement(node, 'portalsUpcall', default_upcall)
884 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
885 if options.subsystem:
886 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
889 def do_add_node(gen, lustre, options, node_name):
890 uuid = new_uuid(node_name)
891 prof_name = new_name("PROFILE_" + node_name)
892 prof_uuid = new_uuid(prof_name)
893 profile = gen.profile(prof_name, prof_uuid)
894 node = gen.node(node_name, uuid, prof_uuid)
895 lustre.appendChild(node)
896 lustre.appendChild(profile)
898 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
899 set_node_options(gen, node, options)
904 def add_node(gen, lustre, options):
905 """ create a node with a network config """
907 node_name = get_option(options, 'node')
908 ret = findByName(lustre, node_name, "node")
910 print "Node:", node_name, "exists."
912 do_add_node(gen, lustre, options, node_name)
915 def add_net(gen, lustre, options):
916 """ create a node with a network config """
918 node_name = get_option(options, 'node')
919 nid = get_option(options, 'nid')
920 cluster_id = get_option(options, 'cluster_id')
921 hostaddr = get_option(options, 'hostaddr')
922 net_type = get_option(options, 'nettype')
924 if net_type in ('tcp',):
925 port = get_option_int(options, 'port')
926 elif net_type in ('elan', 'gm', 'openib','iib'):
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,
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 = get_option(options, 'mdsuuid')
994 if lookup(lustre, mds_uuid):
995 error("Duplicate MDS UUID:", mds_uuid)
997 mds_uuid = new_uuid(mds_name)
998 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
999 lustre.appendChild(mds)
1001 lmv_add_obd(gen, lmv, mds_uuid)
1003 mds = lookup(lustre, mds_uuid)
1005 if options.failover:
1006 mds.setAttribute('failover', "1")
1008 devname = get_option(options, 'dev')
1009 backdevname = get_option(options, 'backdev')
1010 size = get_option(options, 'size')
1011 fstype = get_option(options, 'fstype')
1012 backfstype = get_option(options, 'backfstype')
1013 journal_size = get_option(options, 'journal_size')
1014 inode_size = get_option(options, 'inode_size')
1015 nspath = get_option(options, 'nspath')
1016 mkfsoptions = get_option(options, 'mkfsoptions')
1017 mountfsoptions = get_option(options, 'mountfsoptions')
1018 root_squash = get_option(options, 'root_squash')
1019 no_root_squash = get_option(options, 'no_root_squash')
1021 node_uuid = name2uuid(lustre, node_name, 'node')
1023 node = findByName(lustre, node_name, "node")
1024 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1025 net_uuid = get_net_uuid(lustre, node_name)
1027 error("NODE: ", node_name, "not found")
1030 mds.appendChild(gen.ref("lmv", lmv_uuid))
1032 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1033 get_format_flag(options), node_uuid, mds_uuid,
1034 size, journal_size, inode_size, nspath, mkfsoptions,
1035 mountfsoptions, backfstype, backdevname,lmv_uuid,
1036 root_squash, no_root_squash)
1037 lustre.appendChild(mdd)
1040 def add_mgmt(gen, lustre, options):
1041 node_name = get_option(options, 'node')
1042 node_uuid = name2uuid(lustre, node_name, 'node')
1043 mgmt_name = get_option(options, 'mgmt')
1045 mgmt_name = new_name('MGMT_' + node_name)
1046 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1048 mgmt_uuid = new_uuid(mgmt_name)
1049 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1050 lustre.appendChild(mgmt)
1052 mgmt = lookup(lustre, mgmt_uuid)
1054 node = findByName(lustre, node_name, "node")
1055 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1057 def add_ost(gen, lustre, options):
1058 node_name = get_option(options, 'node')
1059 lovname = get_option(options, 'lov')
1060 osdtype = get_option(options, 'osdtype')
1062 node_uuid = name2uuid(lustre, node_name, 'node')
1064 if osdtype == 'obdecho':
1075 devname = get_option(options, 'dev') # can be unset for bluearcs
1076 backdevname = get_option(options, 'backdev')
1077 size = get_option(options, 'size')
1078 fstype = get_option(options, 'fstype')
1079 backfstype = get_option(options, 'backfstype')
1080 journal_size = get_option(options, 'journal_size')
1081 inode_size = get_option(options, 'inode_size')
1082 mkfsoptions = get_option(options, 'mkfsoptions')
1083 mountfsoptions = get_option(options, 'mountfsoptions')
1085 nspath = get_option(options, 'nspath')
1087 ostname = get_option(options, 'ost')
1089 ostname = new_name('OST_'+ node_name)
1091 osdname = new_name("OSD_" + ostname + "_" + node_name)
1092 osd_uuid = new_uuid(osdname)
1094 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1096 ost_uuid = get_option(options, 'ostuuid')
1098 if lookup(lustre, ost_uuid):
1099 error("Duplicate OST UUID:", ost_uuid)
1101 ost_uuid = new_uuid(ostname)
1103 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1104 lustre.appendChild(ost)
1106 ost = lookup(lustre, ost_uuid)
1109 lov = findByName(lustre, lovname, "lov")
1111 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1112 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1114 if options.failover:
1115 ost.setAttribute('failover', "1")
1118 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1119 get_format_flag(options), ost_uuid, node_uuid, size,
1120 journal_size, inode_size, nspath, mkfsoptions,
1121 mountfsoptions, backfstype, backdevname)
1123 node = findByName(lustre, node_name, "node")
1125 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1127 ## oss_uuid = new_uuid(ossname)
1128 ## oss = gen.oss(ossname, oss_uuid)
1129 ## lustre.appendChild(oss)
1131 node_add_profile(gen, node, 'osd', osd_uuid)
1132 lustre.appendChild(osd)
1134 def del_ost(gen, lustre, options):
1135 ostname = get_option(options, 'ost')
1137 raise OptionError("del_ost: --ost requires a <ost name>")
1138 ost = findByName(lustre, ostname, "ost")
1140 error('del_ost: ', 'Unable to find ', ostname)
1141 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1143 error('del_ost: ', 'Unable to find uuid for ', ostname)
1144 lovname = get_option(options, 'lov')
1146 lov = findByName(lustre, lovname, "lov")
1148 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1149 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1150 # if the user specified a speficic LOV don't delete the OST itself
1153 # remove OSD references from all LOVs
1154 for n in lustre.getElementsByTagName('lov'):
1155 lov_del_obd(gen, lustre, n, ost_uuid, options)
1156 if not options.migrate:
1159 for osd in lustre.getElementsByTagName('osd'):
1160 if ref_exists(osd, ost_uuid):
1161 osd_uuid = osd.getAttribute('uuid')
1162 # delete all profile references to this OSD
1163 for profile in lustre.getElementsByTagName('profile'):
1164 for osd_ref in profile.getElementsByTagName('osd_ref'):
1165 if osd_uuid == osd_ref.getAttribute('uuidref'):
1166 profile.removeChild(osd_ref)
1167 lustre.removeChild(osd)
1170 lustre.removeChild(ost)
1172 def add_cmobd(gen, lustre, options):
1173 node_name = get_option(options, 'node')
1174 name = get_option(options, 'cmobd')
1175 uuid = new_uuid(name)
1177 real_name = get_option(options, 'master_dev')
1178 cache_name = get_option(options, 'cache_dev')
1180 node = findByName(lustre, node_name, "node")
1181 node_add_profile(gen, node, "cmobd", uuid)
1182 real_uuid = node_found_target_by_dev(gen, lustre, node, real_name)
1183 cache_uuid = node_found_target_by_dev(gen, lustre, node, cache_name)
1185 panic("add_cmobd", "can not find real_uuid")
1187 panic("add_cmobd", "can not find cache_uuid")
1188 cmobd = gen.cmobd(name, uuid, real_uuid, cache_uuid)
1189 lustre.appendChild(cmobd)
1191 def add_cobd(gen, lustre, options):
1192 node_name = get_option(options, 'node')
1193 name = get_option(options, 'cobd')
1194 uuid = new_uuid(name)
1196 real_name = get_option(options, 'real_obd')
1197 cache_name = get_option(options, 'cache_obd')
1199 real_uuid = name2uuid(lustre, real_name, tag='lov', fatal=0)
1200 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1203 node = lookup(lustre, real_uuid)
1204 rets = node.getElementsByTagName('lov_tgt')
1206 ost_uuid = ret.getAttribute('uuidref')
1207 ost_node = lookup(lustre, ost_uuid)
1208 ret = ost_node.getElementsByTagName('active_ref')
1210 osd_uuid = ret[0].getAttribute('uuidref')
1211 osd_node = lookup(lustre, osd_uuid)
1212 gen.addElement(osd_node, 'cachetype', 'master')
1215 node = lookup(lustre, cache_uuid)
1216 rets = node.getElementsByTagName('lov_tgt')
1218 ost_uuid = ret.getAttribute('uuidref')
1219 ost_node = lookup(lustre, ost_uuid)
1220 ret = ost_node.getElementsByTagName('active_ref')
1222 osd_uuid = ret[0].getAttribute('uuidref')
1223 osd_node = lookup(lustre, osd_uuid)
1224 gen.addElement(osd_node, 'cachetype', 'cache')
1226 if not real_uuid or not cache_uuid:
1227 real_uuid = name2uuid(lustre,real_name, tag='mds')
1228 cache_uuid = name2uuid(lustre,cache_name, tag='mds')
1230 mds_node = lookup(lustre, real_uuid)
1231 ret = mds_node.getElementsByTagName('active_ref')
1233 mdsdev_uuid = ret[0].getAttribute('uuidref')
1234 mdsdev_node = lookup(lustre, mdsdev_uuid)
1235 gen.addElement(mdsdev_node, 'cachetype', 'master')
1237 mds_node = lookup(lustre, cache_uuid)
1238 ret = mds_node.getElementsByTagName('active_ref')
1240 mdsdev_uuid = ret[0].getAttribute('uuidref')
1241 mdsdev_node = lookup(lustre, mdsdev_uuid)
1242 gen.addElement(mdsdev_node, 'cachetype', 'cache')
1244 node = findByName(lustre, node_name, "node")
1245 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
1246 lustre.appendChild(cobd)
1249 def add_echo_client(gen, lustre, options):
1250 """ add an echo client to the profile for this node. """
1251 node_name = get_option(options, 'node')
1252 lov_name = get_option(options, 'ost')
1254 node = findByName(lustre, node_name, 'node')
1256 echoname = new_name('ECHO_'+ node_name)
1257 echo_uuid = new_uuid(echoname)
1258 node_add_profile(gen, node, 'echoclient', echo_uuid)
1260 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1262 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1264 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1265 lustre.appendChild(echo)
1268 def add_lov(gen, lustre, options):
1269 """ create a lov """
1271 lmv_name = get_option(options, 'lmv')
1272 lov_orig = get_option(options, 'lov')
1273 name = new_name(lov_orig)
1274 if name != lov_orig:
1275 warning("name:", lov_orig, "already used. using:", name)
1277 mds_name = get_option(options, 'mds')
1280 error("LOV: MDS or LMV must be specified.");
1282 stripe_sz = get_option_int(options, 'stripe_sz')
1283 stripe_cnt = get_option_int(options, 'stripe_cnt')
1284 pattern = get_option_int(options, 'stripe_pattern')
1285 uuid = new_uuid(name)
1287 ret = findByName(lustre, name, "lov")
1289 error("LOV: ", name, " already exists.")
1292 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1294 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1296 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1297 lustre.appendChild(lov)
1299 # add an lovconfig entry to the active mdsdev profile
1300 lovconfig_name = new_name('LVCFG_' + name)
1301 lovconfig_uuid = new_uuid(lovconfig_name)
1303 mds = findByName(lustre, mds_name, "mds")
1304 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1306 lmv = findByName(lustre, lmv_name, "lmv")
1307 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1308 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1309 lustre.appendChild(lovconfig)
1311 def add_default_lov(gen, lustre, mds_name, lov_name):
1312 """ create a default lov """
1314 stripe_sz = DEFAULT_STRIPE_SZ
1315 stripe_cnt = DEFAULT_STRIPE_CNT
1316 pattern = DEFAULT_STRIPE_PATTERN
1317 uuid = new_uuid(lov_name)
1319 ret = findByName(lustre, lov_name, "lov")
1321 error("LOV: ", lov_name, " already exists.")
1323 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1324 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1325 lustre.appendChild(lov)
1327 # add an lovconfig entry to the active mdsdev profile
1328 lovconfig_name = new_name('LVCFG_' + lov_name)
1329 lovconfig_uuid = new_uuid(lovconfig_name)
1330 mds = findByName(lustre, mds_name)
1331 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1332 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1333 lustre.appendChild(lovconfig)
1335 def add_lmv(gen, lustre, options):
1336 """ create a lmv """
1338 lmv_orig = get_option(options, 'lmv')
1339 name = new_name(lmv_orig)
1340 if name != lmv_orig:
1341 warning("name:", lmv_orig, "already used. using:", name)
1343 uuid = new_uuid(name)
1344 ret = findByName(lustre, name, "lmv")
1346 error("LMV: ", name, " already exists.")
1348 lmv = gen.lmv(name, uuid)
1349 lustre.appendChild(lmv)
1351 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1352 fs_name = new_name("FS_fsname")
1353 fs_uuid = new_uuid(fs_name)
1354 cobd = lookup(lustre, mds_uuid)
1355 #SHOULD appendChild filesystem to real mds not cobd
1356 ret = cobd.getElementsByTagName("cacheobd_ref")
1358 cacheobd_uuid = ret[0].getAttribute('uuidref')
1359 cacheobd = lookup(lustre, cacheobd_uuid)
1360 cacheobd.appendChild(gen.ref("filesystem", fs_uuid))
1361 ret = cobd.getElementsByTagName("realobd_ref")
1363 realobd_uuid = ret[0].getAttribute('uuidref')
1364 realobd = lookup(lustre, realobd_uuid)
1365 realobd.appendChild(gen.ref("filesystem", fs_uuid))
1367 cobd.appendChild(gen.ref("filesystem", fs_uuid))
1368 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid, mgmt_uuid)
1369 lustre.appendChild(fs)
1372 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1373 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1375 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1377 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=1)
1378 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1380 obd_uuid = name2uuid(lustre, obd_name, tag='cobd')
1382 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1385 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1387 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid)
1390 def add_mtpt(gen, lustre, options):
1391 """ create mtpt on a node """
1392 node_name = get_option(options, 'node')
1394 path = get_option(options, 'path')
1395 clientoptions = get_option(options, "clientoptions")
1396 fs_name = get_option(options, 'filesystem')
1398 lov_name = get_option(options, 'lov')
1399 ost_name = get_option(options, 'ost')
1400 mds_name = get_option(options, 'mds')
1402 mds_name = get_option(options, 'lmv')
1404 error("--add mtpt requires either --mds or --lmv.")
1407 error("--add mtpt requires --lov lov_name or --ost ost_name")
1409 warning("use default value for lov, due no --lov lov_name provided")
1410 lov_name = new_name("lov_default")
1411 add_default_lov(gen, lustre, mds_name, lov_name)
1412 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1414 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1415 lov = findByName(lustre, lov_name, "lov")
1416 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1419 mgmt_name = get_option(options, 'mgmt')
1420 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1422 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1424 name = new_name('MNT_'+ node_name)
1426 ret = findByName(lustre, name, "mountpoint")
1428 # this can't happen, because new_name creates unique names
1429 error("MOUNTPOINT: ", name, " already exists.")
1431 uuid = new_uuid(name)
1432 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
1433 node = findByName(lustre, node_name, "node")
1435 error('node:', node_name, "not found.")
1436 node_add_profile(gen, node, "mountpoint", uuid)
1437 lustre.appendChild(mtpt)
1439 def commit_version(gen, lustre):
1440 update = findLastUpdate(lustre)
1442 version = int(update.getAttribute("version")) + 1
1446 new = gen.update(str(version))
1447 lustre.appendChild(new)
1450 ############################################################
1451 # Command line processing
1453 class OptionError (exceptions.Exception):
1454 def __init__(self, args):
1457 def get_option(options, tag):
1458 """Look for tag in options hash and return the value if set. If not
1459 set, then if return default it is set, otherwise exception."""
1460 if options.__getattr__(tag) != None:
1461 return options.__getattr__(tag)
1463 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1465 def get_option_int(options, tag):
1466 """Return an integer option. Raise exception if the value is not an int"""
1467 val = get_option(options, tag)
1471 raise OptionError("--%s <num> (value must be integer)" % (tag))
1474 # simple class for profiling
1481 self._start = time.time()
1482 def stop(self, msg=''):
1483 self._stop = time.time()
1487 return self._stop - self._start
1488 def display(self, msg):
1490 str = '%s: %g secs' % (msg, d)
1493 #################################################################
1494 # function cmdlinesplit used to split cmd line from batch file
1496 def cmdlinesplit(cmdline):
1498 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1499 single_quote = re.compile(r"'(.*?)'")
1500 escaped = re.compile(r'\\(.)')
1501 esc_quote = re.compile(r'\\([\\"])')
1502 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1506 while i < len(cmdline):
1509 match = double_quote.match(cmdline, i)
1511 print "Unmatched double quote:", cmdline
1514 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1515 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1518 match = single_quote.match(cmdline, i)
1520 print "Unmatched single quote:", cmdline
1523 if arg is None: arg = match.group(1)
1524 else: arg = arg + match.group(1)
1527 match = escaped.match(cmdline, i)
1529 print "Unmatched backslash", cmdline
1532 if arg is None: arg = match.group(1)
1533 else: arg = arg + match.group(1)
1535 elif c in string.whitespace:
1537 arg_list.append(str(arg))
1539 while i < len(cmdline) and cmdline[i] in string.whitespace:
1542 match = outside.match(cmdline, i)
1545 if arg is None: arg = match.group()
1546 else: arg = arg + match.group()
1548 if arg != None: arg_list.append(str(arg))
1552 ############################################################
1556 def add(devtype, gen, lustre, options):
1557 if devtype == 'net':
1558 add_net(gen, lustre, options)
1559 elif devtype == 'mtpt':
1560 add_mtpt(gen, lustre, options)
1561 elif devtype == 'mds':
1562 add_mds(gen, lustre, options)
1563 elif devtype == 'ost':
1564 add_ost(gen, lustre, options)
1565 elif devtype == 'lov':
1566 add_lov(gen, lustre, options)
1567 elif devtype == 'route':
1568 add_route(gen, lustre, options)
1569 elif devtype == 'node':
1570 add_node(gen, lustre, options)
1571 elif devtype == 'echo_client':
1572 add_echo_client(gen, lustre, options)
1573 elif devtype == 'cobd':
1574 add_cobd(gen, lustre, options)
1575 elif devtype == 'cmobd':
1576 add_cmobd(gen, lustre, options)
1577 elif devtype == 'mgmt':
1578 add_mgmt(gen, lustre, options)
1579 elif devtype == 'lmv':
1580 add_lmv(gen, lustre, options)
1582 error("unknown device type:", devtype)
1584 def delete(devtype, gen, lustre, options):
1585 if devtype == 'ost':
1586 del_ost(gen, lustre, options)
1587 elif options.delete:
1588 error("delete not supported for device type:", devtype)
1589 elif options.deactivate:
1590 error("deactivate not supported for device type:", devtype)
1592 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1594 def commit(gen, lustre):
1595 commit_version(gen, lustre)
1597 def do_command(gen, lustre, options, args):
1599 add(options.add, gen, lustre, options)
1600 elif options.delete:
1601 delete(options.delete, gen, lustre, options)
1602 elif options.deactivate:
1603 delete(options.deactivate, gen, lustre, options)
1604 elif options.commit:
1607 error("Missing command")
1610 cl = Lustre.Options("lmc", "", lmc_options)
1612 options, args = cl.parse(sys.argv[1:])
1613 except Lustre.OptionError, e:
1617 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1619 if options.reference:
1626 outFile = options.merge
1627 if os.access(outFile, os.R_OK):
1628 doc = xml.dom.minidom.parse(outFile)
1630 doc = new_lustre(xml.dom.minidom)
1632 doc = xml.dom.minidom.parse(options.input)
1634 doc = new_lustre(xml.dom.minidom)
1637 outFile = options.output
1639 lustre = doc.documentElement
1641 if lustre.tagName != "lustre":
1642 print "Existing config not valid."
1645 gen = GenConfig(doc)
1648 fp = open(options.batch)
1649 batchCommands = fp.readlines()
1651 for cmd in batchCommands:
1653 options, args = cl.parse(cmdlinesplit(cmd))
1654 if options.merge or options.input or options.output:
1655 print "The batchfile should not contain --merge, --input or --output."
1657 do_command(gen, lustre, options, args)
1658 except OptionError, e:
1660 except Lustre.OptionError, e:
1664 do_command(gen, lustre, options, args)
1665 except OptionError, e:
1666 panic(string.join(sys.argv),e)
1667 except Lustre.OptionError, e:
1673 printDoc(doc, open(outFile,"w"))
1675 if __name__ == "__main__":