Skip to content

Commit

Permalink
CA-405381 Mpathcount Info Does Not Automatically Refresh in XenCenter…
Browse files Browse the repository at this point in the history
… After Disabling and Enabling Multipath

Signed-off-by: Lunfan Zhang <[email protected]>
  • Loading branch information
LunfanZhang authored and MarkSymsCtx committed Feb 11, 2025
1 parent f1ee1e3 commit a948ac9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 19 deletions.
36 changes: 28 additions & 8 deletions drivers/mpathcount.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import xs_errors
import mpath_cli
import json
import subprocess

supported = ['iscsi', 'lvmoiscsi', 'rawhba', 'lvmohba', 'ocfsohba', 'ocfsoiscsi', 'netapp', 'gfs2']

Expand All @@ -35,6 +36,7 @@
match_bySCSIid = False
mpath_enabled = True
SCSIid = 'NOTSUPPLIED'
XAPI_HEALTH_CHECK = '/opt/xensource/libexec/xapi-health-check'

cached_DM_maj = None

Expand Down Expand Up @@ -199,13 +201,31 @@ def check_devconfig(devconfig, sm_config, config, remove, add, mpath_status=None
else:
update_config(key, i, config[key], remove, add, mpath_status)


def check_xapi_is_enabled(session, hostref):
host = session.xenapi.host.get_record(hostref)
if not host['enabled']:
util.SMlog("Xapi is not enabled, exiting")
mpc_exit(session, 0)

def check_xapi_is_enabled():
"""Check XAPI health status"""
def _run_command(command, timeout):
try:
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True
)
try:
stdout, stderr = process.communicate(timeout=timeout)
return process.returncode, stdout, stderr
except subprocess.TimeoutExpired:
process.kill()
util.SMlog(f"Command execution timeout after {timeout}s: {' '.join(command)}")
return -1, "", "Timeout"
except Exception as e:
util.SMlog(f"Error executing command: {e}")
return -1, "", str(e)

returncode, _, stderr = _run_command([XAPI_HEALTH_CHECK], timeout=120)
if returncode != 0:
util.SMlog(f"XAPI health check failed: {stderr}")
return returncode == 0

if __name__ == '__main__':
try:
Expand All @@ -215,7 +235,7 @@ def check_xapi_is_enabled(session, hostref):
sys.exit(-1)

localhost = session.xenapi.host.get_by_uuid(get_localhost_uuid())
check_xapi_is_enabled(session, localhost)
check_xapi_is_enabled()
# Check whether multipathing is enabled (either for root dev or SRs)
try:
if get_root_dev_major() != get_dm_major():
Expand Down
32 changes: 21 additions & 11 deletions tests/test_mpathcount.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,27 +211,37 @@ def test_exit_log_out_error(self, mock_exit):
session.xenapi.session.logout.assert_called_once()

@mock.patch('mpathcount.sys.exit', autospec=True)
def test_check_xapi_enabled_yes(self, mock_exit):
@mock.patch('mpathcount.util.SMlog', autospec=True)
@mock.patch('mpathcount.subprocess.Popen', autospec=True)
def test_check_xapi_enabled_yes(self, mock_popen, mock_smlog, mock_exit):
# Arrange
session = mock.MagicMock()
session.xenapi.host.get_record.return_value = {'enabled': True}
hostref = mock.MagicMock()
process_mock = mock.Mock()
attrs = {'communicate.return_value': ('output', ''), 'returncode': 0}
process_mock.configure_mock(**attrs)
mock_popen.return_value = process_mock

# Act
mpathcount.check_xapi_is_enabled(session, hostref)
result = mpathcount.check_xapi_is_enabled()

# Assert
self.assertTrue(result)
mock_exit.assert_not_called()
mock_smlog.assert_not_called()

@mock.patch('mpathcount.sys.exit', autospec=True)
def test_check_xapi_enabled_no(self, mock_exit):
@mock.patch('mpathcount.util.SMlog', autospec=True)
@mock.patch('mpathcount.subprocess.Popen', autospec=True)
def test_check_xapi_enabled_no(self, mock_popen, mock_smlog, mock_exit):
# Arrange
session = mock.MagicMock()
session.xenapi.host.get_record.return_value = {'enabled': False}
hostref = mock.MagicMock()
process_mock = mock.Mock()
attrs = {'communicate.return_value': ('', 'error'), 'returncode': 1}
process_mock.configure_mock(**attrs)
mock_popen.return_value = process_mock

# Act
mpathcount.check_xapi_is_enabled(session, hostref)
result = mpathcount.check_xapi_is_enabled()

# Assert
mock_exit.assert_called_once_with(0)
self.assertFalse(result)
mock_exit.assert_not_called()
mock_smlog.assert_called_once_with('XAPI health check failed: error')

0 comments on commit a948ac9

Please sign in to comment.