Whamcloud - gitweb
- configuring an obd seems to work
[fs/lustre-release.git] / lustre / utils / lmc
1 #!/usr/bin/env python
2 #
3 #  Copyright (C) 2002 Cluster File Systems, Inc.
4 #   Author: Robert Read <rread@clusterfs.com>
5
6 #   This file is part of Lustre, http://www.lustre.org.
7 #
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.
11 #
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.
16 #
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.
20 #
21
22 # lmc - lustre configurtion data  manager
23 #
24 import sys, getopt
25 import xml.dom.minidom
26
27
28 def usage():
29     print """usage: lmc [--ost | --mtpt | --lov] cmd args
30 Commands:
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.
35
36 --mtpt "mds" "ost/lov-name" /mnt/point
37    Creates a client mount point.
38
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.)
42
43 Options:
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,
47                     I think)
48 (SCRIPT STILL UNDER DEVELOPMENT, MOST COMMANDS/OPTIONS UNIMPLEMENTED)
49 """  
50
51 #
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
57 name_ctr = 1
58 def new_name(base):
59     global name_ctr
60     name = "%s_%d" % (base, name_ctr)
61     name_ctr += 1
62     return name
63
64 def get_uuid(name):
65     return "%s_UUID" % (name)
66
67 #
68 # Create a new empty lustre document 
69 def new_Lustre():
70     str = """<lustre>
71 </lustre>"""
72     dom = xml.dom.minidom.parseString(str)
73     return dom
74
75 #
76 # Create a new object the "correct" way by using the DOM api.
77 #
78 def new_OBD(dom, name, fs, devname, format, dev_size=0, dev_file=""):
79     uuid = get_uuid(name)
80     
81     obd = dom.createElement("obd")
82     obd.setAttribute("name", name)
83     obd.setAttribute("uuid", uuid)
84
85     fstype = dom.createElement("fstype")
86     txt= dom.createTextNode(fs)
87     fstype.appendChild(txt)
88     obd.appendChild(fstype)
89     
90     dev = dom.createElement("device")
91     if (dev_size):
92         dev.setAttribute("size", "%s" % (dev_size))
93     txt = dom.createTextNode(devname)
94     dev.appendChild(txt)
95     obd.appendChild(dev)
96
97     fmt = dom.createElement("autoformat")
98     txt = dom.createTextNode(format)
99     fmt.appendChild(txt)
100     obd.appendChild(fmt)
101
102     return obd
103
104 #
105 # Create new object the fast and easy way
106 # (note: dom is not needed for this way)
107 def new_OSC(dom, osc, obd):
108     osc_uuid = get_uuid(osc)
109     obd_uuid = get_uuid(obd)
110
111     osc_str ="""
112 <osc name="%s" uuid="%s">
113    <service_id num="1" name="%s" uuid="%s"/>
114 </osc> """ % (osc, osc_uuid, obd, obd_uuid)
115     osc = xml.dom.minidom.parseString(osc_str)
116     return osc.getElementsByTagName("osc")[0]
117
118 #
119 # Create new object the fast and easy way
120 #
121 def new_OST(dom, ost, host, port, obd):
122     ost_uuid = get_uuid(ost)
123     obd_uuid = get_uuid(obd)
124
125     str ="""
126 <ost name="%s" uuid="%s">
127    <network type="tcp">
128       <server>%s</server>
129       <port>%d</port>
130    </network>
131    <server_id num="1" name="%s" uuid="%s"/>
132 </ost> """ % (ost, ost_uuid, host, port, obd, obd_uuid)
133     node = xml.dom.minidom.parseString(str)
134     return node.getElementsByTagName("ost")[0]
135
136 #
137 # Create a new obd, osc, and ost. Add them to the DOM.
138 #
139 def add_OST(dom, options, args):
140     # XXX need some error checking
141     devname = args[0]
142     host = args[1]
143     size = args[2]
144
145     obdname = new_name("obd")
146     oscname = new_name("osc")
147     ostname = new_name("ost")
148     
149     obd = new_OBD(dom, obdname, "extN", devname, "no", size)
150     osc = new_OSC(dom, oscname, obdname)
151     ost = new_OST(dom, ostname, host, 2020, obdname)
152     
153     dom.getElementsByTagName("lustre")[0].appendChild(obd)
154     dom.getElementsByTagName("lustre")[0].appendChild(osc)
155     dom.getElementsByTagName("lustre")[0].appendChild(ost)
156
157
158 #
159 # Command line processing
160 #
161
162 def parse_cmdline(argv):
163     short_opts = "ho:"
164     long_opts = ["ost", "mtpt", "lov",
165                  "merge=", "format", "reformat", "output=",
166                  "help"]
167     opts = []
168     args = []
169     options = {}
170     try:
171         opts, args = getopt.getopt(argv, short_opts, long_opts)
172     except getopt.GetoptError:
173         print "invalid opt"
174         usage()
175         sys.exit(2)
176
177     for o, a in opts:
178         if o in ("-h", "--help"):
179             usage()
180             sys.exit()
181         if o in ("-o", "--output"):
182             options['output'] = a
183         if o == "--ost":
184             options['ost'] = 1
185         if o == "--merge":
186             options['merge'] = a
187         if o == "--format":
188             options['format'] = 1
189         if o  == "--reformat":
190             options['reformat'] = 1
191             
192     return options, args
193
194 def main():
195     options, args = parse_cmdline(sys.argv[1:])
196     outFile = '-'
197
198     if options.has_key('merge'):
199         outFile = options['merge']
200         dom = xml.dom.minidom.parse(outFile)
201     else:
202         dom = new_Lustre()
203
204     if options.has_key('output'):
205         outFile = options['output']
206
207     if options.has_key('ost'):
208         add_OST(dom, options, args)
209     elif options.has_key('mtpt'):
210         print "--mtpt not implemented"
211     elif options.has_key('lov'):
212         print "--lov not implemented"
213     else:
214         print "Missing command"
215         usage()
216         sys.exit(1)
217         
218
219     if outFile == '-':
220         print dom.toxml()
221     else:
222         dom.writexml(open(outFile,"w"))
223     
224 if __name__ == "__main__":
225     main()
226