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')
1258 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1259 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1261 if not master_uuid or not cache_uuid:
1262 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1263 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1266 node = lookup(lustre, master_uuid)
1267 rets = node.getElementsByTagName('lov_tgt')
1269 ost_uuid = ret.getAttribute('uuidref')
1270 ost_node = lookup(lustre, ost_uuid)
1271 active = ost_node.getElementsByTagName('active_ref')
1273 osd_uuid = active[0].getAttribute('uuidref')
1274 osd_node = lookup(lustre, osd_uuid)
1275 if not osd_node.getElementsByTagName('obdtype'):
1276 gen.addElement(osd_node, 'obdtype', 'master')
1279 node = lookup(lustre, cache_uuid)
1280 rets = node.getElementsByTagName('lov_tgt')
1282 ost_uuid = ret.getAttribute('uuidref')
1283 ost_node = lookup(lustre, ost_uuid)
1284 active = ost_node.getElementsByTagName('active_ref')
1286 osd_uuid = active[0].getAttribute('uuidref')
1287 osd_node = lookup(lustre, osd_uuid)
1288 if not osd_node.getElementsByTagName('obdtype'):
1289 gen.addElement(osd_node, 'obdtype', 'cache')
1291 if not master_uuid or not cache_uuid:
1292 master_uuid = name2uuid(lustre,master_name, tag='lmv')
1293 cache_uuid = name2uuid(lustre,cache_name, tag='lmv')
1295 mds_node = lookup(lustre, master_uuid)
1296 ret = mds_node.getElementsByTagName('active_ref')
1298 mdsdev_uuid = ret[0].getAttribute('uuidref')
1299 mdsdev_node = lookup(lustre, mdsdev_uuid)
1300 if not mdsdev_node.getElementsByTagName('obdtype'):
1301 gen.addElement(mdsdev_node, 'obdtype', 'master')
1303 mds_node = lookup(lustre, cache_uuid)
1304 ret = mds_node.getElementsByTagName('active_ref')
1306 mdsdev_uuid = ret[0].getAttribute('uuidref')
1307 mdsdev_node = lookup(lustre, mdsdev_uuid)
1308 if not mdsdev_node.getElementsByTagName('obdtype'):
1309 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1311 node = findByName(lustre, node_name, "node")
1312 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1313 lustre.appendChild(cobd)
1315 def add_echo_client(gen, lustre, options):
1316 """ add an echo client to the profile for this node. """
1317 node_name = get_option(options, 'node')
1318 lov_name = get_option(options, 'ost')
1320 node = findByName(lustre, node_name, 'node')
1322 echoname = new_name('ECHO_'+ node_name)
1323 echo_uuid = new_uuid(echoname)
1324 node_add_profile(gen, node, 'echoclient', echo_uuid)
1326 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1328 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1330 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1331 lustre.appendChild(echo)
1334 def add_lov(gen, lustre, options):
1335 """ create a lov """
1337 lmv_name = get_option(options, 'lmv')
1338 cache_lmv_name = get_option(options, 'cachelmv')
1339 master_lmv_name = get_option(options, 'masterlmv')
1340 lov_orig = get_option(options, 'lov')
1341 name = new_name(lov_orig)
1342 if name != lov_orig:
1343 warning("name:", lov_orig, "already used. using:", name)
1345 mds_name = get_option(options, 'mds')
1346 if not mds_name and not lmv_name and not cache_lmv_name and not master_lmv_name:
1347 error("LOV: MDS or LMV must be specified.");
1349 stripe_sz = get_option_int(options, 'stripe_sz')
1350 stripe_cnt = get_option_int(options, 'stripe_cnt')
1351 pattern = get_option_int(options, 'stripe_pattern')
1352 uuid = new_uuid(name)
1354 ret = findByName(lustre, name, "lov")
1356 error("LOV: ", name, " already exists.")
1359 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1361 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1363 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1364 lustre.appendChild(lov)
1366 # add an lovconfig entry to the active mdsdev profile
1367 lovconfig_name = new_name('LVCFG_' + name)
1368 lovconfig_uuid = new_uuid(lovconfig_name)
1370 mds = findByName(lustre, mds_name, "mds")
1371 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1372 mds.appendChild(gen.ref("client", uuid))
1375 lmv = findByName(lustre, lmv_name, "lmv")
1376 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1377 lmv.appendChild(gen.ref("client", uuid))
1381 lmv = findByName(lustre, cache_lmv_name, "lmv")
1382 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1383 lmv.appendChild(gen.ref("client", uuid))
1386 lmv = findByName(lustre, master_lmv_name, "lmv")
1387 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1388 lmv.appendChild(gen.ref("client", uuid))
1390 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1391 lustre.appendChild(lovconfig)
1393 def add_default_lov(gen, lustre, mds_name, lov_name):
1394 """ create a default lov """
1396 stripe_sz = DEFAULT_STRIPE_SZ
1397 stripe_cnt = DEFAULT_STRIPE_CNT
1398 pattern = DEFAULT_STRIPE_PATTERN
1399 uuid = new_uuid(lov_name)
1401 ret = findByName(lustre, lov_name, "lov")
1403 error("LOV: ", lov_name, " already exists.")
1405 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1406 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1407 lustre.appendChild(lov)
1409 # add an lovconfig entry to the active mdsdev profile
1410 lovconfig_name = new_name('LVCFG_' + lov_name)
1411 lovconfig_uuid = new_uuid(lovconfig_name)
1412 mds = findByName(lustre, mds_name)
1413 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1414 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1415 lustre.appendChild(lovconfig)
1417 def add_lmv(gen, lustre, options):
1418 """ create a lmv """
1420 lmv_orig = get_option(options, 'lmv')
1421 name = new_name(lmv_orig)
1422 if name != lmv_orig:
1423 warning("name:", lmv_orig, "already used. using:", name)
1425 uuid = new_uuid(name)
1426 ret = findByName(lustre, name, "lmv")
1428 error("LMV: ", name, " already exists.")
1430 lmv = gen.lmv(name, uuid)
1431 lustre.appendChild(lmv)
1433 def find_client(lustre, mds_uuid, client_uuid):
1434 mds = lookup(lustre, mds_uuid)
1435 clients = mds.getElementsByTagName('client_ref')
1438 for client in clients:
1439 if client.getAttribute("uuidref") == client_uuid:
1443 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
1444 fs_name = new_name("FS_fsname")
1445 fs_uuid = new_uuid(fs_name)
1447 mds = lookup(lustre, mds_uuid)
1448 clients = mds.getElementsByTagName('client_ref')
1450 if find_client(lustre, mds_uuid, obd_uuid) == 0:
1451 mds.appendChild(gen.ref("client", obd_uuid))
1453 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid,
1454 obd_uuid, mgmt_uuid)
1456 lustre.appendChild(fs)
1459 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
1460 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1462 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1464 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1466 error("mds '" + mds_name + "' is not found")
1468 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1470 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1472 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1474 error("ost '" + obd_name + "' is not found")
1477 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1481 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1483 fs_uuid = new_filesystem(gen, lustre, mds_uuid,
1484 obd_uuid, mgmt_uuid)
1487 def add_mtpt(gen, lustre, options):
1488 """ create mtpt on a node """
1489 node_name = get_option(options, 'node')
1491 path = get_option(options, 'path')
1492 clientoptions = get_option(options, "clientoptions")
1493 mds_sec = get_option(options, "mds_sec")
1494 oss_sec = get_option(options, "oss_sec")
1495 fs_name = get_option(options, 'filesystem')
1497 lov_name = get_option(options, 'lov')
1498 ost_name = get_option(options, 'ost')
1499 mds_name = get_option(options, 'mds')
1501 mds_name = get_option(options, 'lmv')
1503 error("--add mtpt requires either --mds or --lmv.")
1506 error("--add mtpt requires --lov lov_name or --ost ost_name")
1508 warning("use default value for lov, due no --lov lov_name provided")
1509 lov_name = new_name("lov_default")
1510 add_default_lov(gen, lustre, mds_name, lov_name)
1511 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1513 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1514 lov = findByName(lustre, lov_name, "lov")
1515 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1518 mgmt_name = get_option(options, 'mgmt')
1519 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
1521 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1523 name = new_name('MNT_'+ node_name)
1525 ret = findByName(lustre, name, "mountpoint")
1527 # this can't happen, because new_name creates unique names
1528 error("MOUNTPOINT: ", name, " already exists.")
1530 uuid = new_uuid(name)
1531 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions, mds_sec, oss_sec)
1532 node = findByName(lustre, node_name, "node")
1534 error('node:', node_name, "not found.")
1535 node_add_profile(gen, node, "mountpoint", uuid)
1536 lustre.appendChild(mtpt)
1538 def commit_version(gen, lustre):
1539 update = findLastUpdate(lustre)
1541 version = int(update.getAttribute("version")) + 1
1545 new = gen.update(str(version))
1546 lustre.appendChild(new)
1549 ############################################################
1550 # Command line processing
1552 class OptionError (exceptions.Exception):
1553 def __init__(self, args):
1556 def get_option(options, tag):
1557 """Look for tag in options hash and return the value if set. If not
1558 set, then if return default it is set, otherwise exception."""
1559 if options.__getattr__(tag) != None:
1560 return options.__getattr__(tag)
1562 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1564 def get_option_int(options, tag):
1565 """Return an integer option. Raise exception if the value is not an int"""
1566 val = get_option(options, tag)
1570 raise OptionError("--%s <num> (value must be integer)" % (tag))
1573 # simple class for profiling
1580 self._start = time.time()
1581 def stop(self, msg=''):
1582 self._stop = time.time()
1586 return self._stop - self._start
1587 def display(self, msg):
1589 str = '%s: %g secs' % (msg, d)
1592 #################################################################
1593 # function cmdlinesplit used to split cmd line from batch file
1595 def cmdlinesplit(cmdline):
1597 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1598 single_quote = re.compile(r"'(.*?)'")
1599 escaped = re.compile(r'\\(.)')
1600 esc_quote = re.compile(r'\\([\\"])')
1601 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1605 while i < len(cmdline):
1608 match = double_quote.match(cmdline, i)
1610 print "Unmatched double quote:", cmdline
1613 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1614 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1617 match = single_quote.match(cmdline, i)
1619 print "Unmatched single quote:", cmdline
1622 if arg is None: arg = match.group(1)
1623 else: arg = arg + match.group(1)
1626 match = escaped.match(cmdline, i)
1628 print "Unmatched backslash", cmdline
1631 if arg is None: arg = match.group(1)
1632 else: arg = arg + match.group(1)
1634 elif c in string.whitespace:
1636 arg_list.append(str(arg))
1638 while i < len(cmdline) and cmdline[i] in string.whitespace:
1641 match = outside.match(cmdline, i)
1644 if arg is None: arg = match.group()
1645 else: arg = arg + match.group()
1647 if arg != None: arg_list.append(str(arg))
1651 ############################################################
1655 def add(devtype, gen, lustre, options):
1656 if devtype == 'net':
1657 add_net(gen, lustre, options)
1658 elif devtype == 'mtpt':
1659 add_mtpt(gen, lustre, options)
1660 elif devtype == 'mds':
1661 add_mds(gen, lustre, options)
1662 elif devtype == 'ost':
1663 add_ost(gen, lustre, options)
1664 elif devtype == 'lov':
1665 add_lov(gen, lustre, options)
1666 elif devtype == 'route':
1667 add_route(gen, lustre, options)
1668 elif devtype == 'node':
1669 add_node(gen, lustre, options)
1670 elif devtype == 'echo_client':
1671 add_echo_client(gen, lustre, options)
1672 elif devtype == 'cobd':
1673 add_cobd(gen, lustre, options)
1674 elif devtype == 'cmobd':
1675 add_cmobd(gen, lustre, options)
1676 elif devtype == 'mgmt':
1677 add_mgmt(gen, lustre, options)
1678 elif devtype == 'lmv':
1679 add_lmv(gen, lustre, options)
1681 error("unknown device type:", devtype)
1683 def delete(devtype, gen, lustre, options):
1684 if devtype == 'ost':
1685 del_ost(gen, lustre, options)
1686 elif options.delete:
1687 error("delete not supported for device type:", devtype)
1688 elif options.deactivate:
1689 error("deactivate not supported for device type:", devtype)
1691 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1693 def commit(gen, lustre):
1694 commit_version(gen, lustre)
1696 def do_command(gen, lustre, options, args):
1698 add(options.add, gen, lustre, options)
1699 elif options.delete:
1700 delete(options.delete, gen, lustre, options)
1701 elif options.deactivate:
1702 delete(options.deactivate, gen, lustre, options)
1703 elif options.commit:
1706 error("Missing command")
1709 cl = Lustre.Options("lmc", "", lmc_options)
1711 options, args = cl.parse(sys.argv[1:])
1712 except Lustre.OptionError, e:
1716 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1718 if options.reference:
1725 outFile = options.merge
1726 if os.access(outFile, os.R_OK):
1727 doc = xml.dom.minidom.parse(outFile)
1729 doc = new_lustre(xml.dom.minidom)
1731 doc = xml.dom.minidom.parse(options.input)
1733 doc = new_lustre(xml.dom.minidom)
1736 outFile = options.output
1738 lustre = doc.documentElement
1740 if lustre.tagName != "lustre":
1741 print "Existing config not valid."
1744 gen = GenConfig(doc)
1747 fp = open(options.batch)
1748 batchCommands = fp.readlines()
1750 for cmd in batchCommands:
1752 options, args = cl.parse(cmdlinesplit(cmd))
1753 if options.merge or options.input or options.output:
1754 print "The batchfile should not contain --merge, --input or --output."
1756 do_command(gen, lustre, options, args)
1757 except OptionError, e:
1759 except Lustre.OptionError, e:
1763 do_command(gen, lustre, options, args)
1764 except OptionError, e:
1765 panic(string.join(sys.argv),e)
1766 except Lustre.OptionError, e:
1772 printDoc(doc, open(outFile,"w"))
1774 if __name__ == "__main__":