2 # Copyright (C) 2002 Cluster File Systems, Inc.
3 # Author: Robert Read <rread@clusterfs.com>
5 # This file is part of Lustre, http://www.lustre.org.
7 # Lustre is free software; you can redistribute it and/or
8 # modify it under the terms of version 2 of the GNU General Public
9 # License as published by the Free Software Foundation.
11 # Lustre is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Lustre; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 lmc - lustre configuration data manager
24 See Lustre book (http://www.lustre.org/docs/lustre.pdf) for documentation on lmc.
28 import sys, os, getopt, string, exceptions, re
29 import xml.dom.minidom
31 def printDoc(doc, stream=sys.stdout):
33 from xml.dom.ext import PrettyPrint
34 PrettyPrint(doc, stream)
36 stream.write(doc.toxml())
40 PYMOD_DIR = "/usr/lib/lustre/python"
42 def development_mode():
43 base = os.path.dirname(sys.argv[0])
44 if os.access(base+"/Makefile.am", os.R_OK):
48 if not development_mode():
49 sys.path.append(PYMOD_DIR)
54 DEFAULT_STRIPE_SZ = 1048576
55 DEFAULT_STRIPE_CNT = 1
56 DEFAULT_STRIPE_PATTERN = 0
60 print """usage: lmc --add object [object parameters]
62 Object creation command summary:
70 --ptldebug debug_level
71 --subsystem subsystem_name
77 --nettype tcp|elan|gm|openib|iib|vib|ra
78 --hostaddr ip[/netmask]
91 --backfstype ldiskfs|ext3|tmpfs
99 --mountfsoptions options
100 --root_squash uid:gid
101 --no_root_squash ptl_nid
104 --mds_deny_sec flavor[,flavor[...]]
123 --fstype ldiskfs|ext3
124 --backfstype ldiskfs|ext3|tmpfs
127 --osdtype obdecho|obdfilter
129 --mkfsoptions options
130 --mountfsoptions options
132 --ost_deny_sec flavor[,flavor[...]]
142 --add mtpt - Mountpoint
147 --ost ost_name OR --lov lov_name
148 --clientoptions options
156 --gateway_cluster_id nid
157 --target_cluster_id nid
164 --add mgmt - Management/monitoring service
166 --mgmt mgmt_service_name
173 --master_obd obd_name
178 --master_obd obd_name
184 --commit - Close a configuration version, and start a new one
187 PARAM = Lustre.Options.PARAM
188 PARAMLIST = Lustre.Options.PARAMLIST
190 # lmc input/output options
191 ('reference', "Print short reference for commands."),
192 ('verbose,v', "Print system commands as they are run."),
193 ('merge,m', "Append to the specified config file.", PARAM),
194 ('output,o', "Write XML configuration into given output file. Overwrite existing content.", PARAM),
195 ('input,i', "", PARAM),
196 ('batch', "Used to execute lmc commands in batch mode.", PARAM),
200 ('delete', "", PARAM),
201 ('deactivate', "", PARAM),
202 ('commit', "Commit all config changes and start a new version"),
205 ('node', "Add a new node in the cluster configuration.", PARAM),
206 ('timeout', "Set timeout to initiate recovery.", PARAM),
207 ('upcall', "Set both lustre and portals upcall scripts.", PARAM),
208 ('lustre_upcall', "Set location of lustre upcall script.", PARAM),
209 ('portals_upcall', "Set location of portals upcall script.", PARAM),
210 ('ptldebug', "Set the portals debug level", PARAM),
211 ('subsystem', "Specify which Lustre subsystems have debug output recorded in the log", PARAM),
214 ('nettype', "Specify the network type. This can be tcp/elan/gm/openib/iib/vib/ra.", PARAM),
215 ('nid', "Give the network ID, e.g ElanID/IP Address as used by portals.", PARAM),
216 ('port', "Optional argument to specify the TCP port number.", PARAM, DEFAULT_PORT),
217 ('hostaddr', "Optional argument to specify the host address.", PARAMLIST),
218 ('cluster_id', "Specify the cluster ID", PARAM, "0"),
221 ('route', "Add a new route for the cluster.", PARAM),
222 ('router', "Optional flag to mark a node as router."),
223 ('gw', "Specify the nid of the gateway for a route.", PARAM),
224 ('gateway_cluster_id', "", PARAM, "0"),
225 ('target_cluster_id', "", PARAM, "0"),
226 ('lo', "For a range route, this is the low value nid.", PARAM),
227 ('hi', "For a range route, this is a hi value nid.", PARAM,""),
229 # servers: mds and ost
230 ('mds', "Specify MDS name.", PARAM,""),
231 ('ost', "Specify the OST name.", PARAM,""),
232 ('osdtype', "This could obdfilter or obdecho.", PARAM, "obdfilter"),
233 ('failover', "Enable failover support on OSTs or MDS?"),
234 ('group', "", PARAM),
235 ('dev', "Path of the device on local system.", PARAM,""),
236 ('backdev', "Path of the device for backing storage on local system.", PARAM,""),
237 ('size', "Specify the size of the device if needed.", PARAM,"0"),
238 ('journal_size', "Specify new journal size for underlying file system.", PARAM,"0"),
239 ('inode_size', "Specify new inode size for underlying file system.", PARAM,"0"),
240 ('fstype', "Optional argument to specify the filesystem type.", PARAM, "ext3"),
241 ('backfstype', "Optional argument to specify the backing filesystem type.", PARAM, "ext3"),
242 ('mkfsoptions', "Optional argument to mkfs.", PARAM, ""),
243 ('mountfsoptions', "Optional argument to mount fs.", PARAM, ""),
244 ('ostuuid', "Optional argument to specify OST UUID", PARAM,""),
245 ('mdsuuid', "Optional argument to specify MDS UUID", PARAM,""),
246 ('root_squash', "MDS squash root to appointed uid.", PARAM, ""),
247 ('no_root_squash', "Don't squash root for appointed nid.", PARAM, ""),
248 ('nspath', "Local mount point of server namespace.", PARAM,""),
249 ('mds_mds_sec', "Specify the secure flavor for connection from this mds to other mds.", PARAM, ""),
250 ('mds_oss_sec', "Specify the secure flavor for connection from this mds to ost.", PARAM, ""),
251 ('mds_deny_sec', "Specify the secure flavor which is denied from remote to this mds.", PARAM, ""),
252 ('ost_deny_sec', "Specify the secure flavor which is denied from remote to this ost.", PARAM, ""),
254 ('migrate', "used for offline migrate of an ost in conjunctio with add/delete"),
256 # clients: mountpoint and echo
257 ('echo_client', "", PARAM),
258 ('path', "Specify the mountpoint for Lustre.", PARAM),
259 ('filesystem', "Lustre filesystem name", PARAM,""),
260 ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
261 ('mds_sec', "Specify the secure flavor for connection from this client to mds.", PARAM, ""),
262 ('oss_sec', "Specify the secure flavor for connection from this client to ost.", PARAM, ""),
265 ('lov', "Specify LOV name.", PARAM,""),
266 ('index', "Specify index for OBD in LOV target table.", PARAM),
267 ('stripe_sz', "Specify the stripe size in bytes.", PARAM),
268 ('stripe_cnt', "Specify the number of OSTs each file should be striped on.", PARAM, 0),
269 ('stripe_pattern', "Specify the stripe pattern. RAID 0 is the only one currently supported.", PARAM, 0),
273 ('master_obd', "Specify the real device for the cache obd system.", PARAM),
274 ('cache_obd', "Specify the cache device for the cache obd system.", PARAM),
275 ('cobd', "Specify COBD name", PARAM),
276 ('cachelmv', "Specify cache lmv name", PARAM, ""),
277 ('masterlmv', "Specify master lmv name", PARAM, ""),
280 ('master_obd', "Specify the master device for the cmobd system.", PARAM),
281 ('cache_obd', "Specify the cache device for the cmobd obd system.", PARAM),
282 ('cmobd', "Specify COBD name", PARAM),
285 ('mgmt', "Specify management/monitoring service name.", PARAM, ""),
288 ('lmv', "Specify LMV name.", PARAM,""),
291 ('gks', "Specify gks name.", PARAM,""),
296 msg = string.join(map(str,args))
297 raise OptionError("Error: " + msg)
306 msg = string.join(map(str,args))
307 print "Warning: ", msg
310 # manage names and uuids
311 # need to initialize this by walking tree to ensure
312 # no duplicate names or uuids are created.
313 # this are just place holders for now.
314 # consider changing this to be like OBD-dev-host
318 while names.has_key(ret):
319 ret = "%s_%d" % (base, ctr)
326 ret = "%s_UUID" % (name)
327 if len(ret) > UUID_MAX_LENGTH:
328 ret = ret[-UUID_MAX_LENGTH:]
329 while uuids.has_key(ret):
330 ret = "%s_UUID_%d" % (name, ctr)
332 if len(ret) > UUID_MAX_LENGTH:
333 ret = ret[-UUID_MAX_LENGTH:]
339 ldlm_uuid = 'ldlm_UUID'
342 """Create a new empty lustre document"""
343 # adding ldlm here is a bit of a hack, but one is enough.
344 str = """<lustre version="%s">
345 <ldlm name="%s" uuid="%s"/>
346 </lustre>""" % (Lustre.CONFIG_VERSION, ldlm_name, ldlm_uuid)
347 return dom.parseString(str)
353 """initialize auto-name generation tables"""
355 # get all elements that contain a name attribute
356 for n in doc.childNodes:
357 if n.nodeType == n.ELEMENT_NODE:
359 names[getName(n)] = 1
360 uuids[getUUID(n)] = 1
363 def get_format_flag(options):
368 ############################################################
369 # Build config objects using DOM
374 def __init__(self, doc):
377 def ref(self, type, uuid):
378 """ generate <[type]_ref uuidref="[uuid]"/> """
379 tag = "%s_ref" % (type)
380 ref = self.doc.createElement(tag)
381 ref.setAttribute("uuidref", uuid)
384 def dev(self, devname):
385 """ generate <dev devpath="[devname]"/> """
386 tgt = self.doc.createElement('dev')
387 tgt.setAttribute("dev", devname)
390 def newService(self, tag, name, uuid):
391 """ create a new service elmement, which requires name and uuid attributes """
392 new = self.doc.createElement(tag)
393 new.setAttribute("uuid", uuid);
394 new.setAttribute("name", name);
397 def addText(self, node, str):
398 txt = self.doc.createTextNode(str)
399 node.appendChild(txt)
401 def addElement(self, node, tag, str=None):
402 """ create a new element and add it as a child to node. If str is passed,
403 a text node is created for the new element"""
404 new = self.doc.createElement(tag)
406 self.addText(new, str)
407 node.appendChild(new)
410 def network(self, name, uuid, nid, cluster_id, net, hostaddr="",
412 """create <network> node"""
413 network = self.newService("network", name, uuid)
414 network.setAttribute("nettype", net);
415 self.addElement(network, "nid", nid)
416 self.addElement(network, "clusterid", cluster_id)
417 for host in hostaddr:
418 self.addElement(network, "hostaddr", host)
420 self.addElement(network, "port", "%d" %(port))
424 def routetbl(self, name, uuid):
425 """create <routetbl> node"""
426 rtbl = self.newService("routetbl", name, uuid)
429 def route(self, gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi):
430 """ create one entry for the route table """
431 ref = self.doc.createElement('route')
432 ref.setAttribute("type", gw_net_type)
433 ref.setAttribute("gw", gw)
434 ref.setAttribute("gwclusterid", gw_cluster_id)
435 ref.setAttribute("tgtclusterid", tgt_cluster_id)
436 ref.setAttribute("lo", lo)
438 ref.setAttribute("hi", hi)
441 def profile(self, name, uuid):
442 """ create a host """
443 profile = self.newService("profile", name, uuid)
446 def node(self, name, uuid, prof_uuid):
447 """ create a host """
448 node = self.newService("node", name, uuid)
449 node.appendChild(self.ref("profile", prof_uuid))
452 def ldlm(self, name, uuid):
453 """ create a ldlm """
454 ldlm = self.newService("ldlm", name, uuid)
457 def osd(self, name, uuid, fstype, osdtype, devname, format, ost_uuid,
458 node_uuid, dev_size=0, journal_size=0, inode_size=0, nspath="",
459 mkfsoptions="", mountfsoptions="", backfstype="", backdevname="",
461 osd = self.newService("osd", name, uuid)
462 osd.setAttribute('osdtype', osdtype)
463 osd.appendChild(self.ref("target", ost_uuid))
464 osd.appendChild(self.ref("node", node_uuid))
465 osd.appendChild(self.dev(devname))
468 self.addElement(osd, "fstype", fstype)
470 self.addElement(osd, "backfstype", backfstype)
472 self.addElement(osd, "backdevpath", backdevname)
474 dev = self.addElement(osd, "devpath", devname)
475 self.addElement(osd, "autoformat", format)
477 self.addElement(osd, "devsize", "%s" % (dev_size))
479 self.addElement(osd, "journalsize", "%s" % (journal_size))
481 self.addElement(osd, "inodesize", "%s" % (inode_size))
483 self.addElement(osd, "mkfsoptions", mkfsoptions)
485 self.addElement(osd, "mountfsoptions", mountfsoptions)
487 self.addElement(osd, "deny_sec", deny_sec)
489 self.addElement(osd, "nspath", nspath)
492 def cobd(self, name, uuid, master_uuid, cache_uuid):
493 cobd = self.newService("cobd", name, uuid)
494 cobd.appendChild(self.ref("masterobd",master_uuid))
495 cobd.appendChild(self.ref("cacheobd",cache_uuid))
498 def cmobd(self, name, uuid, master_uuid, cache_uuid):
499 cmobd = self.newService("cmobd", name, uuid)
500 cmobd.appendChild(self.ref("masterobd",master_uuid))
501 cmobd.appendChild(self.ref("cacheobd",cache_uuid))
504 def ost(self, name, uuid, osd_uuid, group=""):
505 ost = self.newService("ost", name, uuid)
506 ost.appendChild(self.ref("active", osd_uuid))
508 self.addElement(ost, "group", group)
511 def oss(self, name, uuid):
512 oss = self.newService("oss", name, uuid)
515 def lov(self, name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern):
516 lov = self.newService("lov", name, uuid)
517 lov.appendChild(self.ref("mds", mds_uuid))
518 lov.setAttribute("stripesize", str(stripe_sz))
519 lov.setAttribute("stripecount", str(stripe_cnt))
520 lov.setAttribute("stripepattern", str(pattern))
523 def lov_tgt(self, obd_uuid, lov_uuid, index, generation):
524 tgt = self.doc.createElement('lov_tgt')
525 tgt.setAttribute("uuidref", obd_uuid)
526 tgt.setAttribute("lov_uuid", lov_uuid)
527 tgt.setAttribute("index", index)
528 tgt.setAttribute("generation", generation)
529 tgt.setAttribute("active", '1')
532 def lovconfig(self, name, uuid, lov_uuid):
533 lovconfig = self.newService("lovconfig", name, uuid)
534 lovconfig.appendChild(self.ref("lov", lov_uuid))
537 def lmv_tgt(self, mdt_uuid):
538 tgt = self.doc.createElement('lmv_tgt')
539 tgt.setAttribute("uuidref", mdt_uuid)
542 def lmv(self, name, uuid):
543 lmv = self.newService("lmv", name, uuid)
546 def gks(self, name, uuid, gkd_uuid):
547 gks = self.newService("gks", name, uuid)
548 gks.appendChild(self.ref("active", gkd_uuid))
551 def gkd(self, name, uuid, node_uuid, gks_uuid):
552 gkd = self.newService("gkd", name, uuid)
553 gkd.appendChild(self.ref("node", node_uuid))
554 gkd.appendChild(self.ref("target", gks_uuid))
557 def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
558 mds = self.newService("mds", name, uuid)
559 mds.appendChild(self.ref("active", mdd_uuid))
561 self.addElement(mds, "group", group)
564 def mdsdev(self, name, uuid, fstype, devname, format, node_uuid,
565 mds_uuid, dev_size=0, journal_size=0, inode_size=256,
566 nspath="", mkfsoptions="", mountfsoptions="", backfstype="",
567 backdevname="",lmv_uuid="", root_squash="", no_root_squash="",
568 mds_sec="", oss_sec="", deny_sec=""):
569 mdd = self.newService("mdsdev", name, uuid)
570 self.addElement(mdd, "fstype", fstype)
572 self.addElement(mdd, "backfstype", backfstype)
573 dev = self.addElement(mdd, "devpath", devname)
575 self.addElement(mdd, "backdevpath", backdevname)
576 self.addElement(mdd, "autoformat", format)
578 self.addElement(mdd, "devsize", "%s" % (dev_size))
580 self.addElement(mdd, "journalsize", "%s" % (journal_size))
582 self.addElement(mdd, "inodesize", "%s" % (inode_size))
584 self.addElement(mdd, "nspath", nspath)
586 self.addElement(mdd, "mkfsoptions", mkfsoptions)
588 self.addElement(mdd, "mountfsoptions", mountfsoptions)
590 self.addElement(mdd, "root_squash", root_squash)
592 self.addElement(mdd, "no_root_squash", no_root_squash)
594 self.addElement(mdd, "mds_sec", mds_sec)
596 self.addElement(mdd, "oss_sec", oss_sec)
598 self.addElement(mdd, "deny_sec", deny_sec)
599 mdd.appendChild(self.ref("node", node_uuid))
600 mdd.appendChild(self.ref("target", mds_uuid))
602 dev = self.dev(devname)
607 mdd.appendChild(self.ref("lmv", lmv_uuid))
608 self.addElement(mdd, "lmv", lmv_uuid)
612 def mgmt(self, mgmt_name, mgmt_uuid, node_uuid):
613 mgmt = self.newService("mgmt", mgmt_name, mgmt_uuid)
614 mgmt.appendChild(self.ref("node", node_uuid))
615 # Placeholder until mgmt-service failover.
616 mgmt.appendChild(self.ref("active", mgmt_uuid))
619 def mountpoint(self, name, uuid, fs_uuid, path, clientoptions,
621 mtpt = self.newService("mountpoint", name, uuid)
622 mtpt.appendChild(self.ref("filesystem", fs_uuid))
623 self.addElement(mtpt, "path", path)
625 self.addElement(mtpt, "clientoptions", clientoptions)
627 self.addElement(mtpt, "mds_sec", mds_sec)
629 self.addElement(mtpt, "oss_sec", oss_sec)
632 def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid):
633 fs = self.newService("filesystem", name, uuid)
634 fs.appendChild(self.ref("mds", mds_uuid))
635 fs.appendChild(self.ref("obd", obd_uuid))
636 fs.appendChild(self.ref("gks", gks_uuid))
638 fs.appendChild(self.ref("mgmt", mgmt_uuid))
641 def echo_client(self, name, uuid, osc_uuid):
642 ec = self.newService("echoclient", name, uuid)
643 ec.appendChild(self.ref("obd", osc_uuid))
646 def update(self, version):
647 new = self.doc.createElement("update")
648 new.setAttribute("version", version)
651 def add(self, lov, ost, index, gen):
652 new = self.doc.createElement("add")
653 new.setAttribute("lov_uuidref", lov)
654 new.setAttribute("ost_uuidref", ost)
655 new.setAttribute("index", index)
656 new.setAttribute("generation", gen)
659 def delete(self, lov, ost, index, gen, options):
661 new = self.doc.createElement("delete")
663 new = self.doc.createElement("deactivate")
664 new.setAttribute("lov_uuidref", lov)
665 new.setAttribute("ost_uuidref", ost)
666 new.setAttribute("index", index)
667 new.setAttribute("generation", gen)
670 ############################################################
671 # Utilities to query a DOM tree
672 # Using this functions we can treat use config information
673 # directly as a database.
675 return n.getAttribute('name')
678 return node.getAttribute('uuid')
680 def findLastUpdate(lustre):
683 for n in lustre.childNodes:
684 if n.nodeType == n.ELEMENT_NODE:
685 if n.nodeName != 'update':
687 tmp = int(n.getAttribute('version'))
689 error('malformed XML: update tag without a version attribute')
690 if tmp != version + 1:
691 error('malformed XML: expecting update record '+str(version + 1)+', found '+str(tmp)+'.')
696 def addUpdate(gen, lustre, node):
697 update = findLastUpdate(lustre)
700 #add_record = update.getElementsByTagName('add')
702 # add_record = gen.add()
703 # update.appendChild(add_record)
705 # add_record = add_record[0]
706 #add_record.appendChild(node)
707 update.appendChild(node)
709 def delUpdate(gen, lustre, node):
710 update = findLastUpdate(lustre)
713 update.appendChild(node)
715 def findByName(lustre, name, tag = ""):
716 for n in lustre.childNodes:
717 if n.nodeType == n.ELEMENT_NODE:
718 if tag and n.nodeName != tag:
720 if getName(n) == name:
723 n = findByName(n, name)
728 def lookup(node, uuid):
729 for n in node.childNodes:
730 if n.nodeType == n.ELEMENT_NODE:
731 if getUUID(n) == uuid:
739 def name2uuid(lustre, name, tag="", fatal=1):
740 ret = findByName(lustre, name, tag)
743 error('name2uuid:', '"'+name+'"', tag, 'element not found.')
748 def lookup_filesystem(lustre, mds_uuid, ost_uuid):
749 for n in lustre.childNodes:
750 if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'filesystem':
751 if ref_exists(n, mds_uuid) and ref_exists(n, ost_uuid):
755 # XXX: assumes only one network element per node. will fix this
756 # as soon as support for routers is added
757 def get_net_uuid(lustre, node_name):
758 """ get a network uuid for a node_name """
759 node = findByName(lustre, node_name, "node")
761 error ('get_net_uuid:', '"'+node_name+'"', "node element not found.")
762 net = node.getElementsByTagName('network')
764 return getUUID(net[0])
767 def lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options):
768 tgt.setAttribute('uuidref', osc_uuid)
770 gener = int(tgt.getAttribute('generation'))
772 gener = int(tgt.getAttribute('generation')) + 1
773 tgt.setAttribute('generation', str(gener))
774 tgt.setAttribute('active', '1')
775 lov_index = int(tgt.getAttribute('index'))
776 addUpdate(gen, lustre, gen.add(getUUID(lov), osc_uuid, str(lov_index),
780 def lov_add_obd(gen, lustre, lov, osc_uuid, options):
781 lov_name = getName(lov)
782 lov_uuid = getUUID(lov)
784 lov_index = get_option_int(options, 'index')
785 for tgt in lustre.getElementsByTagName('lov_tgt'):
786 if str(lov_index) == tgt.getAttribute('index'):
787 uuidref = tgt.getAttribute('uuidref')
789 raise OptionError("%s --index %d is still in use: %s" %
790 (lov_name, lov_index, uuidref))
791 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
795 for tgt in lustre.getElementsByTagName('lov_tgt'):
796 uuidref = tgt.getAttribute('uuidref')
797 tmp = int(tgt.getAttribute('index'))
798 own_lov_uuid = tgt.getAttribute('lov_uuid')
800 error('malformed xml: LOV targets are not ordered; found index '+str(tmp)+', expected '+str(lov_index)+'.')
801 uuidref = tgt.getAttribute('uuidref')
803 lov_mod_obd(gen, lustre, lov, tgt, osc_uuid, options)
805 if own_lov_uuid == lov_uuid:
806 lov_index = lov_index + 1
808 lov.appendChild(gen.lov_tgt(osc_uuid, lov_uuid, str(lov_index), '1'))
809 addUpdate(gen, lustre, gen.add(getUUID(lov), lov_uuid, str(lov_index), '1'))
811 def lov_del_obd(gen, lustre, lov, osc_uuid, options):
812 lov_name = getName(lov)
814 lov_index = get_option_int(options, 'index')
815 for tgt in lustre.getElementsByTagName('lov_tgt'):
816 index = tgt.getAttribute('index')
817 if index == lov_index:
818 uuidref = tgt.getAttribute('uuidref')
819 if uuidref != osc_uuid:
820 raise OptionError("%s --index %d contains %s, not %s" %
821 (lov_name, lov_index, osc_uuid, uuidref))
823 tgt.setAttribute('uuidref', '')
825 # bump the generation just in case...
827 gen = int(tgt.getAttribute('generation'))
829 gen = int(tgt.getAttribute('generation')) + 1
831 tgt.setAttribute('active', '0')
832 tgt.setAttribute('generation', str(gen))
834 raise OptionError("%s --index %d not in use by %s." %
835 (lov_name, lov_index, osc_uuid))
837 for tgt in lustre.getElementsByTagName('lov_tgt'):
838 uuidref = tgt.getAttribute('uuidref')
839 if uuidref == osc_uuid:
840 genera = int(tgt.getAttribute('generation'))
841 delete_rec = gen.delete(getUUID(lov),
842 osc_uuid,tgt.getAttribute('index'),
843 str(genera), options)
844 delUpdate(gen, lustre, delete_rec)
847 tgt.setAttribute('uuidref', '')
848 if not options.migrate:
850 tgt.setAttribute('active', '0')
851 tgt.setAttribute('generation', str(genera))
853 def lmv_add_obd(gen, lmv, mdc_uuid):
854 lmv.appendChild(gen.lmv_tgt(mdc_uuid))
856 def ref_exists(profile, uuid):
857 elist = profile.childNodes
859 if e.nodeType == e.ELEMENT_NODE:
860 ref = e.getAttribute('uuidref')
865 # ensure that uuid is not already in the profile
866 # return true if uuid is added
867 def node_add_profile(gen, node, ref, uuid):
868 refname = "%s_ref" % "profile"
869 ret = node.getElementsByTagName(refname)
871 error('node has no profile ref:', node)
872 prof_uuid = ret[0].getAttribute('uuidref')
873 profile = lookup(node.parentNode, prof_uuid)
875 error("no profile found:", prof_uuid)
876 if ref_exists(profile, uuid):
878 profile.appendChild(gen.ref(ref, uuid))
881 def get_attr(dom_node, attr, default=""):
882 v = dom_node.getAttribute(attr)
887 ############################################################
890 def set_node_options(gen, node, options):
892 node.setAttribute('router', '1')
894 gen.addElement(node, "timeout", get_option(options, 'timeout'))
896 default_upcall = get_option(options, 'upcall')
899 if default_upcall or options.lustre_upcall:
900 if options.lustre_upcall:
901 gen.addElement(node, 'lustreUpcall', options.lustre_upcall)
903 gen.addElement(node, 'lustreUpcall', default_upcall)
904 if default_upcall or options.portals_upcall:
905 if options.portals_upcall:
906 gen.addElement(node, 'portalsUpcall', options.portals_upcall)
908 gen.addElement(node, 'portalsUpcall', default_upcall)
910 gen.addElement(node, "ptldebug", get_option(options, 'ptldebug'))
911 if options.subsystem:
912 gen.addElement(node, "subsystem", get_option(options, 'subsystem'))
915 def do_add_node(gen, lustre, options, node_name):
916 uuid = new_uuid(node_name)
917 prof_name = new_name("PROFILE_" + node_name)
918 prof_uuid = new_uuid(prof_name)
919 profile = gen.profile(prof_name, prof_uuid)
920 node = gen.node(node_name, uuid, prof_uuid)
921 lustre.appendChild(node)
922 lustre.appendChild(profile)
924 node_add_profile(gen, node, 'ldlm', ldlm_uuid)
925 set_node_options(gen, node, options)
930 def add_node(gen, lustre, options):
931 """ create a node with a network config """
933 node_name = get_option(options, 'node')
934 ret = findByName(lustre, node_name, "node")
936 print "Node:", node_name, "exists."
938 do_add_node(gen, lustre, options, node_name)
941 def add_net(gen, lustre, options):
942 """ create a node with a network config """
944 node_name = get_option(options, 'node')
945 nid = get_option(options, 'nid')
946 cluster_id = get_option(options, 'cluster_id')
947 hostaddr = get_option(options, 'hostaddr')
948 net_type = get_option(options, 'nettype')
950 if net_type in ('tcp','openib','ra'):
951 port = get_option_int(options, 'port')
952 elif net_type in ('elan', 'gm', 'iib', 'vib', 'lo', 'cray_kern_nal'):
955 print "Unknown net_type: ", net_type
958 ret = findByName(lustre, node_name, "node")
960 node = do_add_node(gen, lustre, options, node_name)
963 set_node_options(gen, node, options)
965 net_name = new_name('NET_'+ node_name +'_'+ net_type)
966 net_uuid = new_uuid(net_name)
967 node.appendChild(gen.network(net_name, net_uuid, nid, cluster_id, net_type,
969 node_add_profile(gen, node, "network", net_uuid)
972 def add_route(gen, lustre, options):
973 """ create a node with a network config """
975 node_name = get_option(options, 'node')
976 gw_net_type = get_option(options, 'nettype')
977 gw = get_option(options, 'gw')
978 gw_cluster_id = get_option(options, 'gateway_cluster_id')
979 tgt_cluster_id = get_option(options, 'target_cluster_id')
980 lo = get_option(options, 'lo')
981 hi = get_option(options, 'hi')
985 node = findByName(lustre, node_name, "node")
987 error (node_name, " not found.")
989 rlist = node.getElementsByTagName('routetbl')
993 rtbl_name = new_name("RTBL_" + node_name)
994 rtbl_uuid = new_uuid(rtbl_name)
995 rtbl = gen.routetbl(rtbl_name, rtbl_uuid)
996 node.appendChild(rtbl)
997 node_add_profile(gen, node, "routetbl", rtbl_uuid)
998 rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
1001 def add_gks(gen, lustre, options):
1002 """ create a gks """
1003 node_name = get_option(options, 'node')
1004 gks_name = get_option(options, 'gks')
1006 gks_name = new_name('GKS_'+ node_name)
1008 gkd_name = new_name("GKD_" + gks_name + "_" + node_name)
1009 gkd_uuid = new_uuid(gkd_name)
1011 gks_uuid = name2uuid(lustre, gks_name, 'gks', fatal=0)
1014 gks_uuid = new_uuid(gks_name)
1015 gks = gen.gks(gks_name, gks_uuid, gkd_uuid)
1016 lustre.appendChild(gks)
1018 gks = lookup(lustre, gks_uuid)
1021 node_uuid = name2uuid(lustre, node_name, 'node')
1022 node = findByName(lustre, node_name, "node")
1023 node_add_profile(gen, node, "gkd", gkd_uuid)
1024 net_uuid = get_net_uuid(lustre, node_name)
1026 error("NODE: ", node_name, "not found")
1028 gkd = gen.gkd(gkd_name, gkd_uuid, node_uuid, gks_uuid)
1029 lustre.appendChild(gkd)
1032 def add_mds(gen, lustre, options):
1033 node_name = get_option(options, 'node')
1034 mds_name = get_option(options, 'mds')
1036 mds_name = new_name('MDS_'+ node_name)
1037 lmv_name = get_option(options, 'lmv')
1038 mdd_name = new_name("MDD_" + mds_name +"_" + node_name)
1039 mdd_uuid = new_uuid(mdd_name)
1043 lmv = findByName(lustre, lmv_name, "lmv")
1045 error('add_mds:', '"' + lmv_name + '"', "lmv element not found.")
1046 lmv_uuid = name2uuid(lustre, lmv_name, fatal=0)
1048 mds_uuid = name2uuid(lustre, mds_name, 'mds', fatal=0)
1050 mds_uuid = get_option(options, 'mdsuuid')
1052 if lookup(lustre, mds_uuid):
1053 error("Duplicate MDS UUID:", mds_uuid)
1055 mds_uuid = new_uuid(mds_name)
1056 mds = gen.mds(mds_name, mds_uuid, mdd_uuid, options.group)
1057 lustre.appendChild(mds)
1059 lmv_add_obd(gen, lmv, mds_uuid)
1061 mds = lookup(lustre, mds_uuid)
1063 if options.failover:
1064 mds.setAttribute('failover', "1")
1066 devname = get_option(options, 'dev')
1067 backdevname = get_option(options, 'backdev')
1068 size = get_option(options, 'size')
1069 fstype = get_option(options, 'fstype')
1070 backfstype = get_option(options, 'backfstype')
1071 journal_size = get_option(options, 'journal_size')
1072 inode_size = get_option(options, 'inode_size')
1073 nspath = get_option(options, 'nspath')
1074 mkfsoptions = get_option(options, 'mkfsoptions')
1075 mountfsoptions = get_option(options, 'mountfsoptions')
1076 root_squash = get_option(options, 'root_squash')
1077 no_root_squash = get_option(options, 'no_root_squash')
1078 mds_sec = get_option(options, 'mds_mds_sec')
1079 oss_sec = get_option(options, 'mds_oss_sec')
1080 deny_sec = get_option(options, 'mds_deny_sec')
1082 node_uuid = name2uuid(lustre, node_name, 'node')
1084 node = findByName(lustre, node_name, "node")
1085 node_add_profile(gen, node, "mdsdev", mdd_uuid)
1086 net_uuid = get_net_uuid(lustre, node_name)
1088 error("NODE: ", node_name, "not found")
1091 mds.appendChild(gen.ref("lmv", lmv_uuid))
1093 mdd = gen.mdsdev(mdd_name, mdd_uuid, fstype, devname,
1094 get_format_flag(options), node_uuid, mds_uuid,
1095 size, journal_size, inode_size, nspath, mkfsoptions,
1096 mountfsoptions, backfstype, backdevname,lmv_uuid,
1097 root_squash, no_root_squash, mds_sec, oss_sec, deny_sec)
1098 lustre.appendChild(mdd)
1101 def add_mgmt(gen, lustre, options):
1102 node_name = get_option(options, 'node')
1103 node_uuid = name2uuid(lustre, node_name, 'node')
1104 mgmt_name = get_option(options, 'mgmt')
1106 mgmt_name = new_name('MGMT_' + node_name)
1107 mgmt_uuid = name2uuid(lustre, mgmt_name, 'mgmt', fatal=0)
1109 mgmt_uuid = new_uuid(mgmt_name)
1110 mgmt = gen.mgmt(mgmt_name, mgmt_uuid, node_uuid)
1111 lustre.appendChild(mgmt)
1113 mgmt = lookup(lustre, mgmt_uuid)
1115 node = findByName(lustre, node_name, "node")
1116 node_add_profile(gen, node, 'mgmt', mgmt_uuid)
1118 def add_ost(gen, lustre, options):
1119 node_name = get_option(options, 'node')
1120 lovname = get_option(options, 'lov')
1121 osdtype = get_option(options, 'osdtype')
1123 node_uuid = name2uuid(lustre, node_name, 'node')
1125 if osdtype == 'obdecho':
1137 devname = get_option(options, 'dev') # can be unset for bluearcs
1138 backdevname = get_option(options, 'backdev')
1139 size = get_option(options, 'size')
1140 fstype = get_option(options, 'fstype')
1141 backfstype = get_option(options, 'backfstype')
1142 journal_size = get_option(options, 'journal_size')
1143 inode_size = get_option(options, 'inode_size')
1144 mkfsoptions = get_option(options, 'mkfsoptions')
1145 mountfsoptions = get_option(options, 'mountfsoptions')
1146 deny_sec = get_option(options, 'ost_deny_sec')
1148 nspath = get_option(options, 'nspath')
1150 ostname = get_option(options, 'ost')
1152 ostname = new_name('OST_'+ node_name)
1154 osdname = new_name("OSD_" + ostname + "_" + node_name)
1155 osd_uuid = new_uuid(osdname)
1157 ost_uuid = name2uuid(lustre, ostname, 'ost', fatal=0)
1159 ost_uuid = get_option(options, 'ostuuid')
1161 if lookup(lustre, ost_uuid):
1162 error("Duplicate OST UUID:", ost_uuid)
1164 ost_uuid = new_uuid(ostname)
1166 ost = gen.ost(ostname, ost_uuid, osd_uuid, options.group)
1167 lustre.appendChild(ost)
1169 ost = lookup(lustre, ost_uuid)
1172 lov = findByName(lustre, lovname, "lov")
1174 error('add_ost:', '"'+lovname+'"', "lov element not found.")
1175 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1177 if options.failover:
1178 ost.setAttribute('failover', "1")
1181 osd = gen.osd(osdname, osd_uuid, fstype, osdtype, devname,
1182 get_format_flag(options), ost_uuid, node_uuid, size,
1183 journal_size, inode_size, nspath, mkfsoptions,
1184 mountfsoptions, backfstype, backdevname, deny_sec)
1186 node = findByName(lustre, node_name, "node")
1188 ## if node_add_profile(gen, node, 'oss', oss_uuid):
1190 ## oss_uuid = new_uuid(ossname)
1191 ## oss = gen.oss(ossname, oss_uuid)
1192 ## lustre.appendChild(oss)
1194 node_add_profile(gen, node, 'osd', osd_uuid)
1195 lustre.appendChild(osd)
1197 def del_ost(gen, lustre, options):
1198 ostname = get_option(options, 'ost')
1200 raise OptionError("del_ost: --ost requires a <ost name>")
1201 ost = findByName(lustre, ostname, "ost")
1203 error('del_ost: ', 'Unable to find ', ostname)
1204 ost_uuid = name2uuid(lustre, ostname, fatal=0)
1206 error('del_ost: ', 'Unable to find uuid for ', ostname)
1207 lovname = get_option(options, 'lov')
1209 lov = findByName(lustre, lovname, "lov")
1211 error('del_ost:', '"'+lovname+'"', "lov element not found.")
1212 lov_del_obd(gen, lustre, lov, ost_uuid, options)
1213 # if the user specified a speficic LOV don't delete the OST itself
1216 # remove OSD references from all LOVs
1217 for n in lustre.getElementsByTagName('lov'):
1218 lov_del_obd(gen, lustre, n, ost_uuid, options)
1219 if not options.migrate:
1222 for osd in lustre.getElementsByTagName('osd'):
1223 if ref_exists(osd, ost_uuid):
1224 osd_uuid = osd.getAttribute('uuid')
1225 # delete all profile references to this OSD
1226 for profile in lustre.getElementsByTagName('profile'):
1227 for osd_ref in profile.getElementsByTagName('osd_ref'):
1228 if osd_uuid == osd_ref.getAttribute('uuidref'):
1229 profile.removeChild(osd_ref)
1230 lustre.removeChild(osd)
1233 lustre.removeChild(ost)
1235 def add_cmobd(gen, lustre, options):
1236 node_name = get_option(options, 'node')
1237 name = get_option(options, 'cmobd')
1238 uuid = new_uuid(name)
1240 master_name = get_option(options, 'master_obd')
1241 cache_name = get_option(options, 'cache_obd')
1243 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1244 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1246 if not master_uuid or not cache_uuid:
1248 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1250 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1252 if not master_uuid or not cache_uuid:
1254 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1256 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1258 if not master_uuid or not cache_uuid:
1260 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1262 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1265 panic("add_cmobd", "cannot find master_uuid by name '" +
1268 panic("add_cmobd", "cannot find cache_uuid by name '" +
1271 node = findByName(lustre, node_name, "node")
1272 node_add_profile(gen, node, "cmobd", uuid)
1274 master_node = lookup(lustre, master_uuid)
1275 cache_node = lookup(lustre, cache_uuid)
1277 panic("cmobd_add", "cannot find master node by its uuid " +
1280 panic("cmobd_add", "cannot find cache node by its uuid " +
1283 active = master_node.getElementsByTagName('active_ref')
1285 active_uuid = active[0].getAttribute('uuidref')
1286 active_node = lookup(lustre, active_uuid)
1287 if not active_node.getElementsByTagName('obdtype'):
1288 gen.addElement(active_node, 'obdtype', 'master')
1290 active = cache_node.getElementsByTagName('active_ref')
1292 active_uuid = active[0].getAttribute('uuidref')
1293 active_node = lookup(lustre, active_uuid)
1294 if not active_node.getElementsByTagName('obdtype'):
1295 gen.addElement(active_node, 'obdtype', 'cache')
1297 cmobd = gen.cmobd(name, uuid, master_uuid, cache_uuid)
1298 lustre.appendChild(cmobd)
1300 def add_cobd(gen, lustre, options):
1301 node_name = get_option(options, 'node')
1302 name = get_option(options, 'cobd')
1303 uuid = new_uuid(name)
1305 master_name = get_option(options, 'master_obd')
1306 cache_name = get_option(options, 'cache_obd')
1309 master_uuid = name2uuid(lustre, master_name, tag='lov', fatal=0)
1311 master_uuid = name2uuid(lustre, master_name, tag='ost', fatal=0)
1314 node = lookup(lustre, master_uuid)
1315 rets = node.getElementsByTagName('lov_tgt')
1317 ost_uuid = ret.getAttribute('uuidref')
1318 ost_node = lookup(lustre, ost_uuid)
1319 active = ost_node.getElementsByTagName('active_ref')
1321 osd_uuid = active[0].getAttribute('uuidref')
1322 osd_node = lookup(lustre, osd_uuid)
1323 if not osd_node.getElementsByTagName('obdtype'):
1324 gen.addElement(osd_node, 'obdtype', 'master')
1327 cache_uuid = name2uuid(lustre, cache_name, tag='lov', fatal=0)
1328 if not not cache_uuid:
1329 cache_uuid = name2uuid(lustre, cache_name, tag='ost', fatal=0)
1332 node = lookup(lustre, cache_uuid)
1333 rets = node.getElementsByTagName('lov_tgt')
1335 ost_uuid = ret.getAttribute('uuidref')
1336 ost_node = lookup(lustre, ost_uuid)
1337 active = ost_node.getElementsByTagName('active_ref')
1339 osd_uuid = active[0].getAttribute('uuidref')
1340 osd_node = lookup(lustre, osd_uuid)
1341 if not osd_node.getElementsByTagName('obdtype'):
1342 gen.addElement(osd_node, 'obdtype', 'cache')
1344 if not master_uuid or not cache_uuid:
1345 master_uuid = name2uuid(lustre, master_name, tag='lmv', fatal=0)
1347 master_uuid = name2uuid(lustre, master_name, tag='mds', fatal=0)
1350 mds_node = lookup(lustre, master_uuid)
1351 ret = mds_node.getElementsByTagName('active_ref')
1353 mdsdev_uuid = ret[0].getAttribute('uuidref')
1354 mdsdev_node = lookup(lustre, mdsdev_uuid)
1355 if not mdsdev_node.getElementsByTagName('obdtype'):
1356 gen.addElement(mdsdev_node, 'obdtype', 'master')
1358 cache_uuid = name2uuid(lustre, cache_name, tag='lmv', fatal=0)
1360 cache_uuid = name2uuid(lustre, cache_name, tag='mds', fatal=0)
1363 mds_node = lookup(lustre, cache_uuid)
1364 ret = mds_node.getElementsByTagName('active_ref')
1366 mdsdev_uuid = ret[0].getAttribute('uuidref')
1367 mdsdev_node = lookup(lustre, mdsdev_uuid)
1368 if not mdsdev_node.getElementsByTagName('obdtype'):
1369 gen.addElement(mdsdev_node, 'obdtype', 'cache')
1371 if not master_uuid or not cache_uuid:
1372 panic("add_cobd", "cannot find master or cache by names '" +
1373 master_name + "' and '" + cache_name + "'")
1375 node = findByName(lustre, node_name, "node")
1376 cobd = gen.cobd(name, uuid, master_uuid, cache_uuid)
1377 lustre.appendChild(cobd)
1379 def add_echo_client(gen, lustre, options):
1380 """ add an echo client to the profile for this node. """
1381 node_name = get_option(options, 'node')
1382 lov_name = get_option(options, 'ost')
1384 node = findByName(lustre, node_name, 'node')
1386 echoname = new_name('ECHO_'+ node_name)
1387 echo_uuid = new_uuid(echoname)
1388 node_add_profile(gen, node, 'echoclient', echo_uuid)
1390 lov_uuid = name2uuid(lustre, lov_name, tag='lov', fatal=0)
1392 lov_uuid = name2uuid(lustre, lov_name, tag='ost', fatal=1)
1394 echo = gen.echo_client(echoname, echo_uuid, lov_uuid)
1395 lustre.appendChild(echo)
1398 def add_lov(gen, lustre, options):
1399 """ create a lov """
1401 lmv_name = get_option(options, 'lmv')
1402 cache_lmv_name = get_option(options, 'cachelmv')
1403 master_lmv_name = get_option(options, 'masterlmv')
1404 lov_orig = get_option(options, 'lov')
1405 name = new_name(lov_orig)
1406 if name != lov_orig:
1407 warning("name:", lov_orig, "already used. using:", name)
1409 mds_name = get_option(options, 'mds')
1410 if not mds_name and not lmv_name and not cache_lmv_name and not master_lmv_name:
1411 error("LOV: MDS or LMV must be specified.");
1413 stripe_sz = get_option_int(options, 'stripe_sz')
1414 stripe_cnt = get_option_int(options, 'stripe_cnt')
1415 pattern = get_option_int(options, 'stripe_pattern')
1416 uuid = new_uuid(name)
1418 ret = findByName(lustre, name, "lov")
1420 error("LOV: ", name, " already exists.")
1423 mds_uuid = name2uuid(lustre, lmv_name, 'lmv')
1425 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1427 lov = gen.lov(name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1428 lustre.appendChild(lov)
1430 # add an lovconfig entry to the active mdsdev profile
1431 lovconfig_name = new_name('LVCFG_' + name)
1432 lovconfig_uuid = new_uuid(lovconfig_name)
1434 mds = findByName(lustre, mds_name, "mds")
1436 panic("add_lov", "can't find MDS '" + mds_name + "'")
1437 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1438 mds.appendChild(gen.ref("client", uuid))
1441 lmv = findByName(lustre, lmv_name, "lmv")
1443 panic("add_lov", "can't find LMV '" + lmv_name + "'")
1444 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1445 lmv.appendChild(gen.ref("client", uuid))
1448 lmv = findByName(lustre, cache_lmv_name, "lmv")
1450 panic("add_lov", "can't find LMV '" + cache_lmv_name + "'")
1451 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1452 lmv.appendChild(gen.ref("client", uuid))
1455 lmv = findByName(lustre, master_lmv_name, "lmv")
1457 panic("add_lov", "can't find LMV '" + master_lmv_name + "'")
1458 lmv.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1459 lmv.appendChild(gen.ref("client", uuid))
1461 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1462 lustre.appendChild(lovconfig)
1464 def add_default_lov(gen, lustre, mds_name, lov_name):
1465 """ create a default lov """
1467 stripe_sz = DEFAULT_STRIPE_SZ
1468 stripe_cnt = DEFAULT_STRIPE_CNT
1469 pattern = DEFAULT_STRIPE_PATTERN
1470 uuid = new_uuid(lov_name)
1472 ret = findByName(lustre, lov_name, "lov")
1474 error("LOV: ", lov_name, " already exists.")
1476 mds_uuid = name2uuid(lustre, mds_name, 'mds')
1477 lov = gen.lov(lov_name, uuid, mds_uuid, stripe_sz, stripe_cnt, pattern)
1478 lustre.appendChild(lov)
1480 # add an lovconfig entry to the active mdsdev profile
1481 lovconfig_name = new_name('LVCFG_' + lov_name)
1482 lovconfig_uuid = new_uuid(lovconfig_name)
1483 mds = findByName(lustre, mds_name)
1484 mds.appendChild(gen.ref("lovconfig", lovconfig_uuid))
1485 lovconfig = gen.lovconfig(lovconfig_name, lovconfig_uuid, uuid)
1486 lustre.appendChild(lovconfig)
1488 def add_lmv(gen, lustre, options):
1489 """ create a lmv """
1491 lmv_orig = get_option(options, 'lmv')
1492 name = new_name(lmv_orig)
1493 if name != lmv_orig:
1494 warning("name:", lmv_orig, "already used. using:", name)
1496 uuid = new_uuid(name)
1497 ret = findByName(lustre, name, "lmv")
1499 error("LMV: ", name, " already exists.")
1501 lmv = gen.lmv(name, uuid)
1502 lustre.appendChild(lmv)
1504 def find_client(lustre, mds_uuid, client_uuid):
1505 mds = lookup(lustre, mds_uuid)
1506 clients = mds.getElementsByTagName('client_ref')
1509 for client in clients:
1510 if client.getAttribute("uuidref") == client_uuid:
1514 def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid):
1515 fs_name = new_name("FS_fsname")
1516 fs_uuid = new_uuid(fs_name)
1518 mds = lookup(lustre, mds_uuid)
1519 clients = mds.getElementsByTagName('client_ref')
1521 if find_client(lustre, mds_uuid, obd_uuid) == 0:
1522 mds.appendChild(gen.ref("client", obd_uuid))
1524 fs = gen.filesystem(fs_name, fs_uuid, mds_uuid,
1525 obd_uuid, mgmt_uuid, gks_uuid)
1527 lustre.appendChild(fs)
1530 def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name, gks_name):
1531 mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
1533 mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
1535 mds_uuid = name2uuid(lustre, mds_name, tag='cobd', fatal=0)
1537 error("mds '" + mds_name + "' is not found")
1539 obd_uuid = name2uuid(lustre, obd_name, tag='ost', fatal=0)
1541 obd_uuid = name2uuid(lustre, obd_name, tag='lov', fatal=0)
1543 obd_uuid = name2uuid(lustre, obd_name, tag='cobd', fatal=0)
1545 error("ost '" + obd_name + "' is not found")
1548 mgmt_uuid = name2uuid(lustre, mgmt_name, tag='mgmt', fatal=1)
1553 gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
1556 fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
1558 fs_uuid = new_filesystem(gen, lustre, mds_uuid,
1559 obd_uuid, mgmt_uuid, gks_uuid)
1562 def add_mtpt(gen, lustre, options):
1563 """ create mtpt on a node """
1564 node_name = get_option(options, 'node')
1566 path = get_option(options, 'path')
1567 clientoptions = get_option(options, "clientoptions")
1568 mds_sec = get_option(options, "mds_sec")
1569 oss_sec = get_option(options, "oss_sec")
1570 fs_name = get_option(options, 'filesystem')
1572 lov_name = get_option(options, 'lov')
1573 ost_name = get_option(options, 'ost')
1574 mds_name = get_option(options, 'mds')
1575 gks_name = get_option(options, 'gks')
1577 mds_name = get_option(options, 'lmv')
1579 error("--add mtpt requires either --mds or --lmv.")
1582 error("--add mtpt requires --lov lov_name or --ost ost_name")
1584 warning("use default value for lov, due no --lov lov_name provided")
1585 lov_name = new_name("lov_default")
1586 add_default_lov(gen, lustre, mds_name, lov_name)
1587 ost_uuid = name2uuid(lustre, ost_name, 'ost', fatal=0)
1589 error('add_mtpt:', '"'+ost_name+'"', "ost element not found.")
1590 lov = findByName(lustre, lov_name, "lov")
1591 lov_add_obd(gen, lustre, lov, ost_uuid, options)
1594 mgmt_name = get_option(options, 'mgmt')
1595 fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name, gks_name)
1597 fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
1599 name = new_name('MNT_'+ node_name)
1601 ret = findByName(lustre, name, "mountpoint")
1603 # this can't happen, because new_name creates unique names
1604 error("MOUNTPOINT: ", name, " already exists.")
1606 uuid = new_uuid(name)
1607 mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions, mds_sec, oss_sec)
1608 node = findByName(lustre, node_name, "node")
1610 error('node:', node_name, "not found.")
1611 node_add_profile(gen, node, "mountpoint", uuid)
1612 lustre.appendChild(mtpt)
1614 def commit_version(gen, lustre):
1615 update = findLastUpdate(lustre)
1617 version = int(update.getAttribute("version")) + 1
1621 new = gen.update(str(version))
1622 lustre.appendChild(new)
1625 ############################################################
1626 # Command line processing
1628 class OptionError (exceptions.Exception):
1629 def __init__(self, args):
1632 def get_option(options, tag):
1633 """Look for tag in options hash and return the value if set. If not
1634 set, then if return default it is set, otherwise exception."""
1635 if options.__getattr__(tag) != None:
1636 return options.__getattr__(tag)
1638 raise OptionError("--add %s requires --%s <value>" % (options.add, tag))
1640 def get_option_int(options, tag):
1641 """Return an integer option. Raise exception if the value is not an int"""
1642 val = get_option(options, tag)
1646 raise OptionError("--%s <num> (value must be integer)" % (tag))
1649 # simple class for profiling
1656 self._start = time.time()
1657 def stop(self, msg=''):
1658 self._stop = time.time()
1662 return self._stop - self._start
1663 def display(self, msg):
1665 str = '%s: %g secs' % (msg, d)
1668 #################################################################
1669 # function cmdlinesplit used to split cmd line from batch file
1671 def cmdlinesplit(cmdline):
1673 double_quote = re.compile(r'"(([^"\\]|\\.)*)"')
1674 single_quote = re.compile(r"'(.*?)'")
1675 escaped = re.compile(r'\\(.)')
1676 esc_quote = re.compile(r'\\([\\"])')
1677 outside = re.compile(r"""([^\s\\'"]+)""") #" fucking emacs.
1681 while i < len(cmdline):
1684 match = double_quote.match(cmdline, i)
1686 print "Unmatched double quote:", cmdline
1689 if arg is None: arg = esc_quote.sub(r'\1', match.group(1))
1690 else: arg = arg + esc_quote.sub(r'\1', match.group(1))
1693 match = single_quote.match(cmdline, i)
1695 print "Unmatched single quote:", cmdline
1698 if arg is None: arg = match.group(1)
1699 else: arg = arg + match.group(1)
1702 match = escaped.match(cmdline, i)
1704 print "Unmatched backslash", cmdline
1707 if arg is None: arg = match.group(1)
1708 else: arg = arg + match.group(1)
1710 elif c in string.whitespace:
1712 arg_list.append(str(arg))
1714 while i < len(cmdline) and cmdline[i] in string.whitespace:
1717 match = outside.match(cmdline, i)
1720 if arg is None: arg = match.group()
1721 else: arg = arg + match.group()
1723 if arg != None: arg_list.append(str(arg))
1727 ############################################################
1731 def add(devtype, gen, lustre, options):
1732 if devtype == 'net':
1733 add_net(gen, lustre, options)
1734 elif devtype == 'mtpt':
1735 add_mtpt(gen, lustre, options)
1736 elif devtype == 'mds':
1737 add_mds(gen, lustre, options)
1738 elif devtype == 'ost':
1739 add_ost(gen, lustre, options)
1740 elif devtype == 'lov':
1741 add_lov(gen, lustre, options)
1742 elif devtype == 'route':
1743 add_route(gen, lustre, options)
1744 elif devtype == 'node':
1745 add_node(gen, lustre, options)
1746 elif devtype == 'echo_client':
1747 add_echo_client(gen, lustre, options)
1748 elif devtype == 'cobd':
1749 add_cobd(gen, lustre, options)
1750 elif devtype == 'cmobd':
1751 add_cmobd(gen, lustre, options)
1752 elif devtype == 'mgmt':
1753 add_mgmt(gen, lustre, options)
1754 elif devtype == 'lmv':
1755 add_lmv(gen, lustre, options)
1756 elif devtype == 'gks':
1757 add_gks(gen, lustre, options)
1759 error("unknown device type:", devtype)
1761 def delete(devtype, gen, lustre, options):
1762 if devtype == 'ost':
1763 del_ost(gen, lustre, options)
1764 elif options.delete:
1765 error("delete not supported for device type:", devtype)
1766 elif options.deactivate:
1767 error("deactivate not supported for device type:", devtype)
1769 error("in delete(), but neither .delete nor .deactivate are set. Tell CFS.")
1771 def commit(gen, lustre):
1772 commit_version(gen, lustre)
1774 def do_command(gen, lustre, options, args):
1776 add(options.add, gen, lustre, options)
1777 elif options.delete:
1778 delete(options.delete, gen, lustre, options)
1779 elif options.deactivate:
1780 delete(options.deactivate, gen, lustre, options)
1781 elif options.commit:
1784 error("Missing command")
1787 cl = Lustre.Options("lmc", "", lmc_options)
1789 options, args = cl.parse(sys.argv[1:])
1790 except Lustre.OptionError, e:
1794 panic(string.join(sys.argv), "Unexpected extra arguments on command line: " + string.join(args))
1796 if options.reference:
1803 outFile = options.merge
1804 if os.access(outFile, os.R_OK):
1805 doc = xml.dom.minidom.parse(outFile)
1807 doc = new_lustre(xml.dom.minidom)
1809 doc = xml.dom.minidom.parse(options.input)
1811 doc = new_lustre(xml.dom.minidom)
1814 outFile = options.output
1816 lustre = doc.documentElement
1818 if lustre.tagName != "lustre":
1819 print "Existing config not valid."
1822 gen = GenConfig(doc)
1825 fp = open(options.batch)
1826 batchCommands = fp.readlines()
1828 for cmd in batchCommands:
1830 options, args = cl.parse(cmdlinesplit(cmd))
1831 if options.merge or options.input or options.output:
1832 print "The batchfile should not contain --merge, --input or --output."
1834 do_command(gen, lustre, options, args)
1835 except OptionError, e:
1837 except Lustre.OptionError, e:
1841 do_command(gen, lustre, options, args)
1842 except OptionError, e:
1843 panic(string.join(sys.argv),e)
1844 except Lustre.OptionError, e:
1850 printDoc(doc, open(outFile,"w"))
1852 if __name__ == "__main__":