3131
3232
3333def call_remote_method (session , host_ref , method , device_path , args ):
34+ host_rec = session .xenapi .host .get_record (host_ref )
35+ host_uuid = host_rec ['uuid' ]
36+
3437 try :
3538 response = session .xenapi .host .call_plugin (
3639 host_ref , MANAGER_PLUGIN , method , args
3740 )
3841 except Exception as e :
39- util .SMlog ('call-plugin ({} with {}) exception: {}' .format (
40- method , args , e
42+ util .SMlog ('call-plugin on {} ({} with {}) exception: {}' .format (
43+ host_uuid , method , args , e
4144 ))
4245 raise util .SMException (str (e ))
4346
44- util .SMlog ('call-plugin ({} with {}) returned: {}' .format (
45- method , args , response
47+ util .SMlog ('call-plugin on {} ({} with {}) returned: {}' .format (
48+ host_uuid , method , args , response
4649 ))
4750
4851 return response
@@ -85,33 +88,6 @@ def wrapper(*args, **kwargs):
8588 self ._linstor .get_volume_name (vdi_uuid )
8689 )
8790
88- # A. Try a call using directly the DRBD device to avoid
89- # remote request.
90-
91- # Try to read locally if the device is not in use or if the device
92- # is up to date and not diskless.
93- (node_names , in_use_by ) = \
94- self ._linstor .find_up_to_date_diskful_nodes (vdi_uuid )
95-
96- local_e = None
97- try :
98- if not in_use_by or socket .gethostname () in node_names :
99- return self ._call_local_method (local_method , device_path , * args [2 :], ** kwargs )
100- except ErofsLinstorCallException as e :
101- local_e = e .cmd_err
102- except Exception as e :
103- local_e = e
104-
105- util .SMlog (
106- 'unable to execute `{}` locally, retry using a readable host... (cause: {})' .format (
107- remote_method , local_e if local_e else 'local diskless + in use or not up to date'
108- )
109- )
110-
111- if in_use_by :
112- node_names = {in_use_by }
113-
114- # B. Execute the plugin on master or slave.
11591 remote_args = {
11692 'devicePath' : device_path ,
11793 'groupName' : self ._linstor .group_name
@@ -120,14 +96,48 @@ def wrapper(*args, **kwargs):
12096 remote_args = {str (key ): str (value ) for key , value in remote_args .items ()}
12197
12298 try :
123- def remote_call ():
124- host_ref = self ._get_readonly_host (vdi_uuid , device_path , node_names )
125- return call_remote_method (self ._session , host_ref , remote_method , device_path , remote_args )
126- response = util .retry (remote_call , 5 , 2 )
127- except Exception as remote_e :
128- self ._raise_openers_exception (device_path , local_e or remote_e )
99+ host_ref_attached = util .get_hosts_attached_on (self ._session , [vdi_uuid ])[0 ]
100+ if host_ref_attached :
101+ response = call_remote_method (
102+ self ._session , host_ref_attached , remote_method , device_path , remote_args
103+ )
104+ return response_parser (self , vdi_uuid , response )
105+ except Exception as e :
106+ util .SMlog (
107+ 'Failed to call method on attached host. Trying local access... (cause: {})' .format (e ),
108+ priority = util .LOG_DEBUG
109+ )
110+
111+ try :
112+ master_ref = self ._session .xenapi .pool .get_all_records ().values ()[0 ]['master' ]
113+ response = call_remote_method (self ._session , master_ref , remote_method , device_path , remote_args )
114+ return response_parser (self , vdi_uuid , response )
115+ except Exception as e :
116+ util .SMlog (
117+ 'Failed to call method on master host. Finding primary node... (cause: {})' .format (e ),
118+ priority = util .LOG_DEBUG
119+ )
120+
121+ nodes , primary_hostname = self ._linstor .find_up_to_date_diskful_nodes (vdi_uuid )
122+ if primary_hostname :
123+ try :
124+ host_ref = self ._get_readonly_host (vdi_uuid , device_path , {primary_hostname })
125+ response = call_remote_method (self ._session , host_ref , remote_method , device_path , remote_args )
126+ return response_parser (self , vdi_uuid , response )
127+ except Exception as remote_e :
128+ self ._raise_openers_exception (device_path , remote_e )
129+ else :
130+ util .SMlog (
131+ 'Couldn\' t get primary for {}. Trying with another node...' .format (vdi_uuid ),
132+ priority = util .LOG_DEBUG
133+ )
134+ try :
135+ host = self ._get_readonly_host (vdi_uuid , device_path , nodes )
136+ response = call_remote_method (self ._session , host , remote_method , device_path , remote_args )
137+ return response_parser (self , vdi_uuid , response )
138+ except Exception as remote_e :
139+ self ._raise_openers_exception (device_path , remote_e )
129140
130- return response_parser (self , vdi_uuid , response )
131141 return wrapper
132142 return decorated
133143
0 commit comments