@@ -270,15 +270,53 @@ let create ~__context ~network ~members ~mAC ~mode ~properties =
270270	let  bond =  Ref. make ()  in 
271271
272272	with_local_lock (fun  ()  ->
273- 		(*  Validation constraints: *) 
273+ 		(*  Collect information *) 
274+ 		let  member_networks =  List. map (fun  pif  -> Db.PIF. get_network ~__context ~self: pif) members in 
275+ 
276+ 		let  local_vifs =  get_local_vifs ~__context host member_networks in 
277+ 		let  local_vlans =  List. concat (List. map (fun  pif  -> Db.PIF. get_VLAN_slave_of ~__context ~self: pif) members) in 
278+ 		let  local_tunnels =  List. concat (List. map (fun  pif  -> Db.PIF. get_tunnel_transport_PIF_of ~__context ~self: pif) members) in 
279+ 
280+ 		let  management_pif = 
281+ 			match  List. filter (fun  p  -> Db.PIF. get_management ~__context ~self: p) members with 
282+ 			|  management_pif  :: _  -> Some  management_pif
283+ 			|  []  -> None 
284+ 		in 
285+ 
286+ 		let  pifs_with_ip_conf = 
287+ 			List. filter (fun  self  ->
288+ 				Db.PIF. get_ip_configuration_mode ~__context ~self  <>  `None 
289+ 			) members in 
290+ 
291+ 		(*  The primary slave is the management PIF, or the first member with
292+ 		 * IP configuration, or otherwise simply the first member in the list. *)  
293+ 		let  primary_slave = 
294+ 			match  management_pif, pifs_with_ip_conf, members with 
295+ 			|  Some  management_pif , _ , _  -> management_pif
296+ 			|  None , pif_with_ip ::_ , _  -> pif_with_ip
297+ 			|  None , [] , pif ::_  -> pif
298+ 			|  None , [] , []  ->
299+ 				raise (Api_errors. Server_error (Api_errors. pif_bond_needs_more_members, [] ))
300+ 		in 
301+ 		let  mAC = 
302+ 			if  mAC <>  " " then 
303+ 				mAC
304+ 			else 
305+ 				Db.PIF. get_MAC ~__context ~self: primary_slave
306+ 		in 
307+ 		let  disallow_unplug = 
308+ 			List. fold_left (fun  a  m  -> Db.PIF. get_disallow_unplug ~__context ~self: m ||  a) false  members
309+ 		in 
310+ 
311+ 		(*  Validate constraints: *) 
274312		(*  1. Members must not be in a bond already *) 
275313		(*  2. Members must not have a VLAN tag set *) 
276314		(*  3. Members must not be tunnel access PIFs *) 
277315		(*  4. Referenced PIFs must be on the same host *) 
278- 		(*  5. There  must be more than one member for  the bond ( ** disabled for now)  *) 
279- 		(*  6. Members must not  be the management interface if HA is enabled  *) 
280- 		(*  7. Members must be PIFs that are managed by xapi  *) 
281- 		(*  8. Members must  have the same PIF properties  *) 
316+ 		(*  5. Members  must not  be the management interface if HA is enabled  *) 
317+ 		(*  6. Members must be PIFs that are managed by xapi  *) 
318+ 		(*  7. Members must have the same PIF properties  *) 
319+ 		(*  8. Only the primary PIF should  have a non-None IP configuration  *) 
282320		List. iter (fun  self  ->
283321			let  bond =  Db.PIF. get_bond_slave_of ~__context ~self  in 
284322			let  bonded =  try  ignore(Db.Bond. get_uuid ~__context ~self: bond); true  with  _  ->  false  in 
@@ -297,10 +335,6 @@ let create ~__context ~network ~members ~mAC ~mode ~properties =
297335		let  hosts =  List. map (fun  self  -> Db.PIF. get_host ~__context ~self ) members in 
298336		if  List. length (List. setify hosts) <>  1 
299337		then  raise (Api_errors. Server_error  (Api_errors. pif_cannot_bond_cross_host, [] ));
300- 		(* 
301- 		if List.length members < 2 
302- 		then raise (Api_errors.Server_error (Api_errors.pif_bond_needs_more_members, [])); 
303- 		*)  
304338		let  pif_properties = 
305339			if  members =  []  then 
306340				[] 
@@ -313,39 +347,8 @@ let create ~__context ~network ~members ~mAC ~mode ~properties =
313347				else 
314348					p
315349		in 
316- 
317- 		(*  Collect information *) 
318- 		let  member_networks =  List. map (fun  pif  -> Db.PIF. get_network ~__context ~self: pif) members in 
319- 
320- 		let  local_vifs =  get_local_vifs ~__context host member_networks in 
321- 		let  local_vlans =  List. concat (List. map (fun  pif  -> Db.PIF. get_VLAN_slave_of ~__context ~self: pif) members) in 
322- 		let  local_tunnels =  List. concat (List. map (fun  pif  -> Db.PIF. get_tunnel_transport_PIF_of ~__context ~self: pif) members) in 
323- 
324- 		let  management_pif = 
325- 			match  List. filter (fun  p  -> Db.PIF. get_management ~__context ~self: p) members with 
326- 			|  management_pif  :: _  -> Some  management_pif
327- 			|  []  -> None 
328- 		in 
329- 		let  primary_slave = 
330- 			(*  The primary slave is the management PIF, or the first member with IP configuration,
331- 			 * or otherwise simply the first member in the list. *)  
332- 			match  management_pif with 
333- 			|  Some  management_pif  -> management_pif
334- 			|  None  ->
335- 				try 
336- 					List. hd (List. filter (fun  pif  -> Db.PIF. get_ip_configuration_mode ~__context ~self: pif <>  `None ) members)
337- 				with  _  -> 
338- 					List. hd members
339- 		in 
340- 		let  mAC = 
341- 			if  mAC <>  " " then 
342- 				mAC
343- 			else 
344- 				Db.PIF. get_MAC ~__context ~self: primary_slave
345- 		in 
346- 		let  disallow_unplug = 
347- 			List. fold_left (fun  a  m  -> Db.PIF. get_disallow_unplug ~__context ~self: m ||  a) false  members
348- 		in 
350+ 		if  List. length pifs_with_ip_conf >  1 
351+ 		then  raise Api_errors. (Server_error  (pif_bond_more_than_one_ip, [] ));
349352
350353		(*  Create master PIF and Bond objects *) 
351354		let  device =  choose_bond_device_name ~__context ~host  in 
0 commit comments