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