Skip to content

Commit fa929c4

Browse files
committed
CA-403867: Block pool join if IP not configured on cluster network
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 0ce8043 commit fa929c4

File tree

3 files changed

+91
-0
lines changed

3 files changed

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

0 commit comments

Comments
 (0)