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
149 --add mtpt - Mountpoint
154 --ost ost_name OR --lov lov_name
155 --clientoptions options
163 --gateway_cluster_id nid
164 --target_cluster_id nid
171 --add mgmt - Management/monitoring service
173 --mgmt mgmt_service_name
180 --master_obd obd_name
185 --master_obd obd_name
191 --commit - Close a configuration version, and start a new one
194 PARAM = Lustre.Options.PARAM
195 PARAMLIST = Lustre.Options.PARAMLIST
197 # lmc input/output options
198 ('reference', "Print short reference for commands."),
199 ('verbose,v', "Print system commands as they are run."),
200 ('merge,m', "Append to the specified config file.", PARAM),
201 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
202 ('input,i', "", PARAM),
203 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
207 ('delete', "", PARAM),
208 ('deactivate', "", PARAM),
209 ('commit', "Commit all config changes and start a new version"),
212 ('node', "Add a new node in the cluster configuration.", PARAM),
213 ('timeout', "Set timeout to initiate recovery.", PARAM),
214 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
215 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
216 ('portals_upcall', "Set location of portals upcall script.", PARAM),
217 ('ptldebug', "Set the portals debug level", PARAM),
218 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
221 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib/iib/vib/ra.", PARAM),
222 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
223 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
224 ('hostaddr', "Optional argument to specify the host address.", PARAMLIST),
225 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
228 ('route', "Add a new route for the cluster.", PARAM),
229 ('router', "Optional flag to mark a node as router."),
230 ('gw', "Specify the nid of the gateway for a route.", PARAM),
231 ('gateway_cluster_id', "", PARAM, "0"),
232 ('target_cluster_id', "", PARAM, "0"),
233 ('lo', "For a range route, this is the low value nid.", PARAM),
234 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
236 # servers: mds and ost
237 ('mds', "Specify MDS name.", PARAM,""),
238 ('ost', "Specify the OST name.", PARAM,""),
239 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
240 ('failover', "Enable failover support on OSTs or MDS?"),
241 ('group', "", PARAM),
242 ('dev', "Path of the device on local system.", PARAM,""),
243 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
244 ('size', "Specify the size of the device if needed.", PARAM,"0"),
245 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
246 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
247 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
248 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
249 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
250 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
251 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
252 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
253 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
254 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
255 ('nspath', "Local mount point of server namespace.", PARAM,""),
256 ('mds_mds_sec', "Specify the secure flavor for connection from this mds to other mds.", PARAM, ""),
257 ('mds_oss_sec', "Specify the secure flavor for connection from this mds to ost.", PARAM, ""),
258 ('mds_deny_sec', "Specify the secure flavor which is denied from remote to this mds.", PARAM, ""),
259 ('ost_deny_sec', "Specify the secure flavor which is denied from remote to this ost.", PARAM, ""),
260 ('filesystem', "Specify the filesystem name device belong to.", PARAM, ""),
262 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
264 # clients: mountpoint and echo
265 ('echo_client', "", PARAM),
266 ('path', "Specify the mountpoint for Lustre.", PARAM),
267 ('filesystem', "Lustre filesystem name", PARAM,""),
268 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
269 ('mds_sec', "Specify the secure flavor for connection from this client to mds.", PARAM, ""),
270 ('oss_sec', "Specify the secure flavor for connection from this client to ost.", PARAM, ""),
273 ('lov', "Specify LOV name.", PARAM,""),
274 ('mds/lmv', "Specify MDS/LMV name using this LOV.", PARAM,""),
275 ('aware', "Specify MDS/LMV aware of this LOV.", PARAM,""),
276 ('index', "Specify index for OBD in LOV target table.", PARAM),
277 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
278 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
279 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
282 ('master_obd', "Specify the real device for the cache obd system.", PARAM),
283 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
284 ('cobd', "Specify COBD name", PARAM),
287 ('master_obd', "Specify the master device for the cmobd system.", PARAM),
288 ('cache_obd', "Specify the cache device for the cmobd obd system.", PARAM),
289 ('cmobd', "Specify COBD name", PARAM),
291 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
294 ('lmv', "Specify LMV name.", PARAM,""),
297 ('gks', "Specify gks name.", PARAM,""),
302 msg = string.join(map(str,args))
303 raise OptionError("Error: " + msg)
312 msg = string.join(map(str,args))
313 print "Warning: ", msg
316 # manage names and uuids
317 # need to initialize this by walking tree to ensure
318 # no duplicate names or uuids are created.
319 # this are just place holders for now.
320 # consider changing this to be like OBD-dev-host
324 while names.has_key(ret):
325 ret = "%s_%d" % (base, ctr)
332 ret = "%s_UUID" % (name)
333 if len(ret) > UUID_MAX_LENGTH:
334 ret = ret[-UUID_MAX_LENGTH:]
335 while uuids.has_key(ret):
336 ret = "%s_UUID_%d" % (name, ctr)
338 if len(ret) > UUID_MAX_LENGTH:
339 ret = ret[-UUID_MAX_LENGTH:]
345 ldlm_uuid = 'ldlm_UUID'
348 """Create a new empty lustre document"""
349 # adding ldlm here is a bit of a hack, but one is enough.
350 str = """<lustre version="%s">
351 <ldlm name="%s" uuid="%s"/>
352 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
353 return dom.parseString(str)
359 """initialize auto-name generation tables"""
361 # get all elements that contain a name attribute
362 for n in doc.childNodes:
363 if n.nodeType == n.ELEMENT_NODE:
365 names[getName(n)] = 1
366 uuids[getUUID(n)] = 1
369 def get_format_flag(options):
374 ############################################################
375 # Build config objects using DOM
380 def __init__(self, doc):
383 def ref(self, type, uuid):
384 """ generate <[type]_ref uuidref="[uuid]"/> """
385 tag = "%s_ref" % (type)
386 ref = self.doc.createElement(tag)
387 ref.setAttribute("uuidref", uuid)
390 def dev(self, devname):
391 """ generate <dev devpath="[devname]"/> """
392 tgt = self.doc.createElement('dev')
393 tgt.setAttribute("dev", devname)
396 def newService(self, tag, name, uuid):
397 """ create a new service elmement, which requires name and uuid attributes """
398 new = self.doc.createElement(tag)
399 new.setAttribute("uuid", uuid);
400 new.setAttribute("name", name);
403 def addText(self, node, str):
404 txt = self.doc.createTextNode(str)
405 node.appendChild(txt)
407 def addElement(self, node, tag, str=None):
408 """ create a new element and add it as a child to node. If str is passed,
409 a text node is created for the new element"""
410 new = self.doc.createElement(tag)
412 self.addText(new, str)
413 node.appendChild(new)
416 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
418 """create <network> node"""
419 network = self.newService("network", name, uuid)
420 network.setAttribute("nettype", net);
421 self.addElement(network, "nid", nid)
422 self.addElement(network, "clusterid", cluster_id)
423 for host in hostaddr:
424 self.addElement(network, "hostaddr", host)
426 self.addElement(network, "port", "%d" %(port))
430 def routetbl(self, name, uuid):
431 """create <routetbl> node"""
432 rtbl = self.newService("routetbl", name, uuid)
435 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
436 """ create one entry for the route table """
437 ref = self.doc.createElement('route')
438 ref.setAttribute("type", gw_net_type)
439 ref.setAttribute("gw", gw)
440 ref.setAttribute("gwclusterid", gw_cluster_id)
441 ref.setAttribute("tgtclusterid", tgt_cluster_id)
442 ref.setAttribute("lo", lo)
444 ref.setAttribute("hi", hi)
447 def profile(self, name, uuid):
448 """ create a host """
449 profile = self.newService("profile", name, uuid)
452 def node(self, name, uuid, prof_uuid):
453 """ create a host """
454 node = self.newService("node", name, uuid)
455 node.appendChild(self.ref("profile", prof_uuid))
458 def ldlm(self, name, uuid):
459 """ create a ldlm """
460 ldlm = self.newService("ldlm", name, uuid)
463 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
464 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
465 mkfsoptions="", mountfsoptions="", backfstype="", backdevname="",
466 deny_sec="", fs_uuid=""):
467 osd = self.newService("osd", name, uuid)
468 osd.setAttribute('osdtype', osdtype)
469 osd.appendChild(self.ref("target", ost_uuid))
470 osd.appendChild(self.ref("node", node_uuid))
473 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)
666 new = self.doc.createElement("info")
669 def lov_add(self, lov, ost, index, gen):
670 new = self.doc.createElement("lov_add")
671 new.setAttribute("lov_uuidref", lov)
672 new.setAttribute("ost_uuidref", ost)
673 new.setAttribute("index", index)
674 new.setAttribute("generation", gen)
677 def lov_delete(self, lov, ost, index, gen, options):
679 new = self.doc.createElement("lov_delete")
681 new = self.doc.createElement("lov_deactivate")
682 new.setAttribute("lov_uuidref", lov)
683 new.setAttribute("ost_uuidref", ost)
684 new.setAttribute("index", index)
685 new.setAttribute("generation", gen)
688 ############################################################
689 # Utilities to query a DOM tree
690 # Using this functions we can treat use config information
691 # directly as a database.
693 return n.getAttribute('name')
696 return node.getAttribute('uuid')
698 def findLastUpdate(lustre):
701 for n in lustre.childNodes:
702 if n.nodeType == n.ELEMENT_NODE:
703 if n.nodeName != 'update':
705 tmp = int(n.getAttribute('version'))
707 error('malformed XML: update tag without a version attribute')
708 if tmp != version + 1:
709 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
714 def addUpdate(gen, lustre, node):
715 update = findLastUpdate(lustre)
718 update.appendChild(node)
720 def findByName(lustre, name, tag = ""):
721 for n in lustre.childNodes:
722 if n.nodeType == n.ELEMENT_NODE:
723 if tag and n.nodeName != tag:
725 if getName(n) == name:
728 n = findByName(n, name)
733 def lookup(node, uuid):
734 for n in node.childNodes:
735 if n.nodeType == n.ELEMENT_NODE:
736 if getUUID(n) == uuid:
744 def name2uuid(lustre, name, tag="", fatal=1):
745 ret = findByName(lustre, name, tag)
748 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
753 def lookup_filesystem(lustre, fs_name):
754 for n in lustre.childNodes:
755 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
756 if getName(n) == fs_name:
760 # XXX: assumes only one network element per node. will fix this
761 # as soon as support for routers is added
762 def get_net_uuid(lustre, node_name):
763 """ get a network uuid for a node_name """
764 node = findByName(lustre, node_name, "node")
766 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
767 net = node.getElementsByTagName('network')
769 return getUUID(net[0])
772 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
773 tgt.setAttribute('uuidref', osc_uuid)
774 gener = int(tgt.getAttribute('generation'))
775 if not options.migrate:
776 gener = str(int(gener) + 1)
777 tgt.setAttribute('generation', str(gener))
778 tgt.setAttribute('active', '1')
779 lov_index = int(tgt.getAttribute('index'))
780 add_rec = gen.lov_add(getUUID(lov), osc_uuid, str(lov_index), str(gener))
781 addUpdate(gen, lustre, add_rec)
784 def lov_add_osc(gen, lustre, lov, osc_uuid, options):
785 lov_name = getName(lov)
786 lov_uuid = getUUID(lov)
788 lov_index = get_option_int(options, 'index')
789 for tgt in lov.getElementsByTagName('lov_tgt'):
790 if str(lov_index) == tgt.getAttribute('index'):
791 uuidref = tgt.getAttribute('uuidref')
793 raise OptionError("%s --index %d is still in use: %s" %
794 (lov_name, lov_index, uuidref))
795 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
799 for tgt in lov.getElementsByTagName('lov_tgt'):
800 uuidref = tgt.getAttribute('uuidref')
801 tmp = int(tgt.getAttribute('index'))
802 own_lov_uuid = tgt.getAttribute('lov_uuid')
803 if lov_uuid != own_lov_uuid:
806 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
808 lov_index = lov_index + 1
810 lov.appendChild(gen.lov_tgt(osc_uuid, lov_uuid, str(lov_index), '1'))
811 addrec = gen.lov_add(lov_uuid, osc_uuid, str(lov_index), '1')
812 addUpdate(gen, lustre, addrec)
814 def lov_del_osc(gen, lustre, lov, osc_uuid, options):
815 lov_name = getName(lov)
817 lov_index = get_option_int(options, 'index')
818 for tgt in lov.getElementsByTagName('lov_tgt'):
819 index = tgt.getAttribute('index')
820 if index == lov_index:
821 uuidref = tgt.getAttribute('uuidref')
822 if uuidref != osc_uuid:
823 raise OptionError("%s --index %d contains %s, not %s" %
824 (lov_name, lov_index, osc_uuid, uuidref))
826 tgt.setAttribute('uuidref', '')
828 gener = tgt.getAttribute('generation')
829 if not options.migrate:
830 # bump the generation just in case...
831 gener = str(int(gener) + 1)
833 tgt.setAttribute('active', '0')
834 tgt.setAttribute('generation', gener)
836 raise OptionError("%s --index %d not in use by %s." %
837 (lov_name, lov_index, osc_uuid))
839 for tgt in lov.getElementsByTagName('lov_tgt'):
840 uuidref = tgt.getAttribute('uuidref')
841 if uuidref == osc_uuid:
842 index = tgt.getAttribute('index')
843 gener = tgt.getAttribute('generation')
844 delete_rec = gen.lov_delete(getUUID(lov), osc_uuid, index, gener,
846 addUpdate(gen, lustre, delete_rec)
849 tgt.setAttribute('uuidref', '')
850 if not options.migrate:
851 gener = str(int(gener) + 1)
852 tgt.setAttribute('active', '0')
853 tgt.setAttribute('generation', gener)
855 def lmv_add_obd(gen, lmv, mdc_uuid):
856 lmv.appendChild(gen.lmv_tgt(mdc_uuid))
858 def ref_exists(profile, uuid):
859 elist = profile.childNodes
861 if e.nodeType == e.ELEMENT_NODE:
862 ref = e.getAttribute('uuidref')
867 # ensure that uuid is not already in the profile
868 # return true if uuid is added
869 def node_add_profile(gen, node, ref, uuid):
870 refname = "%s_ref" % "profile"
871 ret = node.getElementsByTagName(refname)
873 error('node has no profile ref:', node)
874 prof_uuid = ret[0].getAttribute('uuidref')
875 profile = lookup(node.parentNode, prof_uuid)
877 error("no profile found:", prof_uuid)
878 if ref_exists(profile, uuid):
880 profile.appendChild(gen.ref(ref, uuid))
883 def get_attr(dom_node, attr, default=""):
884 v = dom_node.getAttribute(attr)
889 ############################################################
892 def set_node_options(gen, node, options):
894 node.setAttribute('router', '1')
896 gen.addElement(node, "timeout", get_option(options, 'timeout'))
898 default_upcall = get_option(options, 'upcall')
901 if default_upcall or options.lustre_upcall:
902 if options.lustre_upcall:
903 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
905 gen.addElement(node, 'lustreUpcall', default_upcall)
906 if default_upcall or options.portals_upcall:
907 if options.portals_upcall:
908 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
910 gen.addElement(node, 'portalsUpcall', default_upcall)
912 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
913 if options.subsystem:
914 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
917 def do_add_node(gen, lustre, options, node_name):
918 uuid = new_uuid(node_name)
919 prof_name = new_name("PROFILE_" + node_name)
920 prof_uuid = new_uuid(prof_name)
921 profile = gen.profile(prof_name, prof_uuid)
922 node = gen.node(node_name, uuid, prof_uuid)
923 lustre.appendChild(node)
924 lustre.appendChild(profile)
926 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
927 set_node_options(gen, node, options)
931 def add_node(gen, lustre, options):
932 """ create a node with a network config """
934 node_name = get_option(options, 'node')
935 ret = findByName(lustre, node_name, "node")
937 print "Node:", node_name, "exists."
939 do_add_node(gen, lustre, options, node_name)
942 def add_net(gen, lustre, options):
943 """ create a node with a network config """
945 node_name = get_option(options, 'node')
946 nid = get_option(options, 'nid')
947 cluster_id = get_option(options, 'cluster_id')
948 hostaddr = get_option(options, 'hostaddr')
949 net_type = get_option(options, 'nettype')
951 if net_type in ('tcp','openib','ra'):
952 port = get_option_int(options, 'port')
953 elif net_type in ('elan', 'gm', 'iib', 'vib', 'lo', 'cray_kern_nal'):
956 print "Unknown net_type: ", net_type
959 ret = findByName(lustre, node_name, "node")
961 node = do_add_node(gen, lustre, options, node_name)
964 set_node_options(gen, node, options)
966 net_name = new_name('NET_'+ node_name +'_'+ net_type)
967 net_uuid = new_uuid(net_name)
968 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
970 node_add_profile(gen, node, "network", net_uuid)
973 def add_route(gen, lustre, options):
974 """ create a node with a network config """
976 node_name = get_option(options, 'node')
977 gw_net_type = get_option(options, 'nettype')
978 gw = get_option(options, 'gw')
979 gw_cluster_id = get_option(options, 'gateway_cluster_id')
980 tgt_cluster_id = get_option(options, 'target_cluster_id')
981 lo = get_option(options, 'lo')
982 hi = get_option(options, 'hi')
986 node = findByName(lustre, node_name, "node")
988 error (node_name, " not found.")
990 rlist = node.getElementsByTagName('routetbl')
994 rtbl_name = new_name("RTBL_" + node_name)
995 rtbl_uuid = new_uuid(rtbl_name)
996 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
997 node.appendChild(rtbl)
998 node_add_profile(gen, node, "routetbl", rtbl_uuid)
999 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
1002 def add_gks(gen, lustre, options):
1003 """ create a gks """
1004 node_name = get_option(options, 'node')
1005 gks_name = get_option(options, 'gks')
1007 gks_name = new_name('GKS_'+ node_name)
1009 gkd_name = new_name("GKD_" + gks_name + "_" + node_name)
1010 gkd_uuid = new_uuid(gkd_name)
1012 gks_uuid = name2uuid(lustre, gks_name, 'gks', fatal=0)
1015 gks_uuid = new_uuid(gks_name)
1016 gks = gen.gks(gks_name, gks_uuid, gkd_uuid)
1017 lustre.appendChild(gks)
1019 gks = lookup(lustre, gks_uuid)
1022 node_uuid = name2uuid(lustre, node_name, 'node')
1023 node = findByName(lustre, node_name, "node")
1024 node_add_profile(gen, node, "gkd", gkd_uuid)
1025 net_uuid = get_net_uuid(lustre, node_name)
1027 error("NODE: ", node_name, "not found")
1029 gkd = gen.gkd(gkd_name, gkd_uuid, node_uuid, gks_uuid)
1030 lustre.appendChild(gkd)
1033 def add_mds(gen, lustre, options):
1034 node_name = get_option(options, 'node')
1035 mds_name = get_option(options, 'mds')
1037 mds_name = new_name('MDS_'+ node_name)
1038 lmv_name = get_option(options, 'lmv')
1039 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
1040 mdd_uuid = new_uuid(mdd_name)
1044 lmv = findByName(lustre, lmv_name, "lmv")
1046 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
1047 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
1049 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
1051 mds_uuid = get_option(options, 'mdsuuid')
1053 if lookup(lustre, mds_uuid):
1054 error("Duplicate MDS UUID:", mds_uuid)
1056 mds_uuid = new_uuid(mds_name)
1057 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
1058 lustre.appendChild(mds)
1060 lmv_add_obd(gen, lmv, mds_uuid)
1062 mds = lookup(lustre, mds_uuid)
1064 if options.failover:
1065 mds.setAttribute('failover', "1")
1067 devname = get_option(options, 'dev')
1068 backdevname = get_option(options, 'backdev')
1069 size = get_option(options, 'size')
1070 fstype = get_option(options, 'fstype')
1071 backfstype = get_option(options, 'backfstype')
1072 journal_size = get_option(options, 'journal_size')
1073 inode_size = get_option(options, 'inode_size')
1074 nspath = get_option(options, 'nspath')
1075 mkfsoptions = get_option(options, 'mkfsoptions')
1076 mountfsoptions = get_option(options, 'mountfsoptions')
1077 root_squash = get_option(options, 'root_squash')
1078 no_root_squash = get_option(options, 'no_root_squash')
1079 mds_sec = get_option(options, 'mds_mds_sec')
1080 oss_sec = get_option(options, 'mds_oss_sec')
1081 deny_sec = get_option(options, 'mds_deny_sec')
1082 fs_name = get_option(options, 'filesystem')
1084 node_uuid = name2uuid(lustre, node_name, 'node')
1086 node = findByName(lustre, node_name, "node")
1087 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1088 net_uuid = get_net_uuid(lustre, node_name)
1090 error("NODE: ", node_name, "not found")
1093 mds.appendChild(gen.ref("lmv", lmv_uuid))
1096 fs_uuid = name2uuid(lustre, fs_name, 'filesystem', fatal=1)
1100 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1101 get_format_flag(options), node_uuid, mds_uuid,
1102 size, journal_size, inode_size, nspath, mkfsoptions,
1103 mountfsoptions, backfstype, backdevname,lmv_uuid,
1104 root_squash, no_root_squash, mds_sec, oss_sec, deny_sec,
1106 lustre.appendChild(mdd)
1108 def add_mgmt(gen, lustre, options):
1109 node_name = get_option(options, 'node')
1110 node_uuid = name2uuid(lustre, node_name, 'node')
1111 mgmt_name = get_option(options, 'mgmt')
1113 mgmt_name = new_name('MGMT_' + node_name)
1114 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1116 mgmt_uuid = new_uuid(mgmt_name)
1117 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1118 lustre.appendChild(mgmt)
1120 mgmt = lookup(lustre, mgmt_uuid)
1122 node = findByName(lustre, node_name, "node")
1123 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1125 def add_ost(gen, lustre, options):
1126 node_name = get_option(options, 'node')
1127 lovname = get_option(options, 'lov')
1128 osdtype = get_option(options, 'osdtype')
1130 node_uuid = name2uuid(lustre, node_name, 'node')
1132 if osdtype == 'obdecho':
1144 devname = get_option(options, 'dev') # can be unset for bluearcs
1145 backdevname = get_option(options, 'backdev')
1146 size = get_option(options, 'size')
1147 fstype = get_option(options, 'fstype')
1148 backfstype = get_option(options, 'backfstype')
1149 journal_size = get_option(options, 'journal_size')
1150 inode_size = get_option(options, 'inode_size')
1151 mkfsoptions = get_option(options, 'mkfsoptions')
1152 mountfsoptions = get_option(options, 'mountfsoptions')
1153 deny_sec = get_option(options, 'ost_deny_sec')
1155 fs_name = get_option(options, 'filesystem')
1156 nspath = get_option(options, 'nspath')
1158 ostname = get_option(options, 'ost')
1160 ostname = new_name('OST_'+ node_name)
1162 osdname = new_name("OSD_" + ostname + "_" + node_name)
1163 osd_uuid = new_uuid(osdname)
1165 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1167 ost_uuid = get_option(options, 'ostuuid')
1169 if lookup(lustre, ost_uuid):
1170 error("Duplicate OST UUID:", ost_uuid)
1172 ost_uuid = new_uuid(ostname)
1174 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1175 lustre.appendChild(ost)
1177 ost = lookup(lustre, ost_uuid)
1180 lov = findByName(lustre, lovname, "lov")
1182 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1183 lov_add_osc(gen, lustre, lov, ost_uuid, options)
1185 if options.failover:
1186 ost.setAttribute('failover', "1")
1189 fs_uuid = name2uuid(lustre, fs_name, 'filesystem', fatal=1)
1193 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1194 get_format_flag(options), ost_uuid, node_uuid, size,
1195 journal_size, inode_size, nspath, mkfsoptions,
1196 mountfsoptions, backfstype, backdevname, deny_sec,
1199 node = findByName(lustre, node_name, "node")
1200 node_add_profile(gen, node, 'osd', osd_uuid)
1201 lustre.appendChild(osd)
1203 def del_ost(gen, lustre, options):
1204 ostname = get_option(options, 'ost')
1206 raise OptionError("del_ost: --ost requires a <ost name>")
1207 ost = findByName(lustre, ostname, "ost")
1209 error('del_ost: ', 'Unable to find ', ostname)
1210 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1212 error('del_ost: ', 'Unable to find uuid for ', ostname)
1213 lovname = get_option(options, 'lov')
1215 lov = findByName(lustre, lovname, "lov")
1217 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1218 lov_del_osc(gen, lustre, lov, ost_uuid, options)
1219 # if the user specified a speficic LOV don't delete the OST itself
1222 # remove OSD references from all LOVs
1223 for lov in lustre.getElementsByTagName('lov'):
1224 lov_del_osc(gen, lustre, lov, ost_uuid, options)
1228 # move the OST description to the update record
1229 lustre.removeChild(ost)
1230 info.appendChild(ost)
1232 active_ref = ost.getElementsByTagName('active_ref')
1234 error('ost has no osd ref:', ostname)
1236 # move the OSD description to the update record
1237 osd_uuid = active_ref[0].getAttribute('uuidref')
1238 osd = lookup(lustre, osd_uuid)
1239 lustre.removeChild(osd)
1240 info.appendChild(osd)
1242 # make a copy of the OSS description in the update record
1243 # XXX - should check to make sure one doesn't already exist.
1244 node_ref = osd.getElementsByTagName('node_ref')
1246 error('osd has no node ref:', ostname)
1247 node_uuid = node_ref[0].getAttribute('uuidref')
1248 node = lookup(lustre, node_uuid)
1250 error('unable to locate node for node ref:', node_uuid)
1252 node_rec = node.cloneNode(1)
1253 info.appendChild(node_rec)
1255 prof_ref = node.getElementsByTagName('profile_ref')
1257 error('node has no profile ref:', node)
1258 profile_uuid = prof_ref[0].getAttribute('uuidref')
1260 # make a copy of the OSS's profile in the update record
1261 # XXX - should check to make sure one doesn't already exist.
1262 profile = lookup(lustre, profile_uuid)
1263 profile_rec = profile.cloneNode(1)
1264 info.appendChild(profile_rec)
1266 # delete all references to this OSD in the OSS's current profile
1267 for osd_ref in profile.getElementsByTagName('osd_ref'):
1268 if osd_uuid == osd_ref.getAttribute('uuidref'):
1269 profile.removeChild(osd_ref)
1271 # XXX - We should cleanup the node and profile elements if they
1272 # no longer serve a purpose.
1273 addUpdate(gen, lustre, info)
1275 def add_cmobd(gen, lustre, options):
1276 node_name = get_option(options, 'node')
1277 name = get_option(options, 'cmobd')
1278 uuid = new_uuid(name)
1280 master_name = get_option(options, 'master_obd')
1281 cache_name = get_option(options, 'cache_obd')
1283 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1284 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1286 if not master_uuid or not cache_uuid:
1288 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1290 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1292 if not master_uuid or not cache_uuid:
1294 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1296 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1298 if not master_uuid or not cache_uuid:
1300 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1302 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1305 error("cannot find master_uuid by name '" + master_name + "'")
1307 error("cannot find cache_uuid by name '" + cache_name + "'")
1309 node = findByName(lustre, node_name, "node")
1310 node_add_profile(gen, node, "cmobd", uuid)
1312 master_node = lookup(lustre, master_uuid)
1313 cache_node = lookup(lustre, cache_uuid)
1315 error("cannot find master node by its uuid " + master_uuid);
1317 error("cannot find cache node by its uuid " + cache_uuid);
1319 active = master_node.getElementsByTagName('active_ref')
1321 active_uuid = active[0].getAttribute('uuidref')
1322 active_node = lookup(lustre, active_uuid)
1323 if not active_node.getElementsByTagName('obdtype'):
1324 gen.addElement(active_node, 'obdtype', 'master')
1326 active = cache_node.getElementsByTagName('active_ref')
1328 active_uuid = active[0].getAttribute('uuidref')
1329 active_node = lookup(lustre, active_uuid)
1330 if not active_node.getElementsByTagName('obdtype'):
1331 gen.addElement(active_node, 'obdtype', 'cache')
1333 cmobd = gen.cmobd(name, uuid, master_uuid, cache_uuid)
1334 lustre.appendChild(cmobd)
1336 def add_cobd(gen, lustre, options):
1337 node_name = get_option(options, 'node')
1338 name = get_option(options, 'cobd')
1339 uuid = new_uuid(name)
1341 master_name = get_option(options, 'master_obd')
1342 cache_name = get_option(options, 'cache_obd')
1345 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1347 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1350 node = lookup(lustre, master_uuid)
1351 rets = node.getElementsByTagName('lov_tgt')
1353 ost_uuid = ret.getAttribute('uuidref')
1354 ost_node = lookup(lustre, ost_uuid)
1355 active = ost_node.getElementsByTagName('active_ref')
1357 osd_uuid = active[0].getAttribute('uuidref')
1358 osd_node = lookup(lustre, osd_uuid)
1359 if not osd_node.getElementsByTagName('obdtype'):
1360 gen.addElement(osd_node, 'obdtype', 'master')
1363 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1365 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1368 node = lookup(lustre, cache_uuid)
1369 rets = node.getElementsByTagName('lov_tgt')
1371 ost_uuid = ret.getAttribute('uuidref')
1372 ost_node = lookup(lustre, ost_uuid)
1373 active = ost_node.getElementsByTagName('active_ref')
1375 osd_uuid = active[0].getAttribute('uuidref')
1376 osd_node = lookup(lustre, osd_uuid)
1377 if not osd_node.getElementsByTagName('obdtype'):
1378 gen.addElement(osd_node, 'obdtype', 'cache')
1380 if not master_uuid or not cache_uuid:
1381 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1383 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1386 mds_node = lookup(lustre, master_uuid)
1387 ret = mds_node.getElementsByTagName('active_ref')
1389 mdsdev_uuid = ret[0].getAttribute('uuidref')
1390 mdsdev_node = lookup(lustre, mdsdev_uuid)
1391 if not mdsdev_node.getElementsByTagName('obdtype'):
1392 gen.addElement(mdsdev_node, 'obdtype', 'master')
1394 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1396 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1399 mds_node = lookup(lustre, cache_uuid)
1400 ret = mds_node.getElementsByTagName('active_ref')
1402 mdsdev_uuid = ret[0].getAttribute('uuidref')
1403 mdsdev_node = lookup(lustre, mdsdev_uuid)
1404 if not mdsdev_node.getElementsByTagName('obdtype'):
1405 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1407 if not master_uuid or not cache_uuid:
1408 panic("add_cobd", "cannot find master or cache by names '" +
1409 master_name + "' and '" + cache_name + "'")
1411 node = findByName(lustre, node_name, "node")
1412 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1413 lustre.appendChild(cobd)
1415 def add_echo_client(gen, lustre, options):
1416 """ add an echo client to the profile for this node. """
1417 node_name = get_option(options, 'node')
1418 lov_name = get_option(options, 'ost')
1420 node = findByName(lustre, node_name, 'node')
1422 echoname = new_name('ECHO_'+ node_name)
1423 echo_uuid = new_uuid(echoname)
1424 node_add_profile(gen, node, 'echoclient', echo_uuid)
1426 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1428 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1430 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1431 lustre.appendChild(echo)
1433 def add_lov(gen, lustre, options):
1434 """ create a lov """
1436 lov_orig = get_option(options, 'lov')
1437 name = new_name(lov_orig)
1438 if name != lov_orig:
1439 warning("name:", lov_orig, "already used. using:", name)
1441 lmv_name = get_option(options, 'lmv')
1442 mds_name = get_option(options, 'mds')
1443 aware = get_option(options, 'aware')
1445 if not mds_name and not lmv_name:
1446 error("LOV: either MDS or LMV must be specified.");
1447 if mds_name and lmv_name:
1448 error("LOV: either MDS or LMV must be specified.");
1450 stripe_sz = get_option_int(options, 'stripe_sz')
1451 stripe_cnt = get_option_int(options, 'stripe_cnt')
1452 pattern = get_option_int(options, 'stripe_pattern')
1453 uuid = new_uuid(name)
1455 ret = findByName(lustre, name, "lov")
1457 error("LOV: ", name, " already exists.")
1460 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1462 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1464 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1465 lustre.appendChild(lov)
1467 # add an lovconfig entry to the active mdsdev profile
1468 lovconfig_name = new_name('LVCFG_' + name)
1469 lovconfig_uuid = new_uuid(lovconfig_name)
1472 md_tgt = findByName(lustre, mds_name, "mds")
1474 error("can't find MDS '" + mds_name + "'")
1476 md_tgt = findByName(lustre, lmv_name, "lmv")
1478 error("can't find LMV '" + lmv_name + "'")
1480 md_tgt.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1481 md_tgt.appendChild(gen.ref("client", uuid))
1483 # adding lovconfig and client to aware MD targets
1485 md_names = string.split(aware, ',');
1486 for md_name in md_names:
1488 md_tgt = findByName(lustre, md_name, "mds")
1490 md_tgt = findByName(lustre, md_name, "lmv")
1493 error("can't find '" + mds_name + "'")
1495 md_tgt.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1496 md_tgt.appendChild(gen.ref("client", uuid))
1498 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1499 lustre.appendChild(lovconfig)
1501 def add_default_lov(gen, lustre, mds_name, lov_name):
1502 """ create a default lov """
1504 stripe_sz = DEFAULT_STRIPE_SZ
1505 stripe_cnt = DEFAULT_STRIPE_CNT
1506 pattern = DEFAULT_STRIPE_PATTERN
1507 uuid = new_uuid(lov_name)
1509 ret = findByName(lustre, lov_name, "lov")
1511 error("LOV: ", lov_name, " already exists.")
1513 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1514 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1515 lustre.appendChild(lov)
1517 # add an lovconfig entry to the active mdsdev profile
1518 lovconfig_name = new_name('LVCFG_' + lov_name)
1519 lovconfig_uuid = new_uuid(lovconfig_name)
1520 mds = findByName(lustre, mds_name)
1521 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1522 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1523 lustre.appendChild(lovconfig)
1525 def add_lmv(gen, lustre, options):
1526 """ create a lmv """
1528 lmv_orig = get_option(options, 'lmv')
1529 name = new_name(lmv_orig)
1530 if name != lmv_orig:
1531 warning("name:", lmv_orig, "already used. using:", name)
1533 uuid = new_uuid(name)
1534 ret = findByName(lustre, name, "lmv")
1536 error("LMV: ", name, " already exists.")
1538 lmv = gen.lmv(name, uuid)
1539 lustre.appendChild(lmv)
1541 def new_filesystem(gen, lustre, fs_name, mds_uuid, obd_uuid,
1542 mgmt_uuid, gks_uuid):
1543 fs_uuid = new_uuid(fs_name)
1544 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, obd_uuid,
1545 mgmt_uuid, gks_uuid)
1546 lustre.appendChild(fs)
1549 def get_fs_uuid(gen, lustre, fs_name, mds_name, obd_name,
1550 mgmt_name, gks_name):
1551 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1553 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1555 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1557 error("mds '" + mds_name + "' is not found")
1559 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1561 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1563 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1565 error("ost '" + obd_name + "' is not found")
1568 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1573 gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
1577 fs_uuid = lookup_filesystem(lustre, fs_name)
1579 fs = lookup(lustre, fs_uuid)
1580 if not ref_exists(fs, mds_uuid):
1581 fs.appendChild(gen.ref("mds", mds_uuid))
1582 if not ref_exists(fs, obd_uuid):
1583 fs.appendChild(gen.ref("obd", obd_uuid))
1584 if gks_uuid and not ref_exists(fs, gks_uuid):
1585 fs.appendChild(gen.ref("gks", gks_uuid))
1587 fs_uuid = new_filesystem(gen, lustre, fs_name,
1589 mgmt_uuid, gks_uuid)
1592 def add_filesystem(gen, lustre, options):
1593 """ create filesytem """
1594 fs_orig = get_option(options, 'filesystem')
1595 name = new_name(fs_orig)
1597 warning("name:", fs_orig, "already used. using:", name)
1599 uuid = new_uuid(name)
1600 ret = findByName(lustre, name, "filesystem")
1602 error("FS: ", name, " already exists.")
1604 gks_name = get_option(options, 'gks')
1606 gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
1609 fs = gen.filesystem(name, uuid, "", "", "", gks_uuid)
1610 lustre.appendChild(fs)
1612 def add_mtpt(gen, lustre, options):
1613 """ create mtpt on a node """
1614 node_name = get_option(options, 'node')
1616 path = get_option(options, 'path')
1617 clientoptions = get_option(options, "clientoptions")
1618 mds_sec = get_option(options, "mds_sec")
1619 oss_sec = get_option(options, "oss_sec")
1620 fs_name = get_option(options, 'filesystem')
1622 lov_name = get_option(options, 'lov')
1623 ost_name = get_option(options, 'ost')
1624 mds_name = get_option(options, 'mds')
1625 gks_name = get_option(options, 'gks')
1627 mds_name = get_option(options, 'lmv')
1629 error("--add mtpt requires either --mds or --lmv.")
1632 error("--add mtpt requires --lov lov_name or --ost ost_name")
1634 warning("use default value for lov, due no --lov lov_name provided")
1635 lov_name = new_name("lov_default")
1636 add_default_lov(gen, lustre, mds_name, lov_name)
1637 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1639 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1640 lov = findByName(lustre, lov_name, "lov")
1641 lov_add_osc(gen, lustre, lov, ost_uuid, options)
1644 fs_name = new_name("FS_fsname")
1645 mgmt_name = get_option(options, 'mgmt')
1649 fs_uuid = get_fs_uuid(gen, lustre, fs_name,
1650 mds_name, lov_name, mgmt_name, gks_name)
1652 name = new_name('MNT_'+ node_name)
1654 ret = findByName(lustre, name, "mountpoint")
1656 # this can't happen, because new_name creates unique names
1657 error("MOUNTPOINT: ", name, " already exists.")
1659 uuid = new_uuid(name)
1660 mtpt = gen.mountpoint(name, uuid, fs_uuid, path,
1661 clientoptions, mds_sec, oss_sec)
1662 node = findByName(lustre, node_name, "node")
1664 error('node:', node_name, "not found.")
1665 node_add_profile(gen, node, "mountpoint", uuid)
1666 lustre.appendChild(mtpt)
1668 def commit_version(gen, lustre):
1669 update = findLastUpdate(lustre)
1671 version = int(update.getAttribute("version")) + 1
1675 new = gen.update(str(version))
1676 lustre.appendChild(new)
1679 ############################################################
1680 # Command line processing
1682 class OptionError (exceptions.Exception):
1683 def __init__(self, args):
1686 def get_option(options, tag):
1687 """Look for tag in options hash and return the value if set. If not
1688 set, then if return default it is set, otherwise exception."""
1689 if options.__getattr__(tag) != None:
1690 return options.__getattr__(tag)
1692 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1694 def get_option_int(options, tag):
1695 """Return an integer option. Raise exception if the value is not an int"""
1696 val = get_option(options, tag)
1700 raise OptionError("--%s <num> (value must be integer)" % (tag))
1703 # simple class for profiling
1710 self._start = time.time()
1711 def stop(self, msg=''):
1712 self._stop = time.time()
1716 return self._stop - self._start
1717 def display(self, msg):
1719 str = '%s: %g secs' % (msg, d)
1722 #################################################################
1723 # function cmdlinesplit used to split cmd line from batch file
1725 def cmdlinesplit(cmdline):
1727 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1728 single_quote = re.compile(r"'(.*?)'")
1729 escaped = re.compile(r'\\(.)')
1730 esc_quote = re.compile(r'\\([\\"])')
1731 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1735 while i < len(cmdline):
1738 match = double_quote.match(cmdline, i)
1740 print "Unmatched double quote:", cmdline
1743 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1744 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1747 match = single_quote.match(cmdline, i)
1749 print "Unmatched single quote:", cmdline
1752 if arg is None: arg = match.group(1)
1753 else: arg = arg + match.group(1)
1756 match = escaped.match(cmdline, i)
1758 print "Unmatched backslash", cmdline
1761 if arg is None: arg = match.group(1)
1762 else: arg = arg + match.group(1)
1764 elif c in string.whitespace:
1766 arg_list.append(str(arg))
1768 while i < len(cmdline) and cmdline[i] in string.whitespace:
1771 match = outside.match(cmdline, i)
1774 if arg is None: arg = match.group()
1775 else: arg = arg + match.group()
1777 if arg != None: arg_list.append(str(arg))
1781 ############################################################
1785 def add(devtype, gen, lustre, options):
1786 if devtype == 'net':
1787 add_net(gen, lustre, options)
1788 elif devtype == 'mtpt':
1789 add_mtpt(gen, lustre, options)
1790 elif devtype == 'mds':
1791 add_mds(gen, lustre, options)
1792 elif devtype == 'ost':
1793 add_ost(gen, lustre, options)
1794 elif devtype == 'lov':
1795 add_lov(gen, lustre, options)
1796 elif devtype == 'route':
1797 add_route(gen, lustre, options)
1798 elif devtype == 'node':
1799 add_node(gen, lustre, options)
1800 elif devtype == 'echo_client':
1801 add_echo_client(gen, lustre, options)
1802 elif devtype == 'cobd':
1803 add_cobd(gen, lustre, options)
1804 elif devtype == 'cmobd':
1805 add_cmobd(gen, lustre, options)
1806 elif devtype == 'mgmt':
1807 add_mgmt(gen, lustre, options)
1808 elif devtype == 'lmv':
1809 add_lmv(gen, lustre, options)
1810 elif devtype == 'filesystem':
1811 add_filesystem(gen, lustre, options)
1812 elif devtype == 'gks':
1813 add_gks(gen, lustre, options)
1815 error("unknown device type:", devtype)
1817 def delete(devtype, gen, lustre, options):
1818 if devtype == 'ost':
1819 del_ost(gen, lustre, options)
1820 elif options.delete:
1821 error("delete not supported for device type:", devtype)
1822 elif options.deactivate:
1823 error("deactivate not supported for device type:", devtype)
1825 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1827 def commit(gen, lustre):
1828 commit_version(gen, lustre)
1830 def do_command(gen, lustre, options, args):
1832 add(options.add, gen, lustre, options)
1833 elif options.delete:
1834 delete(options.delete, gen, lustre, options)
1835 elif options.deactivate:
1836 delete(options.deactivate, gen, lustre, options)
1837 elif options.commit:
1840 error("Missing command")
1843 cl = Lustre.Options("lmc", "", lmc_options)
1845 options, args = cl.parse(sys.argv[1:])
1846 except Lustre.OptionError, e:
1850 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1852 if options.reference:
1859 outFile = options.merge
1860 if os.access(outFile, os.R_OK):
1861 doc = xml.dom.minidom.parse(outFile)
1863 doc = new_lustre(xml.dom.minidom)
1865 doc = xml.dom.minidom.parse(options.input)
1867 doc = new_lustre(xml.dom.minidom)
1870 outFile = options.output
1872 lustre = doc.documentElement
1874 if lustre.tagName != "lustre":
1875 print "Existing config not valid."
1878 gen = GenConfig(doc)
1881 fp = open(options.batch)
1882 batchCommands = fp.readlines()
1884 for cmd in batchCommands:
1886 options, args = cl.parse(cmdlinesplit(cmd))
1887 if options.merge or options.input or options.output:
1888 print "The batchfile should not contain --merge, --input or --output."
1890 do_command(gen, lustre, options, args)
1891 except OptionError, e:
1893 except Lustre.OptionError, e:
1897 do_command(gen, lustre, options, args)
1898 except OptionError, e:
1899 panic(string.join(sys.argv),e)
1900 except Lustre.OptionError, e:
1906 printDoc(doc, open(outFile,"w"))
1908 if __name__ == "__main__":