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]
95 --backfstype ldiskfs|ext3|tmpfs
102 --mkfsoptions options
103 --mountfsoptions options
104 --root_squash uid:gid
105 --no_root_squash ptl_nid
108 --mds_deny_sec flavor[,flavor[...]]
109 --filesystem filesystem name
115 --aware one or few mds/lmv names separated by comma
129 --fstype ldiskfs|ext3
130 --backfstype ldiskfs|ext3|tmpfs
133 --osdtype obdecho|obdfilter
135 --mkfsoptions options
136 --mountfsoptions options
138 --ost_deny_sec flavor[,flavor[...]]
139 --filesystem filesystem name
150 --add mtpt - Mountpoint
155 --ost ost_name OR --lov lov_name
156 --clientoptions options
164 --gateway_cluster_id nid
165 --target_cluster_id nid
172 --add mgmt - Management/monitoring service
174 --mgmt mgmt_service_name
181 --master_obd obd_name
186 --master_obd obd_name
192 --commit - Close a configuration version, and start a new one
195 PARAM = Lustre.Options.PARAM
196 PARAMLIST = Lustre.Options.PARAMLIST
198 # lmc input/output options
199 ('reference', "Print short reference for commands."),
200 ('verbose,v', "Print system commands as they are run."),
201 ('merge,m', "Append to the specified config file.", PARAM),
202 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
203 ('input,i', "", PARAM),
204 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
208 ('delete', "", PARAM),
209 ('deactivate', "", PARAM),
210 ('commit', "Commit all config changes and start a new version"),
213 ('node', "Add a new node in the cluster configuration.", PARAM),
214 ('timeout', "Set timeout to initiate recovery.", PARAM),
215 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
216 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
217 ('portals_upcall', "Set location of portals upcall script.", PARAM),
218 ('ptldebug', "Set the portals debug level", PARAM),
219 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
222 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib/iib/vib/ra.", PARAM),
223 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
224 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
225 ('hostaddr', "Optional argument to specify the host address.", PARAMLIST),
226 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
229 ('route', "Add a new route for the cluster.", PARAM),
230 ('router', "Optional flag to mark a node as router."),
231 ('gw', "Specify the nid of the gateway for a route.", PARAM),
232 ('gateway_cluster_id', "", PARAM, "0"),
233 ('target_cluster_id', "", PARAM, "0"),
234 ('lo', "For a range route, this is the low value nid.", PARAM),
235 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
237 # servers: mds and ost
238 ('mds', "Specify MDS name.", PARAM,""),
239 ('ost', "Specify the OST name.", PARAM,""),
240 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
241 ('failover', "Enable failover support on OSTs or MDS?"),
242 ('group', "", PARAM),
243 ('dev', "Path of the device on local system.", PARAM,""),
244 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
245 ('size', "Specify the size of the device if needed.", PARAM,"0"),
246 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
247 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
248 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
249 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
250 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
251 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
252 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
253 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
254 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
255 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
256 ('nspath', "Local mount point of server namespace.", PARAM,""),
257 ('mds_mds_sec', "Specify the secure flavor for connection from this mds to other mds.", PARAM, ""),
258 ('mds_oss_sec', "Specify the secure flavor for connection from this mds to ost.", PARAM, ""),
259 ('mds_deny_sec', "Specify the secure flavor which is denied from remote to this mds.", PARAM, ""),
260 ('ost_deny_sec', "Specify the secure flavor which is denied from remote to this ost.", PARAM, ""),
261 ('filesystem', "Specify the filesystem name device belong to.", PARAM, ""),
263 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
265 # clients: mountpoint and echo
266 ('echo_client', "", PARAM),
267 ('path', "Specify the mountpoint for Lustre.", PARAM),
268 ('filesystem', "Lustre filesystem name", PARAM,""),
269 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
270 ('mds_sec', "Specify the secure flavor for connection from this client to mds.", PARAM, ""),
271 ('oss_sec', "Specify the secure flavor for connection from this client to ost.", PARAM, ""),
274 ('lov', "Specify LOV name.", PARAM,""),
275 ('mds/lmv', "Specify MDS/LMV name using this LOV.", PARAM,""),
276 ('aware', "Specify MDS/LMV aware of this LOV.", PARAM,""),
277 ('index', "Specify index for OBD in LOV target table.", PARAM),
278 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
279 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
280 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
283 ('master_obd', "Specify the real device for the cache obd system.", PARAM),
284 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
285 ('cobd', "Specify COBD name", PARAM),
288 ('master_obd', "Specify the master device for the cmobd system.", PARAM),
289 ('cache_obd', "Specify the cache device for the cmobd obd system.", PARAM),
290 ('cmobd', "Specify COBD name", PARAM),
292 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
295 ('lmv', "Specify LMV name.", PARAM,""),
298 ('gks', "Specify gks name.", PARAM,""),
303 msg = string.join(map(str,args))
304 raise OptionError("Error: " + msg)
313 msg = string.join(map(str,args))
314 print "Warning: ", msg
317 # manage names and uuids
318 # need to initialize this by walking tree to ensure
319 # no duplicate names or uuids are created.
320 # this are just place holders for now.
321 # consider changing this to be like OBD-dev-host
325 while names.has_key(ret):
326 ret = "%s_%d" % (base, ctr)
333 ret = "%s_UUID" % (name)
334 if len(ret) > UUID_MAX_LENGTH:
335 ret = ret[-UUID_MAX_LENGTH:]
336 while uuids.has_key(ret):
337 ret = "%s_UUID_%d" % (name, ctr)
339 if len(ret) > UUID_MAX_LENGTH:
340 ret = ret[-UUID_MAX_LENGTH:]
346 ldlm_uuid = 'ldlm_UUID'
349 """Create a new empty lustre document"""
350 # adding ldlm here is a bit of a hack, but one is enough.
351 str = """<lustre version="%s">
352 <ldlm name="%s" uuid="%s"/>
353 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
354 return dom.parseString(str)
360 """initialize auto-name generation tables"""
362 # get all elements that contain a name attribute
363 for n in doc.childNodes:
364 if n.nodeType == n.ELEMENT_NODE:
366 names[getName(n)] = 1
367 uuids[getUUID(n)] = 1
370 def get_format_flag(options):
375 ############################################################
376 # Build config objects using DOM
381 def __init__(self, doc):
384 def ref(self, type, uuid):
385 """ generate <[type]_ref uuidref="[uuid]"/> """
386 tag = "%s_ref" % (type)
387 ref = self.doc.createElement(tag)
388 ref.setAttribute("uuidref", uuid)
391 def dev(self, devname):
392 """ generate <dev devpath="[devname]"/> """
393 tgt = self.doc.createElement('dev')
394 tgt.setAttribute("dev", devname)
397 def newService(self, tag, name, uuid):
398 """ create a new service elmement, which requires name and uuid attributes """
399 new = self.doc.createElement(tag)
400 new.setAttribute("uuid", uuid);
401 new.setAttribute("name", name);
404 def addText(self, node, str):
405 txt = self.doc.createTextNode(str)
406 node.appendChild(txt)
408 def addElement(self, node, tag, str=None):
409 """ create a new element and add it as a child to node. If str is passed,
410 a text node is created for the new element"""
411 new = self.doc.createElement(tag)
413 self.addText(new, str)
414 node.appendChild(new)
417 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
419 """create <network> node"""
420 network = self.newService("network", name, uuid)
421 network.setAttribute("nettype", net);
422 self.addElement(network, "nid", nid)
423 self.addElement(network, "clusterid", cluster_id)
424 for host in hostaddr:
425 self.addElement(network, "hostaddr", host)
427 self.addElement(network, "port", "%d" %(port))
431 def routetbl(self, name, uuid):
432 """create <routetbl> node"""
433 rtbl = self.newService("routetbl", name, uuid)
436 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
437 """ create one entry for the route table """
438 ref = self.doc.createElement('route')
439 ref.setAttribute("type", gw_net_type)
440 ref.setAttribute("gw", gw)
441 ref.setAttribute("gwclusterid", gw_cluster_id)
442 ref.setAttribute("tgtclusterid", tgt_cluster_id)
443 ref.setAttribute("lo", lo)
445 ref.setAttribute("hi", hi)
448 def profile(self, name, uuid):
449 """ create a host """
450 profile = self.newService("profile", name, uuid)
453 def node(self, name, uuid, prof_uuid):
454 """ create a host """
455 node = self.newService("node", name, uuid)
456 node.appendChild(self.ref("profile", prof_uuid))
459 def ldlm(self, name, uuid):
460 """ create a ldlm """
461 ldlm = self.newService("ldlm", name, uuid)
464 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
465 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
466 mkfsoptions="", mountfsoptions="", backfstype="", backdevname="",
467 deny_sec="", fs_uuid=""):
468 osd = self.newService("osd", name, uuid)
469 osd.setAttribute('osdtype', osdtype)
470 osd.appendChild(self.ref("target", ost_uuid))
471 osd.appendChild(self.ref("node", node_uuid))
472 osd.appendChild(self.dev(devname))
475 self.addElement(osd, "fstype", fstype)
477 self.addElement(osd, "backfstype", backfstype)
479 self.addElement(osd, "backdevpath", backdevname)
481 dev = self.addElement(osd, "devpath", devname)
482 self.addElement(osd, "autoformat", format)
484 self.addElement(osd, "devsize", "%s" % (dev_size))
486 self.addElement(osd, "journalsize", "%s" % (journal_size))
488 self.addElement(osd, "inodesize", "%s" % (inode_size))
490 self.addElement(osd, "mkfsoptions", mkfsoptions)
492 self.addElement(osd, "mountfsoptions", mountfsoptions)
494 self.addElement(osd, "deny_sec", deny_sec)
496 osd.appendChild(self.ref("filesystem", fs_uuid))
498 self.addElement(osd, "nspath", nspath)
501 def cobd(self, name, uuid, master_uuid, cache_uuid):
502 cobd = self.newService("cobd", name, uuid)
503 cobd.appendChild(self.ref("masterobd",master_uuid))
504 cobd.appendChild(self.ref("cacheobd",cache_uuid))
507 def cmobd(self, name, uuid, master_uuid, cache_uuid):
508 cmobd = self.newService("cmobd", name, uuid)
509 cmobd.appendChild(self.ref("masterobd",master_uuid))
510 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
513 def ost(self, name, uuid, osd_uuid, group=""):
514 ost = self.newService("ost", name, uuid)
515 ost.appendChild(self.ref("active", osd_uuid))
517 self.addElement(ost, "group", group)
520 def oss(self, name, uuid):
521 oss = self.newService("oss", name, uuid)
524 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
525 lov = self.newService("lov", name, uuid)
526 lov.appendChild(self.ref("mds", mds_uuid))
527 lov.setAttribute("stripesize", str(stripe_sz))
528 lov.setAttribute("stripecount", str(stripe_cnt))
529 lov.setAttribute("stripepattern", str(pattern))
532 def lov_tgt(self, obd_uuid, lov_uuid, index, generation):
533 tgt = self.doc.createElement('lov_tgt')
534 tgt.setAttribute("uuidref", obd_uuid)
535 tgt.setAttribute("lov_uuid", lov_uuid)
536 tgt.setAttribute("index", index)
537 tgt.setAttribute("generation", generation)
538 tgt.setAttribute("active", '1')
541 def lovconfig(self, name, uuid, lov_uuid):
542 lovconfig = self.newService("lovconfig", name, uuid)
543 lovconfig.appendChild(self.ref("lov", lov_uuid))
546 def lmv_tgt(self, mdt_uuid):
547 tgt = self.doc.createElement('lmv_tgt')
548 tgt.setAttribute("uuidref", mdt_uuid)
551 def lmv(self, name, uuid):
552 lmv = self.newService("lmv", name, uuid)
555 def gks(self, name, uuid, gkd_uuid):
556 gks = self.newService("gks", name, uuid)
557 gks.appendChild(self.ref("active", gkd_uuid))
560 def gkd(self, name, uuid, node_uuid, gks_uuid):
561 gkd = self.newService("gkd", name, uuid)
562 gkd.appendChild(self.ref("node", node_uuid))
563 gkd.appendChild(self.ref("target", gks_uuid))
566 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
567 mds = self.newService("mds", name, uuid)
568 mds.appendChild(self.ref("active", mdd_uuid))
570 self.addElement(mds, "group", group)
573 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
574 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
575 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
576 backdevname="",lmv_uuid="", root_squash="", no_root_squash="",
577 mds_sec="", oss_sec="", deny_sec="", fs_uuid=""):
578 mdd = self.newService("mdsdev", name, uuid)
579 self.addElement(mdd, "fstype", fstype)
581 self.addElement(mdd, "backfstype", backfstype)
582 dev = self.addElement(mdd, "devpath", devname)
584 self.addElement(mdd, "backdevpath", backdevname)
585 self.addElement(mdd, "autoformat", format)
587 self.addElement(mdd, "devsize", "%s" % (dev_size))
589 self.addElement(mdd, "journalsize", "%s" % (journal_size))
591 self.addElement(mdd, "inodesize", "%s" % (inode_size))
593 self.addElement(mdd, "nspath", nspath)
595 self.addElement(mdd, "mkfsoptions", mkfsoptions)
597 self.addElement(mdd, "mountfsoptions", mountfsoptions)
599 self.addElement(mdd, "root_squash", root_squash)
601 self.addElement(mdd, "no_root_squash", no_root_squash)
603 self.addElement(mdd, "mds_sec", mds_sec)
605 self.addElement(mdd, "oss_sec", oss_sec)
607 self.addElement(mdd, "deny_sec", deny_sec)
609 mdd.appendChild(self.ref("filesystem", fs_uuid))
610 mdd.appendChild(self.ref("node", node_uuid))
611 mdd.appendChild(self.ref("target", mds_uuid))
613 dev = self.dev(devname)
618 mdd.appendChild(self.ref("lmv", lmv_uuid))
622 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
623 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
624 mgmt.appendChild(self.ref("node", node_uuid))
625 # Placeholder until mgmt-service failover.
626 mgmt.appendChild(self.ref("active", mgmt_uuid))
629 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions,
631 mtpt = self.newService("mountpoint", name, uuid)
632 mtpt.appendChild(self.ref("filesystem", fs_uuid))
633 self.addElement(mtpt, "path", path)
635 self.addElement(mtpt, "clientoptions", clientoptions)
637 self.addElement(mtpt, "mds_sec", mds_sec)
639 self.addElement(mtpt, "oss_sec", oss_sec)
642 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid):
643 fs = self.newService("filesystem", name, uuid)
646 fs.appendChild(self.ref("mds", mds_uuid))
648 fs.appendChild(self.ref("obd", obd_uuid))
650 fs.appendChild(self.ref("gks", gks_uuid))
652 fs.appendChild(self.ref("mgmt", mgmt_uuid))
655 def echo_client(self, name, uuid, osc_uuid):
656 ec = self.newService("echoclient", name, uuid)
657 ec.appendChild(self.ref("obd", osc_uuid))
660 def update(self, version):
661 new = self.doc.createElement("update")
662 new.setAttribute("version", version)
665 def add(self, lov, ost, index, gen):
666 new = self.doc.createElement("add")
667 new.setAttribute("lov_uuidref", lov)
668 new.setAttribute("ost_uuidref", ost)
669 new.setAttribute("index", index)
670 new.setAttribute("generation", gen)
673 def delete(self, lov, ost, index, gen, options):
675 new = self.doc.createElement("delete")
677 new = self.doc.createElement("deactivate")
678 new.setAttribute("lov_uuidref", lov)
679 new.setAttribute("ost_uuidref", ost)
680 new.setAttribute("index", index)
681 new.setAttribute("generation", gen)
684 ############################################################
685 # Utilities to query a DOM tree
686 # Using this functions we can treat use config information
687 # directly as a database.
689 return n.getAttribute('name')
692 return node.getAttribute('uuid')
694 def findLastUpdate(lustre):
697 for n in lustre.childNodes:
698 if n.nodeType == n.ELEMENT_NODE:
699 if n.nodeName != 'update':
701 tmp = int(n.getAttribute('version'))
703 error('malformed XML: update tag without a version attribute')
704 if tmp != version + 1:
705 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
710 def addUpdate(gen, lustre, node):
711 update = findLastUpdate(lustre)
714 #add_record = update.getElementsByTagName('add')
716 # add_record = gen.add()
717 # update.appendChild(add_record)
719 # add_record = add_record[0]
720 #add_record.appendChild(node)
721 update.appendChild(node)
723 def delUpdate(gen, lustre, node):
724 update = findLastUpdate(lustre)
727 update.appendChild(node)
729 def findByName(lustre, name, tag = ""):
730 for n in lustre.childNodes:
731 if n.nodeType == n.ELEMENT_NODE:
732 if tag and n.nodeName != tag:
734 if getName(n) == name:
737 n = findByName(n, name)
742 def lookup(node, uuid):
743 for n in node.childNodes:
744 if n.nodeType == n.ELEMENT_NODE:
745 if getUUID(n) == uuid:
753 def name2uuid(lustre, name, tag="", fatal=1):
754 ret = findByName(lustre, name, tag)
757 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
762 def lookup_filesystem(lustre, fs_name):
763 for n in lustre.childNodes:
764 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
765 if getName(n) == fs_name:
769 # XXX: assumes only one network element per node. will fix this
770 # as soon as support for routers is added
771 def get_net_uuid(lustre, node_name):
772 """ get a network uuid for a node_name """
773 node = findByName(lustre, node_name, "node")
775 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
776 net = node.getElementsByTagName('network')
778 return getUUID(net[0])
781 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
782 tgt.setAttribute('uuidref', osc_uuid)
784 gener = int(tgt.getAttribute('generation'))
786 gener = int(tgt.getAttribute('generation')) + 1
787 tgt.setAttribute('generation', str(gener))
788 tgt.setAttribute('active', '1')
789 lov_index = int(tgt.getAttribute('index'))
790 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
794 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
795 lov_name = getName(lov)
796 lov_uuid = getUUID(lov)
798 lov_index = get_option_int(options, 'index')
799 for tgt in lustre.getElementsByTagName('lov_tgt'):
800 if str(lov_index) == tgt.getAttribute('index'):
801 uuidref = tgt.getAttribute('uuidref')
803 raise OptionError("%s --index %d is still in use: %s" %
804 (lov_name, lov_index, uuidref))
805 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
809 for tgt in lustre.getElementsByTagName('lov_tgt'):
810 uuidref = tgt.getAttribute('uuidref')
811 tmp = int(tgt.getAttribute('index'))
812 own_lov_uuid = tgt.getAttribute('lov_uuid')
813 if lov_uuid != own_lov_uuid:
816 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
818 lov_index = lov_index + 1
820 lov.appendChild(gen.lov_tgt(osc_uuid, lov_uuid, str(lov_index), '1'))
821 addUpdate(gen, lustre, gen.add(getUUID(lov), lov_uuid, str(lov_index), '1'))
823 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
824 lov_name = getName(lov)
826 lov_index = get_option_int(options, 'index')
827 for tgt in lustre.getElementsByTagName('lov_tgt'):
828 index = tgt.getAttribute('index')
829 if index == lov_index:
830 uuidref = tgt.getAttribute('uuidref')
831 if uuidref != osc_uuid:
832 raise OptionError("%s --index %d contains %s, not %s" %
833 (lov_name, lov_index, osc_uuid, uuidref))
835 tgt.setAttribute('uuidref', '')
837 # bump the generation just in case...
839 gen = int(tgt.getAttribute('generation'))
841 gen = int(tgt.getAttribute('generation')) + 1
843 tgt.setAttribute('active', '0')
844 tgt.setAttribute('generation', str(gen))
846 raise OptionError("%s --index %d not in use by %s." %
847 (lov_name, lov_index, osc_uuid))
849 for tgt in lustre.getElementsByTagName('lov_tgt'):
850 uuidref = tgt.getAttribute('uuidref')
851 if uuidref == osc_uuid:
852 genera = int(tgt.getAttribute('generation'))
853 delete_rec = gen.delete(getUUID(lov),
854 osc_uuid,tgt.getAttribute('index'),
855 str(genera), options)
856 delUpdate(gen, lustre, delete_rec)
859 tgt.setAttribute('uuidref', '')
860 if not options.migrate:
862 tgt.setAttribute('active', '0')
863 tgt.setAttribute('generation', str(genera))
865 def lmv_add_obd(gen, lmv, mdc_uuid):
866 lmv.appendChild(gen.lmv_tgt(mdc_uuid))
868 def ref_exists(profile, uuid):
869 elist = profile.childNodes
871 if e.nodeType == e.ELEMENT_NODE:
872 ref = e.getAttribute('uuidref')
877 # ensure that uuid is not already in the profile
878 # return true if uuid is added
879 def node_add_profile(gen, node, ref, uuid):
880 refname = "%s_ref" % "profile"
881 ret = node.getElementsByTagName(refname)
883 error('node has no profile ref:', node)
884 prof_uuid = ret[0].getAttribute('uuidref')
885 profile = lookup(node.parentNode, prof_uuid)
887 error("no profile found:", prof_uuid)
888 if ref_exists(profile, uuid):
890 profile.appendChild(gen.ref(ref, uuid))
893 def get_attr(dom_node, attr, default=""):
894 v = dom_node.getAttribute(attr)
899 ############################################################
902 def set_node_options(gen, node, options):
904 node.setAttribute('router', '1')
906 gen.addElement(node, "timeout", get_option(options, 'timeout'))
908 default_upcall = get_option(options, 'upcall')
911 if default_upcall or options.lustre_upcall:
912 if options.lustre_upcall:
913 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
915 gen.addElement(node, 'lustreUpcall', default_upcall)
916 if default_upcall or options.portals_upcall:
917 if options.portals_upcall:
918 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
920 gen.addElement(node, 'portalsUpcall', default_upcall)
922 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
923 if options.subsystem:
924 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
927 def do_add_node(gen, lustre, options, node_name):
928 uuid = new_uuid(node_name)
929 prof_name = new_name("PROFILE_" + node_name)
930 prof_uuid = new_uuid(prof_name)
931 profile = gen.profile(prof_name, prof_uuid)
932 node = gen.node(node_name, uuid, prof_uuid)
933 lustre.appendChild(node)
934 lustre.appendChild(profile)
936 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
937 set_node_options(gen, node, options)
941 def add_node(gen, lustre, options):
942 """ create a node with a network config """
944 node_name = get_option(options, 'node')
945 ret = findByName(lustre, node_name, "node")
947 print "Node:", node_name, "exists."
949 do_add_node(gen, lustre, options, node_name)
952 def add_net(gen, lustre, options):
953 """ create a node with a network config """
955 node_name = get_option(options, 'node')
956 nid = get_option(options, 'nid')
957 cluster_id = get_option(options, 'cluster_id')
958 hostaddr = get_option(options, 'hostaddr')
959 net_type = get_option(options, 'nettype')
961 if net_type in ('tcp','openib','ra'):
962 port = get_option_int(options, 'port')
963 elif net_type in ('elan', 'gm', 'iib', 'vib', 'lo', 'cray_kern_nal'):
966 print "Unknown net_type: ", net_type
969 ret = findByName(lustre, node_name, "node")
971 node = do_add_node(gen, lustre, options, node_name)
974 set_node_options(gen, node, options)
976 net_name = new_name('NET_'+ node_name +'_'+ net_type)
977 net_uuid = new_uuid(net_name)
978 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
980 node_add_profile(gen, node, "network", net_uuid)
983 def add_route(gen, lustre, options):
984 """ create a node with a network config """
986 node_name = get_option(options, 'node')
987 gw_net_type = get_option(options, 'nettype')
988 gw = get_option(options, 'gw')
989 gw_cluster_id = get_option(options, 'gateway_cluster_id')
990 tgt_cluster_id = get_option(options, 'target_cluster_id')
991 lo = get_option(options, 'lo')
992 hi = get_option(options, 'hi')
996 node = findByName(lustre, node_name, "node")
998 error (node_name, " not found.")
1000 rlist = node.getElementsByTagName('routetbl')
1004 rtbl_name = new_name("RTBL_" + node_name)
1005 rtbl_uuid = new_uuid(rtbl_name)
1006 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
1007 node.appendChild(rtbl)
1008 node_add_profile(gen, node, "routetbl", rtbl_uuid)
1009 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
1012 def add_gks(gen, lustre, options):
1013 """ create a gks """
1014 node_name = get_option(options, 'node')
1015 gks_name = get_option(options, 'gks')
1017 gks_name = new_name('GKS_'+ node_name)
1019 gkd_name = new_name("GKD_" + gks_name + "_" + node_name)
1020 gkd_uuid = new_uuid(gkd_name)
1022 gks_uuid = name2uuid(lustre, gks_name, 'gks', fatal=0)
1025 gks_uuid = new_uuid(gks_name)
1026 gks = gen.gks(gks_name, gks_uuid, gkd_uuid)
1027 lustre.appendChild(gks)
1029 gks = lookup(lustre, gks_uuid)
1032 node_uuid = name2uuid(lustre, node_name, 'node')
1033 node = findByName(lustre, node_name, "node")
1034 node_add_profile(gen, node, "gkd", gkd_uuid)
1035 net_uuid = get_net_uuid(lustre, node_name)
1037 error("NODE: ", node_name, "not found")
1039 gkd = gen.gkd(gkd_name, gkd_uuid, node_uuid, gks_uuid)
1040 lustre.appendChild(gkd)
1043 def add_mds(gen, lustre, options):
1044 node_name = get_option(options, 'node')
1045 mds_name = get_option(options, 'mds')
1047 mds_name = new_name('MDS_'+ node_name)
1048 lmv_name = get_option(options, 'lmv')
1049 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
1050 mdd_uuid = new_uuid(mdd_name)
1054 lmv = findByName(lustre, lmv_name, "lmv")
1056 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
1057 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
1059 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
1061 mds_uuid = get_option(options, 'mdsuuid')
1063 if lookup(lustre, mds_uuid):
1064 error("Duplicate MDS UUID:", mds_uuid)
1066 mds_uuid = new_uuid(mds_name)
1067 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
1068 lustre.appendChild(mds)
1070 lmv_add_obd(gen, lmv, mds_uuid)
1072 mds = lookup(lustre, mds_uuid)
1074 if options.failover:
1075 mds.setAttribute('failover', "1")
1077 devname = get_option(options, 'dev')
1078 backdevname = get_option(options, 'backdev')
1079 size = get_option(options, 'size')
1080 fstype = get_option(options, 'fstype')
1081 backfstype = get_option(options, 'backfstype')
1082 journal_size = get_option(options, 'journal_size')
1083 inode_size = get_option(options, 'inode_size')
1084 nspath = get_option(options, 'nspath')
1085 mkfsoptions = get_option(options, 'mkfsoptions')
1086 mountfsoptions = get_option(options, 'mountfsoptions')
1087 root_squash = get_option(options, 'root_squash')
1088 no_root_squash = get_option(options, 'no_root_squash')
1089 mds_sec = get_option(options, 'mds_mds_sec')
1090 oss_sec = get_option(options, 'mds_oss_sec')
1091 deny_sec = get_option(options, 'mds_deny_sec')
1092 fs_name = get_option(options, 'filesystem')
1094 node_uuid = name2uuid(lustre, node_name, 'node')
1096 node = findByName(lustre, node_name, "node")
1097 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1098 net_uuid = get_net_uuid(lustre, node_name)
1100 error("NODE: ", node_name, "not found")
1103 mds.appendChild(gen.ref("lmv", lmv_uuid))
1106 fs_uuid = name2uuid(lustre, fs_name, 'filesystem', fatal=1)
1110 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1111 get_format_flag(options), node_uuid, mds_uuid,
1112 size, journal_size, inode_size, nspath, mkfsoptions,
1113 mountfsoptions, backfstype, backdevname,lmv_uuid,
1114 root_squash, no_root_squash, mds_sec, oss_sec, deny_sec,
1116 lustre.appendChild(mdd)
1118 def add_mgmt(gen, lustre, options):
1119 node_name = get_option(options, 'node')
1120 node_uuid = name2uuid(lustre, node_name, 'node')
1121 mgmt_name = get_option(options, 'mgmt')
1123 mgmt_name = new_name('MGMT_' + node_name)
1124 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1126 mgmt_uuid = new_uuid(mgmt_name)
1127 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1128 lustre.appendChild(mgmt)
1130 mgmt = lookup(lustre, mgmt_uuid)
1132 node = findByName(lustre, node_name, "node")
1133 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1135 def add_ost(gen, lustre, options):
1136 node_name = get_option(options, 'node')
1137 lovname = get_option(options, 'lov')
1138 osdtype = get_option(options, 'osdtype')
1140 node_uuid = name2uuid(lustre, node_name, 'node')
1142 if osdtype == 'obdecho':
1154 devname = get_option(options, 'dev') # can be unset for bluearcs
1155 backdevname = get_option(options, 'backdev')
1156 size = get_option(options, 'size')
1157 fstype = get_option(options, 'fstype')
1158 backfstype = get_option(options, 'backfstype')
1159 journal_size = get_option(options, 'journal_size')
1160 inode_size = get_option(options, 'inode_size')
1161 mkfsoptions = get_option(options, 'mkfsoptions')
1162 mountfsoptions = get_option(options, 'mountfsoptions')
1163 deny_sec = get_option(options, 'ost_deny_sec')
1165 fs_name = get_option(options, 'filesystem')
1166 nspath = get_option(options, 'nspath')
1168 ostname = get_option(options, 'ost')
1170 ostname = new_name('OST_'+ node_name)
1172 osdname = new_name("OSD_" + ostname + "_" + node_name)
1173 osd_uuid = new_uuid(osdname)
1175 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1177 ost_uuid = get_option(options, 'ostuuid')
1179 if lookup(lustre, ost_uuid):
1180 error("Duplicate OST UUID:", ost_uuid)
1182 ost_uuid = new_uuid(ostname)
1184 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1185 lustre.appendChild(ost)
1187 ost = lookup(lustre, ost_uuid)
1190 lov = findByName(lustre, lovname, "lov")
1192 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1193 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1195 if options.failover:
1196 ost.setAttribute('failover', "1")
1199 fs_uuid = name2uuid(lustre, fs_name, 'filesystem', fatal=1)
1203 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1204 get_format_flag(options), ost_uuid, node_uuid, size,
1205 journal_size, inode_size, nspath, mkfsoptions,
1206 mountfsoptions, backfstype, backdevname, deny_sec,
1209 node = findByName(lustre, node_name, "node")
1210 node_add_profile(gen, node, 'osd', osd_uuid)
1211 lustre.appendChild(osd)
1213 def del_ost(gen, lustre, options):
1214 ostname = get_option(options, 'ost')
1216 raise OptionError("del_ost: --ost requires a <ost name>")
1217 ost = findByName(lustre, ostname, "ost")
1219 error('del_ost: ', 'Unable to find ', ostname)
1220 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1222 error('del_ost: ', 'Unable to find uuid for ', ostname)
1223 lovname = get_option(options, 'lov')
1225 lov = findByName(lustre, lovname, "lov")
1227 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1228 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1229 # if the user specified a speficic LOV don't delete the OST itself
1232 # remove OSD references from all LOVs
1233 for n in lustre.getElementsByTagName('lov'):
1234 lov_del_obd(gen, lustre, n, ost_uuid, options)
1235 if not options.migrate:
1238 for osd in lustre.getElementsByTagName('osd'):
1239 if ref_exists(osd, ost_uuid):
1240 osd_uuid = osd.getAttribute('uuid')
1241 # delete all profile references to this OSD
1242 for profile in lustre.getElementsByTagName('profile'):
1243 for osd_ref in profile.getElementsByTagName('osd_ref'):
1244 if osd_uuid == osd_ref.getAttribute('uuidref'):
1245 profile.removeChild(osd_ref)
1246 lustre.removeChild(osd)
1249 lustre.removeChild(ost)
1251 def add_cmobd(gen, lustre, options):
1252 node_name = get_option(options, 'node')
1253 name = get_option(options, 'cmobd')
1254 uuid = new_uuid(name)
1256 master_name = get_option(options, 'master_obd')
1257 cache_name = get_option(options, 'cache_obd')
1259 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1260 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1262 if not master_uuid or not cache_uuid:
1264 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1266 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1268 if not master_uuid or not cache_uuid:
1270 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1272 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1274 if not master_uuid or not cache_uuid:
1276 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1278 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1281 error("cannot find master_uuid by name '" + master_name + "'")
1283 error("cannot find cache_uuid by name '" + cache_name + "'")
1285 node = findByName(lustre, node_name, "node")
1286 node_add_profile(gen, node, "cmobd", uuid)
1288 master_node = lookup(lustre, master_uuid)
1289 cache_node = lookup(lustre, cache_uuid)
1291 error("cannot find master node by its uuid " + master_uuid);
1293 error("cannot find cache node by its uuid " + cache_uuid);
1295 active = master_node.getElementsByTagName('active_ref')
1297 active_uuid = active[0].getAttribute('uuidref')
1298 active_node = lookup(lustre, active_uuid)
1299 if not active_node.getElementsByTagName('obdtype'):
1300 gen.addElement(active_node, 'obdtype', 'master')
1302 active = cache_node.getElementsByTagName('active_ref')
1304 active_uuid = active[0].getAttribute('uuidref')
1305 active_node = lookup(lustre, active_uuid)
1306 if not active_node.getElementsByTagName('obdtype'):
1307 gen.addElement(active_node, 'obdtype', 'cache')
1309 cmobd = gen.cmobd(name, uuid, master_uuid, cache_uuid)
1310 lustre.appendChild(cmobd)
1312 def add_cobd(gen, lustre, options):
1313 node_name = get_option(options, 'node')
1314 name = get_option(options, 'cobd')
1315 uuid = new_uuid(name)
1317 master_name = get_option(options, 'master_obd')
1318 cache_name = get_option(options, 'cache_obd')
1321 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1323 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1326 node = lookup(lustre, master_uuid)
1327 rets = node.getElementsByTagName('lov_tgt')
1329 ost_uuid = ret.getAttribute('uuidref')
1330 ost_node = lookup(lustre, ost_uuid)
1331 active = ost_node.getElementsByTagName('active_ref')
1333 osd_uuid = active[0].getAttribute('uuidref')
1334 osd_node = lookup(lustre, osd_uuid)
1335 if not osd_node.getElementsByTagName('obdtype'):
1336 gen.addElement(osd_node, 'obdtype', 'master')
1339 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1341 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1344 node = lookup(lustre, cache_uuid)
1345 rets = node.getElementsByTagName('lov_tgt')
1347 ost_uuid = ret.getAttribute('uuidref')
1348 ost_node = lookup(lustre, ost_uuid)
1349 active = ost_node.getElementsByTagName('active_ref')
1351 osd_uuid = active[0].getAttribute('uuidref')
1352 osd_node = lookup(lustre, osd_uuid)
1353 if not osd_node.getElementsByTagName('obdtype'):
1354 gen.addElement(osd_node, 'obdtype', 'cache')
1356 if not master_uuid or not cache_uuid:
1357 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1359 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1362 mds_node = lookup(lustre, master_uuid)
1363 ret = mds_node.getElementsByTagName('active_ref')
1365 mdsdev_uuid = ret[0].getAttribute('uuidref')
1366 mdsdev_node = lookup(lustre, mdsdev_uuid)
1367 if not mdsdev_node.getElementsByTagName('obdtype'):
1368 gen.addElement(mdsdev_node, 'obdtype', 'master')
1370 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1372 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1375 mds_node = lookup(lustre, cache_uuid)
1376 ret = mds_node.getElementsByTagName('active_ref')
1378 mdsdev_uuid = ret[0].getAttribute('uuidref')
1379 mdsdev_node = lookup(lustre, mdsdev_uuid)
1380 if not mdsdev_node.getElementsByTagName('obdtype'):
1381 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1383 if not master_uuid or not cache_uuid:
1384 panic("add_cobd", "cannot find master or cache by names '" +
1385 master_name + "' and '" + cache_name + "'")
1387 node = findByName(lustre, node_name, "node")
1388 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1389 lustre.appendChild(cobd)
1391 def add_echo_client(gen, lustre, options):
1392 """ add an echo client to the profile for this node. """
1393 node_name = get_option(options, 'node')
1394 lov_name = get_option(options, 'ost')
1396 node = findByName(lustre, node_name, 'node')
1398 echoname = new_name('ECHO_'+ node_name)
1399 echo_uuid = new_uuid(echoname)
1400 node_add_profile(gen, node, 'echoclient', echo_uuid)
1402 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1404 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1406 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1407 lustre.appendChild(echo)
1409 def add_lov(gen, lustre, options):
1410 """ create a lov """
1412 lov_orig = get_option(options, 'lov')
1413 name = new_name(lov_orig)
1414 if name != lov_orig:
1415 warning("name:", lov_orig, "already used. using:", name)
1417 lmv_name = get_option(options, 'lmv')
1418 mds_name = get_option(options, 'mds')
1419 aware = get_option(options, 'aware')
1421 if not mds_name and not lmv_name:
1422 error("LOV: either MDS or LMV must be specified.");
1423 if mds_name and lmv_name:
1424 error("LOV: either MDS or LMV must be specified.");
1426 stripe_sz = get_option_int(options, 'stripe_sz')
1427 stripe_cnt = get_option_int(options, 'stripe_cnt')
1428 pattern = get_option_int(options, 'stripe_pattern')
1429 uuid = new_uuid(name)
1431 ret = findByName(lustre, name, "lov")
1433 error("LOV: ", name, " already exists.")
1436 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1438 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1440 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1441 lustre.appendChild(lov)
1443 # add an lovconfig entry to the active mdsdev profile
1444 lovconfig_name = new_name('LVCFG_' + name)
1445 lovconfig_uuid = new_uuid(lovconfig_name)
1448 md_tgt = findByName(lustre, mds_name, "mds")
1450 error("can't find MDS '" + mds_name + "'")
1452 md_tgt = findByName(lustre, lmv_name, "lmv")
1454 error("can't find LMV '" + lmv_name + "'")
1456 md_tgt.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1457 md_tgt.appendChild(gen.ref("client", uuid))
1459 # adding lovconfig and client to aware MD targets
1461 md_names = string.split(aware, ',');
1462 for md_name in md_names:
1464 md_tgt = findByName(lustre, md_name, "mds")
1466 md_tgt = findByName(lustre, md_name, "lmv")
1469 error("can't find '" + mds_name + "'")
1471 md_tgt.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1472 md_tgt.appendChild(gen.ref("client", uuid))
1474 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1475 lustre.appendChild(lovconfig)
1477 def add_default_lov(gen, lustre, mds_name, lov_name):
1478 """ create a default lov """
1480 stripe_sz = DEFAULT_STRIPE_SZ
1481 stripe_cnt = DEFAULT_STRIPE_CNT
1482 pattern = DEFAULT_STRIPE_PATTERN
1483 uuid = new_uuid(lov_name)
1485 ret = findByName(lustre, lov_name, "lov")
1487 error("LOV: ", lov_name, " already exists.")
1489 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1490 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1491 lustre.appendChild(lov)
1493 # add an lovconfig entry to the active mdsdev profile
1494 lovconfig_name = new_name('LVCFG_' + lov_name)
1495 lovconfig_uuid = new_uuid(lovconfig_name)
1496 mds = findByName(lustre, mds_name)
1497 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1498 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1499 lustre.appendChild(lovconfig)
1501 def add_lmv(gen, lustre, options):
1502 """ create a lmv """
1504 lmv_orig = get_option(options, 'lmv')
1505 name = new_name(lmv_orig)
1506 if name != lmv_orig:
1507 warning("name:", lmv_orig, "already used. using:", name)
1509 uuid = new_uuid(name)
1510 ret = findByName(lustre, name, "lmv")
1512 error("LMV: ", name, " already exists.")
1514 lmv = gen.lmv(name, uuid)
1515 lustre.appendChild(lmv)
1517 def new_filesystem(gen, lustre, fs_name, mds_uuid, obd_uuid,
1518 mgmt_uuid, gks_uuid):
1519 fs_uuid = new_uuid(fs_name)
1520 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid,
1521 mgmt_uuid, gks_uuid)
1522 lustre.appendChild(fs)
1525 def get_fs_uuid(gen, lustre, fs_name, mds_name, obd_name,
1526 mgmt_name, gks_name):
1527 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1529 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1531 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1533 error("mds '" + mds_name + "' is not found")
1535 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1537 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1539 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1541 error("ost '" + obd_name + "' is not found")
1544 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1549 gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
1553 fs_uuid = lookup_filesystem(lustre, fs_name)
1555 fs = lookup(lustre, fs_uuid)
1556 if not ref_exists(fs, mds_uuid):
1557 fs.appendChild(gen.ref("mds", mds_uuid))
1558 if not ref_exists(fs, obd_uuid):
1559 fs.appendChild(gen.ref("obd", obd_uuid))
1560 if gks_uuid and not ref_exists(fs, gks_uuid):
1561 fs.appendChild(gen.ref("gks", gks_uuid))
1563 fs_uuid = new_filesystem(gen, lustre, fs_name,
1565 mgmt_uuid, gks_uuid)
1568 def add_filesystem(gen, lustre, options):
1569 """ create filesytem """
1570 fs_orig = get_option(options, 'filesystem')
1571 name = new_name(fs_orig)
1573 warning("name:", fs_orig, "already used. using:", name)
1575 uuid = new_uuid(name)
1576 ret = findByName(lustre, name, "filesystem")
1578 error("FS: ", name, " already exists.")
1580 gks_name = get_option(options, 'gks')
1582 gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
1585 fs = gen.filesystem(name, uuid, "", "", "", gks_uuid)
1586 lustre.appendChild(fs)
1588 def add_mtpt(gen, lustre, options):
1589 """ create mtpt on a node """
1590 node_name = get_option(options, 'node')
1592 path = get_option(options, 'path')
1593 clientoptions = get_option(options, "clientoptions")
1594 mds_sec = get_option(options, "mds_sec")
1595 oss_sec = get_option(options, "oss_sec")
1596 fs_name = get_option(options, 'filesystem')
1598 lov_name = get_option(options, 'lov')
1599 ost_name = get_option(options, 'ost')
1600 mds_name = get_option(options, 'mds')
1601 gks_name = get_option(options, 'gks')
1603 mds_name = get_option(options, 'lmv')
1605 error("--add mtpt requires either --mds or --lmv.")
1608 error("--add mtpt requires --lov lov_name or --ost ost_name")
1610 warning("use default value for lov, due no --lov lov_name provided")
1611 lov_name = new_name("lov_default")
1612 add_default_lov(gen, lustre, mds_name, lov_name)
1613 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1615 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1616 lov = findByName(lustre, lov_name, "lov")
1617 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1620 fs_name = new_name("FS_fsname")
1621 mgmt_name = get_option(options, 'mgmt')
1625 fs_uuid = get_fs_uuid(gen, lustre, fs_name,
1626 mds_name, lov_name, mgmt_name, gks_name)
1628 name = new_name('MNT_'+ node_name)
1630 ret = findByName(lustre, name, "mountpoint")
1632 # this can't happen, because new_name creates unique names
1633 error("MOUNTPOINT: ", name, " already exists.")
1635 uuid = new_uuid(name)
1636 mtpt = gen.mountpoint(name, uuid, fs_uuid, path,
1637 clientoptions, mds_sec, oss_sec)
1638 node = findByName(lustre, node_name, "node")
1640 error('node:', node_name, "not found.")
1641 node_add_profile(gen, node, "mountpoint", uuid)
1642 lustre.appendChild(mtpt)
1644 def commit_version(gen, lustre):
1645 update = findLastUpdate(lustre)
1647 version = int(update.getAttribute("version")) + 1
1651 new = gen.update(str(version))
1652 lustre.appendChild(new)
1655 ############################################################
1656 # Command line processing
1658 class OptionError (exceptions.Exception):
1659 def __init__(self, args):
1662 def get_option(options, tag):
1663 """Look for tag in options hash and return the value if set. If not
1664 set, then if return default it is set, otherwise exception."""
1665 if options.__getattr__(tag) != None:
1666 return options.__getattr__(tag)
1668 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1670 def get_option_int(options, tag):
1671 """Return an integer option. Raise exception if the value is not an int"""
1672 val = get_option(options, tag)
1676 raise OptionError("--%s <num> (value must be integer)" % (tag))
1679 # simple class for profiling
1686 self._start = time.time()
1687 def stop(self, msg=''):
1688 self._stop = time.time()
1692 return self._stop - self._start
1693 def display(self, msg):
1695 str = '%s: %g secs' % (msg, d)
1698 #################################################################
1699 # function cmdlinesplit used to split cmd line from batch file
1701 def cmdlinesplit(cmdline):
1703 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1704 single_quote = re.compile(r"'(.*?)'")
1705 escaped = re.compile(r'\\(.)')
1706 esc_quote = re.compile(r'\\([\\"])')
1707 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1711 while i < len(cmdline):
1714 match = double_quote.match(cmdline, i)
1716 print "Unmatched double quote:", cmdline
1719 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1720 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1723 match = single_quote.match(cmdline, i)
1725 print "Unmatched single quote:", cmdline
1728 if arg is None: arg = match.group(1)
1729 else: arg = arg + match.group(1)
1732 match = escaped.match(cmdline, i)
1734 print "Unmatched backslash", cmdline
1737 if arg is None: arg = match.group(1)
1738 else: arg = arg + match.group(1)
1740 elif c in string.whitespace:
1742 arg_list.append(str(arg))
1744 while i < len(cmdline) and cmdline[i] in string.whitespace:
1747 match = outside.match(cmdline, i)
1750 if arg is None: arg = match.group()
1751 else: arg = arg + match.group()
1753 if arg != None: arg_list.append(str(arg))
1757 ############################################################
1761 def add(devtype, gen, lustre, options):
1762 if devtype == 'net':
1763 add_net(gen, lustre, options)
1764 elif devtype == 'mtpt':
1765 add_mtpt(gen, lustre, options)
1766 elif devtype == 'mds':
1767 add_mds(gen, lustre, options)
1768 elif devtype == 'ost':
1769 add_ost(gen, lustre, options)
1770 elif devtype == 'lov':
1771 add_lov(gen, lustre, options)
1772 elif devtype == 'route':
1773 add_route(gen, lustre, options)
1774 elif devtype == 'node':
1775 add_node(gen, lustre, options)
1776 elif devtype == 'echo_client':
1777 add_echo_client(gen, lustre, options)
1778 elif devtype == 'cobd':
1779 add_cobd(gen, lustre, options)
1780 elif devtype == 'cmobd':
1781 add_cmobd(gen, lustre, options)
1782 elif devtype == 'mgmt':
1783 add_mgmt(gen, lustre, options)
1784 elif devtype == 'lmv':
1785 add_lmv(gen, lustre, options)
1786 elif devtype == 'filesystem':
1787 add_filesystem(gen, lustre, options)
1788 elif devtype == 'gks':
1789 add_gks(gen, lustre, options)
1791 error("unknown device type:", devtype)
1793 def delete(devtype, gen, lustre, options):
1794 if devtype == 'ost':
1795 del_ost(gen, lustre, options)
1796 elif options.delete:
1797 error("delete not supported for device type:", devtype)
1798 elif options.deactivate:
1799 error("deactivate not supported for device type:", devtype)
1801 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1803 def commit(gen, lustre):
1804 commit_version(gen, lustre)
1806 def do_command(gen, lustre, options, args):
1808 add(options.add, gen, lustre, options)
1809 elif options.delete:
1810 delete(options.delete, gen, lustre, options)
1811 elif options.deactivate:
1812 delete(options.deactivate, gen, lustre, options)
1813 elif options.commit:
1816 error("Missing command")
1819 cl = Lustre.Options("lmc", "", lmc_options)
1821 options, args = cl.parse(sys.argv[1:])
1822 except Lustre.OptionError, e:
1826 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1828 if options.reference:
1835 outFile = options.merge
1836 if os.access(outFile, os.R_OK):
1837 doc = xml.dom.minidom.parse(outFile)
1839 doc = new_lustre(xml.dom.minidom)
1841 doc = xml.dom.minidom.parse(options.input)
1843 doc = new_lustre(xml.dom.minidom)
1846 outFile = options.output
1848 lustre = doc.documentElement
1850 if lustre.tagName != "lustre":
1851 print "Existing config not valid."
1854 gen = GenConfig(doc)
1857 fp = open(options.batch)
1858 batchCommands = fp.readlines()
1860 for cmd in batchCommands:
1862 options, args = cl.parse(cmdlinesplit(cmd))
1863 if options.merge or options.input or options.output:
1864 print "The batchfile should not contain --merge, --input or --output."
1866 do_command(gen, lustre, options, args)
1867 except OptionError, e:
1869 except Lustre.OptionError, e:
1873 do_command(gen, lustre, options, args)
1874 except OptionError, e:
1875 panic(string.join(sys.argv),e)
1876 except Lustre.OptionError, e:
1882 printDoc(doc, open(outFile,"w"))
1884 if __name__ == "__main__":