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
RevLine 
[146]1#!/usr/bin/env python
2
3import sys
[1987]4import time
5import os
6import random
7import string
[175]8from subprocess import call, PIPE, Popen
[834]9from invirt.config import structs as config
[146]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.
[175]22    rv = call(["/usr/sbin/xm", "destroy", prefix + machine],
23              stderr=PIPE)
[146]24
[156]25if subcommand == "lvcreate-all":
[837]26    from invirt import database
[156]27    import re
[837]28    database.connect()
[156]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
[146]46if subcommand == "lvremove":
[1066]47    def error():
48        print >>sys.stderr, "Error removing LV %s\n" % lvname
49        sys.exit(1)
[1987]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
[146]64    ensureoff(machine)
[1987]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])
[149]75elif subcommand == "lvresize":
[146]76    size = sys.argv[4]
77    ensureoff(machine)
[175]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
[146]85        sys.exit(1)
[175]86    print >> sys.stderr, err
[149]87elif subcommand == "lvrename":
[146]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)
[149]96elif subcommand == "lvcreate":
[146]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.