CIFS extension failing because of volume in use
Unmouting of the volume from service instance sometimes fails because Windows clients tends to check the availability of shares even if not mounted and the volume is in use then. Fix finds out processes via smbstatus and kill them before unmounting. Closes-Bug: 1703581 Change-Id: I2cbf959d7cb849d3ead1655b1a0932fd428a9e9f Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
parent
9fbde73868
commit
2c9fbc7505
@ -529,6 +529,30 @@ class CIFSHelperIPAccess(CIFSHelperBase):
|
||||
]
|
||||
self._ssh_exec(server, backup_exports)
|
||||
self._set_allow_hosts(server, [], share_name)
|
||||
self._kick_out_users(server, share_name)
|
||||
|
||||
def _kick_out_users(self, server, share_name):
|
||||
"""Kick out all users of share"""
|
||||
(out, _) = self._ssh_exec(server, ['sudo', 'smbstatus', '-S'])
|
||||
|
||||
shares = []
|
||||
header = True
|
||||
regexp = r"^(?P<share>[^ ]+)\s+(?P<pid>[0-9]+)\s+(?P<machine>[^ ]+).*"
|
||||
for line in out.splitlines():
|
||||
line = line.strip()
|
||||
if not header and line:
|
||||
match = re.match(regexp, line)
|
||||
if match:
|
||||
shares.append(match.groupdict())
|
||||
else:
|
||||
raise exception.ShareBackendException(
|
||||
msg="Failed to obtain smbstatus for %s!" % share_name)
|
||||
elif line.startswith('----'):
|
||||
header = False
|
||||
to_kill = [s['pid'] for s in shares if
|
||||
share_name == s['share'] or share_name is None]
|
||||
if to_kill:
|
||||
self._ssh_exec(server, ['sudo', 'kill', '-15'] + to_kill)
|
||||
|
||||
def restore_access_after_maintenance(self, server, share_name):
|
||||
maintenance_file = self._get_maintenance_file_path(share_name)
|
||||
|
@ -678,11 +678,39 @@ class CIFSHelperIPAccessTestCase(test.TestCase):
|
||||
self.server_details, self.share_name)
|
||||
self._helper._set_allow_hosts.assert_called_once_with(
|
||||
self.server_details, [], self.share_name)
|
||||
kickoff_user_cmd = ['sudo', 'smbstatus', '-S']
|
||||
self._helper._ssh_exec.assert_any_call(
|
||||
self.server_details, kickoff_user_cmd)
|
||||
valid_cmd = ['echo', "'test test2'", '|', 'sudo', 'tee',
|
||||
maintenance_path]
|
||||
self._helper._ssh_exec.assert_called_once_with(
|
||||
self._helper._ssh_exec.assert_any_call(
|
||||
self.server_details, valid_cmd)
|
||||
|
||||
def test__kick_out_users_success(self):
|
||||
smbstatus_return = """Service pid machine Connected at
|
||||
-------------------------------------------------------
|
||||
fake_share_name 1001 fake_machine1 Thu Sep 14 14:59:07 2017
|
||||
fake_share_name 1002 fake_machine2 Thu Sep 14 14:59:07 2017
|
||||
"""
|
||||
self.mock_object(self._helper, '_ssh_exec', mock.Mock(
|
||||
side_effect=[(smbstatus_return, "fake_stderr"), ("fake", "fake")]))
|
||||
self._helper._kick_out_users(self.server_details, self.share_name)
|
||||
self._helper._ssh_exec.assert_any_call(
|
||||
self.server_details, ['sudo', 'smbstatus', '-S'])
|
||||
self._helper._ssh_exec.assert_any_call(
|
||||
self.server_details, ["sudo", "kill", "-15", "1001", "1002"])
|
||||
|
||||
def test__kick_out_users_failed(self):
|
||||
smbstatus_return = """Service pid machine Connected at
|
||||
-------------------------------------------------------
|
||||
fake line
|
||||
"""
|
||||
self.mock_object(self._helper, '_ssh_exec', mock.Mock(
|
||||
return_value=(smbstatus_return, "fake_stderr")))
|
||||
self.assertRaises(exception.ShareBackendException,
|
||||
self._helper._kick_out_users, self.server_details,
|
||||
self.share_name)
|
||||
|
||||
def test_restore_access_after_maintenance(self):
|
||||
fake_maintenance_path = "test.path"
|
||||
self.mock_object(self._helper, '_set_allow_hosts')
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
fixes:
|
||||
- Fixed the Generic driver to evict and kill any user processes accessing
|
||||
a share before attempting to extend or shrink a CIFS share.
|
Loading…
x
Reference in New Issue
Block a user