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 configurtion data manager
24 See lustre book for documentation for lmc.
28 import sys, os, getopt, string, exceptions
29 import xml.dom.minidom
30 from xml.dom.ext import PrettyPrint
32 PYMOD_DIR = "/usr/lib/lustre/python"
34 def development_mode():
35 base = os.path.dirname(sys.argv[0])
36 if os.access(base+"/Makefile.am", os.R_OK):
40 if not development_mode():
41 sys.path.append(PYMOD_DIR)
48 print """usage: lmc --add object [object parameters]
50 Object creation command summary:
63 --nettype tcp|elan|toe|gm|scimac
96 --add mtpt - Mountpoint
100 --ost ost_name OR --lov lov_name
103 PARAM = Lustre.Options.PARAM
105 # lmc input/output options
106 ('reference', "Print short reference for commands"),
107 ('verbose,v', "Print system commands as they are run"),
108 ('merge,m', "", PARAM),
109 ('output,o', "", PARAM),
110 ('input,i', "", PARAM),
111 ('batch', "", PARAM),
118 ('timeout', "", PARAM),
119 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
120 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
121 ('portals_upcall', "Set location of portals upcall script.", PARAM),
124 ('nettype', "", PARAM),
126 ('tcpbuf', "", PARAM, 0),
127 ('port', "", PARAM, DEFAULT_PORT),
128 ('nid_exchange', "", PARAM, 0),
129 ('irq_affinity', "", PARAM, 0),
130 ('hostaddr', "", PARAM, ""),
131 ('cluster_id', "", PARAM, "0"),
134 ('route', "", PARAM),
137 ('gw_cluster_id', "", PARAM, "0"),
138 ('target_cluster_id', "", PARAM, "0"),
140 ('hi', "", PARAM, ""),
142 # servers: mds and ost
144 ('ost', "", PARAM, ""),
145 ('osdtype', "", PARAM, "obdfilter"),
147 ('group', "", PARAM),
148 ('dev', "", PARAM, ""),
149 ('size', "", PARAM, 0),
150 ('journal_size', "", PARAM, 0),
151 ('fstype', "", PARAM, "ext3"),
152 ('ostuuid', "", PARAM, ""),
153 ('nspath', "Local mount point of server namespace.", PARAM, ""),
156 # clients: mountpoint and echo
157 ('echo_client', "", PARAM),
159 ('filesystem', "Lustre filesystem name", PARAM, ''),
162 ('lov', "", PARAM, ''),
163 ('stripe_sz', "", PARAM),
164 ('stripe_cnt', "", PARAM, 0),
165 ('stripe_pattern', "", PARAM, 0),
168 ('real_obd', "", PARAM),
169 ('cache_obd', "", PARAM),
173 msg = string.join(map(str,args))
174 raise OptionError("Error: " + msg)
183 msg = string.join(map(str,args))
184 print "Warning: ", msg
187 # manage names and uuids
188 # need to initialize this by walking tree to ensure
189 # no duplicate names or uuids are created.
190 # this are just place holders for now.
191 # consider changing this to be like OBD-dev-host
195 while names.has_key(ret):
196 ret = "%s_%d" % (base, ctr)
202 return "%s_UUID" % (name)
205 ldlm_uuid = 'ldlm_UUID'
208 """Create a new empty lustre document"""
209 # adding ldlm here is a bit of a hack, but one is enough.
210 str = """<lustre version="%s">
211 <ldlm name="%s" uuid="%s"/>
212 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
213 return dom.parseString(str)
219 """initialize auto-name generation tables"""
221 # get all elements that contain a name attribute
222 for n in doc.childNodes:
223 if n.nodeType == n.ELEMENT_NODE:
225 names[getName(n)] = 1
226 uuids[getUUID(n)] = 1
229 def get_format_flag(options):
234 ############################################################
235 # Build config objects using DOM
240 def __init__(self, doc):
243 def ref(self, type, uuid):
244 """ generate <[type]_ref uuidref="[uuid]"/> """
245 tag = "%s_ref" % (type)
246 ref = self.doc.createElement(tag)
247 ref.setAttribute("uuidref", uuid)
250 def newService(self, tag, name, uuid):
251 """ create a new service elmement, which requires name and uuid attributes """
252 new = self.doc.createElement(tag)
253 new.setAttribute("uuid", uuid);
254 new.setAttribute("name", name);
257 def addText(self, node, str):
258 txt = self.doc.createTextNode(str)
259 node.appendChild(txt)
261 def addElement(self, node, tag, str=None):
262 """ create a new element and add it as a child to node. If str is passed,
263 a text node is created for the new element"""
264 new = self.doc.createElement(tag)
266 self.addText(new, str)
267 node.appendChild(new)
270 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
271 port=0, tcpbuf=0, irq_aff=0, nid_xchg=0):
272 """create <network> node"""
273 network = self.newService("network", name, uuid)
274 network.setAttribute("nettype", net);
275 self.addElement(network, "nid", nid)
276 self.addElement(network, "clusterid", cluster_id)
278 self.addElement(network, "hostaddr", hostaddr)
280 self.addElement(network, "port", "%d" %(port))
282 self.addElement(network, "sendmem", "%d" %(tcpbuf))
283 self.addElement(network, "recvmem", "%d" %(tcpbuf))
285 self.addElement(network, "irqaffinity", "%d" %(irq_aff))
287 self.addElement(network, "nidexchange", "%d" %(nid_xchg))
291 def routetbl(self, name, uuid):
292 """create <routetbl> node"""
293 rtbl = self.newService("routetbl", name, uuid)
296 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
297 """ create one entry for the route table """
298 ref = self.doc.createElement('route')
299 ref.setAttribute("type", gw_net_type)
300 ref.setAttribute("gw", gw)
301 ref.setAttribute("gwclusterid", gw_cluster_id)
302 ref.setAttribute("tgtclusterid", tgt_cluster_id)
303 ref.setAttribute("lo", lo)
305 ref.setAttribute("hi", hi)
308 def profile(self, name, uuid):
309 """ create a host """
310 profile = self.newService("profile", name, uuid)
313 def node(self, name, uuid, prof_uuid):
314 """ create a host """
315 node = self.newService("node", name, uuid)
316 node.appendChild(self.ref("profile", prof_uuid))
319 def ldlm(self, name, uuid):
320 """ create a ldlm """
321 ldlm = self.newService("ldlm", name, uuid)
324 def osd(self, name, uuid, fs, osdtype, devname, format, ost_uuid,
325 node_uuid, dev_size=0, journal_size=0, nspath=""):
326 osd = self.newService("osd", name, uuid)
327 osd.setAttribute('osdtype', osdtype)
328 osd.appendChild(self.ref("target", ost_uuid))
329 osd.appendChild(self.ref("node", node_uuid))
331 self.addElement(osd, "fstype", fs)
333 dev = self.addElement(osd, "devpath", devname)
334 self.addElement(osd, "autoformat", format)
336 self.addElement(osd, "devsize", "%s" % (dev_size))
338 self.addElement(osd, "journalsize", "%s" % (journal_size))
340 self.addElement(osd, "nspath", nspath)
343 def cobd(self, name, uuid, real_uuid, cache_uuid):
344 cobd = self.newService("cobd", name, uuid)
345 cobd.appendChild(self.ref("realobd",real_uuid))
346 cobd.appendChild(self.ref("cacheobd",cache_uuid))
349 def ost(self, name, uuid, osd_uuid, group=""):
350 ost = self.newService("ost", name, uuid)
351 ost.appendChild(self.ref("active", osd_uuid))
353 self.addElement(ost, "group", group)
356 def oss(self, name, uuid):
357 oss = self.newService("oss", name, uuid)
360 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
361 lov = self.newService("lov", name, uuid)
362 lov.appendChild(self.ref("mds", mds_uuid))
363 lov.setAttribute("stripesize", str(stripe_sz))
364 lov.setAttribute("stripecount", str(stripe_cnt))
365 lov.setAttribute("stripepattern", str(pattern))
368 def lovconfig(self, name, uuid, lov_uuid):
369 lovconfig = self.newService("lovconfig", name, uuid)
370 lovconfig.appendChild(self.ref("lov", lov_uuid))
373 def mds(self, name, uuid, mdd_uuid, group=""):
374 mds = self.newService("mds", name, uuid)
375 mds.appendChild(self.ref("active",mdd_uuid))
377 self.addElement(mds, "group", group)
380 def mdsdev(self, name, uuid, fs, devname, format, node_uuid,
381 mds_uuid, dev_size=0, journal_size=0, nspath=""):
382 mdd = self.newService("mdsdev", name, uuid)
383 self.addElement(mdd, "fstype", fs)
384 dev = self.addElement(mdd, "devpath", devname)
385 self.addElement(mdd, "autoformat", format)
387 self.addElement(mdd, "devsize", "%s" % (dev_size))
389 self.addElement(mdd, "journalsize", "%s" % (journal_size))
391 self.addElement(mdd, "nspath", nspath)
392 mdd.appendChild(self.ref("node", node_uuid))
393 mdd.appendChild(self.ref("target", mds_uuid))
396 def mountpoint(self, name, uuid, fs_uuid, path):
397 mtpt = self.newService("mountpoint", name, uuid)
398 mtpt.appendChild(self.ref("filesystem", fs_uuid))
399 self.addElement(mtpt, "path", path)
402 def filesystem(self, name, uuid, mds_uuid, obd_uuid):
403 fs = self.newService("filesystem", name, uuid)
404 fs.appendChild(self.ref("mds", mds_uuid))
405 fs.appendChild(self.ref("obd", obd_uuid))
408 def echo_client(self, name, uuid, osc_uuid):
409 ec = self.newService("echoclient", name, uuid)
410 ec.appendChild(self.ref("obd", osc_uuid))
413 ############################################################
414 # Utilities to query a DOM tree
415 # Using this functions we can treat use config information
416 # directly as a database.
418 return n.getAttribute('name')
421 return node.getAttribute('uuid')
424 def findByName(lustre, name, tag = ""):
425 for n in lustre.childNodes:
426 if n.nodeType == n.ELEMENT_NODE:
427 if tag and n.nodeName != tag:
429 if getName(n) == name:
432 n = findByName(n, name)
437 def lookup(node, uuid):
438 for n in node.childNodes:
439 if n.nodeType == n.ELEMENT_NODE:
440 if getUUID(n) == uuid:
448 def name2uuid(lustre, name, tag="", fatal=1):
449 ret = findByName(lustre, name, tag)
452 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
457 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
458 for n in lustre.childNodes:
459 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
460 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
464 # XXX: assumes only one network element per node. will fix this
465 # as soon as support for routers is added
466 def get_net_uuid(lustre, node_name):
467 """ get a network uuid for a node_name """
468 node = findByName(lustre, node_name, "node")
470 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
471 net = node.getElementsByTagName('network')
473 return getUUID(net[0])
477 def lov_add_obd(gen, lov, osc_uuid):
478 lov.appendChild(gen.ref("obd", osc_uuid))
480 def ref_exists(profile, uuid):
481 elist = profile.childNodes
483 if e.nodeType == e.ELEMENT_NODE:
484 ref = e.getAttribute('uuidref')
489 # ensure that uuid is not already in the profile
490 # return true if uuid is added
491 def node_add_profile(gen, node, ref, uuid):
492 refname = "%s_ref" % "profile"
493 ret = node.getElementsByTagName(refname)
495 error('node has no profile ref:', node)
496 prof_uuid = ret[0].getAttribute('uuidref')
497 profile = lookup(node.parentNode, prof_uuid)
499 error("no profile found:", prof_uuid)
500 if ref_exists(profile, uuid):
502 profile.appendChild(gen.ref(ref, uuid))
505 def get_attr(dom_node, attr, default=""):
506 v = dom_node.getAttribute(attr)
511 ############################################################
514 def set_node_options(gen, node, options):
516 node.setAttribute('router', '1')
518 gen.addElement(node, "timeout", get_option(options, 'timeout'))
520 default_upcall = get_option(options, 'upcall')
523 if default_upcall or options.lustre_upcall:
524 if options.lustre_upcall:
525 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
527 gen.addElement(node, 'lustreUpcall', default_upcall)
528 if default_upcall or options.portals_upcall:
529 if options.portals_upcall:
530 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
532 gen.addElement(node, 'portalsUpcall', default_upcall)
535 def do_add_node(gen, lustre, options, node_name):
536 uuid = new_uuid(node_name)
537 prof_name = new_name("PROFILE_" + node_name)
538 prof_uuid = new_uuid(prof_name)
539 profile = gen.profile(prof_name, prof_uuid)
540 node = gen.node(node_name, uuid, prof_uuid)
541 lustre.appendChild(node)
542 lustre.appendChild(profile)
544 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
545 set_node_options(gen, node, options)
549 def add_node(gen, lustre, options):
550 """ create a node with a network config """
552 node_name = get_option(options, 'node')
553 ret = findByName(lustre, node_name, "node")
555 print "Node:", node_name, "exists."
557 do_add_node(gen, lustre, options, node_name)
560 def add_net(gen, lustre, options):
561 """ create a node with a network config """
563 node_name = get_option(options, 'node')
564 nid = get_option(options, 'nid')
565 cluster_id = get_option(options, 'cluster_id')
566 hostaddr = get_option(options, 'hostaddr')
567 net_type = get_option(options, 'nettype')
569 if net_type in ('tcp', 'toe'):
570 port = get_option_int(options, 'port')
571 tcpbuf = get_option_int(options, 'tcpbuf')
572 irq_aff = get_option_int(options, 'irq_affinity')
573 nid_xchg = get_option_int(options, 'nid_exchange')
574 elif net_type in ('elan', 'gm', 'scimac'):
580 print "Unknown net_type: ", net_type
583 ret = findByName(lustre, node_name, "node")
585 node = do_add_node(gen, lustre, options, node_name)
588 set_node_options(gen, node, options)
590 net_name = new_name('NET_'+ node_name +'_'+ net_type)
591 net_uuid = new_uuid(net_name)
592 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
593 hostaddr, port, tcpbuf, irq_aff, nid_xchg))
594 node_add_profile(gen, node, "network", net_uuid)
597 def add_route(gen, lustre, options):
598 """ create a node with a network config """
600 node_name = get_option(options, 'node')
601 gw_net_type = get_option(options, 'nettype')
602 gw = get_option(options, 'gw')
603 gw_cluster_id = get_option(options, 'gw_cluster_id')
604 tgt_cluster_id = get_option(options, 'target_cluster_id')
605 lo = get_option(options, 'lo')
606 hi = get_option(options, 'hi')
610 node = findByName(lustre, node_name, "node")
612 error (node_name, " not found.")
614 rlist = node.getElementsByTagName('routetbl')
618 rtbl_name = new_name("RTBL_" + node_name)
619 rtbl_uuid = new_uuid(rtbl_name)
620 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
621 node.appendChild(rtbl)
622 node_add_profile(gen, node, "routetbl", rtbl_uuid)
623 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
627 def add_mds(gen, lustre, options):
628 node_name = get_option(options, 'node')
629 mds_name = get_option(options, 'mds')
630 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
631 mdd_uuid = new_uuid(mdd_name)
633 mds_uuid = name2uuid(lustre, mds_name, fatal=0)
635 mds_uuid = new_uuid(mds_name)
636 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
637 lustre.appendChild(mds)
639 mds = lookup(lustre, mds_uuid)
641 mds.setAttribute('failover', "1")
643 devname = get_option(options, 'dev')
644 size = get_option(options, 'size')
645 fstype = get_option(options, 'fstype')
646 journal_size = get_option(options, 'journal_size')
647 nspath = get_option(options, 'nspath')
649 node_uuid = name2uuid(lustre, node_name, 'node')
651 node = findByName(lustre, node_name, "node")
652 node_add_profile(gen, node, "mdsdev", mdd_uuid)
653 net_uuid = get_net_uuid(lustre, node_name)
655 error("NODE: ", node_name, "not found")
657 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
658 get_format_flag(options), node_uuid, mds_uuid,
659 size, journal_size, nspath)
660 lustre.appendChild(mdd)
663 def add_ost(gen, lustre, options):
664 node_name = get_option(options, 'node')
665 lovname = get_option(options, 'lov')
666 osdtype = get_option(options, 'osdtype')
668 node_uuid = name2uuid(lustre, node_name)
670 if osdtype == 'obdecho':
677 devname = get_option(options, 'dev') # can be unset for bluearcs
678 size = get_option(options, 'size')
679 fstype = get_option(options, 'fstype')
680 journal_size = get_option(options, 'journal_size')
682 nspath = get_option(options, 'nspath')
684 ostname = get_option(options, 'ost')
686 ostname = new_name('OST_'+ node_name)
688 osdname = new_name("OSD_" + ostname + "_" + node_name)
689 osd_uuid = new_uuid(osdname)
691 ost_uuid = name2uuid(lustre, ostname, fatal=0)
693 ost_uuid = get_option(options, 'ostuuid')
695 if lookup(lustre, ost_uuid):
696 error("Duplicate OST UUID:", ost_uuid)
698 ost_uuid = new_uuid(ostname)
700 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
701 lustre.appendChild(ost)
703 lov = findByName(lustre, lovname, "lov")
705 error('add_ost:', '"'+lovname+'"', "lov element not found.")
706 lov_add_obd(gen, lov, ost_uuid)
708 ost = lookup(lustre, ost_uuid)
711 ost.setAttribute('failover', "1")
714 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
715 get_format_flag(options), ost_uuid, node_uuid, size,
716 journal_size, nspath)
718 node = findByName(lustre, node_name, "node")
720 ## if node_add_profile(gen, node, 'oss', oss_uuid):
722 ## oss_uuid = new_uuid(ossname)
723 ## oss = gen.oss(ossname, oss_uuid)
724 ## lustre.appendChild(oss)
726 node_add_profile(gen, node, 'osd', osd_uuid)
727 lustre.appendChild(osd)
730 def add_cobd(gen, lustre, options):
731 node_name = get_option(options, 'node')
732 name = new_name('COBD_' + node_name)
733 uuid = new_uuid(name)
735 real_name = get_option(options, 'real_obd')
736 cache_name = get_option(options, 'cache_obd')
738 real_uuid = name2uuid(lustre, real_name, tag='obd')
739 cache_uuid = name2uuid(lustre, cache_name, tag='obd')
741 node = findByName(lustre, node_name, "node")
742 node_add_profile(gen, node, "cobd", uuid)
743 cobd = gen.cobd(name, uuid, real_uuid, cache_uuid)
744 lustre.appendChild(cobd)
747 def add_echo_client(gen, lustre, options):
748 """ add an echo client to the profile for this node. """
749 node_name = get_option(options, 'node')
750 lov_name = get_option(options, 'ost')
752 node = findByName(lustre, node_name, 'node')
754 echoname = new_name('ECHO_'+ node_name)
755 echo_uuid = new_uuid(echoname)
756 node_add_profile(gen, node, 'echoclient', echo_uuid)
758 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
760 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
762 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
763 lustre.appendChild(echo)
766 def add_lov(gen, lustre, options):
769 lov_orig = get_option(options, 'lov')
770 name = new_name(lov_orig)
772 warning("name:", lov_orig, "already used. using:", name)
774 mds_name = get_option(options, 'mds')
775 stripe_sz = get_option_int(options, 'stripe_sz')
776 stripe_cnt = get_option_int(options, 'stripe_cnt')
777 pattern = get_option_int(options, 'stripe_pattern')
778 uuid = new_uuid(name)
780 ret = findByName(lustre, name, "lov")
782 error("LOV: ", name, " already exists.")
784 mds_uuid = name2uuid(lustre, mds_name, 'mds')
785 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
786 lustre.appendChild(lov)
788 # add an lovconfig entry to the active mdsdev profile
789 lovconfig_name = new_name('LVCFG_' + name)
790 lovconfig_uuid = new_uuid(lovconfig_name)
791 mds = findByName(lustre, mds_name)
792 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
793 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
794 lustre.appendChild(lovconfig)
796 def new_filesystem(gen, lustre, mds_uuid, obd_uuid):
797 fs_name = new_name("FS_fsname")
798 fs_uuid = new_uuid(fs_name)
799 mds = lookup(lustre, mds_uuid)
800 mds.appendChild(gen.ref("filesystem", fs_uuid))
801 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid)
802 lustre.appendChild(fs)
805 def get_fs_uuid(gen, lustre, mds_name, obd_name):
806 mds_uuid = name2uuid(lustre, mds_name, tag='mds')
807 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
809 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=1)
810 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
812 fs_uuid = new_filesystem(gen, lustre, mds_uuid, obd_uuid)
815 def add_mtpt(gen, lustre, options):
816 """ create mtpt on a node """
817 node_name = get_option(options, 'node')
819 path = get_option(options, 'path')
820 fs_name = get_option(options, 'filesystem')
822 mds_name = get_option(options, 'mds')
823 lov_name = get_option(options, 'lov')
825 lov_name = get_option(options, 'ost')
827 error("--add mtpt requires either --filesystem or --mds with an --lov lov_name or --ost ost_name")
828 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name)
830 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
832 name = new_name('MNT_'+ node_name)
834 ret = findByName(lustre, name, "mountpoint")
836 # this can't happen, because new_name creates unique names
837 error("MOUNTPOINT: ", name, " already exists.")
839 uuid = new_uuid(name)
840 mtpt = gen.mountpoint(name, uuid, fs_uuid, path)
841 node = findByName(lustre, node_name, "node")
843 error('node:', node_name, "not found.")
844 node_add_profile(gen, node, "mountpoint", uuid)
845 lustre.appendChild(mtpt)
847 ############################################################
848 # Command line processing
850 class OptionError (exceptions.Exception):
851 def __init__(self, args):
854 def get_option(options, tag):
855 """Look for tag in options hash and return the value if set. If not
856 set, then if return default it is set, otherwise exception."""
857 if options.__getattr__(tag) != None:
858 return options.__getattr__(tag)
860 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
862 def get_option_int(options, tag):
863 """Return an integer option. Raise exception if the value is not an int"""
864 val = get_option(options, tag)
868 raise OptionError("--%s <num> (value must be integer)" % (tag))
871 # simple class for profiling
878 self._start = time.time()
879 def stop(self, msg=''):
880 self._stop = time.time()
884 return self._stop - self._start
885 def display(self, msg):
887 str = '%s: %g secs' % (msg, d)
890 ############################################################
894 def add(devtype, gen, lustre, options):
896 add_net(gen, lustre, options)
897 elif devtype == 'mtpt':
898 add_mtpt(gen, lustre, options)
899 elif devtype == 'mds':
900 add_mds(gen, lustre, options)
901 elif devtype == 'ost':
902 add_ost(gen, lustre, options)
903 elif devtype == 'lov':
904 add_lov(gen, lustre, options)
905 elif devtype == 'route':
906 add_route(gen, lustre, options)
907 elif devtype == 'node':
908 add_node(gen, lustre, options)
909 elif devtype == 'echo_client':
910 add_echo_client(gen, lustre, options)
911 elif devtype == 'cobd':
912 add_cobd(gen, lustre, options)
914 error("unknown device type:", devtype)
916 def do_command(gen, lustre, options, args):
918 add(options.add, gen, lustre, options)
920 error("Missing command")
923 cl = Lustre.Options("lmc", "", lmc_options)
925 options, args = cl.parse(sys.argv[1:])
926 except Lustre.OptionError, e:
930 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
932 if options.reference:
939 outFile = options.merge
940 if os.access(outFile, os.R_OK):
941 doc = xml.dom.minidom.parse(outFile)
943 doc = new_lustre(xml.dom.minidom)
945 doc = xml.dom.minidom.parse(options.input)
947 doc = new_lustre(xml.dom.minidom)
950 outFile = options.output
952 lustre = doc.documentElement
954 if lustre.tagName != "lustre":
955 print "Existing config not valid."
961 fp = open(options.batch)
962 batchCommands = fp.readlines()
964 for cmd in batchCommands:
966 options, args = cl.parse(string.split(cmd))
967 do_command(gen, lustre, options, args)
968 except OptionError, e:
970 except Lustre.OptionError, e:
974 do_command(gen, lustre, options, args)
975 except OptionError, e:
976 panic(string.join(sys.argv),e)
977 except Lustre.OptionError, e:
983 PrettyPrint(doc, open(outFile,"w"))
985 if __name__ == "__main__":