@@ -76,33 +76,6 @@ def wrapper(*args, **kwargs):
76
76
self ._linstor .get_volume_name (vdi_uuid )
77
77
)
78
78
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.
106
79
remote_args = {
107
80
'devicePath' : device_path ,
108
81
'groupName' : self ._linstor .group_name
@@ -111,14 +84,48 @@ def wrapper(*args, **kwargs):
111
84
remote_args = {str (key ): str (value ) for key , value in remote_args .iteritems ()}
112
85
113
86
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' )
120
128
121
- return response_parser (self , vdi_uuid , response )
122
129
return wrapper
123
130
return decorated
124
131
0 commit comments