From: Jon Ludlam Date: Thu, 13 Aug 2009 12:24:11 +0000 (+0100) Subject: Fix the allocation of IDs to NICs. All NICs now have a unique ID allocated on reading... X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=75b2e3643ecc7e317fa97e842c90126d83e995ad;p=xenclient%2Ftoolstack.git Fix the allocation of IDs to NICs. All NICs now have a unique ID allocated on reading the config file (if one hasn't been specified) --- diff --git a/xenvm/vmact.ml b/xenvm/vmact.ml index fd30774..5fe4f11 100644 --- a/xenvm/vmact.ml +++ b/xenvm/vmact.ml @@ -162,20 +162,20 @@ let add_nic_to_vm ~xs state nic = nic.nic_mac_gen <- ( match nic.nic_mac with | Some "random" -> generate_random_mac (); - | None | Some "vm" -> generate_vm_mac nic.nic_aid nic.nic_model state.vm_uuid + | None | Some "vm" -> generate_vm_mac nic.nic_id nic.nic_model state.vm_uuid | Some mac -> - if is_valid_mac mac then mac else generate_vm_mac nic.nic_aid nic.nic_model state.vm_uuid + if is_valid_mac mac then mac else generate_vm_mac nic.nic_id nic.nic_model state.vm_uuid ) ); let netty = Netman.Bridge nic.nic_bridge_gen in let (_: Device_common.device) = - Device.Vif.add ~xs ~devid:nic.nic_aid ~netty ~mac:nic.nic_mac_gen + Device.Vif.add ~xs ~devid:nic.nic_id ~netty ~mac:nic.nic_mac_gen ~protocol:(devproto_of_state state) state.vm_domid in () let get_nics cfg = (* then sort the nics by ascending order *) - List.sort (fun nic1 nic2 -> if nic1.nic_aid > nic2.nic_aid then 1 else -1) cfg.nics + List.sort (fun nic1 nic2 -> if nic1.nic_id > nic2.nic_id then 1 else -1) cfg.nics let get_pcis cfg = let ids = ref [] in @@ -218,27 +218,6 @@ let dm_info_of_cfg cfg = Device.Dm.extras = cfg.extrahvm; } -(* set all nics aid *) -let setup_nics state = - List.iter (fun nic -> - if nic.nic_id = (-1) then ( - let first_free_id = - let rec s i = - if i > 32 then - failwith "cannot find a free nic id"; - let found = - try let (_: config_nic) = List.find (fun x -> x.nic_aid = i) state.vm_cfg.nics in true - with Not_found -> false - in - if not found then i else s (i + 1) - in - s 0 - in - nic.nic_aid <- first_free_id - ) - ) state.vm_cfg.nics; - () - let add_devices xc xs domid state restore = let cfg = state.vm_cfg in let pcis = get_pcis cfg in @@ -631,7 +610,7 @@ let device_cmd xc xs state ty subcmd args = let nic_list args = let l = List.map (fun nic -> sprintf "id: %d, bridge:%s, mac:%s\n" - nic.nic_aid nic.nic_bridge_gen nic.nic_mac_gen + nic.nic_id nic.nic_bridge_gen nic.nic_mac_gen ) cfg.nics in Xenvmlib.Msg (String.concat "" l) in diff --git a/xenvm/vmconfig.ml b/xenvm/vmconfig.ml index 9a21c61..15a5aa2 100644 --- a/xenvm/vmconfig.ml +++ b/xenvm/vmconfig.ml @@ -17,9 +17,14 @@ open Printf open Stringext +module D = Debug.Debugger(struct let name="vmconfig" end) +open D + type action = ActionSuspend | ActionResume | ActionRestart | ActionDestroy | ActionPreserve type startupstate = StartupShutdown | StartupPause | StartupStart | StartupRestore of (string * bool) +exception InvalidConfig + type notify_ty = | NotifyTcp6 of string | NotifyTcp of Unix.inet_addr * int @@ -82,7 +87,6 @@ type config_disk = { type config_nic = { nic_id: int; - mutable nic_aid: int; (* actual id for unallocated devices *) nic_bridge: string option; mutable nic_bridge_gen: string; nic_mac: string option; @@ -152,7 +156,6 @@ type config = { let default_nic = { nic_id = -1; - nic_aid = -1; nic_bridge = None; nic_bridge_gen = ""; nic_mac = None; @@ -228,12 +231,36 @@ let config_nic_of_string s = { default_nic with nic_id = !id; - nic_aid = !id; nic_bridge = !bridge; nic_mac = !mac; nic_model = !model; } +(* Where NIC IDs have been left blank (or explicitly set to -1), here we allocate them a reasonable number *) +let assign_nic_ids nics = + let sort_nics nics = List.sort (fun nic1 nic2 -> compare nic1.nic_id nic2.nic_id) nics in + let assert_ok nics = + ignore(List.fold_left (fun last_id nic -> + let id = nic.nic_id in + if last_id=id + then (error "Duplicate NIC ids found (%d)" id; raise InvalidConfig); + if id<0 || id>31 + then (error "NIC id %d out of range (must be between 0 and 31 inclusive)" id; raise InvalidConfig); + id) + (-1) nics) + in + let allocate_nic_id nic nics = + let rec find_unused n = + if List.exists (fun nic -> nic.nic_id = n) nics then find_unused (n+1) else n + in + let id = find_unused 0 in + sort_nics ({nic with nic_id = id}::nics) + in + let (assigned,unassigned) = List.partition (fun nic -> nic.nic_id >= 0) nics in + let nics = List.fold_right allocate_nic_id unassigned (sort_nics assigned) in + assert_ok nics; + nics + let config_disk_of_string s = (* physpath:phystype:virtpath:mode:devtype *) let ls = String.split ':' s in @@ -560,12 +587,16 @@ let of_file uuid error_report file = with Config.Error ls -> error_report ls end; + + let nics = assign_nic_ids !cfg.nics in + { !cfg with __uuid = !__uuid; debug = !debug; memory = Int64.mul (Int64.of_int !memory) 1024L; startup = !startup; output = !output; + nics = nics; no_mem_check = !no_mem_check; } diff --git a/xenvm/xenvm.ml b/xenvm/xenvm.ml index 845ec47..4714e2d 100644 --- a/xenvm/xenvm.ml +++ b/xenvm/xenvm.ml @@ -325,7 +325,7 @@ let monitor_vm state = | Xal.HotplugChanged (true, "vif", devid, oldextra, newextra) -> let devid = int_of_string devid in let nic = - try Some (List.find (fun nic -> nic.nic_aid = devid) state.vm_cfg.nics) + try Some (List.find (fun nic -> nic.nic_id = devid) state.vm_cfg.nics) with Not_found -> None in let device = may (fun nic -> let backend = {