source: trunk/packages/invirt-remote/host/usr/sbin/invirt-lvm @ 1987

Last change on this file since 1987 was 1987, checked in by broder, 15 years ago

Overwrite all content of a VM's LV before deleting it.

  • Property svn:executable set to *
File size: 3.4 KB
Line 
1#!/usr/bin/env python
2
3import sys
4import time
5import os
6import random
7import string
8from subprocess import call, PIPE, Popen
9from invirt.config import structs as config
10
11def check(b):
12    if not b:
13        exit(1)
14
15vg = "xenvg"
16prefix = "d_"
17
18subcommand = sys.argv[1]
19
20def ensureoff(machine):
21    # Make sure the machine is off, but we don't care about errors if it is already off.
22    rv = call(["/usr/sbin/xm", "destroy", prefix + machine],
23              stderr=PIPE)
24
25if subcommand == "lvcreate-all":
26    from invirt import database
27    import re
28    database.connect()
29    for d in Disk.select():
30        check(re.match('^[A-Za-z0-9]+$', d.guest_device_name))
31        machine = Machine.get(d.machine_id)
32        check(re.match('^[A-Za-z0-9][A-Za-z0-9._-]*$', machine.name))
33        lvname = prefix + machine.name + "_" + d.guest_device_name
34        if not os.path.exists("/dev/%s/%s" % (vg, lvname)):
35            # LV doesn't exist
36            print >>sys.stderr, "Creating LV %s..." % (lvname,)
37            rv = call(["/sbin/lvcreate", "-L", str(d.size) + "M", "-n", lvname, vg])
38            if rv != 0:
39                print >>sys.stderr, "Error creating LV %s\n" %(lvname,)
40                sys.exit(1)
41else:
42    machine = sys.argv[2]
43    disk = sys.argv[3]
44    lvname = prefix + machine + "_" + disk
45    lvpath = "/dev/" + vg + "/" + lvname
46if subcommand == "lvremove":
47    def error():
48        print >>sys.stderr, "Error removing LV %s\n" % lvname
49        sys.exit(1)
50   
51    # Rename the LV to something else so we can wipe it before reusing
52    # the space
53    while True:
54        new_lvname = "old_%s_%s" % (lvname, ''.join(random.choice(string.ascii_letters) for i in xrange(6)))
55        new_lvpath = "/dev/%s/%s" % (vg, new_lvname)
56        p = Popen(["/sbin/lvrename", lvpath, new_lvpath], stdout=PIPE, stderr=PIPE)
57        rv = p.wait()
58        if rv == 5 and 'already exists in volume group' in p.stderr.read():
59            continue
60        elif rv != 0:
61            error()
62        else:
63            break
64    ensureoff(machine)
65   
66    # Fork. The child process wipes the LV and then deletes
67    # it. There's not really anything sane to do with errors (since
68    # this is running non-interactively), so let's just drop them on
69    # the floor for now.
70    if os.fork() == 0:
71        call(["/bin/dd", "if=/dev/zero", "of=%s" % new_lvpath])
72        call(["/sbin/lvchange", "-a", "n", new_lvpath])
73        call(["/sbin/lvchange", "-a", "ey", new_lvpath])
74        call(["/sbin/lvremove", "--force", new_lvpath])
75elif subcommand == "lvresize":
76    size = sys.argv[4]
77    ensureoff(machine)
78    p = Popen(["/sbin/lvresize", "-L", size + "M", lvpath],
79              stdin=PIPE, stderr=PIPE)
80    print >> p.stdin, 'y'
81    err = p.stderr.read()
82    if p.wait() != 0 and 'matches existing size' not in err:
83        print >> sys.stderr, "Error resizing LV %s:\n" %(lvname,)
84        print >> sys.stderr, err
85        sys.exit(1)
86    print >> sys.stderr, err
87elif subcommand == "lvrename":
88    newmachine = sys.argv[4]
89    newlvname = prefix + newmachine + "_" + disk
90    ensureoff(machine)
91    ensureoff(newmachine)   
92    rv = call(["/sbin/lvrename", vg, lvname, newlvname])
93    if rv != 0:
94        print >>sys.stderr, "Error renaming LV %s\n" %(lvname,)
95        sys.exit(1)
96elif subcommand == "lvcreate":
97    size = sys.argv[4]
98    rv = call(["/sbin/lvcreate", "-L", size + "M", "-n", lvname, vg])
99    if rv != 0:
100        print >>sys.stderr, "Error creating LV %s\n" %(lvname,)
101        sys.exit(1)
102
Note: See TracBrowser for help on using the repository browser.