Merge "GPFS Verify min release level for mmclone command"
This commit is contained in:
commit
ea734c5db9
@ -342,6 +342,10 @@ class GPFSDriverTestCase(test.TestCase):
|
||||
self._fake_gpfs_get_state_active)
|
||||
self.stubs.Set(GPFSDriver, '_is_gpfs_path',
|
||||
self._fake_is_gpfs_path)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_cluster_release_level',
|
||||
self._fake_gpfs_compatible_cluster_release_level)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_filesystem_release_level',
|
||||
self._fake_gpfs_compatible_filesystem_release_level)
|
||||
self.driver.check_for_setup_error()
|
||||
|
||||
def test_check_for_setup_error_gpfs_not_active(self):
|
||||
@ -357,6 +361,32 @@ class GPFSDriverTestCase(test.TestCase):
|
||||
self._fake_gpfs_get_state_active)
|
||||
self.stubs.Set(GPFSDriver, '_is_gpfs_path',
|
||||
self._fake_is_not_gpfs_path)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_cluster_release_level',
|
||||
self._fake_gpfs_compatible_cluster_release_level)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_filesystem_release_level',
|
||||
self._fake_gpfs_compatible_filesystem_release_level)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.check_for_setup_error)
|
||||
|
||||
def test_check_for_setup_error_incompatible_cluster_version(self):
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_state',
|
||||
self._fake_gpfs_get_state_active)
|
||||
self.stubs.Set(GPFSDriver, '_is_gpfs_path',
|
||||
self._fake_is_gpfs_path)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_cluster_release_level',
|
||||
self._fake_gpfs_incompatible_cluster_release_level)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.check_for_setup_error)
|
||||
|
||||
def test_check_for_setup_error_incompatible_filesystem_version(self):
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_state',
|
||||
self._fake_gpfs_get_state_active)
|
||||
self.stubs.Set(GPFSDriver, '_is_gpfs_path',
|
||||
self._fake_is_gpfs_path)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_cluster_release_level',
|
||||
self._fake_gpfs_compatible_cluster_release_level)
|
||||
self.stubs.Set(GPFSDriver, '_get_gpfs_filesystem_release_level',
|
||||
self._fake_gpfs_incompatible_filesystem_release_level)
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.check_for_setup_error)
|
||||
|
||||
@ -405,6 +435,24 @@ class GPFSDriverTestCase(test.TestCase):
|
||||
'1:quorum node:(undefined):')
|
||||
return inactive_txt
|
||||
|
||||
def _fake_gpfs_compatible_cluster_release_level(self):
|
||||
release = 1400
|
||||
return release
|
||||
|
||||
def _fake_gpfs_incompatible_cluster_release_level(self):
|
||||
release = 1105
|
||||
return release
|
||||
|
||||
def _fake_gpfs_compatible_filesystem_release_level(self, path=None):
|
||||
release = 1400
|
||||
fs = '/dev/gpfs'
|
||||
return fs, release
|
||||
|
||||
def _fake_gpfs_incompatible_filesystem_release_level(self, path=None):
|
||||
release = 1105
|
||||
fs = '/dev/gpfs'
|
||||
return fs, release
|
||||
|
||||
def _fake_is_gpfs_path(self, path):
|
||||
pass
|
||||
|
||||
|
@ -32,6 +32,8 @@ from cinder import units
|
||||
from cinder.volume import driver
|
||||
|
||||
VERSION = 1.0
|
||||
GPFS_CLONE_MIN_RELEASE = 1200
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
gpfs_opts = [
|
||||
@ -91,6 +93,32 @@ class GPFSDriver(driver.VolumeDriver):
|
||||
gpfs_state)
|
||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||
|
||||
def _get_filesystem_from_path(self, path):
|
||||
(out, _) = self._execute('df', path, run_as_root=True)
|
||||
lines = out.splitlines()
|
||||
fs = lines[1].split()[0]
|
||||
return fs
|
||||
|
||||
def _get_gpfs_filesystem_release_level(self, path):
|
||||
fs = self._get_filesystem_from_path(path)
|
||||
(out, _) = self._execute('mmlsfs', fs, '-V', '-Y',
|
||||
run_as_root=True)
|
||||
lines = out.splitlines()
|
||||
value_token = lines[0].split(':').index('data')
|
||||
fs_release_level_str = lines[1].split(':')[value_token]
|
||||
# at this point, release string looks like "13.23 (3.5.0.7)"
|
||||
# extract first token and convert to whole number value
|
||||
fs_release_level = int(float(fs_release_level_str.split()[0]) * 100)
|
||||
return fs, fs_release_level
|
||||
|
||||
def _get_gpfs_cluster_release_level(self):
|
||||
(out, _) = self._execute('mmlsconfig', 'minreleaseLeveldaemon', '-Y',
|
||||
run_as_root=True)
|
||||
lines = out.splitlines()
|
||||
value_token = lines[0].split(':').index('value')
|
||||
min_release_level = lines[1].split(':')[value_token]
|
||||
return int(min_release_level)
|
||||
|
||||
def _is_gpfs_path(self, directory):
|
||||
self._execute('mmlsattr', directory, run_as_root=True)
|
||||
|
||||
@ -131,6 +159,16 @@ class GPFSDriver(driver.VolumeDriver):
|
||||
LOG.warn(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
_gpfs_cluster_release_level = self._get_gpfs_cluster_release_level()
|
||||
if not _gpfs_cluster_release_level >= GPFS_CLONE_MIN_RELEASE:
|
||||
msg = (_('Downlevel GPFS Cluster Detected. GPFS Clone feature '
|
||||
'not enabled in cluster daemon level %(cur)s - must '
|
||||
'be at least at level %(min)s.') %
|
||||
{'cur': _gpfs_cluster_release_level,
|
||||
'min': GPFS_CLONE_MIN_RELEASE})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
for directory in [self.configuration.gpfs_mount_point_base,
|
||||
self.configuration.gpfs_images_dir]:
|
||||
if directory is None:
|
||||
@ -155,6 +193,17 @@ class GPFSDriver(driver.VolumeDriver):
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
fs, fslevel = self._get_gpfs_filesystem_release_level(directory)
|
||||
if not fslevel >= GPFS_CLONE_MIN_RELEASE:
|
||||
msg = (_('The GPFS filesystem %(fs)s is not at the required '
|
||||
'release level. Current level is %(cur)s, must be '
|
||||
'at least %(min)s.') %
|
||||
{'fs': fs,
|
||||
'cur': fslevel,
|
||||
'min': GPFS_CLONE_MIN_RELEASE})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
def _create_sparse_file(self, path, size):
|
||||
"""Creates file with 0 disk usage."""
|
||||
|
||||
|
@ -73,5 +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
|
||||
mmlsconfig: CommandFilter, /usr/lpp/mmfs/bin/mmlsconfig, root
|
||||
mmlsfs: CommandFilter, /usr/lpp/mmfs/bin/mmlsfs, root
|
||||
find: CommandFilter, find, root
|
||||
mkfs: CommandFilter, mkfs, root
|
||||
|
Loading…
x
Reference in New Issue
Block a user