Statistics
| Branch: | Tag: | Revision:

root / tools / lvmstrap @ 728489a3

History | View | Annotate | Download (23.7 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Program which configures LVM on the Ganeti nodes.
23 a8083063 Iustin Pop
24 a8083063 Iustin Pop
This program wipes disks and creates a volume group on top of them. It
25 a8083063 Iustin Pop
can also show disk information to help you decide which disks you want
26 a8083063 Iustin Pop
to wipe.
27 a8083063 Iustin Pop
28 a8083063 Iustin Pop
The error handling is done by raising our own exceptions from most of
29 a8083063 Iustin Pop
the functions; these exceptions then handled globally in the main()
30 a8083063 Iustin Pop
function. The exceptions that each function can raise are not
31 a8083063 Iustin Pop
documented individually, since almost every error path ends in a
32 a8083063 Iustin Pop
raise.
33 a8083063 Iustin Pop
34 a8083063 Iustin Pop
Another two exceptions that are handled globally are IOError and
35 a8083063 Iustin Pop
OSError. The idea behind this is, since we run as root, we should
36 a8083063 Iustin Pop
usually not get these errors, but if we do it's most probably a system
37 a8083063 Iustin Pop
error, so they should be handled and the user instructed to report
38 a8083063 Iustin Pop
them.
39 a8083063 Iustin Pop
"""
40 a8083063 Iustin Pop
41 a8083063 Iustin Pop
42 a8083063 Iustin Pop
import os
43 a8083063 Iustin Pop
import sys
44 a8083063 Iustin Pop
import optparse
45 a8083063 Iustin Pop
import time
46 a8083063 Iustin Pop
47 3374afa9 Guido Trotter
from ganeti.utils import RunCmd, ReadFile
48 a8083063 Iustin Pop
from ganeti import constants
49 e194129a Stephen Shirley
from ganeti import cli
50 a8083063 Iustin Pop
51 d1687c6f Iustin Pop
USAGE = ("\tlvmstrap diskinfo\n"
52 d1687c6f Iustin Pop
         "\tlvmstrap [--vgname=NAME] [--allow-removable]"
53 d1687c6f Iustin Pop
         " { --alldisks | --disks DISKLIST }"
54 a8083063 Iustin Pop
         " create")
55 a8083063 Iustin Pop
56 a8083063 Iustin Pop
verbose_flag = False
57 a8083063 Iustin Pop
58 a8083063 Iustin Pop
59 a8083063 Iustin Pop
class Error(Exception):
60 a8083063 Iustin Pop
  """Generic exception"""
61 a8083063 Iustin Pop
  pass
62 a8083063 Iustin Pop
63 a8083063 Iustin Pop
64 a8083063 Iustin Pop
class ProgrammingError(Error):
65 a8083063 Iustin Pop
  """Exception denoting invalid assumptions in programming.
66 a8083063 Iustin Pop
67 a8083063 Iustin Pop
  This should catch sysfs tree changes, or otherwise incorrect
68 a8083063 Iustin Pop
  assumptions about the contents of the /sys/block/... directories.
69 a8083063 Iustin Pop
  """
70 a8083063 Iustin Pop
  pass
71 a8083063 Iustin Pop
72 a8083063 Iustin Pop
73 a8083063 Iustin Pop
class SysconfigError(Error):
74 a8083063 Iustin Pop
  """Exception denoting invalid system configuration.
75 a8083063 Iustin Pop
76 a8083063 Iustin Pop
  If the system configuration is somehow wrong (e.g. /dev files
77 a8083063 Iustin Pop
  missing, or having mismatched major/minor numbers relative to
78 a8083063 Iustin Pop
  /sys/block devices), this exception will be raised.
79 a8083063 Iustin Pop
80 a8083063 Iustin Pop
  This should usually mean that the installation of the Xen node
81 a8083063 Iustin Pop
  failed in some steps.
82 a8083063 Iustin Pop
  """
83 a8083063 Iustin Pop
  pass
84 a8083063 Iustin Pop
85 a8083063 Iustin Pop
86 a8083063 Iustin Pop
class PrereqError(Error):
87 a8083063 Iustin Pop
  """Exception denoting invalid prerequisites.
88 a8083063 Iustin Pop
89 a8083063 Iustin Pop
  If the node does not meet the requirements for cluster membership, this
90 a8083063 Iustin Pop
  exception will be raised. Things like wrong kernel version, or no
91 a8083063 Iustin Pop
  free disks, etc. belong here.
92 a8083063 Iustin Pop
93 a8083063 Iustin Pop
  This should usually mean that the build steps for the Xen node were
94 a8083063 Iustin Pop
  not followed correctly.
95 a8083063 Iustin Pop
  """
96 a8083063 Iustin Pop
  pass
97 a8083063 Iustin Pop
98 a8083063 Iustin Pop
99 a8083063 Iustin Pop
class OperationalError(Error):
100 a8083063 Iustin Pop
  """Exception denoting actual errors.
101 a8083063 Iustin Pop
102 a8083063 Iustin Pop
  Errors during the bootstrapping are signaled using this exception.
103 a8083063 Iustin Pop
  """
104 a8083063 Iustin Pop
  pass
105 a8083063 Iustin Pop
106 a8083063 Iustin Pop
107 a8083063 Iustin Pop
class ParameterError(Error):
108 a8083063 Iustin Pop
  """Exception denoting invalid input from user.
109 a8083063 Iustin Pop
110 a8083063 Iustin Pop
  Wrong disks given as parameters will be signaled using this
111 a8083063 Iustin Pop
  exception.
112 a8083063 Iustin Pop
  """
113 a8083063 Iustin Pop
  pass
114 a8083063 Iustin Pop
115 7c0d6283 Michael Hanselmann
116 a8083063 Iustin Pop
def Usage():
117 a8083063 Iustin Pop
  """Shows program usage information and exits the program."""
118 a8083063 Iustin Pop
119 a8083063 Iustin Pop
  print >> sys.stderr, "Usage:"
120 a8083063 Iustin Pop
  print >> sys.stderr, USAGE
121 a8083063 Iustin Pop
  sys.exit(2)
122 a8083063 Iustin Pop
123 a8083063 Iustin Pop
124 a8083063 Iustin Pop
def ParseOptions():
125 a8083063 Iustin Pop
  """Parses the command line options.
126 a8083063 Iustin Pop
127 a8083063 Iustin Pop
  In case of command line errors, it will show the usage and exit the
128 a8083063 Iustin Pop
  program.
129 a8083063 Iustin Pop
130 a8083063 Iustin Pop
  Returns:
131 a8083063 Iustin Pop
    (options, args), as returned by OptionParser.parse_args
132 a8083063 Iustin Pop
  """
133 7260cfbe Iustin Pop
  global verbose_flag # pylint: disable-msg=W0603
134 a8083063 Iustin Pop
135 a8083063 Iustin Pop
  parser = optparse.OptionParser(usage="\n%s" % USAGE,
136 a8083063 Iustin Pop
                                 version="%%prog (ganeti) %s" %
137 a8083063 Iustin Pop
                                 constants.RELEASE_VERSION)
138 a8083063 Iustin Pop
139 a8083063 Iustin Pop
  parser.add_option("--alldisks", dest="alldisks",
140 a8083063 Iustin Pop
                    help="erase ALL disks", action="store_true",
141 a8083063 Iustin Pop
                    default=False)
142 a8083063 Iustin Pop
  parser.add_option("-d", "--disks", dest="disks",
143 a8083063 Iustin Pop
                    help="Choose disks (e.g. hda,hdg)",
144 a8083063 Iustin Pop
                    metavar="DISKLIST")
145 9cdb9578 Iustin Pop
  parser.add_option(cli.VERBOSE_OPT)
146 d1687c6f Iustin Pop
  parser.add_option("-r", "--allow-removable",
147 d1687c6f Iustin Pop
                    action="store_true", dest="removable_ok", default=False,
148 d1687c6f Iustin Pop
                    help="allow and use removable devices too")
149 a8083063 Iustin Pop
  parser.add_option("-g", "--vg-name", type="string",
150 a8083063 Iustin Pop
                    dest="vgname", default="xenvg", metavar="NAME",
151 a8083063 Iustin Pop
                    help="the volume group to be created [default: xenvg]")
152 a8083063 Iustin Pop
153 a8083063 Iustin Pop
154 a8083063 Iustin Pop
  options, args = parser.parse_args()
155 a8083063 Iustin Pop
  if len(args) != 1:
156 a8083063 Iustin Pop
    Usage()
157 a8083063 Iustin Pop
158 a8083063 Iustin Pop
  verbose_flag = options.verbose
159 a8083063 Iustin Pop
160 a8083063 Iustin Pop
  return options, args
161 a8083063 Iustin Pop
162 a8083063 Iustin Pop
163 a8083063 Iustin Pop
def ExecCommand(command):
164 a8083063 Iustin Pop
  """Executes a command.
165 a8083063 Iustin Pop
166 a8083063 Iustin Pop
  This is just a wrapper around commands.getstatusoutput, with the
167 a8083063 Iustin Pop
  difference that if the command line argument -v has been given, it
168 a8083063 Iustin Pop
  will print the command line and the command output on stdout.
169 a8083063 Iustin Pop
170 a8083063 Iustin Pop
  Args:
171 a8083063 Iustin Pop
    the command line
172 a8083063 Iustin Pop
  Returns:
173 a8083063 Iustin Pop
    (status, output) where status is the exit status and output the
174 a8083063 Iustin Pop
      stdout and stderr of the command together
175 a8083063 Iustin Pop
  """
176 a8083063 Iustin Pop
177 a8083063 Iustin Pop
  if verbose_flag:
178 a8083063 Iustin Pop
    print command
179 a8083063 Iustin Pop
  result = RunCmd(command)
180 a8083063 Iustin Pop
  if verbose_flag:
181 a8083063 Iustin Pop
    print result.output
182 a8083063 Iustin Pop
  return result
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
185 a8083063 Iustin Pop
def CheckPrereq():
186 a8083063 Iustin Pop
  """Check the prerequisites of this program.
187 a8083063 Iustin Pop
188 a8083063 Iustin Pop
  It check that it runs on Linux 2.6, and that /sys is mounted and the
189 a8083063 Iustin Pop
  fact that /sys/block is a directory.
190 a8083063 Iustin Pop
  """
191 a8083063 Iustin Pop
192 a8083063 Iustin Pop
  if os.getuid() != 0:
193 a8083063 Iustin Pop
    raise PrereqError("This tool runs as root only. Really.")
194 a8083063 Iustin Pop
195 f4ad2ef0 Iustin Pop
  osname, _, release, _, _ = os.uname()
196 a8083063 Iustin Pop
  if osname != 'Linux':
197 f4bc1f2c Michael Hanselmann
    raise PrereqError("This tool only runs on Linux"
198 f4bc1f2c Michael Hanselmann
                      " (detected OS: %s)." % osname)
199 a8083063 Iustin Pop
200 a8083063 Iustin Pop
  if not release.startswith("2.6."):
201 f4bc1f2c Michael Hanselmann
    raise PrereqError("Wrong major kernel version (detected %s, needs"
202 f4bc1f2c Michael Hanselmann
                      " 2.6.*)" % release)
203 a8083063 Iustin Pop
204 a8083063 Iustin Pop
  if not os.path.ismount("/sys"):
205 f4bc1f2c Michael Hanselmann
    raise PrereqError("Can't find a filesystem mounted at /sys."
206 f4bc1f2c Michael Hanselmann
                      " Please mount /sys.")
207 a8083063 Iustin Pop
208 a8083063 Iustin Pop
  if not os.path.isdir("/sys/block"):
209 f4bc1f2c Michael Hanselmann
    raise SysconfigError("Can't find /sys/block directory. Has the"
210 f4bc1f2c Michael Hanselmann
                         " layout of /sys changed?")
211 a8083063 Iustin Pop
212 a8083063 Iustin Pop
  if not os.path.ismount("/proc"):
213 f4bc1f2c Michael Hanselmann
    raise PrereqError("Can't find a filesystem mounted at /proc."
214 f4bc1f2c Michael Hanselmann
                      " Please mount /proc.")
215 a8083063 Iustin Pop
216 a8083063 Iustin Pop
  if not os.path.exists("/proc/mounts"):
217 a8083063 Iustin Pop
    raise SysconfigError("Can't find /proc/mounts")
218 a8083063 Iustin Pop
219 a8083063 Iustin Pop
220 a8083063 Iustin Pop
def CheckVGExists(vgname):
221 a8083063 Iustin Pop
  """Checks to see if a volume group exists.
222 a8083063 Iustin Pop
223 a8083063 Iustin Pop
  Args:
224 a8083063 Iustin Pop
    vgname: the volume group name
225 a8083063 Iustin Pop
226 a8083063 Iustin Pop
  Returns:
227 a8083063 Iustin Pop
    a four-tuple (exists, lv_count, vg_size, vg_free), where:
228 a8083063 Iustin Pop
      exists: True if the volume exists, otherwise False; if False,
229 a8083063 Iustin Pop
        all other members of the tuple are None
230 a8083063 Iustin Pop
      lv_count: The number of logical volumes in the volume group
231 a8083063 Iustin Pop
      vg_size: The total size of the volume group (in gibibytes)
232 a8083063 Iustin Pop
      vg_free: The available space in the volume group
233 a8083063 Iustin Pop
  """
234 a8083063 Iustin Pop
235 f4bc1f2c Michael Hanselmann
  result = ExecCommand("vgs --nohead -o lv_count,vg_size,vg_free"
236 f4bc1f2c Michael Hanselmann
                       " --nosuffix --units g"
237 f4bc1f2c Michael Hanselmann
                       " --ignorelockingfailure %s" % vgname)
238 a8083063 Iustin Pop
  if not result.failed:
239 a8083063 Iustin Pop
    try:
240 a8083063 Iustin Pop
      lv_count, vg_size, vg_free = result.stdout.strip().split()
241 a8083063 Iustin Pop
    except ValueError:
242 a8083063 Iustin Pop
      # This means the output of vgdisplay can't be parsed
243 a8083063 Iustin Pop
      raise PrereqError("cannot parse output of vgs (%s)" % result.stdout)
244 a8083063 Iustin Pop
  else:
245 a8083063 Iustin Pop
    lv_count = vg_size = vg_free = None
246 a8083063 Iustin Pop
247 a8083063 Iustin Pop
  return not result.failed, lv_count, vg_size, vg_free
248 a8083063 Iustin Pop
249 a8083063 Iustin Pop
250 a8083063 Iustin Pop
def CheckSysDev(name, devnum):
251 a8083063 Iustin Pop
  """Checks consistency between /sys and /dev trees.
252 a8083063 Iustin Pop
253 a8083063 Iustin Pop
  In /sys/block/<name>/dev and /sys/block/<name>/<part>/dev are the
254 a8083063 Iustin Pop
  kernel-known device numbers. The /dev/<name> block/char devices are
255 a8083063 Iustin Pop
  created by userspace and thus could differ from the kernel
256 a8083063 Iustin Pop
  view. This function checks the consistency between the device number
257 a8083063 Iustin Pop
  read from /sys and the actual device number in /dev.
258 a8083063 Iustin Pop
259 a8083063 Iustin Pop
  Note that since the system could be using udev which removes and
260 a8083063 Iustin Pop
  recreates the device nodes on partition table rescan, we need to do
261 a8083063 Iustin Pop
  some retries here. Since we only do a stat, we can afford to do many
262 a8083063 Iustin Pop
  short retries.
263 a8083063 Iustin Pop
264 a8083063 Iustin Pop
  Args:
265 a8083063 Iustin Pop
   name: the device name, e.g. 'sda'
266 a8083063 Iustin Pop
   devnum: the device number, e.g. 0x803 (2051 in decimal) for sda3
267 a8083063 Iustin Pop
268 a8083063 Iustin Pop
  Returns:
269 5bbd3f7f Michael Hanselmann
    None; failure of the check is signaled by raising a
270 a8083063 Iustin Pop
      SysconfigError exception
271 a8083063 Iustin Pop
  """
272 a8083063 Iustin Pop
273 a8083063 Iustin Pop
  path = "/dev/%s" % name
274 f4ad2ef0 Iustin Pop
  for _ in range(40):
275 a8083063 Iustin Pop
    if os.path.exists(path):
276 a8083063 Iustin Pop
      break
277 a8083063 Iustin Pop
    time.sleep(0.250)
278 a8083063 Iustin Pop
  else:
279 f4bc1f2c Michael Hanselmann
    raise SysconfigError("the device file %s does not exist, but the block"
280 f4bc1f2c Michael Hanselmann
                         " device exists in the /sys/block tree" % path)
281 a8083063 Iustin Pop
  rdev = os.stat(path).st_rdev
282 a8083063 Iustin Pop
  if devnum != rdev:
283 f4bc1f2c Michael Hanselmann
    raise SysconfigError("For device %s, the major:minor in /dev is %04x"
284 f4bc1f2c Michael Hanselmann
                         " while the major:minor in sysfs is %s" %
285 a8083063 Iustin Pop
                         (path, rdev, devnum))
286 a8083063 Iustin Pop
287 a8083063 Iustin Pop
288 a8083063 Iustin Pop
def ReadDev(syspath):
289 a8083063 Iustin Pop
  """Reads the device number from a sysfs path.
290 a8083063 Iustin Pop
291 a8083063 Iustin Pop
  The device number is given in sysfs under a block device directory
292 a8083063 Iustin Pop
  in a file named 'dev' which contains major:minor (in ASCII). This
293 a8083063 Iustin Pop
  function reads that file and converts the major:minor pair to a dev
294 a8083063 Iustin Pop
  number.
295 a8083063 Iustin Pop
296 a8083063 Iustin Pop
  Args:
297 a8083063 Iustin Pop
    syspath: the path to a block device dir in sysfs, e.g. /sys/block/sda
298 a8083063 Iustin Pop
299 a8083063 Iustin Pop
  Returns:
300 a8083063 Iustin Pop
    the device number
301 a8083063 Iustin Pop
  """
302 a8083063 Iustin Pop
303 a8083063 Iustin Pop
  if not os.path.exists("%s/dev" % syspath):
304 a8083063 Iustin Pop
    raise ProgrammingError("Invalid path passed to ReadDev: %s" % syspath)
305 a8083063 Iustin Pop
  f = open("%s/dev" % syspath)
306 a8083063 Iustin Pop
  data = f.read().strip()
307 a8083063 Iustin Pop
  f.close()
308 a8083063 Iustin Pop
  major, minor = data.split(":", 1)
309 a8083063 Iustin Pop
  major = int(major)
310 a8083063 Iustin Pop
  minor = int(minor)
311 a8083063 Iustin Pop
  dev = os.makedev(major, minor)
312 a8083063 Iustin Pop
  return dev
313 a8083063 Iustin Pop
314 a8083063 Iustin Pop
315 a8083063 Iustin Pop
def ReadSize(syspath):
316 a8083063 Iustin Pop
  """Reads the size from a sysfs path.
317 a8083063 Iustin Pop
318 a8083063 Iustin Pop
  The size is given in sysfs under a block device directory in a file
319 a8083063 Iustin Pop
  named 'size' which contains the number of sectors (in ASCII). This
320 a8083063 Iustin Pop
  function reads that file and converts the number in sectors to the
321 a8083063 Iustin Pop
  size in bytes.
322 a8083063 Iustin Pop
323 a8083063 Iustin Pop
  Args:
324 a8083063 Iustin Pop
    syspath: the path to a block device dir in sysfs, e.g. /sys/block/sda
325 a8083063 Iustin Pop
326 a8083063 Iustin Pop
  Returns:
327 a8083063 Iustin Pop
    the device size in bytes
328 a8083063 Iustin Pop
  """
329 a8083063 Iustin Pop
330 a8083063 Iustin Pop
  if not os.path.exists("%s/size" % syspath):
331 a8083063 Iustin Pop
    raise ProgrammingError("Invalid path passed to ReadSize: %s" % syspath)
332 a8083063 Iustin Pop
  f = open("%s/size" % syspath)
333 a8083063 Iustin Pop
  data = f.read().strip()
334 a8083063 Iustin Pop
  f.close()
335 a8083063 Iustin Pop
  size = 512L * int(data)
336 a8083063 Iustin Pop
  return size
337 a8083063 Iustin Pop
338 a8083063 Iustin Pop
339 a8083063 Iustin Pop
def ReadPV(name):
340 a8083063 Iustin Pop
  """Reads physical volume information.
341 a8083063 Iustin Pop
342 a8083063 Iustin Pop
  This function tries to see if a block device is a physical volume.
343 a8083063 Iustin Pop
344 a8083063 Iustin Pop
  Args:
345 a8083063 Iustin Pop
    dev: the device name (e.g. sda)
346 a8083063 Iustin Pop
  Returns:
347 a8083063 Iustin Pop
    The name of the volume group to which this PV belongs, or
348 a8083063 Iustin Pop
    "" if this PV is not in use, or
349 a8083063 Iustin Pop
    None if this is not a PV
350 a8083063 Iustin Pop
  """
351 a8083063 Iustin Pop
352 a8083063 Iustin Pop
  result = ExecCommand("pvdisplay -c /dev/%s" % name)
353 a8083063 Iustin Pop
  if result.failed:
354 a8083063 Iustin Pop
    return None
355 a8083063 Iustin Pop
  vgname = result.stdout.strip().split(":")[1]
356 a8083063 Iustin Pop
  return vgname
357 a8083063 Iustin Pop
358 a8083063 Iustin Pop
359 d1687c6f Iustin Pop
def GetDiskList(opts):
360 a8083063 Iustin Pop
  """Computes the block device list for this system.
361 a8083063 Iustin Pop
362 a8083063 Iustin Pop
  This function examines the /sys/block tree and using information
363 a8083063 Iustin Pop
  therein, computes the status of the block device.
364 a8083063 Iustin Pop
365 a8083063 Iustin Pop
  Returns:
366 a8083063 Iustin Pop
    [(name, size, dev, partitions, inuse), ...]
367 a8083063 Iustin Pop
  where:
368 a8083063 Iustin Pop
    name is the block device name (e.g. sda)
369 a8083063 Iustin Pop
    size the size in bytes
370 a8083063 Iustin Pop
    dev  the device number (e.g. 8704 for hdg)
371 a8083063 Iustin Pop
    partitions is [(name, size, dev), ...] mirroring the disk list data
372 a8083063 Iustin Pop
    inuse is a boolean showing the in-use status of the disk, computed as the
373 a8083063 Iustin Pop
      possibility of re-reading the partition table (the meaning of the
374 a8083063 Iustin Pop
      operation varies with the kernel version, but is usually accurate;
375 a8083063 Iustin Pop
      a mounted disk/partition or swap-area or PV with active LVs on it
376 a8083063 Iustin Pop
      is busy)
377 a8083063 Iustin Pop
  """
378 a8083063 Iustin Pop
379 a8083063 Iustin Pop
  dlist = []
380 a8083063 Iustin Pop
  for name in os.listdir("/sys/block"):
381 a8083063 Iustin Pop
    if (not name.startswith("hd") and
382 a8083063 Iustin Pop
        not name.startswith("sd") and
383 3c9a0742 Michael Hanselmann
        not name.startswith("ubd")):
384 a8083063 Iustin Pop
      continue
385 a8083063 Iustin Pop
386 a8083063 Iustin Pop
    size = ReadSize("/sys/block/%s" % name)
387 a8083063 Iustin Pop
388 a8083063 Iustin Pop
    f = open("/sys/block/%s/removable" % name)
389 a8083063 Iustin Pop
    removable = int(f.read().strip())
390 a8083063 Iustin Pop
    f.close()
391 a8083063 Iustin Pop
392 d1687c6f Iustin Pop
    if removable and not opts.removable_ok:
393 a8083063 Iustin Pop
      continue
394 a8083063 Iustin Pop
395 a8083063 Iustin Pop
    dev = ReadDev("/sys/block/%s" % name)
396 a8083063 Iustin Pop
    CheckSysDev(name, dev)
397 a8083063 Iustin Pop
    inuse = not CheckReread(name)
398 a8083063 Iustin Pop
    # Enumerate partitions of the block device
399 a8083063 Iustin Pop
    partitions = []
400 a8083063 Iustin Pop
    for partname in os.listdir("/sys/block/%s" % name):
401 a8083063 Iustin Pop
      if not partname.startswith(name):
402 a8083063 Iustin Pop
        continue
403 a8083063 Iustin Pop
      partdev = ReadDev("/sys/block/%s/%s" % (name, partname))
404 a8083063 Iustin Pop
      partsize = ReadSize("/sys/block/%s/%s" % (name, partname))
405 a8083063 Iustin Pop
      CheckSysDev(partname, partdev)
406 a8083063 Iustin Pop
      partitions.append((partname, partsize, partdev))
407 a8083063 Iustin Pop
    partitions.sort()
408 a8083063 Iustin Pop
    dlist.append((name, size, dev, partitions, inuse))
409 a8083063 Iustin Pop
  dlist.sort()
410 a8083063 Iustin Pop
  return dlist
411 a8083063 Iustin Pop
412 a8083063 Iustin Pop
413 a8083063 Iustin Pop
def GetMountInfo():
414 a8083063 Iustin Pop
  """Reads /proc/mounts and computes the mountpoint-devnum mapping.
415 a8083063 Iustin Pop
416 a8083063 Iustin Pop
  This function reads /proc/mounts, finds the mounted filesystems
417 a8083063 Iustin Pop
  (excepting a hard-coded blacklist of network and virtual
418 a8083063 Iustin Pop
  filesystems) and does a stat on these mountpoints. The st_dev number
419 a8083063 Iustin Pop
  of the results is memorised for later matching against the
420 a8083063 Iustin Pop
  /sys/block devices.
421 a8083063 Iustin Pop
422 a8083063 Iustin Pop
  Returns:
423 a8083063 Iustin Pop
   a mountpoint: device number dictionary
424 a8083063 Iustin Pop
  """
425 a8083063 Iustin Pop
426 3374afa9 Guido Trotter
  mountlines = ReadFile("/proc/mounts").splitlines()
427 a8083063 Iustin Pop
  mounts = {}
428 a8083063 Iustin Pop
  for line in mountlines:
429 f4ad2ef0 Iustin Pop
    _, mountpoint, fstype, _ = line.split(None, 3)
430 a8083063 Iustin Pop
    # fs type blacklist
431 a8083063 Iustin Pop
    if fstype in ["nfs", "nfs4", "autofs", "tmpfs", "proc", "sysfs"]:
432 a8083063 Iustin Pop
      continue
433 a8083063 Iustin Pop
    try:
434 a8083063 Iustin Pop
      dev = os.stat(mountpoint).st_dev
435 a8083063 Iustin Pop
    except OSError, err:
436 a8083063 Iustin Pop
      # this should be a fairly rare error, since we are blacklisting
437 a8083063 Iustin Pop
      # network filesystems; with this in mind, we'll ignore it,
438 a8083063 Iustin Pop
      # since the rereadpt check catches in-use filesystems,
439 a8083063 Iustin Pop
      # and this is used for disk information only
440 a8083063 Iustin Pop
      print >> sys.stderr, ("Can't stat mountpoint '%s': %s" %
441 a8083063 Iustin Pop
                            (mountpoint, err))
442 a8083063 Iustin Pop
      print >> sys.stderr, "Ignoring."
443 a8083063 Iustin Pop
      continue
444 a8083063 Iustin Pop
    mounts[dev] = mountpoint
445 a8083063 Iustin Pop
  return mounts
446 a8083063 Iustin Pop
447 a8083063 Iustin Pop
448 a8083063 Iustin Pop
def DevInfo(name, dev, mountinfo):
449 5bbd3f7f Michael Hanselmann
  """Computes miscellaneous information about a block device.
450 a8083063 Iustin Pop
451 a8083063 Iustin Pop
  Args:
452 a8083063 Iustin Pop
    name: the device name, e.g. sda
453 a8083063 Iustin Pop
454 a8083063 Iustin Pop
  Returns:
455 a8083063 Iustin Pop
    (mpath, whatvg, fileinfo), where
456 a8083063 Iustin Pop
    mpath is the mount path where this device is mounted or None
457 a8083063 Iustin Pop
    whatvg is the result of the ReadPV function
458 a8083063 Iustin Pop
    fileinfo is the output of file -bs on the device
459 a8083063 Iustin Pop
  """
460 a8083063 Iustin Pop
461 a8083063 Iustin Pop
  if dev in mountinfo:
462 a8083063 Iustin Pop
    mpath = mountinfo[dev]
463 a8083063 Iustin Pop
  else:
464 a8083063 Iustin Pop
    mpath = None
465 a8083063 Iustin Pop
466 a8083063 Iustin Pop
  whatvg = ReadPV(name)
467 a8083063 Iustin Pop
468 a8083063 Iustin Pop
  result = ExecCommand("file -bs /dev/%s" % name)
469 a8083063 Iustin Pop
  if result.failed:
470 a8083063 Iustin Pop
    fileinfo = "<error: %s>" % result.stderr
471 a8083063 Iustin Pop
  fileinfo = result.stdout[:45]
472 a8083063 Iustin Pop
  return mpath, whatvg, fileinfo
473 a8083063 Iustin Pop
474 a8083063 Iustin Pop
475 d1687c6f Iustin Pop
def ShowDiskInfo(opts):
476 a8083063 Iustin Pop
  """Shows a nicely formatted block device list for this system.
477 a8083063 Iustin Pop
478 5bbd3f7f Michael Hanselmann
  This function shows the user a table with the information gathered
479 a8083063 Iustin Pop
  by the other functions defined, in order to help the user make a
480 a8083063 Iustin Pop
  choice about which disks should be allocated to our volume group.
481 a8083063 Iustin Pop
482 a8083063 Iustin Pop
  """
483 a8083063 Iustin Pop
  mounts = GetMountInfo()
484 d1687c6f Iustin Pop
  dlist = GetDiskList(opts)
485 a8083063 Iustin Pop
486 a8083063 Iustin Pop
  print "------- Disk information -------"
487 e194129a Stephen Shirley
  headers = {
488 e194129a Stephen Shirley
      "name": "Name",
489 e194129a Stephen Shirley
      "size": "Size[M]",
490 e194129a Stephen Shirley
      "used": "Used",
491 e194129a Stephen Shirley
      "mount": "Mount",
492 e194129a Stephen Shirley
      "lvm": "LVM?",
493 e194129a Stephen Shirley
      "info": "Info"
494 e194129a Stephen Shirley
      }
495 e194129a Stephen Shirley
  fields = ["name", "size", "used", "mount", "lvm", "info"]
496 a8083063 Iustin Pop
497 a8083063 Iustin Pop
  flatlist = []
498 a8083063 Iustin Pop
  # Flatten the [(disk, [partition,...]), ...] list
499 a8083063 Iustin Pop
  for name, size, dev, parts, inuse in dlist:
500 a8083063 Iustin Pop
    if inuse:
501 a8083063 Iustin Pop
      str_inuse = "yes"
502 a8083063 Iustin Pop
    else:
503 a8083063 Iustin Pop
      str_inuse = "no"
504 a8083063 Iustin Pop
    flatlist.append((name, size, dev, str_inuse))
505 a8083063 Iustin Pop
    for partname, partsize, partdev in parts:
506 a8083063 Iustin Pop
      flatlist.append((partname, partsize, partdev, ""))
507 a8083063 Iustin Pop
508 e194129a Stephen Shirley
  strlist = []
509 a8083063 Iustin Pop
  for name, size, dev, in_use in flatlist:
510 a8083063 Iustin Pop
    mp, vgname, fileinfo = DevInfo(name, dev, mounts)
511 a8083063 Iustin Pop
    if mp is None:
512 a8083063 Iustin Pop
      mp = "-"
513 a8083063 Iustin Pop
    if vgname is None:
514 a8083063 Iustin Pop
      lvminfo = "-"
515 a8083063 Iustin Pop
    elif vgname == "":
516 a8083063 Iustin Pop
      lvminfo = "yes,free"
517 a8083063 Iustin Pop
    else:
518 a8083063 Iustin Pop
      lvminfo = "in %s" % vgname
519 a8083063 Iustin Pop
520 a8083063 Iustin Pop
    if len(name) > 3:
521 a8083063 Iustin Pop
      # Indent partitions
522 a8083063 Iustin Pop
      name = " %s" % name
523 e194129a Stephen Shirley
524 e194129a Stephen Shirley
    strlist.append([name, "%.2f" % (float(size) / 1024 / 1024),
525 e194129a Stephen Shirley
                    in_use, mp, lvminfo, fileinfo])
526 e194129a Stephen Shirley
527 e194129a Stephen Shirley
  data = cli.GenerateTable(headers, fields, None,
528 e194129a Stephen Shirley
                           strlist, numfields=["size"])
529 e194129a Stephen Shirley
530 e194129a Stephen Shirley
  for line in data:
531 e194129a Stephen Shirley
    print line
532 a8083063 Iustin Pop
533 a8083063 Iustin Pop
534 a8083063 Iustin Pop
def CheckReread(name):
535 a8083063 Iustin Pop
  """Check to see if a block device is in use.
536 a8083063 Iustin Pop
537 a8083063 Iustin Pop
  Uses blockdev to reread the partition table of a block device, and
538 a8083063 Iustin Pop
  thus compute the in-use status. See the discussion in GetDiskList
539 a8083063 Iustin Pop
  about the meaning of 'in use'.
540 a8083063 Iustin Pop
541 a8083063 Iustin Pop
  Returns:
542 a8083063 Iustin Pop
    boolean, the in-use status of the device
543 a8083063 Iustin Pop
  """
544 a8083063 Iustin Pop
545 f4ad2ef0 Iustin Pop
  for _ in range(3):
546 a8083063 Iustin Pop
    result = ExecCommand("blockdev --rereadpt /dev/%s" % name)
547 a8083063 Iustin Pop
    if not result.failed:
548 a8083063 Iustin Pop
      break
549 a8083063 Iustin Pop
    time.sleep(2)
550 a8083063 Iustin Pop
551 a8083063 Iustin Pop
  return not result.failed
552 a8083063 Iustin Pop
553 a8083063 Iustin Pop
554 a8083063 Iustin Pop
def WipeDisk(name):
555 a8083063 Iustin Pop
  """Wipes a block device.
556 a8083063 Iustin Pop
557 a8083063 Iustin Pop
  This function wipes a block device, by clearing and re-reading the
558 a8083063 Iustin Pop
  partition table. If not successful, it writes back the old partition
559 a8083063 Iustin Pop
  data, and leaves the cleanup to the user.
560 a8083063 Iustin Pop
561 a8083063 Iustin Pop
  Args:
562 a8083063 Iustin Pop
    the device name (e.g. sda)
563 a8083063 Iustin Pop
  """
564 a8083063 Iustin Pop
565 a8083063 Iustin Pop
  if not CheckReread(name):
566 f4bc1f2c Michael Hanselmann
    raise OperationalError("CRITICAL: disk %s you selected seems to be in"
567 f4bc1f2c Michael Hanselmann
                           " use. ABORTING!" % name)
568 a8083063 Iustin Pop
569 a8083063 Iustin Pop
  fd = os.open("/dev/%s" % name, os.O_RDWR | os.O_SYNC)
570 a8083063 Iustin Pop
  olddata = os.read(fd, 512)
571 a8083063 Iustin Pop
  if len(olddata) != 512:
572 f4bc1f2c Michael Hanselmann
    raise OperationalError("CRITICAL: Can't read partition table information"
573 f4bc1f2c Michael Hanselmann
                           " from /dev/%s (needed 512 bytes, got %d" %
574 a8083063 Iustin Pop
                           (name, len(olddata)))
575 a8083063 Iustin Pop
  newdata = "\0" * 512
576 a8083063 Iustin Pop
  os.lseek(fd, 0, 0)
577 a8083063 Iustin Pop
  bytes_written = os.write(fd, newdata)
578 a8083063 Iustin Pop
  os.close(fd)
579 a8083063 Iustin Pop
  if bytes_written != 512:
580 a8083063 Iustin Pop
    raise OperationalError("CRITICAL: Can't write partition table information"
581 f4bc1f2c Michael Hanselmann
                           " to /dev/%s (tried to write 512 bytes, written"
582 f4bc1f2c Michael Hanselmann
                           " %d. I don't know how to cleanup. Sorry." %
583 a8083063 Iustin Pop
                           (name, bytes_written))
584 a8083063 Iustin Pop
585 a8083063 Iustin Pop
  if not CheckReread(name):
586 a8083063 Iustin Pop
    fd = os.open("/dev/%s" % name, os.O_RDWR | os.O_SYNC)
587 a8083063 Iustin Pop
    os.write(fd, olddata)
588 a8083063 Iustin Pop
    os.close(fd)
589 f4bc1f2c Michael Hanselmann
    raise OperationalError("CRITICAL: disk %s which I have just wiped cannot"
590 f4bc1f2c Michael Hanselmann
                           " reread partition table. Most likely, it is"
591 f4bc1f2c Michael Hanselmann
                           " in use. You have to clean after this yourself."
592 f4bc1f2c Michael Hanselmann
                           " I tried to restore the old partition table,"
593 f4bc1f2c Michael Hanselmann
                           " but I cannot guarantee nothing has broken." %
594 a8083063 Iustin Pop
                           name)
595 a8083063 Iustin Pop
596 a8083063 Iustin Pop
597 a8083063 Iustin Pop
def PartitionDisk(name):
598 a8083063 Iustin Pop
  """Partitions a disk.
599 a8083063 Iustin Pop
600 a8083063 Iustin Pop
  This function creates a single partition spanning the entire disk,
601 a8083063 Iustin Pop
  by means of fdisk.
602 a8083063 Iustin Pop
603 a8083063 Iustin Pop
  Args:
604 a8083063 Iustin Pop
    the device name, e.g. sda
605 a8083063 Iustin Pop
  """
606 a8083063 Iustin Pop
  result = ExecCommand(
607 a8083063 Iustin Pop
    'echo ,,8e, | sfdisk /dev/%s' % name)
608 a8083063 Iustin Pop
  if result.failed:
609 f4bc1f2c Michael Hanselmann
    raise OperationalError("CRITICAL: disk %s which I have just partitioned"
610 f4bc1f2c Michael Hanselmann
                           " cannot reread its partition table, or there"
611 f4bc1f2c Michael Hanselmann
                           " is some other sfdisk error. Likely, it is in"
612 f4bc1f2c Michael Hanselmann
                           " use. You have to clean this yourself. Error"
613 f4bc1f2c Michael Hanselmann
                           " message from sfdisk: %s" %
614 a8083063 Iustin Pop
                           (name, result.output))
615 a8083063 Iustin Pop
616 a8083063 Iustin Pop
617 a8083063 Iustin Pop
def CreatePVOnDisk(name):
618 a8083063 Iustin Pop
  """Creates a physical volume on a block device.
619 a8083063 Iustin Pop
620 a8083063 Iustin Pop
  This function creates a physical volume on a block device, overriding
621 a8083063 Iustin Pop
  all warnings. So it can wipe existing PVs and PVs which are in a VG.
622 a8083063 Iustin Pop
623 a8083063 Iustin Pop
  Args:
624 a8083063 Iustin Pop
    the device name, e.g. sda
625 a8083063 Iustin Pop
626 a8083063 Iustin Pop
  """
627 a8083063 Iustin Pop
  result = ExecCommand("pvcreate -yff /dev/%s1 " % name)
628 a8083063 Iustin Pop
  if result.failed:
629 f4bc1f2c Michael Hanselmann
    raise OperationalError("I cannot create a physical volume on"
630 f4bc1f2c Michael Hanselmann
                           " partition /dev/%s1. Error message: %s."
631 f4bc1f2c Michael Hanselmann
                           " Please clean up yourself." %
632 a8083063 Iustin Pop
                           (name, result.output))
633 a8083063 Iustin Pop
634 a8083063 Iustin Pop
635 a8083063 Iustin Pop
def CreateVG(vgname, disks):
636 a8083063 Iustin Pop
  """Creates the volume group.
637 a8083063 Iustin Pop
638 a8083063 Iustin Pop
  This function creates a volume group named `vgname` on the disks
639 a8083063 Iustin Pop
  given as parameters. The physical extent size is set to 64MB.
640 a8083063 Iustin Pop
641 a8083063 Iustin Pop
  Args:
642 a8083063 Iustin Pop
    disks: a list of disk names, e.g. ['sda','sdb']
643 a8083063 Iustin Pop
644 a8083063 Iustin Pop
  """
645 a8083063 Iustin Pop
  pnames = ["'/dev/%s1'" % disk for disk in disks]
646 a8083063 Iustin Pop
  result = ExecCommand("vgcreate -s 64MB '%s' %s" % (vgname, " ".join(pnames)))
647 a8083063 Iustin Pop
  if result.failed:
648 f4bc1f2c Michael Hanselmann
    raise OperationalError("I cannot create the volume group %s from"
649 f4bc1f2c Michael Hanselmann
                           " disks %s. Error message: %s. Please clean up"
650 f4bc1f2c Michael Hanselmann
                           " yourself." %
651 a8083063 Iustin Pop
                           (vgname, " ".join(disks), result.output))
652 a8083063 Iustin Pop
653 a8083063 Iustin Pop
654 a8083063 Iustin Pop
def ValidateDiskList(options):
655 a8083063 Iustin Pop
  """Validates or computes the disk list for create.
656 a8083063 Iustin Pop
657 a8083063 Iustin Pop
  This function either computes the available disk list (if the user
658 a8083063 Iustin Pop
  gave --alldisks option), or validates the user-given disk list (by
659 a8083063 Iustin Pop
  using the --disks option) such that all given disks are present and
660 a8083063 Iustin Pop
  not in use.
661 a8083063 Iustin Pop
662 a8083063 Iustin Pop
  Args:
663 a8083063 Iustin Pop
    the options returned from OptParser.parse_options
664 a8083063 Iustin Pop
665 a8083063 Iustin Pop
  Returns:
666 a8083063 Iustin Pop
    a list of disk names, e.g. ['sda', 'sdb']
667 a8083063 Iustin Pop
  """
668 a8083063 Iustin Pop
669 d1687c6f Iustin Pop
  sysdisks = GetDiskList(options)
670 a8083063 Iustin Pop
  if not sysdisks:
671 f4bc1f2c Michael Hanselmann
    raise PrereqError("no disks found (I looked for"
672 f4bc1f2c Michael Hanselmann
                      " non-removable block devices).")
673 a8083063 Iustin Pop
  sysd_free = []
674 a8083063 Iustin Pop
  sysd_used = []
675 f4ad2ef0 Iustin Pop
  for name, _, _, _, used in sysdisks:
676 a8083063 Iustin Pop
    if used:
677 a8083063 Iustin Pop
      sysd_used.append(name)
678 a8083063 Iustin Pop
    else:
679 a8083063 Iustin Pop
      sysd_free.append(name)
680 a8083063 Iustin Pop
681 a8083063 Iustin Pop
  if not sysd_free:
682 a8083063 Iustin Pop
    raise PrereqError("no free disks found! (%d in-use disks)" %
683 a8083063 Iustin Pop
                      len(sysd_used))
684 a8083063 Iustin Pop
  if options.alldisks:
685 a8083063 Iustin Pop
    disklist = sysd_free
686 a8083063 Iustin Pop
  elif options.disks:
687 a8083063 Iustin Pop
    disklist = options.disks.split(",")
688 a8083063 Iustin Pop
    for name in disklist:
689 a8083063 Iustin Pop
      if name in sysd_used:
690 a8083063 Iustin Pop
        raise ParameterError("disk %s is in use, cannot wipe!" % name)
691 a8083063 Iustin Pop
      if name not in sysd_free:
692 a8083063 Iustin Pop
        raise ParameterError("cannot find disk %s!" % name)
693 a8083063 Iustin Pop
  else:
694 a8083063 Iustin Pop
    raise ParameterError("Please use either --alldisks or --disks!")
695 a8083063 Iustin Pop
696 a8083063 Iustin Pop
  return disklist
697 a8083063 Iustin Pop
698 f4bc1f2c Michael Hanselmann
699 a8083063 Iustin Pop
def BootStrap():
700 a8083063 Iustin Pop
  """Actual main routine."""
701 a8083063 Iustin Pop
702 a8083063 Iustin Pop
  CheckPrereq()
703 a8083063 Iustin Pop
704 a8083063 Iustin Pop
  options, args = ParseOptions()
705 a8083063 Iustin Pop
  vgname = options.vgname
706 a8083063 Iustin Pop
  command = args.pop(0)
707 a8083063 Iustin Pop
  if command == "diskinfo":
708 d1687c6f Iustin Pop
    ShowDiskInfo(options)
709 a8083063 Iustin Pop
    return
710 a8083063 Iustin Pop
  if command != "create":
711 a8083063 Iustin Pop
    Usage()
712 a8083063 Iustin Pop
713 a8083063 Iustin Pop
  exists, lv_count, vg_size, vg_free = CheckVGExists(vgname)
714 a8083063 Iustin Pop
  if exists:
715 a8083063 Iustin Pop
    raise PrereqError("It seems volume group '%s' already exists:\n"
716 a8083063 Iustin Pop
                      "  LV count: %s, size: %s, free: %s." %
717 a8083063 Iustin Pop
                      (vgname, lv_count, vg_size, vg_free))
718 a8083063 Iustin Pop
719 a8083063 Iustin Pop
720 a8083063 Iustin Pop
  disklist = ValidateDiskList(options)
721 a8083063 Iustin Pop
722 a8083063 Iustin Pop
  for disk in disklist:
723 a8083063 Iustin Pop
    WipeDisk(disk)
724 a8083063 Iustin Pop
    PartitionDisk(disk)
725 a8083063 Iustin Pop
  for disk in disklist:
726 a8083063 Iustin Pop
    CreatePVOnDisk(disk)
727 a8083063 Iustin Pop
  CreateVG(vgname, disklist)
728 a8083063 Iustin Pop
729 f4ad2ef0 Iustin Pop
  status, lv_count, size, _ = CheckVGExists(vgname)
730 a8083063 Iustin Pop
  if status:
731 a8083063 Iustin Pop
    print "Done! %s: size %s GiB, disks: %s" % (vgname, size,
732 f4bc1f2c Michael Hanselmann
                                              ",".join(disklist))
733 a8083063 Iustin Pop
  else:
734 f4bc1f2c Michael Hanselmann
    raise OperationalError("Although everything seemed ok, the volume"
735 f4bc1f2c Michael Hanselmann
                           " group did not get created.")
736 a8083063 Iustin Pop
737 a8083063 Iustin Pop
738 a8083063 Iustin Pop
def main():
739 a8083063 Iustin Pop
  """application entry point.
740 a8083063 Iustin Pop
741 a8083063 Iustin Pop
  This is just a wrapper over BootStrap, to handle our own exceptions.
742 a8083063 Iustin Pop
  """
743 a8083063 Iustin Pop
744 a8083063 Iustin Pop
  try:
745 a8083063 Iustin Pop
    BootStrap()
746 a8083063 Iustin Pop
  except PrereqError, err:
747 a8083063 Iustin Pop
    print >> sys.stderr, "The prerequisites for running this tool are not met."
748 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("Please make sure you followed all the steps in"
749 f4bc1f2c Michael Hanselmann
                          " the build document.")
750 a8083063 Iustin Pop
    print >> sys.stderr, "Description: %s" % str(err)
751 a8083063 Iustin Pop
    sys.exit(1)
752 a8083063 Iustin Pop
  except SysconfigError, err:
753 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("This system's configuration seems wrong, at"
754 f4bc1f2c Michael Hanselmann
                          " least is not what I expect.")
755 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("Please check that the installation didn't fail"
756 f4bc1f2c Michael Hanselmann
                          " at some step.")
757 a8083063 Iustin Pop
    print >> sys.stderr, "Description: %s" % str(err)
758 a8083063 Iustin Pop
    sys.exit(1)
759 a8083063 Iustin Pop
  except ParameterError, err:
760 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("Some parameters you gave to the program or the"
761 f4bc1f2c Michael Hanselmann
                          " invocation is wrong. ")
762 a8083063 Iustin Pop
    print >> sys.stderr, "Description: %s" % str(err)
763 a8083063 Iustin Pop
    Usage()
764 a8083063 Iustin Pop
  except OperationalError, err:
765 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("A serious error has happened while modifying"
766 f4bc1f2c Michael Hanselmann
                          " the system's configuration.")
767 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("Please review the error message below and make"
768 f4bc1f2c Michael Hanselmann
                          " sure you clean up yourself.")
769 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("It is most likely that the system configuration"
770 f4bc1f2c Michael Hanselmann
                          " has been partially altered.")
771 a8083063 Iustin Pop
    print >> sys.stderr, str(err)
772 a8083063 Iustin Pop
    sys.exit(1)
773 a8083063 Iustin Pop
  except ProgrammingError, err:
774 f4bc1f2c Michael Hanselmann
    print >> sys.stderr, ("Internal application error. Please signal this"
775 f4bc1f2c Michael Hanselmann
                          " to xencluster-team.")
776 a8083063 Iustin Pop
    print >> sys.stderr, "Error description: %s" % str(err)
777 a8083063 Iustin Pop
    sys.exit(1)
778 a8083063 Iustin Pop
  except Error, err:
779 a8083063 Iustin Pop
    print >> sys.stderr, "Unhandled application error: %s" % err
780 a8083063 Iustin Pop
    sys.exit(1)
781 a8083063 Iustin Pop
  except (IOError, OSError), err:
782 a8083063 Iustin Pop
    print >> sys.stderr, "I/O error detected, please report."
783 a8083063 Iustin Pop
    print >> sys.stderr, "Description: %s" % str(err)
784 a8083063 Iustin Pop
    sys.exit(1)
785 a8083063 Iustin Pop
786 a8083063 Iustin Pop
787 a8083063 Iustin Pop
if __name__ == "__main__":
788 a8083063 Iustin Pop
  main()