3 # Copyright (C) 2002 Cluster File Systems, Inc.
4 # Author: Robert Read <rread@clusterfs.com>
6 # This file is part of Lustre, http://www.lustre.org.
8 # Lustre is free software; you can redistribute it and/or
9 # modify it under the terms of version 2 of the GNU General Public
10 # License as published by the Free Software Foundation.
12 # Lustre is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Lustre; if not, write to the Free Software
19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 # lmc - lustre configurtion data manager
25 import xml.dom.minidom
26 from xml.dom.ext import PrettyPrint
30 print """usage: lmc [--ost | --mtpt | --lov] cmd args
32 --ost "device" "host" [size]
33 Creates an OBD/OST/OSC configuration triplet for a new device.
34 When used on "host", the device will be initialized and the OST
35 will be enabled. On client nodes, the OSC will be avaiable.
37 --osc "device" "host" [lov_name]
38 Create an osc, and optionally add it to an lov.
40 --mtpt "mds" "ost/lov-name" /mnt/point
41 Creates a client mount point.
43 --lov lov_name mdc_name stripe_sz stripe_off pattern
44 Produces a logical volum striped over the OSTs found in all-ost.xml.
47 --merge="xml file" Add the new objects to an existing file
48 --format Format the partitions if unformated
49 --reformat Reformat partitions (this should be an lconf arg,
51 (SCRIPT STILL UNDER DEVELOPMENT, MOST COMMANDS/OPTIONS UNIMPLEMENTED)
55 # manage names and uuids
56 # need to initialize this by walking tree to ensure
57 # no duplicate names or uuids are created.
58 # this are just place holders for now.
59 # consider changing this to be like OBD-dev-host
63 name = "%s_%d" % (base, name_ctr)
68 return "%s_UUID" % (name)
71 """Create a new empty lustre document"""
72 str = """<lustre> </lustre>"""
73 return dom.parseString(str)
79 def __init__(self, doc):
82 def ref(self, type, uuid):
83 """ generate <[type]_ref uuidref="[uuid]"/> """
84 tag = "%s_ref" % (type)
85 ref = self.doc.createElement(tag)
86 ref.setAttribute("uuidref", uuid)
89 def newService(self, tag, name, uuid):
90 """ create a new service elmement, which requires name and uuid attributes """
91 new = self.doc.createElement(tag)
92 new.setAttribute("name", name);
93 new.setAttribute("uuid", uuid);
96 def addText(self, node, str):
97 txt = self.doc.createTextNode(str)
100 def addElement(self, node, tag, str=None):
101 """ create a new element and add it as a child to node. If str is passed,
102 a text node is created for the new element"""
103 new = self.doc.createElement(tag)
105 self.addText(new, str)
106 node.appendChild(new)
109 def network(self, name, uuid, net, hostname, port=0):
110 """create <network> node"""
111 network = self.newService("network", name, uuid)
112 network.setAttribute("type", net);
113 self.addElement(network, "server", hostname)
115 self.addElement(network, "port", "%d" %(port))
118 def node(self, name, uuid):
119 """ create a host """
120 node = self.newService("node", name, uuid)
123 def obd(self, name, uuid, fs, devname, format, dev_size=0, dev_file=""):
124 obd = self.newService("obd", name, uuid)
125 obd.setAttribute('type', 'obdfilter')
126 self.addElement(obd, "fstype", fs)
127 dev = self.addElement(obd, "device", devname)
129 dev.setAttribute("size", "%s" % (dev_size))
130 self.addElement(obd, "autoformat", format)
133 def osc(self, name, uuid, obd_uuid, net_uuid):
134 osc = self.newService("osc", name, uuid)
135 osc.appendChild(self.ref("network", net_uuid))
136 osc.appendChild(self.ref("obd", obd_uuid))
139 def ost(self, name, uuid, obd_uuid, net_uuid):
140 ost = self.newService("ost", name, uuid)
141 ost.appendChild(self.ref("network", net_uuid))
142 ost.appendChild(self.ref("obd", obd_uuid))
146 # Create a new obd, osc, and ost. Add them to the DOM.
148 def add_OST(doc, options, args):
149 # XXX need some error checking
158 lustre = doc.getElementsByTagName("lustre")[0]
160 obdname = new_name("obd")
161 oscname = new_name("osc")
162 ostname = new_name("ost")
163 node_uuid = get_uuid(host)
164 net_uuid = get_uuid("net")
165 obd_uuid = get_uuid(obdname)
166 ost_uuid = get_uuid(ostname)
167 osc_uuid = get_uuid(oscname)
169 node = gen.node(host, node_uuid)
170 node.appendChild(gen.network(host, net_uuid, "tcp", host, port=2436))
171 obd = gen.obd(obdname, obd_uuid, "extN", devname, "no", size)
172 ost = gen.ost(ostname, ost_uuid, obd_uuid, net_uuid)
173 osc = gen.osc(oscname, osc_uuid, obd_uuid, net_uuid)
175 lustre.appendChild(node)
176 lustre.appendChild(obd)
177 lustre.appendChild(osc)
178 lustre.appendChild(ost)
182 # Command line processing
185 def parse_cmdline(argv):
187 long_opts = ["ost", "mtpt", "lov",
188 "merge=", "format", "reformat", "output=",
194 opts, args = getopt.getopt(argv, short_opts, long_opts)
195 except getopt.GetoptError:
201 if o in ("-h", "--help"):
204 if o in ("-o", "--output"):
205 options['output'] = a
211 options['format'] = 1
212 if o == "--reformat":
213 options['reformat'] = 1
218 options, args = parse_cmdline(sys.argv[1:])
221 if options.has_key('merge'):
222 outFile = options['merge']
223 doc = xml.dom.minidom.parse(outFile)
225 doc = new_lustre(xml.dom.minidom)
227 if options.has_key('output'):
228 outFile = options['output']
230 if options.has_key('ost'):
231 add_OST(doc, options, args)
232 elif options.has_key('mtpt'):
233 print "--mtpt not implemented"
234 elif options.has_key('lov'):
235 print "--lov not implemented"
237 print "Missing command"
244 PrettyPrint(doc, open(outFile,"w"))
245 if __name__ == "__main__":