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
29 print """usage: lmc [--ost | --mtpt | --lov] cmd args
31 --ost "device" "host" [size]
32 Creates an OBD/OST/OSC configuration triplet for a new device.
33 When used on "host", the device will be initialized and the OST
34 will be enabled. On client nodes, the OSC will be avaiable.
36 --mtpt "mds" "ost/lov-name" /mnt/point
37 Creates a client mount point.
39 --lov "mds" "lov name" < "all-ost.xml"
40 Produces a logical volum striped over the OSTs found in all-ost.xml.
41 (Not sure how all-ost.xml is created, exactly.)
44 --merge="xml file" Add the new objects to an existing file
45 --format Format the partitions if unformated
46 --reformat Reformat partitions (this should be an lconf arg,
48 (SCRIPT STILL UNDER DEVELOPMENT, MOST COMMANDS/OPTIONS UNIMPLEMENTED)
52 # manage names and uuids
53 # need to initialize this by walking tree to ensure
54 # no duplicate names or uuids are created.
55 # this are just place holders for now.
56 # consider changing this to be like OBD-dev-host
60 name = "%s_%d" % (base, name_ctr)
65 return "%s_UUID" % (name)
67 # simple pretty print XML
68 def newline(dom, node, ind = ""):
69 node.appendChild(dom.createTextNode("\n" + ind))
70 def indent(dom, node, ind = " "):
71 node.appendChild(dom.createTextNode(ind))
74 # Create a new empty lustre document
78 dom = xml.dom.minidom.parseString(str)
81 def new_network(dom, net, hostname, port):
82 name = new_name('net')
85 <network name = "%s" uuid = "%s" type="%s" >
88 </network> """ % (name, uuid, net, hostname, port)
89 node = xml.dom.minidom.parseString(str)
90 return node.getElementsByTagName("network")[0]
93 # Create new object the fast and easy way
94 # (note: dom is not needed for this way)
95 def new_node(dom, net, hostname, port):
96 uuid = get_uuid(hostname)
98 <node name="%s" uuid="%s">
99 </node> """ % (hostname, uuid)
100 node = xml.dom.minidom.parseString(str)
101 node = node.getElementsByTagName("node")[0]
103 node.appendChild(new_network(dom, net, hostname, port))
107 # Create a new object the "correct" way by using the DOM api.
109 def new_OBD(dom, name, fs, devname, format, dev_size=0, dev_file=""):
110 uuid = get_uuid(name)
112 obd = dom.createElement("obd")
113 obd.setAttribute("name", name)
114 obd.setAttribute("uuid", uuid)
115 obd.setAttribute('type', 'obdfilter')
116 obd.appendChild(dom.createTextNode("\n "))
118 fstype = dom.createElement("fstype")
119 txt= dom.createTextNode(fs)
120 fstype.appendChild(txt)
121 obd.appendChild(fstype)
123 dev = dom.createElement("device")
125 dev.setAttribute("size", "%s" % (dev_size))
126 txt = dom.createTextNode(devname)
128 newline(dom, obd, " ")
130 newline(dom, obd, " ")
131 fmt = dom.createElement("autoformat")
132 txt = dom.createTextNode(format)
140 # Create new object the fast and easy way
141 # (note: dom is not needed for this way)
142 def new_OSC(dom, osc, obd):
143 osc_uuid = get_uuid(osc)
144 obd_uuid = get_uuid(obd)
147 <osc name="%s" uuid="%s">
148 <service_id num="1" name="%s" uuid="%s"/>
149 </osc> """ % (osc, osc_uuid, obd, obd_uuid)
150 osc = xml.dom.minidom.parseString(osc_str)
151 return osc.getElementsByTagName("osc")[0]
154 # Create new object the fast and easy way
156 def new_OST(dom, ost, host, port, obd):
157 ost_uuid = get_uuid(ost)
158 obd_uuid = get_uuid(obd)
161 <ost name="%s" uuid="%s">
166 <server_id num="1" name="%s" uuid="%s"/>
167 </ost> """ % (ost, ost_uuid, host, port, obd, obd_uuid)
168 node = xml.dom.minidom.parseString(str)
169 return node.getElementsByTagName("ost")[0]
172 # Create a new obd, osc, and ost. Add them to the DOM.
174 def add_OST(dom, options, args):
175 # XXX need some error checking
180 obdname = new_name("obd")
181 oscname = new_name("osc")
182 ostname = new_name("ost")
184 node = new_node(dom, "tcp", host, 2436)
185 obd = new_OBD(dom, obdname, "extN", devname, "no", size)
186 osc = new_OSC(dom, oscname, obdname)
187 ost = new_OST(dom, ostname, host, 2020, obdname)
189 lustre = dom.getElementsByTagName("lustre")[0]
190 lustre.appendChild(node)
192 lustre.appendChild(obd)
194 lustre.appendChild(osc)
196 lustre.appendChild(ost)
200 # Command line processing
203 def parse_cmdline(argv):
205 long_opts = ["ost", "mtpt", "lov",
206 "merge=", "format", "reformat", "output=",
212 opts, args = getopt.getopt(argv, short_opts, long_opts)
213 except getopt.GetoptError:
219 if o in ("-h", "--help"):
222 if o in ("-o", "--output"):
223 options['output'] = a
229 options['format'] = 1
230 if o == "--reformat":
231 options['reformat'] = 1
236 options, args = parse_cmdline(sys.argv[1:])
239 if options.has_key('merge'):
240 outFile = options['merge']
241 dom = xml.dom.minidom.parse(outFile)
245 if options.has_key('output'):
246 outFile = options['output']
248 if options.has_key('ost'):
249 add_OST(dom, options, args)
250 elif options.has_key('mtpt'):
251 print "--mtpt not implemented"
252 elif options.has_key('lov'):
253 print "--lov not implemented"
255 print "Missing command"
263 dom.writexml(open(outFile,"w"))
265 if __name__ == "__main__":