33
33
34
34
35
35
def 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
+
36
39
try :
37
40
response = session .xenapi .host .call_plugin (
38
41
host_ref , MANAGER_PLUGIN , method , args
39
42
)
40
43
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
43
46
))
44
47
raise util .SMException (str (e ))
45
48
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
48
51
))
49
52
50
53
return response
@@ -86,33 +89,6 @@ def wrapper(*args, **kwargs):
86
89
self ._linstor .get_volume_name (vdi_uuid )
87
90
)
88
91
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.
116
92
remote_args = {
117
93
'devicePath' : device_path ,
118
94
'groupName' : self ._linstor .group_name
@@ -121,14 +97,48 @@ def wrapper(*args, **kwargs):
121
97
remote_args = {str (key ): str (value ) for key , value in remote_args .iteritems ()}
122
98
123
99
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 )
130
141
131
- return response_parser (self , vdi_uuid , response )
132
142
return wrapper
133
143
return decorated
134
144
0 commit comments