diff --git a/manila/share/drivers/hitachi/hds_hnas.py b/manila/share/drivers/hitachi/hds_hnas.py index ab2b810f3f..5e5060f1b7 100644 --- a/manila/share/drivers/hitachi/hds_hnas.py +++ b/manila/share/drivers/hitachi/hds_hnas.py @@ -479,10 +479,10 @@ class HDSHNASDriver(driver.ShareDriver): LOG.exception(msg) def _check_fs_mounted(self): - if not self.hnas.check_fs_mounted(): - LOG.debug("Filesystem %(fs)s is unmounted. Mounting...", - {'fs': self.fs_name}) - self.hnas.mount() + mounted = self.hnas.check_fs_mounted() + if not mounted: + msg = _("Filesystem %s is not mounted.") % self.fs_name + raise exception.HNASBackendException(msg=msg) def _ensure_share(self, share_id): """Ensure that share is exported. diff --git a/manila/share/drivers/hitachi/ssh.py b/manila/share/drivers/hitachi/ssh.py index 7d37953cb3..a41e444e97 100644 --- a/manila/share/drivers/hitachi/ssh.py +++ b/manila/share/drivers/hitachi/ssh.py @@ -58,11 +58,9 @@ class HNASSSHBackend(object): output, err = self._execute(command) line = output.split('\n') - fs_capacity = Capacity(line[3]) - - available_space = fs_capacity.size - fs_capacity.used - - return fs_capacity.size, available_space + fs = Filesystem(line[3]) + available_space = fs.size - fs.used + return fs.size, available_space def nfs_export_add(self, share_id): path = '/shares/' + share_id @@ -195,16 +193,16 @@ class HNASSSHBackend(object): self._locked_selectfs('delete', path) def check_fs_mounted(self): - fs_list = self._get_filesystem_list() - for i in range(0, len(fs_list)): - if fs_list[i].name == self.fs_name: - if fs_list[i].state == 'Mount': - return True - else: - return False - msg = (_("Filesystem %s does not exist or it is not available " - "in the current EVS context.") % self.fs_name) - raise exception.HNASItemNotFoundException(msg=msg) + command = ['df', '-a', '-f', self.fs_name] + output, err = self._execute(command) + if "not found" in output: + msg = (_("Filesystem %s does not exist or it is not available " + "in the current EVS context.") % self.fs_name) + raise exception.HNASItemNotFoundException(msg=msg) + else: + line = output.split('\n') + fs = Filesystem(line[3]) + return fs.mounted def mount(self): command = ['mount', self.fs_name] @@ -335,29 +333,6 @@ class HNASSSHBackend(object): export_list.append(Export(items[i])) return export_list - def _get_filesystem_list(self): - command = ['filesystem-list', self.fs_name] - output, err = self._execute(command) - items = output.split('\n') - filesystem_list = [] - fs_name = None - if len(items) > 2: - j = 0 - for i in range(2, len(items) - 1): - if "Filesystem " in items[i] and len(items[i].split()) == 2: - description, fs_name = items[i].split() - fs_name = fs_name[:len(fs_name) - 1] - elif "NoEVS" not in items[i]: - # Not considering FS without EVS - filesystem_list.append(FileSystem(items[i])) - if fs_name is not None: - filesystem_list[j].name = fs_name - fs_name = None - j += 1 - else: - LOG.debug("Ignoring filesystems without EVS.") - return filesystem_list - @mutils.retry(exception=exception.HNASConnException, wait_random=True) def _execute(self, commands): command = ['ssc', '127.0.0.1'] @@ -428,24 +403,6 @@ class HNASSSHBackend(object): raise e -class FileSystem(object): - def __init__(self, data): - if data: - items = data.split() - if len(items) >= 7: - self.name = items[0] - self.dev = items[1] - self.on_span = items[2] - self.state = items[3] - self.evs = int(items[4]) - self.capacity = int(items[5]) - self.confined = int(items[6]) - if len(items) == 8: - self.flag = items[7] - else: - self.flag = '' - - class Export(object): def __init__(self, data): if data: @@ -533,7 +490,7 @@ class JobSubmit(object): self.job_id = split_data[8] -class Capacity(object): +class Filesystem(object): def __init__(self, data): if data: items = data.split() @@ -544,10 +501,14 @@ class Capacity(object): self.size_measure = items[4] if self.size_measure == 'TB': self.size = self.size * units.Ki - self.used = float(items[5]) - self.used_measure = items[6] - if self.used_measure == 'TB': - self.used = self.used * units.Ki + if items[5:7] == ["Not", "mounted"]: + self.mounted = False + else: + self.mounted = True + self.used = float(items[5]) + self.used_measure = items[6] + if self.used_measure == 'TB': + self.used = self.used * units.Ki class Quota(object): diff --git a/manila/tests/share/drivers/hitachi/test_hds_hnas.py b/manila/tests/share/drivers/hitachi/test_hds_hnas.py index 286bbf7d28..10622f7ac9 100644 --- a/manila/tests/share/drivers/hitachi/test_hds_hnas.py +++ b/manila/tests/share/drivers/hitachi/test_hds_hnas.py @@ -101,7 +101,7 @@ class HDSHNASTestCase(test.TestCase): CONF.hds_hnas_ip_port = 'hds_hnas_ip_port' CONF.hds_hnas_user = 'hds_hnas_user' CONF.hds_hnas_password = 'hds_hnas_password' - CONF.hds_hnas_file_system = 'file_system' + CONF.hds_hnas_file_system_name = 'file_system' CONF.hds_hnas_ssh_private_key = 'private_key' CONF.hds_hnas_cluster_admin_ip0 = None CONF.hds_hnas_stalled_job_timeout = 10 @@ -498,13 +498,11 @@ class HDSHNASTestCase(test.TestCase): def test__check_fs_mounted_not_mounted(self): self.mock_object(ssh.HNASSSHBackend, 'check_fs_mounted', mock.Mock( return_value=False)) - self.mock_object(ssh.HNASSSHBackend, 'mount', mock.Mock()) - self._driver._check_fs_mounted() + self.assertRaises( + exception.HNASBackendException, self._driver._check_fs_mounted) ssh.HNASSSHBackend.check_fs_mounted.assert_called_once_with() - ssh.HNASSSHBackend.mount.assert_called_once_with() - self.assertTrue(self.mock_log.debug.called) def test__update_share_stats(self): fake_data = { diff --git a/manila/tests/share/drivers/hitachi/test_ssh.py b/manila/tests/share/drivers/hitachi/test_ssh.py index 2811f56604..f0100b2e49 100644 --- a/manila/tests/share/drivers/hitachi/test_ssh.py +++ b/manila/tests/share/drivers/hitachi/test_ssh.py @@ -58,27 +58,6 @@ Warning: Clearing dangling space trackers from empty vivol""" HNAS_RESULT_selectfs = "Current selected file system: fake_fs, number(1)" -HNAS_RESULT_fs = """ \ -Instance name Dev On span State EVS Cap/GiB Confined Flag ------------------ ---- ------- ------ --- ------- -------- ---- -Filesystem 8e6e2c85-fake-long-filesystem-b9b4-e4b09993841e: -8e6e2c8..9993841e 1057 fake_span Mount 2 4 3 -fake_fs 1051 fake_span NoEVS - 100 1024 -file_system 1055 fake_span Mount 2 4 5 1 -""" - -HNAS_RESULT_u_fs = """ \ -Instance name Dev On span State EVS Cap/GiB Confined Flag ------------------ ---- ------- ------ --- ------- -------- ---- -file_system 1055 fake_span Umount 2 4 5 -file_system2 1050 fake_span2 NoEVS - 10 0 1 -fake_fs 1051 fake_span Umount 2 100 1024 """ - -HNAS_RESULT_one_fs = """ \ -Instance name Dev On span State EVS Cap/GiB Confined Flag ------------------ ---- ------- ------ --- ------- -------- ---- -fake_fs 1051 fake_span Mount 2 100 1024 1""" - HNAS_RESULT_expadd = "NFS Export Add: Export added successfully" HNAS_RESULT_vvol = """vvol_test @@ -261,36 +240,6 @@ Export Modify: Export modified successfully""" HNAS_RESULT_expnotmod = "Export not modified." -HNAS_RESULT_fslimits = """ -Filesystem fake_fs on span fake_span: - -Current capacity 100GiB - -Thin provision: disabled - -Free space on span allows expansion to: 10GiB (Run 'span-expand') -Filesystem is confined to: 1024GiB (Run 'filesystem-confine') -Chunk size allows growth to: 1024GiB (This is a conservative \ - estimate) -Largest filesystem that can be checked: 10000GiB (This is a hard limit) -This server model allows growth to: 10000GiB (Upgrade the server) -""" - -HNAS_RESULT_fslimits_tb = """ \ -Filesystem fake_fs on span fake_span: - -Current capacity 1500GiB - -Thin provision: disabled - -Free space on span allows expansion to: 1000GiB (Run 'span-expand') -Filesystem is confined to: 10240GiB (Run 'filesystem-confine') -Chunk size allows growth to: 10240GiB (This is a conservative \ -estimate) -Largest filesystem that can be checked: 10000GiB (This is a hard limit) -This server model allows growth to: 10000GiB (Upgrade the server) -""" - HNAS_RESULT_job = """tree-operation-job-submit: Request submitted successfully. tree-operation-job-submit: Job id = d933100a-b5f6-11d0-91d9-836896aada5d""" @@ -340,9 +289,6 @@ HNAS_RESULT_tree_job_status_fail = """JOB ID : d933100a-b5f6-11d0-91d9-836896aad Skipping details : 104 symlinks, 452 hard links, 47 block special devices, 25 character devices""" -HNAS_RESULT_job = """tree-operation-job-submit: Request submitted successfully. -tree-operation-job-submit: Job id = d933100a-b5f6-11d0-91d9-836896aada5d """ - HNAS_RESULT_job_completed = """JOB ID : ab4211b8-aac8-11ce-91af-39e0822ea368 Job request Physical node : 1 @@ -417,6 +363,17 @@ HNAS_RESULT_df_tb = """ 18.3 GB (25%) No 4 KB,WFS-2,128 DSBs """ +HNAS_RESULT_df_unmounted = """ + ID Label EVS Size Used Snapshots Deduped \ + Avail Thin ThinSize ThinAvail FS Type +---- ------------- --- -------- -------------- --------- ------- \ +------------- ---- -------- --------- ------------------- +1051 FS-ManilaDev1 3 70.00 GB Not mounted 0 B (0%) NA \ +18.3 GB (25%) No 4 KB,WFS-2,128 DSBs +""" + +HNAS_RESULT_df_error = """File system file_system not found""" + HNAS_RESULT_mounted_filesystem = """ file_system 1055 fake_span Mount 2 4 5 1 """ @@ -650,22 +607,22 @@ class HNASSSHTestCase(test.TestCase): *locked_selectfs_args) def test_check_fs_mounted_true(self): - self.mock_object(ssh.HNASSSHBackend, "_get_filesystem_list", - mock.Mock(return_value=[ssh.FileSystem( - HNAS_RESULT_mounted_filesystem)])) + self.mock_object(ssh.HNASSSHBackend, "_execute", + mock.Mock(return_value=(HNAS_RESULT_df, ''))) self.assertTrue(self._driver_ssh.check_fs_mounted()) def test_check_fs_mounted_false(self): - self.mock_object(ssh.HNASSSHBackend, "_get_filesystem_list", - mock.Mock(return_value=[ssh.FileSystem( - HNAS_RESULT_unmounted_filesystem)])) + self.mock_object( + ssh.HNASSSHBackend, "_execute", + mock.Mock(return_value=(HNAS_RESULT_df_unmounted, ''))) self.assertFalse(self._driver_ssh.check_fs_mounted()) - def test_check_fs_mounted_eror(self): - self.mock_object(ssh.HNASSSHBackend, "_get_filesystem_list", - mock.Mock(return_value=[])) + def test_check_fs_mounted_error(self): + self.mock_object( + ssh.HNASSSHBackend, "_execute", + mock.Mock(return_value=(HNAS_RESULT_df_error, ''))) self.assertRaises(exception.HNASItemNotFoundException, self._driver_ssh.check_fs_mounted) @@ -853,19 +810,6 @@ class HNASSSHTestCase(test.TestCase): self.assertRaises(putils.ProcessExecutionError, self._driver_ssh._get_share_export, 'fake_id') - def test__get_filesystem_list(self): - self.mock_object(ssh.HNASSSHBackend, '_execute', - mock.Mock(return_value=[HNAS_RESULT_fs, ''])) - - out = self._driver_ssh._get_filesystem_list() - - self.assertEqual('8e6e2c85-fake-long-filesystem-b9b4-e4b09993841e', - out[0].name) - self.assertEqual('fake_span', out[0].on_span) - self.assertEqual('Mount', out[0].state) - self.assertEqual(2, out[0].evs) - self.assertTrue(self.mock_log.debug.called) - def test__execute(self): key = self.ssh_private_key commands = ['tree-clone-job-submit', '-e', '/src', '/dst'] diff --git a/releasenotes/notes/fix-hds-hnas-unconfined-09b79f3bdb24a83c.yaml b/releasenotes/notes/fix-hds-hnas-unconfined-09b79f3bdb24a83c.yaml new file mode 100644 index 0000000000..e5774f10ef --- /dev/null +++ b/releasenotes/notes/fix-hds-hnas-unconfined-09b79f3bdb24a83c.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - Crash when using unconfined filesystems in HDS HNAS driver using + SSH backend. + - HDS HNAS Driver no longer mounts unmounted filesystems automatically.