Skip to content

Commit

Permalink
Merge "GPFS support for various volume attributes"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Aug 21, 2013
2 parents 4bad48e + 932c3b6 commit 27df5c5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 10 deletions.
26 changes: 23 additions & 3 deletions cinder/tests/test_gpfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ def setUp(self):
self._fake_delete_gpfs_file)
self.stubs.Set(GPFSDriver, '_create_sparse_file',
self._fake_create_sparse_file)
self.stubs.Set(GPFSDriver, '_create_regular_file',
self._fake_create_regular_file)
self.stubs.Set(GPFSDriver, '_allocate_file_blocks',
self._fake_allocate_file_blocks)
self.stubs.Set(GPFSDriver, '_get_available_capacity',
self._fake_get_available_capacity)
self.stubs.Set(image_utils, 'qemu_img_info',
Expand Down Expand Up @@ -153,6 +153,23 @@ def test_create_delete_volume_sparse_backing_file(self):
self.volume.delete_volume(self.context, volume_id)
self.assertFalse(os.path.exists(path))

def test_create_volume_with_attributes(self):
self.stubs.Set(GPFSDriver, '_gpfs_change_attributes',
self._fake_gpfs_change_attributes)
attributes = {'dio': 'yes', 'data_pool_name': 'ssd_pool',
'replicas': '2', 'write_affinity_depth': '1',
'block_group_factor': '1',
'write_affinity_failure-group':
'1,1,1:2;2,1,1:2;2,0,3:4'}
vol = self._create_volume(size=1, metadata=attributes)
volume_id = vol['id']
self.assertTrue(os.path.exists(self.volumes_path))
self.volume.create_volume(self.context, volume_id)
path = self.volumes_path + '/' + vol['name']
self.assertTrue(os.path.exists(path))
self.volume.delete_volume(self.context, volume_id)
self.assertFalse(os.path.exists(path))

def _create_snapshot(self, volume_id, size='0'):
"""Create a snapshot object."""
snap = {}
Expand Down Expand Up @@ -405,9 +422,12 @@ def _fake_gpfs_copy(self, src, dest):
def _fake_create_sparse_file(self, path, size):
self._fake_create_file(path)

def _fake_create_regular_file(self, path, size):
def _fake_allocate_file_blocks(self, path, size):
self._fake_create_file(path)

def _fake_gpfs_change_attributes(self, options, path):
pass

def _fake_gpfs_redirect(self, src):
return True

Expand Down
46 changes: 39 additions & 7 deletions cinder/volume/drivers/gpfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ def _create_sparse_file(self, path, size):
self._execute('truncate', '-s', sizestr, path, run_as_root=True)
self._execute('chmod', '666', path, run_as_root=True)

def _create_regular_file(self, path, size):
"""Creates regular file of given size."""
def _allocate_file_blocks(self, path, size):
"""Preallocate file blocks by writing zeros."""

block_size_mb = 1
block_count = size * units.GiB / (block_size_mb * units.MiB)
Expand All @@ -222,19 +222,51 @@ def _create_regular_file(self, path, size):
'bs=%dM' % block_size_mb,
'count=%d' % block_count,
run_as_root=True)
self._execute('chmod', '666', path, run_as_root=True)

def _gpfs_change_attributes(self, options, path):
cmd = ['mmchattr']
cmd.extend(options)
cmd.append(path)
self._execute(*cmd, run_as_root=True)

def _set_volume_attributes(self, path, metadata):
"""Set various GPFS attributes for this volume."""

options = []
for item in metadata:
if item['key'] == 'data_pool_name':
options.extend(['-P', item['value']])
elif item['key'] == 'replicas':
options.extend(['-r', item['value'], '-m', item['value']])
elif item['key'] == 'dio':
options.extend(['-D', item['value']])
elif item['key'] == 'write_affinity_depth':
options.extend(['--write-affinity-depth', item['value']])
elif item['key'] == 'block_group_factor':
options.extend(['--block-group-factor', item['value']])
elif item['key'] == 'write_affinity_failure_group':
options.extend(['--write-affinity-failure-group',
item['value']])

if options:
self._gpfs_change_attributes(options, path)

def create_volume(self, volume):
"""Creates a GPFS volume."""
volume_path = self.local_path(volume)
volume_size = volume['size']

if self.configuration.gpfs_sparse_volumes:
self._create_sparse_file(volume_path, volume_size)
else:
self._create_regular_file(volume_path, volume_size)
# Create a sparse file first; allocate blocks later if requested
self._create_sparse_file(volume_path, volume_size)

# Set the attributes prior to allocating any blocks so that
# they are allocated according to the policy
v_metadata = volume.get('volume_metadata')
self._set_volume_attributes(volume_path, v_metadata)

if not self.configuration.gpfs_sparse_volumes:
self._allocate_file_blocks(volume_path, volume_size)

fstype = None
fslabel = None
for item in v_metadata:
Expand Down
1 change: 1 addition & 0 deletions etc/cinder/rootwrap.d/volume.filters
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ blockdev: CommandFilter, blockdev, root
mmgetstate: CommandFilter, /usr/lpp/mmfs/bin/mmgetstate, root
mmclone: CommandFilter, /usr/lpp/mmfs/bin/mmclone, root
mmlsattr: CommandFilter, /usr/lpp/mmfs/bin/mmlsattr, root
mmchattr: CommandFilter, /usr/lpp/mmfs/bin/mmchattr, root
mmlsconfig: CommandFilter, /usr/lpp/mmfs/bin/mmlsconfig, root
mmlsfs: CommandFilter, /usr/lpp/mmfs/bin/mmlsfs, root
find: CommandFilter, find, root
Expand Down

0 comments on commit 27df5c5

Please sign in to comment.