aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenctl
diff options
context:
space:
mode:
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>2004-06-16 13:30:35 +0000
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>2004-06-16 13:30:35 +0000
commit7b06304aceb9f2ca5f04e28e91fe5f7419f63a18 (patch)
tree4e72497bb3a350d5c490e049d284ae4f0ea1663b /tools/xenctl
parenteb5277a30e0834fcfecac290917a67c17eabb757 (diff)
downloadxen-7b06304aceb9f2ca5f04e28e91fe5f7419f63a18.tar.gz
xen-7b06304aceb9f2ca5f04e28e91fe5f7419f63a18.tar.bz2
xen-7b06304aceb9f2ca5f04e28e91fe5f7419f63a18.zip
bitkeeper revision 1.959.1.5 (40d04b7b7MkMcLlaSNJov9qsPAZ9tg)
Remove vdisk code.
Diffstat (limited to 'tools/xenctl')
-rw-r--r--tools/xenctl/lib/vdisk.py944
-rw-r--r--tools/xenctl/setup.py2
2 files changed, 1 insertions, 945 deletions
diff --git a/tools/xenctl/lib/vdisk.py b/tools/xenctl/lib/vdisk.py
deleted file mode 100644
index 6c4d144f9f..0000000000
--- a/tools/xenctl/lib/vdisk.py
+++ /dev/null
@@ -1,944 +0,0 @@
-import os
-import re
-import socket
-import string
-import sys
-import tempfile
-import struct
-
-##### Module variables
-
-"""Location of the Virtual Disk management database.
- defaults to /var/db/xen_vdisks.sqlite
-"""
-VD_DB_FILE = "/var/db/xen_vdisks.sqlite"
-
-"""VBD expertise level - determines the strictness of the sanity checking.
- This mode determines the level of complaints when disk sharing occurs
- through the current VBD mappings.
- 0 - only allow shared mappings if both domains have r/o access (always OK)
- 1 - also allow sharing with one dom r/w and the other r/o
- 2 - allow sharing with both doms r/w
-"""
-VBD_SAFETY_RR = 0
-VBD_SAFETY_RW = 1
-VBD_SAFETY_WW = 2
-
-VBD_SECTORS_PER_MB = 2048
-
-##### Module initialisation
-
-try:
- # try to import sqlite (not everyone will have it installed)
- import sqlite
-except ImportError:
- # on failure, just catch the error, don't do anything
- pass
-
-
-
-##### VBD-related Functions
-
-def blkdev_name_to_number(name):
- """Take the given textual block-device name (e.g., '/dev/sda1',
- 'hda') and return the device number used by the OS. """
-
- if not re.match( '/dev/', name ):
- name = '/dev/' + name
-
- return os.stat(name).st_rdev
-
-# lookup_blkdev_partn_info( '/dev/sda3' )
-def lookup_raw_partn(partition):
- """Take the given block-device name (e.g., '/dev/sda1', 'hda')
- and return a dictionary { device, start_sector,
- nr_sectors, type }
- device: Device number of the given partition
- start_sector: Index of first sector of the partition
- nr_sectors: Number of sectors comprising this partition
- type: 'Disk' or identifying name for partition type
- """
-
- if not re.match( '/dev/', partition ):
- partition = '/dev/' + partition
-
- drive = re.split( '[0-9]', partition )[0]
-
- if drive == partition:
- fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
- line = readline(fd)
- if line:
- return [ { 'device' : blkdev_name_to_number(drive),
- 'start_sector' : long(0),
- 'nr_sectors' : long(line) * 2,
- 'type' : 'Disk' } ]
- return None
-
- # determine position on disk
- fd = os.popen( '/sbin/sfdisk -d ' + drive + ' 2>/dev/null' )
-
- #['/dev/sda3 : start= 16948575, size=16836120, Id=83, bootable\012']
- lines = readlines(fd)
- for line in lines:
- m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' +
- 'size=\s*([0-9]+), Id=\s*(\S+).*$', line)
- if m:
- return [ { 'device' : blkdev_name_to_number(drive),
- 'start_sector' : long(m.group(1)),
- 'nr_sectors' : long(m.group(2)),
- 'type' : m.group(3) } ]
-
- return None
-
-def lookup_disk_uname( uname ):
- """Lookup a list of segments for either a physical or a virtual device.
- uname [string]: name of the device in the format \'vd:id\' for a virtual
- disk, or \'phy:dev\' for a physical device
- returns [list of dicts]: list of extents that make up the named device
- """
- ( type, d_name ) = string.split( uname, ':' )
-
- if type == "phy":
- segments = lookup_raw_partn( d_name )
- elif type == "vd":
- segments = vd_lookup( d_name )
-
- return segments
-
-
-##### VD Management-related functions
-
-##### By Mark Williamson, <mark.a.williamson@intel.com>
-##### (C) Intel Research Cambridge
-
-# TODO:
-#
-# Plenty of room for enhancement to this functionality (contributions
-# welcome - and then you get to have your name in the source ;-)...
-#
-# vd_unformat() : want facilities to unallocate virtual disk
-# partitions, possibly migrating virtual disks of them, with checks to see if
-# it's safe and options to force it anyway
-#
-# vd_create() : should have an optional argument specifying a physical
-# disk preference - useful to allocate for guest doms to do RAID
-#
-# vd_undelete() : add ability to "best effort" undelete as much of a
-# vdisk as is left in the case that some of it has already been
-# reallocated. Some people might still be able to recover some of
-# their data this way, even if some of the disk has disappeared.
-#
-# It'd be nice if we could wipe virtual disks for security purposes -
-# should be easy to do this using dev if=/dev/{zero,random} on each
-# extent in turn. There could be another optional flag to vd_create
-# in order to allow this.
-#
-# Error codes could be more expressive - i.e. actually tell why the
-# error occurred rather than "it broke". Currently the code avoids
-# using exceptions to make control scripting simpler and more
-# accessible to beginners - therefore probably should just use more
-# return codes.
-#
-# Enhancements / additions to the example scripts are also welcome:
-# some people will interact with this code mostly through those
-# scripts.
-#
-# More documentation of how this stuff should be used is always nice -
-# if you have a novel configuration that you feel isn't discussed
-# enough in the HOWTO (which is currently a work in progress), feel
-# free to contribute a walkthrough, or something more substantial.
-#
-
-
-def __vd_no_database():
- """Called when no database found - exits with an error
- """
- print >> sys.stderr, "ERROR: Could not locate the database file at " + VD_DB_FILE
- sys.exit(1)
-
-def readlines(fd):
- """Version of readlines safe against EINTR.
- """
- import errno
-
- lines = []
- while 1:
- try:
- line = fd.readline()
- except IOError, ex:
- if ex.errno == errno.EINTR:
- continue
- else:
- raise
- if line == '': break
- lines.append(line)
- return lines
-
-def readline(fd):
- """Version of readline safe against EINTR.
- """
- while 1:
- try:
- return fd.readline()
- except IOError, ex:
- if ex.errno == errno.EINTR:
- continue
- else:
- raise
-
-
-def vd_format(partition, extent_size_mb):
- """Format a partition or drive for use a virtual disk storage.
- partition [string]: device file representing the partition
- extent_size_mb [string]: extent size in megabytes to use on this disk
- """
-
- if not os.path.isfile(VD_DB_FILE):
- vd_init_db(VD_DB_FILE)
-
- if not re.match( '/dev/', partition ):
- partition = '/dev/' + partition
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("select * from vdisk_part where partition = \'"
- + partition + "\'")
- row = cu.fetchone()
-
- extent_size = extent_size_mb * VBD_SECTORS_PER_MB # convert megabytes to sectors
-
- if not row:
- part_info = lookup_raw_partn(partition)[0]
-
- cu.execute("INSERT INTO vdisk_part(partition, part_id, extent_size) " +
- "VALUES ( \'" + partition + "\', "
- + str(blkdev_name_to_number(partition))
- + ", " + str(extent_size) + ")")
-
-
- cu.execute("SELECT max(vdisk_extent_no) FROM vdisk_extents "
- + "WHERE vdisk_id = 0")
-
- max_id, = cu.fetchone()
-
- if max_id != None:
- new_id = max_id + 1
- else:
- new_id = 0
-
- num_extents = part_info['nr_sectors'] / extent_size
-
- for i in range(num_extents):
- sql ="""INSERT INTO vdisk_extents(vdisk_extent_no, vdisk_id,
- part_id, part_extent_no)
- VALUES ("""+ str(new_id + i) + ", 0, "\
- + str(blkdev_name_to_number(partition))\
- + ", " + str(num_extents - (i + 1)) + ")"
- cu.execute(sql)
-
- cx.commit()
- cx.close()
- return 0
-
-
-def vd_create(size_mb, expiry):
- """Create a new virtual disk.
- size_mb [int]: size in megabytes for the new virtual disk
- expiry [int]: expiry time in seconds from now
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- size = size_mb * VBD_SECTORS_PER_MB
-
- cu.execute("SELECT max(vdisk_id) FROM vdisks")
- max_id, = cu.fetchone()
- new_id = int(max_id) + 1
-
- # fetch a list of extents from the expired disks, along with information
- # about their size
- cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
- vdisk_extents.part_id, extent_size
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
- WHERE expires AND expiry_time <= datetime('now')
- ORDER BY expiry_time ASC, vdisk_extent_no DESC
- """) # aims to reuse the last extents
- # from the longest-expired disks first
-
- allocated = 0
-
- if expiry:
- expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
- expires = 1
- else:
- expiry_ts = "NULL"
- expires = 0
-
- # we'll use this to build the SQL statement we want
- building_sql = "INSERT INTO vdisks(vdisk_id, size, expires, expiry_time)" \
- +" VALUES ("+str(new_id)+", "+str(size)+ ", " \
- + str(expires) + ", " + expiry_ts + "); "
-
- counter = 0
-
- while allocated < size:
- row = cu.fetchone()
- if not row:
- print "ran out of space, having allocated %d meg of %d" % (allocated, size)
- cx.close()
- return -1
-
-
- (vdisk_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
- allocated += extent_size
- building_sql += "UPDATE vdisk_extents SET vdisk_id = " + str(new_id) \
- + ", " + "vdisk_extent_no = " + str(counter) \
- + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
- + " AND vdisk_id = " + str(vdisk_id) + "; "
-
- counter += 1
-
-
- # this will execute the SQL query we build to store details of the new
- # virtual disk and allocate space to it print building_sql
- cu.execute(building_sql)
-
- cx.commit()
- cx.close()
- return str(new_id)
-
-
-def vd_lookup(id):
- """Lookup a Virtual Disk by ID.
- id [string]: a virtual disk identifier
- Returns [list of dicts]: a list of extents as dicts, containing fields:
- device : Linux device number of host disk
- start_sector : within the device
- nr_sectors : size of this extent
- type : set to \'VD Extent\'
-
- part_device : Linux device no of host partition
- part_start_sector : within the partition
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("-- types int")
- cu.execute("""SELECT COUNT(*)
- FROM vdisks
- WHERE (expiry_time > datetime('now') OR NOT expires)
- AND vdisk_id = """ + id)
- count, = cu.fetchone()
-
- if not count:
- cx.close()
- return None
-
- cu.execute("SELECT size from vdisks WHERE vdisk_id = " + id)
- real_size, = cu.fetchone()
-
- # This query tells PySQLite how to convert the data returned from the
- # following query - the use of the multiplication confuses it otherwise ;-)
- # This row is significant to PySQLite but is syntactically an SQL comment.
-
- cu.execute("-- types str, int, int, int")
-
- # This SQL statement is designed so that when the results are fetched they
- # will be in the right format to return immediately.
- cu.execute("""SELECT partition, vdisk_part.part_id,
- round(part_extent_no * extent_size) as start,
- extent_size
-
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
-
- WHERE vdisk_extents.vdisk_id = """ + id
- + " ORDER BY vdisk_extents.vdisk_extent_no ASC"
- )
-
- extent_tuples = cu.fetchall()
-
- # use this function to map the results from the database into a dict
- # list of extents, for consistency with the rest of the code
- def transform ((partition, part_device, part_offset, nr_sectors)):
- return {
- # the disk device this extent is on - for passing to Xen
- 'device' : lookup_raw_partn(partition)[0]['device'],
- # the offset of this extent within the disk - for passing to Xen
- 'start_sector' : long(part_offset + lookup_raw_partn(partition)[0]['start_sector']),
- # extent size, in sectors
- 'nr_sectors' : nr_sectors,
- # partition device this extent is on (useful to know for xenctl.utils fns)
- 'part_device' : part_device,
- # start sector within this partition (useful to know for xenctl.utils fns)
- 'part_start_sector' : part_offset,
- # type of this extent - handy to know
- 'type' : 'VD Extent' }
-
- cx.commit()
- cx.close()
-
- extent_dicts = map(transform, extent_tuples)
-
- # calculate the over-allocation in sectors (happens because
- # we allocate whole extents)
- allocated_size = 0
- for i in extent_dicts:
- allocated_size += i['nr_sectors']
-
- over_allocation = allocated_size - real_size
-
- # trim down the last extent's length so the resulting VBD will be the
- # size requested, rather than being rounded up to the nearest extent
- extent_dicts[len(extent_dicts) - 1]['nr_sectors'] -= over_allocation
-
- return extent_dicts
-
-
-def vd_enlarge(vdisk_id, extra_size_mb):
- """Create a new virtual disk.
- vdisk_id [string] : ID of the virtual disk to enlarge
- extra_size_mb [int]: size in megabytes to increase the allocation by
- returns [int] : 0 on success, otherwise non-zero
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- extra_size = extra_size_mb * VBD_SECTORS_PER_MB
-
- cu.execute("-- types int")
- cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id
- + " AND (expiry_time > datetime('now') OR NOT expires)")
- count, = cu.fetchone()
-
- if not count: # no such vdisk
- cx.close()
- return -1
-
- cu.execute("-- types int")
- cu.execute("""SELECT SUM(extent_size)
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
- WHERE vdisks.vdisk_id = """ + vdisk_id)
-
- real_size, = cu.fetchone() # get the true allocated size
-
- cu.execute("-- types int")
- cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
-
- old_size, = cu.fetchone()
-
-
- cu.execute("--- types int")
- cu.execute("""SELECT MAX(vdisk_extent_no)
- FROM vdisk_extents
- WHERE vdisk_id = """ + vdisk_id)
-
- counter = cu.fetchone()[0] + 1 # this stores the extent numbers
-
-
- # because of the extent-based allocation, the VD may already have more
- # allocated space than they asked for. Find out how much we really
- # need to add.
- add_size = extra_size + old_size - real_size
-
- # fetch a list of extents from the expired disks, along with information
- # about their size
- cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
- vdisk_extents.part_id, extent_size
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
- WHERE expires AND expiry_time <= datetime('now')
- ORDER BY expiry_time ASC, vdisk_extent_no DESC
- """) # aims to reuse the last extents
- # from the longest-expired disks first
-
- allocated = 0
-
- building_sql = "UPDATE vdisks SET size = " + str(old_size + extra_size)\
- + " WHERE vdisk_id = " + vdisk_id + "; "
-
- while allocated < add_size:
- row = cu.fetchone()
- if not row:
- cx.close()
- return -1
-
- (dead_vd_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
- allocated += extent_size
- building_sql += "UPDATE vdisk_extents SET vdisk_id = " + vdisk_id \
- + ", " + "vdisk_extent_no = " + str(counter) \
- + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
- + " AND vdisk_id = " + str(dead_vd_id) + "; "
-
- counter += 1
-
-
- # this will execute the SQL query we build to store details of the new
- # virtual disk and allocate space to it print building_sql
- cu.execute(building_sql)
-
- cx.commit()
- cx.close()
- return 0
-
-
-def vd_undelete(vdisk_id, expiry_time):
- """Create a new virtual disk.
- vdisk_id [int]: size in megabytes for the new virtual disk
- expiry_time [int]: expiry time, in seconds from now
- returns [int]: zero on success, non-zero on failure
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- if vdisk_id == '0': # undeleting vdisk 0 isn't sane!
- return -1
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("-- types int")
- cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id)
- count, = cu.fetchone()
-
- if not count:
- cx.close()
- return -1
-
- cu.execute("-- types int")
- cu.execute("""SELECT SUM(extent_size)
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
- WHERE vdisks.vdisk_id = """ + vdisk_id)
-
- real_size, = cu.fetchone() # get the true allocated size
-
-
- cu.execute("-- types int")
- cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
-
- old_size, = cu.fetchone()
-
- if real_size < old_size:
- cx.close()
- return -1
-
- if expiry_time == 0:
- expires = '0'
- else:
- expires = '1'
-
- # this will execute the SQL query we build to store details of the new
- # virtual disk and allocate space to it print building_sql
- cu.execute("UPDATE vdisks SET expiry_time = datetime('now','"
- + str(expiry_time) + " seconds'), expires = " + expires
- + " WHERE vdisk_id = " + vdisk_id)
-
- cx.commit()
- cx.close()
- return 0
-
-
-
-
-def vd_list():
- """Lists all the virtual disks registered in the system.
- returns [list of dicts]
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("""SELECT vdisk_id, size, expires, expiry_time
- FROM vdisks
- WHERE (NOT expires) OR expiry_time > datetime('now')
- """)
-
- ret = cu.fetchall()
-
- cx.close()
-
- def makedicts((vdisk_id, size, expires, expiry_time)):
- return { 'vdisk_id' : str(vdisk_id), 'size': size,
- 'expires' : expires, 'expiry_time' : expiry_time }
-
- return map(makedicts, ret)
-
-
-def vd_refresh(id, expiry):
- """Change the expiry time of a virtual disk.
- id [string] : a virtual disk identifier
- expiry [int] : expiry time in seconds from now (0 = never expire)
- returns [int]: zero on success, non-zero on failure
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("-- types int")
- cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
- + " AND (expiry_time > datetime('now') OR NOT expires)")
- count, = cu.fetchone()
-
- if not count:
- cx.close()
- return -1
-
- if expiry:
- expires = 1
- expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
- else:
- expires = 0
- expiry_ts = "NULL"
-
- cu.execute("UPDATE vdisks SET expires = " + str(expires)
- + ", expiry_time = " + expiry_ts
- + " WHERE (expiry_time > datetime('now') OR NOT expires)"
- + " AND vdisk_id = " + id)
-
- cx.commit()
- cx.close()
-
- return 0
-
-
-def vd_delete(id):
- """Deletes a Virtual Disk, making its extents available for future VDs.
- id [string] : identifier for the virtual disk to delete
- returns [int] : 0 on success, -1 on failure (VD not found
- or already deleted)
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("-- types int")
- cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
- + " AND (expiry_time > datetime('now') OR NOT expires)")
- count, = cu.fetchone()
-
- if not count:
- cx.close()
- return -1
-
- cu.execute("UPDATE vdisks SET expires = 1, expiry_time = datetime('now')"
- + " WHERE vdisk_id = " + id)
-
- cx.commit()
- cx.close()
-
- return 0
-
-
-def vd_freespace():
- """Returns the amount of free space available for new virtual disks, in MB
- returns [int] : free space for VDs in MB
- """
-
- if not os.path.isfile(VD_DB_FILE):
- __vd_no_database()
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("-- types int")
-
- cu.execute("""SELECT SUM(extent_size)
- FROM vdisks NATURAL JOIN vdisk_extents
- NATURAL JOIN vdisk_part
- WHERE expiry_time <= datetime('now') AND expires""")
-
- sum, = cu.fetchone()
-
- cx.close()
-
- return sum / VBD_SECTORS_PER_MB
-
-
-def vd_init_db(path):
- """Initialise the VD SQLite database
- path [string]: path to the SQLite database file
- """
-
- cx = sqlite.connect(path)
- cu = cx.cursor()
-
- cu.execute(
- """CREATE TABLE vdisk_extents
- ( vdisk_extent_no INT,
- vdisk_id INT,
- part_id INT,
- part_extent_no INT )
- """)
-
- cu.execute(
- """CREATE TABLE vdisk_part
- ( part_id INT,
- partition VARCHAR,
- extent_size INT )
- """)
-
- cu.execute(
- """CREATE TABLE vdisks
- ( vdisk_id INT,
- size INT,
- expires BOOLEAN,
- expiry_time TIMESTAMP )
- """)
-
-
- cu.execute(
- """INSERT INTO vdisks ( vdisk_id, size, expires, expiry_time )
- VALUES ( 0, 0, 1, datetime('now') )
- """)
-
- cx.commit()
- cx.close()
-
- VD_DB_FILE = path
-
-
-
-def vd_cp_to_file(vdisk_id,filename):
- """Writes the contents of a specified vdisk out into a disk file, leaving
- the original copy in the virtual disk pool."""
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- extents = vd_lookup(vdisk_id)
-
- if not extents:
- return -1
-
- file_idx = 0 # index into source file, in sectors
-
- for i in extents:
- cu.execute("""SELECT partition, extent_size FROM vdisk_part
- WHERE part_id = """ + str(i['part_device']))
-
- (partition, extent_size) = cu.fetchone()
-
- os.system("dd bs=1b if=" + partition + " of=" + filename
- + " skip=" + str(i['part_start_sector'])
- + " seek=" + str(file_idx)
- + " count=" + str(i['nr_sectors'])
- + " > /dev/null")
-
- file_idx += i['nr_sectors']
-
- cx.close()
-
- return 0 # should return -1 if something breaks
-
-
-def vd_mv_to_file(vdisk_id,filename):
- """Writes a vdisk out into a disk file and frees the space originally
- taken within the virtual disk pool.
- vdisk_id [string]: ID of the vdisk to write out
- filename [string]: file to write vdisk contents out to
- returns [int]: zero on success, nonzero on failure
- """
-
- if vd_cp_to_file(vdisk_id,filename):
- return -1
-
- if vd_delete(vdisk_id):
- return -1
-
- return 0
-
-
-def vd_read_from_file(filename,expiry):
- """Reads the contents of a file directly into a vdisk, which is
- automatically allocated to fit.
- filename [string]: file to read disk contents from
- returns [string] : vdisk ID for the destination vdisk
- """
-
- size_bytes = os.stat(filename).st_size
-
- (size_mb,leftover) = divmod(size_bytes,1048580) # size in megabytes
- if leftover > 0: size_mb += 1 # round up if not an exact number of MB
-
- vdisk_id = vd_create(size_mb, expiry)
-
- if vdisk_id < 0:
- return -1
-
- cx = sqlite.connect(VD_DB_FILE)
- cu = cx.cursor()
-
- cu.execute("""SELECT partition, extent_size, part_extent_no
- FROM vdisk_part NATURAL JOIN vdisk_extents
- WHERE vdisk_id = """ + vdisk_id + """
- ORDER BY vdisk_extent_no ASC""")
-
- extents = cu.fetchall()
-
- size_sectors = size_mb * VBD_SECTORS_PER_MB # for feeding to dd
-
- file_idx = 0 # index into source file, in sectors
-
- def write_extent_to_vd((partition, extent_size, part_extent_no),
- file_idx, filename):
- """Write an extent out to disk and update file_idx"""
-
- os.system("dd bs=512 if=" + filename + " of=" + partition
- + " skip=" + str(file_idx)
- + " seek=" + str(part_extent_no * extent_size)
- + " count=" + str(min(extent_size, size_sectors - file_idx))
- + " > /dev/null")
-
- return extent_size
-
- for i in extents:
- file_idx += write_extent_to_vd(i, file_idx, filename)
-
- cx.close()
-
- return vdisk_id
-
-
-
-
-def vd_extents_validate(new_extents, new_writeable, safety=VBD_SAFETY_RR):
- """Validate the extents against the existing extents.
- Complains if the list supplied clashes against the extents that
- are already in use in the system.
- new_extents [list of dicts]: list of new extents, as dicts
- new_writeable [int]: 1 if they are to be writeable, 0 otherwise
- returns [int]: either the expertise level of the mapping if it doesn't
- exceed VBD_EXPERT_MODE or -1 if it does (error)
- """
-
- import Xc # this is only needed in this function
-
- xc = Xc.new()
-
- ##### Probe for explicitly created virtual disks and build a list
- ##### of extents for comparison with the ones that are being added
-
- probe = xc.vbd_probe()
-
- old_extents = [] # this will hold a list of all existing extents and
- # their writeable status, as a list of (device,
- # start, size, writeable?) tuples
-
- for vbd in probe:
- this_vbd_extents = xc.vbd_getextents(vbd['dom'],vbd['vbd'])
- for vbd_ext in this_vbd_extents:
- vbd_ext['writeable'] = vbd['writeable']
- old_extents.append(vbd_ext)
-
- ##### Now scan /proc/mounts for compile a list of extents corresponding to
- ##### any devices mounted in DOM0. This list is added on to old_extents
-
- regexp = re.compile("/dev/(\S*) \S* \S* (..).*")
- fd = open('/proc/mounts', "r")
-
- while True:
- line = readline(fd)
- if not line: # if we've run out of lines then stop reading
- break
-
- m = regexp.match(line)
-
- # if the regexp didn't match then it's probably a line we don't
- # care about - skip to next line
- if not m:
- continue
-
- # lookup the device
- ext_list = lookup_raw_partn(m.group(1))
-
- # if lookup failed, skip to next mounted device
- if not ext_list:
- continue
-
- # set a writeable flag as appropriate
- for ext in ext_list:
- ext['writeable'] = m.group(2) == 'rw'
-
- # now we've got here, the contents of ext_list are in a
- # suitable format to be added onto the old_extents list, ready
- # for checking against the new extents
-
- old_extents.extend(ext_list)
-
- fd.close() # close /proc/mounts
-
- ##### By this point, old_extents contains a list of extents, in
- ##### dictionary format corresponding to every extent of physical
- ##### disk that's either part of an explicitly created VBD, or is
- ##### mounted under DOM0. We now check these extents against the
- ##### proposed additions in new_extents, to see if a conflict will
- ##### happen if they are added with write status new_writeable
-
- level = 0 # this'll accumulate the max warning level
-
- # Search for clashes between the new extents and the old ones
- # Takes time O(len(new_extents) * len(old_extents))
- for new_ext in new_extents:
- for old_ext in old_extents:
- if(new_ext['device'] == old_ext['device']):
-
- new_ext_start = new_ext['start_sector']
- new_ext_end = new_ext_start + new_ext['nr_sectors'] - 1
-
- old_ext_start = old_ext['start_sector']
- old_ext_end = old_ext_start + old_ext['nr_sectors'] - 1
-
- if((old_ext_start <= new_ext_start <= old_ext_end) or
- (old_ext_start <= new_ext_end <= old_ext_end)):
- if (not old_ext['writeable']) and new_writeable:
- level = max(1,level)
- elif old_ext['writeable'] and (not new_writeable):
- level = max(1,level)
- elif old_ext['writeable'] and new_writeable:
- level = max(2,level)
-
-
- ##### level now holds the warning level incurred by the current
- ##### VBD setup and we complain appropriately to the user
-
-
- if level == 1:
- print >> sys.stderr, """Warning: one or more hard disk extents
- writeable by one domain are also readable by another."""
- elif level == 2:
- print >> sys.stderr, """Warning: one or more hard disk extents are
- writeable by two or more domains simultaneously."""
-
- if level > safety:
- print >> sys.stderr, """ERROR: This kind of disk sharing is not allowed
- at the current safety level (%d).""" % safety
- level = -1
-
- return level
-
diff --git a/tools/xenctl/setup.py b/tools/xenctl/setup.py
index 1d67a843ef..03f3f1e25c 100644
--- a/tools/xenctl/setup.py
+++ b/tools/xenctl/setup.py
@@ -2,7 +2,7 @@
from distutils.core import setup, Extension
import sys
-modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' , 'xenctl.vdisk' ]
+modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' ]
# We need the 'tempfile' module from Python 2.3. We install this ourselves
# if the installed Python is older than 2.3.