]> xenbits.xensource.com Git - xenclient/toolstack.git/commitdiff
Fix the allocation of IDs to NICs. All NICs now have a unique ID allocated on reading...
authorJon Ludlam <jludlam@snoosnoo2.(none)>
Thu, 13 Aug 2009 12:24:11 +0000 (13:24 +0100)
committerJon Ludlam <Jonathan.Ludlam@eu.citrix.com>
Mon, 17 Aug 2009 13:01:58 +0000 (14:01 +0100)
xenvm/vmact.ml
xenvm/vmconfig.ml
xenvm/xenvm.ml

index fd307746dda8cce4abd958fb66b2a5f09e0b94c0..5fe4f118137f8ddb1633156832bc40fe3fdc3993 100644 (file)
@@ -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
index 9a21c61f072ecdd96337533d727ff3e50ff70147..15a5aa2d8f4a0b9b19c88486698bccbdc5a443f0 100644 (file)
 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;
        }
 
index 845ec47bc0d7b0e150e8814d7234a78ac2d58514..4714e2dede28ca51b7adb1631d4353855e7a76f3 100644 (file)
@@ -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 = {