@@ -76,33 +76,6 @@ def wrapper(*args, **kwargs):
7676 self ._linstor .get_volume_name (vdi_uuid )
7777 )
7878
79- # A. Try a call using directly the DRBD device to avoid
80- # remote request.
81-
82- # Try to read locally if the device is not in use or if the device
83- # is up to date and not diskless.
84- (node_names , in_use_by ) = \
85- self ._linstor .find_up_to_date_diskful_nodes (vdi_uuid )
86-
87- local_e = None
88- try :
89- if not in_use_by or socket .gethostname () in node_names :
90- return self ._call_local_method (local_method , device_path , * args [2 :], ** kwargs )
91- except ErofsLinstorCallException as e :
92- local_e = e .cmd_err
93- except Exception as e :
94- local_e = e
95-
96- util .SMlog (
97- 'unable to execute `{}` locally, retry using a readable host... (cause: {})' .format (
98- remote_method , local_e if local_e else 'local diskless + in use or not up to date'
99- )
100- )
101-
102- if in_use_by :
103- node_names = {in_use_by }
104-
105- # B. Execute the plugin on master or slave.
10679 remote_args = {
10780 'devicePath' : device_path ,
10881 'groupName' : self ._linstor .group_name
@@ -111,14 +84,48 @@ def wrapper(*args, **kwargs):
11184 remote_args = {str (key ): str (value ) for key , value in remote_args .iteritems ()}
11285
11386 try :
114- def remote_call ():
115- host_ref = self ._get_readonly_host (vdi_uuid , device_path , node_names )
116- return call_remote_method (self ._session , host_ref , remote_method , device_path , remote_args )
117- response = util .retry (remote_call , 5 , 2 )
118- except Exception as remote_e :
119- self ._raise_openers_exception (device_path , local_e or remote_e )
87+ host_ref_attached = util .get_hosts_attached_on (self ._session , [vdi_uuid ])[0 ]
88+ if host_ref_attached :
89+ response = call_remote_method (
90+ self ._session , host_ref_attached , remote_method , device_path , remote_args
91+ )
92+ return response_parser (self , vdi_uuid , response )
93+ except Exception as e :
94+ util .SMlog (
95+ 'Failed to call method on attached host. Trying local access... (cause: {})' .format (e ),
96+ priority = util .LOG_DEBUG
97+ )
98+
99+ try :
100+ master_ref = self ._session .xenapi .pool .get_all_records ().values ()[0 ]['master' ]
101+ response = call_remote_method (self ._session , master_ref , remote_method , device_path , remote_args )
102+ return response_parser (self , vdi_uuid , response )
103+ except Exception as e :
104+ util .SMlog (
105+ 'Failed to call method on master host. Finding primary node... (cause: {})' .format (e ),
106+ priority = util .LOG_DEBUG
107+ )
108+
109+ nodes , primary_hostname = self ._linstor .find_up_to_date_diskful_nodes (vdi_uuid )
110+ if primary_hostname :
111+ try :
112+ host_ref = self ._get_readonly_host (vdi_uuid , device_path , {primary_hostname })
113+ response = call_remote_method (self ._session , host_ref , remote_method , device_path , remote_args )
114+ return response_parser (self , vdi_uuid , response )
115+ except Exception as remote_e :
116+ self ._raise_openers_exception (device_path , remote_e )
117+ else :
118+ util .SMlog (
119+ 'Couldn\' t get primary for {}. Trying with another node...' .format (vdi_uuid ),
120+ priority = util .LOG_DEBUG
121+ )
122+ try :
123+ host = self ._get_readonly_host (vdi_uuid , device_path , nodes )
124+ response = call_remote_method (self ._session , host , remote_method , device_path , remote_args )
125+ return response_parser (self , vdi_uuid , response )
126+ except Exception as remote_e :
127+ self ._raise_openers_exception (self , vdi_uuid , 'Couldn\' t make vhdutil call' )
120128
121- return response_parser (self , vdi_uuid , response )
122129 return wrapper
123130 return decorated
124131
0 commit comments