support a configurable volume wiping method
Add a clear_volume() method that is called from delete_method(). This is only implemented at present for the base LVM driver. This new clear_volume() method now supports these config vars: volume_clear = none, zero, shred volume_clear_size = size_in_MiB 'zero' is the default method and unchanged from previously. 'none' is used if security isn't a concern, or there is independent volume scrubbing. 'shred' is for more security conscious situations where an overwrite count is required. Currently this defaults to 3 passes. size_in_MiB can be used to limit the cleared area to the first part of the volume, which can greatly speed up the operation, and can be useful with encrypted volumes for example where overwritting the encryption keys at the start is sufficient. Fixes bug: 1022511 Change-Id: I7312678ff5d66156578501483a1b74e2a69e19a0
This commit is contained in:
parent
7905b6b233
commit
bb06ebd0f6
|
@ -229,9 +229,6 @@ global_opts = [
|
|||
'and deprecated.'),
|
||||
cfg.StrOpt('control_exchange',
|
||||
default='cinder',
|
||||
help='AMQP exchange to connect to if using RabbitMQ or Qpid'),
|
||||
cfg.BoolOpt('secure_delete',
|
||||
default=True,
|
||||
help='Whether to perform secure delete'), ]
|
||||
help='AMQP exchange to connect to if using RabbitMQ or Qpid'), ]
|
||||
|
||||
FLAGS.register_opts(global_opts)
|
||||
|
|
|
@ -56,8 +56,12 @@ class LoggingVolumeDriver(driver.VolumeDriver):
|
|||
self.log_action('create_volume', volume)
|
||||
|
||||
def delete_volume(self, volume):
|
||||
self.clear_volume(volume)
|
||||
self.log_action('delete_volume', volume)
|
||||
|
||||
def clear_volume(self, volume):
|
||||
self.log_action('clear_volume', volume)
|
||||
|
||||
def local_path(self, volume):
|
||||
print "local_path not implemented"
|
||||
raise NotImplementedError()
|
||||
|
|
|
@ -39,6 +39,13 @@ volume_opts = [
|
|||
cfg.StrOpt('volume_group',
|
||||
default='cinder-volumes',
|
||||
help='Name for the VG that will contain exported volumes'),
|
||||
cfg.StrOpt('volume_clear',
|
||||
default='zero',
|
||||
help='Method used to wipe old volumes (valid options are: '
|
||||
'none, zero, shred)'),
|
||||
cfg.IntOpt('volume_clear_size',
|
||||
default=0,
|
||||
help='Size in MiB to wipe at start of old volumes. 0 => all'),
|
||||
cfg.IntOpt('lvm_mirrors',
|
||||
default=0,
|
||||
help='If set, create lvms with multiple mirrors. Note that '
|
||||
|
@ -119,10 +126,8 @@ class LVMVolumeDriver(driver.VolumeDriver):
|
|||
# zero out old volumes to prevent data leaking between users
|
||||
# TODO(ja): reclaiming space should be done lazy and low priority
|
||||
dev_path = self.local_path(volume)
|
||||
if FLAGS.secure_delete and os.path.exists(dev_path):
|
||||
LOG.info(_("Performing secure delete on volume: %s")
|
||||
% volume['id'])
|
||||
self._copy_volume('/dev/zero', dev_path, size_in_g)
|
||||
if os.path.exists(dev_path):
|
||||
self.clear_volume(volume)
|
||||
|
||||
self._try_execute('lvremove', '-f', "%s/%s" %
|
||||
(FLAGS.volume_group,
|
||||
|
@ -173,6 +178,38 @@ class LVMVolumeDriver(driver.VolumeDriver):
|
|||
|
||||
self._delete_volume(volume, volume['size'])
|
||||
|
||||
def clear_volume(self, volume):
|
||||
"""unprovision old volumes to prevent data leaking between users."""
|
||||
|
||||
vol_path = self.local_path(volume)
|
||||
size_in_g = volume.get('size')
|
||||
size_in_m = FLAGS.volume_clear_size
|
||||
|
||||
if not size_in_g:
|
||||
return
|
||||
|
||||
if FLAGS.volume_clear == 'none':
|
||||
return
|
||||
|
||||
LOG.info(_("Performing secure delete on volume: %s") % volume['id'])
|
||||
|
||||
if FLAGS.volume_clear == 'zero':
|
||||
if size_in_m == 0:
|
||||
return self._copy_volume('/dev/zero', vol_path, size_in_g)
|
||||
else:
|
||||
clear_cmd = ['shred', '-n0', '-z', '-s%dMiB' % size_in_m]
|
||||
elif FLAGS.volume_clear == 'shred':
|
||||
clear_cmd = ['shred', '-n3']
|
||||
if size_in_m:
|
||||
clear_cmd.append('-s%dMiB' % size_in_m)
|
||||
else:
|
||||
LOG.error(_("Error unrecognized volume_clear option: %s"),
|
||||
FLAGS.volume_clear)
|
||||
return
|
||||
|
||||
clear_cmd.append(vol_path)
|
||||
self._execute(*clear_cmd, run_as_root=True)
|
||||
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Creates a snapshot."""
|
||||
orig_lv_name = "%s/%s" % (FLAGS.volume_group, snapshot['volume_name'])
|
||||
|
|
|
@ -28,6 +28,10 @@ lvdisplay: CommandFilter, /sbin/lvdisplay, root
|
|||
iscsiadm: CommandFilter, /sbin/iscsiadm, root
|
||||
iscsiadm_usr: CommandFilter, /usr/bin/iscsiadm, root
|
||||
|
||||
# cinder/volume/drivers/lvm.py: 'shred', '-n3'
|
||||
# cinder/volume/drivers/lvm.py: 'shred', '-n0', '-z', '-s%dMiB'
|
||||
shred: CommandFilter, /usr/bin/shred, root
|
||||
|
||||
#cinder/volume/.py: utils.temporary_chown(path, 0), ...
|
||||
chown: CommandFilter, /bin/chown, root
|
||||
|
||||
|
|
Loading…
Reference in New Issue