-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 0179-feat-Linstor-rewrite-linstorhostcall-logic.patch
Signed-off-by: Damien Thenot <[email protected]>
- Loading branch information
Showing
2 changed files
with
173 additions
and
1 deletion.
There are no files selected for viewing
168 changes: 168 additions & 0 deletions
168
SOURCES/0179-feat-Linstor-rewrite-linstorhostcall-logic.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
From 3f63f6aaa51aaf806de529c169d09b85ace85241 Mon Sep 17 00:00:00 2001 | ||
From: Damien Thenot <[email protected]> | ||
Date: Fri, 19 Apr 2024 14:55:49 +0200 | ||
Subject: [PATCH 179/179] feat(Linstor): rewrite linstorhostcall logic | ||
|
||
Try to use host_OpaqueRef to access primary then try on the master host | ||
if it doesn't work, then find the primary with linstor API or if no | ||
primary, any other host. | ||
|
||
Signed-off-by: Damien Thenot <[email protected]> | ||
Co-authored-by: Ronan Abhamon <[email protected]> | ||
--- | ||
drivers/linstorvhdutil.py | 86 ++++++++++++++++++--------------- | ||
drivers/linstorvolumemanager.py | 18 +++++++ | ||
2 files changed, 66 insertions(+), 38 deletions(-) | ||
|
||
diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py | ||
index 7f8efa1..4b7115b 100644 | ||
--- a/drivers/linstorvhdutil.py | ||
+++ b/drivers/linstorvhdutil.py | ||
@@ -33,18 +33,21 @@ EMEDIUMTYPE = 124 | ||
|
||
|
||
def call_remote_method(session, host_ref, method, device_path, args): | ||
+ host_rec = session.xenapi.host.get_record(host_ref) | ||
+ host_uuid = host_rec['uuid'] | ||
+ | ||
try: | ||
response = session.xenapi.host.call_plugin( | ||
host_ref, MANAGER_PLUGIN, method, args | ||
) | ||
except Exception as e: | ||
- util.SMlog('call-plugin ({} with {}) exception: {}'.format( | ||
- method, args, e | ||
+ util.SMlog('call-plugin on {} ({} with {}) exception: {}'.format( | ||
+ host_uuid, method, args, e | ||
)) | ||
raise util.SMException(str(e)) | ||
|
||
- util.SMlog('call-plugin ({} with {}) returned: {}'.format( | ||
- method, args, response | ||
+ util.SMlog('call-plugin on {} ({} with {}) returned: {}'.format( | ||
+ host_uuid, method, args, response | ||
)) | ||
|
||
return response | ||
@@ -86,33 +89,6 @@ def linstorhostcall(local_method, remote_method): | ||
self._linstor.get_volume_name(vdi_uuid) | ||
) | ||
|
||
- # A. Try a call using directly the DRBD device to avoid | ||
- # remote request. | ||
- | ||
- # Try to read locally if the device is not in use or if the device | ||
- # is up to date and not diskless. | ||
- (node_names, in_use_by) = \ | ||
- self._linstor.find_up_to_date_diskful_nodes(vdi_uuid) | ||
- | ||
- local_e = None | ||
- try: | ||
- if not in_use_by or socket.gethostname() in node_names: | ||
- return self._call_local_method(local_method, device_path, *args[2:], **kwargs) | ||
- except ErofsLinstorCallException as e: | ||
- local_e = e.cmd_err | ||
- except Exception as e: | ||
- local_e = e | ||
- | ||
- util.SMlog( | ||
- 'unable to execute `{}` locally, retry using a readable host... (cause: {})'.format( | ||
- remote_method, local_e if local_e else 'local diskless + in use or not up to date' | ||
- ) | ||
- ) | ||
- | ||
- if in_use_by: | ||
- node_names = {in_use_by} | ||
- | ||
- # B. Execute the plugin on master or slave. | ||
remote_args = { | ||
'devicePath': device_path, | ||
'groupName': self._linstor.group_name | ||
@@ -121,14 +97,48 @@ def linstorhostcall(local_method, remote_method): | ||
remote_args = {str(key): str(value) for key, value in remote_args.iteritems()} | ||
|
||
try: | ||
- def remote_call(): | ||
- host_ref = self._get_readonly_host(vdi_uuid, device_path, node_names) | ||
- return call_remote_method(self._session, host_ref, remote_method, device_path, remote_args) | ||
- response = util.retry(remote_call, 5, 2) | ||
- except Exception as remote_e: | ||
- self._raise_openers_exception(device_path, local_e or remote_e) | ||
+ host_ref_attached = util.get_hosts_attached_on(self._session, [vdi_uuid])[0] | ||
+ if host_ref_attached: | ||
+ response = call_remote_method( | ||
+ self._session, host_ref_attached, remote_method, device_path, remote_args | ||
+ ) | ||
+ return response_parser(self, vdi_uuid, response) | ||
+ except Exception as e: | ||
+ util.SMlog( | ||
+ 'Failed to call method on attached host. Trying local access... (cause: {})'.format(e), | ||
+ priority=util.LOG_DEBUG | ||
+ ) | ||
+ | ||
+ try: | ||
+ master_ref = self._session.xenapi.pool.get_all_records().values()[0]['master'] | ||
+ response = call_remote_method(self._session, master_ref, remote_method, device_path, remote_args) | ||
+ return response_parser(self, vdi_uuid, response) | ||
+ except Exception as e: | ||
+ util.SMlog( | ||
+ 'Failed to call method on master host. Finding primary node... (cause: {})'.format(e), | ||
+ priority=util.LOG_DEBUG | ||
+ ) | ||
+ | ||
+ nodes, primary_hostname = self._linstor.find_up_to_date_diskful_nodes(vdi_uuid) | ||
+ if primary_hostname: | ||
+ try: | ||
+ host_ref = self._get_readonly_host(vdi_uuid, device_path, {primary_hostname}) | ||
+ response = call_remote_method(self._session, host_ref, remote_method, device_path, remote_args) | ||
+ return response_parser(self, vdi_uuid, response) | ||
+ except Exception as remote_e: | ||
+ self._raise_openers_exception(device_path, remote_e) | ||
+ else: | ||
+ util.SMlog( | ||
+ 'Couldn\'t get primary for {}. Trying with another node...'.format(vdi_uuid), | ||
+ priority=util.LOG_DEBUG | ||
+ ) | ||
+ try: | ||
+ host = self._get_readonly_host(vdi_uuid, device_path, nodes) | ||
+ response = call_remote_method(self._session, host, remote_method, device_path, remote_args) | ||
+ return response_parser(self, vdi_uuid, response) | ||
+ except Exception as remote_e: | ||
+ self._raise_openers_exception(device_path, remote_e) | ||
|
||
- return response_parser(self, vdi_uuid, response) | ||
return wrapper | ||
return decorated | ||
|
||
diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py | ||
index 8bfd1c1..fb47b09 100755 | ||
--- a/drivers/linstorvolumemanager.py | ||
+++ b/drivers/linstorvolumemanager.py | ||
@@ -1438,6 +1438,24 @@ class LinstorVolumeManager(object): | ||
|
||
return (node_names, in_use_by) | ||
|
||
+ def get_primary(self, volume_uuid): | ||
+ """ | ||
+ Find the node that opened a volume, i.e. the primary. | ||
+ :rtype: str | ||
+ """ | ||
+ volume_name = self.get_volume_name(volume_uuid) | ||
+ | ||
+ resource_states = filter( | ||
+ lambda resource_state: resource_state.name == volume_name, | ||
+ self._get_resource_cache().resource_states | ||
+ ) | ||
+ | ||
+ for resource_state in resource_states: | ||
+ if resource_state.in_use: | ||
+ return resource_state.node_name | ||
+ | ||
+ return None | ||
+ | ||
def invalidate_resource_cache(self): | ||
""" | ||
If resources are impacted by external commands like vhdutil, | ||
-- | ||
2.45.2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ | |
Summary: sm - XCP storage managers | ||
Name: sm | ||
Version: 2.30.8 | ||
Release: %{?xsrel}.1.0.linstor.4%{?dist} | ||
Release: %{?xsrel}.1.0.linstor.5%{?dist} | ||
Group: System/Hypervisor | ||
License: LGPL | ||
URL: https://github.com/xapi-project/sm | ||
|
@@ -274,6 +274,7 @@ Patch1175: 0175-fix-LinstorSR-Misc-fixes-on-destroy.patch | |
Patch1176: 0176-fix-LinstorSR-open-non-leaf-volumes-in-RO-mode-creat.patch | ||
Patch1177: 0177-fix-LinstorSR-ensure-_is_master-is-always-set.patch | ||
Patch1178: 0178-fix-linstor-check-if-resource-is-tiebreaker-62.patch | ||
Patch1179: 0179-feat-Linstor-rewrite-linstorhostcall-logic.patch | ||
|
||
%description | ||
This package contains storage backends used in XCP | ||
|
@@ -690,6 +691,9 @@ cp -r htmlcov %{buildroot}/htmlcov | |
%{_unitdir}/linstor-monitor.service | ||
|
||
%changelog | ||
* Wed Jul 31 2024 Damien Thenot <[email protected]> 2.30.8-12.1.0.linstor.5 | ||
- Add 0179-feat-Linstor-rewrite-linstorhostcall-logic.patch | ||
|
||
* Fri Jul 26 2024 Ronan Abhamon <[email protected]> 2.30.8-12.1.0.linstor.4 | ||
- Add 0177-fix-LinstorSR-ensure-_is_master-is-always-set.patch | ||
- Add 0178-fix-linstor-check-if-resource-is-tiebreaker-62.patch | ||
|