Implement LVM thin provisioning support.

As of LVM2 version 2.02.89 the ability to do thin provisioning
was made available in LVM, this provides some cool new features
but also addresses some problems with things like terrible
LVM snapshot performance.

Currently the version of LVM in Ubuntu 12.04 does NOT support LVM thin,
however an experimental PPA from brightbox which is a backport from
Quantal has been proposed to Cannonical to be pulled in.  For some
users the experimental PPA is a better option than dealing with some of
the current issues in the standard LVM2 version of Precise (including
the dd hangs on secure delete). See BP for more info.

This change will create the thin pool if it doesn't exist
using pool_size flag, or by default using entire VG space.

Implements BP: implement-lvm-thin-provisioning

Change-Id: I8a30a1283e1992c64e8ac96841ae4a6f82f7018a
This commit is contained in:
John Griffith
2013-01-11 14:38:23 -07:00
committed by john-griffith
parent 602da5b06b
commit 6b8ba716d2
3 changed files with 75 additions and 0 deletions

View File

@@ -46,6 +46,10 @@ volume_opts = [
cfg.IntOpt('volume_clear_size',
default=0,
help='Size in MiB to wipe at start of old volumes. 0 => all'),
cfg.StrOpt('pool_size',
default=None,
help='Size of thin provisioning pool '
'(None uses entire cinder VG)'),
cfg.IntOpt('lvm_mirrors',
default=0,
help='If set, create lvms with multiple mirrors. Note that '
@@ -492,3 +496,65 @@ class LVMISCSIDriver(LVMVolumeDriver, driver.ISCSIDriver):
def _iscsi_authentication(self, chap, name, password):
return "%s %s %s" % (chap, name, password)
class ThinLVMVolumeDriver(LVMISCSIDriver):
"""Subclass for thin provisioned LVM's."""
def __init__(self, *args, **kwargs):
super(ThinLVMVolumeDriver, self).__init__(*args, **kwargs)
def check_for_setup_error(self):
"""Returns an error if prerequisites aren't met"""
out, err = self._execute('lvs', '--option',
'name', '--noheadings',
run_as_root=True)
pool_name = "%s-pool" % FLAGS.volume_group
if pool_name not in out:
if not FLAGS.pool_size:
out, err = self._execute('vgs', FLAGS.volume_group,
'--noheadings', '--options',
'name,size', run_as_root=True)
size = re.sub(r'[\.][\d][\d]', '', out.split()[1])
else:
size = "%s" % FLAGS.pool_size
pool_path = '%s/%s' % (FLAGS.volume_group, pool_name)
out, err = self._execute('lvcreate', '-T', '-L', size,
pool_path, run_as_root=True)
def _do_lvm_snapshot(self, src_lvm_name, dest_vref, is_cinder_snap=True):
if is_cinder_snap:
new_name = self._escape_snapshot(dest_vref['name'])
else:
new_name = dest_vref['name']
self._try_execute('lvcreate', '-s', '-n', new_name,
src_lvm_name, run_as_root=True)
def create_volume(self, volume):
"""Creates a logical volume. Can optionally return a Dictionary of
changes to the volume object to be persisted."""
sizestr = self._sizestr(volume['size'])
vg_name = ("%s/%s-pool" % (FLAGS.volume_group, FLAGS.volume_group))
self._try_execute('lvcreate', '-T', '-V', sizestr, '-n',
volume['name'], vg_name, run_as_root=True)
def delete_volume(self, volume):
"""Deletes a logical volume."""
if self._volume_not_present(volume['name']):
return True
self._try_execute('lvremove', '-f', "%s/%s" %
(FLAGS.volume_group,
self._escape_snapshot(volume['name'])),
run_as_root=True)
def create_cloned_volume(self, volume, src_vref):
"""Creates a clone of the specified volume."""
LOG.info(_('Creating clone of volume: %s') % src_vref['id'])
orig_lv_name = "%s/%s" % (FLAGS.volume_group, src_vref['name'])
self._do_lvm_snapshot(orig_lv_name, volume, False)
def create_snapshot(self, snapshot):
"""Creates a snapshot of a volume."""
orig_lv_name = "%s/%s" % (FLAGS.volume_group, snapshot['volume_name'])
self._do_lvm_snapshot(orig_lv_name, snapshot)

View File

@@ -618,6 +618,9 @@
# Options defined in cinder.scheduler.host_manager
#
# num_shell_tries=3
#### (IntOpt) number of times to attempt to run flakey shell commands
# Which filter class names to use for filtering hosts when not
# specified in the request. (list value)
#scheduler_default_filters=AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter
@@ -723,6 +726,11 @@
# value)
#lvm_mirrors=0
# pool_size=None
### (strOpt) Size of thin pool to create including suffix (5G),
### default is None and uses full size of VG###
#
# Options defined in cinder.volume.drivers.netapp

View File

@@ -49,3 +49,4 @@ df: CommandFilter, /bin/df, root
truncate: CommandFilter, /usr/bin/truncate, root
chmod: CommandFilter, /bin/chmod, root
rm: CommandFilter, /bin/rm, root
lvs: CommandFilter, /sbin/lvs, root