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
104 --mds_deny_sec flavor[,flavor[...]]
123 --fstype ldiskfs|ext3
124 --backfstype ldiskfs|ext3|tmpfs
127 --osdtype obdecho|obdfilter
129 --mkfsoptions options
130 --mountfsoptions options
132 --ost_deny_sec flavor[,flavor[...]]
142 --add mtpt - Mountpoint
147 --ost ost_name OR --lov lov_name
148 --clientoptions options
156 --gateway_cluster_id nid
157 --target_cluster_id nid
164 --add mgmt - Management/monitoring service
166 --mgmt mgmt_service_name
173 --master_obd obd_name
178 --master_obd obd_name
181 --commit - Close a configuration version, and start a new one
184 PARAM = Lustre.Options.PARAM
185 PARAMLIST = Lustre.Options.PARAMLIST
187 # lmc input/output options
188 ('reference', "Print short reference for commands."),
189 ('verbose,v', "Print system commands as they are run."),
190 ('merge,m', "Append to the specified config file.", PARAM),
191 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
192 ('input,i', "", PARAM),
193 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
197 ('delete', "", PARAM),
198 ('deactivate', "", PARAM),
199 ('commit', "Commit all config changes and start a new version"),
202 ('node', "Add a new node in the cluster configuration.", PARAM),
203 ('timeout', "Set timeout to initiate recovery.", PARAM),
204 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
205 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
206 ('portals_upcall', "Set location of portals upcall script.", PARAM),
207 ('ptldebug', "Set the portals debug level", PARAM),
208 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
211 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib/iib/vib/ra.", PARAM),
212 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
213 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
214 ('hostaddr', "Optional argument to specify the host address.", PARAMLIST),
215 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
218 ('route', "Add a new route for the cluster.", PARAM),
219 ('router', "Optional flag to mark a node as router."),
220 ('gw', "Specify the nid of the gateway for a route.", PARAM),
221 ('gateway_cluster_id', "", PARAM, "0"),
222 ('target_cluster_id', "", PARAM, "0"),
223 ('lo', "For a range route, this is the low value nid.", PARAM),
224 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
226 # servers: mds and ost
227 ('mds', "Specify MDS name.", PARAM,""),
228 ('ost', "Specify the OST name.", PARAM,""),
229 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
230 ('failover', "Enable failover support on OSTs or MDS?"),
231 ('group', "", PARAM),
232 ('dev', "Path of the device on local system.", PARAM,""),
233 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
234 ('size', "Specify the size of the device if needed.", PARAM,"0"),
235 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
236 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
237 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
238 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
239 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
240 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
241 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
242 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
243 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
244 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
245 ('nspath', "Local mount point of server namespace.", PARAM,""),
246 ('mds_mds_sec', "Specify the secure flavor for connection from this mds to other mds.", PARAM, ""),
247 ('mds_oss_sec', "Specify the secure flavor for connection from this mds to ost.", PARAM, ""),
248 ('mds_deny_sec', "Specify the secure flavor which is denied from remote to this mds.", PARAM, ""),
249 ('ost_deny_sec', "Specify the secure flavor which is denied from remote to this ost.", PARAM, ""),
251 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
253 # clients: mountpoint and echo
254 ('echo_client', "", PARAM),
255 ('path', "Specify the mountpoint for Lustre.", PARAM),
256 ('filesystem', "Lustre filesystem name", PARAM,""),
257 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
258 ('mds_sec', "Specify the secure flavor for connection from this client to mds.", PARAM, ""),
259 ('oss_sec', "Specify the secure flavor for connection from this client to ost.", PARAM, ""),
262 ('lov', "Specify LOV name.", PARAM,""),
263 ('index', "Specify index for OBD in LOV target table.", PARAM),
264 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
265 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
266 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
270 ('master_obd', "Specify the real device for the cache obd system.", PARAM),
271 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
272 ('cobd', "Specify COBD name", PARAM),
273 ('cachelmv', "Specify cache lmv name", PARAM, ""),
274 ('masterlmv', "Specify master lmv name", PARAM, ""),
277 ('master_obd', "Specify the master device for the cmobd system.", PARAM),
278 ('cache_obd', "Specify the cache device for the cmobd obd system.", PARAM),
279 ('cmobd', "Specify COBD name", PARAM),
282 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
285 ('lmv', "Specify LMV name.", PARAM,""),
289 msg = string.join(map(str,args))
290 raise OptionError("Error: " + msg)
299 msg = string.join(map(str,args))
300 print "Warning: ", msg
303 # manage names and uuids
304 # need to initialize this by walking tree to ensure
305 # no duplicate names or uuids are created.
306 # this are just place holders for now.
307 # consider changing this to be like OBD-dev-host
311 while names.has_key(ret):
312 ret = "%s_%d" % (base, ctr)
319 ret = "%s_UUID" % (name)
320 if len(ret) > UUID_MAX_LENGTH:
321 ret = ret[-UUID_MAX_LENGTH:]
322 while uuids.has_key(ret):
323 ret = "%s_UUID_%d" % (name, ctr)
325 if len(ret) > UUID_MAX_LENGTH:
326 ret = ret[-UUID_MAX_LENGTH:]
332 ldlm_uuid = 'ldlm_UUID'
335 """Create a new empty lustre document"""
336 # adding ldlm here is a bit of a hack, but one is enough.
337 str = """<lustre version="%s">
338 <ldlm name="%s" uuid="%s"/>
339 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
340 return dom.parseString(str)
346 """initialize auto-name generation tables"""
348 # get all elements that contain a name attribute
349 for n in doc.childNodes:
350 if n.nodeType == n.ELEMENT_NODE:
352 names[getName(n)] = 1
353 uuids[getUUID(n)] = 1
356 def get_format_flag(options):
361 ############################################################
362 # Build config objects using DOM
367 def __init__(self, doc):
370 def ref(self, type, uuid):
371 """ generate <[type]_ref uuidref="[uuid]"/> """
372 tag = "%s_ref" % (type)
373 ref = self.doc.createElement(tag)
374 ref.setAttribute("uuidref", uuid)
377 def dev(self, devname):
378 """ generate <dev devpath="[devname]"/> """
379 tgt = self.doc.createElement('dev')
380 tgt.setAttribute("dev", devname)
383 def newService(self, tag, name, uuid):
384 """ create a new service elmement, which requires name and uuid attributes """
385 new = self.doc.createElement(tag)
386 new.setAttribute("uuid", uuid);
387 new.setAttribute("name", name);
390 def addText(self, node, str):
391 txt = self.doc.createTextNode(str)
392 node.appendChild(txt)
394 def addElement(self, node, tag, str=None):
395 """ create a new element and add it as a child to node. If str is passed,
396 a text node is created for the new element"""
397 new = self.doc.createElement(tag)
399 self.addText(new, str)
400 node.appendChild(new)
403 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
405 """create <network> node"""
406 network = self.newService("network", name, uuid)
407 network.setAttribute("nettype", net);
408 self.addElement(network, "nid", nid)
409 self.addElement(network, "clusterid", cluster_id)
410 for host in hostaddr:
411 self.addElement(network, "hostaddr", host)
413 self.addElement(network, "port", "%d" %(port))
417 def routetbl(self, name, uuid):
418 """create <routetbl> node"""
419 rtbl = self.newService("routetbl", name, uuid)
422 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
423 """ create one entry for the route table """
424 ref = self.doc.createElement('route')
425 ref.setAttribute("type", gw_net_type)
426 ref.setAttribute("gw", gw)
427 ref.setAttribute("gwclusterid", gw_cluster_id)
428 ref.setAttribute("tgtclusterid", tgt_cluster_id)
429 ref.setAttribute("lo", lo)
431 ref.setAttribute("hi", hi)
434 def profile(self, name, uuid):
435 """ create a host """
436 profile = self.newService("profile", name, uuid)
439 def node(self, name, uuid, prof_uuid):
440 """ create a host """
441 node = self.newService("node", name, uuid)
442 node.appendChild(self.ref("profile", prof_uuid))
445 def ldlm(self, name, uuid):
446 """ create a ldlm """
447 ldlm = self.newService("ldlm", name, uuid)
450 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
451 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
452 mkfsoptions="", mountfsoptions="", backfstype="", backdevname="",
454 osd = self.newService("osd", name, uuid)
455 osd.setAttribute('osdtype', osdtype)
456 osd.appendChild(self.ref("target", ost_uuid))
457 osd.appendChild(self.ref("node", node_uuid))
458 osd.appendChild(self.dev(devname))
461 self.addElement(osd, "fstype", fstype)
463 self.addElement(osd, "backfstype", backfstype)
465 self.addElement(osd, "backdevpath", backdevname)
467 dev = self.addElement(osd, "devpath", devname)
468 self.addElement(osd, "autoformat", format)
470 self.addElement(osd, "devsize", "%s" % (dev_size))
472 self.addElement(osd, "journalsize", "%s" % (journal_size))
474 self.addElement(osd, "inodesize", "%s" % (inode_size))
476 self.addElement(osd, "mkfsoptions", mkfsoptions)
478 self.addElement(osd, "mountfsoptions", mountfsoptions)
480 self.addElement(osd, "deny_sec", deny_sec)
482 self.addElement(osd, "nspath", nspath)
485 def cobd(self, name, uuid, master_uuid, cache_uuid):
486 cobd = self.newService("cobd", name, uuid)
487 cobd.appendChild(self.ref("masterobd",master_uuid))
488 cobd.appendChild(self.ref("cacheobd",cache_uuid))
491 def cmobd(self, name, uuid, master_uuid, cache_uuid):
492 cmobd = self.newService("cmobd", name, uuid)
493 cmobd.appendChild(self.ref("masterobd",master_uuid))
494 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
497 def ost(self, name, uuid, osd_uuid, group=""):
498 ost = self.newService("ost", name, uuid)
499 ost.appendChild(self.ref("active", osd_uuid))
501 self.addElement(ost, "group", group)
504 def oss(self, name, uuid):
505 oss = self.newService("oss", name, uuid)
508 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
509 lov = self.newService("lov", name, uuid)
510 lov.appendChild(self.ref("mds", mds_uuid))
511 lov.setAttribute("stripesize", str(stripe_sz))
512 lov.setAttribute("stripecount", str(stripe_cnt))
513 lov.setAttribute("stripepattern", str(pattern))
516 def lov_tgt(self, obd_uuid, lov_uuid, index, generation):
517 tgt = self.doc.createElement('lov_tgt')
518 tgt.setAttribute("uuidref", obd_uuid)
519 tgt.setAttribute("lov_uuid", lov_uuid)
520 tgt.setAttribute("index", index)
521 tgt.setAttribute("generation", generation)
522 tgt.setAttribute("active", '1')
525 def lovconfig(self, name, uuid, lov_uuid):
526 lovconfig = self.newService("lovconfig", name, uuid)
527 lovconfig.appendChild(self.ref("lov", lov_uuid))
530 def lmv_tgt(self, mdt_uuid):
531 tgt = self.doc.createElement('lmv_tgt')
532 tgt.setAttribute("uuidref", mdt_uuid)
535 def lmv(self, name, uuid):
536 lmv = self.newService("lmv", name, uuid)
539 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
540 mds = self.newService("mds", name, uuid)
541 mds.appendChild(self.ref("active", mdd_uuid))
543 self.addElement(mds, "group", group)
546 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
547 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
548 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
549 backdevname="",lmv_uuid="", root_squash="", no_root_squash="",
550 mds_sec="", oss_sec="", deny_sec=""):
551 mdd = self.newService("mdsdev", name, uuid)
552 self.addElement(mdd, "fstype", fstype)
554 self.addElement(mdd, "backfstype", backfstype)
555 dev = self.addElement(mdd, "devpath", devname)
557 self.addElement(mdd, "backdevpath", backdevname)
558 self.addElement(mdd, "autoformat", format)
560 self.addElement(mdd, "devsize", "%s" % (dev_size))
562 self.addElement(mdd, "journalsize", "%s" % (journal_size))
564 self.addElement(mdd, "inodesize", "%s" % (inode_size))
566 self.addElement(mdd, "nspath", nspath)
568 self.addElement(mdd, "mkfsoptions", mkfsoptions)
570 self.addElement(mdd, "mountfsoptions", mountfsoptions)
572 self.addElement(mdd, "root_squash", root_squash)
574 self.addElement(mdd, "no_root_squash", no_root_squash)
576 self.addElement(mdd, "mds_sec", mds_sec)
578 self.addElement(mdd, "oss_sec", oss_sec)
580 self.addElement(mdd, "deny_sec", deny_sec)
581 mdd.appendChild(self.ref("node", node_uuid))
582 mdd.appendChild(self.ref("target", mds_uuid))
584 dev = self.dev(devname)
589 mdd.appendChild(self.ref("lmv", lmv_uuid))
590 self.addElement(mdd, "lmv", lmv_uuid)
594 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
595 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
596 mgmt.appendChild(self.ref("node", node_uuid))
597 # Placeholder until mgmt-service failover.
598 mgmt.appendChild(self.ref("active", mgmt_uuid))
601 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions,
603 mtpt = self.newService("mountpoint", name, uuid)
604 mtpt.appendChild(self.ref("filesystem", fs_uuid))
605 self.addElement(mtpt, "path", path)
607 self.addElement(mtpt, "clientoptions", clientoptions)
609 self.addElement(mtpt, "mds_sec", mds_sec)
611 self.addElement(mtpt, "oss_sec", oss_sec)
614 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
615 fs = self.newService("filesystem", name, uuid)
616 fs.appendChild(self.ref("mds", mds_uuid))
617 fs.appendChild(self.ref("obd", obd_uuid))
619 fs.appendChild(self.ref("mgmt", mgmt_uuid))
622 def echo_client(self, name, uuid, osc_uuid):
623 ec = self.newService("echoclient", name, uuid)
624 ec.appendChild(self.ref("obd", osc_uuid))
627 def update(self, version):
628 new = self.doc.createElement("update")
629 new.setAttribute("version", version)
632 def add(self, lov, ost, index, gen):
633 new = self.doc.createElement("add")
634 new.setAttribute("lov_uuidref", lov)
635 new.setAttribute("ost_uuidref", ost)
636 new.setAttribute("index", index)
637 new.setAttribute("generation", gen)
640 def delete(self, lov, ost, index, gen, options):
642 new = self.doc.createElement("delete")
644 new = self.doc.createElement("deactivate")
645 new.setAttribute("lov_uuidref", lov)
646 new.setAttribute("ost_uuidref", ost)
647 new.setAttribute("index", index)
648 new.setAttribute("generation", gen)
651 ############################################################
652 # Utilities to query a DOM tree
653 # Using this functions we can treat use config information
654 # directly as a database.
656 return n.getAttribute('name')
659 return node.getAttribute('uuid')
661 def findLastUpdate(lustre):
664 for n in lustre.childNodes:
665 if n.nodeType == n.ELEMENT_NODE:
666 if n.nodeName != 'update':
668 tmp = int(n.getAttribute('version'))
670 error('malformed XML: update tag without a version attribute')
671 if tmp != version + 1:
672 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
677 def addUpdate(gen, lustre, node):
678 update = findLastUpdate(lustre)
681 #add_record = update.getElementsByTagName('add')
683 # add_record = gen.add()
684 # update.appendChild(add_record)
686 # add_record = add_record[0]
687 #add_record.appendChild(node)
688 update.appendChild(node)
690 def delUpdate(gen, lustre, node):
691 update = findLastUpdate(lustre)
694 update.appendChild(node)
696 def findByName(lustre, name, tag = ""):
697 for n in lustre.childNodes:
698 if n.nodeType == n.ELEMENT_NODE:
699 if tag and n.nodeName != tag:
701 if getName(n) == name:
704 n = findByName(n, name)
709 def lookup(node, uuid):
710 for n in node.childNodes:
711 if n.nodeType == n.ELEMENT_NODE:
712 if getUUID(n) == uuid:
720 def name2uuid(lustre, name, tag="", fatal=1):
721 ret = findByName(lustre, name, tag)
724 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
729 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
730 for n in lustre.childNodes:
731 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
732 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
736 # XXX: assumes only one network element per node. will fix this
737 # as soon as support for routers is added
738 def get_net_uuid(lustre, node_name):
739 """ get a network uuid for a node_name """
740 node = findByName(lustre, node_name, "node")
742 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
743 net = node.getElementsByTagName('network')
745 return getUUID(net[0])
748 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
749 tgt.setAttribute('uuidref', osc_uuid)
751 gener = int(tgt.getAttribute('generation'))
753 gener = int(tgt.getAttribute('generation')) + 1
754 tgt.setAttribute('generation', str(gener))
755 tgt.setAttribute('active', '1')
756 lov_index = int(tgt.getAttribute('index'))
757 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
761 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
762 lov_name = getName(lov)
763 lov_uuid = getUUID(lov)
765 lov_index = get_option_int(options, 'index')
766 for tgt in lustre.getElementsByTagName('lov_tgt'):
767 if str(lov_index) == tgt.getAttribute('index'):
768 uuidref = tgt.getAttribute('uuidref')
770 raise OptionError("%s --index %d is still in use: %s" %
771 (lov_name, lov_index, uuidref))
772 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
776 for tgt in lustre.getElementsByTagName('lov_tgt'):
777 uuidref = tgt.getAttribute('uuidref')
778 tmp = int(tgt.getAttribute('index'))
779 own_lov_uuid = tgt.getAttribute('lov_uuid')
781 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
782 uuidref = tgt.getAttribute('uuidref')
784 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
786 if own_lov_uuid == lov_uuid:
787 lov_index = lov_index + 1
789 lov.appendChild(gen.lov_tgt(osc_uuid, lov_uuid, str(lov_index), '1'))
790 addUpdate(gen, lustre, gen.add(getUUID(lov), lov_uuid, str(lov_index), '1'))
792 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
793 lov_name = getName(lov)
795 lov_index = get_option_int(options, 'index')
796 for tgt in lustre.getElementsByTagName('lov_tgt'):
797 index = tgt.getAttribute('index')
798 if index == lov_index:
799 uuidref = tgt.getAttribute('uuidref')
800 if uuidref != osc_uuid:
801 raise OptionError("%s --index %d contains %s, not %s" %
802 (lov_name, lov_index, osc_uuid, uuidref))
804 tgt.setAttribute('uuidref', '')
806 # bump the generation just in case...
808 gen = int(tgt.getAttribute('generation'))
810 gen = int(tgt.getAttribute('generation')) + 1
812 tgt.setAttribute('active', '0')
813 tgt.setAttribute('generation', str(gen))
815 raise OptionError("%s --index %d not in use by %s." %
816 (lov_name, lov_index, osc_uuid))
818 for tgt in lustre.getElementsByTagName('lov_tgt'):
819 uuidref = tgt.getAttribute('uuidref')
820 if uuidref == osc_uuid:
821 genera = int(tgt.getAttribute('generation'))
822 delete_rec = gen.delete(getUUID(lov),
823 osc_uuid,tgt.getAttribute('index'),
824 str(genera), options)
825 delUpdate(gen, lustre, delete_rec)
828 tgt.setAttribute('uuidref', '')
829 if not options.migrate:
831 tgt.setAttribute('active', '0')
832 tgt.setAttribute('generation', str(genera))
834 def lmv_add_obd(gen, lmv, mdc_uuid):
835 lmv.appendChild(gen.lmv_tgt(mdc_uuid))
837 def ref_exists(profile, uuid):
838 elist = profile.childNodes
840 if e.nodeType == e.ELEMENT_NODE:
841 ref = e.getAttribute('uuidref')
846 # ensure that uuid is not already in the profile
847 # return true if uuid is added
848 def node_add_profile(gen, node, ref, uuid):
849 refname = "%s_ref" % "profile"
850 ret = node.getElementsByTagName(refname)
852 error('node has no profile ref:', node)
853 prof_uuid = ret[0].getAttribute('uuidref')
854 profile = lookup(node.parentNode, prof_uuid)
856 error("no profile found:", prof_uuid)
857 if ref_exists(profile, uuid):
859 profile.appendChild(gen.ref(ref, uuid))
862 def get_attr(dom_node, attr, default=""):
863 v = dom_node.getAttribute(attr)
868 ############################################################
871 def set_node_options(gen, node, options):
873 node.setAttribute('router', '1')
875 gen.addElement(node, "timeout", get_option(options, 'timeout'))
877 default_upcall = get_option(options, 'upcall')
880 if default_upcall or options.lustre_upcall:
881 if options.lustre_upcall:
882 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
884 gen.addElement(node, 'lustreUpcall', default_upcall)
885 if default_upcall or options.portals_upcall:
886 if options.portals_upcall:
887 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
889 gen.addElement(node, 'portalsUpcall', default_upcall)
891 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
892 if options.subsystem:
893 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
896 def do_add_node(gen, lustre, options, node_name):
897 uuid = new_uuid(node_name)
898 prof_name = new_name("PROFILE_" + node_name)
899 prof_uuid = new_uuid(prof_name)
900 profile = gen.profile(prof_name, prof_uuid)
901 node = gen.node(node_name, uuid, prof_uuid)
902 lustre.appendChild(node)
903 lustre.appendChild(profile)
905 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
906 set_node_options(gen, node, options)
911 def add_node(gen, lustre, options):
912 """ create a node with a network config """
914 node_name = get_option(options, 'node')
915 ret = findByName(lustre, node_name, "node")
917 print "Node:", node_name, "exists."
919 do_add_node(gen, lustre, options, node_name)
922 def add_net(gen, lustre, options):
923 """ create a node with a network config """
925 node_name = get_option(options, 'node')
926 nid = get_option(options, 'nid')
927 cluster_id = get_option(options, 'cluster_id')
928 hostaddr = get_option(options, 'hostaddr')
929 net_type = get_option(options, 'nettype')
931 if net_type in ('tcp','openib','ra'):
932 port = get_option_int(options, 'port')
933 elif net_type in ('elan', 'gm', 'iib', 'vib', 'lo', 'cray_kern_nal'):
936 print "Unknown net_type: ", net_type
939 ret = findByName(lustre, node_name, "node")
941 node = do_add_node(gen, lustre, options, node_name)
944 set_node_options(gen, node, options)
946 net_name = new_name('NET_'+ node_name +'_'+ net_type)
947 net_uuid = new_uuid(net_name)
948 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
950 node_add_profile(gen, node, "network", net_uuid)
953 def add_route(gen, lustre, options):
954 """ create a node with a network config """
956 node_name = get_option(options, 'node')
957 gw_net_type = get_option(options, 'nettype')
958 gw = get_option(options, 'gw')
959 gw_cluster_id = get_option(options, 'gateway_cluster_id')
960 tgt_cluster_id = get_option(options, 'target_cluster_id')
961 lo = get_option(options, 'lo')
962 hi = get_option(options, 'hi')
966 node = findByName(lustre, node_name, "node")
968 error (node_name, " not found.")
970 rlist = node.getElementsByTagName('routetbl')
974 rtbl_name = new_name("RTBL_" + node_name)
975 rtbl_uuid = new_uuid(rtbl_name)
976 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
977 node.appendChild(rtbl)
978 node_add_profile(gen, node, "routetbl", rtbl_uuid)
979 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
982 def add_mds(gen, lustre, options):
983 node_name = get_option(options, 'node')
984 mds_name = get_option(options, 'mds')
986 mds_name = new_name('MDS_'+ node_name)
987 lmv_name = get_option(options, 'lmv')
988 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
989 mdd_uuid = new_uuid(mdd_name)
993 lmv = findByName(lustre, lmv_name, "lmv")
995 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
996 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
998 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
1000 mds_uuid = get_option(options, 'mdsuuid')
1002 if lookup(lustre, mds_uuid):
1003 error("Duplicate MDS UUID:", mds_uuid)
1005 mds_uuid = new_uuid(mds_name)
1006 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
1007 lustre.appendChild(mds)
1009 lmv_add_obd(gen, lmv, mds_uuid)
1011 mds = lookup(lustre, mds_uuid)
1013 if options.failover:
1014 mds.setAttribute('failover', "1")
1016 devname = get_option(options, 'dev')
1017 backdevname = get_option(options, 'backdev')
1018 size = get_option(options, 'size')
1019 fstype = get_option(options, 'fstype')
1020 backfstype = get_option(options, 'backfstype')
1021 journal_size = get_option(options, 'journal_size')
1022 inode_size = get_option(options, 'inode_size')
1023 nspath = get_option(options, 'nspath')
1024 mkfsoptions = get_option(options, 'mkfsoptions')
1025 mountfsoptions = get_option(options, 'mountfsoptions')
1026 root_squash = get_option(options, 'root_squash')
1027 no_root_squash = get_option(options, 'no_root_squash')
1028 mds_sec = get_option(options, 'mds_mds_sec')
1029 oss_sec = get_option(options, 'mds_oss_sec')
1030 deny_sec = get_option(options, 'mds_deny_sec')
1032 node_uuid = name2uuid(lustre, node_name, 'node')
1034 node = findByName(lustre, node_name, "node")
1035 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1036 net_uuid = get_net_uuid(lustre, node_name)
1038 error("NODE: ", node_name, "not found")
1041 mds.appendChild(gen.ref("lmv", lmv_uuid))
1043 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1044 get_format_flag(options), node_uuid, mds_uuid,
1045 size, journal_size, inode_size, nspath, mkfsoptions,
1046 mountfsoptions, backfstype, backdevname,lmv_uuid,
1047 root_squash, no_root_squash, mds_sec, oss_sec, deny_sec)
1048 lustre.appendChild(mdd)
1051 def add_mgmt(gen, lustre, options):
1052 node_name = get_option(options, 'node')
1053 node_uuid = name2uuid(lustre, node_name, 'node')
1054 mgmt_name = get_option(options, 'mgmt')
1056 mgmt_name = new_name('MGMT_' + node_name)
1057 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1059 mgmt_uuid = new_uuid(mgmt_name)
1060 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1061 lustre.appendChild(mgmt)
1063 mgmt = lookup(lustre, mgmt_uuid)
1065 node = findByName(lustre, node_name, "node")
1066 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1068 def add_ost(gen, lustre, options):
1069 node_name = get_option(options, 'node')
1070 lovname = get_option(options, 'lov')
1071 osdtype = get_option(options, 'osdtype')
1073 node_uuid = name2uuid(lustre, node_name, 'node')
1075 if osdtype == 'obdecho':
1087 devname = get_option(options, 'dev') # can be unset for bluearcs
1088 backdevname = get_option(options, 'backdev')
1089 size = get_option(options, 'size')
1090 fstype = get_option(options, 'fstype')
1091 backfstype = get_option(options, 'backfstype')
1092 journal_size = get_option(options, 'journal_size')
1093 inode_size = get_option(options, 'inode_size')
1094 mkfsoptions = get_option(options, 'mkfsoptions')
1095 mountfsoptions = get_option(options, 'mountfsoptions')
1096 deny_sec = get_option(options, 'ost_deny_sec')
1098 nspath = get_option(options, 'nspath')
1100 ostname = get_option(options, 'ost')
1102 ostname = new_name('OST_'+ node_name)
1104 osdname = new_name("OSD_" + ostname + "_" + node_name)
1105 osd_uuid = new_uuid(osdname)
1107 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1109 ost_uuid = get_option(options, 'ostuuid')
1111 if lookup(lustre, ost_uuid):
1112 error("Duplicate OST UUID:", ost_uuid)
1114 ost_uuid = new_uuid(ostname)
1116 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1117 lustre.appendChild(ost)
1119 ost = lookup(lustre, ost_uuid)
1122 lov = findByName(lustre, lovname, "lov")
1124 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1125 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1127 if options.failover:
1128 ost.setAttribute('failover', "1")
1131 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1132 get_format_flag(options), ost_uuid, node_uuid, size,
1133 journal_size, inode_size, nspath, mkfsoptions,
1134 mountfsoptions, backfstype, backdevname, deny_sec)
1136 node = findByName(lustre, node_name, "node")
1138 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1140 ## oss_uuid = new_uuid(ossname)
1141 ## oss = gen.oss(ossname, oss_uuid)
1142 ## lustre.appendChild(oss)
1144 node_add_profile(gen, node, 'osd', osd_uuid)
1145 lustre.appendChild(osd)
1147 def del_ost(gen, lustre, options):
1148 ostname = get_option(options, 'ost')
1150 raise OptionError("del_ost: --ost requires a <ost name>")
1151 ost = findByName(lustre, ostname, "ost")
1153 error('del_ost: ', 'Unable to find ', ostname)
1154 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1156 error('del_ost: ', 'Unable to find uuid for ', ostname)
1157 lovname = get_option(options, 'lov')
1159 lov = findByName(lustre, lovname, "lov")
1161 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1162 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1163 # if the user specified a speficic LOV don't delete the OST itself
1166 # remove OSD references from all LOVs
1167 for n in lustre.getElementsByTagName('lov'):
1168 lov_del_obd(gen, lustre, n, ost_uuid, options)
1169 if not options.migrate:
1172 for osd in lustre.getElementsByTagName('osd'):
1173 if ref_exists(osd, ost_uuid):
1174 osd_uuid = osd.getAttribute('uuid')
1175 # delete all profile references to this OSD
1176 for profile in lustre.getElementsByTagName('profile'):
1177 for osd_ref in profile.getElementsByTagName('osd_ref'):
1178 if osd_uuid == osd_ref.getAttribute('uuidref'):
1179 profile.removeChild(osd_ref)
1180 lustre.removeChild(osd)
1183 lustre.removeChild(ost)
1185 def add_cmobd(gen, lustre, options):
1186 node_name = get_option(options, 'node')
1187 name = get_option(options, 'cmobd')
1188 uuid = new_uuid(name)
1190 master_name = get_option(options, 'master_obd')
1191 cache_name = get_option(options, 'cache_obd')
1193 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1194 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1196 if not master_uuid or not cache_uuid:
1198 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1200 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1202 if not master_uuid or not cache_uuid:
1204 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1206 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1208 if not master_uuid or not cache_uuid:
1210 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1212 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1215 panic("add_cmobd", "cannot find master_uuid by name '" +
1218 panic("add_cmobd", "cannot find cache_uuid by name '" +
1221 node = findByName(lustre, node_name, "node")
1222 node_add_profile(gen, node, "cmobd", uuid)
1224 master_node = lookup(lustre, master_uuid)
1225 cache_node = lookup(lustre, cache_uuid)
1227 panic("cmobd_add", "cannot find master node by its uuid " +
1230 panic("cmobd_add", "cannot find cache node by its uuid " +
1233 active = master_node.getElementsByTagName('active_ref')
1235 active_uuid = active[0].getAttribute('uuidref')
1236 active_node = lookup(lustre, active_uuid)
1237 if not active_node.getElementsByTagName('obdtype'):
1238 gen.addElement(active_node, 'obdtype', 'master')
1240 active = cache_node.getElementsByTagName('active_ref')
1242 active_uuid = active[0].getAttribute('uuidref')
1243 active_node = lookup(lustre, active_uuid)
1244 if not active_node.getElementsByTagName('obdtype'):
1245 gen.addElement(active_node, 'obdtype', 'cache')
1247 cmobd = gen.cmobd(name, uuid, master_uuid, cache_uuid)
1248 lustre.appendChild(cmobd)
1250 def add_cobd(gen, lustre, options):
1251 node_name = get_option(options, 'node')
1252 name = get_option(options, 'cobd')
1253 uuid = new_uuid(name)
1255 master_name = get_option(options, 'master_obd')
1256 cache_name = get_option(options, 'cache_obd')
1259 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1261 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1264 node = lookup(lustre, master_uuid)
1265 rets = node.getElementsByTagName('lov_tgt')
1267 ost_uuid = ret.getAttribute('uuidref')
1268 ost_node = lookup(lustre, ost_uuid)
1269 active = ost_node.getElementsByTagName('active_ref')
1271 osd_uuid = active[0].getAttribute('uuidref')
1272 osd_node = lookup(lustre, osd_uuid)
1273 if not osd_node.getElementsByTagName('obdtype'):
1274 gen.addElement(osd_node, 'obdtype', 'master')
1277 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1278 if not not cache_uuid:
1279 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1282 node = lookup(lustre, cache_uuid)
1283 rets = node.getElementsByTagName('lov_tgt')
1285 ost_uuid = ret.getAttribute('uuidref')
1286 ost_node = lookup(lustre, ost_uuid)
1287 active = ost_node.getElementsByTagName('active_ref')
1289 osd_uuid = active[0].getAttribute('uuidref')
1290 osd_node = lookup(lustre, osd_uuid)
1291 if not osd_node.getElementsByTagName('obdtype'):
1292 gen.addElement(osd_node, 'obdtype', 'cache')
1294 if not master_uuid or not cache_uuid:
1295 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1297 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1300 mds_node = lookup(lustre, master_uuid)
1301 ret = mds_node.getElementsByTagName('active_ref')
1303 mdsdev_uuid = ret[0].getAttribute('uuidref')
1304 mdsdev_node = lookup(lustre, mdsdev_uuid)
1305 if not mdsdev_node.getElementsByTagName('obdtype'):
1306 gen.addElement(mdsdev_node, 'obdtype', 'master')
1308 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1310 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1313 mds_node = lookup(lustre, cache_uuid)
1314 ret = mds_node.getElementsByTagName('active_ref')
1316 mdsdev_uuid = ret[0].getAttribute('uuidref')
1317 mdsdev_node = lookup(lustre, mdsdev_uuid)
1318 if not mdsdev_node.getElementsByTagName('obdtype'):
1319 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1321 if not master_uuid or not cache_uuid:
1322 panic("add_cobd", "cannot find master or cache by names '" +
1323 master_name + "' and '" + cache_name + "'")
1325 node = findByName(lustre, node_name, "node")
1326 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1327 lustre.appendChild(cobd)
1329 def add_echo_client(gen, lustre, options):
1330 """ add an echo client to the profile for this node. """
1331 node_name = get_option(options, 'node')
1332 lov_name = get_option(options, 'ost')
1334 node = findByName(lustre, node_name, 'node')
1336 echoname = new_name('ECHO_'+ node_name)
1337 echo_uuid = new_uuid(echoname)
1338 node_add_profile(gen, node, 'echoclient', echo_uuid)
1340 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1342 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1344 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1345 lustre.appendChild(echo)
1348 def add_lov(gen, lustre, options):
1349 """ create a lov """
1351 lmv_name = get_option(options, 'lmv')
1352 cache_lmv_name = get_option(options, 'cachelmv')
1353 master_lmv_name = get_option(options, 'masterlmv')
1354 lov_orig = get_option(options, 'lov')
1355 name = new_name(lov_orig)
1356 if name != lov_orig:
1357 warning("name:", lov_orig, "already used. using:", name)
1359 mds_name = get_option(options, 'mds')
1360 if not mds_name and not lmv_name and not cache_lmv_name and not master_lmv_name:
1361 error("LOV: MDS or LMV must be specified.");
1363 stripe_sz = get_option_int(options, 'stripe_sz')
1364 stripe_cnt = get_option_int(options, 'stripe_cnt')
1365 pattern = get_option_int(options, 'stripe_pattern')
1366 uuid = new_uuid(name)
1368 ret = findByName(lustre, name, "lov")
1370 error("LOV: ", name, " already exists.")
1373 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1375 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1377 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1378 lustre.appendChild(lov)
1380 # add an lovconfig entry to the active mdsdev profile
1381 lovconfig_name = new_name('LVCFG_' + name)
1382 lovconfig_uuid = new_uuid(lovconfig_name)
1384 mds = findByName(lustre, mds_name, "mds")
1386 panic("add_lov", "can't find MDS '" + mds_name + "'")
1387 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1388 mds.appendChild(gen.ref("client", uuid))
1391 lmv = findByName(lustre, lmv_name, "lmv")
1393 panic("add_lov", "can't find LMV '" + lmv_name + "'")
1394 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1395 lmv.appendChild(gen.ref("client", uuid))
1398 lmv = findByName(lustre, cache_lmv_name, "lmv")
1400 panic("add_lov", "can't find LMV '" + cache_lmv_name + "'")
1401 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1402 lmv.appendChild(gen.ref("client", uuid))
1405 lmv = findByName(lustre, master_lmv_name, "lmv")
1407 panic("add_lov", "can't find LMV '" + master_lmv_name + "'")
1408 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1409 lmv.appendChild(gen.ref("client", uuid))
1411 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1412 lustre.appendChild(lovconfig)
1414 def add_default_lov(gen, lustre, mds_name, lov_name):
1415 """ create a default lov """
1417 stripe_sz = DEFAULT_STRIPE_SZ
1418 stripe_cnt = DEFAULT_STRIPE_CNT
1419 pattern = DEFAULT_STRIPE_PATTERN
1420 uuid = new_uuid(lov_name)
1422 ret = findByName(lustre, lov_name, "lov")
1424 error("LOV: ", lov_name, " already exists.")
1426 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1427 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1428 lustre.appendChild(lov)
1430 # add an lovconfig entry to the active mdsdev profile
1431 lovconfig_name = new_name('LVCFG_' + lov_name)
1432 lovconfig_uuid = new_uuid(lovconfig_name)
1433 mds = findByName(lustre, mds_name)
1434 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1435 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1436 lustre.appendChild(lovconfig)
1438 def add_lmv(gen, lustre, options):
1439 """ create a lmv """
1441 lmv_orig = get_option(options, 'lmv')
1442 name = new_name(lmv_orig)
1443 if name != lmv_orig:
1444 warning("name:", lmv_orig, "already used. using:", name)
1446 uuid = new_uuid(name)
1447 ret = findByName(lustre, name, "lmv")
1449 error("LMV: ", name, " already exists.")
1451 lmv = gen.lmv(name, uuid)
1452 lustre.appendChild(lmv)
1454 def find_client(lustre, mds_uuid, client_uuid):
1455 mds = lookup(lustre, mds_uuid)
1456 clients = mds.getElementsByTagName('client_ref')
1459 for client in clients:
1460 if client.getAttribute("uuidref") == client_uuid:
1464 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1465 fs_name = new_name("FS_fsname")
1466 fs_uuid = new_uuid(fs_name)
1468 mds = lookup(lustre, mds_uuid)
1469 clients = mds.getElementsByTagName('client_ref')
1471 if find_client(lustre, mds_uuid, obd_uuid) == 0:
1472 mds.appendChild(gen.ref("client", obd_uuid))
1474 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid,
1475 obd_uuid, mgmt_uuid)
1477 lustre.appendChild(fs)
1480 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1481 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1483 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1485 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1487 error("mds '" + mds_name + "' is not found")
1489 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1491 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1493 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1495 error("ost '" + obd_name + "' is not found")
1498 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1502 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1504 fs_uuid = new_filesystem(gen, lustre, mds_uuid,
1505 obd_uuid, mgmt_uuid)
1508 def add_mtpt(gen, lustre, options):
1509 """ create mtpt on a node """
1510 node_name = get_option(options, 'node')
1512 path = get_option(options, 'path')
1513 clientoptions = get_option(options, "clientoptions")
1514 mds_sec = get_option(options, "mds_sec")
1515 oss_sec = get_option(options, "oss_sec")
1516 fs_name = get_option(options, 'filesystem')
1518 lov_name = get_option(options, 'lov')
1519 ost_name = get_option(options, 'ost')
1520 mds_name = get_option(options, 'mds')
1522 mds_name = get_option(options, 'lmv')
1524 error("--add mtpt requires either --mds or --lmv.")
1527 error("--add mtpt requires --lov lov_name or --ost ost_name")
1529 warning("use default value for lov, due no --lov lov_name provided")
1530 lov_name = new_name("lov_default")
1531 add_default_lov(gen, lustre, mds_name, lov_name)
1532 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1534 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1535 lov = findByName(lustre, lov_name, "lov")
1536 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1539 mgmt_name = get_option(options, 'mgmt')
1540 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1542 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1544 name = new_name('MNT_'+ node_name)
1546 ret = findByName(lustre, name, "mountpoint")
1548 # this can't happen, because new_name creates unique names
1549 error("MOUNTPOINT: ", name, " already exists.")
1551 uuid = new_uuid(name)
1552 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions, mds_sec, oss_sec)
1553 node = findByName(lustre, node_name, "node")
1555 error('node:', node_name, "not found.")
1556 node_add_profile(gen, node, "mountpoint", uuid)
1557 lustre.appendChild(mtpt)
1559 def commit_version(gen, lustre):
1560 update = findLastUpdate(lustre)
1562 version = int(update.getAttribute("version")) + 1
1566 new = gen.update(str(version))
1567 lustre.appendChild(new)
1570 ############################################################
1571 # Command line processing
1573 class OptionError (exceptions.Exception):
1574 def __init__(self, args):
1577 def get_option(options, tag):
1578 """Look for tag in options hash and return the value if set. If not
1579 set, then if return default it is set, otherwise exception."""
1580 if options.__getattr__(tag) != None:
1581 return options.__getattr__(tag)
1583 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1585 def get_option_int(options, tag):
1586 """Return an integer option. Raise exception if the value is not an int"""
1587 val = get_option(options, tag)
1591 raise OptionError("--%s <num> (value must be integer)" % (tag))
1594 # simple class for profiling
1601 self._start = time.time()
1602 def stop(self, msg=''):
1603 self._stop = time.time()
1607 return self._stop - self._start
1608 def display(self, msg):
1610 str = '%s: %g secs' % (msg, d)
1613 #################################################################
1614 # function cmdlinesplit used to split cmd line from batch file
1616 def cmdlinesplit(cmdline):
1618 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1619 single_quote = re.compile(r"'(.*?)'")
1620 escaped = re.compile(r'\\(.)')
1621 esc_quote = re.compile(r'\\([\\"])')
1622 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1626 while i < len(cmdline):
1629 match = double_quote.match(cmdline, i)
1631 print "Unmatched double quote:", cmdline
1634 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1635 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1638 match = single_quote.match(cmdline, i)
1640 print "Unmatched single quote:", cmdline
1643 if arg is None: arg = match.group(1)
1644 else: arg = arg + match.group(1)
1647 match = escaped.match(cmdline, i)
1649 print "Unmatched backslash", cmdline
1652 if arg is None: arg = match.group(1)
1653 else: arg = arg + match.group(1)
1655 elif c in string.whitespace:
1657 arg_list.append(str(arg))
1659 while i < len(cmdline) and cmdline[i] in string.whitespace:
1662 match = outside.match(cmdline, i)
1665 if arg is None: arg = match.group()
1666 else: arg = arg + match.group()
1668 if arg != None: arg_list.append(str(arg))
1672 ############################################################
1676 def add(devtype, gen, lustre, options):
1677 if devtype == 'net':
1678 add_net(gen, lustre, options)
1679 elif devtype == 'mtpt':
1680 add_mtpt(gen, lustre, options)
1681 elif devtype == 'mds':
1682 add_mds(gen, lustre, options)
1683 elif devtype == 'ost':
1684 add_ost(gen, lustre, options)
1685 elif devtype == 'lov':
1686 add_lov(gen, lustre, options)
1687 elif devtype == 'route':
1688 add_route(gen, lustre, options)
1689 elif devtype == 'node':
1690 add_node(gen, lustre, options)
1691 elif devtype == 'echo_client':
1692 add_echo_client(gen, lustre, options)
1693 elif devtype == 'cobd':
1694 add_cobd(gen, lustre, options)
1695 elif devtype == 'cmobd':
1696 add_cmobd(gen, lustre, options)
1697 elif devtype == 'mgmt':
1698 add_mgmt(gen, lustre, options)
1699 elif devtype == 'lmv':
1700 add_lmv(gen, lustre, options)
1702 error("unknown device type:", devtype)
1704 def delete(devtype, gen, lustre, options):
1705 if devtype == 'ost':
1706 del_ost(gen, lustre, options)
1707 elif options.delete:
1708 error("delete not supported for device type:", devtype)
1709 elif options.deactivate:
1710 error("deactivate not supported for device type:", devtype)
1712 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1714 def commit(gen, lustre):
1715 commit_version(gen, lustre)
1717 def do_command(gen, lustre, options, args):
1719 add(options.add, gen, lustre, options)
1720 elif options.delete:
1721 delete(options.delete, gen, lustre, options)
1722 elif options.deactivate:
1723 delete(options.deactivate, gen, lustre, options)
1724 elif options.commit:
1727 error("Missing command")
1730 cl = Lustre.Options("lmc", "", lmc_options)
1732 options, args = cl.parse(sys.argv[1:])
1733 except Lustre.OptionError, e:
1737 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1739 if options.reference:
1746 outFile = options.merge
1747 if os.access(outFile, os.R_OK):
1748 doc = xml.dom.minidom.parse(outFile)
1750 doc = new_lustre(xml.dom.minidom)
1752 doc = xml.dom.minidom.parse(options.input)
1754 doc = new_lustre(xml.dom.minidom)
1757 outFile = options.output
1759 lustre = doc.documentElement
1761 if lustre.tagName != "lustre":
1762 print "Existing config not valid."
1765 gen = GenConfig(doc)
1768 fp = open(options.batch)
1769 batchCommands = fp.readlines()
1771 for cmd in batchCommands:
1773 options, args = cl.parse(cmdlinesplit(cmd))
1774 if options.merge or options.input or options.output:
1775 print "The batchfile should not contain --merge, --input or --output."
1777 do_command(gen, lustre, options, args)
1778 except OptionError, e:
1780 except Lustre.OptionError, e:
1784 do_command(gen, lustre, options, args)
1785 except OptionError, e:
1786 panic(string.join(sys.argv),e)
1787 except Lustre.OptionError, e:
1793 printDoc(doc, open(outFile,"w"))
1795 if __name__ == "__main__":