Skip to content

Commit caaad26

Browse files
committed
CA-403867: Block pool join if IP not configured on cluster network
Refix with some review comments addressed. To join a host into a pool with cluster enabled, the host must have one and only one IP configured on the joining cluster network. If not, after the host joinied the pool, GFS2 SR cannot be plugged on the joined host because an IP is required in the cluster network. Pool join in this scenario has been blocked in XenCenter, here we will block it inside xapi. Signed-off-by: Gang Ji <[email protected]>
1 parent 8f94586 commit caaad26

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

ocaml/idl/datamodel_errors.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,14 @@ let _ =
897897
the pool coordinator. Make sure the sm are of the same versions and try \
898898
again."
899899
() ;
900+
error Api_errors.pool_joining_pool_cannot_enable_clustering_on_vlan_network
901+
["vlan"] ~doc:"The remote pool cannot enable clustering on vlan network" () ;
902+
error Api_errors.pool_joining_host_must_have_only_one_IP_on_clustering_network
903+
[]
904+
~doc:
905+
"The host joining the pool must have one and only one IP on the \
906+
clustering network"
907+
() ;
900908

901909
(* External directory service *)
902910
error Api_errors.subject_cannot_be_resolved []

ocaml/xapi-consts/api_errors.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,12 @@ let pool_joining_host_ca_certificates_conflict =
757757
let pool_joining_sm_features_incompatible =
758758
add_error "POOL_JOINING_SM_FEATURES_INCOMPATIBLE"
759759

760+
let pool_joining_pool_cannot_enable_clustering_on_vlan_network =
761+
add_error "POOL_JOINING_POOL_CANNOT_ENABLE_CLUSTERING_ON_VLAN_NETWORK"
762+
763+
let pool_joining_host_must_have_only_one_IP_on_clustering_network =
764+
add_error "POOL_JOINING_HOST_MUST_HAVE_ONLY_ONE_IP_ON_CLUSTERING_NETWORK"
765+
760766
(*workload balancing*)
761767
let wlb_not_initialized = add_error "WLB_NOT_INITIALIZED"
762768

ocaml/xapi/xapi_pool.ml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,89 @@ let pre_join_checks ~__context ~rpc ~session_id ~force =
112112
)
113113
)
114114
in
115+
let one_ip_configured_on_joining_cluster_network () =
116+
let one_ip_configured_on_joining_cluster_network' cluster_host =
117+
match Client.Cluster_host.get_PIF ~rpc ~session_id ~self:cluster_host with
118+
| pif when pif = Ref.null ->
119+
()
120+
| pif -> (
121+
match Client.PIF.get_VLAN ~rpc ~session_id ~self:pif with
122+
| vlan when vlan > 0L ->
123+
error "Cannot join pool whose clustering is enabled on VLAN network" ;
124+
raise
125+
(Api_errors.Server_error
126+
( Api_errors
127+
.pool_joining_pool_cannot_enable_clustering_on_vlan_network
128+
, [Int64.to_string vlan]
129+
)
130+
)
131+
| 0L | _ -> (
132+
let clustering_bridges_in_pool =
133+
( match
134+
Client.PIF.get_bond_master_of ~rpc ~session_id ~self:pif
135+
with
136+
| [] ->
137+
[pif]
138+
| bonds ->
139+
List.concat_map
140+
(fun bond ->
141+
Client.Bond.get_slaves ~rpc ~session_id ~self:bond
142+
)
143+
bonds
144+
)
145+
|> List.map (fun self ->
146+
Client.PIF.get_network ~rpc ~session_id ~self
147+
)
148+
|> List.map (fun self ->
149+
Client.Network.get_bridge ~rpc ~session_id ~self
150+
)
151+
in
152+
match
153+
Db.Host.get_PIFs ~__context
154+
~self:(Helpers.get_localhost ~__context)
155+
|> List.filter (fun p ->
156+
List.exists
157+
(fun b ->
158+
let network = Db.PIF.get_network ~__context ~self:p in
159+
Db.Network.get_bridge ~__context ~self:network = b
160+
)
161+
clustering_bridges_in_pool
162+
&& Db.PIF.get_IP ~__context ~self:p <> ""
163+
)
164+
with
165+
| [_] ->
166+
()
167+
| _ ->
168+
error
169+
"Cannot join pool as the joining host needs to have one (and \
170+
only one) IP address on the network that will be used for \
171+
clustering." ;
172+
raise
173+
(Api_errors.Server_error
174+
( Api_errors
175+
.pool_joining_host_must_have_only_one_IP_on_clustering_network
176+
, []
177+
)
178+
)
179+
)
180+
)
181+
in
182+
match Client.Cluster_host.get_all ~rpc ~session_id with
183+
| [] ->
184+
()
185+
| ch :: _ -> (
186+
let cluster =
187+
Client.Cluster_host.get_cluster ~rpc ~session_id ~self:ch
188+
in
189+
match
190+
Client.Cluster.get_pool_auto_join ~rpc ~session_id ~self:cluster
191+
with
192+
| false ->
193+
()
194+
| true ->
195+
one_ip_configured_on_joining_cluster_network' ch
196+
)
197+
in
115198
(* CA-26975: Pool edition MUST match *)
116199
let assert_restrictions_match () =
117200
let my_edition =
@@ -888,6 +971,7 @@ let pre_join_checks ~__context ~rpc ~session_id ~force =
888971
assert_management_interface_exists () ;
889972
ha_is_not_enable_on_me () ;
890973
clustering_is_not_enabled_on_me () ;
974+
one_ip_configured_on_joining_cluster_network () ;
891975
ha_is_not_enable_on_the_distant_pool () ;
892976
assert_not_joining_myself () ;
893977
assert_i_know_of_no_other_hosts () ;

0 commit comments

Comments
 (0)