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|vib|ra
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
167 --master_obd obd_name
172 --master_obd 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/vib/ra.", 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 ('master_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),
261 ('cachelmv', "Specify cache lmv name", PARAM, ""),
262 ('masterlmv', "Specify master lmv name", PARAM, ""),
265 ('master_obd', "Specify the master device for the cmobd system.", PARAM),
266 ('cache_obd', "Specify the cache device for the cmobd obd system.", PARAM),
267 ('cmobd', "Specify COBD name", PARAM),
270 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
273 ('lmv', "Specify LMV name.", PARAM,""),
277 msg = string.join(map(str,args))
278 raise OptionError("Error: " + msg)
287 msg = string.join(map(str,args))
288 print "Warning: ", msg
291 # manage names and uuids
292 # need to initialize this by walking tree to ensure
293 # no duplicate names or uuids are created.
294 # this are just place holders for now.
295 # consider changing this to be like OBD-dev-host
299 while names.has_key(ret):
300 ret = "%s_%d" % (base, ctr)
307 ret = "%s_UUID" % (name)
308 if len(ret) > UUID_MAX_LENGTH:
309 ret = ret[-UUID_MAX_LENGTH:]
310 while uuids.has_key(ret):
311 ret = "%s_UUID_%d" % (name, ctr)
313 if len(ret) > UUID_MAX_LENGTH:
314 ret = ret[-UUID_MAX_LENGTH:]
320 ldlm_uuid = 'ldlm_UUID'
323 """Create a new empty lustre document"""
324 # adding ldlm here is a bit of a hack, but one is enough.
325 str = """<lustre version="%s">
326 <ldlm name="%s" uuid="%s"/>
327 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
328 return dom.parseString(str)
334 """initialize auto-name generation tables"""
336 # get all elements that contain a name attribute
337 for n in doc.childNodes:
338 if n.nodeType == n.ELEMENT_NODE:
340 names[getName(n)] = 1
341 uuids[getUUID(n)] = 1
344 def get_format_flag(options):
349 ############################################################
350 # Build config objects using DOM
355 def __init__(self, doc):
358 def ref(self, type, uuid):
359 """ generate <[type]_ref uuidref="[uuid]"/> """
360 tag = "%s_ref" % (type)
361 ref = self.doc.createElement(tag)
362 ref.setAttribute("uuidref", uuid)
365 def dev(self, devname):
366 """ generate <dev devpath="[devname]"/> """
367 tgt = self.doc.createElement('dev')
368 tgt.setAttribute("dev", devname)
371 def newService(self, tag, name, uuid):
372 """ create a new service elmement, which requires name and uuid attributes """
373 new = self.doc.createElement(tag)
374 new.setAttribute("uuid", uuid);
375 new.setAttribute("name", name);
378 def addText(self, node, str):
379 txt = self.doc.createTextNode(str)
380 node.appendChild(txt)
382 def addElement(self, node, tag, str=None):
383 """ create a new element and add it as a child to node. If str is passed,
384 a text node is created for the new element"""
385 new = self.doc.createElement(tag)
387 self.addText(new, str)
388 node.appendChild(new)
391 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
393 """create <network> node"""
394 network = self.newService("network", name, uuid)
395 network.setAttribute("nettype", net);
396 self.addElement(network, "nid", nid)
397 self.addElement(network, "clusterid", cluster_id)
398 for host in hostaddr:
399 self.addElement(network, "hostaddr", host)
401 self.addElement(network, "port", "%d" %(port))
405 def routetbl(self, name, uuid):
406 """create <routetbl> node"""
407 rtbl = self.newService("routetbl", name, uuid)
410 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
411 """ create one entry for the route table """
412 ref = self.doc.createElement('route')
413 ref.setAttribute("type", gw_net_type)
414 ref.setAttribute("gw", gw)
415 ref.setAttribute("gwclusterid", gw_cluster_id)
416 ref.setAttribute("tgtclusterid", tgt_cluster_id)
417 ref.setAttribute("lo", lo)
419 ref.setAttribute("hi", hi)
422 def profile(self, name, uuid):
423 """ create a host """
424 profile = self.newService("profile", name, uuid)
427 def node(self, name, uuid, prof_uuid):
428 """ create a host """
429 node = self.newService("node", name, uuid)
430 node.appendChild(self.ref("profile", prof_uuid))
433 def ldlm(self, name, uuid):
434 """ create a ldlm """
435 ldlm = self.newService("ldlm", name, uuid)
438 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
439 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
440 mkfsoptions="", mountfsoptions="", backfstype="", backdevname=""):
441 osd = self.newService("osd", name, uuid)
442 osd.setAttribute('osdtype', osdtype)
443 osd.appendChild(self.ref("target", ost_uuid))
444 osd.appendChild(self.ref("node", node_uuid))
445 osd.appendChild(self.dev(devname))
448 self.addElement(osd, "fstype", fstype)
450 self.addElement(osd, "backfstype", backfstype)
452 self.addElement(osd, "backdevpath", backdevname)
454 dev = self.addElement(osd, "devpath", devname)
455 self.addElement(osd, "autoformat", format)
457 self.addElement(osd, "devsize", "%s" % (dev_size))
459 self.addElement(osd, "journalsize", "%s" % (journal_size))
461 self.addElement(osd, "inodesize", "%s" % (inode_size))
463 self.addElement(osd, "mkfsoptions", mkfsoptions)
465 self.addElement(osd, "mountfsoptions", mountfsoptions)
467 self.addElement(osd, "nspath", nspath)
470 def cobd(self, name, uuid, master_uuid, cache_uuid):
471 cobd = self.newService("cobd", name, uuid)
472 cobd.appendChild(self.ref("masterobd",master_uuid))
473 cobd.appendChild(self.ref("cacheobd",cache_uuid))
476 def cmobd(self, name, uuid, master_uuid, cache_uuid):
477 cmobd = self.newService("cmobd", name, uuid)
478 cmobd.appendChild(self.ref("masterobd",master_uuid))
479 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
482 def ost(self, name, uuid, osd_uuid, group=""):
483 ost = self.newService("ost", name, uuid)
484 ost.appendChild(self.ref("active", osd_uuid))
486 self.addElement(ost, "group", group)
489 def oss(self, name, uuid):
490 oss = self.newService("oss", name, uuid)
493 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
494 lov = self.newService("lov", name, uuid)
495 lov.appendChild(self.ref("mds", mds_uuid))
496 lov.setAttribute("stripesize", str(stripe_sz))
497 lov.setAttribute("stripecount", str(stripe_cnt))
498 lov.setAttribute("stripepattern", str(pattern))
501 def lov_tgt(self, obd_uuid, lov_uuid, index, generation):
502 tgt = self.doc.createElement('lov_tgt')
503 tgt.setAttribute("uuidref", obd_uuid)
504 tgt.setAttribute("lov_uuid", lov_uuid)
505 tgt.setAttribute("index", index)
506 tgt.setAttribute("generation", generation)
507 tgt.setAttribute("active", '1')
510 def lovconfig(self, name, uuid, lov_uuid):
511 lovconfig = self.newService("lovconfig", name, uuid)
512 lovconfig.appendChild(self.ref("lov", lov_uuid))
515 def lmv_tgt(self, mdt_uuid):
516 tgt = self.doc.createElement('lmv_tgt')
517 tgt.setAttribute("uuidref", mdt_uuid)
520 def lmv(self, name, uuid):
521 lmv = self.newService("lmv", name, uuid)
524 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
525 mds = self.newService("mds", name, uuid)
526 mds.appendChild(self.ref("active", mdd_uuid))
528 self.addElement(mds, "group", group)
531 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
532 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
533 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
534 backdevname="",lmv_uuid="", root_squash="", no_root_squash=""):
535 mdd = self.newService("mdsdev", name, uuid)
536 self.addElement(mdd, "fstype", fstype)
538 self.addElement(mdd, "backfstype", backfstype)
539 dev = self.addElement(mdd, "devpath", devname)
541 self.addElement(mdd, "backdevpath", backdevname)
542 self.addElement(mdd, "autoformat", format)
544 self.addElement(mdd, "devsize", "%s" % (dev_size))
546 self.addElement(mdd, "journalsize", "%s" % (journal_size))
548 self.addElement(mdd, "inodesize", "%s" % (inode_size))
550 self.addElement(mdd, "nspath", nspath)
552 self.addElement(mdd, "mkfsoptions", mkfsoptions)
554 self.addElement(mdd, "mountfsoptions", mountfsoptions)
556 self.addElement(mdd, "root_squash", root_squash)
558 self.addElement(mdd, "no_root_squash", no_root_squash)
559 mdd.appendChild(self.ref("node", node_uuid))
560 mdd.appendChild(self.ref("target", mds_uuid))
562 dev = self.dev(devname)
567 mdd.appendChild(self.ref("lmv", lmv_uuid))
568 self.addElement(mdd, "lmv", lmv_uuid)
572 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
573 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
574 mgmt.appendChild(self.ref("node", node_uuid))
575 # Placeholder until mgmt-service failover.
576 mgmt.appendChild(self.ref("active", mgmt_uuid))
579 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
580 mtpt = self.newService("mountpoint", name, uuid)
581 mtpt.appendChild(self.ref("filesystem", fs_uuid))
582 self.addElement(mtpt, "path", path)
584 self.addElement(mtpt, "clientoptions", clientoptions)
587 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
588 fs = self.newService("filesystem", name, uuid)
589 fs.appendChild(self.ref("mds", mds_uuid))
590 fs.appendChild(self.ref("obd", obd_uuid))
592 fs.appendChild(self.ref("mgmt", mgmt_uuid))
595 def echo_client(self, name, uuid, osc_uuid):
596 ec = self.newService("echoclient", name, uuid)
597 ec.appendChild(self.ref("obd", osc_uuid))
600 def update(self, version):
601 new = self.doc.createElement("update")
602 new.setAttribute("version", version)
605 def add(self, lov, ost, index, gen):
606 new = self.doc.createElement("add")
607 new.setAttribute("lov_uuidref", lov)
608 new.setAttribute("ost_uuidref", ost)
609 new.setAttribute("index", index)
610 new.setAttribute("generation", gen)
613 def delete(self, lov, ost, index, gen, options):
615 new = self.doc.createElement("delete")
617 new = self.doc.createElement("deactivate")
618 new.setAttribute("lov_uuidref", lov)
619 new.setAttribute("ost_uuidref", ost)
620 new.setAttribute("index", index)
621 new.setAttribute("generation", gen)
624 ############################################################
625 # Utilities to query a DOM tree
626 # Using this functions we can treat use config information
627 # directly as a database.
629 return n.getAttribute('name')
632 return node.getAttribute('uuid')
634 def findLastUpdate(lustre):
637 for n in lustre.childNodes:
638 if n.nodeType == n.ELEMENT_NODE:
639 if n.nodeName != 'update':
641 tmp = int(n.getAttribute('version'))
643 error('malformed XML: update tag without a version attribute')
644 if tmp != version + 1:
645 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
650 def addUpdate(gen, lustre, node):
651 update = findLastUpdate(lustre)
654 #add_record = update.getElementsByTagName('add')
656 # add_record = gen.add()
657 # update.appendChild(add_record)
659 # add_record = add_record[0]
660 #add_record.appendChild(node)
661 update.appendChild(node)
663 def delUpdate(gen, lustre, node):
664 update = findLastUpdate(lustre)
667 update.appendChild(node)
669 def findByName(lustre, name, tag = ""):
670 for n in lustre.childNodes:
671 if n.nodeType == n.ELEMENT_NODE:
672 if tag and n.nodeName != tag:
674 if getName(n) == name:
677 n = findByName(n, name)
682 def lookup(node, uuid):
683 for n in node.childNodes:
684 if n.nodeType == n.ELEMENT_NODE:
685 if getUUID(n) == uuid:
693 def name2uuid(lustre, name, tag="", fatal=1):
694 ret = findByName(lustre, name, tag)
697 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
702 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
703 for n in lustre.childNodes:
704 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
705 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
709 # XXX: assumes only one network element per node. will fix this
710 # as soon as support for routers is added
711 def get_net_uuid(lustre, node_name):
712 """ get a network uuid for a node_name """
713 node = findByName(lustre, node_name, "node")
715 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
716 net = node.getElementsByTagName('network')
718 return getUUID(net[0])
721 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
722 tgt.setAttribute('uuidref', osc_uuid)
724 gener = int(tgt.getAttribute('generation'))
726 gener = int(tgt.getAttribute('generation')) + 1
727 tgt.setAttribute('generation', str(gener))
728 tgt.setAttribute('active', '1')
729 lov_index = int(tgt.getAttribute('index'))
730 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
734 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
735 lov_name = getName(lov)
736 lov_uuid = getUUID(lov)
738 lov_index = get_option_int(options, 'index')
739 for tgt in lustre.getElementsByTagName('lov_tgt'):
740 if str(lov_index) == tgt.getAttribute('index'):
741 uuidref = tgt.getAttribute('uuidref')
743 raise OptionError("%s --index %d is still in use: %s" %
744 (lov_name, lov_index, uuidref))
745 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
749 for tgt in lustre.getElementsByTagName('lov_tgt'):
750 uuidref = tgt.getAttribute('uuidref')
751 tmp = int(tgt.getAttribute('index'))
752 own_lov_uuid = tgt.getAttribute('lov_uuid')
754 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
755 uuidref = tgt.getAttribute('uuidref')
757 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
759 if own_lov_uuid == lov_uuid:
760 lov_index = lov_index + 1
762 lov.appendChild(gen.lov_tgt(osc_uuid, lov_uuid, str(lov_index), '1'))
763 addUpdate(gen, lustre, gen.add(getUUID(lov), lov_uuid, str(lov_index), '1'))
765 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
766 lov_name = getName(lov)
768 lov_index = get_option_int(options, 'index')
769 for tgt in lustre.getElementsByTagName('lov_tgt'):
770 index = tgt.getAttribute('index')
771 if index == lov_index:
772 uuidref = tgt.getAttribute('uuidref')
773 if uuidref != osc_uuid:
774 raise OptionError("%s --index %d contains %s, not %s" %
775 (lov_name, lov_index, osc_uuid, uuidref))
777 tgt.setAttribute('uuidref', '')
779 # bump the generation just in case...
781 gen = int(tgt.getAttribute('generation'))
783 gen = int(tgt.getAttribute('generation')) + 1
785 tgt.setAttribute('active', '0')
786 tgt.setAttribute('generation', str(gen))
788 raise OptionError("%s --index %d not in use by %s." %
789 (lov_name, lov_index, osc_uuid))
791 for tgt in lustre.getElementsByTagName('lov_tgt'):
792 uuidref = tgt.getAttribute('uuidref')
793 if uuidref == osc_uuid:
794 genera = int(tgt.getAttribute('generation'))
795 delete_rec = gen.delete(getUUID(lov),
796 osc_uuid,tgt.getAttribute('index'),
797 str(genera), options)
798 delUpdate(gen, lustre, delete_rec)
801 tgt.setAttribute('uuidref', '')
802 if not options.migrate:
804 tgt.setAttribute('active', '0')
805 tgt.setAttribute('generation', str(genera))
807 def lmv_add_obd(gen, lmv, mdc_uuid):
808 lmv.appendChild(gen.lmv_tgt(mdc_uuid))
810 def ref_exists(profile, uuid):
811 elist = profile.childNodes
813 if e.nodeType == e.ELEMENT_NODE:
814 ref = e.getAttribute('uuidref')
819 # ensure that uuid is not already in the profile
820 # return true if uuid is added
821 def node_add_profile(gen, node, ref, uuid):
822 refname = "%s_ref" % "profile"
823 ret = node.getElementsByTagName(refname)
825 error('node has no profile ref:', node)
826 prof_uuid = ret[0].getAttribute('uuidref')
827 profile = lookup(node.parentNode, prof_uuid)
829 error("no profile found:", prof_uuid)
830 if ref_exists(profile, uuid):
832 profile.appendChild(gen.ref(ref, uuid))
835 def get_attr(dom_node, attr, default=""):
836 v = dom_node.getAttribute(attr)
841 ############################################################
844 def set_node_options(gen, node, options):
846 node.setAttribute('router', '1')
848 gen.addElement(node, "timeout", get_option(options, 'timeout'))
850 default_upcall = get_option(options, 'upcall')
853 if default_upcall or options.lustre_upcall:
854 if options.lustre_upcall:
855 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
857 gen.addElement(node, 'lustreUpcall', default_upcall)
858 if default_upcall or options.portals_upcall:
859 if options.portals_upcall:
860 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
862 gen.addElement(node, 'portalsUpcall', default_upcall)
864 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
865 if options.subsystem:
866 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
869 def do_add_node(gen, lustre, options, node_name):
870 uuid = new_uuid(node_name)
871 prof_name = new_name("PROFILE_" + node_name)
872 prof_uuid = new_uuid(prof_name)
873 profile = gen.profile(prof_name, prof_uuid)
874 node = gen.node(node_name, uuid, prof_uuid)
875 lustre.appendChild(node)
876 lustre.appendChild(profile)
878 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
879 set_node_options(gen, node, options)
884 def add_node(gen, lustre, options):
885 """ create a node with a network config """
887 node_name = get_option(options, 'node')
888 ret = findByName(lustre, node_name, "node")
890 print "Node:", node_name, "exists."
892 do_add_node(gen, lustre, options, node_name)
895 def add_net(gen, lustre, options):
896 """ create a node with a network config """
898 node_name = get_option(options, 'node')
899 nid = get_option(options, 'nid')
900 cluster_id = get_option(options, 'cluster_id')
901 hostaddr = get_option(options, 'hostaddr')
902 net_type = get_option(options, 'nettype')
904 if net_type in ('tcp','openib','ra'):
905 port = get_option_int(options, 'port')
906 elif net_type in ('elan', 'gm', 'iib', 'vib', 'lo', 'cray_kern_nal'):
909 print "Unknown net_type: ", net_type
912 ret = findByName(lustre, node_name, "node")
914 node = do_add_node(gen, lustre, options, node_name)
917 set_node_options(gen, node, options)
919 net_name = new_name('NET_'+ node_name +'_'+ net_type)
920 net_uuid = new_uuid(net_name)
921 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
923 node_add_profile(gen, node, "network", net_uuid)
926 def add_route(gen, lustre, options):
927 """ create a node with a network config """
929 node_name = get_option(options, 'node')
930 gw_net_type = get_option(options, 'nettype')
931 gw = get_option(options, 'gw')
932 gw_cluster_id = get_option(options, 'gateway_cluster_id')
933 tgt_cluster_id = get_option(options, 'target_cluster_id')
934 lo = get_option(options, 'lo')
935 hi = get_option(options, 'hi')
939 node = findByName(lustre, node_name, "node")
941 error (node_name, " not found.")
943 rlist = node.getElementsByTagName('routetbl')
947 rtbl_name = new_name("RTBL_" + node_name)
948 rtbl_uuid = new_uuid(rtbl_name)
949 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
950 node.appendChild(rtbl)
951 node_add_profile(gen, node, "routetbl", rtbl_uuid)
952 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
955 def add_mds(gen, lustre, options):
956 node_name = get_option(options, 'node')
957 mds_name = get_option(options, 'mds')
959 mds_name = new_name('MDS_'+ node_name)
960 lmv_name = get_option(options, 'lmv')
961 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
962 mdd_uuid = new_uuid(mdd_name)
966 lmv = findByName(lustre, lmv_name, "lmv")
968 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
969 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
971 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
973 mds_uuid = get_option(options, 'mdsuuid')
975 if lookup(lustre, mds_uuid):
976 error("Duplicate MDS UUID:", mds_uuid)
978 mds_uuid = new_uuid(mds_name)
979 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
980 lustre.appendChild(mds)
982 lmv_add_obd(gen, lmv, mds_uuid)
984 mds = lookup(lustre, mds_uuid)
987 mds.setAttribute('failover', "1")
989 devname = get_option(options, 'dev')
990 backdevname = get_option(options, 'backdev')
991 size = get_option(options, 'size')
992 fstype = get_option(options, 'fstype')
993 backfstype = get_option(options, 'backfstype')
994 journal_size = get_option(options, 'journal_size')
995 inode_size = get_option(options, 'inode_size')
996 nspath = get_option(options, 'nspath')
997 mkfsoptions = get_option(options, 'mkfsoptions')
998 mountfsoptions = get_option(options, 'mountfsoptions')
999 root_squash = get_option(options, 'root_squash')
1000 no_root_squash = get_option(options, 'no_root_squash')
1002 node_uuid = name2uuid(lustre, node_name, 'node')
1004 node = findByName(lustre, node_name, "node")
1005 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1006 net_uuid = get_net_uuid(lustre, node_name)
1008 error("NODE: ", node_name, "not found")
1011 mds.appendChild(gen.ref("lmv", lmv_uuid))
1013 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1014 get_format_flag(options), node_uuid, mds_uuid,
1015 size, journal_size, inode_size, nspath, mkfsoptions,
1016 mountfsoptions, backfstype, backdevname,lmv_uuid,
1017 root_squash, no_root_squash)
1018 lustre.appendChild(mdd)
1021 def add_mgmt(gen, lustre, options):
1022 node_name = get_option(options, 'node')
1023 node_uuid = name2uuid(lustre, node_name, 'node')
1024 mgmt_name = get_option(options, 'mgmt')
1026 mgmt_name = new_name('MGMT_' + node_name)
1027 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1029 mgmt_uuid = new_uuid(mgmt_name)
1030 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1031 lustre.appendChild(mgmt)
1033 mgmt = lookup(lustre, mgmt_uuid)
1035 node = findByName(lustre, node_name, "node")
1036 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1038 def add_ost(gen, lustre, options):
1039 node_name = get_option(options, 'node')
1040 lovname = get_option(options, 'lov')
1041 osdtype = get_option(options, 'osdtype')
1043 node_uuid = name2uuid(lustre, node_name, 'node')
1045 if osdtype == 'obdecho':
1056 devname = get_option(options, 'dev') # can be unset for bluearcs
1057 backdevname = get_option(options, 'backdev')
1058 size = get_option(options, 'size')
1059 fstype = get_option(options, 'fstype')
1060 backfstype = get_option(options, 'backfstype')
1061 journal_size = get_option(options, 'journal_size')
1062 inode_size = get_option(options, 'inode_size')
1063 mkfsoptions = get_option(options, 'mkfsoptions')
1064 mountfsoptions = get_option(options, 'mountfsoptions')
1066 nspath = get_option(options, 'nspath')
1068 ostname = get_option(options, 'ost')
1070 ostname = new_name('OST_'+ node_name)
1072 osdname = new_name("OSD_" + ostname + "_" + node_name)
1073 osd_uuid = new_uuid(osdname)
1075 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1077 ost_uuid = get_option(options, 'ostuuid')
1079 if lookup(lustre, ost_uuid):
1080 error("Duplicate OST UUID:", ost_uuid)
1082 ost_uuid = new_uuid(ostname)
1084 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1085 lustre.appendChild(ost)
1087 ost = lookup(lustre, ost_uuid)
1090 lov = findByName(lustre, lovname, "lov")
1092 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1093 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1095 if options.failover:
1096 ost.setAttribute('failover', "1")
1099 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1100 get_format_flag(options), ost_uuid, node_uuid, size,
1101 journal_size, inode_size, nspath, mkfsoptions,
1102 mountfsoptions, backfstype, backdevname)
1104 node = findByName(lustre, node_name, "node")
1106 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1108 ## oss_uuid = new_uuid(ossname)
1109 ## oss = gen.oss(ossname, oss_uuid)
1110 ## lustre.appendChild(oss)
1112 node_add_profile(gen, node, 'osd', osd_uuid)
1113 lustre.appendChild(osd)
1115 def del_ost(gen, lustre, options):
1116 ostname = get_option(options, 'ost')
1118 raise OptionError("del_ost: --ost requires a <ost name>")
1119 ost = findByName(lustre, ostname, "ost")
1121 error('del_ost: ', 'Unable to find ', ostname)
1122 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1124 error('del_ost: ', 'Unable to find uuid for ', ostname)
1125 lovname = get_option(options, 'lov')
1127 lov = findByName(lustre, lovname, "lov")
1129 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1130 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1131 # if the user specified a speficic LOV don't delete the OST itself
1134 # remove OSD references from all LOVs
1135 for n in lustre.getElementsByTagName('lov'):
1136 lov_del_obd(gen, lustre, n, ost_uuid, options)
1137 if not options.migrate:
1140 for osd in lustre.getElementsByTagName('osd'):
1141 if ref_exists(osd, ost_uuid):
1142 osd_uuid = osd.getAttribute('uuid')
1143 # delete all profile references to this OSD
1144 for profile in lustre.getElementsByTagName('profile'):
1145 for osd_ref in profile.getElementsByTagName('osd_ref'):
1146 if osd_uuid == osd_ref.getAttribute('uuidref'):
1147 profile.removeChild(osd_ref)
1148 lustre.removeChild(osd)
1151 lustre.removeChild(ost)
1153 def add_cmobd(gen, lustre, options):
1154 node_name = get_option(options, 'node')
1155 name = get_option(options, 'cmobd')
1156 uuid = new_uuid(name)
1158 master_name = get_option(options, 'master_obd')
1159 cache_name = get_option(options, 'cache_obd')
1161 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1162 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1164 if not master_uuid or not cache_uuid:
1166 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1168 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1170 if not master_uuid or not cache_uuid:
1172 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1174 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1176 if not master_uuid or not cache_uuid:
1178 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1180 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1183 panic("add_cmobd", "cannot find master_uuid by name '" +
1186 panic("add_cmobd", "cannot find cache_uuid by name '" +
1189 node = findByName(lustre, node_name, "node")
1190 node_add_profile(gen, node, "cmobd", uuid)
1192 master_node = lookup(lustre, master_uuid)
1193 cache_node = lookup(lustre, cache_uuid)
1195 panic("cmobd_add", "cannot find master node by its uuid " +
1198 panic("cmobd_add", "cannot find cache node by its uuid " +
1201 active = master_node.getElementsByTagName('active_ref')
1203 active_uuid = active[0].getAttribute('uuidref')
1204 active_node = lookup(lustre, active_uuid)
1205 if not active_node.getElementsByTagName('obdtype'):
1206 gen.addElement(active_node, 'obdtype', 'master')
1208 active = cache_node.getElementsByTagName('active_ref')
1210 active_uuid = active[0].getAttribute('uuidref')
1211 active_node = lookup(lustre, active_uuid)
1212 if not active_node.getElementsByTagName('obdtype'):
1213 gen.addElement(active_node, 'obdtype', 'cache')
1215 cmobd = gen.cmobd(name, uuid, master_uuid, cache_uuid)
1216 lustre.appendChild(cmobd)
1218 def add_cobd(gen, lustre, options):
1219 node_name = get_option(options, 'node')
1220 name = get_option(options, 'cobd')
1221 uuid = new_uuid(name)
1223 master_name = get_option(options, 'master_obd')
1224 cache_name = get_option(options, 'cache_obd')
1226 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1227 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1229 if not master_uuid or not cache_uuid:
1230 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1231 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1234 node = lookup(lustre, master_uuid)
1235 rets = node.getElementsByTagName('lov_tgt')
1237 ost_uuid = ret.getAttribute('uuidref')
1238 ost_node = lookup(lustre, ost_uuid)
1239 active = ost_node.getElementsByTagName('active_ref')
1241 osd_uuid = active[0].getAttribute('uuidref')
1242 osd_node = lookup(lustre, osd_uuid)
1243 if not osd_node.getElementsByTagName('obdtype'):
1244 gen.addElement(osd_node, 'obdtype', 'master')
1247 node = lookup(lustre, cache_uuid)
1248 rets = node.getElementsByTagName('lov_tgt')
1250 ost_uuid = ret.getAttribute('uuidref')
1251 ost_node = lookup(lustre, ost_uuid)
1252 active = ost_node.getElementsByTagName('active_ref')
1254 osd_uuid = active[0].getAttribute('uuidref')
1255 osd_node = lookup(lustre, osd_uuid)
1256 if not osd_node.getElementsByTagName('obdtype'):
1257 gen.addElement(osd_node, 'obdtype', 'cache')
1259 if not master_uuid or not cache_uuid:
1260 master_uuid = name2uuid(lustre,master_name, tag='lmv')
1261 cache_uuid = name2uuid(lustre,cache_name, tag='lmv')
1263 mds_node = lookup(lustre, master_uuid)
1264 ret = mds_node.getElementsByTagName('active_ref')
1266 mdsdev_uuid = ret[0].getAttribute('uuidref')
1267 mdsdev_node = lookup(lustre, mdsdev_uuid)
1268 if not mdsdev_node.getElementsByTagName('obdtype'):
1269 gen.addElement(mdsdev_node, 'obdtype', 'master')
1271 mds_node = lookup(lustre, cache_uuid)
1272 ret = mds_node.getElementsByTagName('active_ref')
1274 mdsdev_uuid = ret[0].getAttribute('uuidref')
1275 mdsdev_node = lookup(lustre, mdsdev_uuid)
1276 if not mdsdev_node.getElementsByTagName('obdtype'):
1277 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1279 node = findByName(lustre, node_name, "node")
1280 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1281 lustre.appendChild(cobd)
1283 def add_echo_client(gen, lustre, options):
1284 """ add an echo client to the profile for this node. """
1285 node_name = get_option(options, 'node')
1286 lov_name = get_option(options, 'ost')
1288 node = findByName(lustre, node_name, 'node')
1290 echoname = new_name('ECHO_'+ node_name)
1291 echo_uuid = new_uuid(echoname)
1292 node_add_profile(gen, node, 'echoclient', echo_uuid)
1294 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1296 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1298 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1299 lustre.appendChild(echo)
1302 def add_lov(gen, lustre, options):
1303 """ create a lov """
1305 lmv_name = get_option(options, 'lmv')
1306 cache_lmv_name = get_option(options, 'cachelmv')
1307 master_lmv_name = get_option(options, 'masterlmv')
1308 lov_orig = get_option(options, 'lov')
1309 name = new_name(lov_orig)
1310 if name != lov_orig:
1311 warning("name:", lov_orig, "already used. using:", name)
1313 mds_name = get_option(options, 'mds')
1314 if not mds_name and not lmv_name and not cache_lmv_name and not master_lmv_name:
1315 error("LOV: MDS or LMV must be specified.");
1317 stripe_sz = get_option_int(options, 'stripe_sz')
1318 stripe_cnt = get_option_int(options, 'stripe_cnt')
1319 pattern = get_option_int(options, 'stripe_pattern')
1320 uuid = new_uuid(name)
1322 ret = findByName(lustre, name, "lov")
1324 error("LOV: ", name, " already exists.")
1327 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1329 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1331 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1332 lustre.appendChild(lov)
1334 # add an lovconfig entry to the active mdsdev profile
1335 lovconfig_name = new_name('LVCFG_' + name)
1336 lovconfig_uuid = new_uuid(lovconfig_name)
1338 mds = findByName(lustre, mds_name, "mds")
1339 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1340 mds.appendChild(gen.ref("client", uuid))
1343 lmv = findByName(lustre, lmv_name, "lmv")
1344 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1345 lmv.appendChild(gen.ref("client", uuid))
1349 lmv = findByName(lustre, cache_lmv_name, "lmv")
1350 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1351 lmv.appendChild(gen.ref("client", uuid))
1354 lmv = findByName(lustre, master_lmv_name, "lmv")
1355 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1356 lmv.appendChild(gen.ref("client", uuid))
1358 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1359 lustre.appendChild(lovconfig)
1361 def add_default_lov(gen, lustre, mds_name, lov_name):
1362 """ create a default lov """
1364 stripe_sz = DEFAULT_STRIPE_SZ
1365 stripe_cnt = DEFAULT_STRIPE_CNT
1366 pattern = DEFAULT_STRIPE_PATTERN
1367 uuid = new_uuid(lov_name)
1369 ret = findByName(lustre, lov_name, "lov")
1371 error("LOV: ", lov_name, " already exists.")
1373 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1374 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1375 lustre.appendChild(lov)
1377 # add an lovconfig entry to the active mdsdev profile
1378 lovconfig_name = new_name('LVCFG_' + lov_name)
1379 lovconfig_uuid = new_uuid(lovconfig_name)
1380 mds = findByName(lustre, mds_name)
1381 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1382 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1383 lustre.appendChild(lovconfig)
1385 def add_lmv(gen, lustre, options):
1386 """ create a lmv """
1388 lmv_orig = get_option(options, 'lmv')
1389 name = new_name(lmv_orig)
1390 if name != lmv_orig:
1391 warning("name:", lmv_orig, "already used. using:", name)
1393 uuid = new_uuid(name)
1394 ret = findByName(lustre, name, "lmv")
1396 error("LMV: ", name, " already exists.")
1398 lmv = gen.lmv(name, uuid)
1399 lustre.appendChild(lmv)
1401 def find_client(lustre, mds_uuid, client_uuid):
1402 mds = lookup(lustre, mds_uuid)
1403 clients = mds.getElementsByTagName('client_ref')
1406 for client in clients:
1407 if client.getAttribute("uuidref") == client_uuid:
1411 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1412 fs_name = new_name("FS_fsname")
1413 fs_uuid = new_uuid(fs_name)
1415 mds = lookup(lustre, mds_uuid)
1416 clients = mds.getElementsByTagName('client_ref')
1418 if find_client(lustre, mds_uuid, obd_uuid) == 0:
1419 mds.appendChild(gen.ref("client", obd_uuid))
1421 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid,
1422 obd_uuid, mgmt_uuid)
1424 lustre.appendChild(fs)
1427 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1428 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1430 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1432 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1434 error("mds '" + mds_name + "' is not found")
1436 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1438 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1440 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1442 error("ost '" + obd_name + "' is not found")
1445 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1449 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1451 fs_uuid = new_filesystem(gen, lustre, mds_uuid,
1452 obd_uuid, mgmt_uuid)
1455 def add_mtpt(gen, lustre, options):
1456 """ create mtpt on a node """
1457 node_name = get_option(options, 'node')
1459 path = get_option(options, 'path')
1460 clientoptions = get_option(options, "clientoptions")
1461 fs_name = get_option(options, 'filesystem')
1463 lov_name = get_option(options, 'lov')
1464 ost_name = get_option(options, 'ost')
1465 mds_name = get_option(options, 'mds')
1467 mds_name = get_option(options, 'lmv')
1469 error("--add mtpt requires either --mds or --lmv.")
1472 error("--add mtpt requires --lov lov_name or --ost ost_name")
1474 warning("use default value for lov, due no --lov lov_name provided")
1475 lov_name = new_name("lov_default")
1476 add_default_lov(gen, lustre, mds_name, lov_name)
1477 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1479 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1480 lov = findByName(lustre, lov_name, "lov")
1481 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1484 mgmt_name = get_option(options, 'mgmt')
1485 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1487 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1489 name = new_name('MNT_'+ node_name)
1491 ret = findByName(lustre, name, "mountpoint")
1493 # this can't happen, because new_name creates unique names
1494 error("MOUNTPOINT: ", name, " already exists.")
1496 uuid = new_uuid(name)
1497 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
1498 node = findByName(lustre, node_name, "node")
1500 error('node:', node_name, "not found.")
1501 node_add_profile(gen, node, "mountpoint", uuid)
1502 lustre.appendChild(mtpt)
1504 def commit_version(gen, lustre):
1505 update = findLastUpdate(lustre)
1507 version = int(update.getAttribute("version")) + 1
1511 new = gen.update(str(version))
1512 lustre.appendChild(new)
1515 ############################################################
1516 # Command line processing
1518 class OptionError (exceptions.Exception):
1519 def __init__(self, args):
1522 def get_option(options, tag):
1523 """Look for tag in options hash and return the value if set. If not
1524 set, then if return default it is set, otherwise exception."""
1525 if options.__getattr__(tag) != None:
1526 return options.__getattr__(tag)
1528 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1530 def get_option_int(options, tag):
1531 """Return an integer option. Raise exception if the value is not an int"""
1532 val = get_option(options, tag)
1536 raise OptionError("--%s <num> (value must be integer)" % (tag))
1539 # simple class for profiling
1546 self._start = time.time()
1547 def stop(self, msg=''):
1548 self._stop = time.time()
1552 return self._stop - self._start
1553 def display(self, msg):
1555 str = '%s: %g secs' % (msg, d)
1558 #################################################################
1559 # function cmdlinesplit used to split cmd line from batch file
1561 def cmdlinesplit(cmdline):
1563 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1564 single_quote = re.compile(r"'(.*?)'")
1565 escaped = re.compile(r'\\(.)')
1566 esc_quote = re.compile(r'\\([\\"])')
1567 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1571 while i < len(cmdline):
1574 match = double_quote.match(cmdline, i)
1576 print "Unmatched double quote:", cmdline
1579 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1580 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1583 match = single_quote.match(cmdline, i)
1585 print "Unmatched single quote:", cmdline
1588 if arg is None: arg = match.group(1)
1589 else: arg = arg + match.group(1)
1592 match = escaped.match(cmdline, i)
1594 print "Unmatched backslash", cmdline
1597 if arg is None: arg = match.group(1)
1598 else: arg = arg + match.group(1)
1600 elif c in string.whitespace:
1602 arg_list.append(str(arg))
1604 while i < len(cmdline) and cmdline[i] in string.whitespace:
1607 match = outside.match(cmdline, i)
1610 if arg is None: arg = match.group()
1611 else: arg = arg + match.group()
1613 if arg != None: arg_list.append(str(arg))
1617 ############################################################
1621 def add(devtype, gen, lustre, options):
1622 if devtype == 'net':
1623 add_net(gen, lustre, options)
1624 elif devtype == 'mtpt':
1625 add_mtpt(gen, lustre, options)
1626 elif devtype == 'mds':
1627 add_mds(gen, lustre, options)
1628 elif devtype == 'ost':
1629 add_ost(gen, lustre, options)
1630 elif devtype == 'lov':
1631 add_lov(gen, lustre, options)
1632 elif devtype == 'route':
1633 add_route(gen, lustre, options)
1634 elif devtype == 'node':
1635 add_node(gen, lustre, options)
1636 elif devtype == 'echo_client':
1637 add_echo_client(gen, lustre, options)
1638 elif devtype == 'cobd':
1639 add_cobd(gen, lustre, options)
1640 elif devtype == 'cmobd':
1641 add_cmobd(gen, lustre, options)
1642 elif devtype == 'mgmt':
1643 add_mgmt(gen, lustre, options)
1644 elif devtype == 'lmv':
1645 add_lmv(gen, lustre, options)
1647 error("unknown device type:", devtype)
1649 def delete(devtype, gen, lustre, options):
1650 if devtype == 'ost':
1651 del_ost(gen, lustre, options)
1652 elif options.delete:
1653 error("delete not supported for device type:", devtype)
1654 elif options.deactivate:
1655 error("deactivate not supported for device type:", devtype)
1657 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1659 def commit(gen, lustre):
1660 commit_version(gen, lustre)
1662 def do_command(gen, lustre, options, args):
1664 add(options.add, gen, lustre, options)
1665 elif options.delete:
1666 delete(options.delete, gen, lustre, options)
1667 elif options.deactivate:
1668 delete(options.deactivate, gen, lustre, options)
1669 elif options.commit:
1672 error("Missing command")
1675 cl = Lustre.Options("lmc", "", lmc_options)
1677 options, args = cl.parse(sys.argv[1:])
1678 except Lustre.OptionError, e:
1682 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1684 if options.reference:
1691 outFile = options.merge
1692 if os.access(outFile, os.R_OK):
1693 doc = xml.dom.minidom.parse(outFile)
1695 doc = new_lustre(xml.dom.minidom)
1697 doc = xml.dom.minidom.parse(options.input)
1699 doc = new_lustre(xml.dom.minidom)
1702 outFile = options.output
1704 lustre = doc.documentElement
1706 if lustre.tagName != "lustre":
1707 print "Existing config not valid."
1710 gen = GenConfig(doc)
1713 fp = open(options.batch)
1714 batchCommands = fp.readlines()
1716 for cmd in batchCommands:
1718 options, args = cl.parse(cmdlinesplit(cmd))
1719 if options.merge or options.input or options.output:
1720 print "The batchfile should not contain --merge, --input or --output."
1722 do_command(gen, lustre, options, args)
1723 except OptionError, e:
1725 except Lustre.OptionError, e:
1729 do_command(gen, lustre, options, args)
1730 except OptionError, e:
1731 panic(string.join(sys.argv),e)
1732 except Lustre.OptionError, e:
1738 printDoc(doc, open(outFile,"w"))
1740 if __name__ == "__main__":