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:
committed by
john-griffith
parent
602da5b06b
commit
6b8ba716d2
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user